1*698f87a4SGarrett D'Amore /* $Id: tree.c,v 1.50 2013/12/24 19:11:46 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 395c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*698f87a4SGarrett D'Amore * Copyright (c) 2013 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 #ifdef HAVE_CONFIG_H 1995c635efSGarrett D'Amore #include "config.h" 2095c635efSGarrett D'Amore #endif 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 /* ARGSUSED */ 4095c635efSGarrett D'Amore void 4195c635efSGarrett D'Amore tree_mdoc(void *arg, const struct mdoc *mdoc) 4295c635efSGarrett D'Amore { 4395c635efSGarrett D'Amore 4495c635efSGarrett D'Amore print_mdoc(mdoc_node(mdoc), 0); 4595c635efSGarrett D'Amore } 4695c635efSGarrett D'Amore 4795c635efSGarrett D'Amore 4895c635efSGarrett D'Amore /* ARGSUSED */ 4995c635efSGarrett D'Amore void 5095c635efSGarrett D'Amore tree_man(void *arg, const struct man *man) 5195c635efSGarrett D'Amore { 5295c635efSGarrett D'Amore 5395c635efSGarrett D'Amore print_man(man_node(man), 0); 5495c635efSGarrett D'Amore } 5595c635efSGarrett D'Amore 5695c635efSGarrett D'Amore 5795c635efSGarrett D'Amore static void 5895c635efSGarrett D'Amore print_mdoc(const struct mdoc_node *n, int indent) 5995c635efSGarrett D'Amore { 6095c635efSGarrett D'Amore const char *p, *t; 6195c635efSGarrett D'Amore int i, j; 62*698f87a4SGarrett D'Amore size_t argc; 6395c635efSGarrett D'Amore struct mdoc_argv *argv; 6495c635efSGarrett D'Amore 6595c635efSGarrett D'Amore argv = NULL; 66*698f87a4SGarrett D'Amore argc = 0; 6795c635efSGarrett D'Amore t = p = NULL; 6895c635efSGarrett D'Amore 6995c635efSGarrett D'Amore switch (n->type) { 7095c635efSGarrett D'Amore case (MDOC_ROOT): 7195c635efSGarrett D'Amore t = "root"; 7295c635efSGarrett D'Amore break; 7395c635efSGarrett D'Amore case (MDOC_BLOCK): 7495c635efSGarrett D'Amore t = "block"; 7595c635efSGarrett D'Amore break; 7695c635efSGarrett D'Amore case (MDOC_HEAD): 7795c635efSGarrett D'Amore t = "block-head"; 7895c635efSGarrett D'Amore break; 7995c635efSGarrett D'Amore case (MDOC_BODY): 8095c635efSGarrett D'Amore if (n->end) 8195c635efSGarrett D'Amore t = "body-end"; 8295c635efSGarrett D'Amore else 8395c635efSGarrett D'Amore t = "block-body"; 8495c635efSGarrett D'Amore break; 8595c635efSGarrett D'Amore case (MDOC_TAIL): 8695c635efSGarrett D'Amore t = "block-tail"; 8795c635efSGarrett D'Amore break; 8895c635efSGarrett D'Amore case (MDOC_ELEM): 8995c635efSGarrett D'Amore t = "elem"; 9095c635efSGarrett D'Amore break; 9195c635efSGarrett D'Amore case (MDOC_TEXT): 9295c635efSGarrett D'Amore t = "text"; 9395c635efSGarrett D'Amore break; 9495c635efSGarrett D'Amore case (MDOC_TBL): 9595c635efSGarrett D'Amore /* FALLTHROUGH */ 9695c635efSGarrett D'Amore case (MDOC_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) { 10495c635efSGarrett D'Amore case (MDOC_TEXT): 10595c635efSGarrett D'Amore p = n->string; 10695c635efSGarrett D'Amore break; 10795c635efSGarrett D'Amore case (MDOC_BODY): 10895c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 10995c635efSGarrett D'Amore break; 11095c635efSGarrett D'Amore case (MDOC_HEAD): 11195c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 11295c635efSGarrett D'Amore break; 11395c635efSGarrett D'Amore case (MDOC_TAIL): 11495c635efSGarrett D'Amore p = mdoc_macronames[n->tok]; 11595c635efSGarrett D'Amore break; 11695c635efSGarrett D'Amore 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; 12395c635efSGarrett D'Amore 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; 13095c635efSGarrett D'Amore case (MDOC_TBL): 13195c635efSGarrett D'Amore /* FALLTHROUGH */ 13295c635efSGarrett D'Amore case (MDOC_EQN): 13395c635efSGarrett D'Amore break; 13495c635efSGarrett D'Amore case (MDOC_ROOT): 13595c635efSGarrett D'Amore p = "root"; 13695c635efSGarrett D'Amore break; 13795c635efSGarrett D'Amore default: 13895c635efSGarrett D'Amore abort(); 13995c635efSGarrett D'Amore /* NOTREACHED */ 14095c635efSGarrett D'Amore } 14195c635efSGarrett D'Amore 14295c635efSGarrett D'Amore if (n->span) { 14395c635efSGarrett D'Amore assert(NULL == p && NULL == t); 14495c635efSGarrett D'Amore print_span(n->span, indent); 14595c635efSGarrett D'Amore } else if (n->eqn) { 14695c635efSGarrett D'Amore assert(NULL == p && NULL == t); 14795c635efSGarrett D'Amore print_box(n->eqn->root, indent); 14895c635efSGarrett D'Amore } else { 14995c635efSGarrett D'Amore for (i = 0; i < indent; i++) 15095c635efSGarrett D'Amore putchar('\t'); 15195c635efSGarrett D'Amore 15295c635efSGarrett D'Amore printf("%s (%s)", p, t); 15395c635efSGarrett D'Amore 15495c635efSGarrett D'Amore for (i = 0; i < (int)argc; i++) { 15595c635efSGarrett D'Amore printf(" -%s", mdoc_argnames[argv[i].arg]); 15695c635efSGarrett D'Amore if (argv[i].sz > 0) 15795c635efSGarrett D'Amore printf(" ["); 15895c635efSGarrett D'Amore for (j = 0; j < (int)argv[i].sz; j++) 15995c635efSGarrett D'Amore printf(" [%s]", argv[i].value[j]); 16095c635efSGarrett D'Amore if (argv[i].sz > 0) 16195c635efSGarrett D'Amore printf(" ]"); 16295c635efSGarrett D'Amore } 16395c635efSGarrett D'Amore 164*698f87a4SGarrett D'Amore putchar(' '); 165*698f87a4SGarrett D'Amore if (MDOC_LINE & n->flags) 166*698f87a4SGarrett D'Amore putchar('*'); 167*698f87a4SGarrett D'Amore printf("%d:%d", n->line, n->pos); 168*698f87a4SGarrett D'Amore if (n->lastline != n->line) 169*698f87a4SGarrett D'Amore printf("-%d", n->lastline); 170*698f87a4SGarrett D'Amore putchar('\n'); 17195c635efSGarrett D'Amore } 17295c635efSGarrett D'Amore 17395c635efSGarrett D'Amore if (n->child) 17495c635efSGarrett D'Amore print_mdoc(n->child, indent + 1); 17595c635efSGarrett D'Amore if (n->next) 17695c635efSGarrett D'Amore print_mdoc(n->next, indent); 17795c635efSGarrett D'Amore } 17895c635efSGarrett D'Amore 17995c635efSGarrett D'Amore 18095c635efSGarrett D'Amore static void 18195c635efSGarrett D'Amore print_man(const struct man_node *n, int indent) 18295c635efSGarrett D'Amore { 18395c635efSGarrett D'Amore const char *p, *t; 18495c635efSGarrett D'Amore int i; 18595c635efSGarrett D'Amore 18695c635efSGarrett D'Amore t = p = NULL; 18795c635efSGarrett D'Amore 18895c635efSGarrett D'Amore switch (n->type) { 18995c635efSGarrett D'Amore case (MAN_ROOT): 19095c635efSGarrett D'Amore t = "root"; 19195c635efSGarrett D'Amore break; 19295c635efSGarrett D'Amore case (MAN_ELEM): 19395c635efSGarrett D'Amore t = "elem"; 19495c635efSGarrett D'Amore break; 19595c635efSGarrett D'Amore case (MAN_TEXT): 19695c635efSGarrett D'Amore t = "text"; 19795c635efSGarrett D'Amore break; 19895c635efSGarrett D'Amore case (MAN_BLOCK): 19995c635efSGarrett D'Amore t = "block"; 20095c635efSGarrett D'Amore break; 20195c635efSGarrett D'Amore case (MAN_HEAD): 20295c635efSGarrett D'Amore t = "block-head"; 20395c635efSGarrett D'Amore break; 20495c635efSGarrett D'Amore case (MAN_BODY): 20595c635efSGarrett D'Amore t = "block-body"; 20695c635efSGarrett D'Amore break; 20795c635efSGarrett D'Amore case (MAN_TAIL): 20895c635efSGarrett D'Amore t = "block-tail"; 20995c635efSGarrett D'Amore break; 21095c635efSGarrett D'Amore case (MAN_TBL): 21195c635efSGarrett D'Amore /* FALLTHROUGH */ 21295c635efSGarrett D'Amore case (MAN_EQN): 21395c635efSGarrett D'Amore break; 21495c635efSGarrett D'Amore default: 21595c635efSGarrett D'Amore abort(); 21695c635efSGarrett D'Amore /* NOTREACHED */ 21795c635efSGarrett D'Amore } 21895c635efSGarrett D'Amore 21995c635efSGarrett D'Amore switch (n->type) { 22095c635efSGarrett D'Amore case (MAN_TEXT): 22195c635efSGarrett D'Amore p = n->string; 22295c635efSGarrett D'Amore break; 22395c635efSGarrett D'Amore case (MAN_ELEM): 22495c635efSGarrett D'Amore /* FALLTHROUGH */ 22595c635efSGarrett D'Amore case (MAN_BLOCK): 22695c635efSGarrett D'Amore /* FALLTHROUGH */ 22795c635efSGarrett D'Amore case (MAN_HEAD): 22895c635efSGarrett D'Amore /* FALLTHROUGH */ 22995c635efSGarrett D'Amore case (MAN_TAIL): 23095c635efSGarrett D'Amore /* FALLTHROUGH */ 23195c635efSGarrett D'Amore case (MAN_BODY): 23295c635efSGarrett D'Amore p = man_macronames[n->tok]; 23395c635efSGarrett D'Amore break; 23495c635efSGarrett D'Amore case (MAN_ROOT): 23595c635efSGarrett D'Amore p = "root"; 23695c635efSGarrett D'Amore break; 23795c635efSGarrett D'Amore case (MAN_TBL): 23895c635efSGarrett D'Amore /* FALLTHROUGH */ 23995c635efSGarrett D'Amore case (MAN_EQN): 24095c635efSGarrett D'Amore break; 24195c635efSGarrett D'Amore default: 24295c635efSGarrett D'Amore abort(); 24395c635efSGarrett D'Amore /* NOTREACHED */ 24495c635efSGarrett D'Amore } 24595c635efSGarrett D'Amore 24695c635efSGarrett D'Amore if (n->span) { 24795c635efSGarrett D'Amore assert(NULL == p && NULL == t); 24895c635efSGarrett D'Amore print_span(n->span, indent); 24995c635efSGarrett D'Amore } else if (n->eqn) { 25095c635efSGarrett D'Amore assert(NULL == p && NULL == t); 25195c635efSGarrett D'Amore print_box(n->eqn->root, indent); 25295c635efSGarrett D'Amore } else { 25395c635efSGarrett D'Amore for (i = 0; i < indent; i++) 25495c635efSGarrett D'Amore putchar('\t'); 25595c635efSGarrett D'Amore printf("%s (%s) %d:%d\n", p, t, n->line, n->pos); 25695c635efSGarrett D'Amore } 25795c635efSGarrett D'Amore 25895c635efSGarrett D'Amore if (n->child) 25995c635efSGarrett D'Amore print_man(n->child, indent + 1); 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 27095c635efSGarrett D'Amore if (NULL == ep) 27195c635efSGarrett D'Amore return; 27295c635efSGarrett D'Amore for (i = 0; i < indent; i++) 27395c635efSGarrett D'Amore putchar('\t'); 27495c635efSGarrett D'Amore 27595c635efSGarrett D'Amore t = NULL; 27695c635efSGarrett D'Amore switch (ep->type) { 27795c635efSGarrett D'Amore case (EQN_ROOT): 27895c635efSGarrett D'Amore t = "eqn-root"; 27995c635efSGarrett D'Amore break; 28095c635efSGarrett D'Amore case (EQN_LIST): 28195c635efSGarrett D'Amore t = "eqn-list"; 28295c635efSGarrett D'Amore break; 28395c635efSGarrett D'Amore case (EQN_SUBEXPR): 28495c635efSGarrett D'Amore t = "eqn-expr"; 28595c635efSGarrett D'Amore break; 28695c635efSGarrett D'Amore case (EQN_TEXT): 28795c635efSGarrett D'Amore t = "eqn-text"; 28895c635efSGarrett D'Amore break; 28995c635efSGarrett D'Amore case (EQN_MATRIX): 29095c635efSGarrett D'Amore t = "eqn-matrix"; 29195c635efSGarrett D'Amore break; 29295c635efSGarrett D'Amore } 29395c635efSGarrett D'Amore 29495c635efSGarrett D'Amore assert(t); 29595c635efSGarrett D'Amore printf("%s(%d, %d, %d, %d, %d, \"%s\", \"%s\") %s\n", 29695c635efSGarrett D'Amore t, EQN_DEFSIZE == ep->size ? 0 : ep->size, 29795c635efSGarrett D'Amore ep->pos, ep->font, ep->mark, ep->pile, 29895c635efSGarrett D'Amore ep->left ? ep->left : "", 29995c635efSGarrett D'Amore ep->right ? ep->right : "", 30095c635efSGarrett D'Amore ep->text ? ep->text : ""); 30195c635efSGarrett D'Amore 30295c635efSGarrett D'Amore print_box(ep->first, indent + 1); 30395c635efSGarrett D'Amore print_box(ep->next, indent); 30495c635efSGarrett D'Amore } 30595c635efSGarrett D'Amore 30695c635efSGarrett D'Amore static void 30795c635efSGarrett D'Amore print_span(const struct tbl_span *sp, int indent) 30895c635efSGarrett D'Amore { 30995c635efSGarrett D'Amore const struct tbl_dat *dp; 31095c635efSGarrett D'Amore int i; 31195c635efSGarrett D'Amore 31295c635efSGarrett D'Amore for (i = 0; i < indent; i++) 31395c635efSGarrett D'Amore putchar('\t'); 31495c635efSGarrett D'Amore 31595c635efSGarrett D'Amore switch (sp->pos) { 31695c635efSGarrett D'Amore case (TBL_SPAN_HORIZ): 31795c635efSGarrett D'Amore putchar('-'); 31895c635efSGarrett D'Amore return; 31995c635efSGarrett D'Amore case (TBL_SPAN_DHORIZ): 32095c635efSGarrett D'Amore putchar('='); 32195c635efSGarrett D'Amore return; 32295c635efSGarrett D'Amore default: 32395c635efSGarrett D'Amore break; 32495c635efSGarrett D'Amore } 32595c635efSGarrett D'Amore 32695c635efSGarrett D'Amore for (dp = sp->first; dp; dp = dp->next) { 32795c635efSGarrett D'Amore switch (dp->pos) { 32895c635efSGarrett D'Amore case (TBL_DATA_HORIZ): 32995c635efSGarrett D'Amore /* FALLTHROUGH */ 33095c635efSGarrett D'Amore case (TBL_DATA_NHORIZ): 33195c635efSGarrett D'Amore putchar('-'); 33295c635efSGarrett D'Amore continue; 33395c635efSGarrett D'Amore case (TBL_DATA_DHORIZ): 33495c635efSGarrett D'Amore /* FALLTHROUGH */ 33595c635efSGarrett D'Amore case (TBL_DATA_NDHORIZ): 33695c635efSGarrett D'Amore putchar('='); 33795c635efSGarrett D'Amore continue; 33895c635efSGarrett D'Amore default: 33995c635efSGarrett D'Amore break; 34095c635efSGarrett D'Amore } 34195c635efSGarrett D'Amore printf("[\"%s\"", dp->string ? dp->string : ""); 34295c635efSGarrett D'Amore if (dp->spans) 34395c635efSGarrett D'Amore printf("(%d)", dp->spans); 34495c635efSGarrett D'Amore if (NULL == dp->layout) 34595c635efSGarrett D'Amore putchar('*'); 34695c635efSGarrett D'Amore putchar(']'); 34795c635efSGarrett D'Amore putchar(' '); 34895c635efSGarrett D'Amore } 34995c635efSGarrett D'Amore 35095c635efSGarrett D'Amore printf("(tbl) %d:1\n", sp->line); 35195c635efSGarrett D'Amore } 352