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 <freetype/freetype.h> 45 #include <freetype/internal/ftdebug.h> 46 47 48 #ifdef FT_DEBUG_LEVEL_ERROR 49 50 /* documentation is in ftdebug.h */ 51 52 FT_BASE_DEF( void ) FT_Message(const char * fmt,...)53 FT_Message( const char* fmt, 54 ... ) 55 { 56 va_list ap; 57 58 59 va_start( ap, fmt ); 60 vfprintf( stderr, fmt, ap ); 61 va_end( ap ); 62 } 63 64 65 /* documentation is in ftdebug.h */ 66 67 FT_BASE_DEF( void ) FT_Panic(const char * fmt,...)68 FT_Panic( const char* fmt, 69 ... ) 70 { 71 va_list ap; 72 73 74 va_start( ap, fmt ); 75 vfprintf( stderr, fmt, ap ); 76 va_end( ap ); 77 78 exit( EXIT_FAILURE ); 79 } 80 81 82 /* documentation is in ftdebug.h */ 83 84 FT_BASE_DEF( int ) FT_Throw(FT_Error error,int line,const char * file)85 FT_Throw( FT_Error error, 86 int line, 87 const char* file ) 88 { 89 #if 0 90 /* activating the code in this block makes FreeType very chatty */ 91 fprintf( stderr, 92 "%s:%d: error 0x%02x: %s\n", 93 file, 94 line, 95 error, 96 FT_Error_String( error ) ); 97 #else 98 FT_UNUSED( error ); 99 FT_UNUSED( line ); 100 FT_UNUSED( file ); 101 #endif 102 103 return 0; 104 } 105 106 #endif /* FT_DEBUG_LEVEL_ERROR */ 107 108 109 110 #ifdef FT_DEBUG_LEVEL_TRACE 111 112 /* array of trace levels, initialized to 0; */ 113 /* this gets adjusted at run-time */ 114 static int ft_trace_levels_enabled[trace_count]; 115 116 /* array of trace levels, always initialized to 0 */ 117 static int ft_trace_levels_disabled[trace_count]; 118 119 /* a pointer to either `ft_trace_levels_enabled' */ 120 /* or `ft_trace_levels_disabled' */ 121 int* ft_trace_levels; 122 123 /* define array of trace toggle names */ 124 #define FT_TRACE_DEF( x ) #x , 125 126 static const char* ft_trace_toggles[trace_count + 1] = 127 { 128 #include <freetype/internal/fttrace.h> 129 NULL 130 }; 131 132 #undef FT_TRACE_DEF 133 134 135 /* documentation is in ftdebug.h */ 136 137 FT_BASE_DEF( FT_Int ) FT_Trace_Get_Count(void)138 FT_Trace_Get_Count( void ) 139 { 140 return trace_count; 141 } 142 143 144 /* documentation is in ftdebug.h */ 145 146 FT_BASE_DEF( const char * ) FT_Trace_Get_Name(FT_Int idx)147 FT_Trace_Get_Name( FT_Int idx ) 148 { 149 int max = FT_Trace_Get_Count(); 150 151 152 if ( idx < max ) 153 return ft_trace_toggles[idx]; 154 else 155 return NULL; 156 } 157 158 159 /* documentation is in ftdebug.h */ 160 161 FT_BASE_DEF( void ) FT_Trace_Disable(void)162 FT_Trace_Disable( void ) 163 { 164 ft_trace_levels = ft_trace_levels_disabled; 165 } 166 167 168 /* documentation is in ftdebug.h */ 169 170 FT_BASE_DEF( void ) FT_Trace_Enable(void)171 FT_Trace_Enable( void ) 172 { 173 ft_trace_levels = ft_trace_levels_enabled; 174 } 175 176 177 /************************************************************************** 178 * 179 * Initialize the tracing sub-system. This is done by retrieving the 180 * value of the `FT2_DEBUG' environment variable. It must be a list of 181 * toggles, separated by spaces, `;', or `,'. Example: 182 * 183 * export FT2_DEBUG="any:3 memory:7 stream:5" 184 * 185 * This requests that all levels be set to 3, except the trace level for 186 * the memory and stream components which are set to 7 and 5, 187 * respectively. 188 * 189 * See the file `include/freetype/internal/fttrace.h' for details of 190 * the available toggle names. 191 * 192 * The level must be between 0 and 7; 0 means quiet (except for serious 193 * runtime errors), and 7 means _very_ verbose. 194 */ 195 FT_BASE_DEF( void ) ft_debug_init(void)196 ft_debug_init( void ) 197 { 198 const char* ft2_debug = ft_getenv( "FT2_DEBUG" ); 199 200 201 if ( ft2_debug ) 202 { 203 const char* p = ft2_debug; 204 const char* q; 205 206 207 for ( ; *p; p++ ) 208 { 209 /* skip leading whitespace and separators */ 210 if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) 211 continue; 212 213 /* read toggle name, followed by ':' */ 214 q = p; 215 while ( *p && *p != ':' ) 216 p++; 217 218 if ( !*p ) 219 break; 220 221 if ( *p == ':' && p > q ) 222 { 223 FT_Int n, i, len = (FT_Int)( p - q ); 224 FT_Int level = -1, found = -1; 225 226 227 for ( n = 0; n < trace_count; n++ ) 228 { 229 const char* toggle = ft_trace_toggles[n]; 230 231 232 for ( i = 0; i < len; i++ ) 233 { 234 if ( toggle[i] != q[i] ) 235 break; 236 } 237 238 if ( i == len && toggle[i] == 0 ) 239 { 240 found = n; 241 break; 242 } 243 } 244 245 /* read level */ 246 p++; 247 if ( *p ) 248 { 249 level = *p - '0'; 250 if ( level < 0 || level > 7 ) 251 level = -1; 252 } 253 254 if ( found >= 0 && level >= 0 ) 255 { 256 if ( found == trace_any ) 257 { 258 /* special case for `any' */ 259 for ( n = 0; n < trace_count; n++ ) 260 ft_trace_levels_enabled[n] = level; 261 } 262 else 263 ft_trace_levels_enabled[found] = level; 264 } 265 } 266 } 267 } 268 269 ft_trace_levels = ft_trace_levels_enabled; 270 } 271 272 273 #else /* !FT_DEBUG_LEVEL_TRACE */ 274 275 276 FT_BASE_DEF( void ) ft_debug_init(void)277 ft_debug_init( void ) 278 { 279 /* nothing */ 280 } 281 282 283 FT_BASE_DEF( FT_Int ) FT_Trace_Get_Count(void)284 FT_Trace_Get_Count( void ) 285 { 286 return 0; 287 } 288 289 290 FT_BASE_DEF( const char * ) FT_Trace_Get_Name(FT_Int idx)291 FT_Trace_Get_Name( FT_Int idx ) 292 { 293 FT_UNUSED( idx ); 294 295 return NULL; 296 } 297 298 299 FT_BASE_DEF( void ) FT_Trace_Disable(void)300 FT_Trace_Disable( void ) 301 { 302 /* nothing */ 303 } 304 305 306 /* documentation is in ftdebug.h */ 307 308 FT_BASE_DEF( void ) FT_Trace_Enable(void)309 FT_Trace_Enable( void ) 310 { 311 /* nothing */ 312 } 313 314 315 #endif /* !FT_DEBUG_LEVEL_TRACE */ 316 317 318 /* END */ 319