1 /* $Id: tree.c,v 1.37 2011/03/23 12:33:01 kristaps Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009 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 #ifdef HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include <assert.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <time.h> 25 26 #include "mandoc.h" 27 #include "mdoc.h" 28 #include "man.h" 29 #include "main.h" 30 31 static void print_mdoc(const struct mdoc_node *, int); 32 static void print_man(const struct man_node *, int); 33 static void print_span(const struct tbl_span *, int); 34 35 36 /* ARGSUSED */ 37 void 38 tree_mdoc(void *arg, const struct mdoc *mdoc) 39 { 40 41 print_mdoc(mdoc_node(mdoc), 0); 42 } 43 44 45 /* ARGSUSED */ 46 void 47 tree_man(void *arg, const struct man *man) 48 { 49 50 print_man(man_node(man), 0); 51 } 52 53 54 static void 55 print_mdoc(const struct mdoc_node *n, int indent) 56 { 57 const char *p, *t; 58 int i, j; 59 size_t argc, sz; 60 char **params; 61 struct mdoc_argv *argv; 62 63 argv = NULL; 64 argc = sz = 0; 65 params = NULL; 66 67 switch (n->type) { 68 case (MDOC_ROOT): 69 t = "root"; 70 break; 71 case (MDOC_BLOCK): 72 t = "block"; 73 break; 74 case (MDOC_HEAD): 75 t = "block-head"; 76 break; 77 case (MDOC_BODY): 78 if (n->end) 79 t = "body-end"; 80 else 81 t = "block-body"; 82 break; 83 case (MDOC_TAIL): 84 t = "block-tail"; 85 break; 86 case (MDOC_ELEM): 87 t = "elem"; 88 break; 89 case (MDOC_TEXT): 90 t = "text"; 91 break; 92 case (MDOC_TBL): 93 t = "tbl"; 94 break; 95 case (MDOC_EQN): 96 t = "eqn"; 97 break; 98 default: 99 abort(); 100 /* NOTREACHED */ 101 } 102 103 p = NULL; 104 105 switch (n->type) { 106 case (MDOC_TEXT): 107 p = n->string; 108 break; 109 case (MDOC_BODY): 110 p = mdoc_macronames[n->tok]; 111 break; 112 case (MDOC_HEAD): 113 p = mdoc_macronames[n->tok]; 114 break; 115 case (MDOC_TAIL): 116 p = mdoc_macronames[n->tok]; 117 break; 118 case (MDOC_ELEM): 119 p = mdoc_macronames[n->tok]; 120 if (n->args) { 121 argv = n->args->argv; 122 argc = n->args->argc; 123 } 124 break; 125 case (MDOC_BLOCK): 126 p = mdoc_macronames[n->tok]; 127 if (n->args) { 128 argv = n->args->argv; 129 argc = n->args->argc; 130 } 131 break; 132 case (MDOC_TBL): 133 break; 134 case (MDOC_EQN): 135 p = n->eqn->data; 136 break; 137 case (MDOC_ROOT): 138 p = "root"; 139 break; 140 default: 141 abort(); 142 /* NOTREACHED */ 143 } 144 145 if (n->span) { 146 assert(NULL == p); 147 print_span(n->span, indent); 148 } else { 149 for (i = 0; i < indent; i++) 150 putchar('\t'); 151 152 printf("%s (%s)", p, t); 153 154 for (i = 0; i < (int)argc; i++) { 155 printf(" -%s", mdoc_argnames[argv[i].arg]); 156 if (argv[i].sz > 0) 157 printf(" ["); 158 for (j = 0; j < (int)argv[i].sz; j++) 159 printf(" [%s]", argv[i].value[j]); 160 if (argv[i].sz > 0) 161 printf(" ]"); 162 } 163 164 for (i = 0; i < (int)sz; i++) 165 printf(" [%s]", params[i]); 166 167 printf(" %d:%d", n->line, n->pos); 168 } 169 170 putchar('\n'); 171 172 if (n->child) 173 print_mdoc(n->child, indent + 1); 174 if (n->next) 175 print_mdoc(n->next, indent); 176 } 177 178 179 static void 180 print_man(const struct man_node *n, int indent) 181 { 182 const char *p, *t; 183 int i; 184 185 switch (n->type) { 186 case (MAN_ROOT): 187 t = "root"; 188 break; 189 case (MAN_ELEM): 190 t = "elem"; 191 break; 192 case (MAN_TEXT): 193 t = "text"; 194 break; 195 case (MAN_BLOCK): 196 t = "block"; 197 break; 198 case (MAN_HEAD): 199 t = "block-head"; 200 break; 201 case (MAN_BODY): 202 t = "block-body"; 203 break; 204 case (MAN_TAIL): 205 t = "block-tail"; 206 break; 207 case (MAN_TBL): 208 t = "tbl"; 209 break; 210 case (MAN_EQN): 211 t = "eqn"; 212 break; 213 default: 214 abort(); 215 /* NOTREACHED */ 216 } 217 218 p = NULL; 219 220 switch (n->type) { 221 case (MAN_TEXT): 222 p = n->string; 223 break; 224 case (MAN_ELEM): 225 /* FALLTHROUGH */ 226 case (MAN_BLOCK): 227 /* FALLTHROUGH */ 228 case (MAN_HEAD): 229 /* FALLTHROUGH */ 230 case (MAN_TAIL): 231 /* FALLTHROUGH */ 232 case (MAN_BODY): 233 p = man_macronames[n->tok]; 234 break; 235 case (MAN_ROOT): 236 p = "root"; 237 break; 238 case (MAN_TBL): 239 break; 240 case (MAN_EQN): 241 p = n->eqn->data; 242 break; 243 default: 244 abort(); 245 /* NOTREACHED */ 246 } 247 248 if (n->span) { 249 assert(NULL == p); 250 print_span(n->span, indent); 251 } else { 252 for (i = 0; i < indent; i++) 253 putchar('\t'); 254 printf("%s (%s) %d:%d", p, t, n->line, n->pos); 255 } 256 257 putchar('\n'); 258 259 if (n->child) 260 print_man(n->child, indent + 1); 261 if (n->next) 262 print_man(n->next, indent); 263 } 264 265 static void 266 print_span(const struct tbl_span *sp, int indent) 267 { 268 const struct tbl_dat *dp; 269 int i; 270 271 for (i = 0; i < indent; i++) 272 putchar('\t'); 273 274 switch (sp->pos) { 275 case (TBL_SPAN_HORIZ): 276 putchar('-'); 277 return; 278 case (TBL_SPAN_DHORIZ): 279 putchar('='); 280 return; 281 default: 282 break; 283 } 284 285 for (dp = sp->first; dp; dp = dp->next) { 286 switch (dp->pos) { 287 case (TBL_DATA_HORIZ): 288 /* FALLTHROUGH */ 289 case (TBL_DATA_NHORIZ): 290 putchar('-'); 291 continue; 292 case (TBL_DATA_DHORIZ): 293 /* FALLTHROUGH */ 294 case (TBL_DATA_NDHORIZ): 295 putchar('='); 296 continue; 297 default: 298 break; 299 } 300 printf("[\"%s\"", dp->string ? dp->string : ""); 301 if (dp->spans) 302 printf("(%d)", dp->spans); 303 if (NULL == dp->layout) 304 putchar('*'); 305 putchar(']'); 306 putchar(' '); 307 } 308 309 printf("(tbl) %d:1", sp->line); 310 } 311