diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2020-02-27 01:26:00 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2020-02-27 01:26:00 +0000 |
commit | 6f8aadfc69810a5c3408b4cae48f85969daf651c (patch) | |
tree | 451d059ba46667c14eff8b88012de8605c885723 /usr.bin/mandoc | |
parent | d1bbe4f0575c40545245502a43df4e9910062b65 (diff) |
Introduce the concept of nodes that are semantically transparent:
they are skipped when looking for previous or following high-level
macros. Examples include roff(7) .ft, .ll, and .ta, mdoc(7) .Sm
and .Tg, and man(7) .DT and .PD. Use this concept for a variety
of improved decisions in various validators and formatters.
While here,
* remove a few const qualifiers on struct arguments that caused trouble;
* get rid of some more Yoda notation in the vicinity;
* and apply some other stylistic improvements in the vicinity.
I found this class of issues while considering .Tg patches from kn@.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/man_html.c | 14 | ||||
-rw-r--r-- | usr.bin/mandoc/man_term.c | 39 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_html.c | 70 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_man.c | 87 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_markdown.c | 38 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_term.c | 140 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_validate.c | 156 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 55 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.h | 10 | ||||
-rw-r--r-- | usr.bin/mandoc/roff_validate.c | 8 |
10 files changed, 332 insertions, 285 deletions
diff --git a/usr.bin/mandoc/man_html.c b/usr.bin/mandoc/man_html.c index 4e66abb36de..589b4114138 100644 --- a/usr.bin/mandoc/man_html.c +++ b/usr.bin/mandoc/man_html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_html.c,v 1.128 2020/02/12 21:14:24 schwarze Exp $ */ +/* $OpenBSD: man_html.c,v 1.129 2020/02/27 01:25:57 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -32,7 +32,7 @@ #include "main.h" #define MAN_ARGS const struct roff_meta *man, \ - const struct roff_node *n, \ + struct roff_node *n, \ struct html *h struct man_html_act { @@ -242,7 +242,7 @@ print_man_node(MAN_ARGS) * Close the list if no further item of the same type * follows; otherwise, close the item only. */ - if (list_continues(n, n->next) == '\0') { + if (list_continues(n, roff_node_next(n)) == '\0') { print_tagq(h, t); t = NULL; } @@ -443,15 +443,17 @@ list_continues(const struct roff_node *n1, const struct roff_node *n2) static int man_IP_pre(MAN_ARGS) { - const struct roff_node *nn; + struct roff_node *nn; const char *list_class; enum htmltag list_elem, body_elem; char list_type; nn = n->type == ROFFT_BLOCK ? n : n->parent; - if ((list_type = list_continues(nn->prev, nn)) == '\0') { + list_type = list_continues(roff_node_prev(nn), nn); + if (list_type == '\0') { /* Start a new list. */ - if ((list_type = list_continues(nn, nn->next)) == '\0') + list_type = list_continues(nn, roff_node_next(nn)); + if (list_type == '\0') list_type = ' '; switch (list_type) { case ' ': diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c index 0a35597877c..33ae377ffb9 100644 --- a/usr.bin/mandoc/man_term.c +++ b/usr.bin/mandoc/man_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_term.c,v 1.186 2020/01/20 10:29:31 schwarze Exp $ */ +/* $OpenBSD: man_term.c,v 1.187 2020/02/27 01:25:57 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -62,7 +62,7 @@ static void print_man_head(struct termp *, static void print_man_foot(struct termp *, const struct roff_meta *); static void print_bvspace(struct termp *, - const struct roff_node *, int); + struct roff_node *, int); static int pre_B(DECL_ARGS); static int pre_DT(DECL_ARGS); @@ -203,19 +203,20 @@ terminal_man(void *arg, const struct roff_meta *man) * first, print it. */ static void -print_bvspace(struct termp *p, const struct roff_node *n, int pardist) +print_bvspace(struct termp *p, struct roff_node *n, int pardist) { - int i; + struct roff_node *nch; + int i; term_newln(p); - if (n->body != NULL && n->body->child != NULL) - if (n->body->child->type == ROFFT_TBL) - return; + if (n->body != NULL && + (nch = roff_node_child(n->body)) != NULL && + nch->type == ROFFT_TBL) + return; - if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS) - if (n->prev == NULL) - return; + if (n->parent->tok != MAN_RS && roff_node_prev(n) == NULL) + return; for (i = 0; i < pardist; i++) term_vspace(p); @@ -681,12 +682,8 @@ pre_SS(DECL_ARGS) * and after an empty subsection. */ - do { - n = n->prev; - } while (n != NULL && n->tok >= MAN_TH && - man_term_act(n->tok)->flags & MAN_NOTEXT); - if (n == NULL || n->type == ROFFT_COMMENT || - (n->tok == MAN_SS && n->body->child == NULL)) + if ((n = roff_node_prev(n)) == NULL || + (n->tok == MAN_SS && roff_node_child(n->body) == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -726,12 +723,8 @@ pre_SH(DECL_ARGS) * and after an empty section. */ - do { - n = n->prev; - } while (n != NULL && n->tok >= MAN_TH && - man_term_act(n->tok)->flags & MAN_NOTEXT); - if (n == NULL || n->type == ROFFT_COMMENT || - (n->tok == MAN_SH && n->body->child == NULL)) + if ((n = roff_node_prev(n)) == NULL || + (n->tok == MAN_SH && roff_node_child(n->body) == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -837,7 +830,7 @@ pre_SY(DECL_ARGS) switch (n->type) { case ROFFT_BLOCK: - if (n->prev == NULL || n->prev->tok != MAN_SY) + if ((nn = roff_node_prev(n)) == NULL || nn->tok != MAN_SY) print_bvspace(p, n, mt->pardist); return 1; case ROFFT_HEAD: diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c index 8a6275f4f5e..cb0c6a82748 100644 --- a/usr.bin/mandoc/mdoc_html.c +++ b/usr.bin/mandoc/mdoc_html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_html.c,v 1.208 2020/01/19 17:59:01 schwarze Exp $ */ +/* $OpenBSD: mdoc_html.c,v 1.209 2020/02/27 01:25:57 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -50,8 +50,7 @@ static void print_mdoc_head(const struct roff_meta *, struct html *); static void print_mdoc_node(MDOC_ARGS); static void print_mdoc_nodelist(MDOC_ARGS); -static void synopsis_pre(struct html *, - const struct roff_node *); +static void synopsis_pre(struct html *, struct roff_node *); static void mdoc_root_post(const struct roff_meta *, struct html *); @@ -248,13 +247,15 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = { * See the same function in mdoc_term.c for documentation. */ static void -synopsis_pre(struct html *h, const struct roff_node *n) +synopsis_pre(struct html *h, struct roff_node *n) { + struct roff_node *np; - if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags)) + if ((n->flags & NODE_SYNPRETTY) == 0 || + (np = roff_node_prev(n)) == NULL) return; - if (n->prev->tok == n->tok && + if (np->tok == n->tok && MDOC_Fo != n->tok && MDOC_Ft != n->tok && MDOC_Fn != n->tok) { @@ -262,7 +263,7 @@ synopsis_pre(struct html *h, const struct roff_node *n) return; } - switch (n->prev->tok) { + switch (np->tok) { case MDOC_Fd: case MDOC_Fn: case MDOC_Fo: @@ -623,17 +624,18 @@ mdoc_ss_pre(MDOC_ARGS) static int mdoc_fl_pre(MDOC_ARGS) { - char *id; + struct roff_node *nn; + char *id; if ((id = cond_id(n)) != NULL) print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "ci", "Fl", id); print_text(h, "\\-"); - if (!(n->child == NULL && - (n->next == NULL || - n->next->type == ROFFT_TEXT || - n->next->flags & NODE_LINE))) + if (n->child != NULL || + ((nn = roff_node_next(n)) != NULL && + nn->type != ROFFT_TEXT && + (nn->flags & NODE_LINE) == 0)) h->flags |= HTML_NOSPACE; return 1; @@ -907,7 +909,7 @@ mdoc_bl_pre(MDOC_ARGS) static int mdoc_ex_pre(MDOC_ARGS) { - if (n->prev) + if (roff_node_prev(n) != NULL) print_otag(h, TAG_BR, ""); return 1; } @@ -984,7 +986,7 @@ mdoc_bd_pre(MDOC_ARGS) continue; if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss) comp = 1; - if (nn->prev != NULL) + if (roff_node_prev(nn) != NULL) break; } (void)strlcpy(buf, "Bd", sizeof(buf)); @@ -1096,22 +1098,21 @@ mdoc_fa_pre(MDOC_ARGS) print_otag(h, TAG_VAR, "c", "Fa"); return 1; } - - for (nn = n->child; nn; nn = nn->next) { + for (nn = n->child; nn != NULL; nn = nn->next) { t = print_otag(h, TAG_VAR, "c", "Fa"); print_text(h, nn->string); print_tagq(h, t); - if (nn->next) { + if (nn->next != NULL) { h->flags |= HTML_NOSPACE; print_text(h, ","); } } - - if (n->child && n->next && n->next->tok == MDOC_Fa) { + if (n->child != NULL && + (nn = roff_node_next(n)) != NULL && + nn->tok == MDOC_Fa) { h->flags |= HTML_NOSPACE; print_text(h, ","); } - return 0; } @@ -1570,7 +1571,9 @@ mdoc_sy_pre(MDOC_ARGS) static int mdoc_lb_pre(MDOC_ARGS) { - if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev) + if (n->sec == SEC_LIBRARY && + n->flags & NODE_LINE && + roff_node_prev(n) != NULL) print_otag(h, TAG_BR, ""); print_otag(h, TAG_SPAN, "c", "Lb"); @@ -1580,17 +1583,18 @@ mdoc_lb_pre(MDOC_ARGS) static int mdoc__x_pre(MDOC_ARGS) { - const char *cattr; - enum htmltag t; + struct roff_node *nn; + const char *cattr; + enum htmltag t; t = TAG_SPAN; switch (n->tok) { case MDOC__A: cattr = "RsA"; - if (n->prev && MDOC__A == n->prev->tok) - if (NULL == n->next || MDOC__A != n->next->tok) - print_text(h, "and"); + if ((nn = roff_node_prev(n)) != NULL && nn->tok == MDOC__A && + ((nn = roff_node_next(n)) == NULL || nn->tok != MDOC__A)) + print_text(h, "and"); break; case MDOC__B: t = TAG_I; @@ -1645,19 +1649,21 @@ mdoc__x_pre(MDOC_ARGS) static void mdoc__x_post(MDOC_ARGS) { + struct roff_node *nn; - if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok) - if (NULL == n->next->next || MDOC__A != n->next->next->tok) - if (NULL == n->prev || MDOC__A != n->prev->tok) - return; + if (n->tok == MDOC__A && + (nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A && + ((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) && + ((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A)) + return; /* TODO: %U */ - if (NULL == n->parent || MDOC_Rs != n->parent->tok) + if (n->parent == NULL || n->parent->tok != MDOC_Rs) return; h->flags |= HTML_NOSPACE; - print_text(h, n->next ? "," : "."); + print_text(h, roff_node_next(n) ? "," : "."); } static int diff --git a/usr.bin/mandoc/mdoc_man.c b/usr.bin/mandoc/mdoc_man.c index 7fde52b78cc..25d59a5a01b 100644 --- a/usr.bin/mandoc/mdoc_man.c +++ b/usr.bin/mandoc/mdoc_man.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_man.c,v 1.133 2020/02/20 22:55:10 schwarze Exp $ */ +/* $OpenBSD: mdoc_man.c,v 1.134 2020/02/27 01:25:57 schwarze Exp $ */ /* * Copyright (c) 2011-2020 Ingo Schwarze <schwarze@openbsd.org> * @@ -111,7 +111,7 @@ static int pre_sm(DECL_ARGS); static void pre_sp(DECL_ARGS); static int pre_sect(DECL_ARGS); static int pre_sy(DECL_ARGS); -static void pre_syn(const struct roff_node *); +static void pre_syn(struct roff_node *); static void pre_ta(DECL_ARGS); static int pre_vt(DECL_ARGS); static int pre_xr(DECL_ARGS); @@ -648,7 +648,9 @@ print_node(DECL_ARGS) * Break the line if we were parsed subsequent the current node. * This makes the page structure be more consistent. */ - if (MMAN_spc & outflags && NODE_LINE & n->flags) + if (outflags & MMAN_spc && + n->flags & NODE_LINE && + !roff_node_transparent(n)) outflags |= MMAN_nl; act = NULL; @@ -775,13 +777,20 @@ post_font(DECL_ARGS) static void post_percent(DECL_ARGS) { + struct roff_node *np, *nn, *nnn; if (mdoc_man_act(n->tok)->pre == pre_em) font_pop(); - if (n->next) { - print_word(","); - if (n->prev && n->prev->tok == n->tok && - n->next->tok == n->tok) + + if ((nn = roff_node_next(n)) != NULL) { + np = roff_node_prev(n); + nnn = nn == NULL ? NULL : roff_node_next(nn); + if (nn->tok != n->tok || + (np != NULL && np->tok == n->tok) || + (nnn != NULL && nnn->tok == n->tok)) + print_word(","); + if (nn->tok == n->tok && + (nnn == NULL || nnn->tok != n->tok)) print_word("and"); } else { print_word("."); @@ -849,13 +858,15 @@ post_sect(DECL_ARGS) /* See mdoc_term.c, synopsis_pre() for comments. */ static void -pre_syn(const struct roff_node *n) +pre_syn(struct roff_node *n) { + struct roff_node *np; - if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags)) + if ((n->flags & NODE_SYNPRETTY) == 0 || + (np = roff_node_prev(n)) == NULL) return; - if (n->prev->tok == n->tok && + if (np->tok == n->tok && MDOC_Ft != n->tok && MDOC_Fo != n->tok && MDOC_Fn != n->tok) { @@ -863,7 +874,7 @@ pre_syn(const struct roff_node *n) return; } - switch (n->prev->tok) { + switch (np->tok) { case MDOC_Fd: case MDOC_Fn: case MDOC_Fo: @@ -939,11 +950,10 @@ static int pre_bd(DECL_ARGS) { outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br); - - if (DISP_unfilled == n->norm->Bd.type || - DISP_literal == n->norm->Bd.type) + if (n->norm->Bd.type == DISP_unfilled || + n->norm->Bd.type == DISP_literal) print_line(".nf", 0); - if (0 == n->norm->Bd.comp && NULL != n->parent->prev) + if (n->norm->Bd.comp == 0 && roff_node_prev(n->parent) != NULL) outflags |= MMAN_sp; print_offs(n->norm->Bd.offs, 1); return 1; @@ -975,7 +985,7 @@ post_bd(DECL_ARGS) } /* Maybe we are inside an enclosing list? */ - if (NULL != n->parent->next) + if (roff_node_next(n->parent) != NULL) mid_it(); } @@ -1100,16 +1110,15 @@ post_bl(DECL_ARGS) print_line(".RE", MMAN_nl); assert(Bl_stack_len); Bl_stack_len--; - assert(0 == Bl_stack[Bl_stack_len]); + assert(Bl_stack[Bl_stack_len] == 0); } else { outflags |= MMAN_PP | MMAN_nl; outflags &= ~(MMAN_sp | MMAN_br); } /* Maybe we are inside an enclosing list? */ - if (NULL != n->parent->next) + if (roff_node_next(n->parent) != NULL) mid_it(); - } static void @@ -1121,7 +1130,6 @@ pre_br(DECL_ARGS) static int pre_dl(DECL_ARGS) { - print_offs("6n", 0); return 1; } @@ -1129,11 +1137,10 @@ pre_dl(DECL_ARGS) static void post_dl(DECL_ARGS) { - print_line(".RE", MMAN_nl); /* Maybe we are inside an enclosing list? */ - if (NULL != n->parent->next) + if (roff_node_next(n->parent) != NULL) mid_it(); } @@ -1234,15 +1241,15 @@ pre_fa(DECL_ARGS) static void post_fa(DECL_ARGS) { + struct roff_node *nn; - if (NULL != n->next && MDOC_Fa == n->next->tok) + if ((nn = roff_node_next(n)) != NULL && nn->tok == MDOC_Fa) print_word(","); } static int pre_fd(DECL_ARGS) { - pre_syn(n); font_push('B'); return 1; @@ -1251,7 +1258,6 @@ pre_fd(DECL_ARGS) static void post_fd(DECL_ARGS) { - font_pop(); outflags |= MMAN_br; } @@ -1259,7 +1265,6 @@ post_fd(DECL_ARGS) static int pre_fl(DECL_ARGS) { - font_push('B'); print_word("\\-"); if (n->child != NULL) @@ -1270,12 +1275,13 @@ pre_fl(DECL_ARGS) static void post_fl(DECL_ARGS) { + struct roff_node *nn; font_pop(); - if (!(n->child != NULL || - n->next == NULL || - n->next->type == ROFFT_TEXT || - n->next->flags & NODE_LINE)) + if (n->child == NULL && + ((nn = roff_node_next(n)) != NULL && + nn->type != ROFFT_TEXT && + (nn->flags & NODE_LINE) == 0)) outflags &= ~MMAN_spc; } @@ -1418,9 +1424,9 @@ pre_it(DECL_ARGS) case ROFFT_HEAD: outflags |= MMAN_PP | MMAN_nl; bln = n->parent->parent; - if (0 == bln->norm->Bl.comp || - (NULL == n->parent->prev && - NULL == bln->parent->prev)) + if (bln->norm->Bl.comp == 0 || + (n->parent->prev == NULL && + roff_node_prev(bln->parent) == NULL)) outflags |= MMAN_sp; outflags &= ~MMAN_br; switch (bln->norm->Bl.type) { @@ -1632,17 +1638,22 @@ pre_nm(DECL_ARGS) { char *name; - if (n->type == ROFFT_BLOCK) { + switch (n->type) { + case ROFFT_BLOCK: outflags |= MMAN_Bk; pre_syn(n); - } - if (n->type != ROFFT_ELEM && n->type != ROFFT_HEAD) return 1; + case ROFFT_HEAD: + case ROFFT_ELEM: + break; + default: + return 1; + } name = n->child == NULL ? NULL : n->child->string; - if (NULL == name) + if (name == NULL) return 0; if (n->type == ROFFT_HEAD) { - if (NULL == n->parent->prev) + if (roff_node_prev(n->parent) == NULL) outflags |= MMAN_sp; print_block(".HP", 0); printf(" %dn", man_strlen(name) + 1); diff --git a/usr.bin/mandoc/mdoc_markdown.c b/usr.bin/mandoc/mdoc_markdown.c index 22b46978320..fe87440b5c1 100644 --- a/usr.bin/mandoc/mdoc_markdown.c +++ b/usr.bin/mandoc/mdoc_markdown.c @@ -1,6 +1,6 @@ -/* $OpenBSD: mdoc_markdown.c,v 1.33 2020/02/20 00:29:10 schwarze Exp $ */ +/* $OpenBSD: mdoc_markdown.c,v 1.34 2020/02/27 01:25:57 schwarze Exp $ */ /* - * Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -310,7 +310,9 @@ md_node(struct roff_node *n) if (outflags & MD_nonl) outflags &= ~(MD_nl | MD_sp); - else if (outflags & MD_spc && n->flags & NODE_LINE) + else if (outflags & MD_spc && + n->flags & NODE_LINE && + !roff_node_transparent(n)) outflags |= MD_nl; act = NULL; @@ -787,14 +789,17 @@ md_post_word(struct roff_node *n) static void md_post_pc(struct roff_node *n) { + struct roff_node *nn; + md_post_raw(n); if (n->parent->tok != MDOC_Rs) return; - if (n->next != NULL) { + + if ((nn = roff_node_next(n)) != NULL) { md_word(","); - if (n->prev != NULL && - n->prev->tok == n->tok && - n->next->tok == n->tok) + if (nn->tok == n->tok && + (nn = roff_node_prev(n)) != NULL && + nn->tok == n->tok) md_word("and"); } else { md_word("."); @@ -811,10 +816,13 @@ md_pre_skip(struct roff_node *n) static void md_pre_syn(struct roff_node *n) { - if (n->prev == NULL || ! (n->flags & NODE_SYNPRETTY)) + struct roff_node *np; + + if ((n->flags & NODE_SYNPRETTY) == 0 || + (np = roff_node_prev(n)) == NULL) return; - if (n->prev->tok == n->tok && + if (np->tok == n->tok && n->tok != MDOC_Ft && n->tok != MDOC_Fo && n->tok != MDOC_Fn) { @@ -822,7 +830,7 @@ md_pre_syn(struct roff_node *n) return; } - switch (n->prev->tok) { + switch (np->tok) { case MDOC_Fd: case MDOC_Fn: case MDOC_Fo: @@ -1053,7 +1061,9 @@ md_pre_Fa(struct roff_node *n) static void md_post_Fa(struct roff_node *n) { - if (n->next != NULL && n->next->tok == MDOC_Fa) + struct roff_node *nn; + + if ((nn = roff_node_next(n)) != NULL && nn->tok == MDOC_Fa) md_word(","); } @@ -1075,9 +1085,11 @@ md_post_Fd(struct roff_node *n) static void md_post_Fl(struct roff_node *n) { + struct roff_node *nn; + md_post_raw(n); - if (n->child == NULL && n->next != NULL && - n->next->type != ROFFT_TEXT && !(n->next->flags & NODE_LINE)) + if (n->child == NULL && (nn = roff_node_next(n)) != NULL && + nn->type != ROFFT_TEXT && (nn->flags & NODE_LINE) == 0) outflags &= ~MD_spc; } diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c index 5e7412e124b..dab449d9da4 100644 --- a/usr.bin/mandoc/mdoc_term.c +++ b/usr.bin/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_term.c,v 1.275 2020/01/20 10:29:31 schwarze Exp $ */ +/* $OpenBSD: mdoc_term.c,v 1.276 2020/02/27 01:25:57 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -52,14 +52,12 @@ struct mdoc_term_act { static int a2width(const struct termp *, const char *); static void print_bvspace(struct termp *, - const struct roff_node *, - const struct roff_node *); + struct roff_node *, struct roff_node *); static void print_mdoc_node(DECL_ARGS); static void print_mdoc_nodelist(DECL_ARGS); static void print_mdoc_head(struct termp *, const struct roff_meta *); static void print_mdoc_foot(struct termp *, const struct roff_meta *); -static void synopsis_pre(struct termp *, - const struct roff_node *); +static void synopsis_pre(struct termp *, struct roff_node *); static void termp____post(DECL_ARGS); static void termp__t_post(DECL_ARGS); @@ -580,29 +578,20 @@ a2width(const struct termp *p, const char *v) * too. */ static void -print_bvspace(struct termp *p, - const struct roff_node *bl, - const struct roff_node *n) +print_bvspace(struct termp *p, struct roff_node *bl, struct roff_node *n) { - const struct roff_node *nn; - - assert(n); + struct roff_node *nn; term_newln(p); - if (MDOC_Bd == bl->tok && bl->norm->Bd.comp) - return; - if (MDOC_Bl == bl->tok && bl->norm->Bl.comp) + if ((bl->tok == MDOC_Bd && bl->norm->Bd.comp) || + (bl->tok == MDOC_Bl && bl->norm->Bl.comp)) return; /* Do not vspace directly after Ss/Sh. */ nn = n; - while (nn->prev != NULL && - (nn->prev->type == ROFFT_COMMENT || - nn->prev->flags & NODE_NOPRT)) - nn = nn->prev; - while (nn->prev == NULL) { + while (roff_node_prev(nn) == NULL) { do { nn = nn->parent; if (nn->type == ROFFT_ROOT) @@ -615,22 +604,18 @@ print_bvspace(struct termp *p, break; } - /* A `-column' does not assert vspace within the list. */ - - if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type) - if (n->prev && MDOC_It == n->prev->tok) - return; - - /* A `-diag' without body does not vspace. */ - - if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type) - if (n->prev && MDOC_It == n->prev->tok) { - assert(n->prev->body); - if (NULL == n->prev->body->child) - return; - } + /* + * No vertical space after: + * items in .Bl -column + * items without a body in .Bl -diag + */ - term_vspace(p); + if (bl->tok != MDOC_Bl || + n->prev == NULL || n->prev->tok != MDOC_It || + (bl->norm->Bl.type != LIST_column && + (bl->norm->Bl.type != LIST_diag || + n->prev->body->child != NULL))) + term_vspace(p); } @@ -1041,15 +1026,16 @@ termp_nm_post(DECL_ARGS) static int termp_fl_pre(DECL_ARGS) { + struct roff_node *nn; termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_BOLD); term_word(p, "\\-"); - if (!(n->child == NULL && - (n->next == NULL || - n->next->type == ROFFT_TEXT || - n->next->flags & NODE_LINE))) + if (n->child != NULL || + ((nn = roff_node_next(n)) != NULL && + nn->type != ROFFT_TEXT && + (nn->flags & NODE_LINE) == 0)) p->flags |= TERMP_NOSPACE; return 1; @@ -1058,10 +1044,11 @@ termp_fl_pre(DECL_ARGS) static int termp__a_pre(DECL_ARGS) { + struct roff_node *nn; - if (n->prev && MDOC__A == n->prev->tok) - if (NULL == n->next || MDOC__A != n->next->tok) - term_word(p, "and"); + if ((nn = roff_node_prev(n)) != NULL && nn->tok == MDOC__A && + ((nn = roff_node_next(n)) == NULL || nn->tok != MDOC__A)) + term_word(p, "and"); return 1; } @@ -1102,10 +1089,9 @@ termp_ns_pre(DECL_ARGS) static int termp_rs_pre(DECL_ARGS) { - if (SEC_SEE_ALSO != n->sec) return 1; - if (n->type == ROFFT_BLOCK && n->prev != NULL) + if (n->type == ROFFT_BLOCK && roff_node_prev(n) != NULL) term_vspace(p); return 1; } @@ -1179,13 +1165,12 @@ termp_xr_pre(DECL_ARGS) * macro combos). */ static void -synopsis_pre(struct termp *p, const struct roff_node *n) +synopsis_pre(struct termp *p, struct roff_node *n) { - /* - * Obviously, if we're not in a SYNOPSIS or no prior macros - * exist, do nothing. - */ - if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags)) + struct roff_node *np; + + if ((n->flags & NODE_SYNPRETTY) == 0 || + (np = roff_node_prev(n)) == NULL) return; /* @@ -1193,7 +1178,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n) * newline and return. UNLESS we're `Fo', `Fn', `Fn', in which * case we soldier on. */ - if (n->prev->tok == n->tok && + if (np->tok == n->tok && MDOC_Ft != n->tok && MDOC_Fo != n->tok && MDOC_Fn != n->tok) { @@ -1206,7 +1191,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n) * another (or Fn/Fo, which we've let slip through) then assert * vertical space, else only newline and move on. */ - switch (n->prev->tok) { + switch (np->tok) { case MDOC_Fd: case MDOC_Fn: case MDOC_Fo: @@ -1215,7 +1200,7 @@ synopsis_pre(struct termp *p, const struct roff_node *n) term_vspace(p); break; case MDOC_Ft: - if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { + if (n->tok != MDOC_Fn && n->tok != MDOC_Fo) { term_vspace(p); break; } @@ -1269,6 +1254,7 @@ termp_fd_post(DECL_ARGS) static int termp_sh_pre(DECL_ARGS) { + struct roff_node *np; switch (n->type) { case ROFFT_BLOCK: @@ -1276,10 +1262,9 @@ termp_sh_pre(DECL_ARGS) * Vertical space before sections, except * when the previous section was empty. */ - if (n->prev == NULL || - n->prev->tok != MDOC_Sh || - (n->prev->body != NULL && - n->prev->body->child != NULL)) + if ((np = roff_node_prev(n)) == NULL || + np->tok != MDOC_Sh || + (np->body != NULL && np->body->child != NULL)) term_vspace(p); break; case ROFFT_HEAD: @@ -1430,19 +1415,22 @@ termp_fa_pre(DECL_ARGS) term_fontpush(p, TERMFONT_UNDER); return 1; } - - for (nn = n->child; nn; nn = nn->next) { + for (nn = n->child; nn != NULL; nn = nn->next) { term_fontpush(p, TERMFONT_UNDER); p->flags |= TERMP_NBRWORD; term_word(p, nn->string); term_fontpop(p); - - if (nn->next || (n->next && n->next->tok == MDOC_Fa)) { + if (nn->next != NULL) { p->flags |= TERMP_NOSPACE; term_word(p, ","); } } - + if (n->child != NULL && + (nn = roff_node_next(n)) != NULL && + nn->tok == MDOC_Fa) { + p->flags |= TERMP_NOSPACE; + term_word(p, ","); + } return 0; } @@ -1522,24 +1510,18 @@ termp_xx_post(DECL_ARGS) static void termp_pf_post(DECL_ARGS) { - - if ( ! (n->next == NULL || n->next->flags & NODE_LINE)) + if (n->next != NULL && (n->next->flags & NODE_LINE) == 0) p->flags |= TERMP_NOSPACE; } static int termp_ss_pre(DECL_ARGS) { - struct roff_node *nn; - switch (n->type) { case ROFFT_BLOCK: - term_newln(p); - for (nn = n->prev; nn != NULL; nn = nn->prev) - if (nn->type != ROFFT_COMMENT && - (nn->flags & NODE_NOPRT) == 0) - break; - if (nn != NULL) + if (roff_node_prev(n) == NULL) + term_newln(p); + else term_vspace(p); break; case ROFFT_HEAD: @@ -1555,14 +1537,12 @@ termp_ss_pre(DECL_ARGS) default: break; } - return 1; } static void termp_ss_post(DECL_ARGS) { - if (n->type == ROFFT_HEAD || n->type == ROFFT_BODY) term_newln(p); } @@ -1890,24 +1870,26 @@ termp_ap_pre(DECL_ARGS) static void termp____post(DECL_ARGS) { + struct roff_node *nn; /* * Handle lists of authors. In general, print each followed by * a comma. Don't print the comma if there are only two * authors. */ - if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok) - if (NULL == n->next->next || MDOC__A != n->next->next->tok) - if (NULL == n->prev || MDOC__A != n->prev->tok) - return; + if (n->tok == MDOC__A && + (nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A && + ((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) && + ((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A)) + return; /* TODO: %U. */ - if (NULL == n->parent || MDOC_Rs != n->parent->tok) + if (n->parent == NULL || n->parent->tok != MDOC_Rs) return; p->flags |= TERMP_NOSPACE; - if (NULL == n->next) { + if (roff_node_next(n) == NULL) { term_word(p, "."); p->flags |= TERMP_SENTENCE; } else diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c index b7ae573a127..902294e8d79 100644 --- a/usr.bin/mandoc/mdoc_validate.c +++ b/usr.bin/mandoc/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_validate.c,v 1.292 2020/01/19 17:59:01 schwarze Exp $ */ +/* $OpenBSD: mdoc_validate.c,v 1.293 2020/02/27 01:25:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -1745,8 +1745,7 @@ post_bl_head(POST_ARGS) static void post_bl(POST_ARGS) { - struct roff_node *nparent, *nprev; /* of the Bl block */ - struct roff_node *nblock, *nbody; /* of the Bl */ + struct roff_node *nbody; /* of the Bl */ struct roff_node *nchild, *nnext; /* of the Bl body */ const char *prev_Er; int order; @@ -1767,88 +1766,73 @@ post_bl(POST_ARGS) if (nbody->end != ENDBODY_NOT) return; - nchild = nbody->child; - if (nchild == NULL) { - mandoc_msg(MANDOCERR_BLK_EMPTY, - nbody->line, nbody->pos, "Bl"); - return; + /* + * Up to the first item, move nodes before the list, + * but leave transparent nodes where they are + * if they precede an item. + * The next non-transparent node is kept in nchild. + * It only needs to be updated after a non-transparent + * node was moved out, and at the very beginning + * when no node at all was moved yet. + */ + + nchild = mdoc->last; + for (;;) { + if (nchild == mdoc->last) + nchild = roff_node_child(nbody); + if (nchild == NULL) { + mdoc->last = nbody; + mandoc_msg(MANDOCERR_BLK_EMPTY, + nbody->line, nbody->pos, "Bl"); + return; + } + if (nchild->tok == MDOC_It) { + mdoc->last = nbody; + break; + } + mandoc_msg(MANDOCERR_BL_MOVE, nbody->child->line, + nbody->child->pos, "%s", roff_name[nbody->child->tok]); + if (nbody->parent->prev == NULL) { + mdoc->last = nbody->parent->parent; + mdoc->next = ROFF_NEXT_CHILD; + } else { + mdoc->last = nbody->parent->prev; + mdoc->next = ROFF_NEXT_SIBLING; + } + roff_node_relink(mdoc, nbody->child); } + + /* + * We have reached the first item, + * so moving nodes out is no longer possible. + * But in .Bl -column, the first rows may be implicit, + * that is, they may not start with .It macros. + * Such rows may be followed by nodes generated on the + * roff level, for example .TS. + * Wrap such roff nodes into an implicit row. + */ + while (nchild != NULL) { - nnext = nchild->next; - if (nchild->tok == MDOC_It || - ((nchild->tok == MDOC_Sm || nchild->tok == MDOC_Tg) && - nnext != NULL && nnext->tok == MDOC_It)) { - nchild = nnext; + if (nchild->tok == MDOC_It) { + nchild = roff_node_next(nchild); continue; } - - /* - * In .Bl -column, the first rows may be implicit, - * that is, they may not start with .It macros. - * Such rows may be followed by nodes generated on the - * roff level, for example .TS, which cannot be moved - * out of the list. In that case, wrap such roff nodes - * into an implicit row. - */ - - if (nchild->prev != NULL) { - mdoc->last = nchild; - mdoc->next = ROFF_NEXT_SIBLING; - roff_block_alloc(mdoc, nchild->line, - nchild->pos, MDOC_It); - roff_head_alloc(mdoc, nchild->line, - nchild->pos, MDOC_It); + nnext = nchild->next; + mdoc->last = nchild->prev; + mdoc->next = ROFF_NEXT_SIBLING; + roff_block_alloc(mdoc, nchild->line, nchild->pos, MDOC_It); + roff_head_alloc(mdoc, nchild->line, nchild->pos, MDOC_It); + mdoc->next = ROFF_NEXT_SIBLING; + roff_body_alloc(mdoc, nchild->line, nchild->pos, MDOC_It); + while (nchild->tok != MDOC_It) { + roff_node_relink(mdoc, nchild); + if (nnext == NULL) + break; + nchild = nnext; + nnext = nchild->next; mdoc->next = ROFF_NEXT_SIBLING; - roff_body_alloc(mdoc, nchild->line, - nchild->pos, MDOC_It); - while (nchild->tok != MDOC_It) { - roff_node_relink(mdoc, nchild); - if ((nchild = nnext) == NULL) - break; - nnext = nchild->next; - mdoc->next = ROFF_NEXT_SIBLING; - } - mdoc->last = nbody; - continue; } - - mandoc_msg(MANDOCERR_BL_MOVE, nchild->line, nchild->pos, - "%s", roff_name[nchild->tok]); - - /* - * Move the node out of the Bl block. - * First, collect all required node pointers. - */ - - nblock = nbody->parent; - nprev = nblock->prev; - nparent = nblock->parent; - - /* - * Unlink this child. - */ - - nbody->child = nnext; - if (nnext == NULL) - nbody->last = NULL; - else - nnext->prev = NULL; - - /* - * Relink this child. - */ - - nchild->parent = nparent; - nchild->prev = nprev; - nchild->next = nblock; - - nblock->prev = nchild; - if (nprev == NULL) - nparent->child = nchild; - else - nprev->next = nchild; - - nchild = nnext; + mdoc->last = nbody; } if (mdoc->meta.os_e != MANDOC_OS_NETBSD) @@ -2485,20 +2469,20 @@ post_ignpar(POST_ARGS) static void post_prevpar(POST_ARGS) { - struct roff_node *n; + struct roff_node *n, *np; n = mdoc->last; - if (NULL == n->prev) - return; if (n->type != ROFFT_ELEM && n->type != ROFFT_BLOCK) return; + if ((np = roff_node_prev(n)) == NULL) + return; /* * Don't allow `Pp' prior to a paragraph-type * block: `Pp' or non-compact `Bd' or `Bl'. */ - if (n->prev->tok != MDOC_Pp && n->prev->tok != ROFF_br) + if (np->tok != MDOC_Pp && np->tok != ROFF_br) return; if (n->tok == MDOC_Bl && n->norm->Bl.comp) return; @@ -2507,9 +2491,9 @@ post_prevpar(POST_ARGS) if (n->tok == MDOC_It && n->parent->norm->Bl.comp) return; - mandoc_msg(MANDOCERR_PAR_SKIP, n->prev->line, n->prev->pos, - "%s before %s", roff_name[n->prev->tok], roff_name[n->tok]); - roff_node_delete(mdoc, n->prev); + mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos, + "%s before %s", roff_name[np->tok], roff_name[n->tok]); + roff_node_delete(mdoc, np); } static void diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 35eec08824c..9a8e77a9893 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.241 2020/01/19 17:59:01 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.242 2020/02/27 01:25:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -1112,6 +1112,59 @@ roff_node_delete(struct roff_man *man, struct roff_node *n) roff_node_free(n); } +int +roff_node_transparent(struct roff_node *n) +{ + if (n == NULL) + return 0; + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) + return 1; + switch (n->tok) { + case ROFF_ft: + case ROFF_ll: + case ROFF_mc: + case ROFF_po: + case ROFF_ta: + case MDOC_Db: + case MDOC_Es: + case MDOC_Sm: + case MDOC_Tg: + case MAN_DT: + case MAN_UC: + case MAN_PD: + case MAN_AT: + return 1; + default: + return 0; + } +} + +struct roff_node * +roff_node_child(struct roff_node *n) +{ + for (n = n->child; roff_node_transparent(n); n = n->next) + continue; + return n; +} + +struct roff_node * +roff_node_prev(struct roff_node *n) +{ + do { + n = n->prev; + } while (roff_node_transparent(n)); + return n; +} + +struct roff_node * +roff_node_next(struct roff_node *n) +{ + do { + n = n->next; + } while (roff_node_transparent(n)); + return n; +} + void deroff(char **dest, const struct roff_node *n) { diff --git a/usr.bin/mandoc/roff.h b/usr.bin/mandoc/roff.h index 1479a12688f..24c0e39bc1f 100644 --- a/usr.bin/mandoc/roff.h +++ b/usr.bin/mandoc/roff.h @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.h,v 1.52 2020/01/19 17:59:01 schwarze Exp $ */ +/* $OpenBSD: roff.h,v 1.53 2020/02/27 01:25:58 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> @@ -549,5 +549,9 @@ struct roff_meta { extern const char *const *roff_name; -int arch_valid(const char *, enum mandoc_os); -void deroff(char **, const struct roff_node *); +int arch_valid(const char *, enum mandoc_os); +void deroff(char **, const struct roff_node *); +struct roff_node *roff_node_child(struct roff_node *); +struct roff_node *roff_node_next(struct roff_node *); +struct roff_node *roff_node_prev(struct roff_node *); +int roff_node_transparent(struct roff_node *); diff --git a/usr.bin/mandoc/roff_validate.c b/usr.bin/mandoc/roff_validate.c index 5b6686c2d4c..6fa4f334456 100644 --- a/usr.bin/mandoc/roff_validate.c +++ b/usr.bin/mandoc/roff_validate.c @@ -1,6 +1,6 @@ -/* $OpenBSD: roff_validate.c,v 1.18 2018/12/31 09:02:30 schwarze Exp $ */ +/* $OpenBSD: roff_validate.c,v 1.19 2020/02/27 01:25:58 schwarze Exp $ */ /* - * Copyright (c) 2010, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2017, 2018, 2020 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -75,7 +75,7 @@ roff_valid_br(ROFF_VALID_ARGS) return; } - if ((np = n->prev) == NULL) + if ((np = roff_node_prev(n)) == NULL) return; switch (np->tok) { @@ -129,7 +129,7 @@ roff_valid_sp(ROFF_VALID_ARGS) { struct roff_node *np; - if ((np = n->prev) == NULL) + if ((np = roff_node_prev(n)) == NULL) return; switch (np->tok) { |