1 /***************************************************************************/ 2 /* */ 3 /* ftdebug.c */ 4 /* */ 5 /* Debugging and logging component (body). */ 6 /* */ 7 /* Copyright 1996-2015 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 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 int ft_trace_levels[trace_count]; 105 106 107 /* define array of trace toggle names */ 108 #define FT_TRACE_DEF( x ) #x , 109 110 static const char* ft_trace_toggles[trace_count + 1] = 111 { 112 #include FT_INTERNAL_TRACE_H 113 NULL 114 }; 115 116 #undef FT_TRACE_DEF 117 118 119 /* documentation is in ftdebug.h */ 120 121 FT_BASE_DEF( FT_Int ) 122 FT_Trace_Get_Count( void ) 123 { 124 return trace_count; 125 } 126 127 128 /* documentation is in ftdebug.h */ 129 130 FT_BASE_DEF( const char * ) 131 FT_Trace_Get_Name( FT_Int idx ) 132 { 133 int max = FT_Trace_Get_Count(); 134 135 136 if ( idx < max ) 137 return ft_trace_toggles[idx]; 138 else 139 return NULL; 140 } 141 142 143 /*************************************************************************/ 144 /* */ 145 /* Initialize the tracing sub-system. This is done by retrieving the */ 146 /* value of the `FT2_DEBUG' environment variable. It must be a list of */ 147 /* toggles, separated by spaces, `;', or `,'. Example: */ 148 /* */ 149 /* export FT2_DEBUG="any:3 memory:7 stream:5" */ 150 /* */ 151 /* This requests that all levels be set to 3, except the trace level for */ 152 /* the memory and stream components which are set to 7 and 5, */ 153 /* respectively. */ 154 /* */ 155 /* See the file <include/internal/fttrace.h> for details of the */ 156 /* available toggle names. */ 157 /* */ 158 /* The level must be between 0 and 7; 0 means quiet (except for serious */ 159 /* runtime errors), and 7 means _very_ verbose. */ 160 /* */ 161 FT_BASE_DEF( void ) 162 ft_debug_init( void ) 163 { 164 const char* ft2_debug = getenv( "FT2_DEBUG" ); 165 166 167 if ( ft2_debug ) 168 { 169 const char* p = ft2_debug; 170 const char* q; 171 172 173 for ( ; *p; p++ ) 174 { 175 /* skip leading whitespace and separators */ 176 if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) 177 continue; 178 179 /* read toggle name, followed by ':' */ 180 q = p; 181 while ( *p && *p != ':' ) 182 p++; 183 184 if ( !*p ) 185 break; 186 187 if ( *p == ':' && p > q ) 188 { 189 FT_Int n, i, len = (FT_Int)( p - q ); 190 FT_Int level = -1, found = -1; 191 192 193 for ( n = 0; n < trace_count; n++ ) 194 { 195 const char* toggle = ft_trace_toggles[n]; 196 197 198 for ( i = 0; i < len; i++ ) 199 { 200 if ( toggle[i] != q[i] ) 201 break; 202 } 203 204 if ( i == len && toggle[i] == 0 ) 205 { 206 found = n; 207 break; 208 } 209 } 210 211 /* read level */ 212 p++; 213 if ( *p ) 214 { 215 level = *p - '0'; 216 if ( level < 0 || level > 7 ) 217 level = -1; 218 } 219 220 if ( found >= 0 && level >= 0 ) 221 { 222 if ( found == trace_any ) 223 { 224 /* special case for `any' */ 225 for ( n = 0; n < trace_count; n++ ) 226 ft_trace_levels[n] = level; 227 } 228 else 229 ft_trace_levels[found] = level; 230 } 231 } 232 } 233 } 234 } 235 236 237 #else /* !FT_DEBUG_LEVEL_TRACE */ 238 239 240 FT_BASE_DEF( void ) 241 ft_debug_init( void ) 242 { 243 /* nothing */ 244 } 245 246 247 FT_BASE_DEF( FT_Int ) 248 FT_Trace_Get_Count( void ) 249 { 250 return 0; 251 } 252 253 254 FT_BASE_DEF( const char * ) 255 FT_Trace_Get_Name( FT_Int idx ) 256 { 257 FT_UNUSED( idx ); 258 259 return NULL; 260 } 261 262 263 #endif /* !FT_DEBUG_LEVEL_TRACE */ 264 265 266 /* END */ 267