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