1 /* $Id: tree.c,v 1.4 2009/09/21 20:57:57 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> 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 <err.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 22 #include "mdoc.h" 23 #include "man.h" 24 25 static void print_mdoc(const struct mdoc_node *, int); 26 static void print_man(const struct man_node *, int); 27 28 29 /* ARGSUSED */ 30 void 31 tree_mdoc(void *arg, const struct mdoc *mdoc) 32 { 33 34 print_mdoc(mdoc_node(mdoc), 0); 35 } 36 37 38 /* ARGSUSED */ 39 void 40 tree_man(void *arg, const struct man *man) 41 { 42 43 print_man(man_node(man), 0); 44 } 45 46 47 static void 48 print_mdoc(const struct mdoc_node *n, int indent) 49 { 50 const char *p, *t; 51 int i, j; 52 size_t argc, sz; 53 char **params; 54 struct mdoc_argv *argv; 55 56 argv = NULL; 57 argc = sz = 0; 58 params = NULL; 59 60 switch (n->type) { 61 case (MDOC_ROOT): 62 t = "root"; 63 break; 64 case (MDOC_BLOCK): 65 t = "block"; 66 break; 67 case (MDOC_HEAD): 68 t = "block-head"; 69 break; 70 case (MDOC_BODY): 71 t = "block-body"; 72 break; 73 case (MDOC_TAIL): 74 t = "block-tail"; 75 break; 76 case (MDOC_ELEM): 77 t = "elem"; 78 break; 79 case (MDOC_TEXT): 80 t = "text"; 81 break; 82 default: 83 abort(); 84 /* NOTREACHED */ 85 } 86 87 switch (n->type) { 88 case (MDOC_TEXT): 89 p = n->string; 90 break; 91 case (MDOC_BODY): 92 p = mdoc_macronames[n->tok]; 93 break; 94 case (MDOC_HEAD): 95 p = mdoc_macronames[n->tok]; 96 break; 97 case (MDOC_TAIL): 98 p = mdoc_macronames[n->tok]; 99 break; 100 case (MDOC_ELEM): 101 p = mdoc_macronames[n->tok]; 102 if (n->args) { 103 argv = n->args->argv; 104 argc = n->args->argc; 105 } 106 break; 107 case (MDOC_BLOCK): 108 p = mdoc_macronames[n->tok]; 109 if (n->args) { 110 argv = n->args->argv; 111 argc = n->args->argc; 112 } 113 break; 114 case (MDOC_ROOT): 115 p = "root"; 116 break; 117 default: 118 abort(); 119 /* NOTREACHED */ 120 } 121 122 for (i = 0; i < indent; i++) 123 (void)printf(" "); 124 (void)printf("%s (%s)", p, t); 125 126 for (i = 0; i < (int)argc; i++) { 127 (void)printf(" -%s", mdoc_argnames[argv[i].arg]); 128 if (argv[i].sz > 0) 129 (void)printf(" ["); 130 for (j = 0; j < (int)argv[i].sz; j++) 131 (void)printf(" [%s]", argv[i].value[j]); 132 if (argv[i].sz > 0) 133 (void)printf(" ]"); 134 } 135 136 for (i = 0; i < (int)sz; i++) 137 (void)printf(" [%s]", params[i]); 138 139 (void)printf(" %d:%d\n", n->line, n->pos); 140 141 if (n->child) 142 print_mdoc(n->child, indent + 1); 143 if (n->next) 144 print_mdoc(n->next, indent); 145 } 146 147 148 static void 149 print_man(const struct man_node *n, int indent) 150 { 151 const char *p, *t; 152 int i; 153 154 switch (n->type) { 155 case (MAN_ROOT): 156 t = "root"; 157 break; 158 case (MAN_ELEM): 159 t = "elem"; 160 break; 161 case (MAN_TEXT): 162 t = "text"; 163 break; 164 case (MAN_BLOCK): 165 t = "block"; 166 break; 167 case (MAN_HEAD): 168 t = "block-head"; 169 break; 170 case (MAN_BODY): 171 t = "block-body"; 172 break; 173 default: 174 abort(); 175 /* NOTREACHED */ 176 } 177 178 switch (n->type) { 179 case (MAN_TEXT): 180 p = n->string; 181 break; 182 case (MAN_ELEM): 183 /* FALLTHROUGH */ 184 case (MAN_BLOCK): 185 /* FALLTHROUGH */ 186 case (MAN_HEAD): 187 /* FALLTHROUGH */ 188 case (MAN_BODY): 189 p = man_macronames[n->tok]; 190 break; 191 case (MAN_ROOT): 192 p = "root"; 193 break; 194 default: 195 abort(); 196 /* NOTREACHED */ 197 } 198 199 for (i = 0; i < indent; i++) 200 (void)printf(" "); 201 (void)printf("%s (%s) %d:%d\n", p, t, n->line, n->pos); 202 203 if (n->child) 204 print_man(n->child, indent + 1); 205 if (n->next) 206 print_man(n->next, indent); 207 } 208