=================================================================== RCS file: /cvs/mandoc/mdoc_macro.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -p -r1.31 -r1.32 --- mandoc/mdoc_macro.c 2009/08/19 11:58:32 1.31 +++ mandoc/mdoc_macro.c 2009/08/19 14:09:33 1.32 @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.31 2009/08/19 11:58:32 kristaps Exp $ */ +/* $Id: mdoc_macro.c,v 1.32 2009/08/19 14:09:33 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -41,11 +41,10 @@ static int rew_dohalt(int, enum mdoc_type, static int rew_alt(int); static int rew_dobreak(int, const struct mdoc_node *); static int rew_elem(struct mdoc *, int); -static int rew_impblock(struct mdoc *, int, int, int); -static int rew_expblock(struct mdoc *, int, int, int); -static int rew_subblock(enum mdoc_type, - struct mdoc *, int, int, int); -static int rew_last(struct mdoc *, struct mdoc_node *); /* FIXME: make const */ +static int rew_sub(enum mdoc_type, struct mdoc *, + int, int, int); +static int rew_last(struct mdoc *, + const struct mdoc_node *); static int append_delims(struct mdoc *, int, int *, char *); static int lookup(struct mdoc *, int, const char *); static int lookup_raw(struct mdoc *, const char *); @@ -233,26 +232,31 @@ swarn(struct mdoc *mdoc, enum mdoc_type type, * are errors. */ int -mdoc_macroend(struct mdoc *mdoc) +mdoc_macroend(struct mdoc *m) { struct mdoc_node *n; /* Scan for open explicit scopes. */ - n = MDOC_VALID & mdoc->last->flags ? - mdoc->last->parent : mdoc->last; + n = MDOC_VALID & m->last->flags ? m->last->parent : m->last; for ( ; n; n = n->parent) { if (MDOC_BLOCK != n->type) continue; if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags)) continue; - return(mdoc_nerr(mdoc, n, EOPEN)); + return(mdoc_nerr(m, n, EOPEN)); } - return(rew_last(mdoc, mdoc->first)); + /* Rewind to the first. */ + + return(rew_last(m, m->first)); } + +/* + * Look up a macro from within a subsequent context. + */ static int lookup(struct mdoc *mdoc, int from, const char *p) { @@ -263,6 +267,9 @@ lookup(struct mdoc *mdoc, int from, const char *p) } +/* + * Lookup a macro following the initial line macro. + */ static int lookup_raw(struct mdoc *mdoc, const char *p) { @@ -277,7 +284,7 @@ lookup_raw(struct mdoc *mdoc, const char *p) static int -rew_last(struct mdoc *mdoc, struct mdoc_node *to) +rew_last(struct mdoc *mdoc, const struct mdoc_node *to) { assert(to); @@ -299,6 +306,10 @@ rew_last(struct mdoc *mdoc, struct mdoc_node *to) } +/* + * Return the opening macro of a closing one, e.g., `Ec' has `Eo' as its + * matching pair. + */ static int rew_alt(int tok) { @@ -380,7 +391,6 @@ rew_dohalt(int tok, enum mdoc_type type, const struct case (MDOC_Qq): /* FALLTHROUGH */ case (MDOC_Sq): - assert(MDOC_HEAD != type); assert(MDOC_TAIL != type); if (type == p->type && tok == p->tok) return(REWIND_REWIND); @@ -439,7 +449,6 @@ rew_dohalt(int tok, enum mdoc_type type, const struct if (type == p->type && tok == p->tok) return(REWIND_REWIND); break; - /* Multi-line explicit scope close. */ case (MDOC_Ac): /* FALLTHROUGH */ @@ -551,80 +560,36 @@ rew_elem(struct mdoc *mdoc, int tok) static int -rew_subblock(enum mdoc_type type, struct mdoc *mdoc, +rew_sub(enum mdoc_type t, struct mdoc *m, int tok, int line, int ppos) { struct mdoc_node *n; int c; /* LINTED */ - for (n = mdoc->last; n; n = n->parent) { - c = rew_dohalt(tok, type, n); - if (REWIND_HALT == c) - return(1); + for (n = m->last; n; n = n->parent) { + c = rew_dohalt(tok, t, n); + if (REWIND_HALT == c) { + if (MDOC_BLOCK != t) + return(1); + if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) + return(1); + return(mdoc_perr(m, line, ppos, ENOCTX)); + } if (REWIND_REWIND == c) break; else if (rew_dobreak(tok, n)) continue; - if ( ! swarn(mdoc, type, line, ppos, n)) + if ( ! swarn(m, t, line, ppos, n)) return(0); } assert(n); - return(rew_last(mdoc, n)); + return(rew_last(m, n)); } static int -rew_expblock(struct mdoc *mdoc, int tok, int line, int ppos) -{ - struct mdoc_node *n; - int c; - - /* LINTED */ - for (n = mdoc->last; n; n = n->parent) { - c = rew_dohalt(tok, MDOC_BLOCK, n); - if (REWIND_HALT == c) - return(mdoc_perr(mdoc, line, ppos, ENOCTX)); - if (REWIND_REWIND == c) - break; - else if (rew_dobreak(tok, n)) - continue; - if ( ! swarn(mdoc, MDOC_BLOCK, line, ppos, n)) - return(0); - } - - assert(n); - return(rew_last(mdoc, n)); -} - - -/* FIXME: can this be merged with subblock? */ -static int -rew_impblock(struct mdoc *mdoc, int tok, int line, int ppos) -{ - struct mdoc_node *n; - int c; - - /* LINTED */ - for (n = mdoc->last; n; n = n->parent) { - c = rew_dohalt(tok, MDOC_BLOCK, n); - if (REWIND_HALT == c) - return(1); - else if (REWIND_REWIND == c) - break; - else if (rew_dobreak(tok, n)) - continue; - if ( ! swarn(mdoc, MDOC_BLOCK, line, ppos, n)) - return(0); - } - - assert(n); - return(rew_last(mdoc, n)); -} - - -static int append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) { int c, lastarg; @@ -671,34 +636,31 @@ blk_exp_close(MACRO_PROT_ARGS) if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { if (buf[*pos]) - if ( ! mdoc_pwarn(mdoc, line, ppos, ENOLINE)) + if ( ! mdoc_pwarn(m, line, ppos, ENOLINE)) return(0); - if ( ! rew_subblock(MDOC_BODY, mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) return(0); - return(rew_expblock(mdoc, tok, line, ppos)); + return(rew_sub(MDOC_BLOCK, m, tok, line, ppos)); } - if ( ! rew_subblock(MDOC_BODY, mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) return(0); - if (maxargs > 0) { - if ( ! mdoc_tail_alloc(mdoc, line, - ppos, rew_alt(tok))) + if (maxargs > 0) + if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok))) return(0); - mdoc->next = MDOC_NEXT_CHILD; - } for (flushed = j = 0; ; j++) { lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rew_expblock(mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) return(0); flushed = 1; } - c = mdoc_args(mdoc, line, pos, buf, tok, &p); + c = mdoc_args(m, line, pos, buf, tok, &p); if (ARGS_ERROR == c) return(0); @@ -707,34 +669,30 @@ blk_exp_close(MACRO_PROT_ARGS) if (ARGS_EOLN == c) break; - if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { + if (MDOC_MAX != (c = lookup(m, tok, p))) { if ( ! flushed) { - if ( ! rew_expblock(mdoc, tok, - line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) return(0); flushed = 1; } - if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) + if ( ! mdoc_macro(m, c, line, lastarg, pos, buf)) return(0); break; } - if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + if ( ! mdoc_word_alloc(m, line, lastarg, p)) return(0); } - if ( ! flushed && ! rew_expblock(mdoc, tok, line, ppos)) + if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) return(0); if (ppos > 1) return(1); - return(append_delims(mdoc, line, pos, buf)); + return(append_delims(m, line, pos, buf)); } -/* - * In-line macros where reserved words cause scope close-reopen. - */ static int in_line(MACRO_PROT_ARGS) { @@ -767,7 +725,7 @@ in_line(MACRO_PROT_ARGS) for (arg = NULL;; ) { la = *pos; - c = mdoc_argv(mdoc, line, tok, &arg, pos, buf); + c = mdoc_argv(m, line, tok, &arg, pos, buf); if (ARGV_WORD == c) { *pos = la; @@ -784,7 +742,7 @@ in_line(MACRO_PROT_ARGS) for (cnt = 0, lastpunct = 1;; ) { la = *pos; - w = mdoc_args(mdoc, line, pos, buf, tok, &p); + w = mdoc_args(m, line, pos, buf, tok, &p); if (ARGS_ERROR == w) return(0); @@ -795,7 +753,7 @@ in_line(MACRO_PROT_ARGS) /* Quoted words shouldn't be looked-up. */ - c = ARGS_QWORD == w ? MDOC_MAX : lookup(mdoc, tok, p); + c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p); /* * In this case, we've located a submacro and must @@ -805,25 +763,24 @@ in_line(MACRO_PROT_ARGS) */ if (MDOC_MAX != c) { - if (0 == lastpunct && ! rew_elem(mdoc, tok)) + if (0 == lastpunct && ! rew_elem(m, tok)) return(0); if (nc && 0 == cnt) { - if ( ! mdoc_elem_alloc(mdoc, line, ppos, - tok, arg)) + if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) return(0); - if ( ! rew_last(mdoc, mdoc->last)) + if ( ! rew_last(m, m->last)) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - if ( ! mdoc_pwarn(mdoc, line, ppos, EIGNE)) + if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) return(0); } - c = mdoc_macro(mdoc, c, line, la, pos, buf); + c = mdoc_macro(m, c, line, la, pos, buf); if (0 == c) return(0); if (ppos > 1) return(1); - return(append_delims(mdoc, line, pos, buf)); + return(append_delims(m, line, pos, buf)); } /* @@ -835,24 +792,22 @@ in_line(MACRO_PROT_ARGS) d = mdoc_isdelim(p); if (ARGS_QWORD != w && d) { - if (0 == lastpunct && ! rew_elem(mdoc, tok)) + if (0 == lastpunct && ! rew_elem(m, tok)) return(0); lastpunct = 1; } else if (lastpunct) { - c = mdoc_elem_alloc(mdoc, line, ppos, tok, arg); - if (0 == c) + if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) return(0); - mdoc->next = MDOC_NEXT_CHILD; lastpunct = 0; } if ( ! d) cnt++; - if ( ! mdoc_word_alloc(mdoc, line, la, p)) + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); } - if (0 == lastpunct && ! rew_elem(mdoc, tok)) + if (0 == lastpunct && ! rew_elem(m, tok)) return(0); /* @@ -862,26 +817,22 @@ in_line(MACRO_PROT_ARGS) * */ if (nc && 0 == cnt) { - c = mdoc_elem_alloc(mdoc, line, ppos, tok, arg); - if (0 == c) + if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) return(0); - if ( ! rew_last(mdoc, mdoc->last)) + if ( ! rew_last(m, m->last)) return(0); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); - if ( ! mdoc_pwarn(mdoc, line, ppos, EIGNE)) + if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) return(0); } if (ppos > 1) return(1); - return(append_delims(mdoc, line, pos, buf)); + return(append_delims(m, line, pos, buf)); } -/* - * Block full-explicit and full-implicit. - */ static int blk_full(MACRO_PROT_ARGS) { @@ -906,16 +857,15 @@ blk_full(MACRO_PROT_ARGS) } if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { - if ( ! rew_subblock(MDOC_BODY, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) return(0); - if ( ! rew_impblock(mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) return(0); } for (arg = NULL;; ) { lastarg = *pos; - c = mdoc_argv(mdoc, line, tok, &arg, pos, buf); + c = mdoc_argv(m, line, tok, &arg, pos, buf); if (ARGV_WORD == c) { *pos = lastarg; @@ -931,39 +881,34 @@ blk_full(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, arg)) + if ( ! mdoc_block_alloc(m, line, ppos, tok, arg)) return(0); - mdoc->next = MDOC_NEXT_CHILD; if (0 == buf[*pos]) { - if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_head_alloc(m, line, ppos, tok)) return(0); - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; return(1); } - if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_head_alloc(m, line, ppos, tok)) return(0); /* Immediately close out head and enter body, if applicable. */ if (0 == dohead) { - if ( ! rew_subblock(MDOC_HEAD, mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); } - mdoc->next = MDOC_NEXT_CHILD; - for (reopen = 0;; ) { lastarg = *pos; - c = mdoc_args(mdoc, line, pos, buf, tok, &p); + c = mdoc_args(m, line, pos, buf, tok, &p); if (ARGS_ERROR == c) return(0); @@ -971,82 +916,76 @@ blk_full(MACRO_PROT_ARGS) break; if (ARGS_PHRASE == c) { assert(dohead); - if (reopen && ! mdoc_head_alloc - (mdoc, line, ppos, tok)) + if (reopen && ! mdoc_head_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; /* * Phrases are self-contained macro phrases used * in the columnar output of a macro. They need * special handling. */ - if ( ! phrase(mdoc, line, lastarg, buf)) + if ( ! phrase(m, line, lastarg, buf)) return(0); - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); reopen = 1; continue; } - if (MDOC_MAX == (c = lookup(mdoc, tok, p))) { - if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + if (MDOC_MAX == (c = lookup(m, tok, p))) { + if ( ! mdoc_word_alloc(m, line, lastarg, p)) return(0); continue; } - if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) + if ( ! mdoc_macro(m, c, line, lastarg, pos, buf)) return(0); break; } - if (1 == ppos && ! append_delims(mdoc, line, pos, buf)) + if (1 == ppos && ! append_delims(m, line, pos, buf)) return(0); /* If the body's already open, then just return. */ if (0 == dohead) return(1); - if ( ! rew_subblock(MDOC_HEAD, mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; return(1); } -/* - * Block partial-imnplicit scope. - */ static int blk_part_imp(MACRO_PROT_ARGS) { - int lastarg, c; + int la, c; char *p; struct mdoc_node *blk, *body, *n; - if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL)) - return(0); - mdoc->next = MDOC_NEXT_CHILD; - blk = mdoc->last; + /* If applicable, close out prior scopes. */ - if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) return(0); - mdoc->next = MDOC_NEXT_SIBLING; - - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + /* Saved for later close-out. */ + blk = m->last; + if ( ! mdoc_head_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; - body = mdoc->last; + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) + return(0); + if ( ! mdoc_body_alloc(m, line, ppos, tok)) + return(0); + /* Saved for later close-out. */ + body = m->last; - /* XXX - no known argument macros. */ + /* Body argument processing. */ for (;;) { - lastarg = *pos; - c = mdoc_args(mdoc, line, pos, buf, tok, &p); + la = *pos; + c = mdoc_args(m, line, pos, buf, tok, &p); assert(ARGS_PHRASE != c); if (ARGS_ERROR == c) @@ -1056,58 +995,53 @@ blk_part_imp(MACRO_PROT_ARGS) if (ARGS_EOLN == c) break; - if (MDOC_MAX == (c = lookup(mdoc, tok, p))) { - if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + if (MDOC_MAX == (c = lookup(m, tok, p))) { + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); continue; } - if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) + if ( ! mdoc_macro(m, c, line, la, pos, buf)) return(0); break; } - /* - * Since we know what our context is, we can rewind directly to - * it. This allows us to accomodate for our scope being - * violated by another token. + /* + * If we can't rewind to our body, then our scope has already + * been closed by another macro (like `Oc' closing `Op'). This + * is ugly behaviour nodding its head to OpenBSD's overwhelming + * crufty use of `Op' breakage--XXX, deprecate in time. */ - - for (n = mdoc->last; n; n = n->parent) + for (n = m->last; n; n = n->parent) if (body == n) break; + if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK)) + return(0); + if (n && ! rew_last(m, body)) + return(0); - if (NULL == n && ! mdoc_nwarn(mdoc, body, EIMPBRK)) - return(0); + /* Standard appending of delimiters. */ - if (n && ! rew_last(mdoc, body)) + if (1 == ppos && ! append_delims(m, line, pos, buf)) return(0); - if (1 == ppos && ! append_delims(mdoc, line, pos, buf)) - return(0); + /* Rewind scope, if applicable. */ - if (n && ! rew_last(mdoc, blk)) + if (n && ! rew_last(m, blk)) return(0); return(1); } -/* - * Block partial-explicit macros. - */ static int blk_part_exp(MACRO_PROT_ARGS) { - int lastarg, flushed, j, c, maxargs; + int la, flushed, j, c, maxargs; char *p; - flushed = 0; + /* Number of head arguments. Only `Eo' has these, */ - /* - * Number of arguments (head arguments). Only `Eo' has these, - */ - switch (tok) { case (MDOC_Eo): maxargs = 1; @@ -1117,37 +1051,44 @@ blk_part_exp(MACRO_PROT_ARGS) break; } - if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, NULL)) + /* Begin the block scope. */ + + if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) return(0); - mdoc->next = MDOC_NEXT_CHILD; + /* + * If no head arguments, open and then close out a head, noting + * that we've flushed our terms. `flushed' means that we've + * flushed out the head and the body is open. + */ + if (0 == maxargs) { - if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_head_alloc(m, line, ppos, tok)) return(0); - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); flushed = 1; - } else if ( ! mdoc_head_alloc(mdoc, line, ppos, tok)) - return(0); + } else { + if ( ! mdoc_head_alloc(m, line, ppos, tok)) + return(0); + flushed = 0; + } - mdoc->next = MDOC_NEXT_CHILD; + /* Process the head/head+body line arguments. */ for (j = 0; ; j++) { - lastarg = *pos; + la = *pos; if (j == maxargs && ! flushed) { - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); flushed = 1; - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; } - c = mdoc_args(mdoc, line, pos, buf, tok, &p); + c = mdoc_args(m, line, pos, buf, tok, &p); assert(ARGS_PHRASE != c); if (ARGS_ERROR == c) @@ -1157,67 +1098,56 @@ blk_part_exp(MACRO_PROT_ARGS) if (ARGS_EOLN == c) break; - if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { + if (MDOC_MAX != (c = lookup(m, tok, p))) { if ( ! flushed) { - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); flushed = 1; - if ( ! mdoc_body_alloc(mdoc, line, - ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; } - if ( ! mdoc_macro(mdoc, c, line, lastarg, - pos, buf)) + if ( ! mdoc_macro(m, c, line, la, pos, buf)) return(0); break; } if ( ! flushed && mdoc_isdelim(p)) { - if ( ! rew_subblock(MDOC_HEAD, mdoc, - tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); flushed = 1; - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; } - if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); } + /* Close the head and open the body, if applicable. */ + if ( ! flushed) { - if ( ! rew_subblock(MDOC_HEAD, mdoc, tok, line, ppos)) + if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) return(0); - if ( ! mdoc_body_alloc(mdoc, line, ppos, tok)) + if ( ! mdoc_body_alloc(m, line, ppos, tok)) return(0); - mdoc->next = MDOC_NEXT_CHILD; } + /* Standard appending of delimiters. */ + if (ppos > 1) return(1); - return(append_delims(mdoc, line, pos, buf)); + return(append_delims(m, line, pos, buf)); } -/* - * In-line macros where reserved words signal closure of the macro. - * Macros also have a fixed number of arguments. - */ static int in_line_argn(MACRO_PROT_ARGS) { - int lastarg, flushed, j, c, maxargs; + int la, flushed, j, c, maxargs; struct mdoc_arg *arg; char *p; - - /* - * Fixed maximum arguments per macro. Some of these have none - * and close as soon as the invocation is parsed. - */ + /* Fixed maximum arguments per macro, if applicable. */ switch (tok) { case (MDOC_Ap): @@ -1234,12 +1164,14 @@ in_line_argn(MACRO_PROT_ARGS) break; } + /* Macro argument processing. */ + for (arg = NULL;; ) { - lastarg = *pos; - c = mdoc_argv(mdoc, line, tok, &arg, pos, buf); + la = *pos; + c = mdoc_argv(m, line, tok, &arg, pos, buf); if (ARGV_WORD == c) { - *pos = lastarg; + *pos = la; break; } @@ -1252,20 +1184,23 @@ in_line_argn(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) + /* Open the element scope. */ + + if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) return(0); - mdoc->next = MDOC_NEXT_CHILD; + /* Process element arguments. */ + for (flushed = j = 0; ; j++) { - lastarg = *pos; + la = *pos; if (j == maxargs && ! flushed) { - if ( ! rew_elem(mdoc, tok)) + if ( ! rew_elem(m, tok)) return(0); flushed = 1; } - c = mdoc_args(mdoc, line, pos, buf, tok, &p); + c = mdoc_args(m, line, pos, buf, tok, &p); if (ARGS_ERROR == c) return(0); @@ -1274,39 +1209,37 @@ in_line_argn(MACRO_PROT_ARGS) if (ARGS_EOLN == c) break; - if (MDOC_MAX != (c = lookup(mdoc, tok, p))) { - if ( ! flushed && ! rew_elem(mdoc, tok)) + if (MDOC_MAX != (c = lookup(m, tok, p))) { + if ( ! flushed && ! rew_elem(m, tok)) return(0); flushed = 1; - if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf)) + if ( ! mdoc_macro(m, c, line, la, pos, buf)) return(0); break; } if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && ! flushed && mdoc_isdelim(p)) { - if ( ! rew_elem(mdoc, tok)) + if ( ! rew_elem(m, tok)) return(0); flushed = 1; } - if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); } - if ( ! flushed && ! rew_elem(mdoc, tok)) + /* Close out and append delimiters. */ + + if ( ! flushed && ! rew_elem(m, tok)) return(0); if (ppos > 1) return(1); - return(append_delims(mdoc, line, pos, buf)); + return(append_delims(m, line, pos, buf)); } -/* - * In-line macro that spans an entire line. May be callable, but has no - * subsequent parsed arguments. - */ static int in_line_eoln(MACRO_PROT_ARGS) { @@ -1316,11 +1249,11 @@ in_line_eoln(MACRO_PROT_ARGS) assert( ! (MDOC_PARSED & mdoc_macros[tok].flags)); - arg = NULL; + /* Parse macro arguments. */ - for (;;) { + for (arg = NULL; ; ) { la = *pos; - c = mdoc_argv(mdoc, line, tok, &arg, pos, buf); + c = mdoc_argv(m, line, tok, &arg, pos, buf); if (ARGV_WORD == c) { *pos = la; @@ -1335,33 +1268,37 @@ in_line_eoln(MACRO_PROT_ARGS) return(0); } - if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) + /* Open element scope. */ + + if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) return(0); - mdoc->next = MDOC_NEXT_CHILD; + /* Parse argument terms. */ for (;;) { la = *pos; - w = mdoc_args(mdoc, line, pos, buf, tok, &p); + w = mdoc_args(m, line, pos, buf, tok, &p); if (ARGS_ERROR == w) return(0); if (ARGS_EOLN == w) break; - c = ARGS_QWORD == w ? MDOC_MAX : lookup(mdoc, tok, p); + c = ARGS_QWORD == w ? MDOC_MAX : lookup(m, tok, p); if (MDOC_MAX != c) { - if ( ! rew_elem(mdoc, tok)) + if ( ! rew_elem(m, tok)) return(0); - return(mdoc_macro(mdoc, c, line, la, pos, buf)); + return(mdoc_macro(m, c, line, la, pos, buf)); } - if ( ! mdoc_word_alloc(mdoc, line, la, p)) + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); } - return(rew_elem(mdoc, tok)); + /* Close out (no delimiters). */ + + return(rew_elem(m, tok)); } @@ -1370,7 +1307,7 @@ static int obsolete(MACRO_PROT_ARGS) { - return(mdoc_pwarn(mdoc, line, ppos, EOBS)); + return(mdoc_pwarn(m, line, ppos, EOBS)); } @@ -1380,7 +1317,7 @@ obsolete(MACRO_PROT_ARGS) * macro is encountered. */ static int -phrase(struct mdoc *mdoc, int line, int ppos, char *buf) +phrase(struct mdoc *m, int line, int ppos, char *buf) { int c, w, la, pos; char *p; @@ -1389,22 +1326,22 @@ phrase(struct mdoc *mdoc, int line, int ppos, char *bu la = pos; /* Note: no calling context! */ - w = mdoc_zargs(mdoc, line, &pos, buf, &p); + w = mdoc_zargs(m, line, &pos, buf, &p); if (ARGS_ERROR == w) return(0); if (ARGS_EOLN == w) break; - c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(mdoc, p); + c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(m, p); if (MDOC_MAX != c) { - if ( ! mdoc_macro(mdoc, c, line, la, &pos, buf)) + if ( ! mdoc_macro(m, c, line, la, &pos, buf)) return(0); - return(append_delims(mdoc, line, &pos, buf)); + return(append_delims(m, line, &pos, buf)); } - if ( ! mdoc_word_alloc(mdoc, line, la, p)) + if ( ! mdoc_word_alloc(m, line, la, p)) return(0); }