xref: /dragonfly/contrib/mdocml/tree.c (revision 783d47c4)
1 /*	$Id: tree.c,v 1.37 2011/03/23 12:33:01 kristaps Exp $ */
2 /*
3  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
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 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <time.h>
25 
26 #include "mandoc.h"
27 #include "mdoc.h"
28 #include "man.h"
29 #include "main.h"
30 
31 static	void	print_mdoc(const struct mdoc_node *, int);
32 static	void	print_man(const struct man_node *, int);
33 static	void	print_span(const struct tbl_span *, int);
34 
35 
36 /* ARGSUSED */
37 void
38 tree_mdoc(void *arg, const struct mdoc *mdoc)
39 {
40 
41 	print_mdoc(mdoc_node(mdoc), 0);
42 }
43 
44 
45 /* ARGSUSED */
46 void
47 tree_man(void *arg, const struct man *man)
48 {
49 
50 	print_man(man_node(man), 0);
51 }
52 
53 
54 static void
55 print_mdoc(const struct mdoc_node *n, int indent)
56 {
57 	const char	 *p, *t;
58 	int		  i, j;
59 	size_t		  argc, sz;
60 	char		**params;
61 	struct mdoc_argv *argv;
62 
63 	argv = NULL;
64 	argc = sz = 0;
65 	params = NULL;
66 
67 	switch (n->type) {
68 	case (MDOC_ROOT):
69 		t = "root";
70 		break;
71 	case (MDOC_BLOCK):
72 		t = "block";
73 		break;
74 	case (MDOC_HEAD):
75 		t = "block-head";
76 		break;
77 	case (MDOC_BODY):
78 		if (n->end)
79 			t = "body-end";
80 		else
81 			t = "block-body";
82 		break;
83 	case (MDOC_TAIL):
84 		t = "block-tail";
85 		break;
86 	case (MDOC_ELEM):
87 		t = "elem";
88 		break;
89 	case (MDOC_TEXT):
90 		t = "text";
91 		break;
92 	case (MDOC_TBL):
93 		t = "tbl";
94 		break;
95 	case (MDOC_EQN):
96 		t = "eqn";
97 		break;
98 	default:
99 		abort();
100 		/* NOTREACHED */
101 	}
102 
103 	p = NULL;
104 
105 	switch (n->type) {
106 	case (MDOC_TEXT):
107 		p = n->string;
108 		break;
109 	case (MDOC_BODY):
110 		p = mdoc_macronames[n->tok];
111 		break;
112 	case (MDOC_HEAD):
113 		p = mdoc_macronames[n->tok];
114 		break;
115 	case (MDOC_TAIL):
116 		p = mdoc_macronames[n->tok];
117 		break;
118 	case (MDOC_ELEM):
119 		p = mdoc_macronames[n->tok];
120 		if (n->args) {
121 			argv = n->args->argv;
122 			argc = n->args->argc;
123 		}
124 		break;
125 	case (MDOC_BLOCK):
126 		p = mdoc_macronames[n->tok];
127 		if (n->args) {
128 			argv = n->args->argv;
129 			argc = n->args->argc;
130 		}
131 		break;
132 	case (MDOC_TBL):
133 		break;
134 	case (MDOC_EQN):
135 		p = n->eqn->data;
136 		break;
137 	case (MDOC_ROOT):
138 		p = "root";
139 		break;
140 	default:
141 		abort();
142 		/* NOTREACHED */
143 	}
144 
145 	if (n->span) {
146 		assert(NULL == p);
147 		print_span(n->span, indent);
148 	} else {
149 		for (i = 0; i < indent; i++)
150 			putchar('\t');
151 
152 		printf("%s (%s)", p, t);
153 
154 		for (i = 0; i < (int)argc; i++) {
155 			printf(" -%s", mdoc_argnames[argv[i].arg]);
156 			if (argv[i].sz > 0)
157 				printf(" [");
158 			for (j = 0; j < (int)argv[i].sz; j++)
159 				printf(" [%s]", argv[i].value[j]);
160 			if (argv[i].sz > 0)
161 				printf(" ]");
162 		}
163 
164 		for (i = 0; i < (int)sz; i++)
165 			printf(" [%s]", params[i]);
166 
167 		printf(" %d:%d", n->line, n->pos);
168 	}
169 
170 	putchar('\n');
171 
172 	if (n->child)
173 		print_mdoc(n->child, indent + 1);
174 	if (n->next)
175 		print_mdoc(n->next, indent);
176 }
177 
178 
179 static void
180 print_man(const struct man_node *n, int indent)
181 {
182 	const char	 *p, *t;
183 	int		  i;
184 
185 	switch (n->type) {
186 	case (MAN_ROOT):
187 		t = "root";
188 		break;
189 	case (MAN_ELEM):
190 		t = "elem";
191 		break;
192 	case (MAN_TEXT):
193 		t = "text";
194 		break;
195 	case (MAN_BLOCK):
196 		t = "block";
197 		break;
198 	case (MAN_HEAD):
199 		t = "block-head";
200 		break;
201 	case (MAN_BODY):
202 		t = "block-body";
203 		break;
204 	case (MAN_TAIL):
205 		t = "block-tail";
206 		break;
207 	case (MAN_TBL):
208 		t = "tbl";
209 		break;
210 	case (MAN_EQN):
211 		t = "eqn";
212 		break;
213 	default:
214 		abort();
215 		/* NOTREACHED */
216 	}
217 
218 	p = NULL;
219 
220 	switch (n->type) {
221 	case (MAN_TEXT):
222 		p = n->string;
223 		break;
224 	case (MAN_ELEM):
225 		/* FALLTHROUGH */
226 	case (MAN_BLOCK):
227 		/* FALLTHROUGH */
228 	case (MAN_HEAD):
229 		/* FALLTHROUGH */
230 	case (MAN_TAIL):
231 		/* FALLTHROUGH */
232 	case (MAN_BODY):
233 		p = man_macronames[n->tok];
234 		break;
235 	case (MAN_ROOT):
236 		p = "root";
237 		break;
238 	case (MAN_TBL):
239 		break;
240 	case (MAN_EQN):
241 		p = n->eqn->data;
242 		break;
243 	default:
244 		abort();
245 		/* NOTREACHED */
246 	}
247 
248 	if (n->span) {
249 		assert(NULL == p);
250 		print_span(n->span, indent);
251 	} else {
252 		for (i = 0; i < indent; i++)
253 			putchar('\t');
254 		printf("%s (%s) %d:%d", p, t, n->line, n->pos);
255 	}
256 
257 	putchar('\n');
258 
259 	if (n->child)
260 		print_man(n->child, indent + 1);
261 	if (n->next)
262 		print_man(n->next, indent);
263 }
264 
265 static void
266 print_span(const struct tbl_span *sp, int indent)
267 {
268 	const struct tbl_dat *dp;
269 	int		 i;
270 
271 	for (i = 0; i < indent; i++)
272 		putchar('\t');
273 
274 	switch (sp->pos) {
275 	case (TBL_SPAN_HORIZ):
276 		putchar('-');
277 		return;
278 	case (TBL_SPAN_DHORIZ):
279 		putchar('=');
280 		return;
281 	default:
282 		break;
283 	}
284 
285 	for (dp = sp->first; dp; dp = dp->next) {
286 		switch (dp->pos) {
287 		case (TBL_DATA_HORIZ):
288 			/* FALLTHROUGH */
289 		case (TBL_DATA_NHORIZ):
290 			putchar('-');
291 			continue;
292 		case (TBL_DATA_DHORIZ):
293 			/* FALLTHROUGH */
294 		case (TBL_DATA_NDHORIZ):
295 			putchar('=');
296 			continue;
297 		default:
298 			break;
299 		}
300 		printf("[\"%s\"", dp->string ? dp->string : "");
301 		if (dp->spans)
302 			printf("(%d)", dp->spans);
303 		if (NULL == dp->layout)
304 			putchar('*');
305 		putchar(']');
306 		putchar(' ');
307 	}
308 
309 	printf("(tbl) %d:1", sp->line);
310 }
311