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