Annotation of mandoc/tree.c, Revision 1.71
1.71 ! schwarze 1: /* $Id: tree.c,v 1.70 2017/01/10 12:53:08 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.63 schwarze 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
1.12 kristaps 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1.63 schwarze 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
1.12 kristaps 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.63 schwarze 29: #include "roff.h"
1.1 kristaps 30: #include "mdoc.h"
1.10 kristaps 31: #include "man.h"
1.16 kristaps 32: #include "main.h"
1.1 kristaps 33:
1.38 kristaps 34: static void print_box(const struct eqn_box *, int);
1.64 schwarze 35: static void print_man(const struct roff_node *, int);
36: static void print_mdoc(const struct roff_node *, int);
1.30 kristaps 37: static void print_span(const struct tbl_span *, int);
1.8 kristaps 38:
39:
1.15 kristaps 40: void
1.65 schwarze 41: tree_mdoc(void *arg, const struct roff_man *mdoc)
1.8 kristaps 42: {
43:
1.66 schwarze 44: print_mdoc(mdoc->first->child, 0);
1.11 kristaps 45: }
46:
1.15 kristaps 47: void
1.65 schwarze 48: tree_man(void *arg, const struct roff_man *man)
1.11 kristaps 49: {
50:
1.66 schwarze 51: print_man(man->first->child, 0);
1.8 kristaps 52: }
1.2 kristaps 53:
1.1 kristaps 54: static void
1.64 schwarze 55: print_mdoc(const struct roff_node *n, int indent)
1.1 kristaps 56: {
57: const char *p, *t;
58: int i, j;
1.48 schwarze 59: size_t argc;
1.8 kristaps 60: struct mdoc_argv *argv;
1.1 kristaps 61:
1.61 schwarze 62: if (n == NULL)
63: return;
64:
1.1 kristaps 65: argv = NULL;
1.48 schwarze 66: argc = 0;
1.38 kristaps 67: t = p = NULL;
1.1 kristaps 68:
1.2 kristaps 69: switch (n->type) {
1.63 schwarze 70: case ROFFT_ROOT:
1.2 kristaps 71: t = "root";
72: break;
1.63 schwarze 73: case ROFFT_BLOCK:
1.2 kristaps 74: t = "block";
75: break;
1.63 schwarze 76: case ROFFT_HEAD:
1.68 schwarze 77: t = "head";
1.2 kristaps 78: break;
1.63 schwarze 79: case ROFFT_BODY:
1.23 schwarze 80: if (n->end)
81: t = "body-end";
82: else
1.68 schwarze 83: t = "body";
1.2 kristaps 84: break;
1.63 schwarze 85: case ROFFT_TAIL:
1.68 schwarze 86: t = "tail";
1.2 kristaps 87: break;
1.63 schwarze 88: case ROFFT_ELEM:
1.2 kristaps 89: t = "elem";
90: break;
1.63 schwarze 91: case ROFFT_TEXT:
1.2 kristaps 92: t = "text";
93: break;
1.63 schwarze 94: case ROFFT_TBL:
1.59 schwarze 95: break;
1.63 schwarze 96: case ROFFT_EQN:
1.59 schwarze 97: t = "eqn";
1.33 kristaps 98: break;
1.2 kristaps 99: default:
100: abort();
101: }
1.1 kristaps 102:
103: switch (n->type) {
1.63 schwarze 104: case ROFFT_TEXT:
1.8 kristaps 105: p = n->string;
1.1 kristaps 106: break;
1.63 schwarze 107: case ROFFT_BODY:
1.1 kristaps 108: p = mdoc_macronames[n->tok];
109: break;
1.63 schwarze 110: case ROFFT_HEAD:
1.1 kristaps 111: p = mdoc_macronames[n->tok];
112: break;
1.63 schwarze 113: case ROFFT_TAIL:
1.1 kristaps 114: p = mdoc_macronames[n->tok];
115: break;
1.63 schwarze 116: case ROFFT_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.63 schwarze 123: case ROFFT_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.63 schwarze 130: case ROFFT_TBL:
1.59 schwarze 131: break;
1.63 schwarze 132: case ROFFT_EQN:
1.59 schwarze 133: p = "EQ";
1.33 kristaps 134: break;
1.63 schwarze 135: case ROFFT_ROOT:
1.1 kristaps 136: p = "root";
137: break;
138: default:
139: abort();
140: }
141:
1.26 kristaps 142: if (n->span) {
1.38 kristaps 143: assert(NULL == p && NULL == t);
1.30 kristaps 144: print_span(n->span, indent);
1.26 kristaps 145: } else {
1.30 kristaps 146: for (i = 0; i < indent; i++)
1.61 schwarze 147: putchar(' ');
1.30 kristaps 148:
1.26 kristaps 149: printf("%s (%s)", p, t);
150:
151: for (i = 0; i < (int)argc; i++) {
152: printf(" -%s", mdoc_argnames[argv[i].arg]);
153: if (argv[i].sz > 0)
154: printf(" [");
155: for (j = 0; j < (int)argv[i].sz; j++)
156: printf(" [%s]", argv[i].value[j]);
157: if (argv[i].sz > 0)
158: printf(" ]");
159: }
1.49 schwarze 160:
161: putchar(' ');
1.71 ! schwarze 162: if (NODE_DELIMO & n->flags)
1.68 schwarze 163: putchar('(');
1.71 ! schwarze 164: if (NODE_LINE & n->flags)
1.49 schwarze 165: putchar('*');
1.68 schwarze 166: printf("%d:%d", n->line, n->pos + 1);
1.71 ! schwarze 167: if (NODE_DELIMC & n->flags)
1.68 schwarze 168: putchar(')');
1.71 ! schwarze 169: if (NODE_EOS & n->flags)
1.68 schwarze 170: putchar('.');
1.70 schwarze 171: if (NODE_NOSRC & n->flags)
172: printf(" NOSRC");
173: if (NODE_NOPRT & n->flags)
174: printf(" NOPRT");
1.68 schwarze 175: putchar('\n');
1.1 kristaps 176: }
177:
1.59 schwarze 178: if (n->eqn)
1.61 schwarze 179: print_box(n->eqn->root->first, indent + 4);
1.1 kristaps 180: if (n->child)
1.61 schwarze 181: print_mdoc(n->child, indent +
1.63 schwarze 182: (n->type == ROFFT_BLOCK ? 2 : 4));
1.1 kristaps 183: if (n->next)
1.11 kristaps 184: print_mdoc(n->next, indent);
1.1 kristaps 185: }
1.2 kristaps 186:
1.10 kristaps 187: static void
1.64 schwarze 188: print_man(const struct roff_node *n, int indent)
1.10 kristaps 189: {
190: const char *p, *t;
191: int i;
192:
1.61 schwarze 193: if (n == NULL)
194: return;
195:
1.38 kristaps 196: t = p = NULL;
197:
1.10 kristaps 198: switch (n->type) {
1.63 schwarze 199: case ROFFT_ROOT:
1.10 kristaps 200: t = "root";
201: break;
1.63 schwarze 202: case ROFFT_ELEM:
1.10 kristaps 203: t = "elem";
204: break;
1.63 schwarze 205: case ROFFT_TEXT:
1.10 kristaps 206: t = "text";
207: break;
1.63 schwarze 208: case ROFFT_BLOCK:
1.14 kristaps 209: t = "block";
210: break;
1.63 schwarze 211: case ROFFT_HEAD:
1.68 schwarze 212: t = "head";
1.14 kristaps 213: break;
1.63 schwarze 214: case ROFFT_BODY:
1.68 schwarze 215: t = "body";
1.14 kristaps 216: break;
1.63 schwarze 217: case ROFFT_TBL:
1.59 schwarze 218: break;
1.63 schwarze 219: case ROFFT_EQN:
1.59 schwarze 220: t = "eqn";
1.33 kristaps 221: break;
1.10 kristaps 222: default:
223: abort();
224: }
225:
226: switch (n->type) {
1.63 schwarze 227: case ROFFT_TEXT:
1.10 kristaps 228: p = n->string;
229: break;
1.63 schwarze 230: case ROFFT_ELEM:
231: case ROFFT_BLOCK:
232: case ROFFT_HEAD:
233: case ROFFT_BODY:
1.10 kristaps 234: p = man_macronames[n->tok];
235: break;
1.63 schwarze 236: case ROFFT_ROOT:
1.10 kristaps 237: p = "root";
1.25 kristaps 238: break;
1.63 schwarze 239: case ROFFT_TBL:
1.59 schwarze 240: break;
1.63 schwarze 241: case ROFFT_EQN:
1.59 schwarze 242: p = "EQ";
1.10 kristaps 243: break;
244: default:
245: abort();
246: }
247:
1.26 kristaps 248: if (n->span) {
1.38 kristaps 249: assert(NULL == p && NULL == t);
1.30 kristaps 250: print_span(n->span, indent);
251: } else {
252: for (i = 0; i < indent; i++)
1.61 schwarze 253: putchar(' ');
1.51 schwarze 254: printf("%s (%s) ", p, t);
1.71 ! schwarze 255: if (NODE_LINE & n->flags)
1.51 schwarze 256: putchar('*');
1.68 schwarze 257: printf("%d:%d", n->line, n->pos + 1);
1.71 ! schwarze 258: if (NODE_EOS & n->flags)
1.68 schwarze 259: putchar('.');
260: putchar('\n');
1.30 kristaps 261: }
1.26 kristaps 262:
1.59 schwarze 263: if (n->eqn)
1.61 schwarze 264: print_box(n->eqn->root->first, indent + 4);
1.10 kristaps 265: if (n->child)
1.61 schwarze 266: print_man(n->child, indent +
1.63 schwarze 267: (n->type == ROFFT_BLOCK ? 2 : 4));
1.10 kristaps 268: if (n->next)
1.11 kristaps 269: print_man(n->next, indent);
1.28 kristaps 270: }
271:
272: static void
1.38 kristaps 273: print_box(const struct eqn_box *ep, int indent)
274: {
275: int i;
1.46 kristaps 276: const char *t;
1.38 kristaps 277:
1.57 schwarze 278: static const char *posnames[] = {
279: NULL, "sup", "subsup", "sub",
280: "to", "from", "fromto",
281: "over", "sqrt", NULL };
282:
1.38 kristaps 283: if (NULL == ep)
284: return;
285: for (i = 0; i < indent; i++)
1.61 schwarze 286: putchar(' ');
1.38 kristaps 287:
1.46 kristaps 288: t = NULL;
1.38 kristaps 289: switch (ep->type) {
1.52 schwarze 290: case EQN_ROOT:
1.46 kristaps 291: t = "eqn-root";
1.45 kristaps 292: break;
1.56 kristaps 293: case EQN_LISTONE:
1.52 schwarze 294: case EQN_LIST:
1.46 kristaps 295: t = "eqn-list";
1.39 kristaps 296: break;
1.52 schwarze 297: case EQN_SUBEXPR:
1.46 kristaps 298: t = "eqn-expr";
1.39 kristaps 299: break;
1.52 schwarze 300: case EQN_TEXT:
1.46 kristaps 301: t = "eqn-text";
1.39 kristaps 302: break;
1.56 kristaps 303: case EQN_PILE:
304: t = "eqn-pile";
305: break;
1.52 schwarze 306: case EQN_MATRIX:
1.46 kristaps 307: t = "eqn-matrix";
1.38 kristaps 308: break;
309: }
1.39 kristaps 310:
1.57 schwarze 311: fputs(t, stdout);
312: if (ep->pos)
313: printf(" pos=%s", posnames[ep->pos]);
314: if (ep->left)
315: printf(" left=\"%s\"", ep->left);
316: if (ep->right)
317: printf(" right=\"%s\"", ep->right);
318: if (ep->top)
319: printf(" top=\"%s\"", ep->top);
320: if (ep->bottom)
321: printf(" bottom=\"%s\"", ep->bottom);
322: if (ep->text)
323: printf(" text=\"%s\"", ep->text);
324: if (ep->font)
325: printf(" font=%d", ep->font);
326: if (ep->size != EQN_DEFSIZE)
327: printf(" size=%d", ep->size);
328: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
329: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
330: else if (ep->args)
331: printf(" args=%zu", ep->args);
332: putchar('\n');
1.46 kristaps 333:
1.61 schwarze 334: print_box(ep->first, indent + 4);
1.39 kristaps 335: print_box(ep->next, indent);
1.38 kristaps 336: }
337:
338: static void
1.30 kristaps 339: print_span(const struct tbl_span *sp, int indent)
1.28 kristaps 340: {
341: const struct tbl_dat *dp;
1.30 kristaps 342: int i;
343:
344: for (i = 0; i < indent; i++)
1.61 schwarze 345: putchar(' ');
1.28 kristaps 346:
347: switch (sp->pos) {
1.52 schwarze 348: case TBL_SPAN_HORIZ:
1.28 kristaps 349: putchar('-');
350: return;
1.52 schwarze 351: case TBL_SPAN_DHORIZ:
1.28 kristaps 352: putchar('=');
353: return;
354: default:
355: break;
356: }
357:
358: for (dp = sp->first; dp; dp = dp->next) {
359: switch (dp->pos) {
1.52 schwarze 360: case TBL_DATA_HORIZ:
361: case TBL_DATA_NHORIZ:
1.28 kristaps 362: putchar('-');
363: continue;
1.52 schwarze 364: case TBL_DATA_DHORIZ:
365: case TBL_DATA_NDHORIZ:
1.28 kristaps 366: putchar('=');
367: continue;
368: default:
369: break;
370: }
1.32 kristaps 371: printf("[\"%s\"", dp->string ? dp->string : "");
372: if (dp->spans)
373: printf("(%d)", dp->spans);
374: if (NULL == dp->layout)
375: putchar('*');
376: putchar(']');
1.34 kristaps 377: putchar(' ');
1.28 kristaps 378: }
1.34 kristaps 379:
1.38 kristaps 380: printf("(tbl) %d:1\n", sp->line);
1.10 kristaps 381: }
CVSweb