1*95c635efSGarrett D'Amore /* $Id: tree.c,v 1.47 2011/09/18 14:14:15 schwarze Exp $ */ 2*95c635efSGarrett D'Amore /* 3*95c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*95c635efSGarrett D'Amore * 5*95c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 6*95c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 7*95c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 8*95c635efSGarrett D'Amore * 9*95c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*95c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*95c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*95c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*95c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*95c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*95c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*95c635efSGarrett D'Amore */ 17*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 18*95c635efSGarrett D'Amore #include "config.h" 19*95c635efSGarrett D'Amore #endif 20*95c635efSGarrett D'Amore 21*95c635efSGarrett D'Amore #include <assert.h> 22*95c635efSGarrett D'Amore #include <limits.h> 23*95c635efSGarrett D'Amore #include <stdio.h> 24*95c635efSGarrett D'Amore #include <stdlib.h> 25*95c635efSGarrett D'Amore #include <time.h> 26*95c635efSGarrett D'Amore 27*95c635efSGarrett D'Amore #include "mandoc.h" 28*95c635efSGarrett D'Amore #include "mdoc.h" 29*95c635efSGarrett D'Amore #include "man.h" 30*95c635efSGarrett D'Amore #include "main.h" 31*95c635efSGarrett D'Amore 32*95c635efSGarrett D'Amore static void print_box(const struct eqn_box *, int); 33*95c635efSGarrett D'Amore static void print_man(const struct man_node *, int); 34*95c635efSGarrett D'Amore static void print_mdoc(const struct mdoc_node *, int); 35*95c635efSGarrett D'Amore static void print_span(const struct tbl_span *, int); 36*95c635efSGarrett D'Amore 37*95c635efSGarrett D'Amore 38*95c635efSGarrett D'Amore /* ARGSUSED */ 39*95c635efSGarrett D'Amore void 40*95c635efSGarrett D'Amore tree_mdoc(void *arg, const struct mdoc *mdoc) 41*95c635efSGarrett D'Amore { 42*95c635efSGarrett D'Amore 43*95c635efSGarrett D'Amore print_mdoc(mdoc_node(mdoc), 0); 44*95c635efSGarrett D'Amore } 45*95c635efSGarrett D'Amore 46*95c635efSGarrett D'Amore 47*95c635efSGarrett D'Amore /* ARGSUSED */ 48*95c635efSGarrett D'Amore void 49*95c635efSGarrett D'Amore tree_man(void *arg, const struct man *man) 50*95c635efSGarrett D'Amore { 51*95c635efSGarrett D'Amore 52*95c635efSGarrett D'Amore print_man(man_node(man), 0); 53*95c635efSGarrett D'Amore } 54*95c635efSGarrett D'Amore 55*95c635efSGarrett D'Amore 56*95c635efSGarrett D'Amore static void 57*95c635efSGarrett D'Amore print_mdoc(const struct mdoc_node *n, int indent) 58*95c635efSGarrett D'Amore { 59*95c635efSGarrett D'Amore const char *p, *t; 60*95c635efSGarrett D'Amore int i, j; 61*95c635efSGarrett D'Amore size_t argc, sz; 62*95c635efSGarrett D'Amore char **params; 63*95c635efSGarrett D'Amore struct mdoc_argv *argv; 64*95c635efSGarrett D'Amore 65*95c635efSGarrett D'Amore argv = NULL; 66*95c635efSGarrett D'Amore argc = sz = 0; 67*95c635efSGarrett D'Amore params = NULL; 68*95c635efSGarrett D'Amore t = p = NULL; 69*95c635efSGarrett D'Amore 70*95c635efSGarrett D'Amore switch (n->type) { 71*95c635efSGarrett D'Amore case (MDOC_ROOT): 72*95c635efSGarrett D'Amore t = "root"; 73*95c635efSGarrett D'Amore break; 74*95c635efSGarrett D'Amore case (MDOC_BLOCK): 75*95c635efSGarrett D'Amore t = "block"; 76*95c635efSGarrett D'Amore break; 77*95c635efSGarrett D'Amore case (MDOC_HEAD): 78*95c635efSGarrett D'Amore t = "block-head"; 79*95c635efSGarrett D'Amore break; 80*95c635efSGarrett D'Amore case (MDOC_BODY): 81*95c635efSGarrett D'Amore if (n->end) 82*95c635efSGarrett D'Amore t = "body-end"; 83*95c635efSGarrett D'Amore else 84*95c635efSGarrett D'Amore t = "block-body"; 85*95c635efSGarrett D'Amore break; 86*95c635efSGarrett D'Amore case (MDOC_TAIL): 87*95c635efSGarrett D'Amore t = "block-tail"; 88*95c635efSGarrett D'Amore break; 89*95c635efSGarrett D'Amore case (MDOC_ELEM): 90*95c635efSGarrett D'Amore t = "elem"; 91*95c635efSGarrett D'Amore break; 92*95c635efSGarrett D'Amore case (MDOC_TEXT): 93*95c635efSGarrett D'Amore t = "text"; 94*95c635efSGarrett D'Amore break; 95*95c635efSGarrett D'Amore case (MDOC_TBL): 96*95c635efSGarrett D'Amore /* FALLTHROUGH */ 97*95c635efSGarrett D'Amore case (MDOC_EQN): 98*95c635efSGarrett D'Amore break; 99*95c635efSGarrett D'Amore default: 100*95c635efSGarrett D'Amore abort(); 101*95c635efSGarrett D'Amore /* NOTREACHED */ 102*95c635efSGarrett D'Amore } 103*95c635efSGarrett D'Amore 104*95c635efSGarrett D'Amore switch (n->type) { 105*95c635efSGarrett D'Amore case (MDOC_TEXT): 106*95c635efSGarrett D'Amore p = n->string; 107*95c635efSGarrett D'Amore break; 108*95c635efSGarrett D'Amore case (MDOC_BODY): 109*95c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 110*95c635efSGarrett D'Amore break; 111*95c635efSGarrett D'Amore case (MDOC_HEAD): 112*95c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 113*95c635efSGarrett D'Amore break; 114*95c635efSGarrett D'Amore case (MDOC_TAIL): 115*95c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 116*95c635efSGarrett D'Amore break; 117*95c635efSGarrett D'Amore case (MDOC_ELEM): 118*95c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 119*95c635efSGarrett D'Amore if (n->args) { 120*95c635efSGarrett D'Amore argv = n->args->argv; 121*95c635efSGarrett D'Amore argc = n->args->argc; 122*95c635efSGarrett D'Amore } 123*95c635efSGarrett D'Amore break; 124*95c635efSGarrett D'Amore case (MDOC_BLOCK): 125*95c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 126*95c635efSGarrett D'Amore if (n->args) { 127*95c635efSGarrett D'Amore argv = n->args->argv; 128*95c635efSGarrett D'Amore argc = n->args->argc; 129*95c635efSGarrett D'Amore } 130*95c635efSGarrett D'Amore break; 131*95c635efSGarrett D'Amore case (MDOC_TBL): 132*95c635efSGarrett D'Amore /* FALLTHROUGH */ 133*95c635efSGarrett D'Amore case (MDOC_EQN): 134*95c635efSGarrett D'Amore break; 135*95c635efSGarrett D'Amore case (MDOC_ROOT): 136*95c635efSGarrett D'Amore p = "root"; 137*95c635efSGarrett D'Amore break; 138*95c635efSGarrett D'Amore default: 139*95c635efSGarrett D'Amore abort(); 140*95c635efSGarrett D'Amore /* NOTREACHED */ 141*95c635efSGarrett D'Amore } 142*95c635efSGarrett D'Amore 143*95c635efSGarrett D'Amore if (n->span) { 144*95c635efSGarrett D'Amore assert(NULL == p && NULL == t); 145*95c635efSGarrett D'Amore print_span(n->span, indent); 146*95c635efSGarrett D'Amore } else if (n->eqn) { 147*95c635efSGarrett D'Amore assert(NULL == p && NULL == t); 148*95c635efSGarrett D'Amore print_box(n->eqn->root, indent); 149*95c635efSGarrett D'Amore } else { 150*95c635efSGarrett D'Amore for (i = 0; i < indent; i++) 151*95c635efSGarrett D'Amore putchar('\t'); 152*95c635efSGarrett D'Amore 153*95c635efSGarrett D'Amore printf("%s (%s)", p, t); 154*95c635efSGarrett D'Amore 155*95c635efSGarrett D'Amore for (i = 0; i < (int)argc; i++) { 156*95c635efSGarrett D'Amore printf(" -%s", mdoc_argnames[argv[i].arg]); 157*95c635efSGarrett D'Amore if (argv[i].sz > 0) 158*95c635efSGarrett D'Amore printf(" ["); 159*95c635efSGarrett D'Amore for (j = 0; j < (int)argv[i].sz; j++) 160*95c635efSGarrett D'Amore printf(" [%s]", argv[i].value[j]); 161*95c635efSGarrett D'Amore if (argv[i].sz > 0) 162*95c635efSGarrett D'Amore printf(" ]"); 163*95c635efSGarrett D'Amore } 164*95c635efSGarrett D'Amore 165*95c635efSGarrett D'Amore for (i = 0; i < (int)sz; i++) 166*95c635efSGarrett D'Amore printf(" [%s]", params[i]); 167*95c635efSGarrett D'Amore 168*95c635efSGarrett D'Amore printf(" %d:%d\n", n->line, n->pos); 169*95c635efSGarrett D'Amore } 170*95c635efSGarrett D'Amore 171*95c635efSGarrett D'Amore if (n->child) 172*95c635efSGarrett D'Amore print_mdoc(n->child, indent + 1); 173*95c635efSGarrett D'Amore if (n->next) 174*95c635efSGarrett D'Amore print_mdoc(n->next, indent); 175*95c635efSGarrett D'Amore } 176*95c635efSGarrett D'Amore 177*95c635efSGarrett D'Amore 178*95c635efSGarrett D'Amore static void 179*95c635efSGarrett D'Amore print_man(const struct man_node *n, int indent) 180*95c635efSGarrett D'Amore { 181*95c635efSGarrett D'Amore const char *p, *t; 182*95c635efSGarrett D'Amore int i; 183*95c635efSGarrett D'Amore 184*95c635efSGarrett D'Amore t = p = NULL; 185*95c635efSGarrett D'Amore 186*95c635efSGarrett D'Amore switch (n->type) { 187*95c635efSGarrett D'Amore case (MAN_ROOT): 188*95c635efSGarrett D'Amore t = "root"; 189*95c635efSGarrett D'Amore break; 190*95c635efSGarrett D'Amore case (MAN_ELEM): 191*95c635efSGarrett D'Amore t = "elem"; 192*95c635efSGarrett D'Amore break; 193*95c635efSGarrett D'Amore case (MAN_TEXT): 194*95c635efSGarrett D'Amore t = "text"; 195*95c635efSGarrett D'Amore break; 196*95c635efSGarrett D'Amore case (MAN_BLOCK): 197*95c635efSGarrett D'Amore t = "block"; 198*95c635efSGarrett D'Amore break; 199*95c635efSGarrett D'Amore case (MAN_HEAD): 200*95c635efSGarrett D'Amore t = "block-head"; 201*95c635efSGarrett D'Amore break; 202*95c635efSGarrett D'Amore case (MAN_BODY): 203*95c635efSGarrett D'Amore t = "block-body"; 204*95c635efSGarrett D'Amore break; 205*95c635efSGarrett D'Amore case (MAN_TAIL): 206*95c635efSGarrett D'Amore t = "block-tail"; 207*95c635efSGarrett D'Amore break; 208*95c635efSGarrett D'Amore case (MAN_TBL): 209*95c635efSGarrett D'Amore /* FALLTHROUGH */ 210*95c635efSGarrett D'Amore case (MAN_EQN): 211*95c635efSGarrett D'Amore break; 212*95c635efSGarrett D'Amore default: 213*95c635efSGarrett D'Amore abort(); 214*95c635efSGarrett D'Amore /* NOTREACHED */ 215*95c635efSGarrett D'Amore } 216*95c635efSGarrett D'Amore 217*95c635efSGarrett D'Amore switch (n->type) { 218*95c635efSGarrett D'Amore case (MAN_TEXT): 219*95c635efSGarrett D'Amore p = n->string; 220*95c635efSGarrett D'Amore break; 221*95c635efSGarrett D'Amore case (MAN_ELEM): 222*95c635efSGarrett D'Amore /* FALLTHROUGH */ 223*95c635efSGarrett D'Amore case (MAN_BLOCK): 224*95c635efSGarrett D'Amore /* FALLTHROUGH */ 225*95c635efSGarrett D'Amore case (MAN_HEAD): 226*95c635efSGarrett D'Amore /* FALLTHROUGH */ 227*95c635efSGarrett D'Amore case (MAN_TAIL): 228*95c635efSGarrett D'Amore /* FALLTHROUGH */ 229*95c635efSGarrett D'Amore case (MAN_BODY): 230*95c635efSGarrett D'Amore p = man_macronames[n->tok]; 231*95c635efSGarrett D'Amore break; 232*95c635efSGarrett D'Amore case (MAN_ROOT): 233*95c635efSGarrett D'Amore p = "root"; 234*95c635efSGarrett D'Amore break; 235*95c635efSGarrett D'Amore case (MAN_TBL): 236*95c635efSGarrett D'Amore /* FALLTHROUGH */ 237*95c635efSGarrett D'Amore case (MAN_EQN): 238*95c635efSGarrett D'Amore break; 239*95c635efSGarrett D'Amore default: 240*95c635efSGarrett D'Amore abort(); 241*95c635efSGarrett D'Amore /* NOTREACHED */ 242*95c635efSGarrett D'Amore } 243*95c635efSGarrett D'Amore 244*95c635efSGarrett D'Amore if (n->span) { 245*95c635efSGarrett D'Amore assert(NULL == p && NULL == t); 246*95c635efSGarrett D'Amore print_span(n->span, indent); 247*95c635efSGarrett D'Amore } else if (n->eqn) { 248*95c635efSGarrett D'Amore assert(NULL == p && NULL == t); 249*95c635efSGarrett D'Amore print_box(n->eqn->root, indent); 250*95c635efSGarrett D'Amore } else { 251*95c635efSGarrett D'Amore for (i = 0; i < indent; i++) 252*95c635efSGarrett D'Amore putchar('\t'); 253*95c635efSGarrett D'Amore printf("%s (%s) %d:%d\n", p, t, n->line, n->pos); 254*95c635efSGarrett D'Amore } 255*95c635efSGarrett D'Amore 256*95c635efSGarrett D'Amore if (n->child) 257*95c635efSGarrett D'Amore print_man(n->child, indent + 1); 258*95c635efSGarrett D'Amore if (n->next) 259*95c635efSGarrett D'Amore print_man(n->next, indent); 260*95c635efSGarrett D'Amore } 261*95c635efSGarrett D'Amore 262*95c635efSGarrett D'Amore static void 263*95c635efSGarrett D'Amore print_box(const struct eqn_box *ep, int indent) 264*95c635efSGarrett D'Amore { 265*95c635efSGarrett D'Amore int i; 266*95c635efSGarrett D'Amore const char *t; 267*95c635efSGarrett D'Amore 268*95c635efSGarrett D'Amore if (NULL == ep) 269*95c635efSGarrett D'Amore return; 270*95c635efSGarrett D'Amore for (i = 0; i < indent; i++) 271*95c635efSGarrett D'Amore putchar('\t'); 272*95c635efSGarrett D'Amore 273*95c635efSGarrett D'Amore t = NULL; 274*95c635efSGarrett D'Amore switch (ep->type) { 275*95c635efSGarrett D'Amore case (EQN_ROOT): 276*95c635efSGarrett D'Amore t = "eqn-root"; 277*95c635efSGarrett D'Amore break; 278*95c635efSGarrett D'Amore case (EQN_LIST): 279*95c635efSGarrett D'Amore t = "eqn-list"; 280*95c635efSGarrett D'Amore break; 281*95c635efSGarrett D'Amore case (EQN_SUBEXPR): 282*95c635efSGarrett D'Amore t = "eqn-expr"; 283*95c635efSGarrett D'Amore break; 284*95c635efSGarrett D'Amore case (EQN_TEXT): 285*95c635efSGarrett D'Amore t = "eqn-text"; 286*95c635efSGarrett D'Amore break; 287*95c635efSGarrett D'Amore case (EQN_MATRIX): 288*95c635efSGarrett D'Amore t = "eqn-matrix"; 289*95c635efSGarrett D'Amore break; 290*95c635efSGarrett D'Amore } 291*95c635efSGarrett D'Amore 292*95c635efSGarrett D'Amore assert(t); 293*95c635efSGarrett D'Amore printf("%s(%d, %d, %d, %d, %d, \"%s\", \"%s\") %s\n", 294*95c635efSGarrett D'Amore t, EQN_DEFSIZE == ep->size ? 0 : ep->size, 295*95c635efSGarrett D'Amore ep->pos, ep->font, ep->mark, ep->pile, 296*95c635efSGarrett D'Amore ep->left ? ep->left : "", 297*95c635efSGarrett D'Amore ep->right ? ep->right : "", 298*95c635efSGarrett D'Amore ep->text ? ep->text : ""); 299*95c635efSGarrett D'Amore 300*95c635efSGarrett D'Amore print_box(ep->first, indent + 1); 301*95c635efSGarrett D'Amore print_box(ep->next, indent); 302*95c635efSGarrett D'Amore } 303*95c635efSGarrett D'Amore 304*95c635efSGarrett D'Amore static void 305*95c635efSGarrett D'Amore print_span(const struct tbl_span *sp, int indent) 306*95c635efSGarrett D'Amore { 307*95c635efSGarrett D'Amore const struct tbl_dat *dp; 308*95c635efSGarrett D'Amore int i; 309*95c635efSGarrett D'Amore 310*95c635efSGarrett D'Amore for (i = 0; i < indent; i++) 311*95c635efSGarrett D'Amore putchar('\t'); 312*95c635efSGarrett D'Amore 313*95c635efSGarrett D'Amore switch (sp->pos) { 314*95c635efSGarrett D'Amore case (TBL_SPAN_HORIZ): 315*95c635efSGarrett D'Amore putchar('-'); 316*95c635efSGarrett D'Amore return; 317*95c635efSGarrett D'Amore case (TBL_SPAN_DHORIZ): 318*95c635efSGarrett D'Amore putchar('='); 319*95c635efSGarrett D'Amore return; 320*95c635efSGarrett D'Amore default: 321*95c635efSGarrett D'Amore break; 322*95c635efSGarrett D'Amore } 323*95c635efSGarrett D'Amore 324*95c635efSGarrett D'Amore for (dp = sp->first; dp; dp = dp->next) { 325*95c635efSGarrett D'Amore switch (dp->pos) { 326*95c635efSGarrett D'Amore case (TBL_DATA_HORIZ): 327*95c635efSGarrett D'Amore /* FALLTHROUGH */ 328*95c635efSGarrett D'Amore case (TBL_DATA_NHORIZ): 329*95c635efSGarrett D'Amore putchar('-'); 330*95c635efSGarrett D'Amore continue; 331*95c635efSGarrett D'Amore case (TBL_DATA_DHORIZ): 332*95c635efSGarrett D'Amore /* FALLTHROUGH */ 333*95c635efSGarrett D'Amore case (TBL_DATA_NDHORIZ): 334*95c635efSGarrett D'Amore putchar('='); 335*95c635efSGarrett D'Amore continue; 336*95c635efSGarrett D'Amore default: 337*95c635efSGarrett D'Amore break; 338*95c635efSGarrett D'Amore } 339*95c635efSGarrett D'Amore printf("[\"%s\"", dp->string ? dp->string : ""); 340*95c635efSGarrett D'Amore if (dp->spans) 341*95c635efSGarrett D'Amore printf("(%d)", dp->spans); 342*95c635efSGarrett D'Amore if (NULL == dp->layout) 343*95c635efSGarrett D'Amore putchar('*'); 344*95c635efSGarrett D'Amore putchar(']'); 345*95c635efSGarrett D'Amore putchar(' '); 346*95c635efSGarrett D'Amore } 347*95c635efSGarrett D'Amore 348*95c635efSGarrett D'Amore printf("(tbl) %d:1\n", sp->line); 349*95c635efSGarrett D'Amore } 350