Import mdocml-1.12.1
[dragonfly.git] / contrib / mdocml / tree.c
1 /*      $Id: tree.c,v 1.47 2011/09/18 14:14:15 schwarze Exp $ */
2 /*
3  * Copyright (c) 2008, 2009, 2011 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 <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26
27 #include "mandoc.h"
28 #include "mdoc.h"
29 #include "man.h"
30 #include "main.h"
31
32 static  void    print_box(const struct eqn_box *, int);
33 static  void    print_man(const struct man_node *, int);
34 static  void    print_mdoc(const struct mdoc_node *, int);
35 static  void    print_span(const struct tbl_span *, int);
36
37
38 /* ARGSUSED */
39 void
40 tree_mdoc(void *arg, const struct mdoc *mdoc)
41 {
42
43         print_mdoc(mdoc_node(mdoc), 0);
44 }
45
46
47 /* ARGSUSED */
48 void
49 tree_man(void *arg, const struct man *man)
50 {
51
52         print_man(man_node(man), 0);
53 }
54
55
56 static void
57 print_mdoc(const struct mdoc_node *n, int indent)
58 {
59         const char       *p, *t;
60         int               i, j;
61         size_t            argc, sz;
62         char            **params;
63         struct mdoc_argv *argv;
64
65         argv = NULL;
66         argc = sz = 0;
67         params = NULL;
68         t = p = NULL;
69
70         switch (n->type) {
71         case (MDOC_ROOT):
72                 t = "root";
73                 break;
74         case (MDOC_BLOCK):
75                 t = "block";
76                 break;
77         case (MDOC_HEAD):
78                 t = "block-head";
79                 break;
80         case (MDOC_BODY):
81                 if (n->end)
82                         t = "body-end";
83                 else
84                         t = "block-body";
85                 break;
86         case (MDOC_TAIL):
87                 t = "block-tail";
88                 break;
89         case (MDOC_ELEM):
90                 t = "elem";
91                 break;
92         case (MDOC_TEXT):
93                 t = "text";
94                 break;
95         case (MDOC_TBL):
96                 /* FALLTHROUGH */
97         case (MDOC_EQN):
98                 break;
99         default:
100                 abort();
101                 /* NOTREACHED */
102         }
103
104         switch (n->type) {
105         case (MDOC_TEXT):
106                 p = n->string;
107                 break;
108         case (MDOC_BODY):
109                 p = mdoc_macronames[n->tok];
110                 break;
111         case (MDOC_HEAD):
112                 p = mdoc_macronames[n->tok];
113                 break;
114         case (MDOC_TAIL):
115                 p = mdoc_macronames[n->tok];
116                 break;
117         case (MDOC_ELEM):
118                 p = mdoc_macronames[n->tok];
119                 if (n->args) {
120                         argv = n->args->argv;
121                         argc = n->args->argc;
122                 }
123                 break;
124         case (MDOC_BLOCK):
125                 p = mdoc_macronames[n->tok];
126                 if (n->args) {
127                         argv = n->args->argv;
128                         argc = n->args->argc;
129                 }
130                 break;
131         case (MDOC_TBL):
132                 /* FALLTHROUGH */
133         case (MDOC_EQN):
134                 break;
135         case (MDOC_ROOT):
136                 p = "root";
137                 break;
138         default:
139                 abort();
140                 /* NOTREACHED */
141         }
142
143         if (n->span) {
144                 assert(NULL == p && NULL == t);
145                 print_span(n->span, indent);
146         } else if (n->eqn) {
147                 assert(NULL == p && NULL == t);
148                 print_box(n->eqn->root, indent);
149         } else {
150                 for (i = 0; i < indent; i++)
151                         putchar('\t');
152
153                 printf("%s (%s)", p, t);
154
155                 for (i = 0; i < (int)argc; i++) {
156                         printf(" -%s", mdoc_argnames[argv[i].arg]);
157                         if (argv[i].sz > 0)
158                                 printf(" [");
159                         for (j = 0; j < (int)argv[i].sz; j++)
160                                 printf(" [%s]", argv[i].value[j]);
161                         if (argv[i].sz > 0)
162                                 printf(" ]");
163                 }
164                 
165                 for (i = 0; i < (int)sz; i++)
166                         printf(" [%s]", params[i]);
167
168                 printf(" %d:%d\n", n->line, n->pos);
169         }
170
171         if (n->child)
172                 print_mdoc(n->child, indent + 1);
173         if (n->next)
174                 print_mdoc(n->next, indent);
175 }
176
177
178 static void
179 print_man(const struct man_node *n, int indent)
180 {
181         const char       *p, *t;
182         int               i;
183
184         t = p = NULL;
185
186         switch (n->type) {
187         case (MAN_ROOT):
188                 t = "root";
189                 break;
190         case (MAN_ELEM):
191                 t = "elem";
192                 break;
193         case (MAN_TEXT):
194                 t = "text";
195                 break;
196         case (MAN_BLOCK):
197                 t = "block";
198                 break;
199         case (MAN_HEAD):
200                 t = "block-head";
201                 break;
202         case (MAN_BODY):
203                 t = "block-body";
204                 break;
205         case (MAN_TAIL):
206                 t = "block-tail";
207                 break;
208         case (MAN_TBL):
209                 /* FALLTHROUGH */
210         case (MAN_EQN):
211                 break;
212         default:
213                 abort();
214                 /* NOTREACHED */
215         }
216
217         switch (n->type) {
218         case (MAN_TEXT):
219                 p = n->string;
220                 break;
221         case (MAN_ELEM):
222                 /* FALLTHROUGH */
223         case (MAN_BLOCK):
224                 /* FALLTHROUGH */
225         case (MAN_HEAD):
226                 /* FALLTHROUGH */
227         case (MAN_TAIL):
228                 /* FALLTHROUGH */
229         case (MAN_BODY):
230                 p = man_macronames[n->tok];
231                 break;
232         case (MAN_ROOT):
233                 p = "root";
234                 break;
235         case (MAN_TBL):
236                 /* FALLTHROUGH */
237         case (MAN_EQN):
238                 break;
239         default:
240                 abort();
241                 /* NOTREACHED */
242         }
243
244         if (n->span) {
245                 assert(NULL == p && NULL == t);
246                 print_span(n->span, indent);
247         } else if (n->eqn) {
248                 assert(NULL == p && NULL == t);
249                 print_box(n->eqn->root, indent);
250         } else {
251                 for (i = 0; i < indent; i++)
252                         putchar('\t');
253                 printf("%s (%s) %d:%d\n", p, t, n->line, n->pos);
254         }
255
256         if (n->child)
257                 print_man(n->child, indent + 1);
258         if (n->next)
259                 print_man(n->next, indent);
260 }
261
262 static void
263 print_box(const struct eqn_box *ep, int indent)
264 {
265         int              i;
266         const char      *t;
267
268         if (NULL == ep)
269                 return;
270         for (i = 0; i < indent; i++)
271                 putchar('\t');
272
273         t = NULL;
274         switch (ep->type) {
275         case (EQN_ROOT):
276                 t = "eqn-root";
277                 break;
278         case (EQN_LIST):
279                 t = "eqn-list";
280                 break;
281         case (EQN_SUBEXPR):
282                 t = "eqn-expr";
283                 break;
284         case (EQN_TEXT):
285                 t = "eqn-text";
286                 break;
287         case (EQN_MATRIX):
288                 t = "eqn-matrix";
289                 break;
290         }
291
292         assert(t);
293         printf("%s(%d, %d, %d, %d, %d, \"%s\", \"%s\") %s\n", 
294                 t, EQN_DEFSIZE == ep->size ? 0 : ep->size,
295                 ep->pos, ep->font, ep->mark, ep->pile, 
296                 ep->left ? ep->left : "",
297                 ep->right ? ep->right : "",
298                 ep->text ? ep->text : "");
299
300         print_box(ep->first, indent + 1);
301         print_box(ep->next, indent);
302 }
303
304 static void
305 print_span(const struct tbl_span *sp, int indent)
306 {
307         const struct tbl_dat *dp;
308         int              i;
309
310         for (i = 0; i < indent; i++)
311                 putchar('\t');
312
313         switch (sp->pos) {
314         case (TBL_SPAN_HORIZ):
315                 putchar('-');
316                 return;
317         case (TBL_SPAN_DHORIZ):
318                 putchar('=');
319                 return;
320         default:
321                 break;
322         }
323
324         for (dp = sp->first; dp; dp = dp->next) {
325                 switch (dp->pos) {
326                 case (TBL_DATA_HORIZ):
327                         /* FALLTHROUGH */
328                 case (TBL_DATA_NHORIZ):
329                         putchar('-');
330                         continue;
331                 case (TBL_DATA_DHORIZ):
332                         /* FALLTHROUGH */
333                 case (TBL_DATA_NDHORIZ):
334                         putchar('=');
335                         continue;
336                 default:
337                         break;
338                 }
339                 printf("[\"%s\"", dp->string ? dp->string : "");
340                 if (dp->spans)
341                         printf("(%d)", dp->spans);
342                 if (NULL == dp->layout)
343                         putchar('*');
344                 putchar(']');
345                 putchar(' ');
346         }
347
348         printf("(tbl) %d:1\n", sp->line);
349 }