Print this page
9718 update mandoc to 1.14.4
*** 1,9 ****
! /* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
! * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
--- 1,9 ----
! /* $Id: mdoc_validate.c,v 1.360 2018/08/01 16:00:58 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
! * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*** 51,64 ****
};
typedef void (*v_post)(POST_ARGS);
static int build_list(struct roff_man *, int);
- static void check_text(struct roff_man *, int, int, char *);
static void check_argv(struct roff_man *,
struct roff_node *, struct mdoc_argv *);
static void check_args(struct roff_man *, struct roff_node *);
static void check_toptext(struct roff_man *, int, int, const char *);
static int child_an(const struct roff_node *);
static size_t macro2len(enum roff_tok);
static void rewrite_macro2len(struct roff_man *, char **);
static int similar(const char *, const char *);
--- 51,65 ----
};
typedef void (*v_post)(POST_ARGS);
static int build_list(struct roff_man *, int);
static void check_argv(struct roff_man *,
struct roff_node *, struct mdoc_argv *);
static void check_args(struct roff_man *, struct roff_node *);
+ static void check_text(struct roff_man *, int, int, char *);
+ static void check_text_em(struct roff_man *, int, int, char *);
static void check_toptext(struct roff_man *, int, int, const char *);
static int child_an(const struct roff_node *);
static size_t macro2len(enum roff_tok);
static void rewrite_macro2len(struct roff_man *, char **);
static int similar(const char *, const char *);
*** 167,182 ****
NULL, /* %P */
post_hyph, /* %R */
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */
NULL, /* %V */
NULL, /* Ac */
! post_delim_nb, /* Ao */
post_delim_nb, /* Aq */
post_at, /* At */
NULL, /* Bc */
post_bf, /* Bf */
! post_delim_nb, /* Bo */
NULL, /* Bq */
post_xx, /* Bsx */
post_bx, /* Bx */
post_obsolete, /* Db */
NULL, /* Dc */
--- 168,183 ----
NULL, /* %P */
post_hyph, /* %R */
post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */
NULL, /* %V */
NULL, /* Ac */
! NULL, /* Ao */
post_delim_nb, /* Aq */
post_at, /* At */
NULL, /* Bc */
post_bf, /* Bf */
! NULL, /* Bo */
NULL, /* Bq */
post_xx, /* Bsx */
post_bx, /* Bx */
post_obsolete, /* Db */
NULL, /* Dc */
*** 192,211 ****
post_ns, /* Ns */
post_xx, /* Nx */
post_xx, /* Ox */
NULL, /* Pc */
NULL, /* Pf */
! post_delim_nb, /* Po */
post_delim_nb, /* Pq */
NULL, /* Qc */
post_delim_nb, /* Ql */
! post_delim_nb, /* Qo */
post_delim_nb, /* Qq */
NULL, /* Re */
post_rs, /* Rs */
NULL, /* Sc */
! post_delim_nb, /* So */
post_delim_nb, /* Sq */
post_sm, /* Sm */
post_sx, /* Sx */
post_delim_nb, /* Sy */
post_useless, /* Tn */
--- 193,212 ----
post_ns, /* Ns */
post_xx, /* Nx */
post_xx, /* Ox */
NULL, /* Pc */
NULL, /* Pf */
! NULL, /* Po */
post_delim_nb, /* Pq */
NULL, /* Qc */
post_delim_nb, /* Ql */
! NULL, /* Qo */
post_delim_nb, /* Qq */
NULL, /* Re */
post_rs, /* Rs */
NULL, /* Sc */
! NULL, /* So */
post_delim_nb, /* Sq */
post_sm, /* Sm */
post_sx, /* Sx */
post_delim_nb, /* Sy */
post_useless, /* Tn */
*** 212,222 ****
post_xx, /* Ux */
NULL, /* Xc */
NULL, /* Xo */
post_fo, /* Fo */
NULL, /* Fc */
! post_delim_nb, /* Oo */
NULL, /* Oc */
post_bk, /* Bk */
NULL, /* Ek */
post_eoln, /* Bt */
post_obsolete, /* Hf */
--- 213,223 ----
post_xx, /* Ux */
NULL, /* Xc */
NULL, /* Xo */
post_fo, /* Fo */
NULL, /* Fc */
! NULL, /* Oo */
NULL, /* Oc */
post_bk, /* Bk */
NULL, /* Ek */
post_eoln, /* Bt */
post_obsolete, /* Hf */
*** 225,235 ****
post_lb, /* Lb */
post_par, /* Lp */
post_delim_nb, /* Lk */
post_defaults, /* Mt */
post_delim_nb, /* Brq */
! post_delim_nb, /* Bro */
NULL, /* Brc */
NULL, /* %C */
post_es, /* Es */
post_en, /* En */
post_xx, /* Dx */
--- 226,236 ----
post_lb, /* Lb */
post_par, /* Lp */
post_delim_nb, /* Lk */
post_defaults, /* Mt */
post_delim_nb, /* Brq */
! NULL, /* Bro */
NULL, /* Brc */
NULL, /* %C */
post_es, /* Es */
post_en, /* En */
post_xx, /* Dx */
*** 286,296 ****
void
mdoc_node_validate(struct roff_man *mdoc)
{
! struct roff_node *n;
const v_post *p;
n = mdoc->last;
mdoc->last = mdoc->last->child;
while (mdoc->last != NULL) {
--- 287,297 ----
void
mdoc_node_validate(struct roff_man *mdoc)
{
! struct roff_node *n, *np;
const v_post *p;
n = mdoc->last;
mdoc->last = mdoc->last->child;
while (mdoc->last != NULL) {
*** 303,321 ****
mdoc->last = n;
mdoc->next = ROFF_NEXT_SIBLING;
switch (n->type) {
case ROFFT_TEXT:
if (n->sec != SEC_SYNOPSIS ||
! (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd))
check_text(mdoc, n->line, n->pos, n->string);
! if (n->parent->tok == MDOC_It ||
! (n->parent->type == ROFFT_BODY &&
! (n->parent->tok == MDOC_Sh ||
! n->parent->tok == MDOC_Ss)))
check_toptext(mdoc, n->line, n->pos, n->string);
break;
case ROFFT_EQN:
case ROFFT_TBL:
break;
case ROFFT_ROOT:
post_root(mdoc);
--- 304,328 ----
mdoc->last = n;
mdoc->next = ROFF_NEXT_SIBLING;
switch (n->type) {
case ROFFT_TEXT:
+ np = n->parent;
if (n->sec != SEC_SYNOPSIS ||
! (np->tok != MDOC_Cd && np->tok != MDOC_Fd))
check_text(mdoc, n->line, n->pos, n->string);
! if (np->tok != MDOC_Ql && np->tok != MDOC_Dl &&
! (np->tok != MDOC_Bd ||
! (mdoc->flags & MDOC_LITERAL) == 0) &&
! (np->tok != MDOC_It || np->type != ROFFT_HEAD ||
! np->parent->parent->norm->Bl.type != LIST_diag))
! check_text_em(mdoc, n->line, n->pos, n->string);
! if (np->tok == MDOC_It || (np->type == ROFFT_BODY &&
! (np->tok == MDOC_Sh || np->tok == MDOC_Ss)))
check_toptext(mdoc, n->line, n->pos, n->string);
break;
+ case ROFFT_COMMENT:
case ROFFT_EQN:
case ROFFT_TBL:
break;
case ROFFT_ROOT:
post_root(mdoc);
*** 393,402 ****
--- 400,460 ----
mandoc_msg(MANDOCERR_FI_TAB, mdoc->parse,
ln, pos + (int)(p - cp), NULL);
}
static void
+ check_text_em(struct roff_man *mdoc, int ln, int pos, char *p)
+ {
+ const struct roff_node *np, *nn;
+ char *cp;
+
+ np = mdoc->last->prev;
+ nn = mdoc->last->next;
+
+ /* Look for em-dashes wrongly encoded as "--". */
+
+ for (cp = p; *cp != '\0'; cp++) {
+ if (cp[0] != '-' || cp[1] != '-')
+ continue;
+ cp++;
+
+ /* Skip input sequences of more than two '-'. */
+
+ if (cp[1] == '-') {
+ while (cp[1] == '-')
+ cp++;
+ continue;
+ }
+
+ /* Skip "--" directly attached to something else. */
+
+ if ((cp - p > 1 && cp[-2] != ' ') ||
+ (cp[1] != '\0' && cp[1] != ' '))
+ continue;
+
+ /* Require a letter right before or right afterwards. */
+
+ if ((cp - p > 2 ?
+ isalpha((unsigned char)cp[-3]) :
+ np != NULL &&
+ np->type == ROFFT_TEXT &&
+ *np->string != '\0' &&
+ isalpha((unsigned char)np->string[
+ strlen(np->string) - 1])) ||
+ (cp[1] != '\0' && cp[2] != '\0' ?
+ isalpha((unsigned char)cp[2]) :
+ nn != NULL &&
+ nn->type == ROFFT_TEXT &&
+ isalpha((unsigned char)*nn->string))) {
+ mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse,
+ ln, pos + (int)(cp - p) - 1, NULL);
+ break;
+ }
+ }
+ }
+
+ static void
check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p)
{
const char *cp, *cpr;
if (*p == '\0')
*** 528,539 ****
if (lc == nch->string + 1 && !isalnum((unsigned char)lc[-1]))
return;
/* At least three alphabetic words with a sentence ending. */
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em ||
! tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq ||
! tok == MDOC_Sy)) {
nw = 0;
for (cp = lc - 1; cp >= nch->string; cp--) {
if (*cp == ' ') {
nw++;
if (cp > nch->string && cp[-1] == ',')
--- 586,596 ----
if (lc == nch->string + 1 && !isalnum((unsigned char)lc[-1]))
return;
/* At least three alphabetic words with a sentence ending. */
if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em ||
! tok == MDOC_Li || tok == MDOC_Pq || tok == MDOC_Sy)) {
nw = 0;
for (cp = lc - 1; cp >= nch->string; cp--) {
if (*cp == ' ') {
nw++;
if (cp > nch->string && cp[-1] == ',')
*** 945,958 ****
mandoc_vmsg(MANDOCERR_LB_BAD, mdoc->parse, n->child->line,
n->child->pos, "Lb %s", n->child->string);
roff_word_alloc(mdoc, n->line, n->pos, "library");
mdoc->last->flags = NODE_NOSRC;
! roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq");
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
mdoc->last = mdoc->last->next;
! roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq");
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
mdoc->last = n;
}
static void
--- 1002,1015 ----
mandoc_vmsg(MANDOCERR_LB_BAD, mdoc->parse, n->child->line,
n->child->pos, "Lb %s", n->child->string);
roff_word_alloc(mdoc, n->line, n->pos, "library");
mdoc->last->flags = NODE_NOSRC;
! roff_word_alloc(mdoc, n->line, n->pos, "\\(lq");
mdoc->last->flags = NODE_DELIMO | NODE_NOSRC;
mdoc->last = mdoc->last->next;
! roff_word_alloc(mdoc, n->line, n->pos, "\\(rq");
mdoc->last->flags = NODE_DELIMC | NODE_NOSRC;
mdoc->last = n;
}
static void
*** 1912,1922 ****
(arch = arches[mdoc->meta.os_e]) != NULL) {
while (*arch != NULL && strcmp(*arch, mdoc->meta.arch))
arch++;
if (*arch == NULL) {
n = mdoc->first->child;
! while (n->tok != MDOC_Dt)
n = n->next;
n = n->child->next->next;
mandoc_vmsg(MANDOCERR_ARCH_BAD,
mdoc->parse, n->line, n->pos,
"Dt ... %s %s", mdoc->meta.arch,
--- 1969,1982 ----
(arch = arches[mdoc->meta.os_e]) != NULL) {
while (*arch != NULL && strcmp(*arch, mdoc->meta.arch))
arch++;
if (*arch == NULL) {
n = mdoc->first->child;
! while (n->tok != MDOC_Dt ||
! n->child == NULL ||
! n->child->next == NULL ||
! n->child->next->next == NULL)
n = n->next;
n = n->child->next->next;
mandoc_vmsg(MANDOCERR_ARCH_BAD,
mdoc->parse, n->line, n->pos,
"Dt ... %s %s", mdoc->meta.arch,
*** 1926,1937 ****
}
/* Check that we begin with a proper `Sh'. */
n = mdoc->first->child;
! while (n != NULL && n->tok >= MDOC_Dd &&
! mdoc_macros[n->tok].flags & MDOC_PROLOGUE)
n = n->next;
if (n == NULL)
mandoc_msg(MANDOCERR_DOC_EMPTY, mdoc->parse, 0, 0, NULL);
else if (n->tok != MDOC_Sh)
--- 1986,1999 ----
}
/* Check that we begin with a proper `Sh'. */
n = mdoc->first->child;
! while (n != NULL &&
! (n->type == ROFFT_COMMENT ||
! (n->tok >= MDOC_Dd &&
! mdoc_macros[n->tok].flags & MDOC_PROLOGUE)))
n = n->next;
if (n == NULL)
mandoc_msg(MANDOCERR_DOC_EMPTY, mdoc->parse, 0, 0, NULL);
else if (n->tok != MDOC_Sh)