home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume14 / okbridge2 / part12 / help.c < prev    next >
C/C++ Source or Header  |  1993-01-27  |  8KB  |  332 lines

  1. /* help.c -- help functions for the bridge program.
  2.  *
  3.  ! Copyright (C) 1990-1992 by Matthew Clegg.  All Rights Reserved
  4.  ! 
  5.  ! OKbridge is made available as a free service to the Internet.
  6.  ! Accordingly, the following restrictions are placed on its use:
  7.  ! 
  8.  ! 1.  OKbridge may not be modified in any way without the explicit 
  9.  !     permission of Matthew Clegg.  
  10.  ! 
  11.  ! 2.  OKbridge may not be used in any way for commercial advantage.
  12.  !     It may not be placed on for-profit networks or on for-profit
  13.  !     computer systems.  It may not be bundled as part of a package
  14.  !     or service provided by a for-profit organization.
  15.  ! 
  16.  ! If you have questions about restrictions on the use of OKbridge,
  17.  ! write to mclegg@cs.ucsd.edu.
  18.  ! 
  19.  ! DISCLAIMER:  The user of OKbridge accepts full responsibility for any
  20.  ! damage which may be caused by OKbridge.
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27.  
  28. #ifndef SEEK_SET
  29. #define SEEK_SET  0
  30. #endif
  31.  
  32. #include "types.h"
  33. #include "input.h"
  34. #include "terminal.h"
  35. #include "display.h"
  36.  
  37. /* char *help_file_name = "okbridge.help"; */
  38. #include "helpfile.h"
  39.  
  40. extern strcasecmp (), fseek ();
  41.  
  42. extern int errno;
  43. extern char *sys_errlist[];
  44. extern char *strdup();
  45. extern char *getenv ();
  46. extern char *malloc ();
  47. extern int  input_help_topic ();
  48.  
  49.  
  50. typedef struct help_entry_struct {
  51.     char    *topic;
  52.     char    *description;
  53.     long int file_offset;
  54.     struct help_entry_struct *next;
  55. } *help_entry;
  56.  
  57. static help_entry main_topic = NULL;
  58. FILE *help_file = NULL;
  59.  
  60. long int current_page = -1;
  61.   /* The offset into the help file of the current page being displayed,
  62.      or -1 if we are not displaying any page. */
  63.  
  64.  
  65. void display_topics (message)
  66.     char *message;
  67. /* Displays the list of topics, with the given message as the top line.
  68.  . Does not display the main topic.
  69.  */
  70. {
  71.     int i;
  72.     help_entry e;
  73.     char msg_buf[80];
  74.  
  75.     clear_screen ();
  76.     print (1,1,message);
  77.     if (main_topic == NULL) {
  78.         print (3,1,"The help system is empty.");
  79.     } else {
  80.         i = 3;
  81.         for (e = main_topic->next; e != NULL; e = e->next) {
  82.           if (strcasecmp(e->topic, "slam")) {
  83.             sprintf (msg_buf, "%-10s -- %s",e->topic,
  84.                 e->description);
  85.             print (i++, 1, msg_buf);
  86.               }
  87.         }
  88.     }
  89. }
  90.  
  91. static int read_help_line (buf, buflen)
  92.     char *buf; int buflen;
  93. /* Reads a line from the help file.  Returns the number of characters
  94.    read of -1 if EOF is encountered.  Skips lines beginning with a '#'. 
  95. */
  96. {
  97.     int i, ch;
  98.  
  99.     do {
  100.         ch = getc(help_file);
  101.         i = 0;
  102.         while ((ch != '\n') && (ch != EOF)) {
  103.             if (i < buflen-1) buf[i++] = ch;
  104.             ch = getc(help_file);
  105.         }
  106.         buf[i] = '\0';
  107.         if (ch == EOF) return (-1);
  108.         while ((i > 0) && isspace(buf[i-1])) buf[--i] = '\0';
  109.     } while (buf[0] == '#');
  110.     return (i);
  111. }
  112.  
  113. static void display_help_entry (e)
  114.     help_entry e;
  115. /* Displays the help_entry e. */
  116. {
  117.     char line[81];
  118.     int lines_on_page, log;
  119.  
  120.     lines_on_page = 0;
  121.     current_page = e->file_offset;
  122.     fseek (help_file, e->file_offset, SEEK_SET);
  123.     log = read_help_line (line, 81);
  124.     while ((log >= 0) && strcmp(line, "--")) {
  125.         if ((lines_on_page > terminal_lines-2) || (line[0] == '^')) {
  126.                 Press_Return_to_Continue ("");
  127.             current_page = ftell (help_file);
  128.             clear_screen ();
  129.             lines_on_page = 0;
  130.              if (line[0] == '^') line[0] = ' ';
  131.         }
  132.         print (++lines_on_page, 1, line);
  133.         log = read_help_line (line, 81);
  134.     }
  135.     Press_Return_to_Continue ("");
  136. }
  137.  
  138. static FILE *open_helpfile ()
  139. /* Tries to open the helpfile with given name from the help_directory.
  140.  * If an error, prints an error message and returns NULL.  Otherwise,
  141.  * returns a pointer to the opened file.
  142.  */
  143. {
  144.     char filename_buf [80], msg_buf[80], *envhelpdir;
  145.     FILE *fp;
  146.  
  147.     if ((envhelpdir = getenv("OKBRIDGE_HELPFILE")) != NULL)
  148.         sprintf (filename_buf, "%s", envhelpdir);
  149.     else
  150.         sprintf (filename_buf, "%s", help_file_name);
  151.  
  152.     fp = fopen (filename_buf, "r");
  153.     if (fp == NULL)
  154.         fp = fopen ("okbridge.help", "r");
  155.  
  156.     if (fp == NULL) {
  157.         sprintf (msg_buf, "Error opening helpfile %s", filename_buf);
  158.         print (3, 1, msg_buf);
  159.         sprintf (msg_buf, "System reports error: %s",
  160.                 sys_errlist[errno]);
  161.         print (4, 1, msg_buf);
  162.         Press_Return_to_Continue ("");
  163.     }
  164.     return (fp);
  165. }
  166.  
  167.  
  168. static help_entry find_help_topic (topic)
  169.     char *topic;
  170. /* Looks for the help entry with the associated topic.  If it is found,
  171.  * returns a pointer to the corresponding record.  Otherwise, returns NULL.
  172.  */
  173. {
  174.     help_entry e;
  175.  
  176.     e = main_topic;
  177.     while (e != NULL) {
  178.         if (!strcasecmp(e->topic, topic))
  179.             return (e);
  180.         e = e->next;
  181.     }
  182.     return (e);
  183. }
  184.  
  185. static help_entry read_new_help_entry ()
  186. /* Reads a help entry from the help_file.  Allocates a help_entry record
  187.  . and records the pertinent information in that record.  Returns the
  188.  . allocated record or NULL if the end of file is reached.
  189.  */
  190. {
  191.     char line_buf[81];
  192.     help_entry e;
  193.     char *curpos, *keypos, *descpos;
  194.     int log;
  195.  
  196.     log = read_help_line (line_buf, 81);
  197.     if (log < 0)
  198.         return (NULL);
  199.  
  200.     for (keypos = line_buf; isspace(*keypos); keypos++);
  201.     for (curpos = keypos;(*curpos != '\0') && !isspace(*curpos);curpos++);
  202.     for (descpos = curpos; isspace(*descpos); descpos++);
  203.  
  204.     e = (help_entry) malloc(sizeof(struct help_entry_struct));
  205.     *curpos = '\0';
  206.     e->topic = strdup (keypos);
  207.     e->description = strdup (descpos);
  208.     e->file_offset = ftell (help_file);
  209.     e->next = NULL;
  210.  
  211.     do
  212.       log = read_help_line (line_buf, 81);
  213.     while 
  214.       ((log >= 0) && strcmp(line_buf, "--"));
  215.  
  216.     return (e);
  217.  
  218. }
  219.  
  220.  
  221. void initialize_help_system ()
  222. /* Called once at the beginning of the program to read the file of help
  223.  * topics.
  224.  */
  225. {
  226.     help_entry e;
  227.  
  228.     help_file = open_helpfile ();
  229.     if (help_file == NULL) return;
  230.  
  231.     e = main_topic = read_new_help_entry ();
  232.     while (e != NULL) {
  233.         e->next = read_new_help_entry ();
  234.         e = e->next;
  235.     }
  236.  
  237. }
  238.  
  239. void Browse_help_topics ();
  240.  
  241. void display_help (topic)
  242.     char *topic;
  243. /* Displays help on the given topic.  This consists of looking up the
  244.  * help file associated to this topic and displaying the contents of this
  245.  * file on the screen.  If the topic string is empty, then displays first
  246.  * the contents of the main topic file, and then displays a list of the
  247.  * topics.  If there is no help on the given topic, then displays a list
  248.  * of topics.
  249.  */
  250. {
  251.   help_entry he;
  252.   char line_buf[81];
  253.   
  254.   if (main_topic == NULL)
  255.     return;
  256.   
  257.   clear_screen ();
  258.   if (strlen(topic) == 0) {
  259.     display_help_entry (main_topic);
  260.   } else if ((he = find_help_topic(topic)) != NULL)
  261.     display_help_entry (he);
  262.   else {
  263.     sprintf (line_buf, "%s  %s",
  264.          "There is no help for this topic.",
  265.          "The available topics are");
  266.     display_topics (line_buf);
  267.     Press_Return_to_Continue ("");
  268.   }
  269.   
  270. }
  271.  
  272. void browse_help (topic)
  273.      char *topic;
  274. /* Displays help on the given topic.  Afterwards, displays a list of
  275.  * topics along with a request to enter the name of a new topic.
  276.  */
  277. {
  278.   help_entry he;
  279.   char line_buf[81];
  280.   int no_topic = 0;
  281.   
  282.   if (main_topic == NULL)
  283.     return;
  284.   
  285.   clear_screen ();
  286.   if (strlen(topic) == 0) {
  287.     display_help_entry (main_topic);
  288.   } else if ((he = find_help_topic(topic)) != NULL)
  289.     display_help_entry (he);
  290.   else 
  291.     no_topic = 1;
  292.   
  293.   display_topics ("LIST OF HELP TOPICS");
  294.   print (terminal_lines-1, 1, "HELP");
  295.   Refresh_Status_Display ();
  296.   
  297.   if (no_topic) {
  298.     sprintf (line_buf, "THERE IS NO HELP FOR THE TOPIC %s", topic);
  299.     print (terminal_lines-2, 1, line_buf);
  300.     ring_bell ();
  301.   }
  302. }
  303.  
  304. void Refresh_Help_Display ()
  305. /* Redisplays the current screen of help information. */
  306. {
  307.   char line[81];
  308.   int lines_on_page, log;
  309.  
  310.   if (current_page < 0) {
  311.     display_topics ("LIST OF HELP TOPICS");
  312.     return;
  313.   }
  314.   
  315.   lines_on_page = 0;
  316.   fseek (help_file, current_page, SEEK_SET);
  317.   log = read_help_line (line, 81);
  318.   while ((log >= 0) && strcmp(line, "--")) {
  319.     if ((lines_on_page > terminal_lines-2) || (line[0] == '^'))
  320.       return;
  321.     print (++lines_on_page, 1, line);
  322.     log = read_help_line (line, 81);
  323.   }
  324.   
  325. }
  326.  
  327. void Clear_Help_Display ()
  328. /* Returns the help system to its initial state. */
  329. {
  330.   current_page = -1;
  331. }
  332.