1*61d06d6bSBaptiste Daroussin /* $Id: tree.c,v 1.78 2018/04/11 17:11:13 schwarze Exp $ */ 2*61d06d6bSBaptiste Daroussin /* 3*61d06d6bSBaptiste Daroussin * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> 4*61d06d6bSBaptiste Daroussin * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> 5*61d06d6bSBaptiste Daroussin * 6*61d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any 7*61d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above 8*61d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies. 9*61d06d6bSBaptiste Daroussin * 10*61d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES 11*61d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12*61d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 13*61d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14*61d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15*61d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16*61d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17*61d06d6bSBaptiste Daroussin */ 18*61d06d6bSBaptiste Daroussin #include "config.h" 19*61d06d6bSBaptiste Daroussin 20*61d06d6bSBaptiste Daroussin #include <sys/types.h> 21*61d06d6bSBaptiste Daroussin 22*61d06d6bSBaptiste Daroussin #include <assert.h> 23*61d06d6bSBaptiste Daroussin #include <limits.h> 24*61d06d6bSBaptiste Daroussin #include <stdio.h> 25*61d06d6bSBaptiste Daroussin #include <stdlib.h> 26*61d06d6bSBaptiste Daroussin #include <time.h> 27*61d06d6bSBaptiste Daroussin 28*61d06d6bSBaptiste Daroussin #include "mandoc.h" 29*61d06d6bSBaptiste Daroussin #include "roff.h" 30*61d06d6bSBaptiste Daroussin #include "mdoc.h" 31*61d06d6bSBaptiste Daroussin #include "man.h" 32*61d06d6bSBaptiste Daroussin #include "main.h" 33*61d06d6bSBaptiste Daroussin 34*61d06d6bSBaptiste Daroussin static void print_box(const struct eqn_box *, int); 35*61d06d6bSBaptiste Daroussin static void print_man(const struct roff_node *, int); 36*61d06d6bSBaptiste Daroussin static void print_meta(const struct roff_meta *); 37*61d06d6bSBaptiste Daroussin static void print_mdoc(const struct roff_node *, int); 38*61d06d6bSBaptiste Daroussin static void print_span(const struct tbl_span *, int); 39*61d06d6bSBaptiste Daroussin 40*61d06d6bSBaptiste Daroussin 41*61d06d6bSBaptiste Daroussin void 42*61d06d6bSBaptiste Daroussin tree_mdoc(void *arg, const struct roff_man *mdoc) 43*61d06d6bSBaptiste Daroussin { 44*61d06d6bSBaptiste Daroussin print_meta(&mdoc->meta); 45*61d06d6bSBaptiste Daroussin putchar('\n'); 46*61d06d6bSBaptiste Daroussin print_mdoc(mdoc->first->child, 0); 47*61d06d6bSBaptiste Daroussin } 48*61d06d6bSBaptiste Daroussin 49*61d06d6bSBaptiste Daroussin void 50*61d06d6bSBaptiste Daroussin tree_man(void *arg, const struct roff_man *man) 51*61d06d6bSBaptiste Daroussin { 52*61d06d6bSBaptiste Daroussin print_meta(&man->meta); 53*61d06d6bSBaptiste Daroussin if (man->meta.hasbody == 0) 54*61d06d6bSBaptiste Daroussin puts("body = empty"); 55*61d06d6bSBaptiste Daroussin putchar('\n'); 56*61d06d6bSBaptiste Daroussin print_man(man->first->child, 0); 57*61d06d6bSBaptiste Daroussin } 58*61d06d6bSBaptiste Daroussin 59*61d06d6bSBaptiste Daroussin static void 60*61d06d6bSBaptiste Daroussin print_meta(const struct roff_meta *meta) 61*61d06d6bSBaptiste Daroussin { 62*61d06d6bSBaptiste Daroussin if (meta->title != NULL) 63*61d06d6bSBaptiste Daroussin printf("title = \"%s\"\n", meta->title); 64*61d06d6bSBaptiste Daroussin if (meta->name != NULL) 65*61d06d6bSBaptiste Daroussin printf("name = \"%s\"\n", meta->name); 66*61d06d6bSBaptiste Daroussin if (meta->msec != NULL) 67*61d06d6bSBaptiste Daroussin printf("sec = \"%s\"\n", meta->msec); 68*61d06d6bSBaptiste Daroussin if (meta->vol != NULL) 69*61d06d6bSBaptiste Daroussin printf("vol = \"%s\"\n", meta->vol); 70*61d06d6bSBaptiste Daroussin if (meta->arch != NULL) 71*61d06d6bSBaptiste Daroussin printf("arch = \"%s\"\n", meta->arch); 72*61d06d6bSBaptiste Daroussin if (meta->os != NULL) 73*61d06d6bSBaptiste Daroussin printf("os = \"%s\"\n", meta->os); 74*61d06d6bSBaptiste Daroussin if (meta->date != NULL) 75*61d06d6bSBaptiste Daroussin printf("date = \"%s\"\n", meta->date); 76*61d06d6bSBaptiste Daroussin } 77*61d06d6bSBaptiste Daroussin 78*61d06d6bSBaptiste Daroussin static void 79*61d06d6bSBaptiste Daroussin print_mdoc(const struct roff_node *n, int indent) 80*61d06d6bSBaptiste Daroussin { 81*61d06d6bSBaptiste Daroussin const char *p, *t; 82*61d06d6bSBaptiste Daroussin int i, j; 83*61d06d6bSBaptiste Daroussin size_t argc; 84*61d06d6bSBaptiste Daroussin struct mdoc_argv *argv; 85*61d06d6bSBaptiste Daroussin 86*61d06d6bSBaptiste Daroussin if (n == NULL) 87*61d06d6bSBaptiste Daroussin return; 88*61d06d6bSBaptiste Daroussin 89*61d06d6bSBaptiste Daroussin argv = NULL; 90*61d06d6bSBaptiste Daroussin argc = 0; 91*61d06d6bSBaptiste Daroussin t = p = NULL; 92*61d06d6bSBaptiste Daroussin 93*61d06d6bSBaptiste Daroussin switch (n->type) { 94*61d06d6bSBaptiste Daroussin case ROFFT_ROOT: 95*61d06d6bSBaptiste Daroussin t = "root"; 96*61d06d6bSBaptiste Daroussin break; 97*61d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 98*61d06d6bSBaptiste Daroussin t = "block"; 99*61d06d6bSBaptiste Daroussin break; 100*61d06d6bSBaptiste Daroussin case ROFFT_HEAD: 101*61d06d6bSBaptiste Daroussin t = "head"; 102*61d06d6bSBaptiste Daroussin break; 103*61d06d6bSBaptiste Daroussin case ROFFT_BODY: 104*61d06d6bSBaptiste Daroussin if (n->end) 105*61d06d6bSBaptiste Daroussin t = "body-end"; 106*61d06d6bSBaptiste Daroussin else 107*61d06d6bSBaptiste Daroussin t = "body"; 108*61d06d6bSBaptiste Daroussin break; 109*61d06d6bSBaptiste Daroussin case ROFFT_TAIL: 110*61d06d6bSBaptiste Daroussin t = "tail"; 111*61d06d6bSBaptiste Daroussin break; 112*61d06d6bSBaptiste Daroussin case ROFFT_ELEM: 113*61d06d6bSBaptiste Daroussin t = "elem"; 114*61d06d6bSBaptiste Daroussin break; 115*61d06d6bSBaptiste Daroussin case ROFFT_TEXT: 116*61d06d6bSBaptiste Daroussin t = "text"; 117*61d06d6bSBaptiste Daroussin break; 118*61d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 119*61d06d6bSBaptiste Daroussin t = "comment"; 120*61d06d6bSBaptiste Daroussin break; 121*61d06d6bSBaptiste Daroussin case ROFFT_TBL: 122*61d06d6bSBaptiste Daroussin break; 123*61d06d6bSBaptiste Daroussin case ROFFT_EQN: 124*61d06d6bSBaptiste Daroussin t = "eqn"; 125*61d06d6bSBaptiste Daroussin break; 126*61d06d6bSBaptiste Daroussin default: 127*61d06d6bSBaptiste Daroussin abort(); 128*61d06d6bSBaptiste Daroussin } 129*61d06d6bSBaptiste Daroussin 130*61d06d6bSBaptiste Daroussin switch (n->type) { 131*61d06d6bSBaptiste Daroussin case ROFFT_TEXT: 132*61d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 133*61d06d6bSBaptiste Daroussin p = n->string; 134*61d06d6bSBaptiste Daroussin break; 135*61d06d6bSBaptiste Daroussin case ROFFT_BODY: 136*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 137*61d06d6bSBaptiste Daroussin break; 138*61d06d6bSBaptiste Daroussin case ROFFT_HEAD: 139*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 140*61d06d6bSBaptiste Daroussin break; 141*61d06d6bSBaptiste Daroussin case ROFFT_TAIL: 142*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 143*61d06d6bSBaptiste Daroussin break; 144*61d06d6bSBaptiste Daroussin case ROFFT_ELEM: 145*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 146*61d06d6bSBaptiste Daroussin if (n->args) { 147*61d06d6bSBaptiste Daroussin argv = n->args->argv; 148*61d06d6bSBaptiste Daroussin argc = n->args->argc; 149*61d06d6bSBaptiste Daroussin } 150*61d06d6bSBaptiste Daroussin break; 151*61d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 152*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 153*61d06d6bSBaptiste Daroussin if (n->args) { 154*61d06d6bSBaptiste Daroussin argv = n->args->argv; 155*61d06d6bSBaptiste Daroussin argc = n->args->argc; 156*61d06d6bSBaptiste Daroussin } 157*61d06d6bSBaptiste Daroussin break; 158*61d06d6bSBaptiste Daroussin case ROFFT_TBL: 159*61d06d6bSBaptiste Daroussin break; 160*61d06d6bSBaptiste Daroussin case ROFFT_EQN: 161*61d06d6bSBaptiste Daroussin p = "EQ"; 162*61d06d6bSBaptiste Daroussin break; 163*61d06d6bSBaptiste Daroussin case ROFFT_ROOT: 164*61d06d6bSBaptiste Daroussin p = "root"; 165*61d06d6bSBaptiste Daroussin break; 166*61d06d6bSBaptiste Daroussin default: 167*61d06d6bSBaptiste Daroussin abort(); 168*61d06d6bSBaptiste Daroussin } 169*61d06d6bSBaptiste Daroussin 170*61d06d6bSBaptiste Daroussin if (n->span) { 171*61d06d6bSBaptiste Daroussin assert(NULL == p && NULL == t); 172*61d06d6bSBaptiste Daroussin print_span(n->span, indent); 173*61d06d6bSBaptiste Daroussin } else { 174*61d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 175*61d06d6bSBaptiste Daroussin putchar(' '); 176*61d06d6bSBaptiste Daroussin 177*61d06d6bSBaptiste Daroussin printf("%s (%s)", p, t); 178*61d06d6bSBaptiste Daroussin 179*61d06d6bSBaptiste Daroussin for (i = 0; i < (int)argc; i++) { 180*61d06d6bSBaptiste Daroussin printf(" -%s", mdoc_argnames[argv[i].arg]); 181*61d06d6bSBaptiste Daroussin if (argv[i].sz > 0) 182*61d06d6bSBaptiste Daroussin printf(" ["); 183*61d06d6bSBaptiste Daroussin for (j = 0; j < (int)argv[i].sz; j++) 184*61d06d6bSBaptiste Daroussin printf(" [%s]", argv[i].value[j]); 185*61d06d6bSBaptiste Daroussin if (argv[i].sz > 0) 186*61d06d6bSBaptiste Daroussin printf(" ]"); 187*61d06d6bSBaptiste Daroussin } 188*61d06d6bSBaptiste Daroussin 189*61d06d6bSBaptiste Daroussin putchar(' '); 190*61d06d6bSBaptiste Daroussin if (NODE_DELIMO & n->flags) 191*61d06d6bSBaptiste Daroussin putchar('('); 192*61d06d6bSBaptiste Daroussin if (NODE_LINE & n->flags) 193*61d06d6bSBaptiste Daroussin putchar('*'); 194*61d06d6bSBaptiste Daroussin printf("%d:%d", n->line, n->pos + 1); 195*61d06d6bSBaptiste Daroussin if (NODE_DELIMC & n->flags) 196*61d06d6bSBaptiste Daroussin putchar(')'); 197*61d06d6bSBaptiste Daroussin if (NODE_EOS & n->flags) 198*61d06d6bSBaptiste Daroussin putchar('.'); 199*61d06d6bSBaptiste Daroussin if (NODE_BROKEN & n->flags) 200*61d06d6bSBaptiste Daroussin printf(" BROKEN"); 201*61d06d6bSBaptiste Daroussin if (NODE_NOSRC & n->flags) 202*61d06d6bSBaptiste Daroussin printf(" NOSRC"); 203*61d06d6bSBaptiste Daroussin if (NODE_NOPRT & n->flags) 204*61d06d6bSBaptiste Daroussin printf(" NOPRT"); 205*61d06d6bSBaptiste Daroussin putchar('\n'); 206*61d06d6bSBaptiste Daroussin } 207*61d06d6bSBaptiste Daroussin 208*61d06d6bSBaptiste Daroussin if (n->eqn) 209*61d06d6bSBaptiste Daroussin print_box(n->eqn->first, indent + 4); 210*61d06d6bSBaptiste Daroussin if (n->child) 211*61d06d6bSBaptiste Daroussin print_mdoc(n->child, indent + 212*61d06d6bSBaptiste Daroussin (n->type == ROFFT_BLOCK ? 2 : 4)); 213*61d06d6bSBaptiste Daroussin if (n->next) 214*61d06d6bSBaptiste Daroussin print_mdoc(n->next, indent); 215*61d06d6bSBaptiste Daroussin } 216*61d06d6bSBaptiste Daroussin 217*61d06d6bSBaptiste Daroussin static void 218*61d06d6bSBaptiste Daroussin print_man(const struct roff_node *n, int indent) 219*61d06d6bSBaptiste Daroussin { 220*61d06d6bSBaptiste Daroussin const char *p, *t; 221*61d06d6bSBaptiste Daroussin int i; 222*61d06d6bSBaptiste Daroussin 223*61d06d6bSBaptiste Daroussin if (n == NULL) 224*61d06d6bSBaptiste Daroussin return; 225*61d06d6bSBaptiste Daroussin 226*61d06d6bSBaptiste Daroussin t = p = NULL; 227*61d06d6bSBaptiste Daroussin 228*61d06d6bSBaptiste Daroussin switch (n->type) { 229*61d06d6bSBaptiste Daroussin case ROFFT_ROOT: 230*61d06d6bSBaptiste Daroussin t = "root"; 231*61d06d6bSBaptiste Daroussin break; 232*61d06d6bSBaptiste Daroussin case ROFFT_ELEM: 233*61d06d6bSBaptiste Daroussin t = "elem"; 234*61d06d6bSBaptiste Daroussin break; 235*61d06d6bSBaptiste Daroussin case ROFFT_TEXT: 236*61d06d6bSBaptiste Daroussin t = "text"; 237*61d06d6bSBaptiste Daroussin break; 238*61d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 239*61d06d6bSBaptiste Daroussin t = "comment"; 240*61d06d6bSBaptiste Daroussin break; 241*61d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 242*61d06d6bSBaptiste Daroussin t = "block"; 243*61d06d6bSBaptiste Daroussin break; 244*61d06d6bSBaptiste Daroussin case ROFFT_HEAD: 245*61d06d6bSBaptiste Daroussin t = "head"; 246*61d06d6bSBaptiste Daroussin break; 247*61d06d6bSBaptiste Daroussin case ROFFT_BODY: 248*61d06d6bSBaptiste Daroussin t = "body"; 249*61d06d6bSBaptiste Daroussin break; 250*61d06d6bSBaptiste Daroussin case ROFFT_TBL: 251*61d06d6bSBaptiste Daroussin break; 252*61d06d6bSBaptiste Daroussin case ROFFT_EQN: 253*61d06d6bSBaptiste Daroussin t = "eqn"; 254*61d06d6bSBaptiste Daroussin break; 255*61d06d6bSBaptiste Daroussin default: 256*61d06d6bSBaptiste Daroussin abort(); 257*61d06d6bSBaptiste Daroussin } 258*61d06d6bSBaptiste Daroussin 259*61d06d6bSBaptiste Daroussin switch (n->type) { 260*61d06d6bSBaptiste Daroussin case ROFFT_TEXT: 261*61d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 262*61d06d6bSBaptiste Daroussin p = n->string; 263*61d06d6bSBaptiste Daroussin break; 264*61d06d6bSBaptiste Daroussin case ROFFT_ELEM: 265*61d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 266*61d06d6bSBaptiste Daroussin case ROFFT_HEAD: 267*61d06d6bSBaptiste Daroussin case ROFFT_BODY: 268*61d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 269*61d06d6bSBaptiste Daroussin break; 270*61d06d6bSBaptiste Daroussin case ROFFT_ROOT: 271*61d06d6bSBaptiste Daroussin p = "root"; 272*61d06d6bSBaptiste Daroussin break; 273*61d06d6bSBaptiste Daroussin case ROFFT_TBL: 274*61d06d6bSBaptiste Daroussin break; 275*61d06d6bSBaptiste Daroussin case ROFFT_EQN: 276*61d06d6bSBaptiste Daroussin p = "EQ"; 277*61d06d6bSBaptiste Daroussin break; 278*61d06d6bSBaptiste Daroussin default: 279*61d06d6bSBaptiste Daroussin abort(); 280*61d06d6bSBaptiste Daroussin } 281*61d06d6bSBaptiste Daroussin 282*61d06d6bSBaptiste Daroussin if (n->span) { 283*61d06d6bSBaptiste Daroussin assert(NULL == p && NULL == t); 284*61d06d6bSBaptiste Daroussin print_span(n->span, indent); 285*61d06d6bSBaptiste Daroussin } else { 286*61d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 287*61d06d6bSBaptiste Daroussin putchar(' '); 288*61d06d6bSBaptiste Daroussin printf("%s (%s) ", p, t); 289*61d06d6bSBaptiste Daroussin if (NODE_LINE & n->flags) 290*61d06d6bSBaptiste Daroussin putchar('*'); 291*61d06d6bSBaptiste Daroussin printf("%d:%d", n->line, n->pos + 1); 292*61d06d6bSBaptiste Daroussin if (NODE_EOS & n->flags) 293*61d06d6bSBaptiste Daroussin putchar('.'); 294*61d06d6bSBaptiste Daroussin putchar('\n'); 295*61d06d6bSBaptiste Daroussin } 296*61d06d6bSBaptiste Daroussin 297*61d06d6bSBaptiste Daroussin if (n->eqn) 298*61d06d6bSBaptiste Daroussin print_box(n->eqn->first, indent + 4); 299*61d06d6bSBaptiste Daroussin if (n->child) 300*61d06d6bSBaptiste Daroussin print_man(n->child, indent + 301*61d06d6bSBaptiste Daroussin (n->type == ROFFT_BLOCK ? 2 : 4)); 302*61d06d6bSBaptiste Daroussin if (n->next) 303*61d06d6bSBaptiste Daroussin print_man(n->next, indent); 304*61d06d6bSBaptiste Daroussin } 305*61d06d6bSBaptiste Daroussin 306*61d06d6bSBaptiste Daroussin static void 307*61d06d6bSBaptiste Daroussin print_box(const struct eqn_box *ep, int indent) 308*61d06d6bSBaptiste Daroussin { 309*61d06d6bSBaptiste Daroussin int i; 310*61d06d6bSBaptiste Daroussin const char *t; 311*61d06d6bSBaptiste Daroussin 312*61d06d6bSBaptiste Daroussin static const char *posnames[] = { 313*61d06d6bSBaptiste Daroussin NULL, "sup", "subsup", "sub", 314*61d06d6bSBaptiste Daroussin "to", "from", "fromto", 315*61d06d6bSBaptiste Daroussin "over", "sqrt", NULL }; 316*61d06d6bSBaptiste Daroussin 317*61d06d6bSBaptiste Daroussin if (NULL == ep) 318*61d06d6bSBaptiste Daroussin return; 319*61d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 320*61d06d6bSBaptiste Daroussin putchar(' '); 321*61d06d6bSBaptiste Daroussin 322*61d06d6bSBaptiste Daroussin t = NULL; 323*61d06d6bSBaptiste Daroussin switch (ep->type) { 324*61d06d6bSBaptiste Daroussin case EQN_LIST: 325*61d06d6bSBaptiste Daroussin t = "eqn-list"; 326*61d06d6bSBaptiste Daroussin break; 327*61d06d6bSBaptiste Daroussin case EQN_SUBEXPR: 328*61d06d6bSBaptiste Daroussin t = "eqn-expr"; 329*61d06d6bSBaptiste Daroussin break; 330*61d06d6bSBaptiste Daroussin case EQN_TEXT: 331*61d06d6bSBaptiste Daroussin t = "eqn-text"; 332*61d06d6bSBaptiste Daroussin break; 333*61d06d6bSBaptiste Daroussin case EQN_PILE: 334*61d06d6bSBaptiste Daroussin t = "eqn-pile"; 335*61d06d6bSBaptiste Daroussin break; 336*61d06d6bSBaptiste Daroussin case EQN_MATRIX: 337*61d06d6bSBaptiste Daroussin t = "eqn-matrix"; 338*61d06d6bSBaptiste Daroussin break; 339*61d06d6bSBaptiste Daroussin } 340*61d06d6bSBaptiste Daroussin 341*61d06d6bSBaptiste Daroussin fputs(t, stdout); 342*61d06d6bSBaptiste Daroussin if (ep->pos) 343*61d06d6bSBaptiste Daroussin printf(" pos=%s", posnames[ep->pos]); 344*61d06d6bSBaptiste Daroussin if (ep->left) 345*61d06d6bSBaptiste Daroussin printf(" left=\"%s\"", ep->left); 346*61d06d6bSBaptiste Daroussin if (ep->right) 347*61d06d6bSBaptiste Daroussin printf(" right=\"%s\"", ep->right); 348*61d06d6bSBaptiste Daroussin if (ep->top) 349*61d06d6bSBaptiste Daroussin printf(" top=\"%s\"", ep->top); 350*61d06d6bSBaptiste Daroussin if (ep->bottom) 351*61d06d6bSBaptiste Daroussin printf(" bottom=\"%s\"", ep->bottom); 352*61d06d6bSBaptiste Daroussin if (ep->text) 353*61d06d6bSBaptiste Daroussin printf(" text=\"%s\"", ep->text); 354*61d06d6bSBaptiste Daroussin if (ep->font) 355*61d06d6bSBaptiste Daroussin printf(" font=%d", ep->font); 356*61d06d6bSBaptiste Daroussin if (ep->size != EQN_DEFSIZE) 357*61d06d6bSBaptiste Daroussin printf(" size=%d", ep->size); 358*61d06d6bSBaptiste Daroussin if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args) 359*61d06d6bSBaptiste Daroussin printf(" badargs=%zu(%zu)", ep->args, ep->expectargs); 360*61d06d6bSBaptiste Daroussin else if (ep->args) 361*61d06d6bSBaptiste Daroussin printf(" args=%zu", ep->args); 362*61d06d6bSBaptiste Daroussin putchar('\n'); 363*61d06d6bSBaptiste Daroussin 364*61d06d6bSBaptiste Daroussin print_box(ep->first, indent + 4); 365*61d06d6bSBaptiste Daroussin print_box(ep->next, indent); 366*61d06d6bSBaptiste Daroussin } 367*61d06d6bSBaptiste Daroussin 368*61d06d6bSBaptiste Daroussin static void 369*61d06d6bSBaptiste Daroussin print_span(const struct tbl_span *sp, int indent) 370*61d06d6bSBaptiste Daroussin { 371*61d06d6bSBaptiste Daroussin const struct tbl_dat *dp; 372*61d06d6bSBaptiste Daroussin int i; 373*61d06d6bSBaptiste Daroussin 374*61d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 375*61d06d6bSBaptiste Daroussin putchar(' '); 376*61d06d6bSBaptiste Daroussin 377*61d06d6bSBaptiste Daroussin switch (sp->pos) { 378*61d06d6bSBaptiste Daroussin case TBL_SPAN_HORIZ: 379*61d06d6bSBaptiste Daroussin putchar('-'); 380*61d06d6bSBaptiste Daroussin return; 381*61d06d6bSBaptiste Daroussin case TBL_SPAN_DHORIZ: 382*61d06d6bSBaptiste Daroussin putchar('='); 383*61d06d6bSBaptiste Daroussin return; 384*61d06d6bSBaptiste Daroussin default: 385*61d06d6bSBaptiste Daroussin break; 386*61d06d6bSBaptiste Daroussin } 387*61d06d6bSBaptiste Daroussin 388*61d06d6bSBaptiste Daroussin for (dp = sp->first; dp; dp = dp->next) { 389*61d06d6bSBaptiste Daroussin switch (dp->pos) { 390*61d06d6bSBaptiste Daroussin case TBL_DATA_HORIZ: 391*61d06d6bSBaptiste Daroussin case TBL_DATA_NHORIZ: 392*61d06d6bSBaptiste Daroussin putchar('-'); 393*61d06d6bSBaptiste Daroussin continue; 394*61d06d6bSBaptiste Daroussin case TBL_DATA_DHORIZ: 395*61d06d6bSBaptiste Daroussin case TBL_DATA_NDHORIZ: 396*61d06d6bSBaptiste Daroussin putchar('='); 397*61d06d6bSBaptiste Daroussin continue; 398*61d06d6bSBaptiste Daroussin default: 399*61d06d6bSBaptiste Daroussin break; 400*61d06d6bSBaptiste Daroussin } 401*61d06d6bSBaptiste Daroussin printf("[\"%s\"", dp->string ? dp->string : ""); 402*61d06d6bSBaptiste Daroussin if (dp->spans) 403*61d06d6bSBaptiste Daroussin printf("(%d)", dp->spans); 404*61d06d6bSBaptiste Daroussin if (NULL == dp->layout) 405*61d06d6bSBaptiste Daroussin putchar('*'); 406*61d06d6bSBaptiste Daroussin putchar(']'); 407*61d06d6bSBaptiste Daroussin putchar(' '); 408*61d06d6bSBaptiste Daroussin } 409*61d06d6bSBaptiste Daroussin 410*61d06d6bSBaptiste Daroussin printf("(tbl) %d:1\n", sp->line); 411*61d06d6bSBaptiste Daroussin } 412