summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--action.c8
-rw-r--r--macro.c56
-rw-r--r--mdoc.c37
-rw-r--r--mdoc.h4
-rw-r--r--mdocml.c9
-rw-r--r--private.h1
-rw-r--r--validate.c68
7 files changed, 131 insertions, 52 deletions
diff --git a/action.c b/action.c
index 754b93b3..ee15b278 100644
--- a/action.c
+++ b/action.c
@@ -223,7 +223,7 @@ post_dt(struct mdoc *mdoc)
}
mdoc_msg(mdoc, "parsed title: %s", mdoc->meta.title);
- /* TODO: have vol2a functions. */
+ /* TODO: print vol2a functions. */
return(1);
}
@@ -240,7 +240,6 @@ post_os(struct mdoc *mdoc)
assert(0 == mdoc->meta.os[0]);
sz = META_OS_SZ;
- (void)xstrlcpy(mdoc->meta.os, "LOCAL", sz);
for (n = mdoc->last->child; n; n = n->next) {
assert(MDOC_TEXT == n->type);
@@ -252,7 +251,10 @@ post_os(struct mdoc *mdoc)
return(mdoc_err(mdoc, ERR_SYNTAX_ARGFORM));
}
- mdoc_msg(mdoc, "parsed operating system (entering document body)");
+ if (0 == mdoc->meta.os[0])
+ (void)xstrlcpy(mdoc->meta.os, "LOCAL", sz);
+
+ mdoc_msg(mdoc, "parsed operating system: %s", mdoc->meta.os);
mdoc->sec_lastn = mdoc->sec_last = SEC_BODY;
return(1);
}
diff --git a/macro.c b/macro.c
index dfd921a0..e8da371e 100644
--- a/macro.c
+++ b/macro.c
@@ -37,16 +37,23 @@ static int rewind_body(struct mdoc *, int);
static int rewind_last(struct mdoc *, struct mdoc_node *);
static int append_delims(struct mdoc *,
int, int, int *, char *);
-static int lookup(struct mdoc *, int, const char *);
+static int lookup(struct mdoc *, int, int, int, const char *);
static int
-lookup(struct mdoc *mdoc, int from, const char *p)
+lookup(struct mdoc *mdoc, int line, int pos, int from, const char *p)
{
+ int res;
- if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
- return(MDOC_MAX);
- return(mdoc_find(mdoc, p));
+ res = mdoc_find(mdoc, p);
+ if (MDOC_PARSED & mdoc_macros[from].flags)
+ return(res);
+ if (MDOC_MAX == res)
+ return(res);
+
+ if ( ! mdoc_pwarn(mdoc, line, pos, WARN_SYNTAX_MACLIKE))
+ return(-1);
+ return(MDOC_MAX);
}
@@ -55,8 +62,14 @@ rewind_last(struct mdoc *mdoc, struct mdoc_node *to)
{
assert(to);
- if (mdoc->last == to)
+ mdoc->next = MDOC_NEXT_SIBLING;
+ if (mdoc->last == to) {
+ if ( ! mdoc_valid_post(mdoc))
+ return(0);
+ if ( ! mdoc_action_post(mdoc))
+ return(0);
return(1);
+ }
do {
mdoc->last = mdoc->last->parent;
@@ -67,7 +80,6 @@ rewind_last(struct mdoc *mdoc, struct mdoc_node *to)
return(0);
} while (mdoc->last != to);
- mdoc->next = MDOC_NEXT_SIBLING;
return(1);
}
@@ -315,7 +327,9 @@ macro_close_explicit(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX != c) {
if ( ! flushed) {
if ( ! rewind_expblock(mdoc, tt))
return(0);
@@ -324,7 +338,7 @@ macro_close_explicit(MACRO_PROT_ARGS)
if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
return(0);
break;
- }
+ }
if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
return(0);
@@ -417,7 +431,9 @@ macro_text(MACRO_PROT_ARGS)
if (ARGS_PUNCT == c)
break;
- if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, la, tok, p)))
+ return(0);
+ else if (MDOC_MAX != c) {
if ( ! rewind_elem(mdoc, tok)) {
mdoc_argv_free(argc, argv);
return(0);
@@ -524,12 +540,14 @@ macro_scoped(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX == c) {
if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
return(0);
mdoc->next = MDOC_NEXT_SIBLING;
continue;
- }
+ }
if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
return(0);
@@ -584,12 +602,14 @@ macro_scoped_line(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX == c) {
if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
return(0);
mdoc->next = MDOC_NEXT_SIBLING;
continue;
- }
+ }
if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
return(0);
@@ -668,7 +688,9 @@ macro_constant_scoped(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX != c) {
if ( ! flushed) {
if ( ! rewind_head(mdoc, tok))
return(0);
@@ -780,7 +802,9 @@ macro_constant_delimited(MACRO_PROT_ARGS)
if (ARGS_EOLN == c)
break;
- if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
+ if (-1 == (c = lookup(mdoc, line, lastarg, tok, p)))
+ return(0);
+ else if (MDOC_MAX != c) {
if ( ! flushed && ! rewind_elem(mdoc, tok))
return(0);
flushed = 1;
diff --git a/mdoc.c b/mdoc.c
index 181b0ba0..f2dd666d 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -243,7 +243,13 @@ mdoc_alloc(void *data, const struct mdoc_cb *cb)
p->data = data;
(void)memcpy(&p->cb, cb, sizeof(struct mdoc_cb));
+ p->last = xcalloc(1, sizeof(struct mdoc_node));
+ p->last->type = MDOC_ROOT;
+ p->first = p->last;
+
+ p->next = MDOC_NEXT_CHILD;
p->htab = mdoc_tokhash_alloc();
+
return(p);
}
@@ -418,17 +424,9 @@ mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p)
/* NOTREACHED */
}
- if (NULL == mdoc->first) {
- assert(NULL == mdoc->last);
- if ( ! mdoc_valid_pre(mdoc, p))
- return(0);
- if ( ! mdoc_action_pre(mdoc, p))
- return(0);
- mdoc->first = p;
- mdoc->last = p;
- mdoc_msg(mdoc, "parse: root %s `%s'", nt, nn);
- return(1);
- }
+ assert(mdoc->last);
+ assert(mdoc->first);
+ assert(MDOC_ROOT != p->type);
switch (mdoc->last->type) {
case (MDOC_TEXT):
@@ -455,6 +453,10 @@ mdoc_node_append(struct mdoc *mdoc, struct mdoc_node *p)
on = mdoc_macronames[mdoc->last->data.block.tok];
ot = "block";
break;
+ case (MDOC_ROOT):
+ on = "root";
+ ot = "root";
+ break;
default:
abort();
/* NOTREACHED */
@@ -545,6 +547,19 @@ mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, int tok)
int
+mdoc_root_alloc(struct mdoc *mdoc)
+{
+ struct mdoc_node *p;
+
+ p = xcalloc(1, sizeof(struct mdoc_node));
+
+ p->type = MDOC_ROOT;
+
+ return(mdoc_node_append(mdoc, p));
+}
+
+
+int
mdoc_block_alloc(struct mdoc *mdoc, int line, int pos,
int tok, size_t argsz, const struct mdoc_arg *args)
{
diff --git a/mdoc.h b/mdoc.h
index e1f06446..99ce0082 100644
--- a/mdoc.h
+++ b/mdoc.h
@@ -252,6 +252,7 @@ enum mdoc_warn {
WARN_IGN_BEFORE_BLK,
WARN_IGN_OBSOLETE,
WARN_SEC_OO,
+ WARN_SEC_REP,
WARN_ARGS_GE1,
WARN_ARGS_EQ0,
WARN_COMPAT_TROFF
@@ -269,7 +270,8 @@ enum mdoc_type {
MDOC_HEAD,
MDOC_TAIL,
MDOC_BODY,
- MDOC_BLOCK
+ MDOC_BLOCK,
+ MDOC_ROOT
};
enum mdoc_msec {
diff --git a/mdocml.c b/mdocml.c
index fbdddb68..f3b0a524 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -222,6 +222,10 @@ print_node(const struct mdoc_node *n, int indent)
argv = n->data.block.argv;
argc = n->data.block.argc;
break;
+ case (MDOC_ROOT):
+ p = "root";
+ t = "root";
+ break;
default:
abort();
/* NOTREACHED */
@@ -262,6 +266,8 @@ parse_leave(struct md_parse *p, int code)
if ((n = mdoc_result(p->mdoc)))
print_node(n, 0);
+ mdoc_free(p->mdoc);
+
return(code);
}
@@ -500,6 +506,9 @@ msg_warn(void *arg, int line, int col, enum mdoc_warn type)
case (WARN_SEC_OO):
lit = "section is out of conventional order";
break;
+ case (WARN_SEC_REP):
+ lit = "section repeated";
+ break;
case (WARN_ARGS_GE1):
lit = "macro suggests one or more arguments";
break;
diff --git a/private.h b/private.h
index 9b85cf99..5da7854e 100644
--- a/private.h
+++ b/private.h
@@ -78,6 +78,7 @@ int mdoc_elem_alloc(struct mdoc *, int, int,
int, size_t, const struct mdoc_arg *);
int mdoc_block_alloc(struct mdoc *, int, int,
int, size_t, const struct mdoc_arg *);
+int mdoc_root_alloc(struct mdoc *);
int mdoc_head_alloc(struct mdoc *, int, int, int);
int mdoc_tail_alloc(struct mdoc *, int, int, int);
int mdoc_body_alloc(struct mdoc *, int, int, int);
diff --git a/validate.c b/validate.c
index 3bc42792..37291092 100644
--- a/validate.c
+++ b/validate.c
@@ -32,25 +32,25 @@ struct valids {
};
-static int pre_sh(struct mdoc *, struct mdoc_node *);
static int pre_prologue(struct mdoc *, struct mdoc_node *);
static int pre_prologue(struct mdoc *, struct mdoc_node *);
static int pre_prologue(struct mdoc *, struct mdoc_node *);
static int post_headchild_err_ge1(struct mdoc *);
-static int post_headchild_err_le8(struct mdoc *);
+static int post_elemchild_err_ge1(struct mdoc *);
static int post_bodychild_warn_ge1(struct mdoc *);
+static int post_sh(struct mdoc *);
-static v_post posts_sh[] = { post_headchild_err_ge1,
- post_bodychild_warn_ge1,
- post_headchild_err_le8, NULL };
+static v_post posts_sh[] = { post_headchild_err_ge1,
+ post_bodychild_warn_ge1, post_sh, NULL };
+static v_post posts_dd[] = { post_elemchild_err_ge1, NULL };
const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* \" */
- { pre_prologue, NULL }, /* Dd */ /* TODO: pre: ordering, repetition */
- { pre_prologue, NULL }, /* Dt */ /* TODO ... */
- { pre_prologue, NULL }, /* Os */ /* TODO ... */
- { pre_sh, posts_sh }, /* Sh */ /* FIXME: preceding Pp. */
+ { pre_prologue, posts_dd }, /* Dd */
+ { pre_prologue, NULL }, /* Dt */
+ { pre_prologue, NULL }, /* Os */
+ { NULL, posts_sh }, /* Sh */ /* FIXME: preceding Pp. */
{ NULL, NULL }, /* Ss */ /* FIXME: preceding Pp. */
{ NULL, NULL }, /* Pp */
{ NULL, NULL }, /* D1 */
@@ -169,11 +169,10 @@ post_bodychild_warn_ge1(struct mdoc *mdoc)
static int
-post_headchild_err_ge1(struct mdoc *mdoc)
+post_elemchild_err_ge1(struct mdoc *mdoc)
{
- if (MDOC_HEAD != mdoc->last->type)
- return(1);
+ assert(MDOC_ELEM == mdoc->last->type);
if (mdoc->last->child)
return(1);
return(mdoc_err(mdoc, ERR_ARGS_GE1));
@@ -181,18 +180,14 @@ post_headchild_err_ge1(struct mdoc *mdoc)
static int
-post_headchild_err_le8(struct mdoc *mdoc)
+post_headchild_err_ge1(struct mdoc *mdoc)
{
- int i;
- struct mdoc_node *n;
if (MDOC_HEAD != mdoc->last->type)
return(1);
- for (i = 0, n = mdoc->last->child; n; n = n->next, i++)
- /* Do nothing. */ ;
- if (i <= 8)
+ if (mdoc->last->child)
return(1);
- return(mdoc_err(mdoc, ERR_ARGS_LE8));
+ return(mdoc_err(mdoc, ERR_ARGS_GE1));
}
@@ -248,11 +243,42 @@ pre_prologue(struct mdoc *mdoc, struct mdoc_node *node)
}
+/*
+ * Warn if sections (those that are with a known title, such as NAME,
+ * DESCRIPTION, and so forth) are out of the conventional order.
+ */
static int
-pre_sh(struct mdoc *mdoc, struct mdoc_node *node)
+post_sh(struct mdoc *mdoc)
{
+ enum mdoc_sec sec;
+ int i;
+ struct mdoc_node *n;
+ char *args[MDOC_LINEARG_MAX];
- return(1);
+ if (MDOC_HEAD != mdoc->last->type)
+ return(1);
+
+ assert(MDOC_Sh == mdoc->last->data.head.tok);
+
+ n = mdoc->last->child;
+ assert(n);
+
+ for (i = 0; n && i < MDOC_LINEARG_MAX; n = n->next, i++) {
+ assert(MDOC_TEXT == n->type);
+ assert(NULL == n->child);
+ assert(n->data.text.string);
+ args[i] = n->data.text.string;
+ }
+
+ sec = mdoc_atosec((size_t)i, (const char **)args);
+ if (SEC_CUSTOM == sec)
+ return(1);
+ if (sec > mdoc->sec_lastn)
+ return(1);
+
+ if (sec == mdoc->sec_lastn)
+ return(mdoc_warn(mdoc, WARN_SEC_REP));
+ return(mdoc_warn(mdoc, WARN_SEC_OO));
}