1 /**************************************************************************** 2 * 3 * ftdebug.c 4 * 5 * Debugging and logging component (body). 6 * 7 * Copyright (C) 1996-2020 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 /************************************************************************** 20 * 21 * This component contains various macros and functions used to ease the 22 * debugging of the FreeType engine. Its main purpose is in assertion 23 * checking, tracing, and error detection. 24 * 25 * There are now three debugging modes: 26 * 27 * - trace mode 28 * 29 * Error and trace messages are sent to the log file (which can be the 30 * standard error output). 31 * 32 * - error mode 33 * 34 * Only error messages are generated. 35 * 36 * - release mode: 37 * 38 * No error message is sent or generated. The code is free from any 39 * debugging parts. 40 * 41 */ 42 43 44 #include <ft2build.h> 45 #include FT_FREETYPE_H 46 #include FT_INTERNAL_DEBUG_H 47 48 49 #ifdef FT_DEBUG_LEVEL_ERROR 50 51 /* documentation is in ftdebug.h */ 52 53 FT_BASE_DEF( void ) 54 FT_Message( const char* fmt, 55 ... ) 56 { 57 va_list ap; 58 59 60 va_start( ap, fmt ); 61 vfprintf( stderr, fmt, ap ); 62 va_end( ap ); 63 } 64 65 66 /* documentation is in ftdebug.h */ 67 68 FT_BASE_DEF( void ) 69 FT_Panic( const char* fmt, 70 ... ) 71 { 72 va_list ap; 73 74 75 va_start( ap, fmt ); 76 vfprintf( stderr, fmt, ap ); 77 va_end( ap ); 78 79 exit( EXIT_FAILURE ); 80 } 81 82 83 /* documentation is in ftdebug.h */ 84 85 FT_BASE_DEF( int ) 86 FT_Throw( FT_Error error, 87 int line, 88 const char* file ) 89 { 90 #if 0 91 /* activating the code in this block makes FreeType very chatty */ 92 fprintf( stderr, 93 "%s:%d: error 0x%02x: %s\n", 94 file, 95 line, 96 error, 97 FT_Error_String( error ) ); 98 #else 99 FT_UNUSED( error ); 100 FT_UNUSED( line ); 101 FT_UNUSED( file ); 102 #endif 103 104 return 0; 105 } 106 107 #endif /* FT_DEBUG_LEVEL_ERROR */ 108 109 110 111 #ifdef FT_DEBUG_LEVEL_TRACE 112 113 /* array of trace levels, initialized to 0; */ 114 /* this gets adjusted at run-time */ 115 static int ft_trace_levels_enabled[trace_count]; 116 117 /* array of trace levels, always initialized to 0 */ 118 static int ft_trace_levels_disabled[trace_count]; 119 120 /* a pointer to either `ft_trace_levels_enabled' */ 121 /* or `ft_trace_levels_disabled' */ 122 int* ft_trace_levels; 123 124 /* define array of trace toggle names */ 125 #define FT_TRACE_DEF( x ) #x , 126 127 static const char* ft_trace_toggles[trace_count + 1] = 128 { 129 #include FT_INTERNAL_TRACE_H 130 NULL 131 }; 132 133 #undef FT_TRACE_DEF 134 135 136 /* documentation is in ftdebug.h */ 137 138 FT_BASE_DEF( FT_Int ) 139 FT_Trace_Get_Count( void ) 140 { 141 return trace_count; 142 } 143 144 145 /* documentation is in ftdebug.h */ 146 147 FT_BASE_DEF( const char * ) 148 FT_Trace_Get_Name( FT_Int idx ) 149 { 150 int max = FT_Trace_Get_Count(); 151 152 153 if ( idx < max ) 154 return ft_trace_toggles[idx]; 155 else 156 return NULL; 157 } 158 159 160 /* documentation is in ftdebug.h */ 161 162 FT_BASE_DEF( void ) 163 FT_Trace_Disable( void ) 164 { 165 ft_trace_levels = ft_trace_levels_disabled; 166 } 167 168 169 /* documentation is in ftdebug.h */ 170 171 FT_BASE_DEF( void ) 172 FT_Trace_Enable( void ) 173 { 174 ft_trace_levels = ft_trace_levels_enabled; 175 } 176 177 178 /************************************************************************** 179 * 180 * Initialize the tracing sub-system. This is done by retrieving the 181 * value of the `FT2_DEBUG' environment variable. It must be a list of 182 * toggles, separated by spaces, `;', or `,'. Example: 183 * 184 * export FT2_DEBUG="any:3 memory:7 stream:5" 185 * 186 * This requests that all levels be set to 3, except the trace level for 187 * the memory and stream components which are set to 7 and 5, 188 * respectively. 189 * 190 * See the file `include/freetype/internal/fttrace.h' for details of 191 * the available toggle names. 192 * 193 * The level must be between 0 and 7; 0 means quiet (except for serious 194 * runtime errors), and 7 means _very_ verbose. 195 */ 196 FT_BASE_DEF( void ) 197 ft_debug_init( void ) 198 { 199 const char* ft2_debug = ft_getenv( "FT2_DEBUG" ); 200 201 202 if ( ft2_debug ) 203 { 204 const char* p = ft2_debug; 205 const char* q; 206 207 208 for ( ; *p; p++ ) 209 { 210 /* skip leading whitespace and separators */ 211 if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) 212 continue; 213 214 /* read toggle name, followed by ':' */ 215 q = p; 216 while ( *p && *p != ':' ) 217 p++; 218 219 if ( !*p ) 220 break; 221 222 if ( *p == ':' && p > q ) 223 { 224 FT_Int n, i, len = (FT_Int)( p - q ); 225 FT_Int level = -1, found = -1; 226 227 228 for ( n = 0; n < trace_count; n++ ) 229 { 230 const char* toggle = ft_trace_toggles[n]; 231 232 233 for ( i = 0; i < len; i++ ) 234 { 235 if ( toggle[i] != q[i] ) 236 break; 237 } 238 239 if ( i == len && toggle[i] == 0 ) 240 { 241 found = n; 242 break; 243 } 244 } 245 246 /* read level */ 247 p++; 248 if ( *p ) 249 { 250 level = *p - '0'; 251 if ( level < 0 || level > 7 ) 252 level = -1; 253 } 254 255 if ( found >= 0 && level >= 0 ) 256 { 257 if ( found == trace_any ) 258 { 259 /* special case for `any' */ 260 for ( n = 0; n < trace_count; n++ ) 261 ft_trace_levels_enabled[n] = level; 262 } 263 else 264 ft_trace_levels_enabled[found] = level; 265 } 266 } 267 } 268 } 269 270 ft_trace_levels = ft_trace_levels_enabled; 271 } 272 273 274 #else /* !FT_DEBUG_LEVEL_TRACE */ 275 276 277 FT_BASE_DEF( void ) 278 ft_debug_init( void ) 279 { 280 /* nothing */ 281 } 282 283 284 FT_BASE_DEF( FT_Int ) 285 FT_Trace_Get_Count( void ) 286 { 287 return 0; 288 } 289 290 291 FT_BASE_DEF( const char * ) 292 FT_Trace_Get_Name( FT_Int idx ) 293 { 294 FT_UNUSED( idx ); 295 296 return NULL; 297 } 298 299 300 FT_BASE_DEF( void ) 301 FT_Trace_Disable( void ) 302 { 303 /* nothing */ 304 } 305 306 307 /* documentation is in ftdebug.h */ 308 309 FT_BASE_DEF( void ) 310 FT_Trace_Enable( void ) 311 { 312 /* nothing */ 313 } 314 315 316 #endif /* !FT_DEBUG_LEVEL_TRACE */ 317 318 319 /* END */