Annotation of src/usr.bin/mandoc/tree.c, Revision 1.27
1.27 ! schwarze 1: /* $OpenBSD: tree.c,v 1.26 2014/10/20 01:43:06 schwarze Exp $ */
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.26 schwarze 89: break;
1.21 schwarze 90: case MDOC_EQN:
1.26 schwarze 91: t = "eqn";
1.14 schwarze 92: break;
1.1 kristaps 93: default:
94: abort();
95: /* NOTREACHED */
96: }
97:
98: switch (n->type) {
1.21 schwarze 99: case MDOC_TEXT:
1.1 kristaps 100: p = n->string;
101: break;
1.21 schwarze 102: case MDOC_BODY:
1.1 kristaps 103: p = mdoc_macronames[n->tok];
104: break;
1.21 schwarze 105: case MDOC_HEAD:
1.1 kristaps 106: p = mdoc_macronames[n->tok];
107: break;
1.21 schwarze 108: case MDOC_TAIL:
1.1 kristaps 109: p = mdoc_macronames[n->tok];
110: break;
1.21 schwarze 111: case MDOC_ELEM:
1.1 kristaps 112: p = mdoc_macronames[n->tok];
113: if (n->args) {
114: argv = n->args->argv;
115: argc = n->args->argc;
116: }
117: break;
1.21 schwarze 118: case MDOC_BLOCK:
1.1 kristaps 119: p = mdoc_macronames[n->tok];
120: if (n->args) {
121: argv = n->args->argv;
122: argc = n->args->argc;
123: }
124: break;
1.21 schwarze 125: case MDOC_TBL:
1.26 schwarze 126: break;
1.21 schwarze 127: case MDOC_EQN:
1.26 schwarze 128: p = "EQ";
1.14 schwarze 129: break;
1.21 schwarze 130: case MDOC_ROOT:
1.1 kristaps 131: p = "root";
132: break;
133: default:
134: abort();
135: /* NOTREACHED */
136: }
137:
1.11 schwarze 138: if (n->span) {
1.16 schwarze 139: assert(NULL == p && NULL == t);
1.11 schwarze 140: print_span(n->span, indent);
141: } else {
142: for (i = 0; i < indent; i++)
143: putchar('\t');
144:
145: printf("%s (%s)", p, t);
146:
147: for (i = 0; i < (int)argc; i++) {
148: printf(" -%s", mdoc_argnames[argv[i].arg]);
149: if (argv[i].sz > 0)
150: printf(" [");
151: for (j = 0; j < (int)argv[i].sz; j++)
152: printf(" [%s]", argv[i].value[j]);
153: if (argv[i].sz > 0)
154: printf(" ]");
155: }
1.18 schwarze 156:
157: putchar(' ');
158: if (MDOC_LINE & n->flags)
159: putchar('*');
1.22 schwarze 160: printf("%d:%d", n->line, n->pos + 1);
1.19 schwarze 161: if (n->lastline != n->line)
162: printf("-%d", n->lastline);
163: putchar('\n');
1.1 kristaps 164: }
165:
1.26 schwarze 166: if (n->eqn)
167: print_box(n->eqn->root->first, indent + 1);
1.1 kristaps 168: if (n->child)
169: print_mdoc(n->child, indent + 1);
170: if (n->next)
171: print_mdoc(n->next, indent);
172: }
173:
174: static void
175: print_man(const struct man_node *n, int indent)
176: {
177: const char *p, *t;
178: int i;
179:
1.16 schwarze 180: t = p = NULL;
181:
1.1 kristaps 182: switch (n->type) {
1.21 schwarze 183: case MAN_ROOT:
1.1 kristaps 184: t = "root";
185: break;
1.21 schwarze 186: case MAN_ELEM:
1.1 kristaps 187: t = "elem";
188: break;
1.21 schwarze 189: case MAN_TEXT:
1.1 kristaps 190: t = "text";
191: break;
1.21 schwarze 192: case MAN_BLOCK:
1.3 schwarze 193: t = "block";
194: break;
1.21 schwarze 195: case MAN_HEAD:
1.3 schwarze 196: t = "block-head";
197: break;
1.21 schwarze 198: case MAN_BODY:
1.3 schwarze 199: t = "block-body";
200: break;
1.21 schwarze 201: case MAN_TBL:
1.26 schwarze 202: break;
1.21 schwarze 203: case MAN_EQN:
1.26 schwarze 204: t = "eqn";
1.14 schwarze 205: break;
1.1 kristaps 206: default:
207: abort();
208: /* NOTREACHED */
209: }
210:
211: switch (n->type) {
1.21 schwarze 212: case MAN_TEXT:
1.1 kristaps 213: p = n->string;
214: break;
1.21 schwarze 215: case MAN_ELEM:
1.3 schwarze 216: /* FALLTHROUGH */
1.21 schwarze 217: case MAN_BLOCK:
1.3 schwarze 218: /* FALLTHROUGH */
1.21 schwarze 219: case MAN_HEAD:
1.3 schwarze 220: /* FALLTHROUGH */
1.21 schwarze 221: case MAN_BODY:
1.1 kristaps 222: p = man_macronames[n->tok];
223: break;
1.21 schwarze 224: case MAN_ROOT:
1.1 kristaps 225: p = "root";
226: break;
1.21 schwarze 227: case MAN_TBL:
1.26 schwarze 228: break;
1.21 schwarze 229: case MAN_EQN:
1.26 schwarze 230: p = "EQ";
1.11 schwarze 231: break;
1.1 kristaps 232: default:
233: abort();
234: /* NOTREACHED */
235: }
236:
1.11 schwarze 237: if (n->span) {
1.16 schwarze 238: assert(NULL == p && NULL == t);
1.11 schwarze 239: print_span(n->span, indent);
240: } else {
241: for (i = 0; i < indent; i++)
242: putchar('\t');
1.20 schwarze 243: printf("%s (%s) ", p, t);
244: if (MAN_LINE & n->flags)
245: putchar('*');
1.22 schwarze 246: printf("%d:%d\n", n->line, n->pos + 1);
1.11 schwarze 247: }
248:
1.26 schwarze 249: if (n->eqn)
250: print_box(n->eqn->root->first, indent + 1);
1.1 kristaps 251: if (n->child)
252: print_man(n->child, indent + 1);
253: if (n->next)
254: print_man(n->next, indent);
1.11 schwarze 255: }
256:
257: static void
1.16 schwarze 258: print_box(const struct eqn_box *ep, int indent)
259: {
260: int i;
261: const char *t;
262:
1.24 schwarze 263: static const char *posnames[] = {
264: NULL, "sup", "subsup", "sub",
265: "to", "from", "fromto",
266: "over", "sqrt", NULL };
267:
1.16 schwarze 268: if (NULL == ep)
269: return;
270: for (i = 0; i < indent; i++)
271: putchar('\t');
272:
273: t = NULL;
274: switch (ep->type) {
1.21 schwarze 275: case EQN_ROOT:
1.16 schwarze 276: t = "eqn-root";
277: break;
1.24 schwarze 278: case EQN_LISTONE:
1.21 schwarze 279: case EQN_LIST:
1.16 schwarze 280: t = "eqn-list";
281: break;
1.21 schwarze 282: case EQN_SUBEXPR:
1.16 schwarze 283: t = "eqn-expr";
284: break;
1.21 schwarze 285: case EQN_TEXT:
1.16 schwarze 286: t = "eqn-text";
287: break;
1.24 schwarze 288: case EQN_PILE:
289: t = "eqn-pile";
290: break;
1.21 schwarze 291: case EQN_MATRIX:
1.16 schwarze 292: t = "eqn-matrix";
293: break;
294: }
295:
1.24 schwarze 296: fputs(t, stdout);
297: if (ep->pos)
298: printf(" pos=%s", posnames[ep->pos]);
299: if (ep->left)
300: printf(" left=\"%s\"", ep->left);
301: if (ep->right)
302: printf(" right=\"%s\"", ep->right);
303: if (ep->top)
304: printf(" top=\"%s\"", ep->top);
305: if (ep->bottom)
306: printf(" bottom=\"%s\"", ep->bottom);
307: if (ep->text)
308: printf(" text=\"%s\"", ep->text);
309: if (ep->font)
310: printf(" font=%d", ep->font);
311: if (ep->size != EQN_DEFSIZE)
312: printf(" size=%d", ep->size);
313: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
314: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
315: else if (ep->args)
316: printf(" args=%zu", ep->args);
317: putchar('\n');
1.16 schwarze 318:
319: print_box(ep->first, indent + 1);
320: print_box(ep->next, indent);
321: }
322:
323: static void
1.11 schwarze 324: print_span(const struct tbl_span *sp, int indent)
325: {
326: const struct tbl_dat *dp;
327: int i;
328:
329: for (i = 0; i < indent; i++)
330: putchar('\t');
331:
332: switch (sp->pos) {
1.21 schwarze 333: case TBL_SPAN_HORIZ:
1.11 schwarze 334: putchar('-');
335: return;
1.21 schwarze 336: case TBL_SPAN_DHORIZ:
1.11 schwarze 337: putchar('=');
338: return;
339: default:
340: break;
341: }
342:
343: for (dp = sp->first; dp; dp = dp->next) {
344: switch (dp->pos) {
1.21 schwarze 345: case TBL_DATA_HORIZ:
1.11 schwarze 346: /* FALLTHROUGH */
1.21 schwarze 347: case TBL_DATA_NHORIZ:
1.11 schwarze 348: putchar('-');
349: continue;
1.21 schwarze 350: case TBL_DATA_DHORIZ:
1.11 schwarze 351: /* FALLTHROUGH */
1.21 schwarze 352: case TBL_DATA_NDHORIZ:
1.11 schwarze 353: putchar('=');
354: continue;
355: default:
356: break;
357: }
1.12 schwarze 358: printf("[\"%s\"", dp->string ? dp->string : "");
359: if (dp->spans)
360: printf("(%d)", dp->spans);
361: if (NULL == dp->layout)
362: putchar('*');
363: putchar(']');
1.13 schwarze 364: putchar(' ');
1.11 schwarze 365: }
1.13 schwarze 366:
1.16 schwarze 367: printf("(tbl) %d:1\n", sp->line);
1.1 kristaps 368: }