1 /****************************************************************************
2  *
3  * fterrors.h
4  *
5  *   FreeType error code handling (specification).
6  *
7  * Copyright (C) 1996-2022 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 
252 FT_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 
286 FT_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