xref: /openbsd-src/usr.bin/mandoc/tree.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*	$Id: tree.c,v 1.4 2009/09/21 20:57:57 schwarze Exp $ */
2 /*
3  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <assert.h>
18 #include <err.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include "mdoc.h"
23 #include "man.h"
24 
25 static	void	print_mdoc(const struct mdoc_node *, int);
26 static	void	print_man(const struct man_node *, int);
27 
28 
29 /* ARGSUSED */
30 void
31 tree_mdoc(void *arg, const struct mdoc *mdoc)
32 {
33 
34 	print_mdoc(mdoc_node(mdoc), 0);
35 }
36 
37 
38 /* ARGSUSED */
39 void
40 tree_man(void *arg, const struct man *man)
41 {
42 
43 	print_man(man_node(man), 0);
44 }
45 
46 
47 static void
48 print_mdoc(const struct mdoc_node *n, int indent)
49 {
50 	const char	 *p, *t;
51 	int		  i, j;
52 	size_t		  argc, sz;
53 	char		**params;
54 	struct mdoc_argv *argv;
55 
56 	argv = NULL;
57 	argc = sz = 0;
58 	params = NULL;
59 
60 	switch (n->type) {
61 	case (MDOC_ROOT):
62 		t = "root";
63 		break;
64 	case (MDOC_BLOCK):
65 		t = "block";
66 		break;
67 	case (MDOC_HEAD):
68 		t = "block-head";
69 		break;
70 	case (MDOC_BODY):
71 		t = "block-body";
72 		break;
73 	case (MDOC_TAIL):
74 		t = "block-tail";
75 		break;
76 	case (MDOC_ELEM):
77 		t = "elem";
78 		break;
79 	case (MDOC_TEXT):
80 		t = "text";
81 		break;
82 	default:
83 		abort();
84 		/* NOTREACHED */
85 	}
86 
87 	switch (n->type) {
88 	case (MDOC_TEXT):
89 		p = n->string;
90 		break;
91 	case (MDOC_BODY):
92 		p = mdoc_macronames[n->tok];
93 		break;
94 	case (MDOC_HEAD):
95 		p = mdoc_macronames[n->tok];
96 		break;
97 	case (MDOC_TAIL):
98 		p = mdoc_macronames[n->tok];
99 		break;
100 	case (MDOC_ELEM):
101 		p = mdoc_macronames[n->tok];
102 		if (n->args) {
103 			argv = n->args->argv;
104 			argc = n->args->argc;
105 		}
106 		break;
107 	case (MDOC_BLOCK):
108 		p = mdoc_macronames[n->tok];
109 		if (n->args) {
110 			argv = n->args->argv;
111 			argc = n->args->argc;
112 		}
113 		break;
114 	case (MDOC_ROOT):
115 		p = "root";
116 		break;
117 	default:
118 		abort();
119 		/* NOTREACHED */
120 	}
121 
122 	for (i = 0; i < indent; i++)
123 		(void)printf("    ");
124 	(void)printf("%s (%s)", p, t);
125 
126 	for (i = 0; i < (int)argc; i++) {
127 		(void)printf(" -%s", mdoc_argnames[argv[i].arg]);
128 		if (argv[i].sz > 0)
129 			(void)printf(" [");
130 		for (j = 0; j < (int)argv[i].sz; j++)
131 			(void)printf(" [%s]", argv[i].value[j]);
132 		if (argv[i].sz > 0)
133 			(void)printf(" ]");
134 	}
135 
136 	for (i = 0; i < (int)sz; i++)
137 		(void)printf(" [%s]", params[i]);
138 
139 	(void)printf(" %d:%d\n", n->line, n->pos);
140 
141 	if (n->child)
142 		print_mdoc(n->child, indent + 1);
143 	if (n->next)
144 		print_mdoc(n->next, indent);
145 }
146 
147 
148 static void
149 print_man(const struct man_node *n, int indent)
150 {
151 	const char	 *p, *t;
152 	int		  i;
153 
154 	switch (n->type) {
155 	case (MAN_ROOT):
156 		t = "root";
157 		break;
158 	case (MAN_ELEM):
159 		t = "elem";
160 		break;
161 	case (MAN_TEXT):
162 		t = "text";
163 		break;
164 	case (MAN_BLOCK):
165 		t = "block";
166 		break;
167 	case (MAN_HEAD):
168 		t = "block-head";
169 		break;
170 	case (MAN_BODY):
171 		t = "block-body";
172 		break;
173 	default:
174 		abort();
175 		/* NOTREACHED */
176 	}
177 
178 	switch (n->type) {
179 	case (MAN_TEXT):
180 		p = n->string;
181 		break;
182 	case (MAN_ELEM):
183 		/* FALLTHROUGH */
184 	case (MAN_BLOCK):
185 		/* FALLTHROUGH */
186 	case (MAN_HEAD):
187 		/* FALLTHROUGH */
188 	case (MAN_BODY):
189 		p = man_macronames[n->tok];
190 		break;
191 	case (MAN_ROOT):
192 		p = "root";
193 		break;
194 	default:
195 		abort();
196 		/* NOTREACHED */
197 	}
198 
199 	for (i = 0; i < indent; i++)
200 		(void)printf("    ");
201 	(void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
202 
203 	if (n->child)
204 		print_man(n->child, indent + 1);
205 	if (n->next)
206 		print_man(n->next, indent);
207 }
208