summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-08-06 15:09:05 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-08-06 15:09:05 +0000
commit24b160c265af79f44e54160d97249622ff07747a (patch)
tree6bab11dc37008079265c87f0b7d5ee5ad38955f6
parent4e6374f6dccb1f26d1d9efc07a9ce9c9c600c3e7 (diff)
downloadmandoc-24b160c265af79f44e54160d97249622ff07747a.tar.gz
Bring the handling of defective prologues even closer to groff,
in particular relaxing the distinction between prologue and body and further improving messages. * The last .Dd wins and the last .Os wins, even in the body. * The last .Dt before the first body macro wins. * Missing title in .Dt defaults to UNTITLED. Warn about it. * Missing section in .Dt does not default to 1. But warn about it. * Do not warn multiple times about the same mdoc(7) prologue macro. * Warn about missing .Os. * Incomplete .TH defaults to empty strings. Warn about it.
-rw-r--r--man_validate.c19
-rw-r--r--mandoc.h11
-rw-r--r--mandocdb.c5
-rw-r--r--mdoc.c59
-rw-r--r--mdoc_html.c11
-rw-r--r--mdoc_man.c5
-rw-r--r--mdoc_term.c6
-rw-r--r--mdoc_validate.c152
-rw-r--r--read.c11
9 files changed, 137 insertions, 142 deletions
diff --git a/man_validate.c b/man_validate.c
index 2091840d..76aebe1c 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -43,7 +43,6 @@ typedef int (*v_check)(CHKARGS);
static int check_eq0(CHKARGS);
static int check_eq2(CHKARGS);
static int check_le1(CHKARGS);
-static int check_ge2(CHKARGS);
static int check_le5(CHKARGS);
static int check_par(CHKARGS);
static int check_part(CHKARGS);
@@ -142,7 +141,7 @@ check_root(CHKARGS)
man->meta.hasbody = 1;
if (NULL == man->meta.title) {
- mandoc_msg(MANDOCERR_TH_MISSING, man->parse,
+ mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
n->line, n->pos, NULL);
/*
@@ -150,8 +149,8 @@ check_root(CHKARGS)
* implication, date and section also aren't set).
*/
- man->meta.title = mandoc_strdup("unknown");
- man->meta.msec = mandoc_strdup("1");
+ man->meta.title = mandoc_strdup("");
+ man->meta.msec = mandoc_strdup("");
man->meta.date = man->quick ? mandoc_strdup("") :
mandoc_normdate(man->parse, NULL, n->line, n->pos);
}
@@ -189,7 +188,6 @@ check_##name(CHKARGS) \
INEQ_DEFINE(0, ==, eq0)
INEQ_DEFINE(2, ==, eq2)
INEQ_DEFINE(1, <=, le1)
-INEQ_DEFINE(2, >=, ge2)
INEQ_DEFINE(5, <=, le5)
static int
@@ -324,7 +322,6 @@ post_TH(CHKARGS)
struct man_node *nb;
const char *p;
- check_ge2(man, n);
check_le5(man, n);
free(man->meta.title);
@@ -354,8 +351,11 @@ post_TH(CHKARGS)
}
}
man->meta.title = mandoc_strdup(n->string);
- } else
+ } else {
man->meta.title = mandoc_strdup("");
+ mandoc_msg(MANDOCERR_TH_NOTITLE, man->parse,
+ nb->line, nb->pos, "TH");
+ }
/* TITLE ->MSEC<- DATE SOURCE VOL */
@@ -363,8 +363,11 @@ post_TH(CHKARGS)
n = n->next;
if (n && n->string)
man->meta.msec = mandoc_strdup(n->string);
- else
+ else {
man->meta.msec = mandoc_strdup("");
+ mandoc_vmsg(MANDOCERR_MSEC_MISSING, man->parse,
+ nb->line, nb->pos, "TH %s", man->meta.title);
+ }
/* TITLE MSEC ->DATE<- SOURCE VOL */
diff --git a/mandoc.h b/mandoc.h
index 136f1070..1ef88d35 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -49,16 +49,19 @@ enum mandocerr {
MANDOCERR_WARNING, /* ===== start of warnings ===== */
/* related to the prologue */
- MANDOCERR_TH_MISSING, /* missing .TH macro, using "unknown 1" */
+ MANDOCERR_DT_NOTITLE, /* missing manual title, using UNTITLED: line */
+ MANDOCERR_TH_NOTITLE, /* missing manual title, using "": [macro] */
MANDOCERR_TITLE_CASE, /* lower case character in document title */
+ MANDOCERR_MSEC_MISSING, /* missing manual section, using "": macro */
MANDOCERR_MSEC_BAD, /* unknown manual section: Dt ... section */
MANDOCERR_ARCH_BAD, /* unknown manual volume or arch: Dt ... volume */
MANDOCERR_DATE_MISSING, /* missing date, using today's date */
MANDOCERR_DATE_BAD, /* cannot parse date, using it verbatim: date */
- MANDOCERR_PROLOG_ORDER, /* prologue macros out of order: macro */
+ MANDOCERR_OS_MISSING, /* missing Os macro, using "" */
MANDOCERR_PROLOG_REP, /* duplicate prologue macro: macro */
- MANDOCERR_PROLOG_BAD, /* incomplete prologue, terminated by: macro */
- MANDOCERR_PROLOG_ONLY, /* skipping prologue macro in body: macro */
+ MANDOCERR_PROLOG_LATE, /* late prologue macro: macro */
+ MANDOCERR_DT_LATE, /* skipping late title macro: Dt args */
+ MANDOCERR_PROLOG_ORDER, /* prologue macros out of order: macros */
/* related to document structure */
MANDOCERR_SO, /* .so is fragile, better use ln(1): so path */
diff --git a/mandocdb.c b/mandocdb.c
index a2f1c884..4dcb5ac6 100644
--- a/mandocdb.c
+++ b/mandocdb.c
@@ -1198,8 +1198,9 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
goto nextpage;
} else if (NULL != mdoc) {
mpage->form = FORM_SRC;
- mpage->sec =
- mandoc_strdup(mdoc_meta(mdoc)->msec);
+ mpage->sec = mdoc_meta(mdoc)->msec;
+ mpage->sec = mandoc_strdup(
+ NULL == mpage->sec ? "" : mpage->sec);
mpage->arch = mdoc_meta(mdoc)->arch;
mpage->arch = mandoc_strdup(
NULL == mpage->arch ? "" : mpage->arch);
diff --git a/mdoc.c b/mdoc.c
index ba5bad7c..fe63c930 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -123,20 +123,13 @@ mdoc_free1(struct mdoc *mdoc)
if (mdoc->first)
mdoc_node_delete(mdoc, mdoc->first);
- if (mdoc->meta.title)
- free(mdoc->meta.title);
- if (mdoc->meta.os)
- free(mdoc->meta.os);
- if (mdoc->meta.name)
- free(mdoc->meta.name);
- if (mdoc->meta.arch)
- free(mdoc->meta.arch);
- if (mdoc->meta.vol)
- free(mdoc->meta.vol);
- if (mdoc->meta.msec)
- free(mdoc->meta.msec);
- if (mdoc->meta.date)
- free(mdoc->meta.date);
+ free(mdoc->meta.msec);
+ free(mdoc->meta.vol);
+ free(mdoc->meta.arch);
+ free(mdoc->meta.date);
+ free(mdoc->meta.title);
+ free(mdoc->meta.os);
+ free(mdoc->meta.name);
}
/*
@@ -271,32 +264,22 @@ mdoc_macro(MACRO_PROT_ARGS)
{
assert(tok < MDOC_MAX);
- /* If we're in the body, deny prologue calls. */
-
- if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
- MDOC_PBODY & mdoc->flags) {
- mandoc_vmsg(MANDOCERR_PROLOG_ONLY, mdoc->parse,
- line, ppos, "%s", mdoc_macronames[tok]);
- return(1);
- }
-
- /* If we're in the prologue, deny "body" macros. */
-
- if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
- ! (MDOC_PBODY & mdoc->flags)) {
- mandoc_vmsg(MANDOCERR_PROLOG_BAD, mdoc->parse,
- line, ppos, "%s", mdoc_macronames[tok]);
- if (NULL == mdoc->meta.msec)
- mdoc->meta.msec = mandoc_strdup("1");
- if (NULL == mdoc->meta.title)
- mdoc->meta.title = mandoc_strdup("UNKNOWN");
+ if (mdoc->flags & MDOC_PBODY) {
+ if (tok == MDOC_Dt) {
+ mandoc_vmsg(MANDOCERR_DT_LATE,
+ mdoc->parse, line, ppos,
+ "Dt %s", buf + *pos);
+ return(1);
+ }
+ } else if ( ! (mdoc_macros[tok].flags & MDOC_PROLOGUE)) {
+ if (mdoc->meta.title == NULL) {
+ mandoc_vmsg(MANDOCERR_DT_NOTITLE,
+ mdoc->parse, line, ppos, "%s %s",
+ mdoc_macronames[tok], buf + *pos);
+ mdoc->meta.title = mandoc_strdup("UNTITLED");
+ }
if (NULL == mdoc->meta.vol)
mdoc->meta.vol = mandoc_strdup("LOCAL");
- if (NULL == mdoc->meta.os)
- mdoc->meta.os = mandoc_strdup("LOCAL");
- if (NULL == mdoc->meta.date)
- mdoc->meta.date = mandoc_normdate
- (mdoc->parse, NULL, line, ppos);
mdoc->flags |= MDOC_PBODY;
}
diff --git a/mdoc_html.c b/mdoc_html.c
index 43ff1d27..328cb9bc 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -380,8 +380,9 @@ print_mdoc_head(MDOC_ARGS)
print_gen_head(h);
bufinit(h);
- bufcat_fmt(h, "%s(%s)", meta->title, meta->msec);
-
+ bufcat(h, meta->title);
+ if (meta->msec)
+ bufcat_fmt(h, "(%s)", meta->msec);
if (meta->arch)
bufcat_fmt(h, " (%s)", meta->arch);
@@ -525,7 +526,11 @@ mdoc_root_pre(MDOC_ARGS)
mandoc_asprintf(&volume, "%s (%s)",
meta->vol, meta->arch);
- mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
+ if (NULL == meta->msec)
+ title = mandoc_strdup(meta->title);
+ else
+ mandoc_asprintf(&title, "%s(%s)",
+ meta->title, meta->msec);
PAIR_SUMMARY_INIT(&tag[0], "Document Header");
PAIR_CLASS_INIT(&tag[1], "head");
diff --git a/mdoc_man.c b/mdoc_man.c
index 504790b9..070372cf 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -548,8 +548,9 @@ man_mdoc(void *arg, const struct mdoc *mdoc)
n = mdoc_node(mdoc);
printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
- meta->title, meta->msec, meta->date,
- meta->os, meta->vol);
+ meta->title,
+ (meta->msec == NULL ? "" : meta->msec),
+ meta->date, meta->os, meta->vol);
/* Disable hyphenation and if nroff, disable justification. */
printf(".nh\n.if n .ad l");
diff --git a/mdoc_term.c b/mdoc_term.c
index ea34908c..9cb6e8e0 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -476,7 +476,11 @@ print_mdoc_head(struct termp *p, const void *arg)
meta->vol, meta->arch);
vollen = term_strlen(p, volume);
- mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
+ if (NULL == meta->msec)
+ title = mandoc_strdup(meta->title);
+ else
+ mandoc_asprintf(&title, "%s(%s)",
+ meta->title, meta->msec);
titlen = term_strlen(p, title);
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 47dd6c39..a7fd30bf 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -114,7 +114,6 @@ static int post_nm(POST_ARGS);
static int post_ns(POST_ARGS);
static int post_os(POST_ARGS);
static int post_par(POST_ARGS);
-static int post_prol(POST_ARGS);
static int post_root(POST_ARGS);
static int post_rs(POST_ARGS);
static int post_sh(POST_ARGS);
@@ -843,14 +842,12 @@ static int
pre_dt(PRE_ARGS)
{
- if (NULL == mdoc->meta.date || mdoc->meta.os)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Dt");
-
- if (mdoc->meta.title)
+ if (mdoc->meta.title != NULL)
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
n->line, n->pos, "Dt");
-
+ else if (mdoc->meta.os != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dt after Os");
return(1);
}
@@ -858,14 +855,12 @@ static int
pre_os(PRE_ARGS)
{
- if (NULL == mdoc->meta.title || NULL == mdoc->meta.date)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Os");
-
- if (mdoc->meta.os)
+ if (mdoc->meta.os != NULL)
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
n->line, n->pos, "Os");
-
+ else if (mdoc->flags & MDOC_PBODY)
+ mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
+ n->line, n->pos, "Os");
return(1);
}
@@ -873,14 +868,18 @@ static int
pre_dd(PRE_ARGS)
{
- if (mdoc->meta.title || mdoc->meta.os)
- mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
- n->line, n->pos, "Dd");
-
- if (mdoc->meta.date)
+ if (mdoc->meta.date != NULL)
mandoc_msg(MANDOCERR_PROLOG_REP, mdoc->parse,
n->line, n->pos, "Dd");
-
+ else if (mdoc->flags & MDOC_PBODY)
+ mandoc_msg(MANDOCERR_PROLOG_LATE, mdoc->parse,
+ n->line, n->pos, "Dd");
+ else if (mdoc->meta.title != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dd after Dt");
+ else if (mdoc->meta.os != NULL)
+ mandoc_msg(MANDOCERR_PROLOG_ORDER, mdoc->parse,
+ n->line, n->pos, "Dd after Os");
return(1);
}
@@ -1627,20 +1626,24 @@ post_root(POST_ARGS)
/* Add missing prologue data. */
- if ( ! (MDOC_PBODY & mdoc->flags)) {
- mandoc_msg(MANDOCERR_PROLOG_BAD, mdoc->parse, 0, 0, "EOF");
- if (mdoc->meta.date == NULL)
- mdoc->meta.date = mdoc->quick ?
- mandoc_strdup("") :
- mandoc_normdate(mdoc->parse, NULL, 0, 0);
- if (mdoc->meta.title == NULL)
- mdoc->meta.title = mandoc_strdup("UNKNOWN");
- if (mdoc->meta.vol == NULL)
- mdoc->meta.vol = mandoc_strdup("LOCAL");
- if (mdoc->meta.arch == NULL)
- mdoc->meta.msec = mandoc_strdup("1");
- if (mdoc->meta.os == NULL)
- mdoc->meta.os = mandoc_strdup("UNKNOWN");
+ if (mdoc->meta.date == NULL)
+ mdoc->meta.date = mdoc->quick ?
+ mandoc_strdup("") :
+ mandoc_normdate(mdoc->parse, NULL, 0, 0);
+
+ if (mdoc->meta.title == NULL) {
+ mandoc_msg(MANDOCERR_DT_NOTITLE,
+ mdoc->parse, 0, 0, "EOF");
+ mdoc->meta.title = mandoc_strdup("UNTITLED");
+ }
+
+ if (mdoc->meta.vol == NULL)
+ mdoc->meta.vol = mandoc_strdup("LOCAL");
+
+ if (mdoc->meta.os == NULL) {
+ mandoc_msg(MANDOCERR_OS_MISSING,
+ mdoc->parse, 0, 0, NULL);
+ mdoc->meta.os = mandoc_strdup("");
}
n = mdoc->first;
@@ -1977,7 +1980,10 @@ post_sh_head(POST_ARGS)
/* Check particular section/manual conventions. */
- assert(mdoc->meta.msec);
+ if (mdoc->meta.msec == NULL) {
+ free(secname);
+ return(1);
+ }
goodsec = NULL;
switch (sec) {
@@ -2156,7 +2162,7 @@ post_dd(POST_ARGS)
if (NULL == n->child || '\0' == n->child->string[0]) {
mdoc->meta.date = mdoc->quick ? mandoc_strdup("") :
mandoc_normdate(mdoc->parse, NULL, n->line, n->pos);
- return(post_prol(mdoc));
+ goto out;
}
datestr = NULL;
@@ -2168,7 +2174,9 @@ post_dd(POST_ARGS)
datestr, n->line, n->pos);
free(datestr);
}
- return(post_prol(mdoc));
+out:
+ mdoc_node_delete(mdoc, n);
+ return(1);
}
static int
@@ -2180,14 +2188,15 @@ post_dt(POST_ARGS)
n = mdoc->last;
- if (mdoc->meta.title)
- free(mdoc->meta.title);
- if (mdoc->meta.vol)
- free(mdoc->meta.vol);
- if (mdoc->meta.arch)
- free(mdoc->meta.arch);
+ free(mdoc->meta.title);
+ free(mdoc->meta.msec);
+ free(mdoc->meta.vol);
+ free(mdoc->meta.arch);
- mdoc->meta.title = mdoc->meta.vol = mdoc->meta.arch = NULL;
+ mdoc->meta.title = NULL;
+ mdoc->meta.msec = NULL;
+ mdoc->meta.vol = NULL;
+ mdoc->meta.arch = NULL;
/* First check that all characters are uppercase. */
@@ -2202,32 +2211,27 @@ post_dt(POST_ARGS)
break;
}
- /* Handles: `.Dt'
- * title = unknown, volume = local, msec = 0, arch = NULL
- */
+ /* No argument: msec and arch remain NULL. */
if (NULL == (nn = n->child)) {
- /* XXX: make these macro values. */
- /* FIXME: warn about missing values. */
- mdoc->meta.title = mandoc_strdup("UNKNOWN");
+ mandoc_msg(MANDOCERR_DT_NOTITLE,
+ mdoc->parse, n->line, n->pos, "Dt");
+ mdoc->meta.title = mandoc_strdup("UNTITLED");
mdoc->meta.vol = mandoc_strdup("LOCAL");
- mdoc->meta.msec = mandoc_strdup("1");
- return(post_prol(mdoc));
+ goto out;
}
- /* Handles: `.Dt TITLE'
- * title = TITLE, volume = local, msec = 0, arch = NULL
- */
+ /* One argument: msec and arch remain NULL. */
mdoc->meta.title = mandoc_strdup(
- '\0' == nn->string[0] ? "UNKNOWN" : nn->string);
+ '\0' == nn->string[0] ? "UNTITLED" : nn->string);
if (NULL == (nn = nn->next)) {
- /* FIXME: warn about missing msec. */
- /* XXX: make this a macro value. */
+ mandoc_vmsg(MANDOCERR_MSEC_MISSING,
+ mdoc->parse, n->line, n->pos,
+ "Dt %s", mdoc->meta.title);
mdoc->meta.vol = mandoc_strdup("LOCAL");
- mdoc->meta.msec = mandoc_strdup("1");
- return(post_prol(mdoc));
+ goto out;
}
/* Handles: `.Dt TITLE SEC'
@@ -2249,7 +2253,7 @@ post_dt(POST_ARGS)
}
if (NULL == (nn = nn->next))
- return(post_prol(mdoc));
+ goto out;
/* Handles: `.Dt TITLE SEC VOL'
* title = TITLE,
@@ -2275,23 +2279,8 @@ post_dt(POST_ARGS)
/* Ignore any subsequent parameters... */
/* FIXME: warn about subsequent parameters. */
-
- return(post_prol(mdoc));
-}
-
-static int
-post_prol(POST_ARGS)
-{
- /*
- * Remove prologue macros from the document after they're
- * processed. The final document uses mdoc_meta for these
- * values and discards the originals.
- */
-
- mdoc_node_delete(mdoc, mdoc->last);
- if (mdoc->meta.title && mdoc->meta.date && mdoc->meta.os)
- mdoc->flags |= MDOC_PBODY;
-
+out:
+ mdoc_node_delete(mdoc, n);
return(1);
}
@@ -2337,11 +2326,11 @@ post_os(POST_ARGS)
mdoc->meta.os = NULL;
mdoc_deroff(&mdoc->meta.os, n);
if (mdoc->meta.os)
- return(post_prol(mdoc));
+ goto out;
if (mdoc->defos) {
mdoc->meta.os = mandoc_strdup(mdoc->defos);
- return(post_prol(mdoc));
+ goto out;
}
#ifdef OSNAME
@@ -2358,7 +2347,10 @@ post_os(POST_ARGS)
}
mdoc->meta.os = mandoc_strdup(defbuf);
#endif /*!OSNAME*/
- return(post_prol(mdoc));
+
+out:
+ mdoc_node_delete(mdoc, n);
+ return(1);
}
/*
diff --git a/read.c b/read.c
index 07329dbe..4ad08236 100644
--- a/read.c
+++ b/read.c
@@ -93,16 +93,19 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"generic warning",
/* related to the prologue */
- "missing .TH macro, using \"unknown 1\"",
+ "missing manual title, using UNTITLED",
+ "missing manual title, using \"\"",
"lower case character in document title",
+ "missing manual section, using \"\"",
"unknown manual section",
"unknown manual volume or arch",
"missing date, using today's date",
"cannot parse date, using it verbatim",
- "prologue macros out of order",
+ "missing Os macro, using \"\"",
"duplicate prologue macro",
- "incomplete prologue, terminated by",
- "skipping prologue macro in body",
+ "late prologue macro",
+ "skipping late title macro",
+ "prologue macros out of order",
/* related to document structure */
".so is fragile, better use ln(1)",