xref: /netbsd/external/bsd/mdocml/dist/tree.c (revision 6550d01e)
1 /*	$Vendor-Id: tree.c,v 1.31 2011/01/03 13:59:21 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 	default:
96 		abort();
97 		/* NOTREACHED */
98 	}
99 
100 	p = NULL;
101 
102 	switch (n->type) {
103 	case (MDOC_TEXT):
104 		p = n->string;
105 		break;
106 	case (MDOC_BODY):
107 		p = mdoc_macronames[n->tok];
108 		break;
109 	case (MDOC_HEAD):
110 		p = mdoc_macronames[n->tok];
111 		break;
112 	case (MDOC_TAIL):
113 		p = mdoc_macronames[n->tok];
114 		break;
115 	case (MDOC_ELEM):
116 		p = mdoc_macronames[n->tok];
117 		if (n->args) {
118 			argv = n->args->argv;
119 			argc = n->args->argc;
120 		}
121 		break;
122 	case (MDOC_BLOCK):
123 		p = mdoc_macronames[n->tok];
124 		if (n->args) {
125 			argv = n->args->argv;
126 			argc = n->args->argc;
127 		}
128 		break;
129 	case (MDOC_TBL):
130 		break;
131 	case (MDOC_ROOT):
132 		p = "root";
133 		break;
134 	default:
135 		abort();
136 		/* NOTREACHED */
137 	}
138 
139 	if (n->span) {
140 		assert(NULL == p);
141 		print_span(n->span, indent);
142 	} else {
143 		for (i = 0; i < indent; i++)
144 			putchar('\t');
145 
146 		printf("%s (%s)", p, t);
147 
148 		for (i = 0; i < (int)argc; i++) {
149 			printf(" -%s", mdoc_argnames[argv[i].arg]);
150 			if (argv[i].sz > 0)
151 				printf(" [");
152 			for (j = 0; j < (int)argv[i].sz; j++)
153 				printf(" [%s]", argv[i].value[j]);
154 			if (argv[i].sz > 0)
155 				printf(" ]");
156 		}
157 
158 		for (i = 0; i < (int)sz; i++)
159 			printf(" [%s]", params[i]);
160 
161 		printf(" %d:%d", n->line, n->pos);
162 	}
163 
164 	putchar('\n');
165 
166 	if (n->child)
167 		print_mdoc(n->child, indent + 1);
168 	if (n->next)
169 		print_mdoc(n->next, indent);
170 }
171 
172 
173 static void
174 print_man(const struct man_node *n, int indent)
175 {
176 	const char	 *p, *t;
177 	int		  i;
178 
179 	switch (n->type) {
180 	case (MAN_ROOT):
181 		t = "root";
182 		break;
183 	case (MAN_ELEM):
184 		t = "elem";
185 		break;
186 	case (MAN_TEXT):
187 		t = "text";
188 		break;
189 	case (MAN_BLOCK):
190 		t = "block";
191 		break;
192 	case (MAN_HEAD):
193 		t = "block-head";
194 		break;
195 	case (MAN_BODY):
196 		t = "block-body";
197 		break;
198 	case (MAN_TBL):
199 		t = "tbl";
200 		break;
201 	default:
202 		abort();
203 		/* NOTREACHED */
204 	}
205 
206 	p = NULL;
207 
208 	switch (n->type) {
209 	case (MAN_TEXT):
210 		p = n->string;
211 		break;
212 	case (MAN_ELEM):
213 		/* FALLTHROUGH */
214 	case (MAN_BLOCK):
215 		/* FALLTHROUGH */
216 	case (MAN_HEAD):
217 		/* FALLTHROUGH */
218 	case (MAN_BODY):
219 		p = man_macronames[n->tok];
220 		break;
221 	case (MAN_ROOT):
222 		p = "root";
223 		break;
224 	case (MAN_TBL):
225 		break;
226 	default:
227 		abort();
228 		/* NOTREACHED */
229 	}
230 
231 	if (n->span) {
232 		assert(NULL == p);
233 		print_span(n->span, indent);
234 	} else {
235 		for (i = 0; i < indent; i++)
236 			putchar('\t');
237 		printf("%s (%s) %d:%d", p, t, n->line, n->pos);
238 	}
239 
240 	putchar('\n');
241 
242 	if (n->child)
243 		print_man(n->child, indent + 1);
244 	if (n->next)
245 		print_man(n->next, indent);
246 }
247 
248 static void
249 print_span(const struct tbl_span *sp, int indent)
250 {
251 	const struct tbl_dat *dp;
252 	int		 i;
253 
254 	for (i = 0; i < indent; i++)
255 		putchar('\t');
256 
257 	printf("tbl: ");
258 
259 	switch (sp->pos) {
260 	case (TBL_SPAN_HORIZ):
261 		putchar('-');
262 		return;
263 	case (TBL_SPAN_DHORIZ):
264 		putchar('=');
265 		return;
266 	default:
267 		break;
268 	}
269 
270 	for (dp = sp->first; dp; dp = dp->next) {
271 		switch (dp->pos) {
272 		case (TBL_DATA_HORIZ):
273 			/* FALLTHROUGH */
274 		case (TBL_DATA_NHORIZ):
275 			putchar('-');
276 			continue;
277 		case (TBL_DATA_DHORIZ):
278 			/* FALLTHROUGH */
279 		case (TBL_DATA_NDHORIZ):
280 			putchar('=');
281 			continue;
282 		default:
283 			break;
284 		}
285 		printf("[%s%s]", dp->string, dp->layout ?  "" : "*");
286 		if (dp->next)
287 			putchar(' ');
288 	}
289 }
290