Annotation of src/usr.bin/mandoc/tree.c, Revision 1.24
1.24 ! schwarze 1: /* $OpenBSD$
1.1 kristaps 2: /*
1.24 ! schwarze 3: * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.20 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.2 schwarze 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.2 schwarze 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.24 ! schwarze 18: #include <sys/types.h>
! 19:
1.1 kristaps 20: #include <assert.h>
1.16 schwarze 21: #include <limits.h>
1.1 kristaps 22: #include <stdio.h>
23: #include <stdlib.h>
1.6 schwarze 24: #include <time.h>
1.1 kristaps 25:
1.7 schwarze 26: #include "mandoc.h"
1.1 kristaps 27: #include "mdoc.h"
28: #include "man.h"
1.5 schwarze 29: #include "main.h"
1.1 kristaps 30:
1.16 schwarze 31: static void print_box(const struct eqn_box *, int);
32: static void print_man(const struct man_node *, int);
1.1 kristaps 33: static void print_mdoc(const struct mdoc_node *, int);
1.11 schwarze 34: static void print_span(const struct tbl_span *, int);
1.1 kristaps 35:
36:
1.4 schwarze 37: void
1.1 kristaps 38: tree_mdoc(void *arg, const struct mdoc *mdoc)
39: {
40:
41: print_mdoc(mdoc_node(mdoc), 0);
42: }
43:
1.4 schwarze 44: void
1.1 kristaps 45: tree_man(void *arg, const struct man *man)
46: {
47:
48: print_man(man_node(man), 0);
49: }
50:
51: static void
52: print_mdoc(const struct mdoc_node *n, int indent)
53: {
54: const char *p, *t;
55: int i, j;
1.17 schwarze 56: size_t argc;
1.1 kristaps 57: struct mdoc_argv *argv;
58:
59: argv = NULL;
1.17 schwarze 60: argc = 0;
1.16 schwarze 61: t = p = NULL;
1.1 kristaps 62:
63: switch (n->type) {
1.21 schwarze 64: case MDOC_ROOT:
1.1 kristaps 65: t = "root";
66: break;
1.21 schwarze 67: case MDOC_BLOCK:
1.1 kristaps 68: t = "block";
69: break;
1.21 schwarze 70: case MDOC_HEAD:
1.1 kristaps 71: t = "block-head";
72: break;
1.21 schwarze 73: case MDOC_BODY:
1.9 schwarze 74: if (n->end)
75: t = "body-end";
76: else
77: t = "block-body";
1.1 kristaps 78: break;
1.21 schwarze 79: case MDOC_TAIL:
1.1 kristaps 80: t = "block-tail";
81: break;
1.21 schwarze 82: case MDOC_ELEM:
1.1 kristaps 83: t = "elem";
84: break;
1.21 schwarze 85: case MDOC_TEXT:
1.1 kristaps 86: t = "text";
87: break;
1.21 schwarze 88: case MDOC_TBL:
1.16 schwarze 89: /* FALLTHROUGH */
1.21 schwarze 90: case MDOC_EQN:
1.14 schwarze 91: break;
1.1 kristaps 92: default:
93: abort();
94: /* NOTREACHED */
95: }
96:
97: switch (n->type) {
1.21 schwarze 98: case MDOC_TEXT:
1.1 kristaps 99: p = n->string;
100: break;
1.21 schwarze 101: case MDOC_BODY:
1.1 kristaps 102: p = mdoc_macronames[n->tok];
103: break;
1.21 schwarze 104: case MDOC_HEAD:
1.1 kristaps 105: p = mdoc_macronames[n->tok];
106: break;
1.21 schwarze 107: case MDOC_TAIL:
1.1 kristaps 108: p = mdoc_macronames[n->tok];
109: break;
1.21 schwarze 110: case MDOC_ELEM:
1.1 kristaps 111: p = mdoc_macronames[n->tok];
112: if (n->args) {
113: argv = n->args->argv;
114: argc = n->args->argc;
115: }
116: break;
1.21 schwarze 117: case MDOC_BLOCK:
1.1 kristaps 118: p = mdoc_macronames[n->tok];
119: if (n->args) {
120: argv = n->args->argv;
121: argc = n->args->argc;
122: }
123: break;
1.21 schwarze 124: case MDOC_TBL:
1.16 schwarze 125: /* FALLTHROUGH */
1.21 schwarze 126: case MDOC_EQN:
1.14 schwarze 127: break;
1.21 schwarze 128: case MDOC_ROOT:
1.1 kristaps 129: p = "root";
130: break;
131: default:
132: abort();
133: /* NOTREACHED */
134: }
135:
1.11 schwarze 136: if (n->span) {
1.16 schwarze 137: assert(NULL == p && NULL == t);
1.11 schwarze 138: print_span(n->span, indent);
1.16 schwarze 139: } else if (n->eqn) {
140: assert(NULL == p && NULL == t);
141: print_box(n->eqn->root, indent);
1.11 schwarze 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: }
1.18 schwarze 157:
158: putchar(' ');
159: if (MDOC_LINE & n->flags)
160: putchar('*');
1.22 schwarze 161: printf("%d:%d", n->line, n->pos + 1);
1.19 schwarze 162: if (n->lastline != n->line)
163: printf("-%d", n->lastline);
164: putchar('\n');
1.1 kristaps 165: }
166:
167: if (n->child)
168: print_mdoc(n->child, indent + 1);
169: if (n->next)
170: print_mdoc(n->next, indent);
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:
1.16 schwarze 179: t = p = NULL;
180:
1.1 kristaps 181: switch (n->type) {
1.21 schwarze 182: case MAN_ROOT:
1.1 kristaps 183: t = "root";
184: break;
1.21 schwarze 185: case MAN_ELEM:
1.1 kristaps 186: t = "elem";
187: break;
1.21 schwarze 188: case MAN_TEXT:
1.1 kristaps 189: t = "text";
190: break;
1.21 schwarze 191: case MAN_BLOCK:
1.3 schwarze 192: t = "block";
193: break;
1.21 schwarze 194: case MAN_HEAD:
1.3 schwarze 195: t = "block-head";
196: break;
1.21 schwarze 197: case MAN_BODY:
1.3 schwarze 198: t = "block-body";
199: break;
1.21 schwarze 200: case MAN_TAIL:
1.15 schwarze 201: t = "block-tail";
202: break;
1.21 schwarze 203: case MAN_TBL:
1.16 schwarze 204: /* FALLTHROUGH */
1.21 schwarze 205: case MAN_EQN:
1.14 schwarze 206: break;
1.1 kristaps 207: default:
208: abort();
209: /* NOTREACHED */
210: }
211:
212: switch (n->type) {
1.21 schwarze 213: case MAN_TEXT:
1.1 kristaps 214: p = n->string;
215: break;
1.21 schwarze 216: case MAN_ELEM:
1.3 schwarze 217: /* FALLTHROUGH */
1.21 schwarze 218: case MAN_BLOCK:
1.3 schwarze 219: /* FALLTHROUGH */
1.21 schwarze 220: case MAN_HEAD:
1.15 schwarze 221: /* FALLTHROUGH */
1.21 schwarze 222: case MAN_TAIL:
1.3 schwarze 223: /* FALLTHROUGH */
1.21 schwarze 224: case MAN_BODY:
1.1 kristaps 225: p = man_macronames[n->tok];
226: break;
1.21 schwarze 227: case MAN_ROOT:
1.1 kristaps 228: p = "root";
229: break;
1.21 schwarze 230: case MAN_TBL:
1.16 schwarze 231: /* FALLTHROUGH */
1.21 schwarze 232: case MAN_EQN:
1.11 schwarze 233: break;
1.1 kristaps 234: default:
235: abort();
236: /* NOTREACHED */
237: }
238:
1.11 schwarze 239: if (n->span) {
1.16 schwarze 240: assert(NULL == p && NULL == t);
1.11 schwarze 241: print_span(n->span, indent);
1.16 schwarze 242: } else if (n->eqn) {
243: assert(NULL == p && NULL == t);
244: print_box(n->eqn->root, indent);
1.11 schwarze 245: } else {
246: for (i = 0; i < indent; i++)
247: putchar('\t');
1.20 schwarze 248: printf("%s (%s) ", p, t);
249: if (MAN_LINE & n->flags)
250: putchar('*');
1.22 schwarze 251: printf("%d:%d\n", n->line, n->pos + 1);
1.11 schwarze 252: }
253:
1.1 kristaps 254: if (n->child)
255: print_man(n->child, indent + 1);
256: if (n->next)
257: print_man(n->next, indent);
1.11 schwarze 258: }
259:
260: static void
1.16 schwarze 261: print_box(const struct eqn_box *ep, int indent)
262: {
263: int i;
264: const char *t;
265:
1.24 ! schwarze 266: static const char *posnames[] = {
! 267: NULL, "sup", "subsup", "sub",
! 268: "to", "from", "fromto",
! 269: "over", "sqrt", NULL };
! 270:
1.16 schwarze 271: if (NULL == ep)
272: return;
273: for (i = 0; i < indent; i++)
274: putchar('\t');
275:
276: t = NULL;
277: switch (ep->type) {
1.21 schwarze 278: case EQN_ROOT:
1.16 schwarze 279: t = "eqn-root";
280: break;
1.24 ! schwarze 281: case EQN_LISTONE:
1.21 schwarze 282: case EQN_LIST:
1.16 schwarze 283: t = "eqn-list";
284: break;
1.21 schwarze 285: case EQN_SUBEXPR:
1.16 schwarze 286: t = "eqn-expr";
287: break;
1.21 schwarze 288: case EQN_TEXT:
1.16 schwarze 289: t = "eqn-text";
290: break;
1.24 ! schwarze 291: case EQN_PILE:
! 292: t = "eqn-pile";
! 293: break;
1.21 schwarze 294: case EQN_MATRIX:
1.16 schwarze 295: t = "eqn-matrix";
296: break;
297: }
298:
1.24 ! schwarze 299: fputs(t, stdout);
! 300: if (ep->pos)
! 301: printf(" pos=%s", posnames[ep->pos]);
! 302: if (ep->left)
! 303: printf(" left=\"%s\"", ep->left);
! 304: if (ep->right)
! 305: printf(" right=\"%s\"", ep->right);
! 306: if (ep->top)
! 307: printf(" top=\"%s\"", ep->top);
! 308: if (ep->bottom)
! 309: printf(" bottom=\"%s\"", ep->bottom);
! 310: if (ep->text)
! 311: printf(" text=\"%s\"", ep->text);
! 312: if (ep->font)
! 313: printf(" font=%d", ep->font);
! 314: if (ep->size != EQN_DEFSIZE)
! 315: printf(" size=%d", ep->size);
! 316: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
! 317: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
! 318: else if (ep->args)
! 319: printf(" args=%zu", ep->args);
! 320: putchar('\n');
1.16 schwarze 321:
322: print_box(ep->first, indent + 1);
323: print_box(ep->next, indent);
324: }
325:
326: static void
1.11 schwarze 327: print_span(const struct tbl_span *sp, int indent)
328: {
329: const struct tbl_dat *dp;
330: int i;
331:
332: for (i = 0; i < indent; i++)
333: putchar('\t');
334:
335: switch (sp->pos) {
1.21 schwarze 336: case TBL_SPAN_HORIZ:
1.11 schwarze 337: putchar('-');
338: return;
1.21 schwarze 339: case TBL_SPAN_DHORIZ:
1.11 schwarze 340: putchar('=');
341: return;
342: default:
343: break;
344: }
345:
346: for (dp = sp->first; dp; dp = dp->next) {
347: switch (dp->pos) {
1.21 schwarze 348: case TBL_DATA_HORIZ:
1.11 schwarze 349: /* FALLTHROUGH */
1.21 schwarze 350: case TBL_DATA_NHORIZ:
1.11 schwarze 351: putchar('-');
352: continue;
1.21 schwarze 353: case TBL_DATA_DHORIZ:
1.11 schwarze 354: /* FALLTHROUGH */
1.21 schwarze 355: case TBL_DATA_NDHORIZ:
1.11 schwarze 356: putchar('=');
357: continue;
358: default:
359: break;
360: }
1.12 schwarze 361: printf("[\"%s\"", dp->string ? dp->string : "");
362: if (dp->spans)
363: printf("(%d)", dp->spans);
364: if (NULL == dp->layout)
365: putchar('*');
366: putchar(']');
1.13 schwarze 367: putchar(' ');
1.11 schwarze 368: }
1.13 schwarze 369:
1.16 schwarze 370: printf("(tbl) %d:1\n", sp->line);
1.1 kristaps 371: }