=================================================================== RCS file: /cvs/mandoc/mdoc_macro.c,v retrieving revision 1.92 retrieving revision 1.99 diff -u -p -r1.92 -r1.99 --- mandoc/mdoc_macro.c 2010/07/04 22:04:04 1.92 +++ mandoc/mdoc_macro.c 2010/12/15 23:39:40 1.99 @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.92 2010/07/04 22:04:04 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.99 2010/12/15 23:39:40 kristaps Exp $ */ /* * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons * Copyright (c) 2010 Ingo Schwarze @@ -34,6 +34,7 @@ enum rew { /* see rew_dohalt() */ REWIND_NONE, REWIND_THIS, REWIND_MORE, + REWIND_FORCE, REWIND_LATER, REWIND_ERROR }; @@ -138,8 +139,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */ { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* No */ - { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* No */ + { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Ns */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */ { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */ @@ -207,14 +208,10 @@ mdoc_macroend(struct mdoc *m) 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; - mdoc_nmsg(m, n, MANDOCERR_SYNTSCOPE); - return(0); - } + for ( ; n; n = n->parent) + if (MDOC_BLOCK == n->type && + MDOC_EXPLICIT & mdoc_macros[n->tok].flags) + mdoc_nmsg(m, n, MANDOCERR_SCOPEEXIT); /* Rewind to the first. */ @@ -255,6 +252,7 @@ lookup_raw(const char *p) static int rew_last(struct mdoc *mdoc, const struct mdoc_node *to) { + struct mdoc_node *n; assert(to); mdoc->next = MDOC_NEXT_SIBLING; @@ -263,15 +261,13 @@ rew_last(struct mdoc *mdoc, const struct mdoc_node *to while (mdoc->last != to) { if ( ! mdoc_valid_post(mdoc)) return(0); - if ( ! mdoc_action_post(mdoc)) - return(0); + n = mdoc->last; mdoc->last = mdoc->last->parent; assert(mdoc->last); + mdoc->last->last = n; } - if ( ! mdoc_valid_post(mdoc)) - return(0); - return(mdoc_action_post(mdoc)); + return(mdoc_valid_post(mdoc)); } @@ -328,6 +324,7 @@ rew_alt(enum mdoct tok) * inside *p, so there is no need to rewind anything at all. * REWIND_THIS: *p matches tok, so rewind *p and nothing else. * REWIND_MORE: *p is implicit, rewind it and keep searching for tok. + * REWIND_FORCE: *p is explicit, but tok is full, force rewinding *p. * REWIND_LATER: *p is explicit and still open, postpone rewinding. * REWIND_ERROR: No tok block is open at all. */ @@ -421,16 +418,13 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type, return(REWIND_MORE); /* - * Partial blocks allow delayed rewinding by default. + * By default, closing out full blocks + * forces closing of broken explicit blocks, + * while closing out partial blocks + * allows delayed rewinding by default. */ - if (&blk_full != mdoc_macros[tok].fp) - return (REWIND_LATER); - - /* - * Full blocks can only be rewound when matching - * or when there is an explicit rule. - */ - return(REWIND_ERROR); + return (&blk_full == mdoc_macros[tok].fp ? + REWIND_FORCE : REWIND_LATER); } @@ -521,9 +515,7 @@ make_pending(struct mdoc_node *broken, enum mdoct tok, /* * Found no matching block for tok. * Are you trying to close a block that is not open? - * XXX Make this non-fatal. */ - mdoc_pmsg(m, line, ppos, MANDOCERR_SYNTNOSCOPE); return(0); } @@ -541,17 +533,22 @@ rew_sub(enum mdoc_type t, struct mdoc *m, return(1); case (REWIND_THIS): break; + case (REWIND_FORCE): + mdoc_vmsg(m, MANDOCERR_SCOPEBROKEN, line, ppos, + "%s breaks %s", mdoc_macronames[tok], + mdoc_macronames[n->tok]); + /* FALLTHROUGH */ case (REWIND_MORE): n = n->parent; continue; case (REWIND_LATER): - return(make_pending(n, tok, m, line, ppos)); + if (make_pending(n, tok, m, line, ppos) || + MDOC_BLOCK != t) + return(1); + /* FALLTHROUGH */ case (REWIND_ERROR): - /* XXX Make this non-fatal. */ - mdoc_vmsg(m, MANDOCERR_SCOPEFATAL, line, ppos, - "%s cannot break %s", mdoc_macronames[tok], - mdoc_macronames[n->tok]); - return 0; + mdoc_pmsg(m, line, ppos, MANDOCERR_NOSCOPE); + return(1); } break; } @@ -610,7 +607,7 @@ append_delims(struct mdoc *m, int line, int *pos, char * knowing which symbols break this behaviour, for * example, `. ;' shouldn't propogate the double-space. */ - if (mandoc_eos(p, strlen(p))) + if (mandoc_eos(p, strlen(p), 0)) m->last->flags |= MDOC_EOS; } @@ -679,8 +676,7 @@ blk_exp_close(MACRO_PROT_ARGS) * postpone closing out the current block * until the rew_sub() closing out the sub-block. */ - if ( ! make_pending(later, tok, m, line, ppos)) - return(0); + make_pending(later, tok, m, line, ppos); /* * Mark the place where the formatting - but not @@ -700,10 +696,8 @@ blk_exp_close(MACRO_PROT_ARGS) if (later && MDOC_EXPLICIT & mdoc_macros[later->tok].flags) continue; - if (MDOC_CALLABLE & mdoc_macros[n->tok].flags) { - assert( ! (MDOC_ACTED & n->flags)); + if (MDOC_CALLABLE & mdoc_macros[n->tok].flags) later = n; - } } if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { @@ -794,7 +788,7 @@ in_line(MACRO_PROT_ARGS) /* FALLTHROUGH */ case (MDOC_Fl): /* FALLTHROUGH */ - case (MDOC_Lk): + case (MDOC_Mt): /* FALLTHROUGH */ case (MDOC_Nm): /* FALLTHROUGH */ @@ -1147,7 +1141,6 @@ blk_full(MACRO_PROT_ARGS) if (MDOC_BLOCK == n->type && MDOC_EXPLICIT & mdoc_macros[n->tok].flags && ! (MDOC_VALID & n->flags)) { - assert( ! (MDOC_ACTED & n->flags)); n->pending = head; return(1); } @@ -1266,7 +1259,7 @@ blk_part_imp(MACRO_PROT_ARGS) */ if (n && MDOC_TEXT == n->type && n->string) - if (mandoc_eos(n->string, strlen(n->string))) + if (mandoc_eos(n->string, strlen(n->string), 1)) n->flags |= MDOC_EOS; /* Up-propogate the end-of-space flag. */ @@ -1285,9 +1278,7 @@ blk_part_imp(MACRO_PROT_ARGS) if (MDOC_BLOCK == n->type && MDOC_EXPLICIT & mdoc_macros[n->tok].flags && ! (MDOC_VALID & n->flags)) { - assert( ! (MDOC_ACTED & n->flags)); - if ( ! make_pending(n, tok, m, line, ppos)) - return(0); + make_pending(n, tok, m, line, ppos); if ( ! mdoc_endbody_alloc(m, line, ppos, tok, body, ENDBODY_NOSPACE)) return(0);