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