=================================================================== RCS file: /cvs/mandoc/man.c,v retrieving revision 1.187 retrieving revision 1.189 diff -u -p -r1.187 -r1.189 --- mandoc/man.c 2019/01/05 00:36:50 1.187 +++ mandoc/man.c 2022/08/16 23:01:09 1.189 @@ -1,7 +1,7 @@ -/* $Id: man.c,v 1.187 2019/01/05 00:36:50 schwarze Exp $ */ +/* $Id: man.c,v 1.189 2022/08/16 23:01:09 schwarze Exp $ */ /* + * Copyright (c) 2013-2015,2017-2019,2022 Ingo Schwarze * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze * Copyright (c) 2011 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -70,26 +70,28 @@ man_hasc(char *start) return (ep - cp) % 2 ? NULL : ep; } +/* + * Rewind all open next-line scopes. + */ void man_descope(struct roff_man *man, int line, int offs, char *start) { - /* Trailing \c keeps next-line scope open. */ + /* First close out all next-line element scopes, if any. */ - if (start != NULL && man_hasc(start) != NULL) - return; - - /* - * Co-ordinate what happens with having a next-line scope open: - * first close out the element scopes (if applicable), - * then close out the block scope (also if applicable). - */ - if (man->flags & MAN_ELINE) { while (man->last->parent->type != ROFFT_ROOT && man_macro(man->last->parent->tok)->flags & MAN_ESCOPED) man_unscope(man, man->last->parent); man->flags &= ~MAN_ELINE; } + + /* Trailing \c keeps next-line block scope open. */ + + if (start != NULL && man_hasc(start) != NULL) + return; + + /* Close out the next-line block scope, if there is one. */ + if ( ! (man->flags & MAN_BLINE)) return; man_unscope(man, man->last->parent); @@ -274,6 +276,10 @@ man_pmacro(struct roff_man *man, int ln, char *buf, in return 1; } +/* + * Rewind open next-line scopes + * unless the tok request or macro is allowed inside them. + */ void man_breakscope(struct roff_man *man, int tok) { @@ -294,10 +300,15 @@ man_breakscope(struct roff_man *man, int tok) (man_macro(n->tok)->flags & (MAN_NSCOPED | MAN_ESCOPED)) == MAN_NSCOPED) n = n->parent; - - mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos, - "%s breaks %s", roff_name[tok], roff_name[n->tok]); - + for (;;) { + mandoc_msg(MANDOCERR_BLK_LINE, n->line, n->pos, + "%s breaks %s", roff_name[tok], roff_name[n->tok]); + if (n->parent->type != ROFFT_ELEM || + (man_macro(n->parent->tok)->flags & + MAN_ESCOPED) == 0) + break; + n = n->parent; + } roff_node_delete(man, n); man->flags &= ~MAN_ELINE; }