Annotation of mandoc/tree.c, Revision 1.61
1.61 ! schwarze 1: /* $Id: tree.c,v 1.60 2014/11/28 05:51:32 schwarze Exp $ */
1.1 kristaps 2: /*
1.58 schwarze 3: * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.61 ! schwarze 4: * Copyright (c) 2013, 2014, 2015 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.61 ! schwarze 43: print_mdoc(mdoc_node(mdoc)->child, 0);
1.11 kristaps 44: }
45:
1.15 kristaps 46: void
1.11 kristaps 47: tree_man(void *arg, const struct man *man)
48: {
49:
1.61 ! schwarze 50: print_man(man_node(man)->child, 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:
1.61 ! schwarze 61: if (n == NULL)
! 62: return;
! 63:
1.1 kristaps 64: argv = NULL;
1.48 schwarze 65: argc = 0;
1.38 kristaps 66: t = p = NULL;
1.1 kristaps 67:
1.2 kristaps 68: switch (n->type) {
1.52 schwarze 69: case MDOC_ROOT:
1.2 kristaps 70: t = "root";
71: break;
1.52 schwarze 72: case MDOC_BLOCK:
1.2 kristaps 73: t = "block";
74: break;
1.52 schwarze 75: case MDOC_HEAD:
1.2 kristaps 76: t = "block-head";
77: break;
1.52 schwarze 78: case MDOC_BODY:
1.23 schwarze 79: if (n->end)
80: t = "body-end";
81: else
82: t = "block-body";
1.2 kristaps 83: break;
1.52 schwarze 84: case MDOC_TAIL:
1.2 kristaps 85: t = "block-tail";
86: break;
1.52 schwarze 87: case MDOC_ELEM:
1.2 kristaps 88: t = "elem";
89: break;
1.52 schwarze 90: case MDOC_TEXT:
1.2 kristaps 91: t = "text";
92: break;
1.52 schwarze 93: case MDOC_TBL:
1.59 schwarze 94: break;
1.52 schwarze 95: case MDOC_EQN:
1.59 schwarze 96: t = "eqn";
1.33 kristaps 97: break;
1.2 kristaps 98: default:
99: abort();
100: /* NOTREACHED */
101: }
1.1 kristaps 102:
103: switch (n->type) {
1.52 schwarze 104: case MDOC_TEXT:
1.8 kristaps 105: p = n->string;
1.1 kristaps 106: break;
1.52 schwarze 107: case MDOC_BODY:
1.1 kristaps 108: p = mdoc_macronames[n->tok];
109: break;
1.52 schwarze 110: case MDOC_HEAD:
1.1 kristaps 111: p = mdoc_macronames[n->tok];
112: break;
1.52 schwarze 113: case MDOC_TAIL:
1.1 kristaps 114: p = mdoc_macronames[n->tok];
115: break;
1.52 schwarze 116: case MDOC_ELEM:
1.1 kristaps 117: p = mdoc_macronames[n->tok];
1.8 kristaps 118: if (n->args) {
119: argv = n->args->argv;
120: argc = n->args->argc;
121: }
1.1 kristaps 122: break;
1.52 schwarze 123: case MDOC_BLOCK:
1.1 kristaps 124: p = mdoc_macronames[n->tok];
1.8 kristaps 125: if (n->args) {
126: argv = n->args->argv;
127: argc = n->args->argc;
128: }
1.1 kristaps 129: break;
1.52 schwarze 130: case MDOC_TBL:
1.59 schwarze 131: break;
1.52 schwarze 132: case MDOC_EQN:
1.59 schwarze 133: p = "EQ";
1.33 kristaps 134: break;
1.52 schwarze 135: case MDOC_ROOT:
1.1 kristaps 136: p = "root";
137: break;
138: default:
139: abort();
140: /* NOTREACHED */
141: }
142:
1.26 kristaps 143: if (n->span) {
1.38 kristaps 144: assert(NULL == p && NULL == t);
1.30 kristaps 145: print_span(n->span, indent);
1.26 kristaps 146: } else {
1.30 kristaps 147: for (i = 0; i < indent; i++)
1.61 ! schwarze 148: putchar(' ');
1.30 kristaps 149:
1.26 kristaps 150: printf("%s (%s)", p, t);
151:
152: for (i = 0; i < (int)argc; i++) {
153: printf(" -%s", mdoc_argnames[argv[i].arg]);
154: if (argv[i].sz > 0)
155: printf(" [");
156: for (j = 0; j < (int)argv[i].sz; j++)
157: printf(" [%s]", argv[i].value[j]);
158: if (argv[i].sz > 0)
159: printf(" ]");
160: }
1.49 schwarze 161:
162: putchar(' ');
163: if (MDOC_LINE & n->flags)
164: putchar('*');
1.53 schwarze 165: printf("%d:%d", n->line, n->pos + 1);
1.50 schwarze 166: if (n->lastline != n->line)
167: printf("-%d", n->lastline);
168: putchar('\n');
1.1 kristaps 169: }
170:
1.59 schwarze 171: if (n->eqn)
1.61 ! schwarze 172: print_box(n->eqn->root->first, indent + 4);
1.1 kristaps 173: if (n->child)
1.61 ! schwarze 174: print_mdoc(n->child, indent +
! 175: (n->type == MDOC_BLOCK ? 2 : 4));
1.1 kristaps 176: if (n->next)
1.11 kristaps 177: print_mdoc(n->next, indent);
1.1 kristaps 178: }
1.2 kristaps 179:
1.10 kristaps 180: static void
1.11 kristaps 181: print_man(const struct man_node *n, int indent)
1.10 kristaps 182: {
183: const char *p, *t;
184: int i;
185:
1.61 ! schwarze 186: if (n == NULL)
! 187: return;
! 188:
1.38 kristaps 189: t = p = NULL;
190:
1.10 kristaps 191: switch (n->type) {
1.52 schwarze 192: case MAN_ROOT:
1.10 kristaps 193: t = "root";
194: break;
1.52 schwarze 195: case MAN_ELEM:
1.10 kristaps 196: t = "elem";
197: break;
1.52 schwarze 198: case MAN_TEXT:
1.10 kristaps 199: t = "text";
200: break;
1.52 schwarze 201: case MAN_BLOCK:
1.14 kristaps 202: t = "block";
203: break;
1.52 schwarze 204: case MAN_HEAD:
1.14 kristaps 205: t = "block-head";
206: break;
1.52 schwarze 207: case MAN_BODY:
1.14 kristaps 208: t = "block-body";
209: break;
1.52 schwarze 210: case MAN_TBL:
1.59 schwarze 211: break;
1.52 schwarze 212: case MAN_EQN:
1.59 schwarze 213: t = "eqn";
1.33 kristaps 214: break;
1.10 kristaps 215: default:
216: abort();
217: /* NOTREACHED */
218: }
219:
220: switch (n->type) {
1.52 schwarze 221: case MAN_TEXT:
1.10 kristaps 222: p = n->string;
223: break;
1.52 schwarze 224: case MAN_ELEM:
1.14 kristaps 225: /* FALLTHROUGH */
1.52 schwarze 226: case MAN_BLOCK:
1.14 kristaps 227: /* FALLTHROUGH */
1.52 schwarze 228: case MAN_HEAD:
1.14 kristaps 229: /* FALLTHROUGH */
1.52 schwarze 230: case MAN_BODY:
1.10 kristaps 231: p = man_macronames[n->tok];
232: break;
1.52 schwarze 233: case MAN_ROOT:
1.10 kristaps 234: p = "root";
1.25 kristaps 235: break;
1.52 schwarze 236: case MAN_TBL:
1.59 schwarze 237: break;
1.52 schwarze 238: case MAN_EQN:
1.59 schwarze 239: p = "EQ";
1.10 kristaps 240: break;
241: default:
242: abort();
243: /* NOTREACHED */
244: }
245:
1.26 kristaps 246: if (n->span) {
1.38 kristaps 247: assert(NULL == p && NULL == t);
1.30 kristaps 248: print_span(n->span, indent);
249: } else {
250: for (i = 0; i < indent; i++)
1.61 ! schwarze 251: putchar(' ');
1.51 schwarze 252: printf("%s (%s) ", p, t);
253: if (MAN_LINE & n->flags)
254: putchar('*');
1.53 schwarze 255: printf("%d:%d\n", n->line, n->pos + 1);
1.30 kristaps 256: }
1.26 kristaps 257:
1.59 schwarze 258: if (n->eqn)
1.61 ! schwarze 259: print_box(n->eqn->root->first, indent + 4);
1.10 kristaps 260: if (n->child)
1.61 ! schwarze 261: print_man(n->child, indent +
! 262: (n->type == MAN_BLOCK ? 2 : 4));
1.10 kristaps 263: if (n->next)
1.11 kristaps 264: print_man(n->next, indent);
1.28 kristaps 265: }
266:
267: static void
1.38 kristaps 268: print_box(const struct eqn_box *ep, int indent)
269: {
270: int i;
1.46 kristaps 271: const char *t;
1.38 kristaps 272:
1.57 schwarze 273: static const char *posnames[] = {
274: NULL, "sup", "subsup", "sub",
275: "to", "from", "fromto",
276: "over", "sqrt", NULL };
277:
1.38 kristaps 278: if (NULL == ep)
279: return;
280: for (i = 0; i < indent; i++)
1.61 ! schwarze 281: putchar(' ');
1.38 kristaps 282:
1.46 kristaps 283: t = NULL;
1.38 kristaps 284: switch (ep->type) {
1.52 schwarze 285: case EQN_ROOT:
1.46 kristaps 286: t = "eqn-root";
1.45 kristaps 287: break;
1.56 kristaps 288: case EQN_LISTONE:
1.52 schwarze 289: case EQN_LIST:
1.46 kristaps 290: t = "eqn-list";
1.39 kristaps 291: break;
1.52 schwarze 292: case EQN_SUBEXPR:
1.46 kristaps 293: t = "eqn-expr";
1.39 kristaps 294: break;
1.52 schwarze 295: case EQN_TEXT:
1.46 kristaps 296: t = "eqn-text";
1.39 kristaps 297: break;
1.56 kristaps 298: case EQN_PILE:
299: t = "eqn-pile";
300: break;
1.52 schwarze 301: case EQN_MATRIX:
1.46 kristaps 302: t = "eqn-matrix";
1.38 kristaps 303: break;
304: }
1.39 kristaps 305:
1.57 schwarze 306: fputs(t, stdout);
307: if (ep->pos)
308: printf(" pos=%s", posnames[ep->pos]);
309: if (ep->left)
310: printf(" left=\"%s\"", ep->left);
311: if (ep->right)
312: printf(" right=\"%s\"", ep->right);
313: if (ep->top)
314: printf(" top=\"%s\"", ep->top);
315: if (ep->bottom)
316: printf(" bottom=\"%s\"", ep->bottom);
317: if (ep->text)
318: printf(" text=\"%s\"", ep->text);
319: if (ep->font)
320: printf(" font=%d", ep->font);
321: if (ep->size != EQN_DEFSIZE)
322: printf(" size=%d", ep->size);
323: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
324: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
325: else if (ep->args)
326: printf(" args=%zu", ep->args);
327: putchar('\n');
1.46 kristaps 328:
1.61 ! schwarze 329: print_box(ep->first, indent + 4);
1.39 kristaps 330: print_box(ep->next, indent);
1.38 kristaps 331: }
332:
333: static void
1.30 kristaps 334: print_span(const struct tbl_span *sp, int indent)
1.28 kristaps 335: {
336: const struct tbl_dat *dp;
1.30 kristaps 337: int i;
338:
339: for (i = 0; i < indent; i++)
1.61 ! schwarze 340: putchar(' ');
1.28 kristaps 341:
342: switch (sp->pos) {
1.52 schwarze 343: case TBL_SPAN_HORIZ:
1.28 kristaps 344: putchar('-');
345: return;
1.52 schwarze 346: case TBL_SPAN_DHORIZ:
1.28 kristaps 347: putchar('=');
348: return;
349: default:
350: break;
351: }
352:
353: for (dp = sp->first; dp; dp = dp->next) {
354: switch (dp->pos) {
1.52 schwarze 355: case TBL_DATA_HORIZ:
1.28 kristaps 356: /* FALLTHROUGH */
1.52 schwarze 357: case TBL_DATA_NHORIZ:
1.28 kristaps 358: putchar('-');
359: continue;
1.52 schwarze 360: case TBL_DATA_DHORIZ:
1.28 kristaps 361: /* FALLTHROUGH */
1.52 schwarze 362: case TBL_DATA_NDHORIZ:
1.28 kristaps 363: putchar('=');
364: continue;
365: default:
366: break;
367: }
1.32 kristaps 368: printf("[\"%s\"", dp->string ? dp->string : "");
369: if (dp->spans)
370: printf("(%d)", dp->spans);
371: if (NULL == dp->layout)
372: putchar('*');
373: putchar(']');
1.34 kristaps 374: putchar(' ');
1.28 kristaps 375: }
1.34 kristaps 376:
1.38 kristaps 377: printf("(tbl) %d:1\n", sp->line);
1.10 kristaps 378: }
CVSweb