xref: /titanic_51/usr/src/cmd/mandoc/tree.c (revision 260e9a87725c090ba5835b1f9f0b62fa2f96036f)
1*260e9a87SYuri Pankov /*	$Id: tree.c,v 1.62 2015/02/05 00:14:13 schwarze Exp $ */
295c635efSGarrett D'Amore /*
3*260e9a87SYuri Pankov  * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4*260e9a87SYuri Pankov  * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
595c635efSGarrett D'Amore  *
695c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
795c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
895c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
995c635efSGarrett D'Amore  *
1095c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1195c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1295c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1395c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1495c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1595c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1695c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1795c635efSGarrett D'Amore  */
1895c635efSGarrett D'Amore #include "config.h"
19*260e9a87SYuri Pankov 
20*260e9a87SYuri Pankov #include <sys/types.h>
2195c635efSGarrett D'Amore 
2295c635efSGarrett D'Amore #include <assert.h>
2395c635efSGarrett D'Amore #include <limits.h>
2495c635efSGarrett D'Amore #include <stdio.h>
2595c635efSGarrett D'Amore #include <stdlib.h>
2695c635efSGarrett D'Amore #include <time.h>
2795c635efSGarrett D'Amore 
2895c635efSGarrett D'Amore #include "mandoc.h"
2995c635efSGarrett D'Amore #include "mdoc.h"
3095c635efSGarrett D'Amore #include "man.h"
3195c635efSGarrett D'Amore #include "main.h"
3295c635efSGarrett D'Amore 
3395c635efSGarrett D'Amore static	void	print_box(const struct eqn_box *, int);
3495c635efSGarrett D'Amore static	void	print_man(const struct man_node *, int);
3595c635efSGarrett D'Amore static	void	print_mdoc(const struct mdoc_node *, int);
3695c635efSGarrett D'Amore static	void	print_span(const struct tbl_span *, int);
3795c635efSGarrett D'Amore 
3895c635efSGarrett D'Amore 
3995c635efSGarrett D'Amore void
4095c635efSGarrett D'Amore tree_mdoc(void *arg, const struct mdoc *mdoc)
4195c635efSGarrett D'Amore {
4295c635efSGarrett D'Amore 
43*260e9a87SYuri Pankov 	print_mdoc(mdoc_node(mdoc)->child, 0);
4495c635efSGarrett D'Amore }
4595c635efSGarrett D'Amore 
4695c635efSGarrett D'Amore void
4795c635efSGarrett D'Amore tree_man(void *arg, const struct man *man)
4895c635efSGarrett D'Amore {
4995c635efSGarrett D'Amore 
50*260e9a87SYuri Pankov 	print_man(man_node(man)->child, 0);
5195c635efSGarrett D'Amore }
5295c635efSGarrett D'Amore 
5395c635efSGarrett D'Amore static void
5495c635efSGarrett D'Amore print_mdoc(const struct mdoc_node *n, int indent)
5595c635efSGarrett D'Amore {
5695c635efSGarrett D'Amore 	const char	 *p, *t;
5795c635efSGarrett D'Amore 	int		  i, j;
58698f87a4SGarrett D'Amore 	size_t		  argc;
5995c635efSGarrett D'Amore 	struct mdoc_argv *argv;
6095c635efSGarrett D'Amore 
61*260e9a87SYuri Pankov 	if (n == NULL)
62*260e9a87SYuri Pankov 		return;
63*260e9a87SYuri Pankov 
6495c635efSGarrett D'Amore 	argv = NULL;
65698f87a4SGarrett D'Amore 	argc = 0;
6695c635efSGarrett D'Amore 	t = p = NULL;
6795c635efSGarrett D'Amore 
6895c635efSGarrett D'Amore 	switch (n->type) {
69*260e9a87SYuri Pankov 	case MDOC_ROOT:
7095c635efSGarrett D'Amore 		t = "root";
7195c635efSGarrett D'Amore 		break;
72*260e9a87SYuri Pankov 	case MDOC_BLOCK:
7395c635efSGarrett D'Amore 		t = "block";
7495c635efSGarrett D'Amore 		break;
75*260e9a87SYuri Pankov 	case MDOC_HEAD:
7695c635efSGarrett D'Amore 		t = "block-head";
7795c635efSGarrett D'Amore 		break;
78*260e9a87SYuri Pankov 	case MDOC_BODY:
7995c635efSGarrett D'Amore 		if (n->end)
8095c635efSGarrett D'Amore 			t = "body-end";
8195c635efSGarrett D'Amore 		else
8295c635efSGarrett D'Amore 			t = "block-body";
8395c635efSGarrett D'Amore 		break;
84*260e9a87SYuri Pankov 	case MDOC_TAIL:
8595c635efSGarrett D'Amore 		t = "block-tail";
8695c635efSGarrett D'Amore 		break;
87*260e9a87SYuri Pankov 	case MDOC_ELEM:
8895c635efSGarrett D'Amore 		t = "elem";
8995c635efSGarrett D'Amore 		break;
90*260e9a87SYuri Pankov 	case MDOC_TEXT:
9195c635efSGarrett D'Amore 		t = "text";
9295c635efSGarrett D'Amore 		break;
93*260e9a87SYuri Pankov 	case MDOC_TBL:
94*260e9a87SYuri Pankov 		break;
95*260e9a87SYuri Pankov 	case MDOC_EQN:
96*260e9a87SYuri Pankov 		t = "eqn";
9795c635efSGarrett D'Amore 		break;
9895c635efSGarrett D'Amore 	default:
9995c635efSGarrett D'Amore 		abort();
10095c635efSGarrett D'Amore 		/* NOTREACHED */
10195c635efSGarrett D'Amore 	}
10295c635efSGarrett D'Amore 
10395c635efSGarrett D'Amore 	switch (n->type) {
104*260e9a87SYuri Pankov 	case MDOC_TEXT:
10595c635efSGarrett D'Amore 		p = n->string;
10695c635efSGarrett D'Amore 		break;
107*260e9a87SYuri Pankov 	case MDOC_BODY:
10895c635efSGarrett D'Amore 		p = mdoc_macronames[n->tok];
10995c635efSGarrett D'Amore 		break;
110*260e9a87SYuri Pankov 	case MDOC_HEAD:
11195c635efSGarrett D'Amore 		p = mdoc_macronames[n->tok];
11295c635efSGarrett D'Amore 		break;
113*260e9a87SYuri Pankov 	case MDOC_TAIL:
11495c635efSGarrett D'Amore 		p = mdoc_macronames[n->tok];
11595c635efSGarrett D'Amore 		break;
116*260e9a87SYuri Pankov 	case MDOC_ELEM:
11795c635efSGarrett D'Amore 		p = mdoc_macronames[n->tok];
11895c635efSGarrett D'Amore 		if (n->args) {
11995c635efSGarrett D'Amore 			argv = n->args->argv;
12095c635efSGarrett D'Amore 			argc = n->args->argc;
12195c635efSGarrett D'Amore 		}
12295c635efSGarrett D'Amore 		break;
123*260e9a87SYuri Pankov 	case MDOC_BLOCK:
12495c635efSGarrett D'Amore 		p = mdoc_macronames[n->tok];
12595c635efSGarrett D'Amore 		if (n->args) {
12695c635efSGarrett D'Amore 			argv = n->args->argv;
12795c635efSGarrett D'Amore 			argc = n->args->argc;
12895c635efSGarrett D'Amore 		}
12995c635efSGarrett D'Amore 		break;
130*260e9a87SYuri Pankov 	case MDOC_TBL:
13195c635efSGarrett D'Amore 		break;
132*260e9a87SYuri Pankov 	case MDOC_EQN:
133*260e9a87SYuri Pankov 		p = "EQ";
134*260e9a87SYuri Pankov 		break;
135*260e9a87SYuri Pankov 	case MDOC_ROOT:
13695c635efSGarrett D'Amore 		p = "root";
13795c635efSGarrett D'Amore 		break;
13895c635efSGarrett D'Amore 	default:
13995c635efSGarrett D'Amore 		abort();
14095c635efSGarrett D'Amore 		/* NOTREACHED */
14195c635efSGarrett D'Amore 	}
14295c635efSGarrett D'Amore 
14395c635efSGarrett D'Amore 	if (n->span) {
14495c635efSGarrett D'Amore 		assert(NULL == p && NULL == t);
14595c635efSGarrett D'Amore 		print_span(n->span, indent);
14695c635efSGarrett D'Amore 	} else {
14795c635efSGarrett D'Amore 		for (i = 0; i < indent; i++)
148*260e9a87SYuri Pankov 			putchar(' ');
14995c635efSGarrett D'Amore 
15095c635efSGarrett D'Amore 		printf("%s (%s)", p, t);
15195c635efSGarrett D'Amore 
15295c635efSGarrett D'Amore 		for (i = 0; i < (int)argc; i++) {
15395c635efSGarrett D'Amore 			printf(" -%s", mdoc_argnames[argv[i].arg]);
15495c635efSGarrett D'Amore 			if (argv[i].sz > 0)
15595c635efSGarrett D'Amore 				printf(" [");
15695c635efSGarrett D'Amore 			for (j = 0; j < (int)argv[i].sz; j++)
15795c635efSGarrett D'Amore 				printf(" [%s]", argv[i].value[j]);
15895c635efSGarrett D'Amore 			if (argv[i].sz > 0)
15995c635efSGarrett D'Amore 				printf(" ]");
16095c635efSGarrett D'Amore 		}
16195c635efSGarrett D'Amore 
162698f87a4SGarrett D'Amore 		putchar(' ');
163698f87a4SGarrett D'Amore 		if (MDOC_LINE & n->flags)
164698f87a4SGarrett D'Amore 			putchar('*');
165*260e9a87SYuri Pankov 		printf("%d:%d\n", n->line, n->pos + 1);
16695c635efSGarrett D'Amore 	}
16795c635efSGarrett D'Amore 
168*260e9a87SYuri Pankov 	if (n->eqn)
169*260e9a87SYuri Pankov 		print_box(n->eqn->root->first, indent + 4);
17095c635efSGarrett D'Amore 	if (n->child)
171*260e9a87SYuri Pankov 		print_mdoc(n->child, indent +
172*260e9a87SYuri Pankov 		    (n->type == MDOC_BLOCK ? 2 : 4));
17395c635efSGarrett D'Amore 	if (n->next)
17495c635efSGarrett D'Amore 		print_mdoc(n->next, indent);
17595c635efSGarrett D'Amore }
17695c635efSGarrett D'Amore 
17795c635efSGarrett D'Amore static void
17895c635efSGarrett D'Amore print_man(const struct man_node *n, int indent)
17995c635efSGarrett D'Amore {
18095c635efSGarrett D'Amore 	const char	 *p, *t;
18195c635efSGarrett D'Amore 	int		  i;
18295c635efSGarrett D'Amore 
183*260e9a87SYuri Pankov 	if (n == NULL)
184*260e9a87SYuri Pankov 		return;
185*260e9a87SYuri Pankov 
18695c635efSGarrett D'Amore 	t = p = NULL;
18795c635efSGarrett D'Amore 
18895c635efSGarrett D'Amore 	switch (n->type) {
189*260e9a87SYuri Pankov 	case MAN_ROOT:
19095c635efSGarrett D'Amore 		t = "root";
19195c635efSGarrett D'Amore 		break;
192*260e9a87SYuri Pankov 	case MAN_ELEM:
19395c635efSGarrett D'Amore 		t = "elem";
19495c635efSGarrett D'Amore 		break;
195*260e9a87SYuri Pankov 	case MAN_TEXT:
19695c635efSGarrett D'Amore 		t = "text";
19795c635efSGarrett D'Amore 		break;
198*260e9a87SYuri Pankov 	case MAN_BLOCK:
19995c635efSGarrett D'Amore 		t = "block";
20095c635efSGarrett D'Amore 		break;
201*260e9a87SYuri Pankov 	case MAN_HEAD:
20295c635efSGarrett D'Amore 		t = "block-head";
20395c635efSGarrett D'Amore 		break;
204*260e9a87SYuri Pankov 	case MAN_BODY:
20595c635efSGarrett D'Amore 		t = "block-body";
20695c635efSGarrett D'Amore 		break;
207*260e9a87SYuri Pankov 	case MAN_TBL:
20895c635efSGarrett D'Amore 		break;
209*260e9a87SYuri Pankov 	case MAN_EQN:
210*260e9a87SYuri Pankov 		t = "eqn";
21195c635efSGarrett D'Amore 		break;
21295c635efSGarrett D'Amore 	default:
21395c635efSGarrett D'Amore 		abort();
21495c635efSGarrett D'Amore 		/* NOTREACHED */
21595c635efSGarrett D'Amore 	}
21695c635efSGarrett D'Amore 
21795c635efSGarrett D'Amore 	switch (n->type) {
218*260e9a87SYuri Pankov 	case MAN_TEXT:
21995c635efSGarrett D'Amore 		p = n->string;
22095c635efSGarrett D'Amore 		break;
221*260e9a87SYuri Pankov 	case MAN_ELEM:
22295c635efSGarrett D'Amore 		/* FALLTHROUGH */
223*260e9a87SYuri Pankov 	case MAN_BLOCK:
22495c635efSGarrett D'Amore 		/* FALLTHROUGH */
225*260e9a87SYuri Pankov 	case MAN_HEAD:
22695c635efSGarrett D'Amore 		/* FALLTHROUGH */
227*260e9a87SYuri Pankov 	case MAN_BODY:
22895c635efSGarrett D'Amore 		p = man_macronames[n->tok];
22995c635efSGarrett D'Amore 		break;
230*260e9a87SYuri Pankov 	case MAN_ROOT:
23195c635efSGarrett D'Amore 		p = "root";
23295c635efSGarrett D'Amore 		break;
233*260e9a87SYuri Pankov 	case MAN_TBL:
234*260e9a87SYuri Pankov 		break;
235*260e9a87SYuri Pankov 	case MAN_EQN:
236*260e9a87SYuri Pankov 		p = "EQ";
23795c635efSGarrett D'Amore 		break;
23895c635efSGarrett D'Amore 	default:
23995c635efSGarrett D'Amore 		abort();
24095c635efSGarrett D'Amore 		/* NOTREACHED */
24195c635efSGarrett D'Amore 	}
24295c635efSGarrett D'Amore 
24395c635efSGarrett D'Amore 	if (n->span) {
24495c635efSGarrett D'Amore 		assert(NULL == p && NULL == t);
24595c635efSGarrett D'Amore 		print_span(n->span, indent);
24695c635efSGarrett D'Amore 	} else {
24795c635efSGarrett D'Amore 		for (i = 0; i < indent; i++)
248*260e9a87SYuri Pankov 			putchar(' ');
249*260e9a87SYuri Pankov 		printf("%s (%s) ", p, t);
250*260e9a87SYuri Pankov 		if (MAN_LINE & n->flags)
251*260e9a87SYuri Pankov 			putchar('*');
252*260e9a87SYuri Pankov 		printf("%d:%d\n", n->line, n->pos + 1);
25395c635efSGarrett D'Amore 	}
25495c635efSGarrett D'Amore 
255*260e9a87SYuri Pankov 	if (n->eqn)
256*260e9a87SYuri Pankov 		print_box(n->eqn->root->first, indent + 4);
25795c635efSGarrett D'Amore 	if (n->child)
258*260e9a87SYuri Pankov 		print_man(n->child, indent +
259*260e9a87SYuri Pankov 		    (n->type == MAN_BLOCK ? 2 : 4));
26095c635efSGarrett D'Amore 	if (n->next)
26195c635efSGarrett D'Amore 		print_man(n->next, indent);
26295c635efSGarrett D'Amore }
26395c635efSGarrett D'Amore 
26495c635efSGarrett D'Amore static void
26595c635efSGarrett D'Amore print_box(const struct eqn_box *ep, int indent)
26695c635efSGarrett D'Amore {
26795c635efSGarrett D'Amore 	int		 i;
26895c635efSGarrett D'Amore 	const char	*t;
26995c635efSGarrett D'Amore 
270*260e9a87SYuri Pankov 	static const char *posnames[] = {
271*260e9a87SYuri Pankov 	    NULL, "sup", "subsup", "sub",
272*260e9a87SYuri Pankov 	    "to", "from", "fromto",
273*260e9a87SYuri Pankov 	    "over", "sqrt", NULL };
274*260e9a87SYuri Pankov 
27595c635efSGarrett D'Amore 	if (NULL == ep)
27695c635efSGarrett D'Amore 		return;
27795c635efSGarrett D'Amore 	for (i = 0; i < indent; i++)
278*260e9a87SYuri Pankov 		putchar(' ');
27995c635efSGarrett D'Amore 
28095c635efSGarrett D'Amore 	t = NULL;
28195c635efSGarrett D'Amore 	switch (ep->type) {
282*260e9a87SYuri Pankov 	case EQN_ROOT:
28395c635efSGarrett D'Amore 		t = "eqn-root";
28495c635efSGarrett D'Amore 		break;
285*260e9a87SYuri Pankov 	case EQN_LISTONE:
286*260e9a87SYuri Pankov 	case EQN_LIST:
28795c635efSGarrett D'Amore 		t = "eqn-list";
28895c635efSGarrett D'Amore 		break;
289*260e9a87SYuri Pankov 	case EQN_SUBEXPR:
29095c635efSGarrett D'Amore 		t = "eqn-expr";
29195c635efSGarrett D'Amore 		break;
292*260e9a87SYuri Pankov 	case EQN_TEXT:
29395c635efSGarrett D'Amore 		t = "eqn-text";
29495c635efSGarrett D'Amore 		break;
295*260e9a87SYuri Pankov 	case EQN_PILE:
296*260e9a87SYuri Pankov 		t = "eqn-pile";
297*260e9a87SYuri Pankov 		break;
298*260e9a87SYuri Pankov 	case EQN_MATRIX:
29995c635efSGarrett D'Amore 		t = "eqn-matrix";
30095c635efSGarrett D'Amore 		break;
30195c635efSGarrett D'Amore 	}
30295c635efSGarrett D'Amore 
303*260e9a87SYuri Pankov 	fputs(t, stdout);
304*260e9a87SYuri Pankov 	if (ep->pos)
305*260e9a87SYuri Pankov 		printf(" pos=%s", posnames[ep->pos]);
306*260e9a87SYuri Pankov 	if (ep->left)
307*260e9a87SYuri Pankov 		printf(" left=\"%s\"", ep->left);
308*260e9a87SYuri Pankov 	if (ep->right)
309*260e9a87SYuri Pankov 		printf(" right=\"%s\"", ep->right);
310*260e9a87SYuri Pankov 	if (ep->top)
311*260e9a87SYuri Pankov 		printf(" top=\"%s\"", ep->top);
312*260e9a87SYuri Pankov 	if (ep->bottom)
313*260e9a87SYuri Pankov 		printf(" bottom=\"%s\"", ep->bottom);
314*260e9a87SYuri Pankov 	if (ep->text)
315*260e9a87SYuri Pankov 		printf(" text=\"%s\"", ep->text);
316*260e9a87SYuri Pankov 	if (ep->font)
317*260e9a87SYuri Pankov 		printf(" font=%d", ep->font);
318*260e9a87SYuri Pankov 	if (ep->size != EQN_DEFSIZE)
319*260e9a87SYuri Pankov 		printf(" size=%d", ep->size);
320*260e9a87SYuri Pankov 	if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
321*260e9a87SYuri Pankov 		printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
322*260e9a87SYuri Pankov 	else if (ep->args)
323*260e9a87SYuri Pankov 		printf(" args=%zu", ep->args);
324*260e9a87SYuri Pankov 	putchar('\n');
32595c635efSGarrett D'Amore 
326*260e9a87SYuri Pankov 	print_box(ep->first, indent + 4);
32795c635efSGarrett D'Amore 	print_box(ep->next, indent);
32895c635efSGarrett D'Amore }
32995c635efSGarrett D'Amore 
33095c635efSGarrett D'Amore static void
33195c635efSGarrett D'Amore print_span(const struct tbl_span *sp, int indent)
33295c635efSGarrett D'Amore {
33395c635efSGarrett D'Amore 	const struct tbl_dat *dp;
33495c635efSGarrett D'Amore 	int		 i;
33595c635efSGarrett D'Amore 
33695c635efSGarrett D'Amore 	for (i = 0; i < indent; i++)
337*260e9a87SYuri Pankov 		putchar(' ');
33895c635efSGarrett D'Amore 
33995c635efSGarrett D'Amore 	switch (sp->pos) {
340*260e9a87SYuri Pankov 	case TBL_SPAN_HORIZ:
34195c635efSGarrett D'Amore 		putchar('-');
34295c635efSGarrett D'Amore 		return;
343*260e9a87SYuri Pankov 	case TBL_SPAN_DHORIZ:
34495c635efSGarrett D'Amore 		putchar('=');
34595c635efSGarrett D'Amore 		return;
34695c635efSGarrett D'Amore 	default:
34795c635efSGarrett D'Amore 		break;
34895c635efSGarrett D'Amore 	}
34995c635efSGarrett D'Amore 
35095c635efSGarrett D'Amore 	for (dp = sp->first; dp; dp = dp->next) {
35195c635efSGarrett D'Amore 		switch (dp->pos) {
352*260e9a87SYuri Pankov 		case TBL_DATA_HORIZ:
35395c635efSGarrett D'Amore 			/* FALLTHROUGH */
354*260e9a87SYuri Pankov 		case TBL_DATA_NHORIZ:
35595c635efSGarrett D'Amore 			putchar('-');
35695c635efSGarrett D'Amore 			continue;
357*260e9a87SYuri Pankov 		case TBL_DATA_DHORIZ:
35895c635efSGarrett D'Amore 			/* FALLTHROUGH */
359*260e9a87SYuri Pankov 		case TBL_DATA_NDHORIZ:
36095c635efSGarrett D'Amore 			putchar('=');
36195c635efSGarrett D'Amore 			continue;
36295c635efSGarrett D'Amore 		default:
36395c635efSGarrett D'Amore 			break;
36495c635efSGarrett D'Amore 		}
36595c635efSGarrett D'Amore 		printf("[\"%s\"", dp->string ? dp->string : "");
36695c635efSGarrett D'Amore 		if (dp->spans)
36795c635efSGarrett D'Amore 			printf("(%d)", dp->spans);
36895c635efSGarrett D'Amore 		if (NULL == dp->layout)
36995c635efSGarrett D'Amore 			putchar('*');
37095c635efSGarrett D'Amore 		putchar(']');
37195c635efSGarrett D'Amore 		putchar(' ');
37295c635efSGarrett D'Amore 	}
37395c635efSGarrett D'Amore 
37495c635efSGarrett D'Amore 	printf("(tbl) %d:1\n", sp->line);
37595c635efSGarrett D'Amore }
376