home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / forth / pfe-0.000 / pfe-0 / pfe-0.9.13 / src / showhelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-17  |  5.0 KB  |  248 lines

  1. /*
  2.  * This file is part of the portable Forth environment written in ANSI C.
  3.  * Copyright (C) 1995  Dirk Uwe Zoller
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Library General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13.  * See the GNU Library General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Library General Public
  16.  * License along with this library; if not, write to the Free
  17.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  * This file is version 0.9.13 of 17-July-95
  20.  * Check for the latest version of this package via anonymous ftp at
  21.  *    roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
  22.  * or    sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
  23.  * or    ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
  24.  *
  25.  * Please direct any comments via internet to
  26.  *    duz@roxi.rz.fht-mannheim.de.
  27.  * Thank You.
  28.  */
  29. /*
  30.  * showhelp.c --- access help files using an index created by helpindex
  31.  * (duz 13Sep94)
  32.  */
  33.  
  34. #if defined STANDALONE
  35. #include "config.h"
  36. #include "const.h"
  37. #include "options.h"
  38. #define OUTS(S) fputs (S, stdout)
  39. #else
  40. #include "forth.h"
  41. #include "support.h"
  42. #define OUTS(S) outs (S)
  43. #endif
  44.  
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48.  
  49. #include "missing.h"        /* SEEK_SET */
  50. #include "help.h"
  51.  
  52.  
  53. typedef char Path[PATH_LENGTH];
  54. static Path path;        /* common path name to all help files */
  55. static Path *file;        /* file names of help files */
  56.  
  57. static HHeader hheader;
  58. static HRecord *hrecord = NULL;
  59.  
  60. /*
  61.  * Read the index file.
  62.  */
  63.  
  64. void
  65. read_help_index (const char *pn, const char *fn)
  66. /*
  67.  * Read an index from a file. The file name is concatenated from pn and fn.
  68.  * pn is preserved and used to access files referred to in the header of
  69.  * the index.
  70.  */
  71. {
  72.   Path buf;
  73.   FILE *index;
  74.  
  75.   strcpy (path, pn);
  76.   sprintf (buf, "%s/%s", pn, fn);
  77.   index = fopen (buf, "rb");
  78.  
  79.   if (index == NULL)
  80.     {
  81. #if defined STANDALONE
  82.       file_errorz (fn);
  83. #else
  84.       return;
  85. #endif
  86.     }
  87.   if (fread (&hheader, sizeof hheader, 1, index) != 1)
  88.     file_errorz (fn);
  89.   if (strncmp (hheader.magic, "HELP", 4) != 0)
  90.     fatal ("%s is no help index file", fn);
  91.   file = (Path *) xalloc (sizeof (Path) * hheader.nfiles);
  92.  
  93.   if (fread (file, sizeof *file, hheader.nfiles, index)
  94.       != hheader.nfiles)
  95.     file_errorz (fn);
  96.   hrecord = (HRecord *) xalloc (sizeof (HRecord) * hheader.nitems);
  97.  
  98.   if (fread (hrecord, sizeof *hrecord, hheader.nitems, index)
  99.       != hheader.nitems)
  100.     file_errorz (fn);
  101.   fclose (index);
  102. }
  103.  
  104. /*
  105.  * Access a help string using the index.
  106.  */
  107.  
  108. static HRecord *
  109. binary_search (const char *name, HRecord *p, int n)
  110. {
  111.   int l = 0;
  112.   int r = n - 1;
  113.  
  114.   for (;;)
  115.     {
  116.       int i = (l + r) >> 1;
  117.       int x = strcmp (name, p[i].name);
  118.  
  119.       if (x == 0)
  120.     return &p[i];
  121.       if (x < 0)
  122.     r = i - 1;
  123.       else
  124.     l = i + 1;
  125.       if (l > r)
  126.     return NULL;
  127.     }
  128. }
  129.  
  130. void
  131. print_help (const char *name)
  132. {
  133.   HRecord *p;
  134.  
  135. #if !defined STANDALONE
  136.   if (hrecord == NULL)
  137.     abortq ("no help strings loaded");
  138. #endif
  139.   p = binary_search (name, hrecord, hheader.nitems);
  140.   if (p == NULL)
  141.     printf ("No help for %s available.\n", name);
  142.   else
  143.     {
  144.       Path fn;
  145.       FILE *f;
  146.       char line[0x80];
  147.       int empty;
  148.  
  149.       sprintf (fn, "%s/%s", path, file[p->fidx]);
  150.       f = fopen (fn, "r");
  151.       if (f == NULL)
  152.     file_errorz (fn);
  153.       if (fseek (f, p->pos, SEEK_SET) != 0)
  154.     file_errorz (fn);
  155.  
  156.       fgets (line, sizeof line, f);
  157.       fputs (line + 2, stdout);
  158.       empty = 0;
  159.  
  160.       for (;;)
  161.     {
  162.       if (!fgets (line, sizeof line, f))
  163.         if (ferror (f))
  164.           file_errorz (fn);
  165.         else
  166.           return;
  167.       if (line[0] == '\n' || line[0] == '#')
  168.         {
  169.           if (++empty == 2)
  170.         return;
  171.         }
  172.       else
  173.         empty = 0;
  174.       if (line[0] != '#')
  175.         fputs (line, stdout);
  176.     }
  177.     }
  178. }
  179.  
  180. #if defined STANDALONE
  181. /*
  182.  * Main program, process command line.
  183.  */
  184.  
  185. static char *
  186. pathname (char *pn, const char *name)
  187. {
  188.   char *p = strrchr (name, DIR_DELIMITER);
  189.  
  190.   if (p)
  191.     {
  192.       int l = ++p - name;
  193.  
  194.       memcpy (pn, name, l);
  195.       pn[l] = '\0';
  196.     }
  197.   else
  198.     *pn = '\0';
  199.   return pn;
  200. }
  201.  
  202. static char *
  203. filename (char *fn, const char *name)
  204. {
  205.   char *p = strrchr (name, DIR_DELIMITER);
  206.  
  207.   if (p)
  208.     strcpy (fn, ++p);
  209.   else
  210.     *fn = '\0';
  211.   return fn;
  212. }
  213.  
  214. static void
  215. usage (void)
  216. {
  217.   fatal ("usage: %s file word [word...]", progname);
  218. }
  219.  
  220. int
  221. main (int argc, char *argv[])
  222. {
  223.   Path pn, fn;
  224.   int i;
  225.  
  226.   /*
  227.    * get program name for error messages
  228.    */
  229.   progname = strrchr (argv[0], '/');
  230.   if (progname)
  231.     progname++;
  232.   else
  233.     progname = argv[0];
  234.   if (argc < 3)
  235.     usage ();
  236.  
  237.   /*
  238.    * process
  239.    */
  240.   pathname (pn, argv[1]);
  241.   filename (fn, argv[1]);
  242.   read_help_index (pn, fn);
  243.   for (i = 2; i < argc; i++)
  244.     print_help (argv[i]);
  245.   return 0;
  246. }
  247. #endif
  248.