]> git.cameronkatri.com Git - mandoc.git/blob - tree.c
Make sure we don't continue recursively parsing once we've exited with
[mandoc.git] / tree.c
1 /* $Id: tree.c,v 1.30 2011/01/02 20:34:05 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 const struct tbl_head *hp;
253 int i;
254
255 if (TBL_SPAN_FIRST & sp->flags) {
256 for (i = 0; i < indent; i++)
257 putchar('\t');
258 printf("tbl-head: ");
259 for (hp = sp->head; hp; hp = hp->next) {
260 printf("[%d]", hp->width);
261 if (hp->next)
262 putchar(' ');
263 }
264 putchar('\n');
265 }
266
267 for (i = 0; i < indent; i++)
268 putchar('\t');
269
270 printf("tbl: ");
271
272 switch (sp->pos) {
273 case (TBL_SPAN_HORIZ):
274 putchar('-');
275 return;
276 case (TBL_SPAN_DHORIZ):
277 putchar('=');
278 return;
279 default:
280 break;
281 }
282
283 for (dp = sp->first; dp; dp = dp->next) {
284 switch (dp->pos) {
285 case (TBL_DATA_HORIZ):
286 /* FALLTHROUGH */
287 case (TBL_DATA_NHORIZ):
288 putchar('-');
289 continue;
290 case (TBL_DATA_DHORIZ):
291 /* FALLTHROUGH */
292 case (TBL_DATA_NDHORIZ):
293 putchar('=');
294 continue;
295 default:
296 break;
297 }
298 printf("[%s%s]", dp->string, dp->layout ? "" : "*");
299 if (dp->next)
300 putchar(' ');
301 }
302 }