1 /** 2 * \file 3 * \brief 4 * Datatypes and functions for error reporting. 5 * 6 * Copyrights 7 * 8 * Portions created or assigned to Cisco Systems, Inc. are 9 * Copyright (c) 2014-2016 Cisco Systems, Inc. All Rights Reserved. 10 */ 11 #ifndef CJOSE_ERROR_H 12 #define CJOSE_ERROR_H 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** 19 * Temporarily disable compiler warnings, if possible (>=gcc-4.6). 20 * 21 * In some cases (particularly within macros), certain compiler warnings are 22 * unavoidable. In order to allow these warnings to be treated as errors in 23 * most cases, these macros will disable particular warnings only during 24 * specific points in the compilation. 25 */ 26 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 27 #define GCC_END_IGNORED_WARNING _Pragma("GCC diagnostic pop") 28 29 #define GCC_BEGIN_IGNORED_WARNING_ADDRESS \ 30 _Pragma("GCC diagnostic push"); \ 31 _Pragma("GCC diagnostic ignored \"-Waddress\"") 32 #define GCC_END_IGNORED_WARNING_ADDRESS GCC_END_IGNORED_WARNING 33 #else 34 #define GCC_BEGIN_IGNORED_WARNING_ADDRESS 35 #define GCC_END_IGNORED_WARNING_ADDRESS 36 #endif /* defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 5) */ 37 38 /** 39 * Enumeration of defined error codes. 40 */ 41 typedef enum { 42 /** No error */ 43 CJOSE_ERR_NONE = 0, 44 45 /** argument was invalid (beyond invariants) */ 46 CJOSE_ERR_INVALID_ARG, 47 48 /** context is not in a valid state */ 49 CJOSE_ERR_INVALID_STATE, 50 51 /** out of memory */ 52 CJOSE_ERR_NO_MEMORY, 53 54 /** an error returned from the crypto libraries */ 55 CJOSE_ERR_CRYPTO, 56 57 } cjose_errcode; 58 59 /** 60 * An instance of an error context. Unlike other structures, it 61 * is the API user's responsibility to allocate the structure; however 62 * the values provided are considered constants, and MUST NOT be 63 * deallocated. 64 */ 65 typedef struct 66 { 67 /** The error code */ 68 cjose_errcode code; 69 70 /** The human readable message for the error code */ 71 const char *message; 72 73 /** The function where the error occured, or "<unknown>" 74 if it cannot be determined */ 75 const char *function; 76 77 /** The file where the error occured */ 78 const char *file; 79 80 /** The line number in the file where the error occured */ 81 unsigned long line; 82 83 } cjose_err; 84 85 /** 86 * Retrieves the error message for the given error code. 87 * 88 * \param code The error code to lookup 89 * \retval const char * The message for {code} 90 */ 91 const char *cjose_err_message(cjose_errcode code); 92 93 /** 94 * \def CJOSE_ERROR(err, code) 95 * 96 * Macro to initialize an error context. 97 * 98 * \param err The pointer to the error context, or NULL if none 99 * \param errcode The error code 100 */ 101 #define CJOSE_ERROR(err, errcode) \ 102 GCC_BEGIN_IGNORED_WARNING_ADDRESS \ 103 if ((err) != NULL && (errcode) != CJOSE_ERR_NONE) \ 104 { \ 105 (err)->code = (errcode); \ 106 (err)->message = cjose_err_message((errcode)); \ 107 (err)->function = __func__; \ 108 (err)->file = __FILE__; \ 109 (err)->line = __LINE__; \ 110 } \ 111 GCC_END_IGNORED_WARNING_ADDRESS 112 113 #ifdef __cplusplus 114 } 115 #endif 116 117 #endif /* CJOSE_ERROR_H */ 118