1 /****************************************************************************
   2  *
   3  * fterrors.h
   4  *
   5  *   FreeType error code handling (specification).
   6  *
   7  * Copyright (C) 1996-2020 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 FT_ERRORS_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 FT_MODULE_ERRORS_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 FT_ERROR_DEFINITIONS_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 if function prototypes should be       */
 236   /*                         included with `#include FT_ERRORS_H'.  This is */
 237   /*                         only true where `FT_ERRORDEF` is undefined.    */
 238   /* FT_ERR_PROTOS_DEFINED:  Actual multiple-inclusion protection of        */
 239   /*                         `fterrors.h`.                                  */
 240 #ifdef FT_INCLUDE_ERR_PROTOS
 241 #undef FT_INCLUDE_ERR_PROTOS
 242 
 243 #ifndef FT_ERR_PROTOS_DEFINED
 244 #define FT_ERR_PROTOS_DEFINED
 245 
 246 
 247 FT_BEGIN_HEADER
 248 
 249   /**************************************************************************
 250    *
 251    * @function:
 252    *   FT_Error_String
 253    *
 254    * @description:
 255    *   Retrieve the description of a valid FreeType error code.
 256    *
 257    * @input:
 258    *   error_code ::
 259    *     A valid FreeType error code.
 260    *
 261    * @return:
 262    *   A C~string or `NULL`, if any error occurred.
 263    *
 264    * @note:
 265    *   FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or
 266    *   `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions.
 267    *   'error_string' will be `NULL` otherwise.
 268    *
 269    *   Module identification will be ignored:
 270    *
 271    *   ```c
 272    *     strcmp( FT_Error_String(  FT_Err_Unknown_File_Format ),
 273    *             FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0;
 274    *   ```
 275    */
 276   FT_EXPORT( const char* )
 277   FT_Error_String( FT_Error  error_code );
 278 
 279 FT_END_HEADER
 280 
 281 
 282 #endif /* FT_ERR_PROTOS_DEFINED */
 283 
 284 #endif /* FT_INCLUDE_ERR_PROTOS */
 285 
 286 #endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
 287 
 288 
 289 /* END */