- assert(tok < MDOC_MAX);
-
- /* If we're in the body, deny prologue calls. */
-
- if (MDOC_PROLOGUE & mdoc_macros[tok].flags &&
- MDOC_PBODY & m->flags) {
- mdoc_pmsg(m, line, ppos, MANDOCERR_BADBODY);
- return(1);
- }
-
- /* If we're in the prologue, deny "body" macros. */
-
- if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) &&
- ! (MDOC_PBODY & m->flags)) {
- mdoc_pmsg(m, line, ppos, MANDOCERR_BADPROLOG);
- if (NULL == m->meta.msec)
- m->meta.msec = mandoc_strdup("1");
- if (NULL == m->meta.title)
- m->meta.title = mandoc_strdup("UNKNOWN");
- if (NULL == m->meta.vol)
- m->meta.vol = mandoc_strdup("LOCAL");
- if (NULL == m->meta.os)
- m->meta.os = mandoc_strdup("LOCAL");
- if (NULL == m->meta.date)
- m->meta.date = mandoc_normdate
- (m->parse, NULL, line, ppos);
- m->flags |= MDOC_PBODY;
- }
-
- return((*mdoc_macros[tok].fp)(m, tok, line, ppos, pos, buf));
-}
-
-
-static int
-node_append(struct mdoc *mdoc, struct mdoc_node *p)
-{
-
- assert(mdoc->last);
- assert(mdoc->first);
- assert(MDOC_ROOT != p->type);
-
- switch (mdoc->next) {
- case (MDOC_NEXT_SIBLING):
- mdoc->last->next = p;
- p->prev = mdoc->last;
- p->parent = mdoc->last->parent;
- break;
- case (MDOC_NEXT_CHILD):
- mdoc->last->child = p;
- p->parent = mdoc->last;
- break;
- default:
- abort();
- /* NOTREACHED */
- }
-
- p->parent->nchild++;
-
- /*
- * Copy over the normalised-data pointer of our parent. Not
- * everybody has one, but copying a null pointer is fine.
- */
-
- switch (p->type) {
- case (MDOC_BODY):
- /* FALLTHROUGH */
- case (MDOC_TAIL):
- /* FALLTHROUGH */
- case (MDOC_HEAD):
- p->norm = p->parent->norm;
- break;
- default:
- break;
- }
-
- if ( ! mdoc_valid_pre(mdoc, p))
- return(0);
-
- switch (p->type) {
- case (MDOC_HEAD):
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->head = p;
- break;
- case (MDOC_TAIL):
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->tail = p;
- break;
- case (MDOC_BODY):
- if (p->end)
- break;
- assert(MDOC_BLOCK == p->parent->type);
- p->parent->body = p;
- break;
- default:
- break;
- }
-
- mdoc->last = p;
-
- switch (p->type) {
- case (MDOC_TBL):
- /* FALLTHROUGH */
- case (MDOC_TEXT):
- if ( ! mdoc_valid_post(mdoc))
- return(0);
- break;
- default:
- break;
+ assert(tok > TOKEN_NONE && tok < MDOC_MAX);
+
+ if (mdoc->flags & MDOC_PBODY) {
+ if (tok == MDOC_Dt) {
+ mandoc_vmsg(MANDOCERR_DT_LATE,
+ mdoc->parse, line, ppos,
+ "Dt %s", buf + *pos);
+ return;
+ }
+ } 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");
+ mdoc->flags |= MDOC_PBODY;