Home | History | Annotate | Line # | Download | only in dist
man.c revision 1.1.1.13.6.1
      1  1.1.1.13.6.1    tls /*	Id: man.c,v 1.122 2013/12/31 23:23:10 schwarze Exp  */
      2           1.1  joerg /*
      3      1.1.1.11  joerg  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps (at) bsd.lv>
      4           1.1  joerg  *
      5           1.1  joerg  * Permission to use, copy, modify, and distribute this software for any
      6           1.1  joerg  * purpose with or without fee is hereby granted, provided that the above
      7           1.1  joerg  * copyright notice and this permission notice appear in all copies.
      8           1.1  joerg  *
      9           1.1  joerg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10           1.1  joerg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11           1.1  joerg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12           1.1  joerg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13           1.1  joerg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14           1.1  joerg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15           1.1  joerg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16           1.1  joerg  */
     17       1.1.1.4  joerg #ifdef HAVE_CONFIG_H
     18       1.1.1.4  joerg #include "config.h"
     19       1.1.1.4  joerg #endif
     20       1.1.1.4  joerg 
     21           1.1  joerg #include <sys/types.h>
     22           1.1  joerg 
     23           1.1  joerg #include <assert.h>
     24           1.1  joerg #include <stdarg.h>
     25           1.1  joerg #include <stdlib.h>
     26           1.1  joerg #include <stdio.h>
     27           1.1  joerg #include <string.h>
     28           1.1  joerg 
     29      1.1.1.11  joerg #include "man.h"
     30       1.1.1.6  joerg #include "mandoc.h"
     31           1.1  joerg #include "libman.h"
     32       1.1.1.3  joerg #include "libmandoc.h"
     33           1.1  joerg 
     34           1.1  joerg const	char *const __man_macronames[MAN_MAX] = {
     35           1.1  joerg 	"br",		"TH",		"SH",		"SS",
     36           1.1  joerg 	"TP", 		"LP",		"PP",		"P",
     37           1.1  joerg 	"IP",		"HP",		"SM",		"SB",
     38           1.1  joerg 	"BI",		"IB",		"BR",		"RB",
     39           1.1  joerg 	"R",		"B",		"I",		"IR",
     40      1.1.1.10  joerg 	"RI",		"na",		"sp",		"nf",
     41      1.1.1.10  joerg 	"fi",		"RE",		"RS",		"DT",
     42      1.1.1.10  joerg 	"UC",		"PD",		"AT",		"in",
     43  1.1.1.13.6.1    tls 	"ft",		"OP",		"EX",		"EE",
     44  1.1.1.13.6.1    tls 	"UR",		"UE"
     45           1.1  joerg 	};
     46           1.1  joerg 
     47           1.1  joerg const	char * const *man_macronames = __man_macronames;
     48           1.1  joerg 
     49      1.1.1.11  joerg static	struct man_node	*man_node_alloc(struct man *, int, int,
     50       1.1.1.5  joerg 				enum man_type, enum mant);
     51           1.1  joerg static	int		 man_node_append(struct man *,
     52           1.1  joerg 				struct man_node *);
     53       1.1.1.5  joerg static	void		 man_node_free(struct man_node *);
     54       1.1.1.5  joerg static	void		 man_node_unlink(struct man *,
     55       1.1.1.5  joerg 				struct man_node *);
     56       1.1.1.6  joerg static	int		 man_ptext(struct man *, int, char *, int);
     57       1.1.1.6  joerg static	int		 man_pmacro(struct man *, int, char *, int);
     58           1.1  joerg static	void		 man_free1(struct man *);
     59       1.1.1.3  joerg static	void		 man_alloc1(struct man *);
     60      1.1.1.10  joerg static	int		 man_descope(struct man *, int, int);
     61           1.1  joerg 
     62           1.1  joerg 
     63           1.1  joerg const struct man_node *
     64  1.1.1.13.6.1    tls man_node(const struct man *man)
     65           1.1  joerg {
     66           1.1  joerg 
     67  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
     68  1.1.1.13.6.1    tls 	return(man->first);
     69           1.1  joerg }
     70           1.1  joerg 
     71           1.1  joerg 
     72           1.1  joerg const struct man_meta *
     73  1.1.1.13.6.1    tls man_meta(const struct man *man)
     74           1.1  joerg {
     75           1.1  joerg 
     76  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
     77  1.1.1.13.6.1    tls 	return(&man->meta);
     78           1.1  joerg }
     79           1.1  joerg 
     80           1.1  joerg 
     81       1.1.1.3  joerg void
     82           1.1  joerg man_reset(struct man *man)
     83           1.1  joerg {
     84           1.1  joerg 
     85           1.1  joerg 	man_free1(man);
     86       1.1.1.3  joerg 	man_alloc1(man);
     87           1.1  joerg }
     88           1.1  joerg 
     89           1.1  joerg 
     90           1.1  joerg void
     91           1.1  joerg man_free(struct man *man)
     92           1.1  joerg {
     93           1.1  joerg 
     94           1.1  joerg 	man_free1(man);
     95           1.1  joerg 	free(man);
     96           1.1  joerg }
     97           1.1  joerg 
     98           1.1  joerg 
     99           1.1  joerg struct man *
    100      1.1.1.12  joerg man_alloc(struct roff *roff, struct mparse *parse)
    101           1.1  joerg {
    102           1.1  joerg 	struct man	*p;
    103           1.1  joerg 
    104       1.1.1.3  joerg 	p = mandoc_calloc(1, sizeof(struct man));
    105           1.1  joerg 
    106           1.1  joerg 	man_hash_init();
    107      1.1.1.11  joerg 	p->parse = parse;
    108      1.1.1.12  joerg 	p->roff = roff;
    109       1.1.1.3  joerg 
    110       1.1.1.3  joerg 	man_alloc1(p);
    111           1.1  joerg 	return(p);
    112           1.1  joerg }
    113           1.1  joerg 
    114           1.1  joerg 
    115           1.1  joerg int
    116  1.1.1.13.6.1    tls man_endparse(struct man *man)
    117           1.1  joerg {
    118           1.1  joerg 
    119  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
    120  1.1.1.13.6.1    tls 	if (man_macroend(man))
    121           1.1  joerg 		return(1);
    122  1.1.1.13.6.1    tls 	man->flags |= MAN_HALT;
    123           1.1  joerg 	return(0);
    124           1.1  joerg }
    125           1.1  joerg 
    126           1.1  joerg 
    127           1.1  joerg int
    128  1.1.1.13.6.1    tls man_parseln(struct man *man, int ln, char *buf, int offs)
    129           1.1  joerg {
    130           1.1  joerg 
    131  1.1.1.13.6.1    tls 	man->flags |= MAN_NEWLINE;
    132      1.1.1.11  joerg 
    133  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
    134      1.1.1.11  joerg 
    135  1.1.1.13.6.1    tls 	return (roff_getcontrol(man->roff, buf, &offs) ?
    136  1.1.1.13.6.1    tls 			man_pmacro(man, ln, buf, offs) :
    137  1.1.1.13.6.1    tls 			man_ptext(man, ln, buf, offs));
    138           1.1  joerg }
    139           1.1  joerg 
    140           1.1  joerg 
    141           1.1  joerg static void
    142           1.1  joerg man_free1(struct man *man)
    143           1.1  joerg {
    144           1.1  joerg 
    145           1.1  joerg 	if (man->first)
    146       1.1.1.5  joerg 		man_node_delete(man, man->first);
    147           1.1  joerg 	if (man->meta.title)
    148           1.1  joerg 		free(man->meta.title);
    149           1.1  joerg 	if (man->meta.source)
    150           1.1  joerg 		free(man->meta.source);
    151      1.1.1.11  joerg 	if (man->meta.date)
    152      1.1.1.11  joerg 		free(man->meta.date);
    153           1.1  joerg 	if (man->meta.vol)
    154           1.1  joerg 		free(man->meta.vol);
    155       1.1.1.6  joerg 	if (man->meta.msec)
    156       1.1.1.6  joerg 		free(man->meta.msec);
    157           1.1  joerg }
    158           1.1  joerg 
    159           1.1  joerg 
    160       1.1.1.3  joerg static void
    161  1.1.1.13.6.1    tls man_alloc1(struct man *man)
    162           1.1  joerg {
    163           1.1  joerg 
    164  1.1.1.13.6.1    tls 	memset(&man->meta, 0, sizeof(struct man_meta));
    165  1.1.1.13.6.1    tls 	man->flags = 0;
    166  1.1.1.13.6.1    tls 	man->last = mandoc_calloc(1, sizeof(struct man_node));
    167  1.1.1.13.6.1    tls 	man->first = man->last;
    168  1.1.1.13.6.1    tls 	man->last->type = MAN_ROOT;
    169  1.1.1.13.6.1    tls 	man->last->tok = MAN_MAX;
    170  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    171           1.1  joerg }
    172           1.1  joerg 
    173           1.1  joerg 
    174           1.1  joerg static int
    175           1.1  joerg man_node_append(struct man *man, struct man_node *p)
    176           1.1  joerg {
    177           1.1  joerg 
    178           1.1  joerg 	assert(man->last);
    179           1.1  joerg 	assert(man->first);
    180           1.1  joerg 	assert(MAN_ROOT != p->type);
    181           1.1  joerg 
    182           1.1  joerg 	switch (man->next) {
    183           1.1  joerg 	case (MAN_NEXT_SIBLING):
    184           1.1  joerg 		man->last->next = p;
    185           1.1  joerg 		p->prev = man->last;
    186           1.1  joerg 		p->parent = man->last->parent;
    187           1.1  joerg 		break;
    188           1.1  joerg 	case (MAN_NEXT_CHILD):
    189           1.1  joerg 		man->last->child = p;
    190           1.1  joerg 		p->parent = man->last;
    191           1.1  joerg 		break;
    192           1.1  joerg 	default:
    193           1.1  joerg 		abort();
    194           1.1  joerg 		/* NOTREACHED */
    195           1.1  joerg 	}
    196           1.1  joerg 
    197       1.1.1.5  joerg 	assert(p->parent);
    198           1.1  joerg 	p->parent->nchild++;
    199           1.1  joerg 
    200           1.1  joerg 	if ( ! man_valid_pre(man, p))
    201           1.1  joerg 		return(0);
    202           1.1  joerg 
    203           1.1  joerg 	switch (p->type) {
    204           1.1  joerg 	case (MAN_HEAD):
    205           1.1  joerg 		assert(MAN_BLOCK == p->parent->type);
    206           1.1  joerg 		p->parent->head = p;
    207           1.1  joerg 		break;
    208      1.1.1.11  joerg 	case (MAN_TAIL):
    209      1.1.1.11  joerg 		assert(MAN_BLOCK == p->parent->type);
    210      1.1.1.11  joerg 		p->parent->tail = p;
    211      1.1.1.11  joerg 		break;
    212           1.1  joerg 	case (MAN_BODY):
    213           1.1  joerg 		assert(MAN_BLOCK == p->parent->type);
    214           1.1  joerg 		p->parent->body = p;
    215           1.1  joerg 		break;
    216           1.1  joerg 	default:
    217           1.1  joerg 		break;
    218           1.1  joerg 	}
    219           1.1  joerg 
    220           1.1  joerg 	man->last = p;
    221           1.1  joerg 
    222           1.1  joerg 	switch (p->type) {
    223      1.1.1.10  joerg 	case (MAN_TBL):
    224      1.1.1.10  joerg 		/* FALLTHROUGH */
    225           1.1  joerg 	case (MAN_TEXT):
    226           1.1  joerg 		if ( ! man_valid_post(man))
    227           1.1  joerg 			return(0);
    228           1.1  joerg 		break;
    229           1.1  joerg 	default:
    230           1.1  joerg 		break;
    231           1.1  joerg 	}
    232           1.1  joerg 
    233           1.1  joerg 	return(1);
    234           1.1  joerg }
    235           1.1  joerg 
    236           1.1  joerg 
    237           1.1  joerg static struct man_node *
    238  1.1.1.13.6.1    tls man_node_alloc(struct man *man, int line, int pos,
    239      1.1.1.11  joerg 		enum man_type type, enum mant tok)
    240           1.1  joerg {
    241           1.1  joerg 	struct man_node *p;
    242           1.1  joerg 
    243       1.1.1.3  joerg 	p = mandoc_calloc(1, sizeof(struct man_node));
    244           1.1  joerg 	p->line = line;
    245           1.1  joerg 	p->pos = pos;
    246           1.1  joerg 	p->type = type;
    247           1.1  joerg 	p->tok = tok;
    248      1.1.1.11  joerg 
    249  1.1.1.13.6.1    tls 	if (MAN_NEWLINE & man->flags)
    250      1.1.1.11  joerg 		p->flags |= MAN_LINE;
    251  1.1.1.13.6.1    tls 	man->flags &= ~MAN_NEWLINE;
    252           1.1  joerg 	return(p);
    253           1.1  joerg }
    254           1.1  joerg 
    255           1.1  joerg 
    256           1.1  joerg int
    257  1.1.1.13.6.1    tls man_elem_alloc(struct man *man, int line, int pos, enum mant tok)
    258           1.1  joerg {
    259           1.1  joerg 	struct man_node *p;
    260           1.1  joerg 
    261  1.1.1.13.6.1    tls 	p = man_node_alloc(man, line, pos, MAN_ELEM, tok);
    262  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, p))
    263           1.1  joerg 		return(0);
    264  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    265           1.1  joerg 	return(1);
    266           1.1  joerg }
    267           1.1  joerg 
    268           1.1  joerg 
    269           1.1  joerg int
    270  1.1.1.13.6.1    tls man_tail_alloc(struct man *man, int line, int pos, enum mant tok)
    271           1.1  joerg {
    272           1.1  joerg 	struct man_node *p;
    273           1.1  joerg 
    274  1.1.1.13.6.1    tls 	p = man_node_alloc(man, line, pos, MAN_TAIL, tok);
    275  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, p))
    276           1.1  joerg 		return(0);
    277  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    278           1.1  joerg 	return(1);
    279           1.1  joerg }
    280           1.1  joerg 
    281           1.1  joerg 
    282           1.1  joerg int
    283  1.1.1.13.6.1    tls man_head_alloc(struct man *man, int line, int pos, enum mant tok)
    284           1.1  joerg {
    285           1.1  joerg 	struct man_node *p;
    286           1.1  joerg 
    287  1.1.1.13.6.1    tls 	p = man_node_alloc(man, line, pos, MAN_HEAD, tok);
    288  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, p))
    289           1.1  joerg 		return(0);
    290  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    291           1.1  joerg 	return(1);
    292           1.1  joerg }
    293           1.1  joerg 
    294           1.1  joerg 
    295           1.1  joerg int
    296  1.1.1.13.6.1    tls man_body_alloc(struct man *man, int line, int pos, enum mant tok)
    297           1.1  joerg {
    298           1.1  joerg 	struct man_node *p;
    299           1.1  joerg 
    300  1.1.1.13.6.1    tls 	p = man_node_alloc(man, line, pos, MAN_BODY, tok);
    301  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, p))
    302           1.1  joerg 		return(0);
    303  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    304           1.1  joerg 	return(1);
    305           1.1  joerg }
    306           1.1  joerg 
    307      1.1.1.10  joerg 
    308      1.1.1.11  joerg int
    309  1.1.1.13.6.1    tls man_block_alloc(struct man *man, int line, int pos, enum mant tok)
    310      1.1.1.11  joerg {
    311      1.1.1.11  joerg 	struct man_node *p;
    312      1.1.1.10  joerg 
    313  1.1.1.13.6.1    tls 	p = man_node_alloc(man, line, pos, MAN_BLOCK, tok);
    314  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, p))
    315      1.1.1.10  joerg 		return(0);
    316  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_CHILD;
    317      1.1.1.10  joerg 	return(1);
    318      1.1.1.10  joerg }
    319           1.1  joerg 
    320       1.1.1.6  joerg int
    321  1.1.1.13.6.1    tls man_word_alloc(struct man *man, int line, int pos, const char *word)
    322           1.1  joerg {
    323           1.1  joerg 	struct man_node	*n;
    324           1.1  joerg 
    325  1.1.1.13.6.1    tls 	n = man_node_alloc(man, line, pos, MAN_TEXT, MAN_MAX);
    326  1.1.1.13.6.1    tls 	n->string = roff_strdup(man->roff, word);
    327           1.1  joerg 
    328  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, n))
    329           1.1  joerg 		return(0);
    330       1.1.1.6  joerg 
    331  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_SIBLING;
    332           1.1  joerg 	return(1);
    333           1.1  joerg }
    334           1.1  joerg 
    335           1.1  joerg 
    336       1.1.1.5  joerg /*
    337       1.1.1.5  joerg  * Free all of the resources held by a node.  This does NOT unlink a
    338       1.1.1.5  joerg  * node from its context; for that, see man_node_unlink().
    339       1.1.1.5  joerg  */
    340       1.1.1.5  joerg static void
    341           1.1  joerg man_node_free(struct man_node *p)
    342           1.1  joerg {
    343           1.1  joerg 
    344           1.1  joerg 	if (p->string)
    345           1.1  joerg 		free(p->string);
    346           1.1  joerg 	free(p);
    347           1.1  joerg }
    348           1.1  joerg 
    349           1.1  joerg 
    350           1.1  joerg void
    351  1.1.1.13.6.1    tls man_node_delete(struct man *man, struct man_node *p)
    352           1.1  joerg {
    353           1.1  joerg 
    354       1.1.1.5  joerg 	while (p->child)
    355  1.1.1.13.6.1    tls 		man_node_delete(man, p->child);
    356       1.1.1.5  joerg 
    357  1.1.1.13.6.1    tls 	man_node_unlink(man, p);
    358           1.1  joerg 	man_node_free(p);
    359           1.1  joerg }
    360           1.1  joerg 
    361      1.1.1.11  joerg int
    362  1.1.1.13.6.1    tls man_addeqn(struct man *man, const struct eqn *ep)
    363      1.1.1.11  joerg {
    364      1.1.1.11  joerg 	struct man_node	*n;
    365      1.1.1.11  joerg 
    366  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
    367      1.1.1.11  joerg 
    368  1.1.1.13.6.1    tls 	n = man_node_alloc(man, ep->ln, ep->pos, MAN_EQN, MAN_MAX);
    369      1.1.1.11  joerg 	n->eqn = ep;
    370      1.1.1.11  joerg 
    371  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, n))
    372      1.1.1.11  joerg 		return(0);
    373      1.1.1.11  joerg 
    374  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_SIBLING;
    375  1.1.1.13.6.1    tls 	return(man_descope(man, ep->ln, ep->pos));
    376      1.1.1.11  joerg }
    377           1.1  joerg 
    378      1.1.1.10  joerg int
    379  1.1.1.13.6.1    tls man_addspan(struct man *man, const struct tbl_span *sp)
    380      1.1.1.10  joerg {
    381      1.1.1.11  joerg 	struct man_node	*n;
    382      1.1.1.10  joerg 
    383  1.1.1.13.6.1    tls 	assert( ! (MAN_HALT & man->flags));
    384      1.1.1.11  joerg 
    385  1.1.1.13.6.1    tls 	n = man_node_alloc(man, sp->line, 0, MAN_TBL, MAN_MAX);
    386      1.1.1.11  joerg 	n->span = sp;
    387      1.1.1.11  joerg 
    388  1.1.1.13.6.1    tls 	if ( ! man_node_append(man, n))
    389      1.1.1.10  joerg 		return(0);
    390      1.1.1.11  joerg 
    391  1.1.1.13.6.1    tls 	man->next = MAN_NEXT_SIBLING;
    392  1.1.1.13.6.1    tls 	return(man_descope(man, sp->line, 0));
    393      1.1.1.10  joerg }
    394      1.1.1.10  joerg 
    395      1.1.1.10  joerg static int
    396  1.1.1.13.6.1    tls man_descope(struct man *man, int line, int offs)
    397      1.1.1.10  joerg {
    398      1.1.1.10  joerg 	/*
    399      1.1.1.10  joerg 	 * Co-ordinate what happens with having a next-line scope open:
    400      1.1.1.10  joerg 	 * first close out the element scope (if applicable), then close
    401      1.1.1.10  joerg 	 * out the block scope (also if applicable).
    402      1.1.1.10  joerg 	 */
    403      1.1.1.10  joerg 
    404  1.1.1.13.6.1    tls 	if (MAN_ELINE & man->flags) {
    405  1.1.1.13.6.1    tls 		man->flags &= ~MAN_ELINE;
    406  1.1.1.13.6.1    tls 		if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
    407      1.1.1.10  joerg 			return(0);
    408      1.1.1.10  joerg 	}
    409      1.1.1.10  joerg 
    410  1.1.1.13.6.1    tls 	if ( ! (MAN_BLINE & man->flags))
    411      1.1.1.10  joerg 		return(1);
    412  1.1.1.13.6.1    tls 	man->flags &= ~MAN_BLINE;
    413      1.1.1.10  joerg 
    414  1.1.1.13.6.1    tls 	if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
    415      1.1.1.10  joerg 		return(0);
    416  1.1.1.13.6.1    tls 	return(man_body_alloc(man, line, offs, man->last->tok));
    417      1.1.1.10  joerg }
    418      1.1.1.10  joerg 
    419           1.1  joerg static int
    420  1.1.1.13.6.1    tls man_ptext(struct man *man, int line, char *buf, int offs)
    421           1.1  joerg {
    422       1.1.1.6  joerg 	int		 i;
    423       1.1.1.6  joerg 
    424           1.1  joerg 	/* Literal free-form text whitespace is preserved. */
    425           1.1  joerg 
    426  1.1.1.13.6.1    tls 	if (MAN_LITERAL & man->flags) {
    427  1.1.1.13.6.1    tls 		if ( ! man_word_alloc(man, line, offs, buf + offs))
    428           1.1  joerg 			return(0);
    429  1.1.1.13.6.1    tls 		return(man_descope(man, line, offs));
    430           1.1  joerg 	}
    431           1.1  joerg 
    432       1.1.1.6  joerg 	for (i = offs; ' ' == buf[i]; i++)
    433           1.1  joerg 		/* Skip leading whitespace. */ ;
    434       1.1.1.4  joerg 
    435  1.1.1.13.6.1    tls 	/*
    436  1.1.1.13.6.1    tls 	 * Blank lines are ignored right after headings
    437  1.1.1.13.6.1    tls 	 * but add a single vertical space elsewhere.
    438  1.1.1.13.6.1    tls 	 */
    439  1.1.1.13.6.1    tls 
    440       1.1.1.4  joerg 	if ('\0' == buf[i]) {
    441       1.1.1.6  joerg 		/* Allocate a blank entry. */
    442  1.1.1.13.6.1    tls 		if (MAN_SH != man->last->tok &&
    443  1.1.1.13.6.1    tls 		    MAN_SS != man->last->tok) {
    444  1.1.1.13.6.1    tls 			if ( ! man_elem_alloc(man, line, offs, MAN_sp))
    445  1.1.1.13.6.1    tls 				return(0);
    446  1.1.1.13.6.1    tls 			man->next = MAN_NEXT_SIBLING;
    447  1.1.1.13.6.1    tls 		}
    448  1.1.1.13.6.1    tls 		return(1);
    449           1.1  joerg 	}
    450           1.1  joerg 
    451       1.1.1.6  joerg 	/*
    452       1.1.1.6  joerg 	 * Warn if the last un-escaped character is whitespace. Then
    453       1.1.1.6  joerg 	 * strip away the remaining spaces (tabs stay!).
    454       1.1.1.6  joerg 	 */
    455           1.1  joerg 
    456       1.1.1.6  joerg 	i = (int)strlen(buf);
    457       1.1.1.6  joerg 	assert(i);
    458       1.1.1.4  joerg 
    459       1.1.1.6  joerg 	if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
    460       1.1.1.6  joerg 		if (i > 1 && '\\' != buf[i - 2])
    461  1.1.1.13.6.1    tls 			man_pmsg(man, line, i - 1, MANDOCERR_EOLNSPACE);
    462       1.1.1.4  joerg 
    463       1.1.1.6  joerg 		for (--i; i && ' ' == buf[i]; i--)
    464       1.1.1.6  joerg 			/* Spin back to non-space. */ ;
    465       1.1.1.4  joerg 
    466       1.1.1.6  joerg 		/* Jump ahead of escaped whitespace. */
    467       1.1.1.6  joerg 		i += '\\' == buf[i] ? 2 : 1;
    468       1.1.1.4  joerg 
    469       1.1.1.6  joerg 		buf[i] = '\0';
    470           1.1  joerg 	}
    471           1.1  joerg 
    472  1.1.1.13.6.1    tls 	if ( ! man_word_alloc(man, line, offs, buf + offs))
    473           1.1  joerg 		return(0);
    474           1.1  joerg 
    475       1.1.1.6  joerg 	/*
    476       1.1.1.6  joerg 	 * End-of-sentence check.  If the last character is an unescaped
    477       1.1.1.6  joerg 	 * EOS character, then flag the node as being the end of a
    478       1.1.1.6  joerg 	 * sentence.  The front-end will know how to interpret this.
    479       1.1.1.6  joerg 	 */
    480       1.1.1.6  joerg 
    481       1.1.1.6  joerg 	assert(i);
    482  1.1.1.13.6.1    tls 	if (mandoc_eos(buf, (size_t)i))
    483  1.1.1.13.6.1    tls 		man->last->flags |= MAN_EOS;
    484           1.1  joerg 
    485  1.1.1.13.6.1    tls 	return(man_descope(man, line, offs));
    486           1.1  joerg }
    487           1.1  joerg 
    488       1.1.1.2  joerg static int
    489  1.1.1.13.6.1    tls man_pmacro(struct man *man, int ln, char *buf, int offs)
    490           1.1  joerg {
    491      1.1.1.11  joerg 	int		 i, ppos;
    492       1.1.1.5  joerg 	enum mant	 tok;
    493           1.1  joerg 	char		 mac[5];
    494           1.1  joerg 	struct man_node	*n;
    495           1.1  joerg 
    496      1.1.1.11  joerg 	if ('"' == buf[offs]) {
    497  1.1.1.13.6.1    tls 		man_pmsg(man, ln, offs, MANDOCERR_BADCOMMENT);
    498      1.1.1.11  joerg 		return(1);
    499      1.1.1.11  joerg 	} else if ('\0' == buf[offs])
    500       1.1.1.3  joerg 		return(1);
    501           1.1  joerg 
    502      1.1.1.11  joerg 	ppos = offs;
    503           1.1  joerg 
    504      1.1.1.10  joerg 	/*
    505      1.1.1.10  joerg 	 * Copy the first word into a nil-terminated buffer.
    506      1.1.1.10  joerg 	 * Stop copying when a tab, space, or eoln is encountered.
    507      1.1.1.10  joerg 	 */
    508           1.1  joerg 
    509      1.1.1.11  joerg 	i = 0;
    510      1.1.1.11  joerg 	while (i < 4 && '\0' != buf[offs] &&
    511      1.1.1.11  joerg 			' ' != buf[offs] && '\t' != buf[offs])
    512      1.1.1.11  joerg 		mac[i++] = buf[offs++];
    513      1.1.1.11  joerg 
    514      1.1.1.11  joerg 	mac[i] = '\0';
    515      1.1.1.11  joerg 
    516      1.1.1.11  joerg 	tok = (i > 0 && i < 4) ? man_hash_find(mac) : MAN_MAX;
    517           1.1  joerg 
    518      1.1.1.10  joerg 	if (MAN_MAX == tok) {
    519  1.1.1.13.6.1    tls 		mandoc_vmsg(MANDOCERR_MACRO, man->parse, ln,
    520      1.1.1.11  joerg 				ppos, "%s", buf + ppos - 1);
    521           1.1  joerg 		return(1);
    522           1.1  joerg 	}
    523           1.1  joerg 
    524           1.1  joerg 	/* The macro is sane.  Jump to the next word. */
    525           1.1  joerg 
    526      1.1.1.11  joerg 	while (buf[offs] && ' ' == buf[offs])
    527      1.1.1.11  joerg 		offs++;
    528           1.1  joerg 
    529       1.1.1.6  joerg 	/*
    530       1.1.1.6  joerg 	 * Trailing whitespace.  Note that tabs are allowed to be passed
    531       1.1.1.6  joerg 	 * into the parser as "text", so we only warn about spaces here.
    532       1.1.1.6  joerg 	 */
    533       1.1.1.4  joerg 
    534      1.1.1.11  joerg 	if ('\0' == buf[offs] && ' ' == buf[offs - 1])
    535  1.1.1.13.6.1    tls 		man_pmsg(man, ln, offs - 1, MANDOCERR_EOLNSPACE);
    536       1.1.1.4  joerg 
    537       1.1.1.5  joerg 	/*
    538      1.1.1.10  joerg 	 * Remove prior ELINE macro, as it's being clobbered by a new
    539       1.1.1.5  joerg 	 * macro.  Note that NSCOPED macros do not close out ELINE
    540       1.1.1.5  joerg 	 * macros---they don't print text---so we let those slip by.
    541       1.1.1.5  joerg 	 */
    542       1.1.1.5  joerg 
    543       1.1.1.5  joerg 	if ( ! (MAN_NSCOPED & man_macros[tok].flags) &&
    544  1.1.1.13.6.1    tls 			man->flags & MAN_ELINE) {
    545  1.1.1.13.6.1    tls 		n = man->last;
    546      1.1.1.10  joerg 		assert(MAN_TEXT != n->type);
    547       1.1.1.5  joerg 
    548      1.1.1.10  joerg 		/* Remove repeated NSCOPED macros causing ELINE. */
    549       1.1.1.5  joerg 
    550      1.1.1.10  joerg 		if (MAN_NSCOPED & man_macros[n->tok].flags)
    551      1.1.1.10  joerg 			n = n->parent;
    552      1.1.1.10  joerg 
    553  1.1.1.13.6.1    tls 		mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
    554      1.1.1.13  joerg 		    n->pos, "%s breaks %s", man_macronames[tok],
    555      1.1.1.13  joerg 		    man_macronames[n->tok]);
    556           1.1  joerg 
    557  1.1.1.13.6.1    tls 		man_node_delete(man, n);
    558  1.1.1.13.6.1    tls 		man->flags &= ~MAN_ELINE;
    559           1.1  joerg 	}
    560           1.1  joerg 
    561       1.1.1.5  joerg 	/*
    562      1.1.1.13  joerg 	 * Remove prior BLINE macro that is being clobbered.
    563      1.1.1.13  joerg 	 */
    564  1.1.1.13.6.1    tls 	if ((man->flags & MAN_BLINE) &&
    565      1.1.1.13  joerg 	    (MAN_BSCOPE & man_macros[tok].flags)) {
    566  1.1.1.13.6.1    tls 		n = man->last;
    567      1.1.1.13  joerg 
    568      1.1.1.13  joerg 		/* Might be a text node like 8 in
    569      1.1.1.13  joerg 		 * .TP 8
    570      1.1.1.13  joerg 		 * .SH foo
    571      1.1.1.13  joerg 		 */
    572      1.1.1.13  joerg 		if (MAN_TEXT == n->type)
    573      1.1.1.13  joerg 			n = n->parent;
    574      1.1.1.13  joerg 
    575      1.1.1.13  joerg 		/* Remove element that didn't end BLINE, if any. */
    576      1.1.1.13  joerg 		if ( ! (MAN_BSCOPE & man_macros[n->tok].flags))
    577      1.1.1.13  joerg 			n = n->parent;
    578      1.1.1.13  joerg 
    579      1.1.1.13  joerg 		assert(MAN_HEAD == n->type);
    580      1.1.1.13  joerg 		n = n->parent;
    581      1.1.1.13  joerg 		assert(MAN_BLOCK == n->type);
    582      1.1.1.13  joerg 		assert(MAN_SCOPED & man_macros[n->tok].flags);
    583      1.1.1.13  joerg 
    584  1.1.1.13.6.1    tls 		mandoc_vmsg(MANDOCERR_LINESCOPE, man->parse, n->line,
    585      1.1.1.13  joerg 		    n->pos, "%s breaks %s", man_macronames[tok],
    586      1.1.1.13  joerg 		    man_macronames[n->tok]);
    587      1.1.1.13  joerg 
    588  1.1.1.13.6.1    tls 		man_node_delete(man, n);
    589  1.1.1.13.6.1    tls 		man->flags &= ~MAN_BLINE;
    590      1.1.1.13  joerg 	}
    591      1.1.1.13  joerg 
    592      1.1.1.13  joerg 	/*
    593       1.1.1.5  joerg 	 * Save the fact that we're in the next-line for a block.  In
    594       1.1.1.5  joerg 	 * this way, embedded roff instructions can "remember" state
    595       1.1.1.5  joerg 	 * when they exit.
    596       1.1.1.5  joerg 	 */
    597           1.1  joerg 
    598  1.1.1.13.6.1    tls 	if (MAN_BLINE & man->flags)
    599  1.1.1.13.6.1    tls 		man->flags |= MAN_BPLINE;
    600           1.1  joerg 
    601       1.1.1.5  joerg 	/* Call to handler... */
    602       1.1.1.5  joerg 
    603       1.1.1.5  joerg 	assert(man_macros[tok].fp);
    604  1.1.1.13.6.1    tls 	if ( ! (*man_macros[tok].fp)(man, tok, ln, ppos, &offs, buf))
    605           1.1  joerg 		goto err;
    606           1.1  joerg 
    607       1.1.1.5  joerg 	/*
    608       1.1.1.5  joerg 	 * We weren't in a block-line scope when entering the
    609       1.1.1.5  joerg 	 * above-parsed macro, so return.
    610       1.1.1.5  joerg 	 */
    611       1.1.1.5  joerg 
    612  1.1.1.13.6.1    tls 	if ( ! (MAN_BPLINE & man->flags)) {
    613  1.1.1.13.6.1    tls 		man->flags &= ~MAN_ILINE;
    614           1.1  joerg 		return(1);
    615       1.1.1.5  joerg 	}
    616  1.1.1.13.6.1    tls 	man->flags &= ~MAN_BPLINE;
    617       1.1.1.5  joerg 
    618       1.1.1.5  joerg 	/*
    619       1.1.1.5  joerg 	 * If we're in a block scope, then allow this macro to slip by
    620       1.1.1.5  joerg 	 * without closing scope around it.
    621       1.1.1.5  joerg 	 */
    622       1.1.1.5  joerg 
    623  1.1.1.13.6.1    tls 	if (MAN_ILINE & man->flags) {
    624  1.1.1.13.6.1    tls 		man->flags &= ~MAN_ILINE;
    625       1.1.1.5  joerg 		return(1);
    626       1.1.1.5  joerg 	}
    627           1.1  joerg 
    628           1.1  joerg 	/*
    629           1.1  joerg 	 * If we've opened a new next-line element scope, then return
    630           1.1  joerg 	 * now, as the next line will close out the block scope.
    631           1.1  joerg 	 */
    632           1.1  joerg 
    633  1.1.1.13.6.1    tls 	if (MAN_ELINE & man->flags)
    634           1.1  joerg 		return(1);
    635           1.1  joerg 
    636           1.1  joerg 	/* Close out the block scope opened in the prior line.  */
    637           1.1  joerg 
    638  1.1.1.13.6.1    tls 	assert(MAN_BLINE & man->flags);
    639  1.1.1.13.6.1    tls 	man->flags &= ~MAN_BLINE;
    640           1.1  joerg 
    641  1.1.1.13.6.1    tls 	if ( ! man_unscope(man, man->last->parent, MANDOCERR_MAX))
    642           1.1  joerg 		return(0);
    643  1.1.1.13.6.1    tls 	return(man_body_alloc(man, ln, ppos, man->last->tok));
    644           1.1  joerg 
    645           1.1  joerg err:	/* Error out. */
    646           1.1  joerg 
    647  1.1.1.13.6.1    tls 	man->flags |= MAN_HALT;
    648           1.1  joerg 	return(0);
    649           1.1  joerg }
    650           1.1  joerg 
    651       1.1.1.5  joerg /*
    652  1.1.1.13.6.1    tls  * Unlink a node from its context.  If "man" is provided, the last parse
    653       1.1.1.5  joerg  * point will also be adjusted accordingly.
    654       1.1.1.5  joerg  */
    655       1.1.1.5  joerg static void
    656  1.1.1.13.6.1    tls man_node_unlink(struct man *man, struct man_node *n)
    657       1.1.1.5  joerg {
    658       1.1.1.5  joerg 
    659       1.1.1.5  joerg 	/* Adjust siblings. */
    660       1.1.1.5  joerg 
    661       1.1.1.5  joerg 	if (n->prev)
    662       1.1.1.5  joerg 		n->prev->next = n->next;
    663       1.1.1.5  joerg 	if (n->next)
    664       1.1.1.5  joerg 		n->next->prev = n->prev;
    665       1.1.1.5  joerg 
    666       1.1.1.5  joerg 	/* Adjust parent. */
    667       1.1.1.5  joerg 
    668       1.1.1.5  joerg 	if (n->parent) {
    669       1.1.1.5  joerg 		n->parent->nchild--;
    670       1.1.1.5  joerg 		if (n->parent->child == n)
    671       1.1.1.5  joerg 			n->parent->child = n->prev ? n->prev : n->next;
    672       1.1.1.5  joerg 	}
    673       1.1.1.5  joerg 
    674       1.1.1.5  joerg 	/* Adjust parse point, if applicable. */
    675       1.1.1.5  joerg 
    676  1.1.1.13.6.1    tls 	if (man && man->last == n) {
    677       1.1.1.5  joerg 		/*XXX: this can occur when bailing from validation. */
    678       1.1.1.5  joerg 		/*assert(NULL == n->next);*/
    679       1.1.1.5  joerg 		if (n->prev) {
    680  1.1.1.13.6.1    tls 			man->last = n->prev;
    681  1.1.1.13.6.1    tls 			man->next = MAN_NEXT_SIBLING;
    682       1.1.1.5  joerg 		} else {
    683  1.1.1.13.6.1    tls 			man->last = n->parent;
    684  1.1.1.13.6.1    tls 			man->next = MAN_NEXT_CHILD;
    685       1.1.1.5  joerg 		}
    686       1.1.1.5  joerg 	}
    687       1.1.1.5  joerg 
    688  1.1.1.13.6.1    tls 	if (man && man->first == n)
    689  1.1.1.13.6.1    tls 		man->first = NULL;
    690       1.1.1.5  joerg }
    691      1.1.1.12  joerg 
    692      1.1.1.12  joerg const struct mparse *
    693  1.1.1.13.6.1    tls man_mparse(const struct man *man)
    694      1.1.1.12  joerg {
    695      1.1.1.12  joerg 
    696  1.1.1.13.6.1    tls 	assert(man && man->parse);
    697  1.1.1.13.6.1    tls 	return(man->parse);
    698      1.1.1.12  joerg }
    699