home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of the portable Forth environment written in ANSI C.
- * Copyright (C) 1995 Dirk Uwe Zoller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This file is version 0.9.13 of 17-July-95
- * Check for the latest version of this package via anonymous ftp at
- * roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
- * or sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
- * or ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
- *
- * Please direct any comments via internet to
- * duz@roxi.rz.fht-mannheim.de.
- * Thank You.
- */
- /*
- * showhelp.c --- access help files using an index created by helpindex
- * (duz 13Sep94)
- */
-
- #if defined STANDALONE
- #include "config.h"
- #include "const.h"
- #include "options.h"
- #define OUTS(S) fputs (S, stdout)
- #else
- #include "forth.h"
- #include "support.h"
- #define OUTS(S) outs (S)
- #endif
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "missing.h" /* SEEK_SET */
- #include "help.h"
-
-
- typedef char Path[PATH_LENGTH];
- static Path path; /* common path name to all help files */
- static Path *file; /* file names of help files */
-
- static HHeader hheader;
- static HRecord *hrecord = NULL;
-
- /*
- * Read the index file.
- */
-
- void
- read_help_index (const char *pn, const char *fn)
- /*
- * Read an index from a file. The file name is concatenated from pn and fn.
- * pn is preserved and used to access files referred to in the header of
- * the index.
- */
- {
- Path buf;
- FILE *index;
-
- strcpy (path, pn);
- sprintf (buf, "%s/%s", pn, fn);
- index = fopen (buf, "rb");
-
- if (index == NULL)
- {
- #if defined STANDALONE
- file_errorz (fn);
- #else
- return;
- #endif
- }
- if (fread (&hheader, sizeof hheader, 1, index) != 1)
- file_errorz (fn);
- if (strncmp (hheader.magic, "HELP", 4) != 0)
- fatal ("%s is no help index file", fn);
- file = (Path *) xalloc (sizeof (Path) * hheader.nfiles);
-
- if (fread (file, sizeof *file, hheader.nfiles, index)
- != hheader.nfiles)
- file_errorz (fn);
- hrecord = (HRecord *) xalloc (sizeof (HRecord) * hheader.nitems);
-
- if (fread (hrecord, sizeof *hrecord, hheader.nitems, index)
- != hheader.nitems)
- file_errorz (fn);
- fclose (index);
- }
-
- /*
- * Access a help string using the index.
- */
-
- static HRecord *
- binary_search (const char *name, HRecord *p, int n)
- {
- int l = 0;
- int r = n - 1;
-
- for (;;)
- {
- int i = (l + r) >> 1;
- int x = strcmp (name, p[i].name);
-
- if (x == 0)
- return &p[i];
- if (x < 0)
- r = i - 1;
- else
- l = i + 1;
- if (l > r)
- return NULL;
- }
- }
-
- void
- print_help (const char *name)
- {
- HRecord *p;
-
- #if !defined STANDALONE
- if (hrecord == NULL)
- abortq ("no help strings loaded");
- #endif
- p = binary_search (name, hrecord, hheader.nitems);
- if (p == NULL)
- printf ("No help for %s available.\n", name);
- else
- {
- Path fn;
- FILE *f;
- char line[0x80];
- int empty;
-
- sprintf (fn, "%s/%s", path, file[p->fidx]);
- f = fopen (fn, "r");
- if (f == NULL)
- file_errorz (fn);
- if (fseek (f, p->pos, SEEK_SET) != 0)
- file_errorz (fn);
-
- fgets (line, sizeof line, f);
- fputs (line + 2, stdout);
- empty = 0;
-
- for (;;)
- {
- if (!fgets (line, sizeof line, f))
- if (ferror (f))
- file_errorz (fn);
- else
- return;
- if (line[0] == '\n' || line[0] == '#')
- {
- if (++empty == 2)
- return;
- }
- else
- empty = 0;
- if (line[0] != '#')
- fputs (line, stdout);
- }
- }
- }
-
- #if defined STANDALONE
- /*
- * Main program, process command line.
- */
-
- static char *
- pathname (char *pn, const char *name)
- {
- char *p = strrchr (name, DIR_DELIMITER);
-
- if (p)
- {
- int l = ++p - name;
-
- memcpy (pn, name, l);
- pn[l] = '\0';
- }
- else
- *pn = '\0';
- return pn;
- }
-
- static char *
- filename (char *fn, const char *name)
- {
- char *p = strrchr (name, DIR_DELIMITER);
-
- if (p)
- strcpy (fn, ++p);
- else
- *fn = '\0';
- return fn;
- }
-
- static void
- usage (void)
- {
- fatal ("usage: %s file word [word...]", progname);
- }
-
- int
- main (int argc, char *argv[])
- {
- Path pn, fn;
- int i;
-
- /*
- * get program name for error messages
- */
- progname = strrchr (argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
- if (argc < 3)
- usage ();
-
- /*
- * process
- */
- pathname (pn, argv[1]);
- filename (fn, argv[1]);
- read_help_index (pn, fn);
- for (i = 2; i < argc; i++)
- print_help (argv[i]);
- return 0;
- }
- #endif
-