=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.191 retrieving revision 1.194 diff -u -p -r1.191 -r1.194 --- mandoc/main.c 2014/09/03 18:09:14 1.191 +++ mandoc/main.c 2014/10/25 01:03:52 1.194 @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.191 2014/09/03 18:09:14 schwarze Exp $ */ +/* $Id: main.c,v 1.194 2014/10/25 01:03:52 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze @@ -82,12 +82,13 @@ struct curparse { char outopts[BUFSIZ]; /* buf of output opts */ }; +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 parse(struct curparse *, int, const char *, enum mandoclevel *); -static enum mandoclevel passthrough(const char *); +static enum mandoclevel passthrough(const char *, int); static void spawn_pager(void); static int toptions(struct curparse *, char *); static void usage(enum argmode) __attribute__((noreturn)); @@ -114,6 +115,8 @@ main(int argc, char *argv[]) #endif enum mandoclevel rc; enum outmode outmode; + pid_t child_pid; + int fd; int show_usage; int use_pager; int options; @@ -147,14 +150,15 @@ main(int argc, char *argv[]) memset(&curp, 0, sizeof(struct curparse)); curp.outtype = OUTT_ASCII; curp.wlevel = MANDOCLEVEL_FATAL; - options = MPARSE_SO; + options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; defos = NULL; use_pager = 1; show_usage = 0; outmode = OUTMODE_DEF; - while (-1 != (c = getopt(argc, argv, "aC:cfhI:iklM:m:O:S:s:T:VW:w"))) { + while (-1 != (c = getopt(argc, argv, + "aC:cfhI:iK:klM:m:O:S:s:T:VW:w"))) { switch (c) { case 'a': outmode = OUTMODE_ALL; @@ -190,6 +194,10 @@ main(int argc, char *argv[]) case 'i': outmode = OUTMODE_INT; break; + case 'K': + if ( ! koptions(&options, optarg)) + return((int)MANDOCLEVEL_BADARG); + break; case 'k': search.argmode = ARG_EXPR; break; @@ -370,16 +378,30 @@ main(int argc, char *argv[]) while (argc) { #if HAVE_SQLITE3 if (resp != NULL) { - if (resp->form & FORM_SRC) { + rc = mparse_open(curp.mp, &fd, resp->file, + &child_pid); + if (fd == -1) + /* nothing */; + else if (resp->form & FORM_SRC) { /* For .so only; ignore failure. */ chdir(paths.paths[resp->ipath]); - parse(&curp, -1, resp->file, &rc); + parse(&curp, fd, resp->file, &rc); } else - rc = passthrough(resp->file); + rc = passthrough(resp->file, fd); resp++; } else #endif - parse(&curp, -1, *argv++, &rc); + { + rc = mparse_open(curp.mp, &fd, *argv++, + &child_pid); + if (fd != -1) + parse(&curp, fd, argv[-1], &rc); + } + + if (child_pid && + mparse_wait(curp.mp, child_pid) != MANDOCLEVEL_OK) + rc = MANDOCLEVEL_SYSERR; + if (MANDOCLEVEL_OK != rc && curp.wstop) break; argc--; @@ -555,37 +577,51 @@ parse(struct curparse *curp, int fd, const char *file, } static enum mandoclevel -passthrough(const char *file) +passthrough(const char *file, int fd) { char buf[BUFSIZ]; const char *syscall; ssize_t nr, nw, off; - int fd; - fd = open(file, O_RDONLY); - if (fd == -1) { - syscall = "open"; - goto fail; - } - while ((nr = read(fd, buf, BUFSIZ)) != -1 && nr != 0) for (off = 0; off < nr; off += nw) if ((nw = write(STDOUT_FILENO, buf + off, (size_t)(nr - off))) == -1 || nw == 0) { + close(fd); syscall = "write"; goto fail; } - if (nr == 0) { - close(fd); + close(fd); + + if (nr == 0) return(MANDOCLEVEL_OK); - } syscall = "read"; fail: fprintf(stderr, "%s: %s: SYSERR: %s: %s", progname, file, syscall, strerror(errno)); return(MANDOCLEVEL_SYSERR); +} + +static int +koptions(int *options, char *arg) +{ + + if ( ! strcmp(arg, "utf-8")) { + *options |= MPARSE_UTF8; + *options &= ~MPARSE_LATIN1; + } else if ( ! strcmp(arg, "iso-8859-1")) { + *options |= MPARSE_LATIN1; + *options &= ~MPARSE_UTF8; + } else if ( ! strcmp(arg, "us-ascii")) { + *options &= ~(MPARSE_UTF8 | MPARSE_LATIN1); + } else { + fprintf(stderr, "%s: -K%s: Bad argument\n", + progname, arg); + return(0); + } + return(1); } static int