1/****************************************************************************
2 *
3 * fterrors.h
4 *
5 * FreeType error code handling (specification).
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 * @section:
22 * error_enumerations
23 *
24 * @title:
25 * Error Enumerations
26 *
27 * @abstract:
28 * How to handle errors and error strings.
29 *
30 * @description:
31 * The header file `fterrors.h` (which is automatically included by
32 * `freetype.h`) defines the handling of FreeType's enumeration
33 * constants. It can also be used to generate error message strings
34 * with a small macro trick explained below.
35 *
36 * **Error Formats**
37 *
38 * The configuration macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` can be
39 * defined in `ftoption.h` in order to make the higher byte indicate the
40 * module where the error has happened (this is not compatible with
41 * standard builds of FreeType~2, however). See the file `ftmoderr.h`
42 * for more details.
43 *
44 * **Error Message Strings**
45 *
46 * Error definitions are set up with special macros that allow client
47 * applications to build a table of error message strings. The strings
48 * are not included in a normal build of FreeType~2 to save space (most
49 * client applications do not use them).
50 *
51 * To do so, you have to define the following macros before including
52 * this file.
53 *
54 * ```
55 * FT_ERROR_START_LIST
56 * ```
57 *
58 * This macro is called before anything else to define the start of the
59 * error list. It is followed by several `FT_ERROR_DEF` calls.
60 *
61 * ```
62 * FT_ERROR_DEF( e, v, s )
63 * ```
64 *
65 * This macro is called to define one single error. 'e' is the error
66 * code identifier (e.g., `Invalid_Argument`), 'v' is the error's
67 * numerical value, and 's' is the corresponding error string.
68 *
69 * ```
70 * FT_ERROR_END_LIST
71 * ```
72 *
73 * This macro ends the list.
74 *
75 * Additionally, you have to undefine `FTERRORS_H_` before #including
76 * this file.
77 *
78 * Here is a simple example.
79 *
80 * ```
81 * #undef FTERRORS_H_
82 * #define FT_ERRORDEF( e, v, s ) { e, s },
83 * #define FT_ERROR_START_LIST {
84 * #define FT_ERROR_END_LIST { 0, NULL } };
85 *
86 * const struct
87 * {
88 * int err_code;
89 * const char* err_msg;
90 * } ft_errors[] =
91 *
92 * #include <freetype/fterrors.h>
93 * ```
94 *
95 * An alternative to using an array is a switch statement.
96 *
97 * ```
98 * #undef FTERRORS_H_
99 * #define FT_ERROR_START_LIST switch ( error_code ) {
100 * #define FT_ERRORDEF( e, v, s ) case v: return s;
101 * #define FT_ERROR_END_LIST }
102 * ```
103 *
104 * If you use `FT_CONFIG_OPTION_USE_MODULE_ERRORS`, `error_code` should
105 * be replaced with `FT_ERROR_BASE(error_code)` in the last example.
106 */
107
108 /* */
109
110 /* In previous FreeType versions we used `__FTERRORS_H__`. However, */
111 /* using two successive underscores in a non-system symbol name */
112 /* violates the C (and C++) standard, so it was changed to the */
113 /* current form. In spite of this, we have to make */
114 /* */
115 /* ``` */
116 /* #undefine __FTERRORS_H__ */
117 /* ``` */
118 /* */
119 /* work for backward compatibility. */
120 /* */
121#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) )
122#define FTERRORS_H_
123#define __FTERRORS_H__
124
125
126 /* include module base error codes */
127#include <freetype/ftmoderr.h>
128
129
130 /*******************************************************************/
131 /*******************************************************************/
132 /***** *****/
133 /***** SETUP MACROS *****/
134 /***** *****/
135 /*******************************************************************/
136 /*******************************************************************/
137
138
139#undef FT_NEED_EXTERN_C
140
141
142 /* FT_ERR_PREFIX is used as a prefix for error identifiers. */
143 /* By default, we use `FT_Err_`. */
144 /* */
145#ifndef FT_ERR_PREFIX
146#define FT_ERR_PREFIX FT_Err_
147#endif
148
149
150 /* FT_ERR_BASE is used as the base for module-specific errors. */
151 /* */
152#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
153
154#ifndef FT_ERR_BASE
155#define FT_ERR_BASE FT_Mod_Err_Base
156#endif
157
158#else
159
160#undef FT_ERR_BASE
161#define FT_ERR_BASE 0
162
163#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */
164
165
166 /* If FT_ERRORDEF is not defined, we need to define a simple */
167 /* enumeration type. */
168 /* */
169#ifndef FT_ERRORDEF
170
171#define FT_INCLUDE_ERR_PROTOS
172
173#define FT_ERRORDEF( e, v, s ) e = v,
174#define FT_ERROR_START_LIST enum {
175#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
176
177#ifdef __cplusplus
178#define FT_NEED_EXTERN_C
179 extern "C" {
180#endif
181
182#endif /* !FT_ERRORDEF */
183
184
185 /* this macro is used to define an error */
186#define FT_ERRORDEF_( e, v, s ) \
187 FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
188
189 /* this is only used for <module>_Err_Ok, which must be 0! */
190#define FT_NOERRORDEF_( e, v, s ) \
191 FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
192
193
194#ifdef FT_ERROR_START_LIST
195 FT_ERROR_START_LIST
196#endif
197
198
199 /* now include the error codes */
200#include <freetype/fterrdef.h>
201
202
203#ifdef FT_ERROR_END_LIST
204 FT_ERROR_END_LIST
205#endif
206
207
208 /*******************************************************************/
209 /*******************************************************************/
210 /***** *****/
211 /***** SIMPLE CLEANUP *****/
212 /***** *****/
213 /*******************************************************************/
214 /*******************************************************************/
215
216#ifdef FT_NEED_EXTERN_C
217 }
218#endif
219
220#undef FT_ERROR_START_LIST
221#undef FT_ERROR_END_LIST
222
223#undef FT_ERRORDEF
224#undef FT_ERRORDEF_
225#undef FT_NOERRORDEF_
226
227#undef FT_NEED_EXTERN_C
228#undef FT_ERR_BASE
229
230 /* FT_ERR_PREFIX is needed internally */
231#ifndef FT2_BUILD_LIBRARY
232#undef FT_ERR_PREFIX
233#endif
234
235 /* FT_INCLUDE_ERR_PROTOS: Control whether function prototypes should be */
236 /* included with */
237 /* */
238 /* #include <freetype/fterrors.h> */
239 /* */
240 /* This is only true where `FT_ERRORDEF` is */
241 /* undefined. */
242 /* */
243 /* FT_ERR_PROTOS_DEFINED: Actual multiple-inclusion protection of */
244 /* `fterrors.h`. */
245#ifdef FT_INCLUDE_ERR_PROTOS
246#undef FT_INCLUDE_ERR_PROTOS
247
248#ifndef FT_ERR_PROTOS_DEFINED
249#define FT_ERR_PROTOS_DEFINED
250
251
252FT_BEGIN_HEADER
253
254 /**************************************************************************
255 *
256 * @function:
257 * FT_Error_String
258 *
259 * @description:
260 * Retrieve the description of a valid FreeType error code.
261 *
262 * @input:
263 * error_code ::
264 * A valid FreeType error code.
265 *
266 * @return:
267 * A C~string or `NULL`, if any error occurred.
268 *
269 * @note:
270 * FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or
271 * `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions.
272 * 'error_string' will be `NULL` otherwise.
273 *
274 * Module identification will be ignored:
275 *
276 * ```c
277 * strcmp( FT_Error_String( FT_Err_Unknown_File_Format ),
278 * FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0;
279 * ```
280 */
281 FT_EXPORT( const char* )
282 FT_Error_String( FT_Error error_code );
283
284 /* */
285
286FT_END_HEADER
287
288
289#endif /* FT_ERR_PROTOS_DEFINED */
290
291#endif /* FT_INCLUDE_ERR_PROTOS */
292
293#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
294
295
296/* END */
297