=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.24 retrieving revision 1.33 diff -u -p -r1.24 -r1.33 --- mandoc/main.c 2009/04/12 19:19:57 1.24 +++ mandoc/main.c 2009/07/04 09:01:55 1.33 @@ -1,20 +1,18 @@ -/* $Id: main.c,v 1.24 2009/04/12 19:19:57 kristaps Exp $ */ +/* $Id: main.c,v 1.33 2009/07/04 09:01:55 kristaps Exp $ */ /* - * Copyright (c) 2008, 2009 Kristaps Dzonsons + * Copyright (c) 2008, 2009 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all - * copies. + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE - * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include @@ -76,12 +74,12 @@ struct curparse { #define NO_IGN_ESCAPE (1 << 1) /* Don't ignore bad escapes. */ #define NO_IGN_MACRO (1 << 2) /* Don't ignore bad macros. */ #define NO_IGN_CHARS (1 << 3) /* Don't ignore bad chars. */ - enum intt inttype; /* Input parsers. */ + enum intt inttype; /* Input parsers... */ struct man *man; struct man *lastman; struct mdoc *mdoc; struct mdoc *lastmdoc; - enum outt outtype; /* Output devices. */ + enum outt outtype; /* Output devices... */ out_mdoc outmdoc; out_man outman; out_free outfree; @@ -103,8 +101,6 @@ static int merr(void *, int, int, const char *); static int manwarn(void *, int, int, const char *); static int mdocwarn(void *, int, int, enum mdoc_warn, const char *); -static int fstdin(struct buf *, struct buf *, - struct curparse *); static int ffile(struct buf *, struct buf *, const char *, struct curparse *); static int fdesc(struct buf *, struct buf *, @@ -136,19 +132,19 @@ main(int argc, char *argv[]) switch (c) { case ('f'): if ( ! foptions(&curp.fflags, optarg)) - return(0); + return(EXIT_FAILURE); break; case ('m'): if ( ! moptions(&curp.inttype, optarg)) - return(0); + return(EXIT_FAILURE); break; case ('T'): if ( ! toptions(&curp.outtype, optarg)) - return(0); + return(EXIT_FAILURE); break; case ('W'): if ( ! woptions(&curp.wflags, optarg)) - return(0); + return(EXIT_FAILURE); break; case ('V'): version(); @@ -161,16 +157,17 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - /* Configure buffers. */ - bzero(&ln, sizeof(struct buf)); bzero(&blk, sizeof(struct buf)); rc = 1; - if (NULL == *argv) - if ( ! fstdin(&blk, &ln, &curp)) + if (NULL == *argv) { + curp.file = ""; + curp.fd = STDIN_FILENO; + if ( ! fdesc(&blk, &ln, &curp)) rc = 0; + } while (rc && *argv) { if ( ! ffile(&blk, &ln, *argv, &curp)) @@ -233,10 +230,16 @@ man_init(struct curparse *curp) mancb.man_err = merr; mancb.man_warn = manwarn; - pflags = MAN_IGN_MACRO; /* XXX */ + /* Defaults from mandoc.1. */ + pflags = MAN_IGN_MACRO | MAN_IGN_ESCAPE | MAN_IGN_CHARS; + if (curp->fflags & NO_IGN_MACRO) pflags &= ~MAN_IGN_MACRO; + if (curp->fflags & NO_IGN_CHARS) + pflags &= ~MAN_IGN_CHARS; + if (curp->fflags & NO_IGN_ESCAPE) + pflags &= ~MAN_IGN_ESCAPE; if (NULL == (man = man_alloc(curp, pflags, &mancb))) warnx("memory exhausted"); @@ -252,10 +255,11 @@ mdoc_init(struct curparse *curp) struct mdoc *mdoc; struct mdoc_cb mdoccb; - mdoccb.mdoc_msg = NULL; mdoccb.mdoc_err = merr; mdoccb.mdoc_warn = mdocwarn; + /* Defaults from mandoc.1. */ + pflags = MDOC_IGN_MACRO | MDOC_IGN_ESCAPE | MDOC_IGN_CHARS; if (curp->fflags & IGN_SCOPE) @@ -275,16 +279,6 @@ mdoc_init(struct curparse *curp) static int -fstdin(struct buf *blk, struct buf *ln, struct curparse *curp) -{ - - curp->file = ""; - curp->fd = STDIN_FILENO; - return(fdesc(blk, ln, curp)); -} - - -static int ffile(struct buf *blk, struct buf *ln, const char *file, struct curparse *curp) { @@ -311,7 +305,7 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse size_t sz; ssize_t ssz; struct stat st; - int j, i, pos, lnn; + int j, i, pos, lnn, comment; struct man *man; struct mdoc *mdoc; @@ -326,7 +320,7 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse */ if (-1 == fstat(curp->fd, &st)) - warnx("%s", curp->file); + warn("%s", curp->file); else if ((size_t)st.st_blksize > sz) sz = st.st_blksize; @@ -341,7 +335,7 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse /* Fill buf with file blocksize. */ - for (lnn = 0, pos = 0; ; ) { + for (lnn = pos = comment = 0; ; ) { if (-1 == (ssz = read(curp->fd, blk->buf, sz))) { warn("%s", curp->file); return(0); @@ -361,17 +355,34 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse } if ('\n' != blk->buf[i]) { + if (comment) + continue; ln->buf[pos++] = blk->buf[i]; + + /* Handle in-line `\"' comments. */ + + if (1 == pos || '\"' != ln->buf[pos - 1]) + continue; + + for (j = pos - 2; j >= 0; j--) + if ('\\' != ln->buf[j]) + break; + + if ( ! ((pos - 2 - j) % 2)) + continue; + + comment = 1; + pos -= 2; continue; - } + } - /* Check for CPP-escaped newline. */ + /* Handle escaped `\\n' newlines. */ - if (pos > 0 && '\\' == ln->buf[pos - 1]) { + if (pos > 0 && 0 == comment && + '\\' == ln->buf[pos - 1]) { for (j = pos - 1; j >= 0; j--) if ('\\' != ln->buf[j]) break; - if ( ! ((pos - j) % 2)) { pos--; lnn++; @@ -381,20 +392,17 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse ln->buf[pos] = 0; lnn++; - - /* - * If no manual parser has been assigned, then - * try to assign one in pset(), which may do - * nothing at all. After this, parse the manual - * line accordingly. - */ + /* If unset, assign parser in pset(). */ + if ( ! (man || mdoc) && ! pset(ln->buf, pos, curp, &man, &mdoc)) return(0); - pos = 0; + pos = comment = 0; + /* Pass down into parsers. */ + if (man && ! man_parseln(man, lnn, ln->buf)) return(0); if (mdoc && ! mdoc_parseln(mdoc, lnn, ln->buf)) @@ -402,7 +410,7 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse } } - /* Note that a parser may not have been assigned, yet. */ + /* NOTE a parser may not have been assigned, yet. */ if ( ! (man || mdoc)) { warnx("%s: not a manual", curp->file); @@ -414,12 +422,7 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse if (man && ! man_endparse(man)) return(0); - /* - * If an output device hasn't been allocated, see if we should - * do so now. Note that not all outtypes have functions, so - * this switch statement may be superfluous, but it's - * low-overhead enough not to matter very much. - */ + /* If unset, allocate output dev now (if applicable). */ if ( ! (curp->outman && curp->outmdoc)) { switch (curp->outtype) { @@ -455,17 +458,23 @@ static int pset(const char *buf, int pos, struct curparse *curp, struct man **man, struct mdoc **mdoc) { + int i; /* * Try to intuit which kind of manual parser should be used. If * passed in by command-line (-man, -mdoc), then use that * explicitly. If passed as -mandoc, then try to guess from the - * line: either skip comments, use -mdoc when finding `.Dt', or + * line: either skip dot-lines, use -mdoc when finding `.Dt', or * default to -man, which is more lenient. */ - if (pos >= 3 && 0 == memcmp(buf, ".\\\"", 3)) - return(1); + if (buf[0] == '.') { + for (i = 1; buf[i]; i++) + if (' ' != buf[i] && '\t' != buf[i]) + break; + if (0 == buf[i]) + return(1); + } switch (curp->inttype) { case (INTT_MDOC): @@ -542,10 +551,6 @@ toptions(enum outt *tflags, char *arg) } -/* - * Parse out the options for [-fopt...] setting compiler options. These - * can be comma-delimited or called again. - */ static int foptions(int *fflags, char *arg) { @@ -578,7 +583,7 @@ foptions(int *fflags, char *arg) NO_IGN_MACRO | NO_IGN_CHARS; break; default: - warnx("bad argument: -f%s", arg); + warnx("bad argument: -f%s", suboptarg); return(0); } @@ -586,10 +591,6 @@ foptions(int *fflags, char *arg) } -/* - * Parse out the options for [-Werr...], which sets warning modes. - * These can be comma-delimited or called again. - */ static int woptions(int *wflags, char *arg) { @@ -617,7 +618,7 @@ woptions(int *wflags, char *arg) *wflags |= WARN_WERR; break; default: - warnx("bad argument: -W%s", arg); + warnx("bad argument: -W%s", suboptarg); return(0); } @@ -632,9 +633,9 @@ merr(void *arg, int line, int col, const char *msg) struct curparse *curp; curp = (struct curparse *)arg; - warnx("%s:%d: error: %s (column %d)", curp->file, line, msg, col); + return(0); } @@ -668,9 +669,8 @@ mdocwarn(void *arg, int line, int col, if ( ! (curp->wflags & WARN_WERR)) return(1); - - warnx("%s: considering warnings as errors", - __progname); + + warnx("considering warnings as errors"); return(0); } @@ -691,7 +691,6 @@ manwarn(void *arg, int line, int col, const char *msg) if ( ! (curp->wflags & WARN_WERR)) return(1); - warnx("%s: considering warnings as errors", - __progname); + warnx("considering warnings as errors"); return(0); }