home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
HELP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-01
|
9KB
|
400 lines
/*
help.c
% help_Init etc.
Routines for the C-scape help system.
C-scape 3.2
Copyright (c) 1986, 1987, by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History:
-----------------
12/11/87 jmd Changed \r\n translation scheme in LookUp for UNIX compat.
3/08/88 jmd Added STRATUS decl.
4/07/88 jmd Fixed index[0] bug in help_Close
6/07/88 jmd Fixed missing message bug in help_LookUp
6/23/88 jmd removed errno.h
6/23/88 jmd converted generic pointers to VOID*
6/24/88 jmd converted to new xarray/iarray calls
8/16/88 jmd added calls to omalloc, oak_Errno
4/16/89 jmd adjusted for jarray
10/25/89 jdc added trailing '\n' strip in help_LookUp
11/07/89 jdc again
3/08/90 jmd improved index array scheme
3/28/90 jmd ansi-fied
11/01/90 ted put (void) in arg list of help_Close.
*/
#include <stdio.h>
#include <string.h>
#include "cscape.h"
#include "ostdlib.h" /* for atoi() */
#include "cserror.h"
#include "oakalloc.h"
#include "oaktag.h"
#include "helpdecl.h"
static help_type help = NULL;
static char buffer[HELPLINE + 1];
/* -------------------------------------------------------------------------- */
/* index macros */
#define help_GetIndex(h, chap, par) \
*(((h)->index + ((chap) * (h)->par_count)) + (par))
#define help_SetIndex(h, chap, par, msg) \
*(((h)->index + ((chap) * (h)->par_count)) + (par)) = (msg)
/* -------------------------------------------------------------------------- */
int help_Init(FILE *fp, help_fptr disp, unsigned int size, VOID *data)
/*
Initialize the help system using fp as the help file
and disp as the disp function.
size is the size of the help buffer.
data is placed in the help data pointer.
Returns HELP_OK if successful, else
a help error message.
*/
{
int chap, par;
int msg, msg_count, chap_count, par_count;
long start, temp;
if (fp == NULL || disp == FNULL || help != NULL) {
return(HELP_BADARG);
}
/* make the help stucture */
if ((help = (help_type) omalloc(CSA_HELP, sizeof(struct help_struct))) == NULL) {
return(HELP_NOMEM);
}
help->fp = fp;
help->disp = disp;
help->high_msg = 0;
help->msg = 0;
help->chap = 0;
help->par = 0;
help->data = data;
help->size = size;
/* set up the help index */
rewind(fp);
/* skip the header */
while(1) {
if (fgets(buffer, HELPLINE, fp) == NULL) {
help = NULL;
return(HELP_BADFILE);
}
if (buffer[0] == '%' && buffer[1] == '%') {
break;
}
}
/* remember where we are */
start = ftell(fp);
/* compute the size of the index */
chap_count = par_count = msg_count = 0;
/* read the index */
while(1) {
if (fgets(buffer, HELPLINE, fp) == NULL) {
help = NULL;
return(HELP_BADFILE);
}
if (buffer[0] == '%' && buffer[1] == '%') {
break;
}
else if (buffer[0] != '!') { /* skip comments */
chap = par = msg = 0;
if (sscanf(buffer, "%d,%d:%d", &chap, &par, &msg) == 3) {
chap_count = (chap_count > chap) ? chap_count : chap;
par_count = (par_count > par) ? par_count : par;
msg_count = (msg_count > msg) ? msg_count : msg;
}
}
}
help->chap_count = chap_count;
help->par_count = par_count + 1; /* add one for default (0) paragraph */
/* allocate the message buffer */
help->text = (char *) omalloc(CSA_HELPTEXT, help->size + 10);
/* allocate the index */
help->index = (int *) ocalloc(CSA_HELPINDEX, help->chap_count * help->par_count, sizeof(int));
if (help->index == NULL || help->text == NULL) {
help = NULL;
return(HELP_NOMEM);
}
/* read the index */
fseek(fp, start, SEEK_SET);
while(1) {
if (fgets(buffer, HELPLINE, fp) == NULL) {
help = NULL;
return(HELP_BADFILE);
}
if (buffer[0] == '%' && buffer[1] == '%') {
break;
}
else if (buffer[0] != '!') { /* skip comments */
chap = par = msg = 0;
if (sscanf(buffer, "%d,%d:%d", &chap, &par, &msg) == 3) {
if (chap > 0 && chap <= help->chap_count &&
par >= 0 && par < help->par_count) {
/* note chap 1 is element 0 in the index array */
help_SetIndex(help, chap - 1, par, msg);
}
}
}
}
/* set up the offset array */
help->offset = la_Open(msg_count + 1);
if (help->offset == NULL) {
help = NULL;
return(HELP_NOMEM);
}
/* find first msg, put into the offset array */
while(fgets(buffer, HELPLINE, fp) != NULL) {
if (buffer[0] == '.' && buffer[1] != '!') {
msg = atoi(buffer + 1);
if (msg > 0 && msg <= msg_count) {
temp = ftell(fp);
if (!la_Put(help->offset, msg, temp)) {
help = NULL;
return(HELP_NOMEM);
}
help->high_msg = msg;
break;
}
}
}
/* set up the help_Show function */
_help_InitShow(_help_Show);
return(HELP_OK);
}
int _help_Show(int chap, int par)
/*
Searches for the appropriate message.
Displays the message via the display function.
If no there is no message for the paragraph, try and give
the message for the chapter. If unable to display a message
return(0) else return(1).
*/
/*
note: this function is called indirectly by help_Show
*/
{
int msg;
/* look up the message number */
if ((msg = help_Index(chap,par)) == -1) {
return(0);
}
/* find the message */
if (!help_LookUp(msg)) {
return(0);
}
(*(help->disp))(help);
return(1);
}
int help_Index(int chap, int par)
/*
Look up the message number associated with the chapter
and paragraph.
Adjusts the help's chapter and paragraph parameters.
Returns (-1) if no message found.
*/
{
int msg;
/* adjust the chapter number */
chap--;
if (help == NULL || chap < 0 || chap >= help->chap_count) {
return(-1);
}
/* check if par exists */
if (par <= 0 || par >= help->par_count || help_GetIndex(help, chap, par) <= 0) {
par = 0;
}
/* lookup the message number */
if ((msg = help_GetIndex(help, chap, par)) <= 0) {
return(-1);
}
help->chap = chap;
help->par = par;
return(msg);
}
boolean help_LookUp(int msg)
/*
Looks up the message in the help file.
Adjusts help parameters for the new message.
Returns TRUE if successful.
*/
{
int m;
unsigned int size, len;
char *found;
long offset, temp;
/* is it the same message as last time? */
if (msg != help->msg) {
/* have we found this msg yet?
if not, look it up.
get offsets of all the other msgs along the way
*/
if (msg > help->high_msg) {
fseek(help->fp, la_Get(help->offset, help->high_msg), SEEK_SET);
while((found = fgets(buffer, HELPLINE, help->fp)) != NULL) {
if (buffer[0] == '.' && buffer[1] != '!') {
m = atoi(buffer + 1);
if (m > 0) {
temp = ftell(help->fp);
if (!la_Put(help->offset, m, temp)) {
return(FALSE);
}
help->high_msg = m;
if (m == msg) {
break;
}
}
}
}
if (found == NULL) {
return(FALSE);
}
}
else {
/* get the message, if it is missing do nothing */
offset = la_Get(help->offset, msg);
if (offset > 0L) {
fseek(help->fp, offset, SEEK_SET);
}
else {
return(FALSE);
}
}
/* get the message */
/* get the title (skip commented lines) */
do {
if (fgets(buffer, HELPLINE, help->fp) == NULL) {
break;
}
} while(buffer[0] == '.' && buffer[1] == '!');
if ((len = strlen(buffer)) > 1 && (buffer[len - 2] == '\r')) {
/* translate '\r' '\n' to '\0' (if needed) */
buffer[len - 2] = '\0';
}
else if ((len = strlen(buffer)) > 0 && (buffer[len - 1] == '\n')) {
/* translate '\n' to '\0' (if needed) */
buffer[len - 1] = '\0';
}
strcpy(help->title, buffer);
/* get the text */
size = 0;
strcpy(help->text, "");
while(1) {
if (fgets(buffer, HELPLINE, help->fp) == NULL) {
break;
}
if (buffer[0] == '.') {
if (buffer[1] == '!') {
/* comment: ignore line */
continue;
}
else {
/* end of message */
break;
}
}
if ((len = strlen(buffer)) > 1 && buffer[len - 2] == '\r') {
/* translate '\r' '\n' to '\n' '\0' (if needed) */
buffer[len - 2] = '\n';
buffer[len - 1] = '\0';
}
size += len;
if (size >= help->size) {
break;
}
strcat(help->text, buffer);
}
}
help->msg = msg;
return(TRUE);
}
void help_Close(void)
/*
Destroy and deallocate storage from the help system.
*/
{
if (help != NULL) {
la_Close(help->offset);
ofree(CSA_HELPINDEX, (VOID *) help->index);
ofree(CSA_HELPTEXT, (VOID *) help->text);
ofree(CSA_HELP, (VOID *) help);
help = NULL;
}
}