error_private.h 4.3 KB

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