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