=================================================================== RCS file: /cvs/mandoc/mdoc_macro.c,v retrieving revision 1.144 retrieving revision 1.149 diff -u -p -r1.144 -r1.149 --- mandoc/mdoc_macro.c 2014/11/17 06:44:58 1.144 +++ mandoc/mdoc_macro.c 2014/11/28 01:05:43 1.149 @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.144 2014/11/17 06:44:58 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.149 2014/11/28 01:05:43 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze @@ -62,9 +62,8 @@ static int phrase(struct mdoc *, int, int, char *); static enum mdoct rew_alt(enum mdoct); static enum rew rew_dohalt(enum mdoct, enum mdoc_type, const struct mdoc_node *); -static int rew_elem(struct mdoc *, enum mdoct); -static int rew_last(struct mdoc *, - const struct mdoc_node *); +static void rew_elem(struct mdoc *, enum mdoct); +static void rew_last(struct mdoc *, const struct mdoc_node *); static int rew_sub(enum mdoc_type, struct mdoc *, enum mdoct, int, int); @@ -171,7 +170,7 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT | MDOC_JOIN }, /* So */ { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sq */ - { in_line_eoln, 0 }, /* Sm */ + { in_line_argn, 0 }, /* Sm */ { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sx */ { in_line, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Sy */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */ @@ -238,7 +237,8 @@ mdoc_macroend(struct mdoc *mdoc) /* Rewind to the first. */ - return(rew_last(mdoc, mdoc->first)); + rew_last(mdoc, mdoc->first); + return(1); } /* @@ -268,15 +268,13 @@ lookup_raw(const char *p) return(MDOC_MAX); } -static int +static void rew_last(struct mdoc *mdoc, const struct mdoc_node *to) { struct mdoc_node *n, *np; assert(to); mdoc->next = MDOC_NEXT_SIBLING; - - while (mdoc->last != to) { /* * Save the parent here, because we may delete the @@ -285,15 +283,13 @@ rew_last(struct mdoc *mdoc, const struct mdoc_node *to * out to be lost. */ np = mdoc->last->parent; - if ( ! mdoc_valid_post(mdoc)) - return(0); + mdoc_valid_post(mdoc); n = mdoc->last; mdoc->last = np; assert(mdoc->last); mdoc->last->last = n; } - - return(mdoc_valid_post(mdoc)); + mdoc_valid_post(mdoc); } /* @@ -437,9 +433,11 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type, * Default block rewinding rules. * In particular, always skip block end markers, * and let all blocks rewind Nm children. + * Do not warn again when closing a block, + * since closing the body already warned. */ if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok || - (MDOC_BLOCK == p->type && + MDOC_BLOCK == type || (MDOC_BLOCK == p->type && ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))) return(REWIND_MORE); @@ -453,7 +451,7 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type, REWIND_FORCE : REWIND_LATER); } -static int +static void rew_elem(struct mdoc *mdoc, enum mdoct tok) { struct mdoc_node *n; @@ -463,8 +461,7 @@ rew_elem(struct mdoc *mdoc, enum mdoct tok) n = n->parent; assert(MDOC_ELEM == n->type); assert(tok == n->tok); - - return(rew_last(mdoc, n)); + rew_last(mdoc, n); } /* @@ -585,16 +582,14 @@ rew_sub(enum mdoc_type t, struct mdoc *mdoc, } assert(n); - if ( ! rew_last(mdoc, n)) - return(0); + rew_last(mdoc, n); /* * The current block extends an enclosing block. * Now that the current block ends, close the enclosing block, too. */ while (NULL != (n = n->pending)) { - if ( ! rew_last(mdoc, n)) - return(0); + rew_last(mdoc, n); if (MDOC_HEAD == n->type && ! mdoc_body_alloc(mdoc, n->line, n->pos, n->tok)) return(0); @@ -691,6 +686,7 @@ static int blk_exp_close(MACRO_PROT_ARGS) { struct mdoc_node *body; /* Our own body. */ + struct mdoc_node *endbody; /* Our own end marker. */ struct mdoc_node *later; /* A sub-block starting later. */ struct mdoc_node *n; /* For searching backwards. */ @@ -717,7 +713,7 @@ blk_exp_close(MACRO_PROT_ARGS) * both of our own and of pending sub-blocks. */ atok = rew_alt(tok); - body = later = NULL; + body = endbody = later = NULL; for (n = mdoc->last; n; n = n->parent) { if (MDOC_VALID & n->flags) continue; @@ -756,6 +752,10 @@ blk_exp_close(MACRO_PROT_ARGS) if ( ! mdoc_endbody_alloc(mdoc, line, ppos, atok, body, ENDBODY_SPACE)) return(0); + if (maxargs) { + endbody = mdoc->last; + mdoc->next = MDOC_NEXT_CHILD; + } break; } @@ -785,15 +785,28 @@ blk_exp_close(MACRO_PROT_ARGS) if ( ! rew_sub(MDOC_BODY, mdoc, tok, line, ppos)) return(0); - if (NULL == later && maxargs > 0) - if ( ! mdoc_tail_alloc(mdoc, line, ppos, rew_alt(tok))) + if (maxargs && endbody == NULL) { + if (n == NULL) { + /* + * Stray .Ec without previous .Eo: + * Break the output line, ignore any arguments. + */ + if ( ! mdoc_elem_alloc(mdoc, line, ppos, + MDOC_br, NULL)) + return(0); + rew_elem(mdoc, MDOC_br); + } else if ( ! mdoc_tail_alloc(mdoc, line, ppos, atok)) return(0); + } - for (flushed = j = 0; ; j++) { + flushed = n == NULL; + for (j = 0; ; j++) { lastarg = *pos; if (j == maxargs && ! flushed) { - if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) + if (endbody != NULL) + rew_last(mdoc, endbody); + else if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); flushed = 1; } @@ -817,7 +830,9 @@ blk_exp_close(MACRO_PROT_ARGS) } if ( ! flushed) { - if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) + if (endbody != NULL) + rew_last(mdoc, endbody); + else if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) return(0); flushed = 1; } @@ -829,8 +844,12 @@ blk_exp_close(MACRO_PROT_ARGS) break; } - if ( ! flushed && ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) - return(0); + if ( ! flushed) { + if (endbody != NULL) + rew_last(mdoc, endbody); + else if ( ! rew_sub(MDOC_BLOCK, mdoc, tok, line, ppos)) + return(0); + } if ( ! nl) return(1); @@ -926,7 +945,8 @@ in_line(MACRO_PROT_ARGS) break; } - ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); + ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ? + MDOC_MAX : lookup(tok, p); /* * In this case, we've located a submacro and must @@ -936,14 +956,13 @@ in_line(MACRO_PROT_ARGS) */ if (MDOC_MAX != ntok) { - if (scope && ! rew_elem(mdoc, tok)) - return(0); + if (scope) + rew_elem(mdoc, tok); if (nc && 0 == cnt) { if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); - if ( ! rew_last(mdoc, mdoc->last)) - return(0); + rew_last(mdoc, mdoc->last); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); mandoc_msg(MANDOCERR_MACRO_EMPTY, @@ -988,9 +1007,11 @@ in_line(MACRO_PROT_ARGS) * Close out our scope, if one is open, before * any punctuation. */ - if (scope && ! rew_elem(mdoc, tok)) - return(0); + if (scope) + rew_elem(mdoc, tok); scope = 0; + if (tok == MDOC_Fn) + mayopen = 0; } else if (mayopen && !scope) { if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); @@ -1017,14 +1038,13 @@ in_line(MACRO_PROT_ARGS) * having to parse out spaces. */ if (scope && MDOC_Fl == tok) { - if ( ! rew_elem(mdoc, tok)) - return(0); + rew_elem(mdoc, tok); scope = 0; } } - if (scope && ! rew_elem(mdoc, tok)) - return(0); + if (scope) + rew_elem(mdoc, tok); /* * If no elements have been collected and we're allowed to have @@ -1035,8 +1055,7 @@ in_line(MACRO_PROT_ARGS) if (nc && 0 == cnt) { if ( ! mdoc_elem_alloc(mdoc, line, ppos, tok, arg)) return(0); - if ( ! rew_last(mdoc, mdoc->last)) - return(0); + rew_last(mdoc, mdoc->last); } else if ( ! nc && 0 == cnt) { mdoc_argv_free(arg); mandoc_msg(MANDOCERR_MACRO_EMPTY, mdoc->parse, @@ -1077,7 +1096,8 @@ blk_full(MACRO_PROT_ARGS) if ( ! mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL)) return(0); - return(rew_elem(mdoc, MDOC_br)); + rew_elem(mdoc, MDOC_br); + return(1); } } @@ -1618,16 +1638,15 @@ in_line_argn(MACRO_PROT_ARGS) return(0); if (j == maxargs && ! flushed) { - if ( ! rew_elem(mdoc, tok)) - return(0); + rew_elem(mdoc, tok); flushed = 1; } ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX != ntok) { - if ( ! flushed && ! rew_elem(mdoc, tok)) - return(0); + if ( ! flushed) + rew_elem(mdoc, tok); flushed = 1; if ( ! mdoc_macro(mdoc, ntok, line, la, pos, buf)) return(0); @@ -1639,8 +1658,7 @@ in_line_argn(MACRO_PROT_ARGS) ARGS_QWORD != ac && ! flushed && DELIM_NONE != mdoc_isdelim(p)) { - if ( ! rew_elem(mdoc, tok)) - return(0); + rew_elem(mdoc, tok); flushed = 1; } @@ -1655,8 +1673,8 @@ in_line_argn(MACRO_PROT_ARGS) /* Close out in a consistent state. */ - if ( ! flushed && ! rew_elem(mdoc, tok)) - return(0); + if ( ! flushed) + rew_elem(mdoc, tok); if ( ! nl) return(1); return(append_delims(mdoc, line, pos, buf)); @@ -1720,15 +1738,14 @@ in_line_eoln(MACRO_PROT_ARGS) return(0); continue; } - - if ( ! rew_elem(mdoc, tok)) - return(0); + rew_elem(mdoc, tok); return(mdoc_macro(mdoc, ntok, line, la, pos, buf)); } /* Close out (no delimiters). */ - return(rew_elem(mdoc, tok)); + rew_elem(mdoc, tok); + return(1); } static int