home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
utility
/
whatis20.zoo
/
mkwhatis.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-13
|
7KB
|
366 lines
/*
* 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;
}