=================================================================== RCS file: /cvs/mandoc/roff.c,v retrieving revision 1.15 retrieving revision 1.17 diff -u -p -r1.15 -r1.17 --- mandoc/roff.c 2008/11/28 15:25:49 1.15 +++ mandoc/roff.c 2008/11/29 14:14:21 1.17 @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.15 2008/11/28 15:25:49 kristaps Exp $ */ +/* $Id: roff.c,v 1.17 2008/11/29 14:14:21 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -130,9 +130,8 @@ static int roffargs(const struct rofftree *, static int roffargok(int, int); static int roffnextopt(const struct rofftree *, int, const char ***, char **); -static int roffparse(struct rofftree *, char *, size_t); -static int textparse(const struct rofftree *, - const char *, size_t); +static int roffparse(struct rofftree *, char *); +static int textparse(const struct rofftree *, char *); static const int roffarg_An[] = { ROFF_Split, ROFF_Nosplit, @@ -357,27 +356,47 @@ const char *const *tokargnames = tokargnamesp; int roff_free(struct rofftree *tree, int flush) { - int error; + int error, t; struct roffnode *n; error = 0; - for (n = tree->last; n->parent; n = n->parent) - if (tokens[n->tok].ctx == 0) { - roff_warn(tree, NULL, "closing explicit scope " - "of `%s'", toknames[n->tok]); - error = 1; - } + if ( ! flush) + goto end; - if (0 == error && (ROFF_PRELUDE & tree->state)) { + error = 1; + + if (ROFF_PRELUDE & tree->state) { roff_warn(tree, NULL, "prelude never finished"); - error = 1; + goto end; + } + + for (n = tree->last; n->parent; n = n->parent) { + if (0 != tokens[n->tok].ctx) + continue; + roff_warn(tree, NULL, "closing explicit scope `%s'", + toknames[n->tok]); + goto end; } + while (tree->last) { + t = tree->last->tok; + if ( ! (*tokens[t].cb)(t, tree, NULL, ROFF_EXIT)) + goto end; + } + + if ( ! (*tree->cb.rofftail)(tree->arg)) + goto end; + + error = 0; + +end: + while (tree->last) roffnode_free(tree); free(tree); + return(error ? 0 : 1); } @@ -387,6 +406,9 @@ roff_alloc(const struct roffcb *cb, void *args) { struct rofftree *tree; + assert(args); + assert(cb); + if (NULL == (tree = calloc(1, sizeof(struct rofftree)))) err(1, "calloc"); @@ -395,32 +417,37 @@ roff_alloc(const struct roffcb *cb, void *args) (void)memcpy(&tree->cb, cb, sizeof(struct roffcb)); + if ( ! (*tree->cb.roffhead)(args)) { + free(tree); + return(NULL); + } + return(tree); } int -roff_engine(struct rofftree *tree, char *buf, size_t sz) +roff_engine(struct rofftree *tree, char *buf) { - tree->cur = NULL; + tree->cur = buf; + assert(buf); - if (0 == sz) { + if (0 == *buf) { roff_warn(tree, buf, "blank line"); return(0); } else if ('.' != *buf) - return(textparse(tree, buf, sz)); + return(textparse(tree, buf)); - return(roffparse(tree, buf, sz)); + return(roffparse(tree, buf)); } static int -textparse(const struct rofftree *tree, const char *buf, size_t sz) +textparse(const struct rofftree *tree, char *buf) { - - /* Print text. */ - return(1); + + return((*tree->cb.roffdata)(tree->arg, buf)); } @@ -490,15 +517,13 @@ roffscan(int tok, const int *tokv) static int -roffparse(struct rofftree *tree, char *buf, size_t sz) +roffparse(struct rofftree *tree, char *buf) { int tok, t; struct roffnode *n; char *argv[ROFF_MAXARG]; const char **argvp; - assert(sz > 0); - if (ROFF_MAX == (tok = rofffindtok(buf + 1))) { roff_err(tree, buf + 1, "bogus line macro"); return(0); @@ -937,6 +962,7 @@ roff_layout(ROFFCALL_ARGS) break; } + assert(tree->arg); if ( ! (*tree->cb.roffdata)(tree->arg, *argv++)) return(0); }