sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
ftdebug.h
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ftdebug.h
4 *
5 * Debugging and logging component (specification).
6 *
7 * Copyright (C) 1996-2025 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
28#ifndef FTDEBUG_H_
29#define FTDEBUG_H_
30
31
32#include <ft2build.h>
33#include FT_CONFIG_CONFIG_H
34#include <freetype/freetype.h>
35
36#include "compiler-macros.h"
37
38#ifdef FT_DEBUG_LOGGING
39#define DLG_STATIC
40#include <dlg/output.h>
41#include <dlg/dlg.h>
42
43#include <freetype/ftlogging.h>
44#endif /* FT_DEBUG_LOGGING */
45
46
47FT_BEGIN_HEADER
48
49 /* force the definition of FT_DEBUG_LEVEL_TRACE if FT_DEBUG_LOGGING is */
50 /* already defined. */
51 /* */
52#ifdef FT_DEBUG_LOGGING
53#undef FT_DEBUG_LEVEL_TRACE
54#define FT_DEBUG_LEVEL_TRACE
55#endif
56
57 /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
58 /* is already defined; this simplifies the following #ifdefs */
59 /* */
60#ifdef FT_DEBUG_LEVEL_TRACE
61#undef FT_DEBUG_LEVEL_ERROR
62#define FT_DEBUG_LEVEL_ERROR
63#endif
64
65
66 /**************************************************************************
67 *
68 * Define the trace enums as well as the trace levels array when they are
69 * needed.
70 *
71 */
72
73#ifdef FT_DEBUG_LEVEL_TRACE
74
75#define FT_TRACE_DEF( x ) trace_ ## x ,
76
77 /* defining the enumeration */
78 typedef enum FT_Trace_
79 {
81 trace_count
82
83 } FT_Trace;
84
85
86 /* a pointer to the array of trace levels, */
87 /* provided by `src/base/ftdebug.c' */
88 extern int* ft_trace_levels;
89
90#undef FT_TRACE_DEF
91
92#endif /* FT_DEBUG_LEVEL_TRACE */
93
94
95 /**************************************************************************
96 *
97 * Define the FT_TRACE macro
98 *
99 * IMPORTANT!
100 *
101 * Each component must define the macro FT_COMPONENT to a valid FT_Trace
102 * value before using any TRACE macro.
103 *
104 * To get consistent logging output, there should be no newline character
105 * (i.e., '\n') or a single trailing one in the message string of
106 * `FT_TRACEx` and `FT_ERROR`.
107 */
108
109
110 /*************************************************************************
111 *
112 * If FT_DEBUG_LOGGING is enabled, tracing messages are sent to dlg's API.
113 * If FT_DEBUG_LOGGING is disabled, tracing messages are sent to
114 * `FT_Message` (defined in ftdebug.c).
115 */
116#ifdef FT_DEBUG_LOGGING
117
118 /* we need two macros to convert the names of `FT_COMPONENT` to a string */
119#define FT_LOGGING_TAG( x ) FT_LOGGING_TAG_( x )
120#define FT_LOGGING_TAG_( x ) #x
121
122 /* we need two macros to convert the component and the trace level */
123 /* to a string that combines them */
124#define FT_LOGGING_TAGX( x, y ) FT_LOGGING_TAGX_( x, y )
125#define FT_LOGGING_TAGX_( x, y ) #x ":" #y
126
127
128#define FT_LOG( level, varformat ) \
129 do \
130 { \
131 const char* dlg_tag = FT_LOGGING_TAGX( FT_COMPONENT, level ); \
132 \
133 \
134 ft_add_tag( dlg_tag ); \
135 if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
136 { \
137 if ( custom_output_handler != NULL ) \
138 FT_Logging_Callback varformat; \
139 else \
140 dlg_trace varformat; \
141 } \
142 ft_remove_tag( dlg_tag ); \
143 } while( 0 )
144
145#else /* !FT_DEBUG_LOGGING */
146
147#define FT_LOG( level, varformat ) \
148 do \
149 { \
150 if ( ft_trace_levels[FT_TRACE_COMP( FT_COMPONENT )] >= level ) \
151 FT_Message varformat; \
152 } while ( 0 )
153
154#endif /* !FT_DEBUG_LOGGING */
155
156
157#ifdef FT_DEBUG_LEVEL_TRACE
158
159 /* we need two macros here to make cpp expand `FT_COMPONENT' */
160#define FT_TRACE_COMP( x ) FT_TRACE_COMP_( x )
161#define FT_TRACE_COMP_( x ) trace_ ## x
162
163#define FT_TRACE( level, varformat ) FT_LOG( level, varformat )
164
165#else /* !FT_DEBUG_LEVEL_TRACE */
166
167#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */
168
169#endif /* !FT_DEBUG_LEVEL_TRACE */
170
171
172 /**************************************************************************
173 *
174 * @function:
175 * FT_Trace_Get_Count
176 *
177 * @description:
178 * Return the number of available trace components.
179 *
180 * @return:
181 * The number of trace components. 0 if FreeType 2 is not built with
182 * FT_DEBUG_LEVEL_TRACE definition.
183 *
184 * @note:
185 * This function may be useful if you want to access elements of the
186 * internal trace levels array by an index.
187 */
188 FT_BASE( FT_Int )
189 FT_Trace_Get_Count( void );
190
191
192 /**************************************************************************
193 *
194 * @function:
195 * FT_Trace_Get_Name
196 *
197 * @description:
198 * Return the name of a trace component.
199 *
200 * @input:
201 * The index of the trace component.
202 *
203 * @return:
204 * The name of the trace component. This is a statically allocated
205 * C~string, so do not free it after use. `NULL` if FreeType is not
206 * built with FT_DEBUG_LEVEL_TRACE definition.
207 *
208 * @note:
209 * Use @FT_Trace_Get_Count to get the number of available trace
210 * components.
211 */
212 FT_BASE( const char* )
213 FT_Trace_Get_Name( FT_Int idx );
214
215
216 /**************************************************************************
217 *
218 * @function:
219 * FT_Trace_Disable
220 *
221 * @description:
222 * Switch off tracing temporarily. It can be activated again with
223 * @FT_Trace_Enable.
224 */
225 FT_BASE( void )
226 FT_Trace_Disable( void );
227
228
229 /**************************************************************************
230 *
231 * @function:
232 * FT_Trace_Enable
233 *
234 * @description:
235 * Activate tracing. Use it after tracing has been switched off with
236 * @FT_Trace_Disable.
237 */
238 FT_BASE( void )
239 FT_Trace_Enable( void );
240
241
242 /**************************************************************************
243 *
244 * You need two opening and closing parentheses!
245 *
246 * Example: FT_TRACE0(( "Value is %i", foo ))
247 *
248 * Output of the FT_TRACEX macros is sent to stderr.
249 *
250 */
251
252#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat )
253#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat )
254#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat )
255#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat )
256#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat )
257#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat )
258#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat )
259#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat )
260
261
262 /**************************************************************************
263 *
264 * Define the FT_ERROR macro.
265 *
266 * Output of this macro is sent to stderr.
267 *
268 */
269
270#ifdef FT_DEBUG_LEVEL_ERROR
271
272 /**************************************************************************
273 *
274 * If FT_DEBUG_LOGGING is enabled, error messages are sent to dlg's API.
275 * If FT_DEBUG_LOGGING is disabled, error messages are sent to `FT_Message`
276 * (defined in ftdebug.c).
277 *
278 */
279#ifdef FT_DEBUG_LOGGING
280
281#define FT_ERROR( varformat ) \
282 do \
283 { \
284 const char* dlg_tag = FT_LOGGING_TAG( FT_COMPONENT ); \
285 \
286 \
287 ft_add_tag( dlg_tag ); \
288 dlg_trace varformat; \
289 ft_remove_tag( dlg_tag ); \
290 } while ( 0 )
291
292#else /* !FT_DEBUG_LOGGING */
293
294#define FT_ERROR( varformat ) FT_Message varformat
295
296#endif /* !FT_DEBUG_LOGGING */
297
298
299#else /* !FT_DEBUG_LEVEL_ERROR */
300
301#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */
302
303#endif /* !FT_DEBUG_LEVEL_ERROR */
304
305
306 /**************************************************************************
307 *
308 * Define the FT_ASSERT and FT_THROW macros. The call to `FT_Throw` makes
309 * it possible to easily set a breakpoint at this function.
310 *
311 */
312
313#ifdef FT_DEBUG_LEVEL_ERROR
314
315#define FT_ASSERT( condition ) \
316 do \
317 { \
318 if ( !( condition ) ) \
319 FT_Panic( "assertion failed on line %d of file %s\n", \
320 __LINE__, __FILE__ ); \
321 } while ( 0 )
322
323#define FT_THROW( e ) \
324 ( FT_Throw( FT_ERR_CAT( FT_ERR_PREFIX, e ), \
325 __LINE__, \
326 __FILE__ ) | \
327 FT_ERR_CAT( FT_ERR_PREFIX, e ) )
328
329#else /* !FT_DEBUG_LEVEL_ERROR */
330
331#define FT_ASSERT( condition ) do { } while ( 0 )
332
333#define FT_THROW( e ) FT_ERR_CAT( FT_ERR_PREFIX, e )
334
335#endif /* !FT_DEBUG_LEVEL_ERROR */
336
337
338 /**************************************************************************
339 *
340 * Define `FT_Message` and `FT_Panic` when needed.
341 *
342 */
343
344#ifdef FT_DEBUG_LEVEL_ERROR
345
346#include "stdio.h" /* for vfprintf() */
347
348 /* print a message */
349 FT_BASE( void )
350 FT_Message( const char* fmt,
351 ... );
352
353 /* print a message and exit */
354 FT_BASE( void )
355 FT_Panic( const char* fmt,
356 ... );
357
358 /* report file name and line number of an error */
359 FT_BASE( int )
360 FT_Throw( FT_Error error,
361 int line,
362 const char* file );
363
364#endif /* FT_DEBUG_LEVEL_ERROR */
365
366
367 FT_BASE( void )
368 ft_debug_init( void );
369
370
371#ifdef FT_DEBUG_LOGGING
372
373 /**************************************************************************
374 *
375 * 'dlg' uses output handlers to control how and where log messages are
376 * printed. Therefore we need to define a default output handler for
377 * FreeType.
378 */
379 FT_BASE( void )
380 ft_log_handler( const struct dlg_origin* origin,
381 const char* string,
382 void* data );
383
384
385 /**************************************************************************
386 *
387 * 1. `ft_default_log_handler` stores the function pointer that is used
388 * internally by FreeType to print logs to a file.
389 *
390 * 2. `custom_output_handler` stores the function pointer to the callback
391 * function provided by the user.
392 *
393 * It is defined in `ftdebug.c`.
394 */
395 extern dlg_handler ft_default_log_handler;
396 extern FT_Custom_Log_Handler custom_output_handler;
397
398
399 /**************************************************************************
400 *
401 * If FT_DEBUG_LOGGING macro is enabled, FreeType needs to initialize and
402 * un-initialize `FILE*`.
403 *
404 * These functions are defined in `ftdebug.c`.
405 */
406 FT_BASE( void )
407 ft_logging_init( void );
408
409 FT_BASE( void )
410 ft_logging_deinit( void );
411
412
413 /**************************************************************************
414 *
415 * For printing the name of `FT_COMPONENT` along with the actual log we
416 * need to add a tag with the name of `FT_COMPONENT`.
417 *
418 * These functions are defined in `ftdebug.c`.
419 */
420 FT_BASE( void )
421 ft_add_tag( const char* tag );
422
423 FT_BASE( void )
424 ft_remove_tag( const char* tag );
425
426
427 /**************************************************************************
428 *
429 * A function to print log data using a custom callback logging function
430 * (which is set using `FT_Set_Log_Handler`).
431 *
432 * This function is defined in `ftdebug.c`.
433 */
434 FT_BASE( void )
435 FT_Logging_Callback( const char* fmt,
436 ... );
437
438#endif /* FT_DEBUG_LOGGING */
439
440
441FT_END_HEADER
442
443#endif /* FTDEBUG_H_ */
444
445
446/* END */