- 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 (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;
- }
-
- return((*mdoc_macros[tok].fp)(mdoc, 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:
- if (ENDBODY_NOT != p->end)
- break;
- /* 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;
- }
-
- return(1);
-}
-
-static struct mdoc_node *
-node_alloc(struct mdoc *mdoc, int line, int pos,
- enum mdoct tok, enum mdoc_type type)
-{
- struct mdoc_node *p;
-
- p = mandoc_calloc(1, sizeof(struct mdoc_node));
- p->sec = mdoc->lastsec;
- p->line = line;
- p->pos = pos;
- p->lastline = line;
- p->tok = tok;
- p->type = type;
-
- /* Flag analysis. */
-
- if (MDOC_SYNOPSIS & mdoc->flags)
- p->flags |= MDOC_SYNPRETTY;
- else
- p->flags &= ~MDOC_SYNPRETTY;
- if (MDOC_NEWLINE & mdoc->flags)
- p->flags |= MDOC_LINE;
- mdoc->flags &= ~MDOC_NEWLINE;
-
- return(p);
-}
-
-int
-mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
-{
- struct mdoc_node *p;