Invoke "nroff" and parse its output if an unformatted manual page uses
macros. Fixes PR bin/9083 by Geoff C. Wing.
This commit is contained in:
parent
1cfb5e6456
commit
93cb6f8300
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: makewhatis.c,v 1.7 2000/01/24 23:03:54 tron Exp $ */
|
/* $NetBSD: makewhatis.c,v 1.8 2000/07/09 23:07:14 tron Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||||
|
@ -43,17 +43,20 @@ __COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\n\
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: makewhatis.c,v 1.7 2000/01/24 23:03:54 tron Exp $");
|
__RCSID("$NetBSD: makewhatis.c,v 1.8 2000/07/09 23:07:14 tron Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fts.h>
|
#include <fts.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -74,6 +77,7 @@ struct whatisstruct {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main (int, char **);
|
int main (int, char **);
|
||||||
|
void sigchildhandler(int);
|
||||||
char *findwhitespace(char *);
|
char *findwhitespace(char *);
|
||||||
char *GetS(gzFile, char *, int);
|
char *GetS(gzFile, char *, int);
|
||||||
int manpagesection (char *);
|
int manpagesection (char *);
|
||||||
|
@ -83,6 +87,7 @@ char *replacestring (char *, char *, char *);
|
||||||
void catpreprocess (char *);
|
void catpreprocess (char *);
|
||||||
char *parsecatpage (gzFile *);
|
char *parsecatpage (gzFile *);
|
||||||
int manpreprocess (char *);
|
int manpreprocess (char *);
|
||||||
|
char *nroff (gzFile *);
|
||||||
char *parsemanpage (gzFile *, int);
|
char *parsemanpage (gzFile *, int);
|
||||||
char *getwhatisdata (char *);
|
char *getwhatisdata (char *);
|
||||||
void processmanpages (manpage **,whatis **);
|
void processmanpages (manpage **,whatis **);
|
||||||
|
@ -109,6 +114,7 @@ main(int argc,char **argv)
|
||||||
FILE *out;
|
FILE *out;
|
||||||
|
|
||||||
(void)setlocale(LC_ALL, "");
|
(void)setlocale(LC_ALL, "");
|
||||||
|
(void)signal(SIGCHLD, sigchildhandler);
|
||||||
|
|
||||||
manpath = (argc < 2) ? default_manpath : &argv[1];
|
manpath = (argc < 2) ? default_manpath : &argv[1];
|
||||||
|
|
||||||
|
@ -135,7 +141,7 @@ main(int argc,char **argv)
|
||||||
default:
|
default:
|
||||||
errx(EXIT_FAILURE, "%s: %s", fe->fts_path,
|
errx(EXIT_FAILURE, "%s: %s", fe->fts_path,
|
||||||
strerror(fe->fts_errno));
|
strerror(fe->fts_errno));
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +164,13 @@ main(int argc,char **argv)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sigchildhandler(int signum)
|
||||||
|
|
||||||
|
{
|
||||||
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
*findwhitespace(char *str)
|
*findwhitespace(char *str)
|
||||||
|
|
||||||
|
@ -447,6 +460,79 @@ manpreprocess(char *line)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
nroff(gzFile *in)
|
||||||
|
{
|
||||||
|
char tempname[MAXPATHLEN], buffer[8192], *data;
|
||||||
|
int tempfd, bytes, pipefd[2];
|
||||||
|
pid_t child;
|
||||||
|
|
||||||
|
if (gzrewind(in) < 0) {
|
||||||
|
perror(__progname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)strcpy(tempname, _PATH_TMP "makewhatis.XXXXXX");
|
||||||
|
if ((tempfd = mkstemp(tempname)) < 0) {
|
||||||
|
perror(__progname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((bytes = gzread(in, buffer, sizeof(buffer))) > 0)
|
||||||
|
if (write(tempfd, buffer, bytes) != bytes) {
|
||||||
|
bytes = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bytes < 0) ||
|
||||||
|
(lseek(tempfd, 0, SEEK_SET) < 0) ||
|
||||||
|
(pipe(pipefd) < 0)) {
|
||||||
|
perror(__progname);
|
||||||
|
(void)close(tempfd);
|
||||||
|
(void)unlink(tempname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (child = vfork()) {
|
||||||
|
case -1:
|
||||||
|
perror(__progname);
|
||||||
|
(void)close(pipefd[1]);
|
||||||
|
(void)close(pipefd[0]);
|
||||||
|
(void)close(tempfd);
|
||||||
|
(void)unlink(tempname);
|
||||||
|
return NULL;
|
||||||
|
/* NOTREACHED */
|
||||||
|
case 0:
|
||||||
|
(void)close(pipefd[0]);
|
||||||
|
if (pipefd[1] != STDOUT_FILENO) {
|
||||||
|
(void)dup2(pipefd[1], STDOUT_FILENO);
|
||||||
|
(void)close(pipefd[1]);
|
||||||
|
}
|
||||||
|
(void)execlp("nroff", "nroff", "-mandoc", tempname, NULL);
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
default:
|
||||||
|
(void)close(pipefd[1]);
|
||||||
|
(void)close(tempfd);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((in = gzdopen(pipefd[0], "r")) == NULL) {
|
||||||
|
if (errno == 0)
|
||||||
|
errno = ENOMEM;
|
||||||
|
perror(__progname);
|
||||||
|
(void)close(pipefd[0]); /* Child will be killed by SIGPIPE. */
|
||||||
|
(void)unlink(tempname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = parsecatpage(in);
|
||||||
|
|
||||||
|
(void)gzclose(in); /* Child will be killed by SIGPIPE. */
|
||||||
|
(void)unlink(tempname);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
parsemanpage(gzFile *in, int defaultsection)
|
parsemanpage(gzFile *in, int defaultsection)
|
||||||
{
|
{
|
||||||
|
@ -480,6 +566,8 @@ parsemanpage(gzFile *in, int defaultsection)
|
||||||
(void) strcat(§ion[2], ") - ");
|
(void) strcat(§ion[2], ") - ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strncasecmp(buffer, ".Ds", 3) == 0)
|
||||||
|
return nroff(in);
|
||||||
} while ((strncasecmp(buffer, ".Sh NAME", 8) != 0));
|
} while ((strncasecmp(buffer, ".Sh NAME", 8) != 0));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
Loading…
Reference in New Issue