xref: /openbsd-src/usr.bin/mandoc/tree.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* $Id: tree.c,v 1.1 2009/04/06 20:30:40 kristaps Exp $ */
2 /*
3  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
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
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 #include <assert.h>
20 #include <err.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include "mdoc.h"
25 #include "man.h"
26 
27 static	void	print_mdoc(const struct mdoc_node *, int);
28 static	void	print_man(const struct man_node *, int);
29 
30 
31 /* ARGSUSED */
32 int
33 tree_mdoc(void *arg, const struct mdoc *mdoc)
34 {
35 
36 	print_mdoc(mdoc_node(mdoc), 0);
37 	return(1);
38 }
39 
40 
41 /* ARGSUSED */
42 int
43 tree_man(void *arg, const struct man *man)
44 {
45 
46 	print_man(man_node(man), 0);
47 	return(1);
48 }
49 
50 
51 static void
52 print_mdoc(const struct mdoc_node *n, int indent)
53 {
54 	const char	 *p, *t;
55 	int		  i, j;
56 	size_t		  argc, sz;
57 	char		**params;
58 	struct mdoc_argv *argv;
59 
60 	argv = NULL;
61 	argc = sz = 0;
62 	params = NULL;
63 
64 	switch (n->type) {
65 	case (MDOC_ROOT):
66 		t = "root";
67 		break;
68 	case (MDOC_BLOCK):
69 		t = "block";
70 		break;
71 	case (MDOC_HEAD):
72 		t = "block-head";
73 		break;
74 	case (MDOC_BODY):
75 		t = "block-body";
76 		break;
77 	case (MDOC_TAIL):
78 		t = "block-tail";
79 		break;
80 	case (MDOC_ELEM):
81 		t = "elem";
82 		break;
83 	case (MDOC_TEXT):
84 		t = "text";
85 		break;
86 	default:
87 		abort();
88 		/* NOTREACHED */
89 	}
90 
91 	switch (n->type) {
92 	case (MDOC_TEXT):
93 		p = n->string;
94 		break;
95 	case (MDOC_BODY):
96 		p = mdoc_macronames[n->tok];
97 		break;
98 	case (MDOC_HEAD):
99 		p = mdoc_macronames[n->tok];
100 		break;
101 	case (MDOC_TAIL):
102 		p = mdoc_macronames[n->tok];
103 		break;
104 	case (MDOC_ELEM):
105 		p = mdoc_macronames[n->tok];
106 		if (n->args) {
107 			argv = n->args->argv;
108 			argc = n->args->argc;
109 		}
110 		break;
111 	case (MDOC_BLOCK):
112 		p = mdoc_macronames[n->tok];
113 		if (n->args) {
114 			argv = n->args->argv;
115 			argc = n->args->argc;
116 		}
117 		break;
118 	case (MDOC_ROOT):
119 		p = "root";
120 		break;
121 	default:
122 		abort();
123 		/* NOTREACHED */
124 	}
125 
126 	for (i = 0; i < indent; i++)
127 		(void)printf("    ");
128 	(void)printf("%s (%s)", p, t);
129 
130 	for (i = 0; i < (int)argc; i++) {
131 		(void)printf(" -%s", mdoc_argnames[argv[i].arg]);
132 		if (argv[i].sz > 0)
133 			(void)printf(" [");
134 		for (j = 0; j < (int)argv[i].sz; j++)
135 			(void)printf(" [%s]", argv[i].value[j]);
136 		if (argv[i].sz > 0)
137 			(void)printf(" ]");
138 	}
139 
140 	for (i = 0; i < (int)sz; i++)
141 		(void)printf(" [%s]", params[i]);
142 
143 	(void)printf(" %d:%d\n", n->line, n->pos);
144 
145 	if (n->child)
146 		print_mdoc(n->child, indent + 1);
147 	if (n->next)
148 		print_mdoc(n->next, indent);
149 }
150 
151 
152 static void
153 print_man(const struct man_node *n, int indent)
154 {
155 	const char	 *p, *t;
156 	int		  i;
157 
158 	switch (n->type) {
159 	case (MAN_ROOT):
160 		t = "root";
161 		break;
162 	case (MAN_ELEM):
163 		t = "elem";
164 		break;
165 	case (MAN_TEXT):
166 		t = "text";
167 		break;
168 	default:
169 		abort();
170 		/* NOTREACHED */
171 	}
172 
173 	switch (n->type) {
174 	case (MAN_TEXT):
175 		p = n->string;
176 		break;
177 	case (MAN_ELEM):
178 		p = man_macronames[n->tok];
179 		break;
180 	case (MAN_ROOT):
181 		p = "root";
182 		break;
183 	default:
184 		abort();
185 		/* NOTREACHED */
186 	}
187 
188 	for (i = 0; i < indent; i++)
189 		(void)printf("    ");
190 	(void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
191 
192 	if (n->child)
193 		print_man(n->child, indent + 1);
194 	if (n->next)
195 		print_man(n->next, indent);
196 }
197