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