Annotation of mandoc/tree.c, Revision 1.84
1.84 ! schwarze 1: /* $Id: tree.c,v 1.83 2018/12/30 00:49:56 schwarze Exp $ */
1.1 kristaps 2: /*
1.58 schwarze 3: * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.84 ! schwarze 4: * Copyright (c) 2013-2015, 2017-2019 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.81 schwarze 32: #include "tbl.h"
1.82 schwarze 33: #include "eqn.h"
1.16 kristaps 34: #include "main.h"
1.1 kristaps 35:
1.38 kristaps 36: static void print_box(const struct eqn_box *, int);
1.64 schwarze 37: static void print_man(const struct roff_node *, int);
1.72 schwarze 38: static void print_meta(const struct roff_meta *);
1.64 schwarze 39: static void print_mdoc(const struct roff_node *, int);
1.30 kristaps 40: static void print_span(const struct tbl_span *, int);
1.8 kristaps 41:
42:
1.15 kristaps 43: void
1.83 schwarze 44: tree_mdoc(void *arg, const struct roff_meta *mdoc)
1.8 kristaps 45: {
1.83 schwarze 46: print_meta(mdoc);
1.72 schwarze 47: putchar('\n');
1.66 schwarze 48: print_mdoc(mdoc->first->child, 0);
1.11 kristaps 49: }
50:
1.15 kristaps 51: void
1.83 schwarze 52: tree_man(void *arg, const struct roff_meta *man)
1.11 kristaps 53: {
1.83 schwarze 54: print_meta(man);
55: if (man->hasbody == 0)
1.72 schwarze 56: puts("body = empty");
57: putchar('\n');
58: print_man(man->first->child, 0);
59: }
1.11 kristaps 60:
1.72 schwarze 61: static void
62: print_meta(const struct roff_meta *meta)
63: {
64: if (meta->title != NULL)
65: printf("title = \"%s\"\n", meta->title);
66: if (meta->name != NULL)
67: printf("name = \"%s\"\n", meta->name);
68: if (meta->msec != NULL)
69: printf("sec = \"%s\"\n", meta->msec);
70: if (meta->vol != NULL)
71: printf("vol = \"%s\"\n", meta->vol);
72: if (meta->arch != NULL)
73: printf("arch = \"%s\"\n", meta->arch);
74: if (meta->os != NULL)
75: printf("os = \"%s\"\n", meta->os);
76: if (meta->date != NULL)
77: printf("date = \"%s\"\n", meta->date);
1.8 kristaps 78: }
1.2 kristaps 79:
1.1 kristaps 80: static void
1.64 schwarze 81: print_mdoc(const struct roff_node *n, int indent)
1.1 kristaps 82: {
83: const char *p, *t;
84: int i, j;
1.48 schwarze 85: size_t argc;
1.8 kristaps 86: struct mdoc_argv *argv;
1.1 kristaps 87:
1.61 schwarze 88: if (n == NULL)
89: return;
90:
1.1 kristaps 91: argv = NULL;
1.48 schwarze 92: argc = 0;
1.38 kristaps 93: t = p = NULL;
1.1 kristaps 94:
1.2 kristaps 95: switch (n->type) {
1.63 schwarze 96: case ROFFT_ROOT:
1.2 kristaps 97: t = "root";
98: break;
1.63 schwarze 99: case ROFFT_BLOCK:
1.2 kristaps 100: t = "block";
101: break;
1.63 schwarze 102: case ROFFT_HEAD:
1.68 schwarze 103: t = "head";
1.2 kristaps 104: break;
1.63 schwarze 105: case ROFFT_BODY:
1.23 schwarze 106: if (n->end)
107: t = "body-end";
108: else
1.68 schwarze 109: t = "body";
1.2 kristaps 110: break;
1.63 schwarze 111: case ROFFT_TAIL:
1.68 schwarze 112: t = "tail";
1.2 kristaps 113: break;
1.63 schwarze 114: case ROFFT_ELEM:
1.2 kristaps 115: t = "elem";
116: break;
1.63 schwarze 117: case ROFFT_TEXT:
1.2 kristaps 118: t = "text";
119: break;
1.78 schwarze 120: case ROFFT_COMMENT:
121: t = "comment";
122: break;
1.63 schwarze 123: case ROFFT_TBL:
1.59 schwarze 124: break;
1.63 schwarze 125: case ROFFT_EQN:
1.59 schwarze 126: t = "eqn";
1.33 kristaps 127: break;
1.2 kristaps 128: default:
129: abort();
130: }
1.1 kristaps 131:
132: switch (n->type) {
1.63 schwarze 133: case ROFFT_TEXT:
1.78 schwarze 134: case ROFFT_COMMENT:
1.8 kristaps 135: p = n->string;
1.1 kristaps 136: break;
1.63 schwarze 137: case ROFFT_BODY:
1.74 schwarze 138: p = roff_name[n->tok];
1.1 kristaps 139: break;
1.63 schwarze 140: case ROFFT_HEAD:
1.74 schwarze 141: p = roff_name[n->tok];
1.1 kristaps 142: break;
1.63 schwarze 143: case ROFFT_TAIL:
1.74 schwarze 144: p = roff_name[n->tok];
1.1 kristaps 145: break;
1.63 schwarze 146: case ROFFT_ELEM:
1.74 schwarze 147: p = roff_name[n->tok];
1.8 kristaps 148: if (n->args) {
149: argv = n->args->argv;
150: argc = n->args->argc;
151: }
1.1 kristaps 152: break;
1.63 schwarze 153: case ROFFT_BLOCK:
1.74 schwarze 154: p = roff_name[n->tok];
1.8 kristaps 155: if (n->args) {
156: argv = n->args->argv;
157: argc = n->args->argc;
158: }
1.1 kristaps 159: break;
1.63 schwarze 160: case ROFFT_TBL:
1.59 schwarze 161: break;
1.63 schwarze 162: case ROFFT_EQN:
1.59 schwarze 163: p = "EQ";
1.33 kristaps 164: break;
1.63 schwarze 165: case ROFFT_ROOT:
1.1 kristaps 166: p = "root";
167: break;
168: default:
169: abort();
170: }
171:
1.26 kristaps 172: if (n->span) {
1.38 kristaps 173: assert(NULL == p && NULL == t);
1.30 kristaps 174: print_span(n->span, indent);
1.26 kristaps 175: } else {
1.30 kristaps 176: for (i = 0; i < indent; i++)
1.61 schwarze 177: putchar(' ');
1.30 kristaps 178:
1.26 kristaps 179: printf("%s (%s)", p, t);
180:
181: for (i = 0; i < (int)argc; i++) {
182: printf(" -%s", mdoc_argnames[argv[i].arg]);
183: if (argv[i].sz > 0)
184: printf(" [");
185: for (j = 0; j < (int)argv[i].sz; j++)
186: printf(" [%s]", argv[i].value[j]);
187: if (argv[i].sz > 0)
188: printf(" ]");
189: }
1.49 schwarze 190:
191: putchar(' ');
1.84 ! schwarze 192: if (n->flags & NODE_DELIMO)
1.68 schwarze 193: putchar('(');
1.84 ! schwarze 194: if (n->flags & NODE_LINE)
1.49 schwarze 195: putchar('*');
1.68 schwarze 196: printf("%d:%d", n->line, n->pos + 1);
1.84 ! schwarze 197: if (n->flags & NODE_DELIMC)
1.68 schwarze 198: putchar(')');
1.84 ! schwarze 199: if (n->flags & NODE_EOS)
1.68 schwarze 200: putchar('.');
1.84 ! schwarze 201: if (n->flags & NODE_BROKEN)
1.73 schwarze 202: printf(" BROKEN");
1.84 ! schwarze 203: if (n->flags & NODE_NOFILL)
! 204: printf(" NOFILL");
! 205: if (n->flags & NODE_NOSRC)
1.70 schwarze 206: printf(" NOSRC");
1.84 ! schwarze 207: if (n->flags & NODE_NOPRT)
1.70 schwarze 208: printf(" NOPRT");
1.68 schwarze 209: putchar('\n');
1.1 kristaps 210: }
211:
1.59 schwarze 212: if (n->eqn)
1.77 schwarze 213: print_box(n->eqn->first, indent + 4);
1.1 kristaps 214: if (n->child)
1.61 schwarze 215: print_mdoc(n->child, indent +
1.63 schwarze 216: (n->type == ROFFT_BLOCK ? 2 : 4));
1.1 kristaps 217: if (n->next)
1.11 kristaps 218: print_mdoc(n->next, indent);
1.1 kristaps 219: }
1.2 kristaps 220:
1.10 kristaps 221: static void
1.64 schwarze 222: print_man(const struct roff_node *n, int indent)
1.10 kristaps 223: {
224: const char *p, *t;
225: int i;
226:
1.61 schwarze 227: if (n == NULL)
228: return;
229:
1.38 kristaps 230: t = p = NULL;
231:
1.10 kristaps 232: switch (n->type) {
1.63 schwarze 233: case ROFFT_ROOT:
1.10 kristaps 234: t = "root";
235: break;
1.63 schwarze 236: case ROFFT_ELEM:
1.10 kristaps 237: t = "elem";
238: break;
1.63 schwarze 239: case ROFFT_TEXT:
1.10 kristaps 240: t = "text";
241: break;
1.78 schwarze 242: case ROFFT_COMMENT:
243: t = "comment";
244: break;
1.63 schwarze 245: case ROFFT_BLOCK:
1.14 kristaps 246: t = "block";
247: break;
1.63 schwarze 248: case ROFFT_HEAD:
1.68 schwarze 249: t = "head";
1.14 kristaps 250: break;
1.63 schwarze 251: case ROFFT_BODY:
1.68 schwarze 252: t = "body";
1.14 kristaps 253: break;
1.63 schwarze 254: case ROFFT_TBL:
1.59 schwarze 255: break;
1.63 schwarze 256: case ROFFT_EQN:
1.59 schwarze 257: t = "eqn";
1.33 kristaps 258: break;
1.10 kristaps 259: default:
260: abort();
261: }
262:
263: switch (n->type) {
1.63 schwarze 264: case ROFFT_TEXT:
1.78 schwarze 265: case ROFFT_COMMENT:
1.10 kristaps 266: p = n->string;
267: break;
1.63 schwarze 268: case ROFFT_ELEM:
269: case ROFFT_BLOCK:
270: case ROFFT_HEAD:
271: case ROFFT_BODY:
1.74 schwarze 272: p = roff_name[n->tok];
1.10 kristaps 273: break;
1.63 schwarze 274: case ROFFT_ROOT:
1.10 kristaps 275: p = "root";
1.25 kristaps 276: break;
1.63 schwarze 277: case ROFFT_TBL:
1.59 schwarze 278: break;
1.63 schwarze 279: case ROFFT_EQN:
1.59 schwarze 280: p = "EQ";
1.10 kristaps 281: break;
282: default:
283: abort();
284: }
285:
1.26 kristaps 286: if (n->span) {
1.38 kristaps 287: assert(NULL == p && NULL == t);
1.30 kristaps 288: print_span(n->span, indent);
289: } else {
290: for (i = 0; i < indent; i++)
1.61 schwarze 291: putchar(' ');
1.51 schwarze 292: printf("%s (%s) ", p, t);
1.84 ! schwarze 293: if (n->flags & NODE_LINE)
1.51 schwarze 294: putchar('*');
1.68 schwarze 295: printf("%d:%d", n->line, n->pos + 1);
1.84 ! schwarze 296: if (n->flags & NODE_DELIMC)
1.79 schwarze 297: putchar(')');
1.84 ! schwarze 298: if (n->flags & NODE_EOS)
1.68 schwarze 299: putchar('.');
1.84 ! schwarze 300: if (n->flags & NODE_NOFILL)
! 301: printf(" NOFILL");
1.68 schwarze 302: putchar('\n');
1.30 kristaps 303: }
1.26 kristaps 304:
1.59 schwarze 305: if (n->eqn)
1.77 schwarze 306: print_box(n->eqn->first, indent + 4);
1.10 kristaps 307: if (n->child)
1.61 schwarze 308: print_man(n->child, indent +
1.63 schwarze 309: (n->type == ROFFT_BLOCK ? 2 : 4));
1.10 kristaps 310: if (n->next)
1.11 kristaps 311: print_man(n->next, indent);
1.28 kristaps 312: }
313:
314: static void
1.38 kristaps 315: print_box(const struct eqn_box *ep, int indent)
316: {
317: int i;
1.46 kristaps 318: const char *t;
1.38 kristaps 319:
1.57 schwarze 320: static const char *posnames[] = {
321: NULL, "sup", "subsup", "sub",
322: "to", "from", "fromto",
323: "over", "sqrt", NULL };
324:
1.38 kristaps 325: if (NULL == ep)
326: return;
327: for (i = 0; i < indent; i++)
1.61 schwarze 328: putchar(' ');
1.38 kristaps 329:
1.46 kristaps 330: t = NULL;
1.38 kristaps 331: switch (ep->type) {
1.52 schwarze 332: case EQN_LIST:
1.46 kristaps 333: t = "eqn-list";
1.39 kristaps 334: break;
1.52 schwarze 335: case EQN_SUBEXPR:
1.46 kristaps 336: t = "eqn-expr";
1.39 kristaps 337: break;
1.52 schwarze 338: case EQN_TEXT:
1.46 kristaps 339: t = "eqn-text";
1.39 kristaps 340: break;
1.56 kristaps 341: case EQN_PILE:
342: t = "eqn-pile";
343: break;
1.52 schwarze 344: case EQN_MATRIX:
1.46 kristaps 345: t = "eqn-matrix";
1.38 kristaps 346: break;
347: }
1.39 kristaps 348:
1.57 schwarze 349: fputs(t, stdout);
350: if (ep->pos)
351: printf(" pos=%s", posnames[ep->pos]);
352: if (ep->left)
353: printf(" left=\"%s\"", ep->left);
354: if (ep->right)
355: printf(" right=\"%s\"", ep->right);
356: if (ep->top)
357: printf(" top=\"%s\"", ep->top);
358: if (ep->bottom)
359: printf(" bottom=\"%s\"", ep->bottom);
360: if (ep->text)
361: printf(" text=\"%s\"", ep->text);
362: if (ep->font)
363: printf(" font=%d", ep->font);
364: if (ep->size != EQN_DEFSIZE)
365: printf(" size=%d", ep->size);
366: if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args)
367: printf(" badargs=%zu(%zu)", ep->args, ep->expectargs);
368: else if (ep->args)
369: printf(" args=%zu", ep->args);
370: putchar('\n');
1.46 kristaps 371:
1.61 schwarze 372: print_box(ep->first, indent + 4);
1.39 kristaps 373: print_box(ep->next, indent);
1.38 kristaps 374: }
375:
376: static void
1.30 kristaps 377: print_span(const struct tbl_span *sp, int indent)
1.28 kristaps 378: {
379: const struct tbl_dat *dp;
1.30 kristaps 380: int i;
381:
382: for (i = 0; i < indent; i++)
1.61 schwarze 383: putchar(' ');
1.28 kristaps 384:
385: switch (sp->pos) {
1.52 schwarze 386: case TBL_SPAN_HORIZ:
1.28 kristaps 387: putchar('-');
1.80 schwarze 388: putchar(' ');
389: break;
1.52 schwarze 390: case TBL_SPAN_DHORIZ:
1.28 kristaps 391: putchar('=');
1.80 schwarze 392: putchar(' ');
393: break;
1.28 kristaps 394: default:
1.80 schwarze 395: for (dp = sp->first; dp; dp = dp->next) {
396: switch (dp->pos) {
397: case TBL_DATA_HORIZ:
398: case TBL_DATA_NHORIZ:
399: putchar('-');
400: putchar(' ');
401: continue;
402: case TBL_DATA_DHORIZ:
403: case TBL_DATA_NDHORIZ:
404: putchar('=');
405: putchar(' ');
406: continue;
407: default:
408: break;
409: }
410: printf("[\"%s\"", dp->string ? dp->string : "");
411: if (dp->hspans)
412: printf(">%d", dp->hspans);
413: if (dp->vspans)
414: printf("v%d", dp->vspans);
415: if (dp->layout == NULL)
416: putchar('*');
417: else if (dp->layout->pos == TBL_CELL_DOWN)
418: putchar('^');
419: putchar(']');
420: putchar(' ');
421: }
1.28 kristaps 422: break;
423: }
1.38 kristaps 424: printf("(tbl) %d:1\n", sp->line);
1.10 kristaps 425: }
CVSweb