=================================================================== RCS file: /cvs/mandoc/read.c,v retrieving revision 1.38 retrieving revision 1.44 diff -u -p -r1.38 -r1.44 --- mandoc/read.c 2013/07/13 12:52:07 1.38 +++ mandoc/read.c 2014/03/19 21:51:20 1.44 @@ -1,7 +1,8 @@ -/* $Id: read.c,v 1.38 2013/07/13 12:52:07 schwarze Exp $ */ +/* $Id: read.c,v 1.44 2014/03/19 21:51:20 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze + * Copyright (c) 2010-2014 Ingo Schwarze + * Copyright (c) 2010, 2012 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,6 +27,7 @@ #include #include +#include #include #include #include @@ -51,7 +53,7 @@ struct mparse { enum mandoclevel file_status; /* status of current parse */ enum mandoclevel wlevel; /* ignore messages below this */ int line; /* line number in the file */ - enum mparset inttype; /* which parser to use */ + int options; /* parser options */ struct man *pman; /* persistent man parser */ struct mdoc *pmdoc; /* persistent mdoc parser */ struct man *man; /* man parser */ @@ -59,7 +61,6 @@ struct mparse { struct roff *roff; /* roff parser (!NULL) */ int reparse_count; /* finite interp. stack */ mandocmsg mmsg; /* warning/error message handler */ - void *arg; /* argument to mmsg */ const char *file; struct buf *secondary; char *defos; /* default operating system */ @@ -68,7 +69,8 @@ struct mparse { static void resize_buf(struct buf *, size_t); static void mparse_buf_r(struct mparse *, struct buf, int); static void pset(const char *, int, struct mparse *); -static int read_whole_file(const char *, int, struct buf *, int *); +static int read_whole_file(struct mparse *, const char *, int, + struct buf *, int *); static void mparse_end(struct mparse *); static void mparse_parse_buffer(struct mparse *, struct buf, const char *); @@ -106,7 +108,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "bad NAME section contents", "sections out of conventional order", "duplicate section name", - "section not in conventional manual section", + "section header suited to sections 2, 3, and 9 only", /* related to macros and nesting */ "skipping obsolete macro", @@ -192,6 +194,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "generic fatal error", + "input too large", "not a manual", "column syntax is inconsistent", "NOT IMPLEMENTED: .Bd -file", @@ -202,6 +205,11 @@ static const char * const mandocerrs[MANDOCERR_MAX] = "no document body", "no document prologue", "static buffer exhausted", + + /* system errors */ + "cannot open file", + "cannot stat file", + "cannot read file", }; static const char * const mandoclevels[MANDOCLEVEL_MAX] = { @@ -246,35 +254,36 @@ pset(const char *buf, int pos, struct mparse *curp) return; } - switch (curp->inttype) { - case (MPARSE_MDOC): + if (MPARSE_MDOC & curp->options) { if (NULL == curp->pmdoc) - curp->pmdoc = mdoc_alloc(curp->roff, curp, - curp->defos); + curp->pmdoc = mdoc_alloc( + curp->roff, curp, curp->defos, + MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pmdoc); curp->mdoc = curp->pmdoc; return; - case (MPARSE_MAN): + } else if (MPARSE_MAN & curp->options) { if (NULL == curp->pman) - curp->pman = man_alloc(curp->roff, curp); + curp->pman = man_alloc(curp->roff, curp, + MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pman); curp->man = curp->pman; return; - default: - break; } if (pos >= 3 && 0 == memcmp(buf, ".Dd", 3)) { if (NULL == curp->pmdoc) - curp->pmdoc = mdoc_alloc(curp->roff, curp, - curp->defos); + curp->pmdoc = mdoc_alloc( + curp->roff, curp, curp->defos, + MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pmdoc); curp->mdoc = curp->pmdoc; return; } if (NULL == curp->pman) - curp->pman = man_alloc(curp->roff, curp); + curp->pman = man_alloc(curp->roff, curp, + MPARSE_QUICK & curp->options ? 1 : 0); assert(curp->pman); curp->man = curp->pman; } @@ -552,7 +561,8 @@ rerun: if (0 == rc) { assert(MANDOCLEVEL_FATAL <= curp->file_status); break; - } + } else if (2 == rc) + break; /* Temporary buffers typically are not full. */ @@ -568,7 +578,8 @@ rerun: } static int -read_whole_file(const char *file, int fd, struct buf *fb, int *with_mmap) +read_whole_file(struct mparse *curp, const char *file, int fd, + struct buf *fb, int *with_mmap) { size_t off; ssize_t ssz; @@ -576,7 +587,10 @@ read_whole_file(const char *file, int fd, struct buf * #ifdef HAVE_MMAP struct stat st; if (-1 == fstat(fd, &st)) { - perror(file); + curp->file_status = MANDOCLEVEL_SYSERR; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_SYSSTAT, curp->file_status, + file, 0, 0, strerror(errno)); return(0); } @@ -589,7 +603,10 @@ read_whole_file(const char *file, int fd, struct buf * if (S_ISREG(st.st_mode)) { if (st.st_size >= (1U << 31)) { - fprintf(stderr, "%s: input too large\n", file); + curp->file_status = MANDOCLEVEL_FATAL; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_TOOLARGE, + curp->file_status, file, 0, 0, NULL); return(0); } *with_mmap = 1; @@ -612,7 +629,11 @@ read_whole_file(const char *file, int fd, struct buf * for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { - fprintf(stderr, "%s: input too large\n", file); + curp->file_status = MANDOCLEVEL_FATAL; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_TOOLARGE, + curp->file_status, + file, 0, 0, NULL); break; } resize_buf(fb, 65536); @@ -623,7 +644,11 @@ read_whole_file(const char *file, int fd, struct buf * return(1); } if (ssz == -1) { - perror(file); + curp->file_status = MANDOCLEVEL_SYSERR; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_SYSREAD, + curp->file_status, file, 0, 0, + strerror(errno)); break; } off += (size_t)ssz; @@ -704,12 +729,15 @@ mparse_readfd(struct mparse *curp, int fd, const char struct buf blk; int with_mmap; - if (-1 == fd) - if (-1 == (fd = open(file, O_RDONLY, 0))) { - perror(file); - curp->file_status = MANDOCLEVEL_SYSERR; - goto out; - } + if (-1 == fd && -1 == (fd = open(file, O_RDONLY, 0))) { + curp->file_status = MANDOCLEVEL_SYSERR; + if (curp->mmsg) + (*curp->mmsg)(MANDOCERR_SYSOPEN, + curp->file_status, + file, 0, 0, strerror(errno)); + goto out; + } + /* * Run for each opened file; may be called more than once for * each full parse sequence if the opened file is nested (i.e., @@ -717,10 +745,8 @@ mparse_readfd(struct mparse *curp, int fd, const char * the parse phase for the file. */ - if ( ! read_whole_file(file, fd, &blk, &with_mmap)) { - curp->file_status = MANDOCLEVEL_SYSERR; + if ( ! read_whole_file(curp, file, fd, &blk, &with_mmap)) goto out; - } mparse_parse_buffer(curp, blk, file); @@ -738,8 +764,8 @@ out: } struct mparse * -mparse_alloc(enum mparset inttype, enum mandoclevel wlevel, - mandocmsg mmsg, void *arg, char *defos) +mparse_alloc(int options, enum mandoclevel wlevel, + mandocmsg mmsg, char *defos) { struct mparse *curp; @@ -747,13 +773,12 @@ mparse_alloc(enum mparset inttype, enum mandoclevel wl curp = mandoc_calloc(1, sizeof(struct mparse)); + curp->options = options; curp->wlevel = wlevel; curp->mmsg = mmsg; - curp->arg = arg; - curp->inttype = inttype; curp->defos = defos; - curp->roff = roff_alloc(inttype, curp); + curp->roff = roff_alloc(curp, options); return(curp); }