xref: /netbsd-src/external/bsd/mdocml/dist/tree.c (revision 179b12252ecaf3553d9c2b7458ce62b6a2203d0c)
1 /*	$Vendor-Id: tree.c,v 1.24 2010/07/07 15:04:54 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 
34 
35 /* ARGSUSED */
36 void
37 tree_mdoc(void *arg, const struct mdoc *mdoc)
38 {
39 
40 	print_mdoc(mdoc_node(mdoc), 0);
41 }
42 
43 
44 /* ARGSUSED */
45 void
46 tree_man(void *arg, const struct man *man)
47 {
48 
49 	print_man(man_node(man), 0);
50 }
51 
52 
53 static void
54 print_mdoc(const struct mdoc_node *n, int indent)
55 {
56 	const char	 *p, *t;
57 	int		  i, j;
58 	size_t		  argc, sz;
59 	char		**params;
60 	struct mdoc_argv *argv;
61 
62 	argv = NULL;
63 	argc = sz = 0;
64 	params = NULL;
65 
66 	switch (n->type) {
67 	case (MDOC_ROOT):
68 		t = "root";
69 		break;
70 	case (MDOC_BLOCK):
71 		t = "block";
72 		break;
73 	case (MDOC_HEAD):
74 		t = "block-head";
75 		break;
76 	case (MDOC_BODY):
77 		if (n->end)
78 			t = "body-end";
79 		else
80 			t = "block-body";
81 		break;
82 	case (MDOC_TAIL):
83 		t = "block-tail";
84 		break;
85 	case (MDOC_ELEM):
86 		t = "elem";
87 		break;
88 	case (MDOC_TEXT):
89 		t = "text";
90 		break;
91 	default:
92 		abort();
93 		/* NOTREACHED */
94 	}
95 
96 	switch (n->type) {
97 	case (MDOC_TEXT):
98 		p = n->string;
99 		break;
100 	case (MDOC_BODY):
101 		p = mdoc_macronames[n->tok];
102 		break;
103 	case (MDOC_HEAD):
104 		p = mdoc_macronames[n->tok];
105 		break;
106 	case (MDOC_TAIL):
107 		p = mdoc_macronames[n->tok];
108 		break;
109 	case (MDOC_ELEM):
110 		p = mdoc_macronames[n->tok];
111 		if (n->args) {
112 			argv = n->args->argv;
113 			argc = n->args->argc;
114 		}
115 		break;
116 	case (MDOC_BLOCK):
117 		p = mdoc_macronames[n->tok];
118 		if (n->args) {
119 			argv = n->args->argv;
120 			argc = n->args->argc;
121 		}
122 		break;
123 	case (MDOC_ROOT):
124 		p = "root";
125 		break;
126 	default:
127 		abort();
128 		/* NOTREACHED */
129 	}
130 
131 	for (i = 0; i < indent; i++)
132 		(void)printf("    ");
133 	(void)printf("%s (%s)", p, t);
134 
135 	for (i = 0; i < (int)argc; i++) {
136 		(void)printf(" -%s", mdoc_argnames[argv[i].arg]);
137 		if (argv[i].sz > 0)
138 			(void)printf(" [");
139 		for (j = 0; j < (int)argv[i].sz; j++)
140 			(void)printf(" [%s]", argv[i].value[j]);
141 		if (argv[i].sz > 0)
142 			(void)printf(" ]");
143 	}
144 
145 	for (i = 0; i < (int)sz; i++)
146 		(void)printf(" [%s]", params[i]);
147 
148 	(void)printf(" %d:%d\n", n->line, n->pos);
149 
150 	if (n->child)
151 		print_mdoc(n->child, indent + 1);
152 	if (n->next)
153 		print_mdoc(n->next, indent);
154 }
155 
156 
157 static void
158 print_man(const struct man_node *n, int indent)
159 {
160 	const char	 *p, *t;
161 	int		  i;
162 
163 	switch (n->type) {
164 	case (MAN_ROOT):
165 		t = "root";
166 		break;
167 	case (MAN_ELEM):
168 		t = "elem";
169 		break;
170 	case (MAN_TEXT):
171 		t = "text";
172 		break;
173 	case (MAN_BLOCK):
174 		t = "block";
175 		break;
176 	case (MAN_HEAD):
177 		t = "block-head";
178 		break;
179 	case (MAN_BODY):
180 		t = "block-body";
181 		break;
182 	default:
183 		abort();
184 		/* NOTREACHED */
185 	}
186 
187 	switch (n->type) {
188 	case (MAN_TEXT):
189 		p = n->string;
190 		break;
191 	case (MAN_ELEM):
192 		/* FALLTHROUGH */
193 	case (MAN_BLOCK):
194 		/* FALLTHROUGH */
195 	case (MAN_HEAD):
196 		/* FALLTHROUGH */
197 	case (MAN_BODY):
198 		p = man_macronames[n->tok];
199 		break;
200 	case (MAN_ROOT):
201 		p = "root";
202 		break;
203 	default:
204 		abort();
205 		/* NOTREACHED */
206 	}
207 
208 	for (i = 0; i < indent; i++)
209 		(void)printf("    ");
210 	(void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
211 
212 	if (n->child)
213 		print_man(n->child, indent + 1);
214 	if (n->next)
215 		print_man(n->next, indent);
216 }
217