1 /****************************************************************************
   2  *
   3  * ftdebug.h
   4  *
   5  *   Debugging and logging component (specification).
   6  *
   7  * Copyright (C) 1996-2019 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  * IMPORTANT: A description of FreeType's debugging support can be
  18  *             found in 'docs/DEBUG.TXT'.  Read it if you need to use or
  19  *             understand this code.
  20  *
  21  */
  22 
  23 
  24 #ifndef FTDEBUG_H_
  25 #define FTDEBUG_H_
  26 
  27 
  28 #include <ft2build.h>
  29 #include FT_CONFIG_CONFIG_H
  30 #include FT_FREETYPE_H
  31 
  32 
  33 FT_BEGIN_HEADER
  34 
  35 
  36   /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
  37   /* is already defined; this simplifies the following #ifdefs            */
  38   /*                                                                      */
  39 #ifdef FT_DEBUG_LEVEL_TRACE
  40 #undef  FT_DEBUG_LEVEL_ERROR
  41 #define FT_DEBUG_LEVEL_ERROR
  42 #endif
  43 
  44 
  45   /**************************************************************************
  46    *
  47    * Define the trace enums as well as the trace levels array when they are
  48    * needed.
  49    *
  50    */
  51 
  52 #ifdef FT_DEBUG_LEVEL_TRACE
  53 
  54 #define FT_TRACE_DEF( x )  trace_ ## x ,
  55 
  56   /* defining the enumeration */
  57   typedef enum  FT_Trace_
  58   {
  59 #include FT_INTERNAL_TRACE_H
  60     trace_count
  61 
  62   } FT_Trace;
  63 
  64 
  65   /* a pointer to the array of trace levels, */
  66   /* provided by `src/base/ftdebug.c'        */
  67   extern int*  ft_trace_levels;
  68 
  69 #undef FT_TRACE_DEF
  70 
  71 #endif /* FT_DEBUG_LEVEL_TRACE */
  72 
  73 
  74   /**************************************************************************
  75    *
  76    * Define the FT_TRACE macro
  77    *
  78    * IMPORTANT!
  79    *
  80    * Each component must define the macro FT_COMPONENT to a valid FT_Trace
  81    * value before using any TRACE macro.
  82    *
  83    */
  84 
  85 #ifdef FT_DEBUG_LEVEL_TRACE
  86 
  87   /* we need two macros here to make cpp expand `FT_COMPONENT' */
  88 #define FT_TRACE_COMP( x )   FT_TRACE_COMP_( x )
  89 #define FT_TRACE_COMP_( x )  trace_ ## x
  90 
  91 #define FT_TRACE( level, varformat )                                       \
  92           do                                                               \
  93           {                                                                \
  94             if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
  95               FT_Message varformat;                                        \
  96           } while ( 0 )
  97 
  98 #else /* !FT_DEBUG_LEVEL_TRACE */
  99 
 100 #define FT_TRACE( level, varformat )  do { } while ( 0 )      /* nothing */
 101 
 102 #endif /* !FT_DEBUG_LEVEL_TRACE */
 103 
 104 
 105   /**************************************************************************
 106    *
 107    * @function:
 108    *   FT_Trace_Get_Count
 109    *
 110    * @description:
 111    *   Return the number of available trace components.
 112    *
 113    * @return:
 114    *   The number of trace components.  0 if FreeType 2 is not built with
 115    *   FT_DEBUG_LEVEL_TRACE definition.
 116    *
 117    * @note:
 118    *   This function may be useful if you want to access elements of the
 119    *   internal trace levels array by an index.
 120    */
 121   FT_BASE( FT_Int )
 122   FT_Trace_Get_Count( void );
 123 
 124 
 125   /**************************************************************************
 126    *
 127    * @function:
 128    *   FT_Trace_Get_Name
 129    *
 130    * @description:
 131    *   Return the name of a trace component.
 132    *
 133    * @input:
 134    *   The index of the trace component.
 135    *
 136    * @return:
 137    *   The name of the trace component.  This is a statically allocated
 138    *   C~string, so do not free it after use.  `NULL` if FreeType is not
 139    *   built with FT_DEBUG_LEVEL_TRACE definition.
 140    *
 141    * @note:
 142    *   Use @FT_Trace_Get_Count to get the number of available trace
 143    *   components.
 144    */
 145   FT_BASE( const char* )
 146   FT_Trace_Get_Name( FT_Int  idx );
 147 
 148 
 149   /**************************************************************************
 150    *
 151    * @function:
 152    *   FT_Trace_Disable
 153    *
 154    * @description:
 155    *   Switch off tracing temporarily.  It can be activated again with
 156    *   @FT_Trace_Enable.
 157    */
 158   FT_BASE( void )
 159   FT_Trace_Disable( void );
 160 
 161 
 162   /**************************************************************************
 163    *
 164    * @function:
 165    *   FT_Trace_Enable
 166    *
 167    * @description:
 168    *   Activate tracing.  Use it after tracing has been switched off with
 169    *   @FT_Trace_Disable.
 170    */
 171   FT_BASE( void )
 172   FT_Trace_Enable( void );
 173 
 174 
 175   /**************************************************************************
 176    *
 177    * You need two opening and closing parentheses!
 178    *
 179    * Example: FT_TRACE0(( "Value is %i", foo ))
 180    *
 181    * Output of the FT_TRACEX macros is sent to stderr.
 182    *
 183    */
 184 
 185 #define FT_TRACE0( varformat )  FT_TRACE( 0, varformat )
 186 #define FT_TRACE1( varformat )  FT_TRACE( 1, varformat )
 187 #define FT_TRACE2( varformat )  FT_TRACE( 2, varformat )
 188 #define FT_TRACE3( varformat )  FT_TRACE( 3, varformat )
 189 #define FT_TRACE4( varformat )  FT_TRACE( 4, varformat )
 190 #define FT_TRACE5( varformat )  FT_TRACE( 5, varformat )
 191 #define FT_TRACE6( varformat )  FT_TRACE( 6, varformat )
 192 #define FT_TRACE7( varformat )  FT_TRACE( 7, varformat )
 193 
 194 
 195   /**************************************************************************
 196    *
 197    * Define the FT_ERROR macro.
 198    *
 199    * Output of this macro is sent to stderr.
 200    *
 201    */
 202 
 203 #ifdef FT_DEBUG_LEVEL_ERROR
 204 
 205 #define FT_ERROR( varformat )  FT_Message  varformat
 206 
 207 #else  /* !FT_DEBUG_LEVEL_ERROR */
 208 
 209 #define FT_ERROR( varformat )  do { } while ( 0 )      /* nothing */
 210 
 211 #endif /* !FT_DEBUG_LEVEL_ERROR */
 212 
 213 
 214   /**************************************************************************
 215    *
 216    * Define the FT_ASSERT and FT_THROW macros.  The call to `FT_Throw` makes
 217    * it possible to easily set a breakpoint at this function.
 218    *
 219    */
 220 
 221 #ifdef FT_DEBUG_LEVEL_ERROR
 222 
 223 #define FT_ASSERT( condition )                                      \
 224           do                                                        \
 225           {                                                         \
 226             if ( !( condition ) )                                   \
 227               FT_Panic( "assertion failed on line %d of file %s\n", \
 228                         __LINE__, __FILE__ );                       \
 229           } while ( 0 )
 230 
 231 #define FT_THROW( e )                                   \
 232           ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ),   \
 233                       __LINE__,                         \
 234                       __FILE__ )                      | \
 235             FT_ERR_CAT( FT_ERR_PREFIX, e )            )
 236 
 237 #else /* !FT_DEBUG_LEVEL_ERROR */
 238 
 239 #define FT_ASSERT( condition )  do { } while ( 0 )
 240 
 241 #define FT_THROW( e )  FT_ERR_CAT( FT_ERR_PREFIX, e )
 242 
 243 #endif /* !FT_DEBUG_LEVEL_ERROR */
 244 
 245 
 246   /**************************************************************************
 247    *
 248    * Define `FT_Message` and `FT_Panic` when needed.
 249    *
 250    */
 251 
 252 #ifdef FT_DEBUG_LEVEL_ERROR
 253 
 254 #include "stdio.h"  /* for vfprintf() */
 255 
 256   /* print a message */
 257   FT_BASE( void )
 258   FT_Message( const char*  fmt,
 259               ... );
 260 
 261   /* print a message and exit */
 262   FT_BASE( void )
 263   FT_Panic( const char*  fmt,
 264             ... );
 265 
 266   /* report file name and line number of an error */
 267   FT_BASE( int )
 268   FT_Throw( FT_Error     error,
 269             int          line,
 270             const char*  file );
 271 
 272 #endif /* FT_DEBUG_LEVEL_ERROR */
 273 
 274 
 275   FT_BASE( void )
 276   ft_debug_init( void );
 277 
 278 FT_END_HEADER
 279 
 280 #endif /* FTDEBUG_H_ */
 281 
 282 
 283 /* END */