summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile21
-rw-r--r--action.c6
-rw-r--r--mdoc.c13
-rw-r--r--private.h4
-rw-r--r--regress/test.name.006
-rw-r--r--regress/test.name.016
-rw-r--r--regress/test.name.025
-rw-r--r--regress/test.name.037
-rw-r--r--regress/test.prologue.052
-rw-r--r--regress/test.prologue.072
-rw-r--r--regress/test.prologue.082
-rw-r--r--regress/test.prologue.092
-rw-r--r--regress/test.prologue.102
-rw-r--r--regress/test.prologue.112
-rw-r--r--regress/test.prologue.122
-rw-r--r--regress/test.prologue.142
-rw-r--r--regress/test.prologue.172
-rw-r--r--regress/test.prologue.202
-rw-r--r--regress/test.prologue.255
-rw-r--r--regress/test.prologue.265
-rw-r--r--regress/test.prologue.275
-rw-r--r--regress/test.prologue.283
-rw-r--r--regress/test.prologue.293
-rw-r--r--regress/test.prologue.301
-rw-r--r--regress/test.prologue.315
-rw-r--r--regress/test.prologue.324
-rw-r--r--regress/test.prologue.334
-rw-r--r--regress/test.sh.006
-rw-r--r--regress/test.sh.014
-rw-r--r--regress/test.sh.024
-rw-r--r--regress/test.sh.035
-rw-r--r--validate.c71
32 files changed, 184 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index 0497c41f..71f4b41a 100644
--- a/Makefile
+++ b/Makefile
@@ -48,7 +48,22 @@ FAIL = regress/test.empty \
regress/test.prologue.21 \
regress/test.prologue.22 \
regress/test.prologue.23 \
- regress/test.prologue.24
+ regress/test.prologue.24 \
+ regress/test.prologue.25 \
+ regress/test.prologue.26 \
+ regress/test.prologue.27 \
+ regress/test.prologue.28 \
+ regress/test.prologue.29 \
+ regress/test.prologue.30 \
+ regress/test.prologue.31 \
+ regress/test.prologue.32 \
+ regress/test.prologue.33 \
+ regress/test.sh.01 \
+ regress/test.sh.02 \
+ regress/test.sh.03 \
+ regress/test.name.01 \
+ regress/test.name.02 \
+ regress/test.name.03
SUCCEED = regress/test.prologue.05 \
regress/test.prologue.07 \
@@ -59,7 +74,9 @@ SUCCEED = regress/test.prologue.05 \
regress/test.prologue.12 \
regress/test.prologue.14 \
regress/test.prologue.17 \
- regress/test.prologue.20
+ regress/test.prologue.20 \
+ regress/test.sh.00 \
+ regress/test.name.00
all: $(BINS)
diff --git a/action.c b/action.c
index d78803ea..e7ece6cd 100644
--- a/action.c
+++ b/action.c
@@ -193,8 +193,7 @@ post_sh(struct mdoc *mdoc)
return(1);
if (xstrlcats(buf, mdoc->last->child, 64)) {
if (SEC_CUSTOM != (sec = mdoc_atosec(buf)))
- mdoc->sec_lastn = sec;
- mdoc->sec_last = sec;
+ mdoc->lastnamed = sec;
return(1);
}
@@ -268,8 +267,7 @@ post_os(struct mdoc *mdoc)
return(mdoc_err(mdoc, "macro parameters too long"));
mdoc->meta.os = xstrdup(buf[0] ? buf : "local");
- mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
- mdoc->flags |= MDOC_BODYPARSE;
+ mdoc->lastnamed = SEC_BODY;
return(post_prologue(mdoc));
}
diff --git a/mdoc.c b/mdoc.c
index 31953ede..473f42b5 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -305,8 +305,8 @@ mdoc_parseln(struct mdoc *mdoc, int line, char *buf)
mdoc->linetok = 0;
if ('.' != *buf) {
- if ( ! (MDOC_BODYPARSE & mdoc->flags))
- return(mdoc_perr(mdoc, line, 0, "text disallowed"));
+ if (SEC_PROLOGUE == mdoc->lastnamed)
+ return(mdoc_perr(mdoc, line, 0, "text disallowed in document prologue"));
if ( ! mdoc_word_alloc(mdoc, line, 0, buf))
return(0);
mdoc->next = MDOC_NEXT_SIBLING;
@@ -407,9 +407,12 @@ mdoc_macro(struct mdoc *mdoc, int tok,
assert(mdoc_macros[tok].fp);
- if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
- ! (MDOC_BODYPARSE & mdoc->flags))
- return(mdoc_perr(mdoc, ln, ppos, "macro disallowed: not in document body"));
+ if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
+ SEC_PROLOGUE != mdoc->lastnamed)
+ return(mdoc_perr(mdoc, ln, ppos, "macro disallowed in document body"));
+ if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
+ SEC_PROLOGUE == mdoc->lastnamed)
+ return(mdoc_perr(mdoc, ln, ppos, "macro disallowed in document prologue"));
if (1 != ppos && ! (MDOC_CALLABLE & mdoc_macros[tok].flags))
return(mdoc_perr(mdoc, ln, ppos, "macro not callable"));
return((*mdoc_macros[tok].fp)(mdoc, tok, ln, ppos, pos, buf));
diff --git a/private.h b/private.h
index 1e80043f..498fb1d2 100644
--- a/private.h
+++ b/private.h
@@ -33,13 +33,11 @@ struct mdoc {
int linetok;
int flags;
#define MDOC_HALT (1 << 0)
-#define MDOC_BODYPARSE (1 << 1)
enum mdoc_next next;
struct mdoc_node *last;
struct mdoc_node *first;
struct mdoc_meta meta;
- enum mdoc_sec sec_lastn;
- enum mdoc_sec sec_last;
+ enum mdoc_sec lastnamed;
};
diff --git a/regress/test.name.00 b/regress/test.name.00
new file mode 100644
index 00000000..2d8517bf
--- /dev/null
+++ b/regress/test.name.00
@@ -0,0 +1,6 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.name.01 b/regress/test.name.01
new file mode 100644
index 00000000..216188f3
--- /dev/null
+++ b/regress/test.name.01
@@ -0,0 +1,6 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
+.Nd description
+.Nm name
diff --git a/regress/test.name.02 b/regress/test.name.02
new file mode 100644
index 00000000..a22e6cff
--- /dev/null
+++ b/regress/test.name.02
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
+.Nd description
diff --git a/regress/test.name.03 b/regress/test.name.03
new file mode 100644
index 00000000..45e46ec9
--- /dev/null
+++ b/regress/test.name.03
@@ -0,0 +1,7 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
+.Nm name
+.Fl
+.Nd description
diff --git a/regress/test.prologue.05 b/regress/test.prologue.05
index d7fd5b66..b88771dc 100644
--- a/regress/test.prologue.05
+++ b/regress/test.prologue.05
@@ -2,3 +2,5 @@
.Dt
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.07 b/regress/test.prologue.07
index d326eaaa..2d8517bf 100644
--- a/regress/test.prologue.07
+++ b/regress/test.prologue.07
@@ -2,3 +2,5 @@
.Dt
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.08 b/regress/test.prologue.08
index e590b07c..b6fb3f2a 100644
--- a/regress/test.prologue.08
+++ b/regress/test.prologue.08
@@ -2,3 +2,5 @@
.Dt
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.09 b/regress/test.prologue.09
index d1e742fa..4feaa925 100644
--- a/regress/test.prologue.09
+++ b/regress/test.prologue.09
@@ -2,3 +2,5 @@
.Dt
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.10 b/regress/test.prologue.10
index d326eaaa..2d8517bf 100644
--- a/regress/test.prologue.10
+++ b/regress/test.prologue.10
@@ -2,3 +2,5 @@
.Dt
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.11 b/regress/test.prologue.11
index def6a5a1..22b57e43 100644
--- a/regress/test.prologue.11
+++ b/regress/test.prologue.11
@@ -2,3 +2,5 @@
.Dt test
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.12 b/regress/test.prologue.12
index 3a789b0d..af8602eb 100644
--- a/regress/test.prologue.12
+++ b/regress/test.prologue.12
@@ -2,3 +2,5 @@
.Dt test 1
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.14 b/regress/test.prologue.14
index 4cdda822..f73384af 100644
--- a/regress/test.prologue.14
+++ b/regress/test.prologue.14
@@ -2,3 +2,5 @@
.Dt test 1 alpha
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.17 b/regress/test.prologue.17
index 6636c2bf..23c4e8c8 100644
--- a/regress/test.prologue.17
+++ b/regress/test.prologue.17
@@ -2,3 +2,5 @@
.Dt test 1 AMD
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.20 b/regress/test.prologue.20
index 640d4e32..47e91431 100644
--- a/regress/test.prologue.20
+++ b/regress/test.prologue.20
@@ -2,3 +2,5 @@
.Dt test\ 1 1 AMD
.Os
.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.prologue.25 b/regress/test.prologue.25
new file mode 100644
index 00000000..2ab5a9df
--- /dev/null
+++ b/regress/test.prologue.25
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
diff --git a/regress/test.prologue.26 b/regress/test.prologue.26
new file mode 100644
index 00000000..3775ba96
--- /dev/null
+++ b/regress/test.prologue.26
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dt
+.Dt
+.Os
+.Sh NAME
diff --git a/regress/test.prologue.27 b/regress/test.prologue.27
new file mode 100644
index 00000000..a9755e36
--- /dev/null
+++ b/regress/test.prologue.27
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Os
+.Sh NAME
diff --git a/regress/test.prologue.28 b/regress/test.prologue.28
new file mode 100644
index 00000000..c8614046
--- /dev/null
+++ b/regress/test.prologue.28
@@ -0,0 +1,3 @@
+.Dd $Mdocdate$
+.Dt
+.Sh NAME
diff --git a/regress/test.prologue.29 b/regress/test.prologue.29
new file mode 100644
index 00000000..485b6fef
--- /dev/null
+++ b/regress/test.prologue.29
@@ -0,0 +1,3 @@
+.Dt
+.Os
+.Sh NAME
diff --git a/regress/test.prologue.30 b/regress/test.prologue.30
new file mode 100644
index 00000000..6d73569f
--- /dev/null
+++ b/regress/test.prologue.30
@@ -0,0 +1 @@
+.Sh NAME
diff --git a/regress/test.prologue.31 b/regress/test.prologue.31
new file mode 100644
index 00000000..8f430c33
--- /dev/null
+++ b/regress/test.prologue.31
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dt
+.Sh NAME
+.Os
+.Sh NAME
diff --git a/regress/test.prologue.32 b/regress/test.prologue.32
new file mode 100644
index 00000000..2aec95a2
--- /dev/null
+++ b/regress/test.prologue.32
@@ -0,0 +1,4 @@
+.Dd $Mdocdate$
+.Os
+.Dt
+.Sh NAME
diff --git a/regress/test.prologue.33 b/regress/test.prologue.33
new file mode 100644
index 00000000..7622251f
--- /dev/null
+++ b/regress/test.prologue.33
@@ -0,0 +1,4 @@
+.Dt
+.Dd $Mdocdate$
+.Os
+.Sh NAME
diff --git a/regress/test.sh.00 b/regress/test.sh.00
new file mode 100644
index 00000000..2d8517bf
--- /dev/null
+++ b/regress/test.sh.00
@@ -0,0 +1,6 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME
+.Nm name
+.Nd description
diff --git a/regress/test.sh.01 b/regress/test.sh.01
new file mode 100644
index 00000000..3c88df81
--- /dev/null
+++ b/regress/test.sh.01
@@ -0,0 +1,4 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh "NAME"
diff --git a/regress/test.sh.02 b/regress/test.sh.02
new file mode 100644
index 00000000..e27c7284
--- /dev/null
+++ b/regress/test.sh.02
@@ -0,0 +1,4 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Sh NAME \
diff --git a/regress/test.sh.03 b/regress/test.sh.03
new file mode 100644
index 00000000..be144b51
--- /dev/null
+++ b/regress/test.sh.03
@@ -0,0 +1,5 @@
+.Dd $Mdocdate$
+.Dt
+.Os
+.Fl
+.Sh NAME
diff --git a/validate.c b/validate.c
index 6ed8b6f8..8841b738 100644
--- a/validate.c
+++ b/validate.c
@@ -91,6 +91,8 @@ static int bwarn_ge1(struct mdoc *);
static int ewarn_ge1(struct mdoc *);
static int ebool(struct mdoc *);
static int post_sh(struct mdoc *);
+static int post_sh_body(struct mdoc *);
+static int post_sh_head(struct mdoc *);
static int post_bl(struct mdoc *);
static int post_it(struct mdoc *);
static int post_ex(struct mdoc *);
@@ -717,7 +719,7 @@ static int
pre_prologue(struct mdoc *mdoc, struct mdoc_node *node)
{
- if (SEC_PROLOGUE != mdoc->sec_lastn)
+ if (SEC_PROLOGUE != mdoc->lastnamed)
return(mdoc_nerr(mdoc, node, "macro may only be invoked in the prologue"));
assert(MDOC_ELEM == node->type);
@@ -1060,39 +1062,78 @@ static int
post_root(struct mdoc *mdoc)
{
- if (NULL == mdoc->last->child)
+ if (NULL == mdoc->first->child)
return(mdoc_err(mdoc, "document has no data"));
- if (NULL == mdoc->meta.title)
- return(mdoc_err(mdoc, "document has incomplete prologue"));
- if (NULL == mdoc->meta.os)
- return(mdoc_err(mdoc, "document has incomplete prologue"));
- if (0 == mdoc->meta.date)
+ if (SEC_PROLOGUE == mdoc->lastnamed)
return(mdoc_err(mdoc, "document has incomplete prologue"));
+ if (MDOC_BLOCK != mdoc->first->child->type)
+ return(mdoc_err(mdoc, "document expects `%s' macro after prologue", mdoc_macronames[MDOC_Sh]));
+ if (MDOC_Sh != mdoc->first->child->tok)
+ return(mdoc_err(mdoc, "document expects `%s' macro after prologue", mdoc_macronames[MDOC_Sh]));
return(1);
}
-/* Warn if conventional sections are out of order. */
static int
post_sh(struct mdoc *mdoc)
{
+
+ if (MDOC_HEAD == mdoc->last->type)
+ return(post_sh_head(mdoc));
+ if (MDOC_BODY == mdoc->last->type)
+ return(post_sh_body(mdoc));
+ return(1);
+}
+
+
+static int
+post_sh_body(struct mdoc *mdoc)
+{
+ struct mdoc_node *n;
+
+ assert(MDOC_Sh == mdoc->last->tok);
+ if (SEC_NAME != mdoc->lastnamed)
+ return(1);
+
+ if (NULL == (n = mdoc->last->child))
+ return(mdoc_err(mdoc, "section NAME must contain %s as the first body child", mdoc_macronames[MDOC_Nm]));
+ if (MDOC_ELEM != n->type || MDOC_Nm != n->tok)
+ return(mdoc_err(mdoc, "section NAME must contain %s as the first body child", mdoc_macronames[MDOC_Nm]));
+ if (NULL == (n = n->next))
+ return(mdoc_err(mdoc, "section NAME must contain %s as the second body child", mdoc_macronames[MDOC_Nd]));
+ if (MDOC_ELEM != n->type || MDOC_Nd != n->tok)
+ return(mdoc_err(mdoc, "section NAME must contain %s as the second body child", mdoc_macronames[MDOC_Nd]));
+ if (NULL == (n = n->next))
+ return(1);
+
+ return(mdoc_warn(mdoc, WARN_SYNTAX, "section NAME usually limited to %s and %s body children",
+ mdoc_macronames[MDOC_Nm], mdoc_macronames[MDOC_Nd]));
+}
+
+
+static int
+post_sh_head(struct mdoc *mdoc)
+{
char buf[64];
enum mdoc_sec sec;
- if (MDOC_HEAD != mdoc->last->type)
- return(1);
assert(MDOC_Sh == mdoc->last->tok);
if ( ! xstrlcats(buf, mdoc->last->child, 64))
return(mdoc_err(mdoc, "macro parameters too long"));
- if (SEC_CUSTOM == (sec = mdoc_atosec(buf)))
- return(1);
- if (sec > mdoc->sec_lastn)
+ sec = mdoc_atosec(buf);
+
+ if (SEC_BODY == mdoc->lastnamed && SEC_NAME != sec)
+ return(mdoc_err(mdoc, "section NAME must be first"));
+ if (SEC_CUSTOM == sec)
return(1);
- if (sec == mdoc->sec_lastn)
+ if (sec == mdoc->lastnamed)
return(mdoc_warn(mdoc, WARN_SYNTAX, "section repeated"));
- return(mdoc_warn(mdoc, WARN_SYNTAX, "section out of conventional order"));
+ if (sec < mdoc->lastnamed)
+ return(mdoc_warn(mdoc, WARN_SYNTAX, "section out of conventional order"));
+
+ return(1);
}