]> git.cameronkatri.com Git - mandoc.git/blob - tree.c
Support for badly nested blocks, written around the time of
[mandoc.git] / tree.c
1 /* $Id: tree.c,v 1.23 2010/06/29 19:20:38 schwarze 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 "regs.h"
28 #include "mdoc.h"
29 #include "man.h"
30 #include "main.h"
31
32 static void print_mdoc(const struct mdoc_node *, int);
33 static void print_man(const struct man_node *, 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 default:
93 abort();
94 /* NOTREACHED */
95 }
96
97 switch (n->type) {
98 case (MDOC_TEXT):
99 p = n->string;
100 break;
101 case (MDOC_BODY):
102 p = mdoc_macronames[n->tok];
103 break;
104 case (MDOC_HEAD):
105 p = mdoc_macronames[n->tok];
106 break;
107 case (MDOC_TAIL):
108 p = mdoc_macronames[n->tok];
109 break;
110 case (MDOC_ELEM):
111 p = mdoc_macronames[n->tok];
112 if (n->args) {
113 argv = n->args->argv;
114 argc = n->args->argc;
115 }
116 break;
117 case (MDOC_BLOCK):
118 p = mdoc_macronames[n->tok];
119 if (n->args) {
120 argv = n->args->argv;
121 argc = n->args->argc;
122 }
123 break;
124 case (MDOC_ROOT):
125 p = "root";
126 break;
127 default:
128 abort();
129 /* NOTREACHED */
130 }
131
132 for (i = 0; i < indent; i++)
133 (void)printf(" ");
134 (void)printf("%s (%s)", p, t);
135
136 for (i = 0; i < (int)argc; i++) {
137 (void)printf(" -%s", mdoc_argnames[argv[i].arg]);
138 if (argv[i].sz > 0)
139 (void)printf(" [");
140 for (j = 0; j < (int)argv[i].sz; j++)
141 (void)printf(" [%s]", argv[i].value[j]);
142 if (argv[i].sz > 0)
143 (void)printf(" ]");
144 }
145
146 for (i = 0; i < (int)sz; i++)
147 (void)printf(" [%s]", params[i]);
148
149 (void)printf(" %d:%d\n", n->line, n->pos);
150
151 if (n->child)
152 print_mdoc(n->child, indent + 1);
153 if (n->next)
154 print_mdoc(n->next, indent);
155 }
156
157
158 static void
159 print_man(const struct man_node *n, int indent)
160 {
161 const char *p, *t;
162 int i;
163
164 switch (n->type) {
165 case (MAN_ROOT):
166 t = "root";
167 break;
168 case (MAN_ELEM):
169 t = "elem";
170 break;
171 case (MAN_TEXT):
172 t = "text";
173 break;
174 case (MAN_BLOCK):
175 t = "block";
176 break;
177 case (MAN_HEAD):
178 t = "block-head";
179 break;
180 case (MAN_BODY):
181 t = "block-body";
182 break;
183 default:
184 abort();
185 /* NOTREACHED */
186 }
187
188 switch (n->type) {
189 case (MAN_TEXT):
190 p = n->string;
191 break;
192 case (MAN_ELEM):
193 /* FALLTHROUGH */
194 case (MAN_BLOCK):
195 /* FALLTHROUGH */
196 case (MAN_HEAD):
197 /* FALLTHROUGH */
198 case (MAN_BODY):
199 p = man_macronames[n->tok];
200 break;
201 case (MAN_ROOT):
202 p = "root";
203 break;
204 default:
205 abort();
206 /* NOTREACHED */
207 }
208
209 for (i = 0; i < indent; i++)
210 (void)printf(" ");
211 (void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
212
213 if (n->child)
214 print_man(n->child, indent + 1);
215 if (n->next)
216 print_man(n->next, indent);
217 }