home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / xgopher.1.3 / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-15  |  5.9 KB  |  269 lines

  1. /* help.c
  2.    functions to support a multi-section help file */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19. /* help file format is:
  20.     ++sec_name-1 : title1
  21.         :
  22.         :
  23.     ++sec_name-i : titlei
  24.         :
  25.         :
  26.     <eof>
  27.   Each section is started by a ++ at the beginning of the line, then
  28.   a keyed section name up to the next colon or new-line character
  29.   (or length limit).  The remainder of the line after the colon (if
  30.   anything) is a title to be displayed with the help text.  The
  31.   contents of that named section include all text starting after the
  32.   new-line, up to the next ++ delimiter or end-of-file.
  33.  
  34.   Sections should be uniquely named.
  35.  
  36.   The structure below allows the first 20 characters of a section name
  37.   to be saved (and to provide uniqueness).  A fixed length table is
  38.   allocated.  Either of these limits may be made longer.
  39.  
  40. */
  41.  
  42. #include <stdio.h>
  43. #include <string.h>
  44.  
  45. #include "help.h"
  46. #include "conf.h"
  47. #include "gopher.h"
  48. #include "gui.h"
  49. #include "misc.h"
  50.  
  51. #include "osdep.h"
  52.  
  53. #define HELP_SEC_NAME_LEN    20
  54. #define HELP_INDEX_LENGTH    20
  55.  
  56. typedef struct _helpIndexStruct {
  57.     char    sectionName[HELP_SEC_NAME_LEN];
  58.     char    sectionTitle[HELP_SEC_TITLE_LEN];
  59.     int    start;
  60.     int    length;
  61.     } helpIndexStruct;
  62.  
  63.  
  64. /* variables global to this file */
  65.  
  66. static char        helpFileName[PATH_NAME_LEN] = "";
  67. static helpIndexStruct helpIndex[HELP_INDEX_LENGTH];
  68. static int        nSections=0;
  69. static BOOLEAN        fileMsg = FALSE;
  70. static BOOLEAN        indexBuilt = FALSE;
  71.  
  72.  
  73. /* setHelpFile
  74.    pass the file name of the help file to these routines for later use */
  75.  
  76. void
  77. setHelpFile(fn)
  78. char    *fn;
  79. {
  80.     strncpy(helpFileName, tildePath(fn), PATH_NAME_LEN-1);
  81.     helpFileName[PATH_NAME_LEN-1] = '\0';
  82. }
  83.  
  84.  
  85. /* openHelpFile
  86.    open the help file and report an error (the first time) if unsuccessful. */
  87.  
  88. static FILE *
  89. openHelpFile()
  90. {
  91.     char    message[MESSAGE_STRING_LEN];
  92.     FILE    *fp;
  93.  
  94.     if ((fp = fopen(helpFileName, "r")) == (FILE *) NULL) {
  95.         if (! fileMsg) {
  96.             sprintf (message,
  97.                 "Unable to open the help file (%s)\n",
  98.                 helpFileName);
  99.             showError(message);
  100.             fileMsg = TRUE;
  101.         }
  102.     }
  103.  
  104.     return fp;
  105. }
  106.  
  107.  
  108. #ifdef DEBUG
  109. /* printHelpIndex
  110.    dump the help index table - debugging use */
  111.  
  112. void
  113. printHelpIndex()
  114. {
  115.     int    i;
  116.  
  117.     fprintf (stderr, "Help index has %d sections.\n", nSections);
  118.     fprintf (stderr, "              name          start   length\n");
  119.     for (i=0; i<nSections; i++) {
  120.         fprintf (stderr, "%2d: \'%20.20s\'  %5d   %5d\n", 
  121.             i, helpIndex[i].sectionName,
  122.             helpIndex[i].start, helpIndex[i].length);
  123.     }
  124. }
  125. #endif
  126.  
  127.  
  128. /* buildHelpIndex
  129.    scan the help file and build the indices to the sections */
  130.  
  131. void
  132. buildHelpIndex()
  133. {
  134.     enum     {cp_bol, cp_plus, cp_plusplus, cp_other} state;
  135.     FILE    *fp;
  136.     int    n=0;
  137.     
  138.     indexBuilt = TRUE;
  139.     if ((fp = openHelpFile()) == (FILE *) NULL) return;
  140.  
  141.     state = cp_bol;
  142.     while ( TRUE ) {
  143.         int    ich;
  144.         char    ch;
  145.  
  146.         if ((ich = getc(fp)) == EOF) {
  147.             if (nSections > 0) {
  148.                 helpIndex[nSections-1].length =
  149.                     n - helpIndex[nSections-1].start;
  150.             }
  151.             break;
  152.         }
  153.  
  154.         ch = (char) ich;
  155.  
  156.         switch (state) {
  157.  
  158.             case cp_bol:
  159.             if (ch == '+') state = cp_plus;
  160.             else   if (ch != '\n') state = cp_other;
  161.             break;
  162.         
  163.             case cp_plus:
  164.             if (ch == '+') state = cp_plusplus;
  165.             else if (ch == '\n') state = cp_bol;
  166.             else state = cp_other;
  167.             break;
  168.         
  169.             case cp_plusplus:
  170.             if (nSections != 0) {
  171.                 helpIndex[nSections-1].length =
  172.                     n - helpIndex[nSections-1].start - 2;
  173.             }
  174.  
  175.             {
  176.             int    i, limit, inTitle=FALSE;
  177.             char    *p;
  178.  
  179.             i = 0;
  180.             p = helpIndex[nSections].sectionName;
  181.             limit = HELP_SEC_NAME_LEN - 1;
  182.             helpIndex[nSections].sectionTitle[0] = '\0';
  183.                 while (ich != EOF  &&  ich != '\n') {
  184.                 if (ich == ':'  &&  ! inTitle) {
  185.                     *p = '\0';
  186.                     i = 0;
  187.                     p = helpIndex[nSections].sectionTitle;
  188.                     limit = HELP_SEC_TITLE_LEN - 1;
  189.                     inTitle = TRUE;
  190.                 } else {
  191.                     if (i < limit) *(p++) = (char) ich;
  192.                     i++;
  193.                 }
  194.                 ich = getc(fp);
  195.                 n++;
  196.                 }
  197.             *p = '\0';
  198.             }
  199.  
  200.             helpIndex[nSections].start = n+1;
  201.             nSections++;
  202.             state = cp_bol;
  203.             break;
  204.         
  205.             case cp_other:
  206.             if (ch == '\n') state = cp_bol;
  207.             break;
  208.             
  209.         }
  210.  
  211.         n++;
  212.     }
  213.  
  214.     fclose(fp);
  215. }
  216.  
  217.  
  218. /* getHelpText
  219.    retrieve the help text from the requested section of the file */
  220.  
  221. char    *
  222. getHelpText(name, title)
  223. char    *name;
  224. char    *title;
  225. {
  226.     char    *string;
  227.     int    i;
  228.     FILE    *fp;
  229.  
  230.     if (! indexBuilt) buildHelpIndex();
  231.     
  232.     string = NULL;
  233.     title[0] = '\0';
  234.  
  235.     for (i=0; i<nSections; i++) {
  236.         if (strncmp(name, helpIndex[i].sectionName, HELP_SEC_NAME_LEN)
  237.                                 == 0) {
  238.             if (helpIndex[i].length == 0) {
  239.                 /* no data in section */
  240.                 break;
  241.             }
  242.             if ((fp = openHelpFile()) == (FILE *) NULL) {
  243.                 /* can't open help file */
  244.                 break;
  245.             }
  246.  
  247.             if ((string =
  248.                 (char *) malloc(helpIndex[i].length+1)) == NULL) {
  249.                 /* can't malloc string */
  250.                 fclose (fp);
  251.                 break;
  252.             }
  253.  
  254.             fseek(fp, helpIndex[i].start, 0);
  255.             fread(string, sizeof (char), helpIndex[i].length, fp);
  256.             fclose (fp);
  257.  
  258.             string[helpIndex[i].length] = '\0';
  259.  
  260.             strncpy(title, helpIndex[i].sectionTitle,
  261.                             HELP_SEC_TITLE_LEN);
  262.  
  263.             break;
  264.         }
  265.     }
  266.  
  267.     return string;
  268. }
  269.