xref: /freebsd/sys/contrib/zstd/lib/common/error_private.h (revision 5ff13fbc199bdf5f0572845351c68ee5ca828e71)
10c16b537SWarner Losh /*
2*5ff13fbcSAllan Jude  * Copyright (c) Yann Collet, Facebook, Inc.
30c16b537SWarner Losh  * All rights reserved.
40c16b537SWarner Losh  *
50c16b537SWarner Losh  * This source code is licensed under both the BSD-style license (found in the
60c16b537SWarner Losh  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
70c16b537SWarner Losh  * in the COPYING file in the root directory of this source tree).
80c16b537SWarner Losh  * You may select, at your option, one of the above-listed licenses.
90c16b537SWarner Losh  */
100c16b537SWarner Losh 
110c16b537SWarner Losh /* Note : this module is expected to remain private, do not expose it */
120c16b537SWarner Losh 
130c16b537SWarner Losh #ifndef ERROR_H_MODULE
140c16b537SWarner Losh #define ERROR_H_MODULE
150c16b537SWarner Losh 
160c16b537SWarner Losh #if defined (__cplusplus)
170c16b537SWarner Losh extern "C" {
180c16b537SWarner Losh #endif
190c16b537SWarner Losh 
200c16b537SWarner Losh 
210c16b537SWarner Losh /* ****************************************
220c16b537SWarner Losh *  Dependencies
230c16b537SWarner Losh ******************************************/
24*5ff13fbcSAllan Jude #include "../zstd_errors.h"  /* enum list */
25*5ff13fbcSAllan Jude #include "compiler.h"
26*5ff13fbcSAllan Jude #include "debug.h"
27f7cd7fe5SConrad Meyer #include "zstd_deps.h"       /* size_t */
280c16b537SWarner Losh 
290c16b537SWarner Losh 
300c16b537SWarner Losh /* ****************************************
310c16b537SWarner Losh *  Compiler-specific
320c16b537SWarner Losh ******************************************/
330c16b537SWarner Losh #if defined(__GNUC__)
340c16b537SWarner Losh #  define ERR_STATIC static __attribute__((unused))
350c16b537SWarner Losh #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
360c16b537SWarner Losh #  define ERR_STATIC static inline
370c16b537SWarner Losh #elif defined(_MSC_VER)
380c16b537SWarner Losh #  define ERR_STATIC static __inline
390c16b537SWarner Losh #else
400c16b537SWarner Losh #  define ERR_STATIC static  /* this version may generate warnings for unused static functions; disable the relevant warning */
410c16b537SWarner Losh #endif
420c16b537SWarner Losh 
430c16b537SWarner Losh 
440c16b537SWarner Losh /*-****************************************
450c16b537SWarner Losh *  Customization (error_public.h)
460c16b537SWarner Losh ******************************************/
470c16b537SWarner Losh typedef ZSTD_ErrorCode ERR_enum;
480c16b537SWarner Losh #define PREFIX(name) ZSTD_error_##name
490c16b537SWarner Losh 
500c16b537SWarner Losh 
510c16b537SWarner Losh /*-****************************************
520c16b537SWarner Losh *  Error codes handling
530c16b537SWarner Losh ******************************************/
5437f1f268SConrad Meyer #undef ERROR   /* already defined on Visual Studio */
550c16b537SWarner Losh #define ERROR(name) ZSTD_ERROR(name)
560c16b537SWarner Losh #define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
570c16b537SWarner Losh 
ERR_isError(size_t code)580c16b537SWarner Losh ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
590c16b537SWarner Losh 
ERR_getErrorCode(size_t code)600c16b537SWarner Losh ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
610c16b537SWarner Losh 
6237f1f268SConrad Meyer /* check and forward error code */
6337f1f268SConrad Meyer #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
6437f1f268SConrad Meyer #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
6537f1f268SConrad Meyer 
660c16b537SWarner Losh 
670c16b537SWarner Losh /*-****************************************
680c16b537SWarner Losh *  Error Strings
690c16b537SWarner Losh ******************************************/
700c16b537SWarner Losh 
710c16b537SWarner Losh const char* ERR_getErrorString(ERR_enum code);   /* error_private.c */
720c16b537SWarner Losh 
ERR_getErrorName(size_t code)730c16b537SWarner Losh ERR_STATIC const char* ERR_getErrorName(size_t code)
740c16b537SWarner Losh {
750c16b537SWarner Losh     return ERR_getErrorString(ERR_getErrorCode(code));
760c16b537SWarner Losh }
770c16b537SWarner Losh 
78*5ff13fbcSAllan Jude /**
79*5ff13fbcSAllan Jude  * Ignore: this is an internal helper.
80*5ff13fbcSAllan Jude  *
81*5ff13fbcSAllan Jude  * This is a helper function to help force C99-correctness during compilation.
82*5ff13fbcSAllan Jude  * Under strict compilation modes, variadic macro arguments can't be empty.
83*5ff13fbcSAllan Jude  * However, variadic function arguments can be. Using a function therefore lets
84*5ff13fbcSAllan Jude  * us statically check that at least one (string) argument was passed,
85*5ff13fbcSAllan Jude  * independent of the compilation flags.
86*5ff13fbcSAllan Jude  */
87*5ff13fbcSAllan Jude static INLINE_KEYWORD UNUSED_ATTR
_force_has_format_string(const char * format,...)88*5ff13fbcSAllan Jude void _force_has_format_string(const char *format, ...) {
89*5ff13fbcSAllan Jude   (void)format;
90*5ff13fbcSAllan Jude }
91*5ff13fbcSAllan Jude 
92*5ff13fbcSAllan Jude /**
93*5ff13fbcSAllan Jude  * Ignore: this is an internal helper.
94*5ff13fbcSAllan Jude  *
95*5ff13fbcSAllan Jude  * We want to force this function invocation to be syntactically correct, but
96*5ff13fbcSAllan Jude  * we don't want to force runtime evaluation of its arguments.
97*5ff13fbcSAllan Jude  */
98*5ff13fbcSAllan Jude #define _FORCE_HAS_FORMAT_STRING(...) \
99*5ff13fbcSAllan Jude   if (0) { \
100*5ff13fbcSAllan Jude     _force_has_format_string(__VA_ARGS__); \
101*5ff13fbcSAllan Jude   }
102*5ff13fbcSAllan Jude 
103*5ff13fbcSAllan Jude #define ERR_QUOTE(str) #str
104*5ff13fbcSAllan Jude 
105*5ff13fbcSAllan Jude /**
106*5ff13fbcSAllan Jude  * Return the specified error if the condition evaluates to true.
107*5ff13fbcSAllan Jude  *
108*5ff13fbcSAllan Jude  * In debug modes, prints additional information.
109*5ff13fbcSAllan Jude  * In order to do that (particularly, printing the conditional that failed),
110*5ff13fbcSAllan Jude  * this can't just wrap RETURN_ERROR().
111*5ff13fbcSAllan Jude  */
112*5ff13fbcSAllan Jude #define RETURN_ERROR_IF(cond, err, ...) \
113*5ff13fbcSAllan Jude   if (cond) { \
114*5ff13fbcSAllan Jude     RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
115*5ff13fbcSAllan Jude            __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
116*5ff13fbcSAllan Jude     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
117*5ff13fbcSAllan Jude     RAWLOG(3, ": " __VA_ARGS__); \
118*5ff13fbcSAllan Jude     RAWLOG(3, "\n"); \
119*5ff13fbcSAllan Jude     return ERROR(err); \
120*5ff13fbcSAllan Jude   }
121*5ff13fbcSAllan Jude 
122*5ff13fbcSAllan Jude /**
123*5ff13fbcSAllan Jude  * Unconditionally return the specified error.
124*5ff13fbcSAllan Jude  *
125*5ff13fbcSAllan Jude  * In debug modes, prints additional information.
126*5ff13fbcSAllan Jude  */
127*5ff13fbcSAllan Jude #define RETURN_ERROR(err, ...) \
128*5ff13fbcSAllan Jude   do { \
129*5ff13fbcSAllan Jude     RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
130*5ff13fbcSAllan Jude            __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
131*5ff13fbcSAllan Jude     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
132*5ff13fbcSAllan Jude     RAWLOG(3, ": " __VA_ARGS__); \
133*5ff13fbcSAllan Jude     RAWLOG(3, "\n"); \
134*5ff13fbcSAllan Jude     return ERROR(err); \
135*5ff13fbcSAllan Jude   } while(0);
136*5ff13fbcSAllan Jude 
137*5ff13fbcSAllan Jude /**
138*5ff13fbcSAllan Jude  * If the provided expression evaluates to an error code, returns that error code.
139*5ff13fbcSAllan Jude  *
140*5ff13fbcSAllan Jude  * In debug modes, prints additional information.
141*5ff13fbcSAllan Jude  */
142*5ff13fbcSAllan Jude #define FORWARD_IF_ERROR(err, ...) \
143*5ff13fbcSAllan Jude   do { \
144*5ff13fbcSAllan Jude     size_t const err_code = (err); \
145*5ff13fbcSAllan Jude     if (ERR_isError(err_code)) { \
146*5ff13fbcSAllan Jude       RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
147*5ff13fbcSAllan Jude              __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
148*5ff13fbcSAllan Jude       _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
149*5ff13fbcSAllan Jude       RAWLOG(3, ": " __VA_ARGS__); \
150*5ff13fbcSAllan Jude       RAWLOG(3, "\n"); \
151*5ff13fbcSAllan Jude       return err_code; \
152*5ff13fbcSAllan Jude     } \
153*5ff13fbcSAllan Jude   } while(0);
154*5ff13fbcSAllan Jude 
1550c16b537SWarner Losh #if defined (__cplusplus)
1560c16b537SWarner Losh }
1570c16b537SWarner Losh #endif
1580c16b537SWarner Losh 
1590c16b537SWarner Losh #endif /* ERROR_H_MODULE */
160