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