=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.273.2.9 retrieving revision 1.274 diff -u -p -r1.273.2.9 -r1.274 --- mandoc/main.c 2017/02/21 17:04:04 1.273.2.9 +++ mandoc/main.c 2016/07/19 21:31:55 1.274 @@ -1,7 +1,7 @@ -/* $Id: main.c,v 1.273.2.9 2017/02/21 17:04:04 schwarze Exp $ */ +/* $Id: main.c,v 1.274 2016/07/19 21:31:55 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze + * Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -81,7 +81,9 @@ struct curparse { struct manoutput *outopts; /* output options */ }; + int mandocdb(int, char *[]); + static int fs_lookup(const struct manpaths *, size_t ipath, const char *, const char *, const char *, @@ -93,12 +95,11 @@ static int koptions(int *, char *); static int moptions(int *, char *); static void mmsg(enum mandocerr, enum mandoclevel, const char *, int, int, const char *); -static void outdata_alloc(struct curparse *); static void parse(struct curparse *, int, const char *); static void passthrough(const char *, int, int); static pid_t spawn_pager(struct tag_files *); static int toptions(struct curparse *, char *); -static void usage(enum argmode) __attribute__((__noreturn__)); +static void usage(enum argmode) __attribute__((noreturn)); static int woptions(struct curparse *, char *); static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; @@ -111,14 +112,16 @@ int main(int argc, char *argv[]) { struct manconf conf; - struct mansearch search; struct curparse curp; + struct mansearch search; struct tag_files *tag_files; - struct manpage *res, *resp; - const char *progname, *sec, *thisarg; - char *conf_file, *defpaths, *auxpaths; - char *defos, *oarg; + const char *progname; + char *auxpaths; + char *defos; unsigned char *uc; + struct manpage *res, *resp; + char *conf_file, *defpaths; + const char *sec; size_t i, sz; int prio, best_prio; enum outmode outmode; @@ -164,7 +167,6 @@ main(int argc, char *argv[]) memset(&search, 0, sizeof(struct mansearch)); search.outkey = "Nd"; - oarg = NULL; if (strcmp(progname, BINM_MAN) == 0) search.argmode = ARG_NAME; @@ -243,7 +245,10 @@ main(int argc, char *argv[]) auxpaths = optarg; break; case 'O': - oarg = optarg; + search.outkey = optarg; + while (optarg != NULL) + manconf_output(&conf.output, + strsep(&optarg, ",")); break; case 'S': search.arch = optarg; @@ -288,21 +293,6 @@ main(int argc, char *argv[]) } } - if (oarg != NULL) { - if (outmode == OUTMODE_LST) - search.outkey = oarg; - else { - while (oarg != NULL) { - thisarg = oarg; - if (manconf_output(&conf.output, - strsep(&oarg, ","), 0) == 0) - continue; - warnx("-O %s: Bad argument", thisarg); - return (int)MANDOCLEVEL_BADARG; - } - } - } - if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST || !isatty(STDOUT_FILENO)) @@ -355,9 +345,6 @@ main(int argc, char *argv[]) /* man(1), whatis(1), apropos(1) */ if (search.argmode != ARG_FILE) { - if (argc == 0) - usage(search.argmode); - if (search.argmode == ARG_NAME && outmode == OUTMODE_ONE) search.firstmatch = 1; @@ -365,10 +352,10 @@ main(int argc, char *argv[]) /* Access the mandoc database. */ manconf_parse(&conf, conf_file, defpaths, auxpaths); - mansearch_setup(1); if ( ! mansearch(&search, &conf.manpath, argc, argv, &res, &sz)) usage(search.argmode); + if (sz == 0) { if (search.argmode == ARG_NAME) fs_search(&search, &conf.manpath, @@ -470,7 +457,7 @@ main(int argc, char *argv[]) if (resp == NULL) parse(&curp, fd, *argv); - else if (resp->form & FORM_SRC) { + else if (resp->form == FORM_SRC) { /* For .so only; ignore failure. */ chdir(conf.manpath.paths[resp->ipath]); parse(&curp, fd, resp->file); @@ -478,11 +465,8 @@ main(int argc, char *argv[]) passthrough(resp->file, fd, conf.output.synopsisonly); - if (argc > 1 && curp.outtype <= OUTT_UTF8) { - if (curp.outdata == NULL) - outdata_alloc(&curp); + if (argc > 1 && curp.outtype <= OUTT_UTF8) terminal_sepline(curp.outdata); - } } else if (rc < MANDOCLEVEL_ERROR) rc = MANDOCLEVEL_ERROR; @@ -522,7 +506,6 @@ out: if (search.argmode != ARG_FILE) { manconf_free(&conf); mansearch_free(res, sz); - mansearch_setup(0); } free(defos); @@ -544,10 +527,10 @@ out: /* Stop here until moved to the foreground. */ - tc_pgid = tcgetpgrp(tag_files->ofd); + tc_pgid = tcgetpgrp(STDIN_FILENO); if (tc_pgid != man_pgid) { if (tc_pgid == pager_pid) { - (void)tcsetpgrp(tag_files->ofd, + (void)tcsetpgrp(STDIN_FILENO, man_pgid); if (signum == SIGTTIN) continue; @@ -560,7 +543,7 @@ out: /* Once in the foreground, activate the pager. */ if (pager_pid) { - (void)tcsetpgrp(tag_files->ofd, pager_pid); + (void)tcsetpgrp(STDIN_FILENO, pager_pid); kill(pager_pid, SIGCONT); } else pager_pid = spawn_pager(tag_files); @@ -626,7 +609,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath, glob_t globinfo; struct manpage *page; char *file; - int form, globres; + int globres; + enum form form; form = FORM_SRC; mandoc_asprintf(&file, "%s/man%s/%s.%s", @@ -738,9 +722,33 @@ parse(struct curparse *curp, int fd, const char *file) if (rctmp != MANDOCLEVEL_OK && curp->wstop) return; - if (curp->outdata == NULL) - outdata_alloc(curp); + /* If unset, allocate output dev now (if applicable). */ + if (curp->outdata == NULL) { + switch (curp->outtype) { + case OUTT_HTML: + curp->outdata = html_alloc(curp->outopts); + break; + case OUTT_UTF8: + curp->outdata = utf8_alloc(curp->outopts); + break; + case OUTT_LOCALE: + curp->outdata = locale_alloc(curp->outopts); + break; + case OUTT_ASCII: + curp->outdata = ascii_alloc(curp->outopts); + break; + case OUTT_PDF: + curp->outdata = pdf_alloc(curp->outopts); + break; + case OUTT_PS: + curp->outdata = ps_alloc(curp->outopts); + break; + default: + break; + } + } + mparse_result(curp->mp, &man, NULL); /* Execute the out device, if it exists. */ @@ -748,8 +756,7 @@ parse(struct curparse *curp, int fd, const char *file) if (man == NULL) return; if (man->macroset == MACROSET_MDOC) { - if (curp->outtype != OUTT_TREE || !curp->outopts->noval) - mdoc_validate(man); + mdoc_validate(man); switch (curp->outtype) { case OUTT_HTML: html_mdoc(curp->outdata, man); @@ -772,8 +779,7 @@ parse(struct curparse *curp, int fd, const char *file) } } if (man->macroset == MACROSET_MAN) { - if (curp->outtype != OUTT_TREE || !curp->outopts->noval) - man_validate(man); + man_validate(man); switch (curp->outtype) { case OUTT_HTML: html_man(curp->outdata, man); @@ -795,37 +801,9 @@ parse(struct curparse *curp, int fd, const char *file) break; } } - mparse_updaterc(curp->mp, &rc); } static void -outdata_alloc(struct curparse *curp) -{ - switch (curp->outtype) { - case OUTT_HTML: - curp->outdata = html_alloc(curp->outopts); - break; - case OUTT_UTF8: - curp->outdata = utf8_alloc(curp->outopts); - break; - case OUTT_LOCALE: - curp->outdata = locale_alloc(curp->outopts); - break; - case OUTT_ASCII: - curp->outdata = ascii_alloc(curp->outopts); - break; - case OUTT_PDF: - curp->outdata = pdf_alloc(curp->outopts); - break; - case OUTT_PS: - curp->outdata = ps_alloc(curp->outopts); - break; - default: - break; - } -} - -static void passthrough(const char *file, int fd, int synopsis_only) { const char synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"; @@ -835,17 +813,11 @@ passthrough(const char *file, int fd, int synopsis_onl const char *syscall; char *line, *cp; size_t linesz; - ssize_t len, written; int print; line = NULL; linesz = 0; - if (fflush(stdout) == EOF) { - syscall = "fflush"; - goto fail; - } - if ((stream = fdopen(fd, "r")) == NULL) { close(fd); syscall = "fdopen"; @@ -853,16 +825,14 @@ passthrough(const char *file, int fd, int synopsis_onl } print = 0; - while ((len = getline(&line, &linesz, stream)) != -1) { + while (getline(&line, &linesz, stream) != -1) { cp = line; if (synopsis_only) { if (print) { if ( ! isspace((unsigned char)*cp)) goto done; - while (isspace((unsigned char)*cp)) { + while (isspace((unsigned char)*cp)) cp++; - len--; - } } else { if (strcmp(cp, synb) == 0 || strcmp(cp, synr) == 0) @@ -870,11 +840,9 @@ passthrough(const char *file, int fd, int synopsis_onl continue; } } - for (; len > 0; len -= written) { - if ((written = write(STDOUT_FILENO, cp, len)) != -1) - continue; + if (fputs(cp, stdout)) { fclose(stream); - syscall = "write"; + syscall = "fputs"; goto fail; } } @@ -1017,8 +985,7 @@ mmsg(enum mandocerr t, enum mandoclevel lvl, { const char *mparse_msg; - fprintf(stderr, "%s: %s:", getprogname(), - file == NULL ? "" : file); + fprintf(stderr, "%s: %s:", getprogname(), file); if (line) fprintf(stderr, "%d:%d:", line, col + 1); @@ -1090,7 +1057,7 @@ spawn_pager(struct tag_files *tag_files) break; default: (void)setpgid(pager_pid, 0); - (void)tcsetpgrp(tag_files->ofd, pager_pid); + (void)tcsetpgrp(STDIN_FILENO, pager_pid); #if HAVE_PLEDGE if (pledge("stdio rpath tmppath tty proc", NULL) == -1) err((int)MANDOCLEVEL_SYSERR, "pledge"); @@ -1108,7 +1075,7 @@ spawn_pager(struct tag_files *tag_files) /* Do not start the pager before controlling the terminal. */ - while (tcgetpgrp(STDOUT_FILENO) != getpid()) + while (tcgetpgrp(STDIN_FILENO) != getpid()) nanosleep(&timeout, NULL); execvp(argv[0], argv);