diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-05-16 00:54:04 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-05-16 00:54:04 +0000 |
commit | 08303d07ede570701a32bd51204b1689f2544119 (patch) | |
tree | 5eca5ae28df12494557e0593c922083fde503180 /usr.bin/mandoc/main.c | |
parent | 9be747ee1b1eac217127619ca44caf4eb6f851ab (diff) |
In theory, Kristaps never intended to write a roff parser,
but in practice, most real legacy man(7)uals are using so much
low level roff that we can't really get away without at least
partially handling some roff instructions.
As doing this in man(7) only has become messy and as even some
mdoc(7) pages need it, start a minimal partial roff preprocessor.
As a first step, move handling of .am[i], .de[i] and .ig there.
Do not use the roff preprocessor for new manuals!
Now that we have three main parser libraries - roff, man and mdoc -
each one having its own error handling is becoming messy, too.
Thus, start unifying message handling in one central place,
introducing a new generic function mmsg().
coded by kristaps@
Diffstat (limited to 'usr.bin/mandoc/main.c')
-rw-r--r-- | usr.bin/mandoc/main.c | 103 |
1 files changed, 85 insertions, 18 deletions
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 63b3019e083..1ddb5844941 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.29 2010/05/15 22:00:22 schwarze Exp $ */ +/* $Id: main.c,v 1.30 2010/05/16 00:54:03 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -26,8 +26,10 @@ #include <string.h> #include <unistd.h> +#include "mandoc.h" #include "mdoc.h" #include "man.h" +#include "roff.h" #include "main.h" #define UNCONST(a) ((void *)(uintptr_t)(const void *)(a)) @@ -59,6 +61,7 @@ struct curparse { const char *file; /* Current parse. */ int fd; /* Current parse. */ int wflags; + /* FIXME: set by max error */ #define WARN_WALL (1 << 0) /* All-warnings mask. */ #define WARN_WERR (1 << 2) /* Warnings->errors. */ int fflags; @@ -71,6 +74,7 @@ struct curparse { enum intt inttype; /* Input parsers... */ struct man *man; struct mdoc *mdoc; + struct roff *roff; enum outt outtype; /* Output devices... */ out_mdoc outmdoc; out_man outman; @@ -84,9 +88,12 @@ static void ffile(const char *, struct curparse *); static int foptions(int *, char *); static struct man *man_init(struct curparse *); static struct mdoc *mdoc_init(struct curparse *); -static int merr(void *, int, int, const char *); +static struct roff *roff_init(struct curparse *); +static int merr(void *, int, int, const char *); /* DEPRECATED */ static int moptions(enum intt *, char *); -static int mwarn(void *, int, int, const char *); +static int mwarn(void *, int, int, const char *); /* DEPRECATED */ +static int mmsg(enum mandocerr, void *, + int, int, const char *); static int pset(const char *, int, struct curparse *, struct man **, struct mdoc **); static int toptions(struct curparse *, char *); @@ -166,6 +173,12 @@ main(int argc, char *argv[]) if (curp.outfree) (*curp.outfree)(curp.outdata); + if (curp.mdoc) + mdoc_free(curp.mdoc); + if (curp.man) + man_free(curp.man); + if (curp.roff) + roff_free(curp.roff); return((with_warning || with_error) ? EXIT_FAILURE : EXIT_SUCCESS); @@ -214,6 +227,14 @@ man_init(struct curparse *curp) } +static struct roff * +roff_init(struct curparse *curp) +{ + + return(roff_alloc(mmsg, curp)); +} + + static struct mdoc * mdoc_init(struct curparse *curp) { @@ -305,7 +326,7 @@ read_whole_file(struct curparse *curp, struct buf *fb, int *with_mmap) return(0); } *with_mmap = 1; - fb->sz = st.st_size; + fb->sz = (size_t)st.st_size; fb->buf = mmap(NULL, fb->sz, PROT_READ, MAP_FILE, curp->fd, 0); if (fb->buf != MAP_FAILED) @@ -331,7 +352,7 @@ read_whole_file(struct curparse *curp, struct buf *fb, int *with_mmap) if (! resize_buf(fb, 65536)) break; } - ssz = read(curp->fd, fb->buf + off, fb->sz - off); + ssz = read(curp->fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; return(1); @@ -340,7 +361,7 @@ read_whole_file(struct curparse *curp, struct buf *fb, int *with_mmap) perror(curp->file); break; } - off += ssz; + off += (size_t)ssz; } free(fb->buf); @@ -355,11 +376,14 @@ fdesc(struct curparse *curp) { struct buf ln, blk; int i, pos, lnn, lnn_start, with_mmap; + enum rofferr re; struct man *man; struct mdoc *mdoc; + struct roff *roff; man = NULL; mdoc = NULL; + roff = NULL; memset(&ln, 0, sizeof(struct buf)); /* @@ -367,9 +391,14 @@ fdesc(struct curparse *curp) * memory mapped. ln is a line buffer and grows on-demand. */ - if (!read_whole_file(curp, &blk, &with_mmap)) + if ( ! read_whole_file(curp, &blk, &with_mmap)) return; + if (NULL == curp->roff) + curp->roff = roff_init(curp); + if (NULL == (roff = curp->roff)) + goto bailout; + for (i = 0, lnn = 1; i < (int)blk.sz;) { pos = 0; lnn_start = lnn; @@ -425,7 +454,13 @@ fdesc(struct curparse *curp) if (pos >= (int)ln.sz) if (! resize_buf(&ln, 256)) goto bailout; - ln.buf[pos] = 0; + ln.buf[pos] = '\0'; + + re = roff_parseln(roff, lnn_start, &ln.buf, &ln.sz); + if (ROFF_IGN == re) + continue; + else if (ROFF_ERR == re) + goto bailout; /* If unset, assign parser in pset(). */ @@ -434,9 +469,9 @@ fdesc(struct curparse *curp) /* Pass down into parsers. */ - if (man && ! man_parseln(man, lnn, ln.buf)) + if (man && ! man_parseln(man, lnn_start, ln.buf)) goto bailout; - if (mdoc && ! mdoc_parseln(mdoc, lnn, ln.buf)) + if (mdoc && ! mdoc_parseln(mdoc, lnn_start, ln.buf)) goto bailout; } @@ -451,6 +486,8 @@ fdesc(struct curparse *curp) goto bailout; if (man && ! man_endparse(man)) goto bailout; + if (roff && ! roff_endparse(roff)) + goto bailout; /* If unset, allocate output dev now (if applicable). */ @@ -491,20 +528,19 @@ fdesc(struct curparse *curp) (*curp->outmdoc)(curp->outdata, mdoc); cleanup: - if (curp->mdoc) { - mdoc_free(curp->mdoc); - curp->mdoc = NULL; - } - if (curp->man) { - man_free(curp->man); - curp->man = NULL; - } + if (mdoc) + mdoc_reset(mdoc); + if (man) + man_reset(man); + if (roff) + roff_reset(roff); if (ln.buf) free(ln.buf); if (with_mmap) munmap(blk.buf, blk.sz); else free(blk.buf); + return; bailout: @@ -726,3 +762,34 @@ mwarn(void *arg, int line, int col, const char *msg) return(1); } +static const char * const mandocerrs[MANDOCERR_MAX] = { + "ok", + "multi-line scope open on exit", + "request for scope closure when no matching scope is open", + "line arguments will be lost", + "memory exhausted" +}; + +/* + * XXX: this is experimental code that will eventually become the + * generic means of covering all warnings and errors! + */ +/* ARGSUSED */ +static int +mmsg(enum mandocerr t, void *arg, int ln, int col, const char *msg) +{ +#if 0 + struct curparse *cp; + + cp = (struct curparse *)arg; + + fprintf(stderr, "%s:%d:%d: %s", cp->file, + ln, col + 1, mandocerrs[t]); + + if (msg) + fprintf(stderr, ": %s", msg); + + fputc('\n', stderr); +#endif + return(1); +} |