b243df2a2467841686126e304652fcfd007b4319
[dragonfly.git] / usr.bin / mandoc / tree.c
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 }