xref: /openbmc/linux/lib/zstd/common/error_private.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1e0c1b49fSNick Terrell /*
2e0c1b49fSNick Terrell  * Copyright (c) Yann Collet, Facebook, Inc.
3e0c1b49fSNick Terrell  * All rights reserved.
4e0c1b49fSNick Terrell  *
5e0c1b49fSNick Terrell  * This source code is licensed under both the BSD-style license (found in the
6e0c1b49fSNick Terrell  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7e0c1b49fSNick Terrell  * in the COPYING file in the root directory of this source tree).
8e0c1b49fSNick Terrell  * You may select, at your option, one of the above-listed licenses.
9e0c1b49fSNick Terrell  */
10e0c1b49fSNick Terrell 
11e0c1b49fSNick Terrell /* Note : this module is expected to remain private, do not expose it */
12e0c1b49fSNick Terrell 
13e0c1b49fSNick Terrell #ifndef ERROR_H_MODULE
14e0c1b49fSNick Terrell #define ERROR_H_MODULE
15e0c1b49fSNick Terrell 
16e0c1b49fSNick Terrell 
17e0c1b49fSNick Terrell 
18e0c1b49fSNick Terrell /* ****************************************
19e0c1b49fSNick Terrell *  Dependencies
20e0c1b49fSNick Terrell ******************************************/
21e0c1b49fSNick Terrell #include <linux/zstd_errors.h>  /* enum list */
22*2aa14b1aSNick Terrell #include "compiler.h"
23*2aa14b1aSNick Terrell #include "debug.h"
24*2aa14b1aSNick Terrell #include "zstd_deps.h"       /* size_t */
25e0c1b49fSNick Terrell 
26e0c1b49fSNick Terrell 
27e0c1b49fSNick Terrell /* ****************************************
28e0c1b49fSNick Terrell *  Compiler-specific
29e0c1b49fSNick Terrell ******************************************/
30e0c1b49fSNick Terrell #define ERR_STATIC static __attribute__((unused))
31e0c1b49fSNick Terrell 
32e0c1b49fSNick Terrell 
33e0c1b49fSNick Terrell /*-****************************************
34e0c1b49fSNick Terrell *  Customization (error_public.h)
35e0c1b49fSNick Terrell ******************************************/
36e0c1b49fSNick Terrell typedef ZSTD_ErrorCode ERR_enum;
37e0c1b49fSNick Terrell #define PREFIX(name) ZSTD_error_##name
38e0c1b49fSNick Terrell 
39e0c1b49fSNick Terrell 
40e0c1b49fSNick Terrell /*-****************************************
41e0c1b49fSNick Terrell *  Error codes handling
42e0c1b49fSNick Terrell ******************************************/
43e0c1b49fSNick Terrell #undef ERROR   /* already defined on Visual Studio */
44e0c1b49fSNick Terrell #define ERROR(name) ZSTD_ERROR(name)
45e0c1b49fSNick Terrell #define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
46e0c1b49fSNick Terrell 
ERR_isError(size_t code)47e0c1b49fSNick Terrell ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
48e0c1b49fSNick Terrell 
ERR_getErrorCode(size_t code)49e0c1b49fSNick Terrell ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
50e0c1b49fSNick Terrell 
51e0c1b49fSNick Terrell /* check and forward error code */
52e0c1b49fSNick Terrell #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
53e0c1b49fSNick Terrell #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
54e0c1b49fSNick Terrell 
55e0c1b49fSNick Terrell 
56e0c1b49fSNick Terrell /*-****************************************
57e0c1b49fSNick Terrell *  Error Strings
58e0c1b49fSNick Terrell ******************************************/
59e0c1b49fSNick Terrell 
60e0c1b49fSNick Terrell const char* ERR_getErrorString(ERR_enum code);   /* error_private.c */
61e0c1b49fSNick Terrell 
ERR_getErrorName(size_t code)62e0c1b49fSNick Terrell ERR_STATIC const char* ERR_getErrorName(size_t code)
63e0c1b49fSNick Terrell {
64e0c1b49fSNick Terrell     return ERR_getErrorString(ERR_getErrorCode(code));
65e0c1b49fSNick Terrell }
66e0c1b49fSNick Terrell 
67*2aa14b1aSNick Terrell /*
68*2aa14b1aSNick Terrell  * Ignore: this is an internal helper.
69*2aa14b1aSNick Terrell  *
70*2aa14b1aSNick Terrell  * This is a helper function to help force C99-correctness during compilation.
71*2aa14b1aSNick Terrell  * Under strict compilation modes, variadic macro arguments can't be empty.
72*2aa14b1aSNick Terrell  * However, variadic function arguments can be. Using a function therefore lets
73*2aa14b1aSNick Terrell  * us statically check that at least one (string) argument was passed,
74*2aa14b1aSNick Terrell  * independent of the compilation flags.
75*2aa14b1aSNick Terrell  */
76*2aa14b1aSNick Terrell static INLINE_KEYWORD UNUSED_ATTR
_force_has_format_string(const char * format,...)77*2aa14b1aSNick Terrell void _force_has_format_string(const char *format, ...) {
78*2aa14b1aSNick Terrell   (void)format;
79*2aa14b1aSNick Terrell }
80*2aa14b1aSNick Terrell 
81*2aa14b1aSNick Terrell /*
82*2aa14b1aSNick Terrell  * Ignore: this is an internal helper.
83*2aa14b1aSNick Terrell  *
84*2aa14b1aSNick Terrell  * We want to force this function invocation to be syntactically correct, but
85*2aa14b1aSNick Terrell  * we don't want to force runtime evaluation of its arguments.
86*2aa14b1aSNick Terrell  */
87*2aa14b1aSNick Terrell #define _FORCE_HAS_FORMAT_STRING(...) \
88*2aa14b1aSNick Terrell   if (0) { \
89*2aa14b1aSNick Terrell     _force_has_format_string(__VA_ARGS__); \
90*2aa14b1aSNick Terrell   }
91*2aa14b1aSNick Terrell 
92*2aa14b1aSNick Terrell #define ERR_QUOTE(str) #str
93*2aa14b1aSNick Terrell 
94*2aa14b1aSNick Terrell /*
95*2aa14b1aSNick Terrell  * Return the specified error if the condition evaluates to true.
96*2aa14b1aSNick Terrell  *
97*2aa14b1aSNick Terrell  * In debug modes, prints additional information.
98*2aa14b1aSNick Terrell  * In order to do that (particularly, printing the conditional that failed),
99*2aa14b1aSNick Terrell  * this can't just wrap RETURN_ERROR().
100*2aa14b1aSNick Terrell  */
101*2aa14b1aSNick Terrell #define RETURN_ERROR_IF(cond, err, ...) \
102*2aa14b1aSNick Terrell   if (cond) { \
103*2aa14b1aSNick Terrell     RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
104*2aa14b1aSNick Terrell            __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
105*2aa14b1aSNick Terrell     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
106*2aa14b1aSNick Terrell     RAWLOG(3, ": " __VA_ARGS__); \
107*2aa14b1aSNick Terrell     RAWLOG(3, "\n"); \
108*2aa14b1aSNick Terrell     return ERROR(err); \
109*2aa14b1aSNick Terrell   }
110*2aa14b1aSNick Terrell 
111*2aa14b1aSNick Terrell /*
112*2aa14b1aSNick Terrell  * Unconditionally return the specified error.
113*2aa14b1aSNick Terrell  *
114*2aa14b1aSNick Terrell  * In debug modes, prints additional information.
115*2aa14b1aSNick Terrell  */
116*2aa14b1aSNick Terrell #define RETURN_ERROR(err, ...) \
117*2aa14b1aSNick Terrell   do { \
118*2aa14b1aSNick Terrell     RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
119*2aa14b1aSNick Terrell            __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
120*2aa14b1aSNick Terrell     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
121*2aa14b1aSNick Terrell     RAWLOG(3, ": " __VA_ARGS__); \
122*2aa14b1aSNick Terrell     RAWLOG(3, "\n"); \
123*2aa14b1aSNick Terrell     return ERROR(err); \
124*2aa14b1aSNick Terrell   } while(0);
125*2aa14b1aSNick Terrell 
126*2aa14b1aSNick Terrell /*
127*2aa14b1aSNick Terrell  * If the provided expression evaluates to an error code, returns that error code.
128*2aa14b1aSNick Terrell  *
129*2aa14b1aSNick Terrell  * In debug modes, prints additional information.
130*2aa14b1aSNick Terrell  */
131*2aa14b1aSNick Terrell #define FORWARD_IF_ERROR(err, ...) \
132*2aa14b1aSNick Terrell   do { \
133*2aa14b1aSNick Terrell     size_t const err_code = (err); \
134*2aa14b1aSNick Terrell     if (ERR_isError(err_code)) { \
135*2aa14b1aSNick Terrell       RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
136*2aa14b1aSNick Terrell              __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
137*2aa14b1aSNick Terrell       _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
138*2aa14b1aSNick Terrell       RAWLOG(3, ": " __VA_ARGS__); \
139*2aa14b1aSNick Terrell       RAWLOG(3, "\n"); \
140*2aa14b1aSNick Terrell       return err_code; \
141*2aa14b1aSNick Terrell     } \
142*2aa14b1aSNick Terrell   } while(0);
143*2aa14b1aSNick Terrell 
144e0c1b49fSNick Terrell 
145e0c1b49fSNick Terrell #endif /* ERROR_H_MODULE */
146