1*260e9a87SYuri Pankov /* $Id: tree.c,v 1.62 2015/02/05 00:14:13 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 3*260e9a87SYuri Pankov * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> 4*260e9a87SYuri Pankov * Copyright (c) 2013, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> 595c635efSGarrett D'Amore * 695c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 795c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 895c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 995c635efSGarrett D'Amore * 1095c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1195c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1295c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1395c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1495c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1595c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1695c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1795c635efSGarrett D'Amore */ 1895c635efSGarrett D'Amore #include "config.h" 19*260e9a87SYuri Pankov 20*260e9a87SYuri Pankov #include <sys/types.h> 2195c635efSGarrett D'Amore 2295c635efSGarrett D'Amore #include <assert.h> 2395c635efSGarrett D'Amore #include <limits.h> 2495c635efSGarrett D'Amore #include <stdio.h> 2595c635efSGarrett D'Amore #include <stdlib.h> 2695c635efSGarrett D'Amore #include <time.h> 2795c635efSGarrett D'Amore 2895c635efSGarrett D'Amore #include "mandoc.h" 2995c635efSGarrett D'Amore #include "mdoc.h" 3095c635efSGarrett D'Amore #include "man.h" 3195c635efSGarrett D'Amore #include "main.h" 3295c635efSGarrett D'Amore 3395c635efSGarrett D'Amore static void print_box(const struct eqn_box *, int); 3495c635efSGarrett D'Amore static void print_man(const struct man_node *, int); 3595c635efSGarrett D'Amore static void print_mdoc(const struct mdoc_node *, int); 3695c635efSGarrett D'Amore static void print_span(const struct tbl_span *, int); 3795c635efSGarrett D'Amore 3895c635efSGarrett D'Amore 3995c635efSGarrett D'Amore void 4095c635efSGarrett D'Amore tree_mdoc(void *arg, const struct mdoc *mdoc) 4195c635efSGarrett D'Amore { 4295c635efSGarrett D'Amore 43*260e9a87SYuri Pankov print_mdoc(mdoc_node(mdoc)->child, 0); 4495c635efSGarrett D'Amore } 4595c635efSGarrett D'Amore 4695c635efSGarrett D'Amore void 4795c635efSGarrett D'Amore tree_man(void *arg, const struct man *man) 4895c635efSGarrett D'Amore { 4995c635efSGarrett D'Amore 50*260e9a87SYuri Pankov print_man(man_node(man)->child, 0); 5195c635efSGarrett D'Amore } 5295c635efSGarrett D'Amore 5395c635efSGarrett D'Amore static void 5495c635efSGarrett D'Amore print_mdoc(const struct mdoc_node *n, int indent) 5595c635efSGarrett D'Amore { 5695c635efSGarrett D'Amore const char *p, *t; 5795c635efSGarrett D'Amore int i, j; 58698f87a4SGarrett D'Amore size_t argc; 5995c635efSGarrett D'Amore struct mdoc_argv *argv; 6095c635efSGarrett D'Amore 61*260e9a87SYuri Pankov if (n == NULL) 62*260e9a87SYuri Pankov return; 63*260e9a87SYuri Pankov 6495c635efSGarrett D'Amore argv = NULL; 65698f87a4SGarrett D'Amore argc = 0; 6695c635efSGarrett D'Amore t = p = NULL; 6795c635efSGarrett D'Amore 6895c635efSGarrett D'Amore switch (n->type) { 69*260e9a87SYuri Pankov case MDOC_ROOT: 7095c635efSGarrett D'Amore t = "root"; 7195c635efSGarrett D'Amore break; 72*260e9a87SYuri Pankov case MDOC_BLOCK: 7395c635efSGarrett D'Amore t = "block"; 7495c635efSGarrett D'Amore break; 75*260e9a87SYuri Pankov case MDOC_HEAD: 7695c635efSGarrett D'Amore t = "block-head"; 7795c635efSGarrett D'Amore break; 78*260e9a87SYuri Pankov case MDOC_BODY: 7995c635efSGarrett D'Amore if (n->end) 8095c635efSGarrett D'Amore t = "body-end"; 8195c635efSGarrett D'Amore else 8295c635efSGarrett D'Amore t = "block-body"; 8395c635efSGarrett D'Amore break; 84*260e9a87SYuri Pankov case MDOC_TAIL: 8595c635efSGarrett D'Amore t = "block-tail"; 8695c635efSGarrett D'Amore break; 87*260e9a87SYuri Pankov case MDOC_ELEM: 8895c635efSGarrett D'Amore t = "elem"; 8995c635efSGarrett D'Amore break; 90*260e9a87SYuri Pankov case MDOC_TEXT: 9195c635efSGarrett D'Amore t = "text"; 9295c635efSGarrett D'Amore break; 93*260e9a87SYuri Pankov case MDOC_TBL: 94*260e9a87SYuri Pankov break; 95*260e9a87SYuri Pankov case MDOC_EQN: 96*260e9a87SYuri Pankov t = "eqn"; 9795c635efSGarrett D'Amore break; 9895c635efSGarrett D'Amore default: 9995c635efSGarrett D'Amore abort(); 10095c635efSGarrett D'Amore /* NOTREACHED */ 10195c635efSGarrett D'Amore } 10295c635efSGarrett D'Amore 10395c635efSGarrett D'Amore switch (n->type) { 104*260e9a87SYuri Pankov case MDOC_TEXT: 10595c635efSGarrett D'Amore p = n->string; 10695c635efSGarrett D'Amore break; 107*260e9a87SYuri Pankov case MDOC_BODY: 10895c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 10995c635efSGarrett D'Amore break; 110*260e9a87SYuri Pankov case MDOC_HEAD: 11195c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 11295c635efSGarrett D'Amore break; 113*260e9a87SYuri Pankov case MDOC_TAIL: 11495c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 11595c635efSGarrett D'Amore break; 116*260e9a87SYuri Pankov case MDOC_ELEM: 11795c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 11895c635efSGarrett D'Amore if (n->args) { 11995c635efSGarrett D'Amore argv = n->args->argv; 12095c635efSGarrett D'Amore argc = n->args->argc; 12195c635efSGarrett D'Amore } 12295c635efSGarrett D'Amore break; 123*260e9a87SYuri Pankov case MDOC_BLOCK: 12495c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 12595c635efSGarrett D'Amore if (n->args) { 12695c635efSGarrett D'Amore argv = n->args->argv; 12795c635efSGarrett D'Amore argc = n->args->argc; 12895c635efSGarrett D'Amore } 12995c635efSGarrett D'Amore break; 130*260e9a87SYuri Pankov case MDOC_TBL: 13195c635efSGarrett D'Amore break; 132*260e9a87SYuri Pankov case MDOC_EQN: 133*260e9a87SYuri Pankov p = "EQ"; 134*260e9a87SYuri Pankov break; 135*260e9a87SYuri Pankov case MDOC_ROOT: 13695c635efSGarrett D'Amore p = "root"; 13795c635efSGarrett D'Amore break; 13895c635efSGarrett D'Amore default: 13995c635efSGarrett D'Amore abort(); 14095c635efSGarrett D'Amore /* NOTREACHED */ 14195c635efSGarrett D'Amore } 14295c635efSGarrett D'Amore 14395c635efSGarrett D'Amore if (n->span) { 14495c635efSGarrett D'Amore assert(NULL == p && NULL == t); 14595c635efSGarrett D'Amore print_span(n->span, indent); 14695c635efSGarrett D'Amore } else { 14795c635efSGarrett D'Amore for (i = 0; i < indent; i++) 148*260e9a87SYuri Pankov putchar(' '); 14995c635efSGarrett D'Amore 15095c635efSGarrett D'Amore printf("%s (%s)", p, t); 15195c635efSGarrett D'Amore 15295c635efSGarrett D'Amore for (i = 0; i < (int)argc; i++) { 15395c635efSGarrett D'Amore printf(" -%s", mdoc_argnames[argv[i].arg]); 15495c635efSGarrett D'Amore if (argv[i].sz > 0) 15595c635efSGarrett D'Amore printf(" ["); 15695c635efSGarrett D'Amore for (j = 0; j < (int)argv[i].sz; j++) 15795c635efSGarrett D'Amore printf(" [%s]", argv[i].value[j]); 15895c635efSGarrett D'Amore if (argv[i].sz > 0) 15995c635efSGarrett D'Amore printf(" ]"); 16095c635efSGarrett D'Amore } 16195c635efSGarrett D'Amore 162698f87a4SGarrett D'Amore putchar(' '); 163698f87a4SGarrett D'Amore if (MDOC_LINE & n->flags) 164698f87a4SGarrett D'Amore putchar('*'); 165*260e9a87SYuri Pankov printf("%d:%d\n", n->line, n->pos + 1); 16695c635efSGarrett D'Amore } 16795c635efSGarrett D'Amore 168*260e9a87SYuri Pankov if (n->eqn) 169*260e9a87SYuri Pankov print_box(n->eqn->root->first, indent + 4); 17095c635efSGarrett D'Amore if (n->child) 171*260e9a87SYuri Pankov print_mdoc(n->child, indent + 172*260e9a87SYuri Pankov (n->type == MDOC_BLOCK ? 2 : 4)); 17395c635efSGarrett D'Amore if (n->next) 17495c635efSGarrett D'Amore print_mdoc(n->next, indent); 17595c635efSGarrett D'Amore } 17695c635efSGarrett D'Amore 17795c635efSGarrett D'Amore static void 17895c635efSGarrett D'Amore print_man(const struct man_node *n, int indent) 17995c635efSGarrett D'Amore { 18095c635efSGarrett D'Amore const char *p, *t; 18195c635efSGarrett D'Amore int i; 18295c635efSGarrett D'Amore 183*260e9a87SYuri Pankov if (n == NULL) 184*260e9a87SYuri Pankov return; 185*260e9a87SYuri Pankov 18695c635efSGarrett D'Amore t = p = NULL; 18795c635efSGarrett D'Amore 18895c635efSGarrett D'Amore switch (n->type) { 189*260e9a87SYuri Pankov case MAN_ROOT: 19095c635efSGarrett D'Amore t = "root"; 19195c635efSGarrett D'Amore break; 192*260e9a87SYuri Pankov case MAN_ELEM: 19395c635efSGarrett D'Amore t = "elem"; 19495c635efSGarrett D'Amore break; 195*260e9a87SYuri Pankov case MAN_TEXT: 19695c635efSGarrett D'Amore t = "text"; 19795c635efSGarrett D'Amore break; 198*260e9a87SYuri Pankov case MAN_BLOCK: 19995c635efSGarrett D'Amore t = "block"; 20095c635efSGarrett D'Amore break; 201*260e9a87SYuri Pankov case MAN_HEAD: 20295c635efSGarrett D'Amore t = "block-head"; 20395c635efSGarrett D'Amore break; 204*260e9a87SYuri Pankov case MAN_BODY: 20595c635efSGarrett D'Amore t = "block-body"; 20695c635efSGarrett D'Amore break; 207*260e9a87SYuri Pankov case MAN_TBL: 20895c635efSGarrett D'Amore break; 209*260e9a87SYuri Pankov case MAN_EQN: 210*260e9a87SYuri Pankov t = "eqn"; 21195c635efSGarrett D'Amore break; 21295c635efSGarrett D'Amore default: 21395c635efSGarrett D'Amore abort(); 21495c635efSGarrett D'Amore /* NOTREACHED */ 21595c635efSGarrett D'Amore } 21695c635efSGarrett D'Amore 21795c635efSGarrett D'Amore switch (n->type) { 218*260e9a87SYuri Pankov case MAN_TEXT: 21995c635efSGarrett D'Amore p = n->string; 22095c635efSGarrett D'Amore break; 221*260e9a87SYuri Pankov case MAN_ELEM: 22295c635efSGarrett D'Amore /* FALLTHROUGH */ 223*260e9a87SYuri Pankov case MAN_BLOCK: 22495c635efSGarrett D'Amore /* FALLTHROUGH */ 225*260e9a87SYuri Pankov case MAN_HEAD: 22695c635efSGarrett D'Amore /* FALLTHROUGH */ 227*260e9a87SYuri Pankov case MAN_BODY: 22895c635efSGarrett D'Amore p = man_macronames[n->tok]; 22995c635efSGarrett D'Amore break; 230*260e9a87SYuri Pankov case MAN_ROOT: 23195c635efSGarrett D'Amore p = "root"; 23295c635efSGarrett D'Amore break; 233*260e9a87SYuri Pankov case MAN_TBL: 234*260e9a87SYuri Pankov break; 235*260e9a87SYuri Pankov case MAN_EQN: 236*260e9a87SYuri Pankov p = "EQ"; 23795c635efSGarrett D'Amore break; 23895c635efSGarrett D'Amore default: 23995c635efSGarrett D'Amore abort(); 24095c635efSGarrett D'Amore /* NOTREACHED */ 24195c635efSGarrett D'Amore } 24295c635efSGarrett D'Amore 24395c635efSGarrett D'Amore if (n->span) { 24495c635efSGarrett D'Amore assert(NULL == p && NULL == t); 24595c635efSGarrett D'Amore print_span(n->span, indent); 24695c635efSGarrett D'Amore } else { 24795c635efSGarrett D'Amore for (i = 0; i < indent; i++) 248*260e9a87SYuri Pankov putchar(' '); 249*260e9a87SYuri Pankov printf("%s (%s) ", p, t); 250*260e9a87SYuri Pankov if (MAN_LINE & n->flags) 251*260e9a87SYuri Pankov putchar('*'); 252*260e9a87SYuri Pankov printf("%d:%d\n", n->line, n->pos + 1); 25395c635efSGarrett D'Amore } 25495c635efSGarrett D'Amore 255*260e9a87SYuri Pankov if (n->eqn) 256*260e9a87SYuri Pankov print_box(n->eqn->root->first, indent + 4); 25795c635efSGarrett D'Amore if (n->child) 258*260e9a87SYuri Pankov print_man(n->child, indent + 259*260e9a87SYuri Pankov (n->type == MAN_BLOCK ? 2 : 4)); 26095c635efSGarrett D'Amore if (n->next) 26195c635efSGarrett D'Amore print_man(n->next, indent); 26295c635efSGarrett D'Amore } 26395c635efSGarrett D'Amore 26495c635efSGarrett D'Amore static void 26595c635efSGarrett D'Amore print_box(const struct eqn_box *ep, int indent) 26695c635efSGarrett D'Amore { 26795c635efSGarrett D'Amore int i; 26895c635efSGarrett D'Amore const char *t; 26995c635efSGarrett D'Amore 270*260e9a87SYuri Pankov static const char *posnames[] = { 271*260e9a87SYuri Pankov NULL, "sup", "subsup", "sub", 272*260e9a87SYuri Pankov "to", "from", "fromto", 273*260e9a87SYuri Pankov "over", "sqrt", NULL }; 274*260e9a87SYuri Pankov 27595c635efSGarrett D'Amore if (NULL == ep) 27695c635efSGarrett D'Amore return; 27795c635efSGarrett D'Amore for (i = 0; i < indent; i++) 278*260e9a87SYuri Pankov putchar(' '); 27995c635efSGarrett D'Amore 28095c635efSGarrett D'Amore t = NULL; 28195c635efSGarrett D'Amore switch (ep->type) { 282*260e9a87SYuri Pankov case EQN_ROOT: 28395c635efSGarrett D'Amore t = "eqn-root"; 28495c635efSGarrett D'Amore break; 285*260e9a87SYuri Pankov case EQN_LISTONE: 286*260e9a87SYuri Pankov case EQN_LIST: 28795c635efSGarrett D'Amore t = "eqn-list"; 28895c635efSGarrett D'Amore break; 289*260e9a87SYuri Pankov case EQN_SUBEXPR: 29095c635efSGarrett D'Amore t = "eqn-expr"; 29195c635efSGarrett D'Amore break; 292*260e9a87SYuri Pankov case EQN_TEXT: 29395c635efSGarrett D'Amore t = "eqn-text"; 29495c635efSGarrett D'Amore break; 295*260e9a87SYuri Pankov case EQN_PILE: 296*260e9a87SYuri Pankov t = "eqn-pile"; 297*260e9a87SYuri Pankov break; 298*260e9a87SYuri Pankov case EQN_MATRIX: 29995c635efSGarrett D'Amore t = "eqn-matrix"; 30095c635efSGarrett D'Amore break; 30195c635efSGarrett D'Amore } 30295c635efSGarrett D'Amore 303*260e9a87SYuri Pankov fputs(t, stdout); 304*260e9a87SYuri Pankov if (ep->pos) 305*260e9a87SYuri Pankov printf(" pos=%s", posnames[ep->pos]); 306*260e9a87SYuri Pankov if (ep->left) 307*260e9a87SYuri Pankov printf(" left=\"%s\"", ep->left); 308*260e9a87SYuri Pankov if (ep->right) 309*260e9a87SYuri Pankov printf(" right=\"%s\"", ep->right); 310*260e9a87SYuri Pankov if (ep->top) 311*260e9a87SYuri Pankov printf(" top=\"%s\"", ep->top); 312*260e9a87SYuri Pankov if (ep->bottom) 313*260e9a87SYuri Pankov printf(" bottom=\"%s\"", ep->bottom); 314*260e9a87SYuri Pankov if (ep->text) 315*260e9a87SYuri Pankov printf(" text=\"%s\"", ep->text); 316*260e9a87SYuri Pankov if (ep->font) 317*260e9a87SYuri Pankov printf(" font=%d", ep->font); 318*260e9a87SYuri Pankov if (ep->size != EQN_DEFSIZE) 319*260e9a87SYuri Pankov printf(" size=%d", ep->size); 320*260e9a87SYuri Pankov if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args) 321*260e9a87SYuri Pankov printf(" badargs=%zu(%zu)", ep->args, ep->expectargs); 322*260e9a87SYuri Pankov else if (ep->args) 323*260e9a87SYuri Pankov printf(" args=%zu", ep->args); 324*260e9a87SYuri Pankov putchar('\n'); 32595c635efSGarrett D'Amore 326*260e9a87SYuri Pankov print_box(ep->first, indent + 4); 32795c635efSGarrett D'Amore print_box(ep->next, indent); 32895c635efSGarrett D'Amore } 32995c635efSGarrett D'Amore 33095c635efSGarrett D'Amore static void 33195c635efSGarrett D'Amore print_span(const struct tbl_span *sp, int indent) 33295c635efSGarrett D'Amore { 33395c635efSGarrett D'Amore const struct tbl_dat *dp; 33495c635efSGarrett D'Amore int i; 33595c635efSGarrett D'Amore 33695c635efSGarrett D'Amore for (i = 0; i < indent; i++) 337*260e9a87SYuri Pankov putchar(' '); 33895c635efSGarrett D'Amore 33995c635efSGarrett D'Amore switch (sp->pos) { 340*260e9a87SYuri Pankov case TBL_SPAN_HORIZ: 34195c635efSGarrett D'Amore putchar('-'); 34295c635efSGarrett D'Amore return; 343*260e9a87SYuri Pankov case TBL_SPAN_DHORIZ: 34495c635efSGarrett D'Amore putchar('='); 34595c635efSGarrett D'Amore return; 34695c635efSGarrett D'Amore default: 34795c635efSGarrett D'Amore break; 34895c635efSGarrett D'Amore } 34995c635efSGarrett D'Amore 35095c635efSGarrett D'Amore for (dp = sp->first; dp; dp = dp->next) { 35195c635efSGarrett D'Amore switch (dp->pos) { 352*260e9a87SYuri Pankov case TBL_DATA_HORIZ: 35395c635efSGarrett D'Amore /* FALLTHROUGH */ 354*260e9a87SYuri Pankov case TBL_DATA_NHORIZ: 35595c635efSGarrett D'Amore putchar('-'); 35695c635efSGarrett D'Amore continue; 357*260e9a87SYuri Pankov case TBL_DATA_DHORIZ: 35895c635efSGarrett D'Amore /* FALLTHROUGH */ 359*260e9a87SYuri Pankov case TBL_DATA_NDHORIZ: 36095c635efSGarrett D'Amore putchar('='); 36195c635efSGarrett D'Amore continue; 36295c635efSGarrett D'Amore default: 36395c635efSGarrett D'Amore break; 36495c635efSGarrett D'Amore } 36595c635efSGarrett D'Amore printf("[\"%s\"", dp->string ? dp->string : ""); 36695c635efSGarrett D'Amore if (dp->spans) 36795c635efSGarrett D'Amore printf("(%d)", dp->spans); 36895c635efSGarrett D'Amore if (NULL == dp->layout) 36995c635efSGarrett D'Amore putchar('*'); 37095c635efSGarrett D'Amore putchar(']'); 37195c635efSGarrett D'Amore putchar(' '); 37295c635efSGarrett D'Amore } 37395c635efSGarrett D'Amore 37495c635efSGarrett D'Amore printf("(tbl) %d:1\n", sp->line); 37595c635efSGarrett D'Amore } 376