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