home *** CD-ROM | disk | FTP | other *** search
- /*
- * mkwhatis - read/print "SEE ALSO" or NAME section of unformatted manpage
- *
- * finds .SH "SEE ALSO" or .SH NAME line and prints next line(s) until
- * either EOF or first char of line is '.'
- *
- * this is a tool to help build the whatis(1) databases. the idea is
- * to feed it a list of manpages (source form). it does a reasonable
- * job, but is not perfect. you may have to do some editing...
- *
- * the format for each line of the whatis databases is:
- *
- * name%aliases%section%subsection%description%xrefs%keywords
- *
- * name program/routine/etc name. (required)
- * alias if this sources another manpage or refered by another
- * name. a comma-separated list. (optional)
- * section number [0-9nlo] (required)
- * subsection single capital letter (optional)
- * description what this is, ascii string (required)
- * xref basically "SEE ALSO". a comma-separated list (optional)
- * keywords any descriptive keywords. comma-sep list (optional)
- *
- * optional fields contain only a '_' char.
- *
- * here is an example:
- *
- * unixmode%_%5%_%Extended Filename Standard%tcsh(1),sh(1)%TOS,MiNT,file,glob,links,shell,standard
- *
- * it assumes manpage (src) that look like this:
- *
- * .TH FOO 1X <-- gives section, subsection
- * .SH NAME
- * foo \- blah blah blah <-- gives name, desc
- * .SH DESCIPTION
- * .
- * .
- * .
- * .SH "SEE ALSO"
- * bar(1), foobar(5) <-- gives xref
- * .SH SOMETHING (or eof)
- *
- * or
- * .TH FOO 1 LOCAL <-- gives section, subsection
- * .
- * .
- * .
- *
- * it does NOT handle sourced files (aliases), ie:
- *
- * .so man1/foo.1
- *
- * at a minimum, you will have to add keywords yourself.
- */
-
- static char *rcsid_mkwhatis_c = "$Id: mkwhatis.c,v 2.0 1992/09/13 05:02:44 rosenkra Exp $";
- /*
- * $Log: mkwhatis.c,v $
- * Revision 2.0 1992/09/13 05:02:44 rosenkra
- * total rewrite. this if first rev of this file.
- *
- *
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
- #define EOS '\0'
- #define NL '\n'
- #define CR '\r'
- #define TAB '\t'
- #define SPC ' '
- #define DOT '.'
- #define DASH '-'
-
-
- #define NAME "NAME"
- #define SEE_ALSO "SEE ALSO"
- #define SEE_ALSO_Q "\"SEE ALSO"
-
-
- #define PR_NULL_FIELD printf("%%_");
-
-
- #define B_SIZE 1024
-
-
- char buf[B_SIZE];
- FILE *stream;
-
-
- void read_xref (void);
- char *skipwhite (char *);
- char *skipword (char *);
- char *finddash (char *);
- void kill_newline (char *);
-
-
- void main (int argc, char *argv[])
- {
- char *ps;
- int sec;
- int subsec;
- int got_xref = 0;
- int got_name = 0;
-
-
-
- for (argc--, argv++; argc && **argv == '-'; argc--, argv++)
- {
- switch (*(*argv+1))
- {
- default:
- fprintf (stderr,
- "usage: mkwhatis [-A | -N | -S | -B] file...\n");
- exit (1);
- }
- }
-
-
- /*
- * args are manpage source files
- */
- for ( ; argc && *argv; argc--, argv++)
- {
- if ((stream = fopen (*argv, "r")) == (FILE *) NULL)
- {
- fprintf (stderr,
- "mkwhatis: could not open %s\n", *argv);
- continue;
- }
-
-
- got_xref = 0;
- got_name = 0;
-
- while (1)
- {
- fgets (buf, B_SIZE-1, stream);
- if (feof (stream))
- {
- /* if we exit loop here, things were probably
- ok, but there was no SEE ALSO. put out
- an appropriate ending... */
-
- if (got_name && !got_xref)
- printf ("%%_%%_\n");
- else
- printf ("\n");
-
- goto next1; /* ERROR? */
- }
- kill_newline (buf);
-
-
- /*
- * look for .TH or .SH
- */
- if (buf[0] != DOT)
- continue;
- if (buf[1] == 'T' && buf[2] == 'H')
- {
- ps = buf;
-
- /* skip .TH */
- if ((ps = skipword (ps)) && *ps == EOS)
- goto next1; /* ERROR */
- if ((ps = skipwhite (ps)) && *ps == EOS)
- goto next1; /* ERROR */
-
- /* skip FOO */
- if ((ps = skipword (ps)) && *ps == EOS)
- goto next1; /* ERROR */
- if ((ps = skipwhite (ps)) && *ps == EOS)
- goto next1; /* ERROR */
-
- if (*ps)
- sec = *ps;
- else
- sec = '1'; /* assume */
-
- subsec = EOS; /* none */
-
- /* skip sect */
- if ((ps = skipword (ps)) && *ps == EOS)
- continue;
- if ((ps = skipwhite (ps)) && *ps == EOS)
- continue;
-
- if (*ps)
- subsec = *ps;
-
- }
- else if (buf[1] == 'S' && buf[2] == 'H')
- {
- ps = buf;
-
- /* skip .SH */
- if ((ps = skipword (ps)) && *ps == EOS)
- goto next1; /* ERROR */
- if ((ps = skipwhite (ps)) && *ps == EOS)
- goto next1; /* ERROR */
-
- if (!strncmp (ps, NAME, 4))
- {
- char *dsh;
-
- fgets (buf, B_SIZE-1, stream);
- if (feof (stream))
- {
- goto next1; /* ERROR */
- }
- kill_newline (buf);
-
- ps = buf;
-
- if ((ps = finddash (ps)) && *ps == EOS)
- goto next1; /* ERROR */
-
- /* skip past dash to desc */
- dsh = ps;
- if ((ps = skipword (ps)) && *ps == EOS)
- goto next1; /* ERROR */
- if ((ps = skipwhite (ps)) && *ps == EOS)
- goto next1; /* ERROR */
-
- /* find end of name, going backwards
- from dash */
- if (dsh[-1] == '\\')
- dsh--;
-
- while (dsh > buf
- && (dsh[-1] == SPC || dsh[-1] == TAB))
- dsh--;
- *dsh = EOS;
-
- /* check for name */
- if (buf[0] == EOS)
- goto next1; /* ERROR */
-
- printf ("%s", buf); /* name */
-
- PR_NULL_FIELD; /* alias */
-
- printf ("%%%c", sec); /* section */
-
- if (subsec) /* subsect */
- printf ("%%%c", subsec);
- else
- PR_NULL_FIELD;
-
- if (ps && *ps) /* desc */
- printf ("%%%s", ps);
- else
- PR_NULL_FIELD;
-
- got_name = 1;
- }
- else if (strncmp (ps, SEE_ALSO, 8) == 0
- || strncmp (ps, SEE_ALSO_Q, 9) == 0)
- {
- got_xref = 1;
- printf ("%%"); /* xref */
-
- read_xref ();
-
- break; /* normal exit! */
- }
- }
- }
- if (!got_xref)
- PR_NULL_FIELD; /* xref */
-
- PR_NULL_FIELD; /* keywords */
- printf ("\n");
- next1: ;
- fclose(stream);
- }
- exit(0);
- }
-
-
-
- /*------------------------------*/
- /* read_xref */
- /*------------------------------*/
- void read_xref (void)
- {
- char *ps;
-
- while (1)
- {
- fgets (buf, B_SIZE-1, stream);
- if (feof (stream) || buf[0] == '.')
- return;
- kill_newline (buf);
-
- /* fputs (buf, stdout);*/
- for (ps = buf; *ps; ps++)
- {
- if (*ps == SPC)
- continue;
- putchar (*ps);
- }
- }
- return;
- }
-
-
-
- /*------------------------------*/
- /* skipwhite */
- /*------------------------------*/
- char *skipwhite (char *ps)
- {
- while (*ps && (*ps == SPC || *ps == TAB))
- ps++;
- return (ps);
- }
-
-
-
- /*------------------------------*/
- /* skipword */
- /*------------------------------*/
- char *skipword (char *ps)
- {
- while (*ps && (*ps != SPC && *ps != TAB))
- ps++;
- return (ps);
- }
-
-
-
- /*------------------------------*/
- /* finddash */
- /*------------------------------*/
- char *finddash (char *ps)
- {
- while (*ps && *ps != DASH)
- ps++;
- return (ps);
- }
-
-
-
- /*------------------------------*/
- /* kill_newline */
- /*------------------------------*/
- void kill_newline (char *ps)
- {
- while (*ps)
- {
- if (*ps == NL || *ps == CR)
- {
- *ps = EOS;
- return;
- }
- ps++;
- }
- return;
- }
-
-
-