home *** CD-ROM | disk | FTP | other *** search
- /*
- 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;
- }
- }
-