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