1 /* $NetBSD: debug.c,v 1.7 2021/12/21 21:04:08 rillig Exp $ */ 2 3 /*- 4 * Copyright (c) 2021 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Roland Illig <rillig@NetBSD.org>. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #if HAVE_NBTOOL_CONFIG_H 33 #include "nbtool_config.h" 34 #endif 35 36 #include <sys/cdefs.h> 37 #if defined(__RCSID) && !defined(lint) 38 __RCSID("$NetBSD: debug.c,v 1.7 2021/12/21 21:04:08 rillig Exp $"); 39 #endif 40 41 #include <stdlib.h> 42 43 #include "lint1.h" 44 45 46 #ifdef DEBUG 47 48 static int debug_indentation = 0; 49 50 51 void __printflike(1, 2) 52 debug_printf(const char *fmt, ...) 53 { 54 va_list va; 55 56 va_start(va, fmt); 57 vfprintf(stdout, fmt, va); 58 va_end(va); 59 } 60 61 void 62 debug_print_indent(void) 63 { 64 65 debug_printf("%*s", 2 * debug_indentation, ""); 66 } 67 68 void 69 debug_indent_inc(void) 70 { 71 72 debug_indentation++; 73 } 74 75 void 76 debug_indent_dec(void) 77 { 78 79 debug_indentation--; 80 } 81 82 void 83 (debug_enter)(const char *func) 84 { 85 86 printf("%*s+ %s\n", 2 * debug_indentation++, "", func); 87 } 88 89 void __printflike(1, 2) 90 debug_step(const char *fmt, ...) 91 { 92 va_list va; 93 94 debug_print_indent(); 95 va_start(va, fmt); 96 vfprintf(stdout, fmt, va); 97 va_end(va); 98 printf("\n"); 99 } 100 101 void 102 (debug_leave)(const char *func) 103 { 104 105 printf("%*s- %s\n", 2 * --debug_indentation, "", func); 106 } 107 108 void 109 debug_node(const tnode_t *tn) 110 { 111 op_t op; 112 113 if (tn == NULL) { 114 debug_step("null"); 115 return; 116 } 117 118 op = tn->tn_op; 119 debug_print_indent(); 120 debug_printf("'%s' with type '%s'%s%s%s", 121 op == CVT && !tn->tn_cast ? "convert" : modtab[op].m_name, 122 type_name(tn->tn_type), tn->tn_lvalue ? ", lvalue" : "", 123 tn->tn_parenthesized ? ", parenthesized" : "", 124 tn->tn_sys ? ", sys" : ""); 125 126 if (op == NAME) 127 debug_printf(" %s %s\n", tn->tn_sym->s_name, 128 storage_class_name(tn->tn_sym->s_scl)); 129 else if (op == CON && is_floating(tn->tn_type->t_tspec)) 130 debug_printf(", value %Lg", tn->tn_val->v_ldbl); 131 else if (op == CON && is_uinteger(tn->tn_type->t_tspec)) 132 debug_printf(", value %llu\n", (unsigned long long)tn->tn_val->v_quad); 133 else if (op == CON && is_integer(tn->tn_type->t_tspec)) 134 debug_printf(", value %lld\n", (long long)tn->tn_val->v_quad); 135 else if (op == CON && tn->tn_type->t_tspec == BOOL) 136 debug_printf(", value %s\n", 137 tn->tn_val->v_quad != 0 ? "true" : "false"); 138 else if (op == CON) 139 debug_printf(", unknown value\n"); 140 else if (op == STRING && tn->tn_string->st_tspec == CHAR) 141 debug_printf(", length %zu, \"%s\"\n", 142 tn->tn_string->st_len, tn->tn_string->st_cp); 143 else if (op == STRING && tn->tn_string->st_tspec == WCHAR) { 144 char *s; 145 size_t n; 146 n = MB_CUR_MAX * (tn->tn_string->st_len + 1); 147 s = xmalloc(n); 148 (void)wcstombs(s, tn->tn_string->st_wcp, n); 149 debug_printf(", length %zu, L\"%s\"", 150 tn->tn_string->st_len, s); 151 free(s); 152 153 } else { 154 debug_printf("\n"); 155 156 debug_indent_inc(); 157 debug_node(tn->tn_left); 158 if (is_binary(tn) || tn->tn_right != NULL) 159 debug_node(tn->tn_right); 160 debug_indent_dec(); 161 } 162 } 163 164 #endif 165