Import mdocml-1.10.9
[dragonfly.git] / contrib / mdocml / tree.c
1 /*      $Id: tree.c,v 1.31 2011/01/03 13:59:21 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 static  void    print_span(const struct tbl_span *, 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         case (MDOC_TBL):
93                 t = "tbl";
94                 break;
95         default:
96                 abort();
97                 /* NOTREACHED */
98         }
99
100         p = NULL;
101
102         switch (n->type) {
103         case (MDOC_TEXT):
104                 p = n->string;
105                 break;
106         case (MDOC_BODY):
107                 p = mdoc_macronames[n->tok];
108                 break;
109         case (MDOC_HEAD):
110                 p = mdoc_macronames[n->tok];
111                 break;
112         case (MDOC_TAIL):
113                 p = mdoc_macronames[n->tok];
114                 break;
115         case (MDOC_ELEM):
116                 p = mdoc_macronames[n->tok];
117                 if (n->args) {
118                         argv = n->args->argv;
119                         argc = n->args->argc;
120                 }
121                 break;
122         case (MDOC_BLOCK):
123                 p = mdoc_macronames[n->tok];
124                 if (n->args) {
125                         argv = n->args->argv;
126                         argc = n->args->argc;
127                 }
128                 break;
129         case (MDOC_TBL):
130                 break;
131         case (MDOC_ROOT):
132                 p = "root";
133                 break;
134         default:
135                 abort();
136                 /* NOTREACHED */
137         }
138
139         if (n->span) {
140                 assert(NULL == p);
141                 print_span(n->span, indent);
142         } else {
143                 for (i = 0; i < indent; i++)
144                         putchar('\t');
145
146                 printf("%s (%s)", p, t);
147
148                 for (i = 0; i < (int)argc; i++) {
149                         printf(" -%s", mdoc_argnames[argv[i].arg]);
150                         if (argv[i].sz > 0)
151                                 printf(" [");
152                         for (j = 0; j < (int)argv[i].sz; j++)
153                                 printf(" [%s]", argv[i].value[j]);
154                         if (argv[i].sz > 0)
155                                 printf(" ]");
156                 }
157                 
158                 for (i = 0; i < (int)sz; i++)
159                         printf(" [%s]", params[i]);
160
161                 printf(" %d:%d", n->line, n->pos);
162         }
163
164         putchar('\n');
165
166         if (n->child)
167                 print_mdoc(n->child, indent + 1);
168         if (n->next)
169                 print_mdoc(n->next, indent);
170 }
171
172
173 static void
174 print_man(const struct man_node *n, int indent)
175 {
176         const char       *p, *t;
177         int               i;
178
179         switch (n->type) {
180         case (MAN_ROOT):
181                 t = "root";
182                 break;
183         case (MAN_ELEM):
184                 t = "elem";
185                 break;
186         case (MAN_TEXT):
187                 t = "text";
188                 break;
189         case (MAN_BLOCK):
190                 t = "block";
191                 break;
192         case (MAN_HEAD):
193                 t = "block-head";
194                 break;
195         case (MAN_BODY):
196                 t = "block-body";
197                 break;
198         case (MAN_TBL):
199                 t = "tbl";
200                 break;
201         default:
202                 abort();
203                 /* NOTREACHED */
204         }
205
206         p = NULL;
207
208         switch (n->type) {
209         case (MAN_TEXT):
210                 p = n->string;
211                 break;
212         case (MAN_ELEM):
213                 /* FALLTHROUGH */
214         case (MAN_BLOCK):
215                 /* FALLTHROUGH */
216         case (MAN_HEAD):
217                 /* FALLTHROUGH */
218         case (MAN_BODY):
219                 p = man_macronames[n->tok];
220                 break;
221         case (MAN_ROOT):
222                 p = "root";
223                 break;
224         case (MAN_TBL):
225                 break;
226         default:
227                 abort();
228                 /* NOTREACHED */
229         }
230
231         if (n->span) {
232                 assert(NULL == p);
233                 print_span(n->span, indent);
234         } else {
235                 for (i = 0; i < indent; i++)
236                         putchar('\t');
237                 printf("%s (%s) %d:%d", p, t, n->line, n->pos);
238         }
239
240         putchar('\n');
241
242         if (n->child)
243                 print_man(n->child, indent + 1);
244         if (n->next)
245                 print_man(n->next, indent);
246 }
247
248 static void
249 print_span(const struct tbl_span *sp, int indent)
250 {
251         const struct tbl_dat *dp;
252         int              i;
253
254         for (i = 0; i < indent; i++)
255                 putchar('\t');
256
257         printf("tbl: ");
258
259         switch (sp->pos) {
260         case (TBL_SPAN_HORIZ):
261                 putchar('-');
262                 return;
263         case (TBL_SPAN_DHORIZ):
264                 putchar('=');
265                 return;
266         default:
267                 break;
268         }
269
270         for (dp = sp->first; dp; dp = dp->next) {
271                 switch (dp->pos) {
272                 case (TBL_DATA_HORIZ):
273                         /* FALLTHROUGH */
274                 case (TBL_DATA_NHORIZ):
275                         putchar('-');
276                         continue;
277                 case (TBL_DATA_DHORIZ):
278                         /* FALLTHROUGH */
279                 case (TBL_DATA_NDHORIZ):
280                         putchar('=');
281                         continue;
282                 default:
283                         break;
284                 }
285                 printf("[%s%s]", dp->string, dp->layout ?  "" : "*");
286                 if (dp->next)
287                         putchar(' ');
288         }
289 }