1 /* $Vendor-Id: tree.c,v 1.31 2011/01/03 13:59:21 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 default: 96 abort(); 97 /* NOTREACHED */ 98 } 99 100 p = NULL; 101 102 switch (n->type) { 103 case (MDOC_TEXT): 104 p = n->string; 105 break; 106 case (MDOC_BODY): 107 p = mdoc_macronames[n->tok]; 108 break; 109 case (MDOC_HEAD): 110 p = mdoc_macronames[n->tok]; 111 break; 112 case (MDOC_TAIL): 113 p = mdoc_macronames[n->tok]; 114 break; 115 case (MDOC_ELEM): 116 p = mdoc_macronames[n->tok]; 117 if (n->args) { 118 argv = n->args->argv; 119 argc = n->args->argc; 120 } 121 break; 122 case (MDOC_BLOCK): 123 p = mdoc_macronames[n->tok]; 124 if (n->args) { 125 argv = n->args->argv; 126 argc = n->args->argc; 127 } 128 break; 129 case (MDOC_TBL): 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); 141 print_span(n->span, indent); 142 } else { 143 for (i = 0; i < indent; i++) 144 putchar('\t'); 145 146 printf("%s (%s)", p, t); 147 148 for (i = 0; i < (int)argc; i++) { 149 printf(" -%s", mdoc_argnames[argv[i].arg]); 150 if (argv[i].sz > 0) 151 printf(" ["); 152 for (j = 0; j < (int)argv[i].sz; j++) 153 printf(" [%s]", argv[i].value[j]); 154 if (argv[i].sz > 0) 155 printf(" ]"); 156 } 157 158 for (i = 0; i < (int)sz; i++) 159 printf(" [%s]", params[i]); 160 161 printf(" %d:%d", n->line, n->pos); 162 } 163 164 putchar('\n'); 165 166 if (n->child) 167 print_mdoc(n->child, indent + 1); 168 if (n->next) 169 print_mdoc(n->next, indent); 170 } 171 172 173 static void 174 print_man(const struct man_node *n, int indent) 175 { 176 const char *p, *t; 177 int i; 178 179 switch (n->type) { 180 case (MAN_ROOT): 181 t = "root"; 182 break; 183 case (MAN_ELEM): 184 t = "elem"; 185 break; 186 case (MAN_TEXT): 187 t = "text"; 188 break; 189 case (MAN_BLOCK): 190 t = "block"; 191 break; 192 case (MAN_HEAD): 193 t = "block-head"; 194 break; 195 case (MAN_BODY): 196 t = "block-body"; 197 break; 198 case (MAN_TBL): 199 t = "tbl"; 200 break; 201 default: 202 abort(); 203 /* NOTREACHED */ 204 } 205 206 p = NULL; 207 208 switch (n->type) { 209 case (MAN_TEXT): 210 p = n->string; 211 break; 212 case (MAN_ELEM): 213 /* FALLTHROUGH */ 214 case (MAN_BLOCK): 215 /* FALLTHROUGH */ 216 case (MAN_HEAD): 217 /* FALLTHROUGH */ 218 case (MAN_BODY): 219 p = man_macronames[n->tok]; 220 break; 221 case (MAN_ROOT): 222 p = "root"; 223 break; 224 case (MAN_TBL): 225 break; 226 default: 227 abort(); 228 /* NOTREACHED */ 229 } 230 231 if (n->span) { 232 assert(NULL == p); 233 print_span(n->span, indent); 234 } else { 235 for (i = 0; i < indent; i++) 236 putchar('\t'); 237 printf("%s (%s) %d:%d", p, t, n->line, n->pos); 238 } 239 240 putchar('\n'); 241 242 if (n->child) 243 print_man(n->child, indent + 1); 244 if (n->next) 245 print_man(n->next, indent); 246 } 247 248 static void 249 print_span(const struct tbl_span *sp, int indent) 250 { 251 const struct tbl_dat *dp; 252 int i; 253 254 for (i = 0; i < indent; i++) 255 putchar('\t'); 256 257 printf("tbl: "); 258 259 switch (sp->pos) { 260 case (TBL_SPAN_HORIZ): 261 putchar('-'); 262 return; 263 case (TBL_SPAN_DHORIZ): 264 putchar('='); 265 return; 266 default: 267 break; 268 } 269 270 for (dp = sp->first; dp; dp = dp->next) { 271 switch (dp->pos) { 272 case (TBL_DATA_HORIZ): 273 /* FALLTHROUGH */ 274 case (TBL_DATA_NHORIZ): 275 putchar('-'); 276 continue; 277 case (TBL_DATA_DHORIZ): 278 /* FALLTHROUGH */ 279 case (TBL_DATA_NDHORIZ): 280 putchar('='); 281 continue; 282 default: 283 break; 284 } 285 printf("[%s%s]", dp->string, dp->layout ? "" : "*"); 286 if (dp->next) 287 putchar(' '); 288 } 289 } 290