1*c1c95addSBrooks Davis /* $Id: tree.c,v 1.92 2022/01/12 04:54:05 schwarze Exp $ */ 261d06d6bSBaptiste Daroussin /* 361d06d6bSBaptiste Daroussin * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> 4*c1c95addSBrooks Davis * Copyright (c) 2013-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org> 561d06d6bSBaptiste Daroussin * 661d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any 761d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above 861d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies. 961d06d6bSBaptiste Daroussin * 1061d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES 1161d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1261d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 1361d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1461d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1561d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1661d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 176d38604fSBaptiste Daroussin * 186d38604fSBaptiste Daroussin * Formatting module to let mandoc(1) show 196d38604fSBaptiste Daroussin * a human readable representation of the syntax tree. 2061d06d6bSBaptiste Daroussin */ 2161d06d6bSBaptiste Daroussin #include "config.h" 2261d06d6bSBaptiste Daroussin 2361d06d6bSBaptiste Daroussin #include <sys/types.h> 2461d06d6bSBaptiste Daroussin 2561d06d6bSBaptiste Daroussin #include <assert.h> 2661d06d6bSBaptiste Daroussin #include <limits.h> 2761d06d6bSBaptiste Daroussin #include <stdio.h> 2861d06d6bSBaptiste Daroussin #include <stdlib.h> 2961d06d6bSBaptiste Daroussin #include <time.h> 3061d06d6bSBaptiste Daroussin 3161d06d6bSBaptiste Daroussin #include "mandoc.h" 3261d06d6bSBaptiste Daroussin #include "roff.h" 3361d06d6bSBaptiste Daroussin #include "mdoc.h" 3461d06d6bSBaptiste Daroussin #include "man.h" 357295610fSBaptiste Daroussin #include "tbl.h" 367295610fSBaptiste Daroussin #include "eqn.h" 3761d06d6bSBaptiste Daroussin #include "main.h" 3861d06d6bSBaptiste Daroussin 396d38604fSBaptiste Daroussin static void print_attr(const struct roff_node *); 4061d06d6bSBaptiste Daroussin static void print_box(const struct eqn_box *, int); 416d38604fSBaptiste Daroussin static void print_cellt(enum tbl_cellt); 4261d06d6bSBaptiste Daroussin static void print_man(const struct roff_node *, int); 4361d06d6bSBaptiste Daroussin static void print_meta(const struct roff_meta *); 4461d06d6bSBaptiste Daroussin static void print_mdoc(const struct roff_node *, int); 4561d06d6bSBaptiste Daroussin static void print_span(const struct tbl_span *, int); 4661d06d6bSBaptiste Daroussin 4761d06d6bSBaptiste Daroussin 4861d06d6bSBaptiste Daroussin void 497295610fSBaptiste Daroussin tree_mdoc(void *arg, const struct roff_meta *mdoc) 5061d06d6bSBaptiste Daroussin { 517295610fSBaptiste Daroussin print_meta(mdoc); 5261d06d6bSBaptiste Daroussin putchar('\n'); 5361d06d6bSBaptiste Daroussin print_mdoc(mdoc->first->child, 0); 5461d06d6bSBaptiste Daroussin } 5561d06d6bSBaptiste Daroussin 5661d06d6bSBaptiste Daroussin void 577295610fSBaptiste Daroussin tree_man(void *arg, const struct roff_meta *man) 5861d06d6bSBaptiste Daroussin { 597295610fSBaptiste Daroussin print_meta(man); 607295610fSBaptiste Daroussin if (man->hasbody == 0) 6161d06d6bSBaptiste Daroussin puts("body = empty"); 6261d06d6bSBaptiste Daroussin putchar('\n'); 6361d06d6bSBaptiste Daroussin print_man(man->first->child, 0); 6461d06d6bSBaptiste Daroussin } 6561d06d6bSBaptiste Daroussin 6661d06d6bSBaptiste Daroussin static void 6761d06d6bSBaptiste Daroussin print_meta(const struct roff_meta *meta) 6861d06d6bSBaptiste Daroussin { 6961d06d6bSBaptiste Daroussin if (meta->title != NULL) 7061d06d6bSBaptiste Daroussin printf("title = \"%s\"\n", meta->title); 7161d06d6bSBaptiste Daroussin if (meta->name != NULL) 7261d06d6bSBaptiste Daroussin printf("name = \"%s\"\n", meta->name); 7361d06d6bSBaptiste Daroussin if (meta->msec != NULL) 7461d06d6bSBaptiste Daroussin printf("sec = \"%s\"\n", meta->msec); 7561d06d6bSBaptiste Daroussin if (meta->vol != NULL) 7661d06d6bSBaptiste Daroussin printf("vol = \"%s\"\n", meta->vol); 7761d06d6bSBaptiste Daroussin if (meta->arch != NULL) 7861d06d6bSBaptiste Daroussin printf("arch = \"%s\"\n", meta->arch); 7961d06d6bSBaptiste Daroussin if (meta->os != NULL) 8061d06d6bSBaptiste Daroussin printf("os = \"%s\"\n", meta->os); 8161d06d6bSBaptiste Daroussin if (meta->date != NULL) 8261d06d6bSBaptiste Daroussin printf("date = \"%s\"\n", meta->date); 8361d06d6bSBaptiste Daroussin } 8461d06d6bSBaptiste Daroussin 8561d06d6bSBaptiste Daroussin static void 8661d06d6bSBaptiste Daroussin print_mdoc(const struct roff_node *n, int indent) 8761d06d6bSBaptiste Daroussin { 8861d06d6bSBaptiste Daroussin const char *p, *t; 8961d06d6bSBaptiste Daroussin int i, j; 9061d06d6bSBaptiste Daroussin size_t argc; 9161d06d6bSBaptiste Daroussin struct mdoc_argv *argv; 9261d06d6bSBaptiste Daroussin 9361d06d6bSBaptiste Daroussin if (n == NULL) 9461d06d6bSBaptiste Daroussin return; 9561d06d6bSBaptiste Daroussin 9661d06d6bSBaptiste Daroussin argv = NULL; 9761d06d6bSBaptiste Daroussin argc = 0; 9861d06d6bSBaptiste Daroussin t = p = NULL; 9961d06d6bSBaptiste Daroussin 10061d06d6bSBaptiste Daroussin switch (n->type) { 10161d06d6bSBaptiste Daroussin case ROFFT_ROOT: 10261d06d6bSBaptiste Daroussin t = "root"; 10361d06d6bSBaptiste Daroussin break; 10461d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 10561d06d6bSBaptiste Daroussin t = "block"; 10661d06d6bSBaptiste Daroussin break; 10761d06d6bSBaptiste Daroussin case ROFFT_HEAD: 10861d06d6bSBaptiste Daroussin t = "head"; 10961d06d6bSBaptiste Daroussin break; 11061d06d6bSBaptiste Daroussin case ROFFT_BODY: 11161d06d6bSBaptiste Daroussin if (n->end) 11261d06d6bSBaptiste Daroussin t = "body-end"; 11361d06d6bSBaptiste Daroussin else 11461d06d6bSBaptiste Daroussin t = "body"; 11561d06d6bSBaptiste Daroussin break; 11661d06d6bSBaptiste Daroussin case ROFFT_TAIL: 11761d06d6bSBaptiste Daroussin t = "tail"; 11861d06d6bSBaptiste Daroussin break; 11961d06d6bSBaptiste Daroussin case ROFFT_ELEM: 12061d06d6bSBaptiste Daroussin t = "elem"; 12161d06d6bSBaptiste Daroussin break; 12261d06d6bSBaptiste Daroussin case ROFFT_TEXT: 12361d06d6bSBaptiste Daroussin t = "text"; 12461d06d6bSBaptiste Daroussin break; 12561d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 12661d06d6bSBaptiste Daroussin t = "comment"; 12761d06d6bSBaptiste Daroussin break; 12861d06d6bSBaptiste Daroussin case ROFFT_TBL: 12961d06d6bSBaptiste Daroussin break; 13061d06d6bSBaptiste Daroussin case ROFFT_EQN: 13161d06d6bSBaptiste Daroussin t = "eqn"; 13261d06d6bSBaptiste Daroussin break; 13361d06d6bSBaptiste Daroussin default: 13461d06d6bSBaptiste Daroussin abort(); 13561d06d6bSBaptiste Daroussin } 13661d06d6bSBaptiste Daroussin 13761d06d6bSBaptiste Daroussin switch (n->type) { 13861d06d6bSBaptiste Daroussin case ROFFT_TEXT: 13961d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 14061d06d6bSBaptiste Daroussin p = n->string; 14161d06d6bSBaptiste Daroussin break; 14261d06d6bSBaptiste Daroussin case ROFFT_BODY: 14361d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 14461d06d6bSBaptiste Daroussin break; 14561d06d6bSBaptiste Daroussin case ROFFT_HEAD: 14661d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 14761d06d6bSBaptiste Daroussin break; 14861d06d6bSBaptiste Daroussin case ROFFT_TAIL: 14961d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 15061d06d6bSBaptiste Daroussin break; 15161d06d6bSBaptiste Daroussin case ROFFT_ELEM: 15261d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 15361d06d6bSBaptiste Daroussin if (n->args) { 15461d06d6bSBaptiste Daroussin argv = n->args->argv; 15561d06d6bSBaptiste Daroussin argc = n->args->argc; 15661d06d6bSBaptiste Daroussin } 15761d06d6bSBaptiste Daroussin break; 15861d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 15961d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 16061d06d6bSBaptiste Daroussin if (n->args) { 16161d06d6bSBaptiste Daroussin argv = n->args->argv; 16261d06d6bSBaptiste Daroussin argc = n->args->argc; 16361d06d6bSBaptiste Daroussin } 16461d06d6bSBaptiste Daroussin break; 16561d06d6bSBaptiste Daroussin case ROFFT_TBL: 16661d06d6bSBaptiste Daroussin break; 16761d06d6bSBaptiste Daroussin case ROFFT_EQN: 16861d06d6bSBaptiste Daroussin p = "EQ"; 16961d06d6bSBaptiste Daroussin break; 17061d06d6bSBaptiste Daroussin case ROFFT_ROOT: 17161d06d6bSBaptiste Daroussin p = "root"; 17261d06d6bSBaptiste Daroussin break; 17361d06d6bSBaptiste Daroussin default: 17461d06d6bSBaptiste Daroussin abort(); 17561d06d6bSBaptiste Daroussin } 17661d06d6bSBaptiste Daroussin 17761d06d6bSBaptiste Daroussin if (n->span) { 17861d06d6bSBaptiste Daroussin assert(NULL == p && NULL == t); 17961d06d6bSBaptiste Daroussin print_span(n->span, indent); 18061d06d6bSBaptiste Daroussin } else { 18161d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 18261d06d6bSBaptiste Daroussin putchar(' '); 18361d06d6bSBaptiste Daroussin 18461d06d6bSBaptiste Daroussin printf("%s (%s)", p, t); 18561d06d6bSBaptiste Daroussin 18661d06d6bSBaptiste Daroussin for (i = 0; i < (int)argc; i++) { 18761d06d6bSBaptiste Daroussin printf(" -%s", mdoc_argnames[argv[i].arg]); 18861d06d6bSBaptiste Daroussin if (argv[i].sz > 0) 18961d06d6bSBaptiste Daroussin printf(" ["); 19061d06d6bSBaptiste Daroussin for (j = 0; j < (int)argv[i].sz; j++) 19161d06d6bSBaptiste Daroussin printf(" [%s]", argv[i].value[j]); 19261d06d6bSBaptiste Daroussin if (argv[i].sz > 0) 19361d06d6bSBaptiste Daroussin printf(" ]"); 19461d06d6bSBaptiste Daroussin } 1956d38604fSBaptiste Daroussin print_attr(n); 19661d06d6bSBaptiste Daroussin } 19761d06d6bSBaptiste Daroussin if (n->eqn) 19861d06d6bSBaptiste Daroussin print_box(n->eqn->first, indent + 4); 19961d06d6bSBaptiste Daroussin if (n->child) 20061d06d6bSBaptiste Daroussin print_mdoc(n->child, indent + 20161d06d6bSBaptiste Daroussin (n->type == ROFFT_BLOCK ? 2 : 4)); 20261d06d6bSBaptiste Daroussin if (n->next) 20361d06d6bSBaptiste Daroussin print_mdoc(n->next, indent); 20461d06d6bSBaptiste Daroussin } 20561d06d6bSBaptiste Daroussin 20661d06d6bSBaptiste Daroussin static void 20761d06d6bSBaptiste Daroussin print_man(const struct roff_node *n, int indent) 20861d06d6bSBaptiste Daroussin { 20961d06d6bSBaptiste Daroussin const char *p, *t; 21061d06d6bSBaptiste Daroussin int i; 21161d06d6bSBaptiste Daroussin 21261d06d6bSBaptiste Daroussin if (n == NULL) 21361d06d6bSBaptiste Daroussin return; 21461d06d6bSBaptiste Daroussin 21561d06d6bSBaptiste Daroussin t = p = NULL; 21661d06d6bSBaptiste Daroussin 21761d06d6bSBaptiste Daroussin switch (n->type) { 21861d06d6bSBaptiste Daroussin case ROFFT_ROOT: 21961d06d6bSBaptiste Daroussin t = "root"; 22061d06d6bSBaptiste Daroussin break; 22161d06d6bSBaptiste Daroussin case ROFFT_ELEM: 22261d06d6bSBaptiste Daroussin t = "elem"; 22361d06d6bSBaptiste Daroussin break; 22461d06d6bSBaptiste Daroussin case ROFFT_TEXT: 22561d06d6bSBaptiste Daroussin t = "text"; 22661d06d6bSBaptiste Daroussin break; 22761d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 22861d06d6bSBaptiste Daroussin t = "comment"; 22961d06d6bSBaptiste Daroussin break; 23061d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 23161d06d6bSBaptiste Daroussin t = "block"; 23261d06d6bSBaptiste Daroussin break; 23361d06d6bSBaptiste Daroussin case ROFFT_HEAD: 23461d06d6bSBaptiste Daroussin t = "head"; 23561d06d6bSBaptiste Daroussin break; 23661d06d6bSBaptiste Daroussin case ROFFT_BODY: 23761d06d6bSBaptiste Daroussin t = "body"; 23861d06d6bSBaptiste Daroussin break; 23961d06d6bSBaptiste Daroussin case ROFFT_TBL: 24061d06d6bSBaptiste Daroussin break; 24161d06d6bSBaptiste Daroussin case ROFFT_EQN: 24261d06d6bSBaptiste Daroussin t = "eqn"; 24361d06d6bSBaptiste Daroussin break; 24461d06d6bSBaptiste Daroussin default: 24561d06d6bSBaptiste Daroussin abort(); 24661d06d6bSBaptiste Daroussin } 24761d06d6bSBaptiste Daroussin 24861d06d6bSBaptiste Daroussin switch (n->type) { 24961d06d6bSBaptiste Daroussin case ROFFT_TEXT: 25061d06d6bSBaptiste Daroussin case ROFFT_COMMENT: 25161d06d6bSBaptiste Daroussin p = n->string; 25261d06d6bSBaptiste Daroussin break; 25361d06d6bSBaptiste Daroussin case ROFFT_ELEM: 25461d06d6bSBaptiste Daroussin case ROFFT_BLOCK: 25561d06d6bSBaptiste Daroussin case ROFFT_HEAD: 25661d06d6bSBaptiste Daroussin case ROFFT_BODY: 25761d06d6bSBaptiste Daroussin p = roff_name[n->tok]; 25861d06d6bSBaptiste Daroussin break; 25961d06d6bSBaptiste Daroussin case ROFFT_ROOT: 26061d06d6bSBaptiste Daroussin p = "root"; 26161d06d6bSBaptiste Daroussin break; 26261d06d6bSBaptiste Daroussin case ROFFT_TBL: 26361d06d6bSBaptiste Daroussin break; 26461d06d6bSBaptiste Daroussin case ROFFT_EQN: 26561d06d6bSBaptiste Daroussin p = "EQ"; 26661d06d6bSBaptiste Daroussin break; 26761d06d6bSBaptiste Daroussin default: 26861d06d6bSBaptiste Daroussin abort(); 26961d06d6bSBaptiste Daroussin } 27061d06d6bSBaptiste Daroussin 27161d06d6bSBaptiste Daroussin if (n->span) { 27261d06d6bSBaptiste Daroussin assert(NULL == p && NULL == t); 27361d06d6bSBaptiste Daroussin print_span(n->span, indent); 27461d06d6bSBaptiste Daroussin } else { 27561d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 27661d06d6bSBaptiste Daroussin putchar(' '); 27761d06d6bSBaptiste Daroussin printf("%s (%s)", p, t); 2786d38604fSBaptiste Daroussin print_attr(n); 27961d06d6bSBaptiste Daroussin } 28061d06d6bSBaptiste Daroussin if (n->eqn) 28161d06d6bSBaptiste Daroussin print_box(n->eqn->first, indent + 4); 28261d06d6bSBaptiste Daroussin if (n->child) 28361d06d6bSBaptiste Daroussin print_man(n->child, indent + 28461d06d6bSBaptiste Daroussin (n->type == ROFFT_BLOCK ? 2 : 4)); 28561d06d6bSBaptiste Daroussin if (n->next) 28661d06d6bSBaptiste Daroussin print_man(n->next, indent); 28761d06d6bSBaptiste Daroussin } 28861d06d6bSBaptiste Daroussin 28961d06d6bSBaptiste Daroussin static void 2906d38604fSBaptiste Daroussin print_attr(const struct roff_node *n) 2916d38604fSBaptiste Daroussin { 2926d38604fSBaptiste Daroussin putchar(' '); 2936d38604fSBaptiste Daroussin if (n->flags & NODE_DELIMO) 2946d38604fSBaptiste Daroussin putchar('('); 2956d38604fSBaptiste Daroussin if (n->flags & NODE_LINE) 2966d38604fSBaptiste Daroussin putchar('*'); 2976d38604fSBaptiste Daroussin printf("%d:%d", n->line, n->pos + 1); 2986d38604fSBaptiste Daroussin if (n->flags & NODE_DELIMC) 2996d38604fSBaptiste Daroussin putchar(')'); 3006d38604fSBaptiste Daroussin if (n->flags & NODE_EOS) 3016d38604fSBaptiste Daroussin putchar('.'); 3026d38604fSBaptiste Daroussin if (n->flags & NODE_ID) { 3036d38604fSBaptiste Daroussin printf(" ID"); 3046d38604fSBaptiste Daroussin if (n->flags & NODE_HREF) 3056d38604fSBaptiste Daroussin printf("=HREF"); 3066d38604fSBaptiste Daroussin } else if (n->flags & NODE_HREF) 3076d38604fSBaptiste Daroussin printf(" HREF"); 3086d38604fSBaptiste Daroussin else if (n->tag != NULL) 3096d38604fSBaptiste Daroussin printf(" STRAYTAG"); 3106d38604fSBaptiste Daroussin if (n->tag != NULL) 3116d38604fSBaptiste Daroussin printf("=%s", n->tag); 3126d38604fSBaptiste Daroussin if (n->flags & NODE_BROKEN) 3136d38604fSBaptiste Daroussin printf(" BROKEN"); 3146d38604fSBaptiste Daroussin if (n->flags & NODE_NOFILL) 3156d38604fSBaptiste Daroussin printf(" NOFILL"); 3166d38604fSBaptiste Daroussin if (n->flags & NODE_NOSRC) 3176d38604fSBaptiste Daroussin printf(" NOSRC"); 3186d38604fSBaptiste Daroussin if (n->flags & NODE_NOPRT) 3196d38604fSBaptiste Daroussin printf(" NOPRT"); 3206d38604fSBaptiste Daroussin putchar('\n'); 3216d38604fSBaptiste Daroussin } 3226d38604fSBaptiste Daroussin 3236d38604fSBaptiste Daroussin static void 32461d06d6bSBaptiste Daroussin print_box(const struct eqn_box *ep, int indent) 32561d06d6bSBaptiste Daroussin { 32661d06d6bSBaptiste Daroussin int i; 32761d06d6bSBaptiste Daroussin const char *t; 32861d06d6bSBaptiste Daroussin 32961d06d6bSBaptiste Daroussin static const char *posnames[] = { 33061d06d6bSBaptiste Daroussin NULL, "sup", "subsup", "sub", 33161d06d6bSBaptiste Daroussin "to", "from", "fromto", 33261d06d6bSBaptiste Daroussin "over", "sqrt", NULL }; 33361d06d6bSBaptiste Daroussin 33461d06d6bSBaptiste Daroussin if (NULL == ep) 33561d06d6bSBaptiste Daroussin return; 33661d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 33761d06d6bSBaptiste Daroussin putchar(' '); 33861d06d6bSBaptiste Daroussin 33961d06d6bSBaptiste Daroussin t = NULL; 34061d06d6bSBaptiste Daroussin switch (ep->type) { 34161d06d6bSBaptiste Daroussin case EQN_LIST: 34261d06d6bSBaptiste Daroussin t = "eqn-list"; 34361d06d6bSBaptiste Daroussin break; 34461d06d6bSBaptiste Daroussin case EQN_SUBEXPR: 34561d06d6bSBaptiste Daroussin t = "eqn-expr"; 34661d06d6bSBaptiste Daroussin break; 34761d06d6bSBaptiste Daroussin case EQN_TEXT: 34861d06d6bSBaptiste Daroussin t = "eqn-text"; 34961d06d6bSBaptiste Daroussin break; 35061d06d6bSBaptiste Daroussin case EQN_PILE: 35161d06d6bSBaptiste Daroussin t = "eqn-pile"; 35261d06d6bSBaptiste Daroussin break; 35361d06d6bSBaptiste Daroussin case EQN_MATRIX: 35461d06d6bSBaptiste Daroussin t = "eqn-matrix"; 35561d06d6bSBaptiste Daroussin break; 35661d06d6bSBaptiste Daroussin } 35761d06d6bSBaptiste Daroussin 35861d06d6bSBaptiste Daroussin fputs(t, stdout); 35961d06d6bSBaptiste Daroussin if (ep->pos) 36061d06d6bSBaptiste Daroussin printf(" pos=%s", posnames[ep->pos]); 36161d06d6bSBaptiste Daroussin if (ep->left) 36261d06d6bSBaptiste Daroussin printf(" left=\"%s\"", ep->left); 36361d06d6bSBaptiste Daroussin if (ep->right) 36461d06d6bSBaptiste Daroussin printf(" right=\"%s\"", ep->right); 36561d06d6bSBaptiste Daroussin if (ep->top) 36661d06d6bSBaptiste Daroussin printf(" top=\"%s\"", ep->top); 36761d06d6bSBaptiste Daroussin if (ep->bottom) 36861d06d6bSBaptiste Daroussin printf(" bottom=\"%s\"", ep->bottom); 36961d06d6bSBaptiste Daroussin if (ep->text) 37061d06d6bSBaptiste Daroussin printf(" text=\"%s\"", ep->text); 37161d06d6bSBaptiste Daroussin if (ep->font) 37261d06d6bSBaptiste Daroussin printf(" font=%d", ep->font); 37361d06d6bSBaptiste Daroussin if (ep->size != EQN_DEFSIZE) 37461d06d6bSBaptiste Daroussin printf(" size=%d", ep->size); 37561d06d6bSBaptiste Daroussin if (ep->expectargs != UINT_MAX && ep->expectargs != ep->args) 37661d06d6bSBaptiste Daroussin printf(" badargs=%zu(%zu)", ep->args, ep->expectargs); 37761d06d6bSBaptiste Daroussin else if (ep->args) 37861d06d6bSBaptiste Daroussin printf(" args=%zu", ep->args); 37961d06d6bSBaptiste Daroussin putchar('\n'); 38061d06d6bSBaptiste Daroussin 38161d06d6bSBaptiste Daroussin print_box(ep->first, indent + 4); 38261d06d6bSBaptiste Daroussin print_box(ep->next, indent); 38361d06d6bSBaptiste Daroussin } 38461d06d6bSBaptiste Daroussin 38561d06d6bSBaptiste Daroussin static void 3866d38604fSBaptiste Daroussin print_cellt(enum tbl_cellt pos) 3876d38604fSBaptiste Daroussin { 3886d38604fSBaptiste Daroussin switch(pos) { 3896d38604fSBaptiste Daroussin case TBL_CELL_LEFT: 3906d38604fSBaptiste Daroussin putchar('L'); 3916d38604fSBaptiste Daroussin break; 3926d38604fSBaptiste Daroussin case TBL_CELL_LONG: 3936d38604fSBaptiste Daroussin putchar('a'); 3946d38604fSBaptiste Daroussin break; 3956d38604fSBaptiste Daroussin case TBL_CELL_CENTRE: 3966d38604fSBaptiste Daroussin putchar('c'); 3976d38604fSBaptiste Daroussin break; 3986d38604fSBaptiste Daroussin case TBL_CELL_RIGHT: 3996d38604fSBaptiste Daroussin putchar('r'); 4006d38604fSBaptiste Daroussin break; 4016d38604fSBaptiste Daroussin case TBL_CELL_NUMBER: 4026d38604fSBaptiste Daroussin putchar('n'); 4036d38604fSBaptiste Daroussin break; 4046d38604fSBaptiste Daroussin case TBL_CELL_SPAN: 4056d38604fSBaptiste Daroussin putchar('s'); 4066d38604fSBaptiste Daroussin break; 4076d38604fSBaptiste Daroussin case TBL_CELL_DOWN: 4086d38604fSBaptiste Daroussin putchar('^'); 4096d38604fSBaptiste Daroussin break; 4106d38604fSBaptiste Daroussin case TBL_CELL_HORIZ: 4116d38604fSBaptiste Daroussin putchar('-'); 4126d38604fSBaptiste Daroussin break; 4136d38604fSBaptiste Daroussin case TBL_CELL_DHORIZ: 4146d38604fSBaptiste Daroussin putchar('='); 4156d38604fSBaptiste Daroussin break; 4166d38604fSBaptiste Daroussin case TBL_CELL_MAX: 4176d38604fSBaptiste Daroussin putchar('#'); 4186d38604fSBaptiste Daroussin break; 4196d38604fSBaptiste Daroussin } 4206d38604fSBaptiste Daroussin } 4216d38604fSBaptiste Daroussin 4226d38604fSBaptiste Daroussin static void 42361d06d6bSBaptiste Daroussin print_span(const struct tbl_span *sp, int indent) 42461d06d6bSBaptiste Daroussin { 42561d06d6bSBaptiste Daroussin const struct tbl_dat *dp; 4266d38604fSBaptiste Daroussin const struct tbl_cell *cp; 42761d06d6bSBaptiste Daroussin int i; 42861d06d6bSBaptiste Daroussin 4296d38604fSBaptiste Daroussin if (sp->prev == NULL) { 4306d38604fSBaptiste Daroussin for (i = 0; i < indent; i++) 4316d38604fSBaptiste Daroussin putchar(' '); 4326d38604fSBaptiste Daroussin printf("%d", sp->opts->cols); 4336d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_CENTRE) 4346d38604fSBaptiste Daroussin fputs(" center", stdout); 4356d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_EXPAND) 4366d38604fSBaptiste Daroussin fputs(" expand", stdout); 4376d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_ALLBOX) 4386d38604fSBaptiste Daroussin fputs(" allbox", stdout); 4396d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_BOX) 4406d38604fSBaptiste Daroussin fputs(" box", stdout); 4416d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_DBOX) 4426d38604fSBaptiste Daroussin fputs(" doublebox", stdout); 4436d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_NOKEEP) 4446d38604fSBaptiste Daroussin fputs(" nokeep", stdout); 4456d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_NOSPACE) 4466d38604fSBaptiste Daroussin fputs(" nospaces", stdout); 4476d38604fSBaptiste Daroussin if (sp->opts->opts & TBL_OPT_NOWARN) 4486d38604fSBaptiste Daroussin fputs(" nowarn", stdout); 4496d38604fSBaptiste Daroussin printf(" (tbl options) %d:1\n", sp->line); 4506d38604fSBaptiste Daroussin } 4516d38604fSBaptiste Daroussin 45261d06d6bSBaptiste Daroussin for (i = 0; i < indent; i++) 45361d06d6bSBaptiste Daroussin putchar(' '); 45461d06d6bSBaptiste Daroussin 45561d06d6bSBaptiste Daroussin switch (sp->pos) { 45661d06d6bSBaptiste Daroussin case TBL_SPAN_HORIZ: 45761d06d6bSBaptiste Daroussin putchar('-'); 4587295610fSBaptiste Daroussin putchar(' '); 4597295610fSBaptiste Daroussin break; 46061d06d6bSBaptiste Daroussin case TBL_SPAN_DHORIZ: 46161d06d6bSBaptiste Daroussin putchar('='); 4627295610fSBaptiste Daroussin putchar(' '); 46361d06d6bSBaptiste Daroussin break; 4647295610fSBaptiste Daroussin default: 4656d38604fSBaptiste Daroussin for (cp = sp->layout->first; cp != NULL; cp = cp->next) 4666d38604fSBaptiste Daroussin print_cellt(cp->pos); 4676d38604fSBaptiste Daroussin putchar(' '); 46861d06d6bSBaptiste Daroussin for (dp = sp->first; dp; dp = dp->next) { 4696d38604fSBaptiste Daroussin if ((cp = dp->layout) == NULL) 4706d38604fSBaptiste Daroussin putchar('*'); 4716d38604fSBaptiste Daroussin else { 4726d38604fSBaptiste Daroussin printf("%d", cp->col); 4736d38604fSBaptiste Daroussin print_cellt(dp->layout->pos); 4746d38604fSBaptiste Daroussin switch (cp->font) { 4756d38604fSBaptiste Daroussin case ESCAPE_FONTROMAN: 4766d38604fSBaptiste Daroussin break; 4776d38604fSBaptiste Daroussin case ESCAPE_FONTBOLD: 4786d38604fSBaptiste Daroussin putchar('b'); 4796d38604fSBaptiste Daroussin break; 4806d38604fSBaptiste Daroussin case ESCAPE_FONTITALIC: 4816d38604fSBaptiste Daroussin putchar('i'); 4826d38604fSBaptiste Daroussin break; 4836d38604fSBaptiste Daroussin case ESCAPE_FONTBI: 4846d38604fSBaptiste Daroussin fputs("bi", stdout); 4856d38604fSBaptiste Daroussin break; 4866d38604fSBaptiste Daroussin case ESCAPE_FONTCR: 4876d38604fSBaptiste Daroussin putchar('c'); 4886d38604fSBaptiste Daroussin break; 4896d38604fSBaptiste Daroussin case ESCAPE_FONTCB: 4906d38604fSBaptiste Daroussin fputs("cb", stdout); 4916d38604fSBaptiste Daroussin break; 4926d38604fSBaptiste Daroussin case ESCAPE_FONTCI: 4936d38604fSBaptiste Daroussin fputs("ci", stdout); 4946d38604fSBaptiste Daroussin break; 4956d38604fSBaptiste Daroussin default: 4966d38604fSBaptiste Daroussin abort(); 4976d38604fSBaptiste Daroussin } 4986d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_TALIGN) 4996d38604fSBaptiste Daroussin putchar('t'); 5006d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_UP) 5016d38604fSBaptiste Daroussin putchar('u'); 5026d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_BALIGN) 5036d38604fSBaptiste Daroussin putchar('d'); 5046d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_WIGN) 5056d38604fSBaptiste Daroussin putchar('z'); 5066d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_EQUAL) 5076d38604fSBaptiste Daroussin putchar('e'); 5086d38604fSBaptiste Daroussin if (cp->flags & TBL_CELL_WMAX) 5096d38604fSBaptiste Daroussin putchar('x'); 5106d38604fSBaptiste Daroussin } 51161d06d6bSBaptiste Daroussin switch (dp->pos) { 51261d06d6bSBaptiste Daroussin case TBL_DATA_NHORIZ: 513*c1c95addSBrooks Davis putchar('\\'); 514*c1c95addSBrooks Davis /* FALLTHROUGH */ 515*c1c95addSBrooks Davis case TBL_DATA_HORIZ: 516*c1c95addSBrooks Davis putchar('_'); 5176d38604fSBaptiste Daroussin break; 51861d06d6bSBaptiste Daroussin case TBL_DATA_NDHORIZ: 519*c1c95addSBrooks Davis putchar('\\'); 520*c1c95addSBrooks Davis /* FALLTHROUGH */ 521*c1c95addSBrooks Davis case TBL_DATA_DHORIZ: 52261d06d6bSBaptiste Daroussin putchar('='); 5236d38604fSBaptiste Daroussin break; 52461d06d6bSBaptiste Daroussin default: 5256d38604fSBaptiste Daroussin putchar(dp->block ? '{' : '['); 5266d38604fSBaptiste Daroussin if (dp->string != NULL) 5276d38604fSBaptiste Daroussin fputs(dp->string, stdout); 5286d38604fSBaptiste Daroussin putchar(dp->block ? '}' : ']'); 52961d06d6bSBaptiste Daroussin break; 53061d06d6bSBaptiste Daroussin } 5317295610fSBaptiste Daroussin if (dp->hspans) 5327295610fSBaptiste Daroussin printf(">%d", dp->hspans); 5337295610fSBaptiste Daroussin if (dp->vspans) 5347295610fSBaptiste Daroussin printf("v%d", dp->vspans); 53561d06d6bSBaptiste Daroussin putchar(' '); 53661d06d6bSBaptiste Daroussin } 5377295610fSBaptiste Daroussin break; 5387295610fSBaptiste Daroussin } 53961d06d6bSBaptiste Daroussin printf("(tbl) %d:1\n", sp->line); 54061d06d6bSBaptiste Daroussin } 541