442 lines
13 KiB
C
442 lines
13 KiB
C
/****************************************************************************
|
|
*
|
|
* ftdebug.h
|
|
*
|
|
* Debugging and logging component (specification).
|
|
*
|
|
* Copyright (C) 1996-2021 by
|
|
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
|
*
|
|
* This file is part of the FreeType project, and may only be used,
|
|
* modified, and distributed under the terms of the FreeType project
|
|
* license, LICENSE.TXT. By continuing to use, modify, or distribute
|
|
* this file you indicate that you have read the license and
|
|
* understand and accept it fully.
|
|
*
|
|
*
|
|
* IMPORTANT: A description of FreeType's debugging support can be
|
|
* found in 'docs/DEBUG.TXT'. Read it if you need to use or
|
|
* understand this code.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef FTDEBUG_H_
|
|
#define FTDEBUG_H_
|
|
|
|
|
|
#include <ft2build.h>
|
|
#include FT_CONFIG_CONFIG_H
|
|
#include <freetype/freetype.h>
|
|
|
|
#include "compiler-macros.h"
|
|
|
|
#ifdef FT_DEBUG_LOGGING
|
|
#include <dlg/output.h>
|
|
#include <dlg/dlg.h>
|
|
|
|
#include <freetype/ftlogging.h>
|
|
#endif /* FT_DEBUG_LOGGING */
|
|
|
|
|
|
FT_BEGIN_HEADER
|
|
|
|
/* force the definition of FT_DEBUG_LEVEL_TRACE if FT_DEBUG_LOGGING is */
|
|
/* already defined. */
|
|
/* */
|
|
#ifdef FT_DEBUG_LOGGING
|
|
#undef FT_DEBUG_LEVEL_TRACE
|
|
#define FT_DEBUG_LEVEL_TRACE
|
|
#endif
|
|
|
|
/* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
|
|
/* is already defined; this simplifies the following #ifdefs */
|
|
/* */
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
#undef FT_DEBUG_LEVEL_ERROR
|
|
#define FT_DEBUG_LEVEL_ERROR
|
|
#endif
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Define the trace enums as well as the trace levels array when they are
|
|
* needed.
|
|
*
|
|
*/
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
|
#define FT_TRACE_DEF( x ) trace_ ## x ,
|
|
|
|
/* defining the enumeration */
|
|
typedef enum FT_Trace_
|
|
{
|
|
#include <freetype/internal/fttrace.h>
|
|
trace_count
|
|
|
|
} FT_Trace;
|
|
|
|
|
|
/* a pointer to the array of trace levels, */
|
|
/* provided by `src/base/ftdebug.c' */
|
|
extern int* ft_trace_levels;
|
|
|
|
#undef FT_TRACE_DEF
|
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Define the FT_TRACE macro
|
|
*
|
|
* IMPORTANT!
|
|
*
|
|
* Each component must define the macro FT_COMPONENT to a valid FT_Trace
|
|
* value before using any TRACE macro.
|
|
*
|
|
* To get consistent logging output, there should be no newline character
|
|
* (i.e., '\n') or a single trailing one in the message string of
|
|
* `FT_TRACEx` and `FT_ERROR`.
|
|
*/
|
|
|
|
|
|
/*************************************************************************
|
|
*
|
|
* If FT_DEBUG_LOGGING is enabled, tracing messages are sent to dlg's API.
|
|
* If FT_DEBUG_LOGGING is disabled, tracing messages are sent to
|
|
* `FT_Message` (defined in ftdebug.c).
|
|
*/
|
|
#ifdef FT_DEBUG_LOGGING
|
|
|
|
/* we need two macros to convert the names of `FT_COMPONENT` to a string */
|
|
#define FT_LOGGING_TAG( x ) FT_LOGGING_TAG_( x )
|
|
#define FT_LOGGING_TAG_( x ) #x
|
|
|
|
/* we need two macros to convert the component and the trace level */
|
|
/* to a string that combines them */
|
|
#define FT_LOGGING_TAGX( x, y ) FT_LOGGING_TAGX_( x, y )
|
|
#define FT_LOGGING_TAGX_( x, y ) #x ":" #y
|
|
|
|
|
|
#define FT_LOG( level, varformat ) \
|
|
do \
|
|
{ \
|
|
const char* dlg_tag = FT_LOGGING_TAGX( FT_COMPONENT, level ); \
|
|
\
|
|
\
|
|
ft_add_tag( dlg_tag ); \
|
|
if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
|
|
{ \
|
|
if ( custom_output_handler != NULL ) \
|
|
FT_Logging_Callback varformat; \
|
|
else \
|
|
dlg_trace varformat; \
|
|
} \
|
|
ft_remove_tag( dlg_tag ); \
|
|
} while( 0 )
|
|
|
|
#else /* !FT_DEBUG_LOGGING */
|
|
|
|
#define FT_LOG( level, varformat ) \
|
|
do \
|
|
{ \
|
|
if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
|
|
FT_Message varformat; \
|
|
} while ( 0 )
|
|
|
|
#endif /* !FT_DEBUG_LOGGING */
|
|
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
|
|
|
/* we need two macros here to make cpp expand `FT_COMPONENT' */
|
|
#define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x )
|
|
#define FT_TRACE_COMP_( x ) trace_ ## x
|
|
|
|
#define FT_TRACE( level, varformat ) FT_LOG( level, varformat )
|
|
|
|
#else /* !FT_DEBUG_LEVEL_TRACE */
|
|
|
|
#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */
|
|
|
|
#endif /* !FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* @function:
|
|
* FT_Trace_Get_Count
|
|
*
|
|
* @description:
|
|
* Return the number of available trace components.
|
|
*
|
|
* @return:
|
|
* The number of trace components. 0 if FreeType 2 is not built with
|
|
* FT_DEBUG_LEVEL_TRACE definition.
|
|
*
|
|
* @note:
|
|
* This function may be useful if you want to access elements of the
|
|
* internal trace levels array by an index.
|
|
*/
|
|
FT_BASE( FT_Int )
|
|
FT_Trace_Get_Count( void );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* @function:
|
|
* FT_Trace_Get_Name
|
|
*
|
|
* @description:
|
|
* Return the name of a trace component.
|
|
*
|
|
* @input:
|
|
* The index of the trace component.
|
|
*
|
|
* @return:
|
|
* The name of the trace component. This is a statically allocated
|
|
* C~string, so do not free it after use. `NULL` if FreeType is not
|
|
* built with FT_DEBUG_LEVEL_TRACE definition.
|
|
*
|
|
* @note:
|
|
* Use @FT_Trace_Get_Count to get the number of available trace
|
|
* components.
|
|
*/
|
|
FT_BASE( const char* )
|
|
FT_Trace_Get_Name( FT_Int idx );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* @function:
|
|
* FT_Trace_Disable
|
|
*
|
|
* @description:
|
|
* Switch off tracing temporarily. It can be activated again with
|
|
* @FT_Trace_Enable.
|
|
*/
|
|
FT_BASE( void )
|
|
FT_Trace_Disable( void );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* @function:
|
|
* FT_Trace_Enable
|
|
*
|
|
* @description:
|
|
* Activate tracing. Use it after tracing has been switched off with
|
|
* @FT_Trace_Disable.
|
|
*/
|
|
FT_BASE( void )
|
|
FT_Trace_Enable( void );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* You need two opening and closing parentheses!
|
|
*
|
|
* Example: FT_TRACE0(( "Value is %i", foo ))
|
|
*
|
|
* Output of the FT_TRACEX macros is sent to stderr.
|
|
*
|
|
*/
|
|
|
|
#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat )
|
|
#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat )
|
|
#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat )
|
|
#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat )
|
|
#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat )
|
|
#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat )
|
|
#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat )
|
|
#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat )
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Define the FT_ERROR macro.
|
|
*
|
|
* Output of this macro is sent to stderr.
|
|
*
|
|
*/
|
|
|
|
#ifdef FT_DEBUG_LEVEL_ERROR
|
|
|
|
/**************************************************************************
|
|
*
|
|
* If FT_DEBUG_LOGGING is enabled, error messages are sent to dlg's API.
|
|
* If FT_DEBUG_LOGGING is disabled, error messages are sent to `FT_Message`
|
|
* (defined in ftdebug.c).
|
|
*
|
|
*/
|
|
#ifdef FT_DEBUG_LOGGING
|
|
|
|
#define FT_ERROR( varformat ) \
|
|
do \
|
|
{ \
|
|
const char* dlg_tag = FT_LOGGING_TAG( FT_COMPONENT ); \
|
|
\
|
|
\
|
|
ft_add_tag( dlg_tag ); \
|
|
dlg_trace varformat; \
|
|
ft_remove_tag( dlg_tag ); \
|
|
} while ( 0 )
|
|
|
|
#else /* !FT_DEBUG_LOGGING */
|
|
|
|
#define FT_ERROR( varformat ) FT_Message varformat
|
|
|
|
#endif /* !FT_DEBUG_LOGGING */
|
|
|
|
|
|
#else /* !FT_DEBUG_LEVEL_ERROR */
|
|
|
|
#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */
|
|
|
|
#endif /* !FT_DEBUG_LEVEL_ERROR */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw` makes
|
|
* it possible to easily set a breakpoint at this function.
|
|
*
|
|
*/
|
|
|
|
#ifdef FT_DEBUG_LEVEL_ERROR
|
|
|
|
#define FT_ASSERT( condition ) \
|
|
do \
|
|
{ \
|
|
if ( !( condition ) ) \
|
|
FT_Panic( "assertion failed on line %d of file %s\n", \
|
|
__LINE__, __FILE__ ); \
|
|
} while ( 0 )
|
|
|
|
#define FT_THROW( e ) \
|
|
( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \
|
|
__LINE__, \
|
|
__FILE__ ) | \
|
|
FT_ERR_CAT( FT_ERR_PREFIX, e ) )
|
|
|
|
#else /* !FT_DEBUG_LEVEL_ERROR */
|
|
|
|
#define FT_ASSERT( condition ) do { } while ( 0 )
|
|
|
|
#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e )
|
|
|
|
#endif /* !FT_DEBUG_LEVEL_ERROR */
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Define `FT_Message` and `FT_Panic` when needed.
|
|
*
|
|
*/
|
|
|
|
#ifdef FT_DEBUG_LEVEL_ERROR
|
|
|
|
#include "stdio.h" /* for vfprintf() */
|
|
|
|
/* print a message */
|
|
FT_BASE( void )
|
|
FT_Message( const char* fmt,
|
|
... );
|
|
|
|
/* print a message and exit */
|
|
FT_BASE( void )
|
|
FT_Panic( const char* fmt,
|
|
... );
|
|
|
|
/* report file name and line number of an error */
|
|
FT_BASE( int )
|
|
FT_Throw( FT_Error error,
|
|
int line,
|
|
const char* file );
|
|
|
|
#endif /* FT_DEBUG_LEVEL_ERROR */
|
|
|
|
|
|
FT_BASE( void )
|
|
ft_debug_init( void );
|
|
|
|
|
|
#ifdef FT_DEBUG_LOGGING
|
|
|
|
/**************************************************************************
|
|
*
|
|
* 'dlg' uses output handlers to control how and where log messages are
|
|
* printed. Therefore we need to define a default output handler for
|
|
* FreeType.
|
|
*/
|
|
FT_BASE( void )
|
|
ft_log_handler( const struct dlg_origin* origin,
|
|
const char* string,
|
|
void* data );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* 1. `ft_default_log_handler` stores the function pointer that is used
|
|
* internally by FreeType to print logs to a file.
|
|
*
|
|
* 2. `custom_output_handler` stores the function pointer to the callback
|
|
* function provided by the user.
|
|
*
|
|
* It is defined in `ftdebug.c`.
|
|
*/
|
|
extern dlg_handler ft_default_log_handler;
|
|
extern FT_Custom_Log_Handler custom_output_handler;
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* If FT_DEBUG_LOGGING macro is enabled, FreeType needs to initialize and
|
|
* un-initialize `FILE*`.
|
|
*
|
|
* These functions are defined in `ftdebug.c`.
|
|
*/
|
|
FT_BASE( void )
|
|
ft_logging_init( void );
|
|
|
|
FT_BASE( void )
|
|
ft_logging_deinit( void );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* For printing the name of `FT_COMPONENT` along with the actual log we
|
|
* need to add a tag with the name of `FT_COMPONENT`.
|
|
*
|
|
* These functions are defined in `ftdebug.c`.
|
|
*/
|
|
FT_BASE( void )
|
|
ft_add_tag( const char* tag );
|
|
|
|
FT_BASE( void )
|
|
ft_remove_tag( const char* tag );
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* A function to print log data using a custom callback logging function
|
|
* (which is set using `FT_Set_Log_Handler`).
|
|
*
|
|
* This function is defined in `ftdebug.c`.
|
|
*/
|
|
FT_BASE( void )
|
|
FT_Logging_Callback( const char* fmt,
|
|
... );
|
|
|
|
#endif /* FT_DEBUG_LOGGING */
|
|
|
|
|
|
FT_END_HEADER
|
|
|
|
#endif /* FTDEBUG_H_ */
|
|
|
|
|
|
/* END */
|