=================================================================== RCS file: /cvs/mandoc/mdoc_validate.c,v retrieving revision 1.380 retrieving revision 1.391 diff -u -p -r1.380 -r1.391 --- mandoc/mdoc_validate.c 2020/03/13 15:32:28 1.380 +++ mandoc/mdoc_validate.c 2022/06/08 16:31:46 1.391 @@ -1,6 +1,6 @@ -/* $Id: mdoc_validate.c,v 1.380 2020/03/13 15:32:28 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.391 2022/06/08 16:31:46 schwarze Exp $ */ /* - * Copyright (c) 2010-2020 Ingo Schwarze + * Copyright (c) 2010-2021 Ingo Schwarze * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010 Joerg Sonnenberger * @@ -37,11 +37,11 @@ #include "mandoc.h" #include "mandoc_xr.h" #include "roff.h" -#include "tag.h" #include "mdoc.h" #include "libmandoc.h" #include "roff_int.h" #include "libmdoc.h" +#include "tag.h" /* FIXME: .Bl -diag can't have non-text children in HEAD. */ @@ -92,11 +92,11 @@ static void post_es(POST_ARGS); static void post_eoln(POST_ARGS); static void post_ex(POST_ARGS); static void post_fa(POST_ARGS); +static void post_fl(POST_ARGS); static void post_fn(POST_ARGS); static void post_fname(POST_ARGS); static void post_fo(POST_ARGS); static void post_hyph(POST_ARGS); -static void post_ignpar(POST_ARGS); static void post_it(POST_ARGS); static void post_lb(POST_ARGS); static void post_nd(POST_ARGS); @@ -109,6 +109,7 @@ static void post_prevpar(POST_ARGS); static void post_root(POST_ARGS); static void post_rs(POST_ARGS); static void post_rv(POST_ARGS); +static void post_section(POST_ARGS); static void post_sh(POST_ARGS); static void post_sh_head(POST_ARGS); static void post_sh_name(POST_ARGS); @@ -129,7 +130,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = post_dt, /* Dt */ post_os, /* Os */ post_sh, /* Sh */ - post_ignpar, /* Ss */ + post_section, /* Ss */ post_par, /* Pp */ post_display, /* D1 */ post_display, /* Dl */ @@ -150,7 +151,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = post_ex, /* Ex */ post_fa, /* Fa */ NULL, /* Fd */ - post_tag, /* Fl */ + post_fl, /* Fl */ post_fn, /* Fn */ post_delim_nb, /* Ft */ post_tag, /* Ic */ @@ -163,7 +164,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = post_defaults, /* Pa */ post_rv, /* Rv */ post_st, /* St */ - post_delim_nb, /* Va */ + post_tag, /* Va */ post_delim_nb, /* Vt */ post_xr, /* Xr */ NULL, /* %A */ @@ -1105,13 +1106,15 @@ post_tg(POST_ARGS) struct roff_node *n; /* The .Tg node. */ struct roff_node *nch; /* The first child of the .Tg node. */ struct roff_node *nn; /* The next node after the .Tg node. */ + struct roff_node *np; /* The parent of the next node. */ struct roff_node *nt; /* The TEXT node containing the tag. */ size_t len; /* The number of bytes in the tag. */ /* Find the next node. */ n = mdoc->last; for (nn = n; nn != NULL; nn = nn->parent) { - if (nn->next != NULL) { + if (nn->type != ROFFT_HEAD && nn->type != ROFFT_BODY && + nn->type != ROFFT_TAIL && nn->next != NULL) { nn = nn->next; break; } @@ -1150,7 +1153,7 @@ post_tg(POST_ARGS) } /* By default, tag the .Tg node itself. */ - if (nn == NULL) + if (nn == NULL || nn->flags & NODE_ID) nn = n; /* Explicit tagging of specific macros. */ @@ -1158,8 +1161,41 @@ post_tg(POST_ARGS) case MDOC_Sh: case MDOC_Ss: case MDOC_Fo: - nn = nn->head; - /* FALLTHROUGH */ + nn = nn->head->child == NULL ? n : nn->head; + break; + case MDOC_It: + np = nn->parent; + while (np->tok != MDOC_Bl) + np = np->parent; + switch (np->norm->Bl.type) { + case LIST_column: + break; + case LIST_diag: + case LIST_hang: + case LIST_inset: + case LIST_ohang: + case LIST_tag: + nn = nn->head; + break; + case LIST_bullet: + case LIST_dash: + case LIST_enum: + case LIST_hyphen: + case LIST_item: + nn = nn->body->child == NULL ? n : nn->body; + break; + default: + abort(); + } + break; + case MDOC_Bd: + case MDOC_Bl: + case MDOC_D1: + case MDOC_Dl: + nn = nn->body->child == NULL ? n : nn->body; + break; + case MDOC_Pp: + break; case MDOC_Cm: case MDOC_Dv: case MDOC_Em: @@ -1172,9 +1208,9 @@ post_tg(POST_ARGS) case MDOC_Ms: case MDOC_No: case MDOC_Sy: - if (nn->child != NULL && (nn->flags & NODE_ID) == 0) - break; - /* FALLTHROUGH */ + if (nn->child == NULL) + nn = n; + break; default: nn = n; break; @@ -1594,6 +1630,29 @@ post_es(POST_ARGS) } static void +post_fl(POST_ARGS) +{ + struct roff_node *n; + char *cp; + + /* + * Transform ".Fl Fl long" to ".Fl \-long", + * resulting for example in better HTML output. + */ + + n = mdoc->last; + if (n->prev != NULL && n->prev->tok == MDOC_Fl && + n->prev->child == NULL && n->child != NULL && + (n->flags & NODE_LINE) == 0) { + mandoc_asprintf(&cp, "\\-%s", n->child->string); + free(n->child->string); + n->child->string = cp; + roff_node_delete(mdoc, n->prev); + } + post_tag(mdoc); +} + +static void post_xx(POST_ARGS) { struct roff_node *n; @@ -2164,10 +2223,11 @@ post_rs(POST_ARGS) static void post_hyph(POST_ARGS) { - struct roff_node *nch; + struct roff_node *n, *nch; char *cp; - for (nch = mdoc->last->child; nch != NULL; nch = nch->next) { + n = mdoc->last; + for (nch = n->child; nch != NULL; nch = nch->next) { if (nch->type != ROFFT_TEXT) continue; cp = nch->string; @@ -2176,8 +2236,11 @@ post_hyph(POST_ARGS) while (*(++cp) != '\0') if (*cp == '-' && isalpha((unsigned char)cp[-1]) && - isalpha((unsigned char)cp[1])) + isalpha((unsigned char)cp[1])) { + if (n->tag == NULL && n->flags & NODE_ID) + n->tag = mandoc_strdup(nch->string); *cp = ASCII_HYPH; + } } } @@ -2202,7 +2265,7 @@ post_sx(POST_ARGS) static void post_sh(POST_ARGS) { - post_ignpar(mdoc); + post_section(mdoc); switch (mdoc->last->type) { case ROFFT_HEAD: @@ -2535,15 +2598,31 @@ post_xr(POST_ARGS) } static void -post_ignpar(POST_ARGS) +post_section(POST_ARGS) { - struct roff_node *np; + struct roff_node *n, *nch; + char *cp, *tag; - switch (mdoc->last->type) { + n = mdoc->last; + switch (n->type) { case ROFFT_BLOCK: post_prevpar(mdoc); return; case ROFFT_HEAD: + tag = NULL; + deroff(&tag, n); + if (tag != NULL) { + for (cp = tag; *cp != '\0'; cp++) + if (*cp == ' ') + *cp = '_'; + if ((nch = n->child) != NULL && + nch->type == ROFFT_TEXT && + strcmp(nch->string, tag) == 0) + tag_put(NULL, TAG_STRONG, n); + else + tag_put(tag, TAG_FALLBACK, n); + free(tag); + } post_delim(mdoc); post_hyph(mdoc); return; @@ -2552,23 +2631,21 @@ post_ignpar(POST_ARGS) default: return; } - - if ((np = mdoc->last->child) != NULL) - if (np->tok == MDOC_Pp || - np->tok == ROFF_br || np->tok == ROFF_sp) { - mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos, - "%s after %s", roff_name[np->tok], - roff_name[mdoc->last->tok]); - roff_node_delete(mdoc, np); - } - - if ((np = mdoc->last->last) != NULL) - if (np->tok == MDOC_Pp || np->tok == ROFF_br) { - mandoc_msg(MANDOCERR_PAR_SKIP, np->line, np->pos, - "%s at the end of %s", roff_name[np->tok], - roff_name[mdoc->last->tok]); - roff_node_delete(mdoc, np); - } + if ((nch = n->child) != NULL && + (nch->tok == MDOC_Pp || nch->tok == ROFF_br || + nch->tok == ROFF_sp)) { + mandoc_msg(MANDOCERR_PAR_SKIP, nch->line, nch->pos, + "%s after %s", roff_name[nch->tok], + roff_name[n->tok]); + roff_node_delete(mdoc, nch); + } + if ((nch = n->last) != NULL && + (nch->tok == MDOC_Pp || nch->tok == ROFF_br)) { + mandoc_msg(MANDOCERR_PAR_SKIP, nch->line, nch->pos, + "%s at the end of %s", roff_name[nch->tok], + roff_name[n->tok]); + roff_node_delete(mdoc, nch); + } } static void @@ -2713,8 +2790,14 @@ post_dt(POST_ARGS) mandoc_msg(MANDOCERR_MSEC_BAD, nn->line, nn->pos, "Dt ... %s", nn->string); mdoc->meta.vol = mandoc_strdup(nn->string); - } else + } else { mdoc->meta.vol = mandoc_strdup(cp); + if (mdoc->filesec != '\0' && + mdoc->filesec != *nn->string && + *nn->string >= '1' && *nn->string <= '9') + mandoc_msg(MANDOCERR_MSEC_FILE, nn->line, nn->pos, + "*.%c vs Dt ... %c", mdoc->filesec, *nn->string); + } /* Optional third argument: architecture. */ @@ -2790,7 +2873,6 @@ post_os(POST_ARGS) { #ifndef OSNAME struct utsname utsname; - static char *defbuf; #endif struct roff_node *n; @@ -2827,15 +2909,15 @@ post_os(POST_ARGS) #ifdef OSNAME mdoc->meta.os = mandoc_strdup(OSNAME); #else /*!OSNAME */ - if (defbuf == NULL) { + if (mdoc->os_r == NULL) { if (uname(&utsname) == -1) { mandoc_msg(MANDOCERR_OS_UNAME, n->line, n->pos, "Os"); - defbuf = mandoc_strdup("UNKNOWN"); + mdoc->os_r = mandoc_strdup("UNKNOWN"); } else - mandoc_asprintf(&defbuf, "%s %s", + mandoc_asprintf(&mdoc->os_r, "%s %s", utsname.sysname, utsname.release); } - mdoc->meta.os = mandoc_strdup(defbuf); + mdoc->meta.os = mandoc_strdup(mdoc->os_r); #endif /*!OSNAME*/ out: