Annotation of mandoc/tree.c, Revision 1.60
1.60 ! schwarze 1: /* $Id: tree.c,v 1.59 2014/10/20 01:43:48 schwarze Exp $ */
1.1 kristaps 2: /*
1.58 schwarze 3: * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.51 schwarze 4: * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
1.1 kristaps 5: *
6: * Permission to use, copy, modify, and distribute this software for any
1.12 kristaps 7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 9: *
1.12 kristaps 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 kristaps 17: */
1.19 kristaps 18: #include "config.h"
1.54 schwarze 19:
20: #include <sys/types.h>
1.19 kristaps 21:
1.8 kristaps 22: #include <assert.h>
1.43 kristaps 23: #include <limits.h>
1.8 kristaps 24: #include <stdio.h>
1.1 kristaps 25: #include <stdlib.h>
1.17 kristaps 26: #include <time.h>
1.1 kristaps 27:
1.20 kristaps 28: #include "mandoc.h"
1.1 kristaps 29: #include "mdoc.h"
1.10 kristaps 30: #include "man.h"
1.16 kristaps 31: #include "main.h"
1.1 kristaps 32:
1.38 kristaps 33: static void print_box(const struct eqn_box *, int);
34: static void print_man(const struct man_node *, int);
1.11 kristaps 35: static void print_mdoc(const struct mdoc_node *, int);
1.30 kristaps 36: static void print_span(const struct tbl_span *, int);
1.8 kristaps 37:
38:
1.15 kristaps 39: void
1.11 kristaps 40: tree_mdoc(void *arg, const struct mdoc *mdoc)
1.8 kristaps 41: {
42:
1.11 kristaps 43: print_mdoc(mdoc_node(mdoc), 0);
44: }
45:
1.15 kristaps 46: void
1.11 kristaps 47: tree_man(void *arg, const struct man *man)
48: {
49:
50: print_man(man_node(man), 0);
1.8 kristaps 51: }
1.2 kristaps 52:
1.1 kristaps 53: static void
1.11 kristaps 54: print_mdoc(const struct mdoc_node *n, int indent)
1.1 kristaps 55: {
56: const char *p, *t;
57: int i, j;
1.48 schwarze 58: size_t argc;
1.8 kristaps 59: struct mdoc_argv *argv;
1.1 kristaps 60:
61: argv = NULL;
1.48 schwarze 62: argc = 0;
1.38 kristaps 63: t = p = NULL;
1.1 kristaps 64:
1.2 kristaps 65: switch (n->type) {
1.52 schwarze 66: case MDOC_ROOT:
1.2 kristaps 67: t = "root";
68: break;
1.52 schwarze 69: case MDOC_BLOCK:
1.2 kristaps 70: t = "block";
71: break;
1.52 schwarze 72: case MDOC_HEAD:
1.2 kristaps 73: t = "block-head";
74: break;
1.52 schwarze 75: case MDOC_BODY:
1.23 schwarze 76: if (n->end)
77: t = "body-end";
78: else
79: t = "block-body";
1.2 kristaps 80: break;
1.52 schwarze 81: case MDOC_TAIL:
1.2 kristaps 82: t = "block-tail";
83: break;
1.52 schwarze 84: case MDOC_ELEM:
1.2 kristaps 85: t = "elem";
86: break;
1.52 schwarze 87: case MDOC_TEXT:
1.2 kristaps 88: t = "text";
89: break;
1.52 schwarze 90: case MDOC_TBL:
1.59 schwarze 91: break;
1.52 schwarze 92: case MDOC_EQN:
1.59 schwarze 93: t = "eqn";
1.33 kristaps 94: break;
1.2 kristaps 95: default:
96: abort();
97: /* NOTREACHED */
98: }
1.1 kristaps 99:
100: switch (n->type) {
1.52 schwarze 101: case MDOC_TEXT:
1.8 kristaps 102: p = n->string;
1.1 kristaps 103: break;
1.52 schwarze 104: case MDOC_BODY:
1.1 kristaps 105: p = mdoc_macronames[n->tok];
106: break;
1.52 schwarze 107: case MDOC_HEAD:
1.1 kristaps 108: p = mdoc_macronames[n->tok];
109: break;
1.52 schwarze 110: case MDOC_TAIL:
1.1 kristaps 111: p = mdoc_macronames[n->tok];
112: break;
1.52 schwarze 113: case MDOC_ELEM:
1.1 kristaps 114: p = mdoc_macronames[n->tok];
1.8 kristaps 115: if (n->args) {
116: argv = n->args->argv;
117: argc = n->args->argc;
118: }
1.1 kristaps 119: break;
1.52 schwarze 120: case MDOC_BLOCK:
1.1 kristaps 121: p = mdoc_macronames[n->tok];
1.8 kristaps 122: if (n->args) {
123: argv = n->args->argv;
124: argc = n->args->argc;
125: }
1.1 kristaps 126: break;
1.52 schwarze 127: case MDOC_TBL:
1.59 schwarze 128: break;
1.52 schwarze 129: case MDOC_EQN:
1.59 schwarze 130: p = "EQ";
1.33 kristaps 131: break;
1.52 schwarze 132: case MDOC_ROOT:
1.1 kristaps 133: p = "root";
134: break;
135: default:
136: abort();
137: /* NOTREACHED */
138: }
139:
1.26 kristaps 140: if (n->span) {
1.38 kristaps 141: assert(NULL == p && NULL == t);
1.30 kristaps 142: print_span(n->span, indent);
1.26 kristaps 143: } else {
1.30 kristaps 144: for (i = 0; i < indent; i++)
145: putchar('\t');
146:
1.26 kristaps 147: printf("%s (%s)", p, t);
148:
149: for (i = 0; i < (int)argc; i++) {
150: printf(" -%s", mdoc_argnames[argv[i].arg]);
151: if (argv[i].sz > 0)
152: printf(" [");
153: for (j = 0; j < (int)argv[i].sz; j++)
154: printf(" [%s]", argv[i].value[j]);
155: if (argv[i].sz > 0)
156: printf(" ]");
157: }
1.49 schwarze 158:
159: putchar(' ');
160: if (MDOC_LINE & n->flags)
161: putchar('*');
1.53 schwarze 162: printf("%d:%d", n->line, n->pos + 1);
1.50 schwarze 163: if (n->lastline != n->line)
164: printf("-%d", n->lastline);
165: putchar('\n');
1.1 kristaps 166: }
167:
1.59 schwarze 168: if (n->eqn)
169: print_box(n->eqn->root->first, indent + 1);
1.1 kristaps 170: if (n->child)
1.11 kristaps 171: print_mdoc(n->child, indent + 1);
1.1 kristaps 172: if (n->next)
1.11 kristaps 173: print_mdoc(n->next, indent);
1.1 kristaps 174: }
1.2 kristaps 175:
1.10 kristaps 176: static void
1.11 kristaps 177: print_man(const struct man_node *n, int indent)
1.10 kristaps 178: {
179: const char *p, *t;
180: int i;
181:
1.38 kristaps 182: t = p = NULL;
183:
1.10 kristaps 184: switch (n->type) {
1.52 schwarze 185: case MAN_ROOT:
1.10 kristaps 186: t = "root";
187: break;
1.52 schwarze 188: case MAN_ELEM:
1.10 kristaps 189: t = "elem";
190: break;
1.52 schwarze 191: case MAN_TEXT:
1.10 kristaps 192: t = "text";
193: break;
1.52 schwarze 194: case MAN_BLOCK:
1.14 kristaps 195: t = "block";
196: break;
1.52 schwarze 197: case MAN_HEAD:
1.14 kristaps 198: t = "block-head";
199: break;
1.52 schwarze 200: case MAN_BODY:
1.14 kristaps 201: t = "block-body";
202: break;
1.52 schwarze 203: case MAN_TBL:
1.59 schwarze 204: break;
1.52 schwarze 205: case MAN_EQN:
1.59 schwarze 206: t = "eqn";
1.33 kristaps 207: break;
1.10 kristaps 208: default:
209: abort();
210: /* NOTREACHED */
211: }
212:
213: switch (n->type) {
1.52 schwarze 214: case MAN_TEXT:
1.10 kristaps 215: p = n->string;
216: break;
1.52 schwarze 217: case MAN_ELEM:
1.14 kristaps 218: /* FALLTHROUGH */
1.52 schwarze 219: case MAN_BLOCK:
1.14 kristaps 220: /* FALLTHROUGH */
1.52 schwarze 221: case MAN_HEAD:
1.14 kristaps 222: /* FALLTHROUGH */
1.52 schwarze 223: case MAN_BODY:
1.10 kristaps 224: p = man_macronames[n->tok];
225: break;
1.52 schwarze 226: case MAN_ROOT:
1.10 kristaps 227: p = "root";
1.25 kristaps 228: break;
1.52 schwarze 229: case MAN_TBL:
1.59 schwarze 230: break;
1.52 schwarze 231: case MAN_EQN:
1.59 schwarze 232: p = "EQ";
1.10 kristaps 233: break;
234: default:
235: abort();
236: /* NOTREACHED */
237: }
238:
1.26 kristaps 239: if (n->span) {
1.38 kristaps 240: assert(NULL == p && NULL == t);
1.30 kristaps 241: print_span(n->span, indent);
242: } else {
243: for (i = 0; i < indent; i++)
244: putchar('\t');
1.51 schwarze 245: printf("%s (%s) ", p, t);
246: if (MAN_LINE & n->flags)
247: putchar('*');
1.53 schwarze 248: printf("%d:%d\n", n->line, n->pos + 1);
1.30 kristaps 249: }
1.26 kristaps 250:
1.59 schwarze 251: if (n->eqn)
252: print_box(n->eqn->root->first, indent + 1);
1.10 kristaps 253: if (n->child)
1.11 kristaps 254: print_man(n->child, indent + 1);
1.10 kristaps 255: if (n->next)
1.11 kristaps 256: print_man(n->next, indent);
1.28 kristaps 257: }
258:
259: static void
1.38 kristaps 260: print_box(const struct eqn_box *ep, int indent)
261: {
262: int i;
1.46 kristaps 263: const char *t;
1.38 kristaps 264:
1.57 schwarze 265: static const char *posnames[] = {
266: NULL, "sup", "subsup", "sub",
267: "to", "from", "fromto",
268: "over", "sqrt", NULL };
269:
1.38 kristaps 270: if (NULL == ep)
271: return;
272: for (i = 0; i < indent; i++)
273: putchar('\t');
274:
1.46 kristaps 275: t = NULL;
1.38 kristaps 276: switch (ep->type) {
1.52 schwarze 277: case EQN_ROOT:
1.46 kristaps 278: t = "eqn-root";
1.45 kristaps 279: break;
1.56 kristaps 280: case EQN_LISTONE:
1.52 schwarze 281: case EQN_LIST:
1.46 kristaps 282: t = "eqn-list";
1.39 kristaps 283: break;
1.52 schwarze 284: case EQN_SUBEXPR:
1.46 kristaps 285: t = "eqn-expr";
1.39 kristaps 286: break;
1.52 schwarze 287: case EQN_TEXT:
1.46 kristaps 288: t = "eqn-text";
1.39 kristaps 289: break;
1.56 kristaps 290: case EQN_PILE:
291: t = "eqn-pile";
292: break;
1.52 schwarze 293: case EQN_MATRIX:
1.46 kristaps 294: t = "eqn-matrix";
1.38 kristaps 295: break;
296: }
1.39 kristaps 297:
1.57 schwarze 298: fputs(t, stdout);
299: if (ep->pos)
300: printf(" pos=%s", posnames[ep->pos]);
301: if (ep->left)
302: printf(" left=\"%s\"", ep->left);
303: if (ep->right)
304: printf(" right=\"%s\"", ep->right);
305: if (ep->top)
306: printf(" top=\"%s\"", ep->top);
307: if (ep->bottom)
308: printf(" bottom=\"%s\"", ep->bottom);
309: if (ep->text)
310: printf(" text=\"%s\"", ep->text);
311: if (ep->font)
312: printf(" font=%d", ep->font);
313: if (ep->size != EQN_DEFSIZE)
314: printf(" size=%d", ep->size);
315: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
316: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
317: else if (ep->args)
318: printf(" args=%zu", ep->args);
319: putchar('\n');
1.46 kristaps 320:
321: print_box(ep->first, indent + 1);
1.39 kristaps 322: print_box(ep->next, indent);
1.38 kristaps 323: }
324:
325: static void
1.30 kristaps 326: print_span(const struct tbl_span *sp, int indent)
1.28 kristaps 327: {
328: const struct tbl_dat *dp;
1.30 kristaps 329: int i;
330:
331: for (i = 0; i < indent; i++)
332: putchar('\t');
1.28 kristaps 333:
334: switch (sp->pos) {
1.52 schwarze 335: case TBL_SPAN_HORIZ:
1.28 kristaps 336: putchar('-');
337: return;
1.52 schwarze 338: case TBL_SPAN_DHORIZ:
1.28 kristaps 339: putchar('=');
340: return;
341: default:
342: break;
343: }
344:
345: for (dp = sp->first; dp; dp = dp->next) {
346: switch (dp->pos) {
1.52 schwarze 347: case TBL_DATA_HORIZ:
1.28 kristaps 348: /* FALLTHROUGH */
1.52 schwarze 349: case TBL_DATA_NHORIZ:
1.28 kristaps 350: putchar('-');
351: continue;
1.52 schwarze 352: case TBL_DATA_DHORIZ:
1.28 kristaps 353: /* FALLTHROUGH */
1.52 schwarze 354: case TBL_DATA_NDHORIZ:
1.28 kristaps 355: putchar('=');
356: continue;
357: default:
358: break;
359: }
1.32 kristaps 360: printf("[\"%s\"", dp->string ? dp->string : "");
361: if (dp->spans)
362: printf("(%d)", dp->spans);
363: if (NULL == dp->layout)
364: putchar('*');
365: putchar(']');
1.34 kristaps 366: putchar(' ');
1.28 kristaps 367: }
1.34 kristaps 368:
1.38 kristaps 369: printf("(tbl) %d:1\n", sp->line);
1.10 kristaps 370: }
CVSweb