home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume13 / okbridge / part06 / help.c < prev    next >
C/C++ Source or Header  |  1992-01-12  |  6KB  |  266 lines

  1. /* help.c -- help functions for the bridge program.
  2.  ! 
  3.  ! Copyright (C) 1990,1991 by Matthew Clegg
  4.  ! 
  5.  ! This program may be copied and distributed freely.  Please do not
  6.  ! charge money for this program or for any program derived from it.
  7.  ! If you modify this program, then include a notice stating plainly
  8.  ! that your program is derived from the okbridge program and is not
  9.  ! the same as the official okbridge program.
  10.  !
  11.  ! I welcome any suggestions for improvement to okbridge, and 
  12.  ! I would be especially happy to receive improved source code.
  13.  ! If you have comments or suggestions, or if you would like to
  14.  ! join the okbridge mailing list, then write to
  15.  !
  16.  !   mclegg@cs.ucsd.edu
  17.  !
  18.  *
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24.  
  25. #ifndef SEEK_SET
  26. #define SEEK_SET  0
  27. #endif
  28.  
  29. #include "globals.h"
  30. #include "ps.h"
  31. #include "input.h"
  32. #include "terminal.h"
  33.  
  34. /* char *help_file_name = "okbridge.help"; */
  35. #include "helpfile.h"
  36.  
  37. extern int errno;
  38. extern char *sys_errlist[];
  39. extern char *strdup();
  40. extern char *getenv ();
  41.  
  42. typedef struct help_entry_struct {
  43.     char    *topic;
  44.     char    *description;
  45.     long int file_offset;
  46.     struct help_entry_struct *next;
  47. } *help_entry;
  48.  
  49. static help_entry main_topic = NULL;
  50. FILE *help_file = NULL;
  51.  
  52.  
  53. static display_topics (message)
  54.     char *message;
  55. /* Displays the list of topics, with the given message as the top line.
  56.  . Does not display the main topic.
  57.  */
  58. {
  59.     int i;
  60.     help_entry e;
  61.     char msg_buf[80];
  62.  
  63.     clear_screen ();
  64.     print (1,1,message);
  65.     if (main_topic == NULL) {
  66.         print (3,1,"The help system is empty.");
  67.     } else {
  68.         i = 3;
  69.         for (e = main_topic->next; e != NULL; e = e->next) {
  70.           if (strcasecmp(e->topic, "slam")) {
  71.             sprintf (msg_buf, "%-10s -- %s",e->topic,
  72.                 e->description);
  73.             print (i++, 1, msg_buf);
  74.               };
  75.         };
  76.     };
  77.     input_acknowledgment (24);
  78. };
  79.  
  80. static int read_help_line (buf, buflen)
  81.     char *buf;
  82. /* Reads a line from the help file.  Returns the number of characters
  83.    read of -1 if EOF is encountered.  Skips lines beginning with a '#'. 
  84. */
  85. {
  86.     int i, ch;
  87.  
  88.     do {
  89.         ch = getc(help_file);
  90.         i = 0;
  91.         while ((ch != '\n') && (ch != EOF)) {
  92.             if (i < buflen-1) buf[i++] = ch;
  93.             ch = getc(help_file);
  94.         };
  95.         buf[i] = '\0';
  96.         if (ch == EOF) return (-1);
  97.         while ((i > 0) && isspace(buf[i-1])) buf[--i] = '\0';
  98.     } while (buf[0] == '#');
  99.     return (i);
  100. };
  101.  
  102. static display_help_entry (e)
  103.     help_entry e;
  104. /* Displays the help_entry e. */
  105. {
  106.     char line[81];
  107.     int lines_on_page, log;
  108.  
  109.     lines_on_page = 0;
  110. /*
  111.     sprintf (line, "%s -- %s", e->topic, e->description);
  112.     print(++lines_on_page, 1, line);
  113.     lines_on_page += 1;
  114. */
  115.  
  116.     fseek (help_file, e->file_offset, SEEK_SET);
  117.     log = read_help_line (line, 81);
  118.     while ((log >= 0) && strcmp(line, "--")) {
  119.         if ((lines_on_page > 22) || (line[0] == '^')) {
  120.             input_acknowledgment (24);
  121.             clear_screen ();
  122.             lines_on_page = 0;
  123.             if (line[0] == '^') line[0] = ' ';
  124.         };
  125.         print (++lines_on_page, 1, line);
  126.         log = read_help_line (line, 81);
  127.     };
  128.     input_acknowledgment (24);
  129.         
  130. };
  131.  
  132. static FILE *open_helpfile ()
  133. /* Tries to open the helpfile with given name from the help_directory.
  134.  * If an error, prints an error message and returns NULL.  Otherwise,
  135.  * returns a pointer to the opened file.
  136.  */
  137. {
  138.     char filename_buf [80], msg_buf[80], *envhelpdir;
  139.     FILE *fp;
  140.  
  141.     if ((envhelpdir = getenv("OKBRIDGE_HELPFILE")) != NULL)
  142.         sprintf (filename_buf, "%s", envhelpdir);
  143.     else
  144.         sprintf (filename_buf, "%s", help_file_name);
  145.  
  146.     fp = fopen (filename_buf, "r");
  147.     if (fp == NULL)
  148.         fp = fopen ("okbridge.help", "r");
  149.  
  150.     if (fp == NULL) {
  151.         sprintf (msg_buf, "Error opening helpfile %s", filename_buf);
  152.         print (3, 1, msg_buf);
  153.         sprintf (msg_buf, "System reports error: %s",
  154.                 sys_errlist[errno]);
  155.         print (4, 1, msg_buf);
  156.         input_acknowledgment (24);
  157.     };
  158.     return (fp);
  159. };
  160.  
  161.  
  162. static help_entry find_help_topic (topic)
  163.     char *topic;
  164. /* Looks for the help entry with the associated topic.  If it is found,
  165.  * returns a pointer to the corresponding record.  Otherwise, returns NULL.
  166.  */
  167. {
  168.     help_entry e;
  169.  
  170.     e = main_topic;
  171.     while (e != NULL) {
  172.         if (!strcasecmp(e->topic, topic))
  173.             return (e);
  174.         e = e->next;
  175.     };
  176.     return (e);
  177. };
  178.  
  179. static help_entry read_new_help_entry ()
  180. /* Reads a help entry from the help_file.  Allocates a help_entry record
  181.  . and records the pertinent information in that record.  Returns the
  182.  . allocated record or NULL if the end of file is reached.
  183.  */
  184. {
  185.     char line_buf[81], keyword_buf[80];
  186.     help_entry e;
  187.     char *curpos, *keypos, *descpos, ch;
  188.     int log;
  189.  
  190.     log = read_help_line (line_buf, 81);
  191.     if (log < 0)
  192.         return (NULL);
  193.  
  194.     for (keypos = line_buf; isspace(*keypos); keypos++);
  195.     for (curpos = keypos;(*curpos != '\0') && !isspace(*curpos);curpos++);
  196.     for (descpos = curpos; isspace(*descpos); descpos++);
  197.  
  198.     e = (help_entry) malloc(sizeof(struct help_entry_struct));
  199.     *curpos = '\0';
  200.     e->topic = strdup (keypos);
  201.     e->description = strdup (descpos);
  202.     e->file_offset = ftell (help_file);
  203.     e->next = NULL;
  204.  
  205.     do
  206.         log = read_help_line (line_buf, 81);
  207.     while 
  208.         ((log >= 0) && strcmp(line_buf, "--"));
  209.  
  210.     return (e);
  211.  
  212. };
  213.  
  214.  
  215. initialize_help_system ()
  216. /* Called once at the beginning of the program to read the file of help
  217.  * topics.
  218.  */
  219. {
  220.     help_entry e;
  221.  
  222.     help_file = open_helpfile ();
  223.     if (help_file == NULL) return;
  224.  
  225.     e = main_topic = read_new_help_entry ();
  226.     while (e != NULL) {
  227.         e->next = read_new_help_entry ();
  228.         e = e->next;
  229.     };
  230.  
  231. };
  232.  
  233.  
  234. display_help (topic)
  235.     char *topic;
  236. /* Displays help on the given topic.  This consists of looking up the
  237.  * help file associated to this topic and displaying the contents of this
  238.  * file on the screen.  If the topic string is empty, then displays first
  239.  * the contents of the main topic file, and then displays a list of the
  240.  * topics.  If there is no help on the given topic, then displays a list
  241.  * of topics.
  242.  */
  243. {
  244.     help_entry he;
  245.     char line_buf[81];
  246.  
  247.     if (main_topic == NULL)
  248.         return;
  249.  
  250.     Suspend_Comment_Display ();
  251.         clear_screen ();
  252.     if (strlen(topic) == 0) {
  253.         display_help_entry (main_topic);
  254.                 display_topics ("Here is a list of available topics: ");
  255.     } else if ((he = find_help_topic(topic)) != NULL)
  256.         display_help_entry (he);
  257.     else {
  258.         sprintf (line_buf, "%s  %s",
  259.          "There is no help for this topic.",
  260.          "The available topics are");
  261.         display_topics (line_buf);
  262.     };
  263.     Continue_Comment_Display ();
  264.  
  265. };
  266.