man.c revision 698f87a48e2e945bfe5493ce168e0d0ae1cedd5c
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore/* $Id: man.c,v 1.121 2013/11/10 22:54:40 schwarze Exp $ */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * copyright notice and this permission notice appear in all copies.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#ifdef HAVE_CONFIG_H
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "config.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#endif
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <sys/types.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <assert.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <stdarg.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <stdlib.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <stdio.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include <string.h>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "man.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "mandoc.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "libman.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore#include "libmandoc.h"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreconst char *const __man_macronames[MAN_MAX] = {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "br", "TH", "SH", "SS",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "TP", "LP", "PP", "P",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "IP", "HP", "SM", "SB",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "BI", "IB", "BR", "RB",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "R", "B", "I", "IR",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "RI", "na", "sp", "nf",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "fi", "RE", "RS", "DT",
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore "UC", "PD", "AT", "in",
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore "ft", "OP", "EX", "EE",
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore "UR", "UE"
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore };
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreconst char * const *man_macronames = __man_macronames;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic struct man_node *man_node_alloc(struct man *, int, int,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore enum man_type, enum mant);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int man_node_append(struct man *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void man_node_free(struct man_node *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void man_node_unlink(struct man *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int man_ptext(struct man *, int, char *, int);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int man_pmacro(struct man *, int, char *, int);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void man_free1(struct man *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void man_alloc1(struct man *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int man_descope(struct man *, int, int);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreconst struct man_node *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_node(const struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man->first);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreconst struct man_meta *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_meta(const struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(&man->meta);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorevoid
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_reset(struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_free1(man);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_alloc1(man);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorevoid
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_free(struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_free1(man);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestruct man *
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_alloc(struct roff *roff, struct mparse *parse)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p = mandoc_calloc(1, sizeof(struct man));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_hash_init();
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parse = parse;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->roff = roff;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_alloc1(p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_endparse(struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (man_macroend(man))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags |= MAN_HALT;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_parseln(struct man *man, int ln, char *buf, int offs)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags |= MAN_NEWLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return (roff_getcontrol(man->roff, buf, &offs) ?
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_pmacro(man, ln, buf, offs) :
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_ptext(man, ln, buf, offs));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_free1(struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->first)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_node_delete(man, man->first);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->meta.title)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man->meta.title);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->meta.source)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man->meta.source);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->meta.date)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man->meta.date);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->meta.vol)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man->meta.vol);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (man->meta.msec)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(man->meta.msec);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_alloc1(struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore memset(&man->meta, 0, sizeof(struct man_meta));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags = 0;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last = mandoc_calloc(1, sizeof(struct man_node));
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->first = man->last;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last->type = MAN_ROOT;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last->tok = MAN_MAX;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_node_append(struct man *man, struct man_node *p)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(man->last);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(man->first);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_ROOT != p->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore switch (man->next) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_NEXT_SIBLING):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man->last->next = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->prev = man->last;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent = man->last->parent;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_NEXT_CHILD):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man->last->child = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent = man->last;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore default:
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore abort();
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* NOTREACHED */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(p->parent);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent->nchild++;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( ! man_valid_pre(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore switch (p->type) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_HEAD):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_BLOCK == p->parent->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent->head = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_TAIL):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_BLOCK == p->parent->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent->tail = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_BODY):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_BLOCK == p->parent->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->parent->body = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore default:
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man->last = p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore switch (p->type) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_TBL):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore case (MAN_TEXT):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( ! man_valid_post(man))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore default:
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore break;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic struct man_node *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_node_alloc(struct man *man, int line, int pos,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore enum man_type type, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p = mandoc_calloc(1, sizeof(struct man_node));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->line = line;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->pos = pos;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->type = type;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->tok = tok;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_NEWLINE & man->flags)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore p->flags |= MAN_LINE;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_NEWLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_elem_alloc(struct man *man, int line, int pos, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_tail_alloc(struct man *man, int line, int pos, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore p = man_node_alloc(man, line, pos, MAN_TAIL, tok);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_head_alloc(struct man *man, int line, int pos, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_body_alloc(struct man *man, int line, int pos, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore p = man_node_alloc(man, line, pos, MAN_BODY, tok);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_block_alloc(struct man *man, int line, int pos, enum mant tok)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *p;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, p))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_word_alloc(struct man *man, int line, int pos, const char *word)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *n;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n->string = roff_strdup(man->roff, word);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, n))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_SIBLING;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Free all of the resources held by a node. This does NOT unlink a
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * node from its context; for that, see man_node_unlink().
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreman_node_free(struct man_node *p)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (p->string)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(p->string);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore free(p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorevoid
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_node_delete(struct man *man, struct man_node *p)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore while (p->child)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_node_delete(man, p->child);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_node_unlink(man, p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_node_free(p);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_addeqn(struct man *man, const struct eqn *ep)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *n;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->eqn = ep;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, n))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_SIBLING;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_descope(man, ep->ln, ep->pos));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreint
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_addspan(struct man *man, const struct tbl_span *sp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *n;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert( ! (MAN_HALT & man->flags));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->span = sp;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_node_append(man, n))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_SIBLING;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_descope(man, sp->line, 0));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_descope(struct man *man, int line, int offs)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Co-ordinate what happens with having a next-line scope open:
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * first close out the element scope (if applicable), then close
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * out the block scope (also if applicable).
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_ELINE & man->flags) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_ELINE;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! (MAN_BLINE & man->flags))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_BLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_body_alloc(man, line, offs, man->last->tok));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_ptext(struct man *man, int line, char *buf, int offs)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int i;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Literal free-form text whitespace is preserved. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_LITERAL & man->flags) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_word_alloc(man, line, offs, buf + offs))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_descope(man, line, offs));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore for (i = offs; ' ' == buf[i]; i++)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Skip leading whitespace. */ ;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore /*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Blank lines are ignored right after headings
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * but add a single vertical space elsewhere.
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ('\0' == buf[i]) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Allocate a blank entry. */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_SH != man->last->tok &&
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore MAN_SS != man->last->tok) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_elem_alloc(man, line, offs, MAN_sp))
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_SIBLING;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Warn if the last un-escaped character is whitespace. Then
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * strip away the remaining spaces (tabs stay!).
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore i = (int)strlen(buf);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(i);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (i > 1 && '\\' != buf[i - 2])
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore for (--i; i && ' ' == buf[i]; i--)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Spin back to non-space. */ ;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Jump ahead of escaped whitespace. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore i += '\\' == buf[i] ? 2 : 1;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore buf[i] = '\0';
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_word_alloc(man, line, offs, buf + offs))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * End-of-sentence check. If the last character is an unescaped
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * EOS character, then flag the node as being the end of a
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * sentence. The front-end will know how to interpret this.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(i);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (mandoc_eos(buf, (size_t)i, 0))
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last->flags |= MAN_EOS;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_descope(man, line, offs));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic int
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_pmacro(struct man *man, int ln, char *buf, int offs)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore int i, ppos;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore enum mant tok;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore char mac[5];
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore struct man_node *n;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ('"' == buf[offs]) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else if ('\0' == buf[offs])
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ppos = offs;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copy the first word into a nil-terminated buffer.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Stop copying when a tab, space, or eoln is encountered.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore i = 0;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore while (i < 4 && '\0' != buf[offs] &&
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ' ' != buf[offs] && '\t' != buf[offs])
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore mac[i++] = buf[offs++];
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore mac[i] = '\0';
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (MAN_MAX == tok) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ppos, "%s", buf + ppos - 1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* The macro is sane. Jump to the next word. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore while (buf[offs] && ' ' == buf[offs])
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore offs++;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Trailing whitespace. Note that tabs are allowed to be passed
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * into the parser as "text", so we only warn about spaces here.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ('\0' == buf[offs] && ' ' == buf[offs - 1])
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Remove prior ELINE macro, as it's being clobbered by a new
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * macro. Note that NSCOPED macros do not close out ELINE
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * macros---they don't print text---so we let those slip by.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags & MAN_ELINE) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n = man->last;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_TEXT != n->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Remove repeated NSCOPED macros causing ELINE. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (MAN_NSCOPED & man_macros[n->tok].flags)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n = n->parent;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->pos, "%s breaks %s", man_macronames[tok],
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_macronames[n->tok]);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_node_delete(man, n);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_ELINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Remove prior BLINE macro that is being clobbered.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ((man->flags & MAN_BLINE) &&
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore (MAN_BSCOPE & man_macros[tok].flags)) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore n = man->last;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Might be a text node like 8 in
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * .TP 8
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * .SH foo
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (MAN_TEXT == n->type)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n = n->parent;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Remove element that didn't end BLINE, if any. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if ( ! (MAN_BSCOPE & man_macros[n->tok].flags))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n = n->parent;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_HEAD == n->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n = n->parent;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_BLOCK == n->type);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(MAN_SCOPED & man_macros[n->tok].flags);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->pos, "%s breaks %s", man_macronames[tok],
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore man_macronames[n->tok]);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man_node_delete(man, n);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_BLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Save the fact that we're in the next-line for a block. In
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * this way, embedded roff instructions can "remember" state
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * when they exit.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_BLINE & man->flags)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags |= MAN_BPLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Call to handler... */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore assert(man_macros[tok].fp);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore goto err;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * We weren't in a block-line scope when entering the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * above-parsed macro, so return.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! (MAN_BPLINE & man->flags)) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_ILINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_BPLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * If we're in a block scope, then allow this macro to slip by
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * without closing scope around it.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_ILINE & man->flags) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_ILINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * If we've opened a new next-line element scope, then return
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * now, as the next line will close out the block scope.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (MAN_ELINE & man->flags)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(1);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Close out the block scope opened in the prior line. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert(MAN_BLINE & man->flags);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags &= ~MAN_BLINE;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man_body_alloc(man, ln, ppos, man->last->tok));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreerr: /* Error out. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->flags |= MAN_HALT;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return(0);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore/*
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore * Unlink a node from its context. If "man" is provided, the last parse
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * point will also be adjusted accordingly.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_node_unlink(struct man *man, struct man_node *n)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Adjust siblings. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (n->prev)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->prev->next = n->next;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (n->next)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->next->prev = n->prev;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Adjust parent. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (n->parent) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->parent->nchild--;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (n->parent->child == n)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore n->parent->child = n->prev ? n->prev : n->next;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Adjust parse point, if applicable. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (man && man->last == n) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*XXX: this can occur when bailing from validation. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /*assert(NULL == n->next);*/
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if (n->prev) {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last = n->prev;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_SIBLING;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore } else {
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->last = n->parent;
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->next = MAN_NEXT_CHILD;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore }
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (man && man->first == n)
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore man->first = NULL;
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoreconst struct mparse *
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amoreman_mparse(const struct man *man)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore{
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore assert(man && man->parse);
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore return(man->parse);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore}