raylib-assert.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**********************************************************************************************
  2. *
  3. * raylib-assert - Assertion library for raylib.
  4. * https://github.com/robloach/raylib-assert
  5. *
  6. * Copyright 2021 Rob Loach (@RobLoach)
  7. *
  8. * DEPENDENCIES:
  9. * raylib https://www.raylib.com/
  10. *
  11. * LICENSE: zlib/libpng
  12. *
  13. * raylib-assert is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  14. * BSD-like license that allows static linking with closed source software:
  15. *
  16. * This software is provided "as-is", without any express or implied warranty. In no event
  17. * will the authors be held liable for any damages arising from the use of this software.
  18. *
  19. * Permission is granted to anyone to use this software for any purpose, including commercial
  20. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  21. *
  22. * 1. The origin of this software must not be misrepresented; you must not claim that you
  23. * wrote the original software. If you use this software in a product, an acknowledgment
  24. * in the product documentation would be appreciated but is not required.
  25. *
  26. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  27. * as being the original software.
  28. *
  29. * 3. This notice may not be removed or altered from any source distribution.
  30. *
  31. **********************************************************************************************/
  32. #ifndef RAYLIB_ASSERT_H
  33. #define RAYLIB_ASSERT_H
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. // How to report failed assertions
  38. #ifndef RAYLIB_ASSERT_LOG
  39. /**
  40. * The Trace Log Level used to report to TraceLog() on failed assertions. Defaults to LOG_FATAL.
  41. *
  42. * @example
  43. * #define RAYLIB_ASSERT_LOG LOG_WARNING
  44. *
  45. * @see TraceLogLevel
  46. */
  47. #define RAYLIB_ASSERT_LOG LOG_FATAL
  48. #endif
  49. // Define NDEBUG or RAYLIB_ASSERT_NDEBUG to skip assertions
  50. #ifdef NDEBUG
  51. #ifndef RAYLIB_ASSERT_NDEBUG
  52. #define RAYLIB_ASSERT_NDEBUG
  53. #endif
  54. #endif
  55. // Variadic Arguments
  56. #define RAYLIB_ASSERT_CAT( A, B ) A ## B
  57. #define RAYLIB_ASSERT_SELECT( NAME, NUM ) RAYLIB_ASSERT_CAT( NAME ## _, NUM )
  58. #define RAYLIB_ASSERT_GET_COUNT( _1, _2, _3, _4, _5, _6, _7, RAYLIB_ASSERT_COUNT, ... ) RAYLIB_ASSERT_COUNT
  59. #define RAYLIB_ASSERT_VA_SIZE( ... ) RAYLIB_ASSERT_GET_COUNT( __VA_ARGS__, 7, 6, 5, 4, 3, 2, 1 )
  60. #define RAYLIB_ASSERT_VA_SELECT( NAME, ... ) RAYLIB_ASSERT_SELECT( NAME, RAYLIB_ASSERT_VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)
  61. /**
  62. * Assert whether the given condition is true.
  63. *
  64. * @param condition The condition that is expected to be true.
  65. * @param message (Optional) The message to provide on failed assertions.
  66. * @param p1 (Optional) The first parameter in the message.
  67. * @param p2 (Optional) The second parameter in the message.
  68. * @param p3 (Optional) The third parameter in the message.
  69. * @param p4 (Optional) The fourth parameter in the message.
  70. * @param p5 (Optional) The fifth parameter in the message.
  71. */
  72. #define Assert(...) RAYLIB_ASSERT_VA_SELECT(Assert, __VA_ARGS__)
  73. /**
  74. * Assert whether the two given parameters are equal.
  75. *
  76. * @param actual The actual value.
  77. * @param expected The expected value.
  78. * @param message (Optional) The message to provide on failed assertions.
  79. * @param p1 (Optional) The first parameter in the message.
  80. * @param p2 (Optional) The second parameter in the message.
  81. * @param p3 (Optional) The third parameter in the message.
  82. * @param p4 (Optional) The fourth parameter in the message.
  83. */
  84. #define AssertEqual(...) RAYLIB_ASSERT_VA_SELECT(AssertEqual, __VA_ARGS__)
  85. /**
  86. * Assert whether the given condition is false.
  87. *
  88. * @param condition The condition that is expected to be false.
  89. * @param message (Optional) The message to provide on failed assertions.
  90. * @param p1 (Optional) The first parameter in the message.
  91. * @param p2 (Optional) The second parameter in the message.
  92. * @param p3 (Optional) The third parameter in the message.
  93. * @param p4 (Optional) The fourth parameter in the message.
  94. * @param p5 (Optional) The fifth parameter in the message.
  95. */
  96. #define AssertNot(...) RAYLIB_ASSERT_VA_SELECT(AssertNot, __VA_ARGS__)
  97. /**
  98. * Assert whether the two given parameters are not equal.
  99. *
  100. * @param actual The actual value.
  101. * @param notexpected The expected value that shouldn't equal the actual value.
  102. * @param message (Optional) The message to provide on failed assertions.
  103. * @param p1 (Optional) The first parameter in the message.
  104. * @param p2 (Optional) The second parameter in the message.
  105. * @param p3 (Optional) The third parameter in the message.
  106. * @param p4 (Optional) The fourth parameter in the message.
  107. */
  108. #define AssertNotEqual(...) RAYLIB_ASSERT_VA_SELECT(AssertNotEqual, __VA_ARGS__)
  109. /**
  110. * Sets a failed assertion, with the given message.
  111. *
  112. * @param message (Optional) The message to provide for the failed assertion.
  113. * @param p1 (Optional) The first parameter in the message.
  114. * @param p2 (Optional) The second parameter in the message.
  115. * @param p3 (Optional) The third parameter in the message.
  116. * @param p4 (Optional) The fourth parameter in the message.
  117. * @param p5 (Optional) The fifth parameter in the message.
  118. * @param p6 (Optional) The sixth parameter in the message.
  119. */
  120. #define AssertFail(...) RAYLIB_ASSERT_VA_SELECT(AssertFail, __VA_ARGS__)
  121. /**
  122. * Assert whether an image is loaded.
  123. *
  124. * @param image The image to check for valid data.
  125. * @param message (Optional) The message to provide on failed assertions.
  126. * @param p1 (Optional) The first parameter in the message.
  127. * @param p2 (Optional) The second parameter in the message.
  128. * @param p3 (Optional) The third parameter in the message.
  129. * @param p4 (Optional) The fourth parameter in the message.
  130. * @param p5 (Optional) The fifth parameter in the message.
  131. */
  132. #define AssertImage(...) RAYLIB_ASSERT_VA_SELECT(AssertImage, __VA_ARGS__)
  133. /**
  134. * Assert whether two images are the same.
  135. *
  136. * @param image1 The first image to check is equal to the second.
  137. * @param image2 The second image to check is equal to the first.
  138. * @param message (Optional) The message to provide on failed assertions.
  139. * @param p1 (Optional) The first parameter in the message.
  140. * @param p2 (Optional) The second parameter in the message.
  141. * @param p3 (Optional) The third parameter in the message.
  142. * @param p4 (Optional) The fourth parameter in the message.
  143. */
  144. #define AssertImageSame(...) RAYLIB_ASSERT_VA_SELECT(AssertImageSame, __VA_ARGS__)
  145. /**
  146. * Assert whether two colors are the same.
  147. *
  148. * @param color1 The first color to check.
  149. * @param color2 The second color to check.
  150. * @param message (Optional) The message to provide on failed assertions.
  151. * @param p1 (Optional) The first parameter in the message.
  152. * @param p2 (Optional) The second parameter in the message.
  153. * @param p3 (Optional) The third parameter in the message.
  154. * @param p4 (Optional) The fourth parameter in the message.
  155. */
  156. #define AssertColorSame(...) RAYLIB_ASSERT_VA_SELECT(AssertColorSame, __VA_ARGS__)
  157. // Assert()
  158. #ifdef RAYLIB_ASSERT_NDEBUG
  159. #define Assert_1(condition)
  160. #define Assert_2(condition, message)
  161. #define Assert_3(condition, message, p1)
  162. #define Assert_4(condition, message, p1, p2)
  163. #define Assert_5(condition, message, p1, p2, p3)
  164. #define Assert_6(condition, message, p1, p2, p3, p4)
  165. #define Assert_7(condition, message, p1, p2, p3, p4, p5)
  166. #else
  167. #define Assert_1(condition) Assert_2(condition, #condition)
  168. #define Assert_2(condition, message) do { if (!((bool)(condition))) { TraceLog(RAYLIB_ASSERT_LOG, "ASSERT: %s (%s:%i)", message, __FILE__, __LINE__); } } while(0)
  169. #define Assert_3(condition, message, p1) Assert_2(condition, TextFormat(message, p1))
  170. #define Assert_4(condition, message, p1, p2) Assert_2(condition, TextFormat(message, p1, p2))
  171. #define Assert_5(condition, message, p1, p2, p3) Assert_2(condition, TextFormat(message, p1, p2, p3))
  172. #define Assert_6(condition, message, p1, p2, p3, p4) Assert_2(condition, TextFormat(message, p1, p2, p3, p4))
  173. #define Assert_7(condition, message, p1, p2, p3, p4, p5) Assert_2(condition, TextFormat(message, p1, p2, p3, p4, p5))
  174. #endif
  175. // AssertEqual()
  176. #define AssertEqual_1(condition) Assert_2(condition, #condition)
  177. #define AssertEqual_2(actual, expected) Assert_4((actual) == (expected), "AssertEqual(%s, %s) - Provided arguments are not equal", #actual, #expected)
  178. #define AssertEqual_3(actual, expected, message) Assert_2((actual) == (expected), message)
  179. #define AssertEqual_4(actual, expected, message, p1) Assert_3((actual) == (expected), message, p1)
  180. #define AssertEqual_5(actual, expected, message, p1, p2) Assert_4((actual) == (expected), message, p1, p2)
  181. #define AssertEqual_6(actual, expected, message, p1, p2, p3) Assert_5((actual) == (expected), message, p1, p2, p3)
  182. #define AssertEqual_7(actual, expected, message, p1, p2, p3, p4) Assert_6((actual) == (expected), message, p1, p2, p3, p4)
  183. // AssertNotEqual()
  184. #define AssertNotEqual_1(condition) AssertNot_2(condition, #condition)
  185. #define AssertNotEqual_2(actual, expected) Assert_4((actual) != (expected), "AssertNotEqual(%s, %s) - Provided arguments are equal", #actual, #expected)
  186. #define AssertNotEqual_3(actual, expected, message) Assert_2((actual) != (expected), message)
  187. #define AssertNotEqual_4(actual, expected, message, p1) Assert_3((actual) != (expected), message, p1)
  188. #define AssertNotEqual_5(actual, expected, message, p1, p2) Assert_4((actual) != (expected), message, p1, p2)
  189. #define AssertNotEqual_6(actual, expected, message, p1, p2, p3) Assert_5((actual) != (expected), message, p1, p2, p3)
  190. #define AssertNotEqual_7(actual, expected, message, p1, p2, p3, p4) Assert_6((actual) != (expected), message, p1, p2, p3, p4)
  191. // AssertNot()
  192. #define AssertNot_1(condition) Assert_2(!(bool)(condition), #condition)
  193. #define AssertNot_2(condition, message) Assert_2(!(bool)(condition), message)
  194. #define AssertNot_3(condition, message, p1) Assert_3(!(bool)(condition), message, p1)
  195. #define AssertNot_4(condition, message, p1, p2) Assert_4(!(bool)(condition), message, p1, p2)
  196. #define AssertNot_5(condition, message, p1, p2, p3) Assert_5(!(bool)(condition), message, p1, p2, p3)
  197. #define AssertNot_6(condition, message, p1, p2, p3, p4) Assert_6(!(bool)(condition), message, p1, p2, p3, p4)
  198. #define AssertNot_7(condition, message, p1, p2, p3, p4, p5) Assert_7(!(bool)(condition), message, p1, p2, p3, p4, p5)
  199. // AssertFail()
  200. #ifdef RAYLIB_ASSERT_NDEBUG
  201. #define AssertFail_0()
  202. #define AssertFail_1(message)
  203. #define AssertFail_2(message, p1)
  204. #define AssertFail_3(message, p1, p2)
  205. #define AssertFail_4(message, p1, p2, p3)
  206. #define AssertFail_5(message, p1, p2, p3, p4)
  207. #define AssertFail_6(message, p1, p2, p3, p4, p5)
  208. #define AssertFail_7(message, p1, p2, p3, p4, p5, p6)
  209. #else
  210. #define AssertFail_0() TraceLog(RAYLIB_ASSERT_LOG, "ASSERT: AssertFail() (%s:%i)", __FILE__, __LINE__)
  211. #define AssertFail_1(message) TraceLog(RAYLIB_ASSERT_LOG, "ASSERT: %s (%s:%i)", message, __FILE__, __LINE__)
  212. #define AssertFail_2(message, p1) AssertFail_1(TextFormat(message, p1))
  213. #define AssertFail_3(message, p1, p2) AssertFail_1(TextFormat(message, p1, p2))
  214. #define AssertFail_4(message, p1, p2, p3) AssertFail_1(TextFormat(message, p1, p2, p3))
  215. #define AssertFail_5(message, p1, p2, p3, p4) AssertFail_1(TextFormat(message, p1, p2, p3, p4))
  216. #define AssertFail_6(message, p1, p2, p3, p4, p5) AssertFail_1(TextFormat(message, p1, p2, p3, p4, p5))
  217. #define AssertFail_7(message, p1, p2, p3, p4, p5, p6) AssertFail_1(TextFormat(message, p1, p2, p3, p4, p5, p6))
  218. #endif
  219. // AssertImage()
  220. #define AssertImage_0() AssertFail_1("No image provided for AssertImage()")
  221. #define AssertImage_1(image) AssertNotEqual_4((image).data, 0, "AssertImage(%s) - Image not loaded", #image)
  222. #define AssertImage_2(image, message) AssertNotEqual_3((image).data, 0, message)
  223. #define AssertImage_3(image, message, p1) AssertNotEqual_4((image).data, 0, message, p1)
  224. #define AssertImage_4(image, message, p1, p2) AssertNotEqual_5((image).data, 0, message, p1, p2)
  225. #define AssertImage_5(image, message, p1, p2, p3) AssertNotEqual_6((image).data, 0, message, p1, p2, p3)
  226. #define AssertImage_6(image, message, p1, p2, p3, p4) AssertNotEqual_7((image).data, 0, message, p1, p2, p3, p4)
  227. // AssertTexture()
  228. #define AssertTexture_0() AssertFail_1("No texture provided for AssertTexture()")
  229. #define AssertTexture_1(texture) AssertNotEqual_4((texture).id, 0, "AssertTexture(%s) - Texture not loaded", #texture)
  230. #define AssertTexture_2(texture, message) AssertNotEqual_3((texture).data, 0, message)
  231. #define AssertTexture_3(texture, message, p1) AssertNotEqual_4((texture).data, 0, message, p1)
  232. #define AssertTexture_4(texture, message, p1, p2) AssertNotEqual_5((texture).data, 0, message, p1, p2)
  233. #define AssertTexture_5(texture, message, p1, p2, p3) AssertNotEqual_6((texture).data, 0, message, p1, p2, p3)
  234. #define AssertTexture_6(texture, message, p1, p2, p3, p4) AssertNotEqual_7((texture).data, 0, message, p1, p2, p3, p4)
  235. // AssertImageSame()
  236. #ifdef RAYLIB_ASSERT_NDEBUG
  237. #define AssertImageSame_0()
  238. #define AssertImageSame_1(image)
  239. #define AssertImageSame_2(image1, image2)
  240. #define AssertImageSame_3(image1, image2, message)
  241. #define AssertImageSame_4(image1, image2, message, p1)
  242. #define AssertImageSame_5(image1, image2, message, p1, p2,)
  243. #define AssertImageSame_6(image1, image2, message, p1, p2, p3)
  244. #define AssertImageSame_7(image1, image2, message, p1, p2, p3, p4)
  245. #else
  246. #define AssertImageSame_0() AssertFail_1("AssertImageSame(): No images provided to AssertImageSame(), expected 2")
  247. #define AssertImageSame_1(image) AssertFail_1("Only one image provided for AssertImageSame()")
  248. #define AssertImageSame_2(image1, image2) AssertImageSame_5(image1, image2, "AssertImageSame(%s, %s) - Images do not match", #image1, #image2)
  249. #define AssertImageSame_3(image1, image2, message) do { \
  250. if (image1.width != image2.width || image1.height != image2.height || image1.format != image2.format) { \
  251. AssertFail_1(message); \
  252. break; \
  253. } \
  254. Color* colors1 = LoadImageColors(image1); \
  255. Color* colors2 = LoadImageColors(image2); \
  256. bool failure = false; \
  257. for (int i = 0; i < image1.width * image1.height; i++) { \
  258. Color color1 = colors1[i]; \
  259. Color color2 = colors2[i]; \
  260. if (color1.r != color2.r || color1.g != color2.g || color1.b != color2.b || color1.a != color2.a) { \
  261. failure = true; \
  262. break; \
  263. } \
  264. } \
  265. UnloadImageColors(colors1); \
  266. UnloadImageColors(colors2); \
  267. if (failure) { \
  268. AssertFail_1(message); \
  269. } \
  270. } while(0)
  271. #define AssertImageSame_4(image1, image2, message, p1) AssertImageSame_3(image1, image2, TextFormat(message, p1))
  272. #define AssertImageSame_5(image1, image2, message, p1, p2) AssertImageSame_3(image1, image2, TextFormat(message, p1, p2))
  273. #define AssertImageSame_6(image1, image2, message, p1, p2, p3) AssertImageSame_3(image1, image2, TextFormat(message, p1, p2, p3))
  274. #define AssertImageSame_7(image1, image2, message, p1, p2, p3, p4) AssertImageSame_3(image1, image2, TextFormat(message, p1, p2, p3, p4))
  275. #endif
  276. // AssertColorSame()
  277. #define AssertColorSame_0() AssertFail_1("Colors not provided to AssertColorSame()")
  278. #define AssertColorSame_1(color) AssertFail_1("Expected two colors for AssertColorSame()")
  279. #define AssertColorSame_2(color1, color2) AssertColorSame_5(color1, color2, "AssertColorSame(%s, %s) - Colors do not match", #color1, #color2)
  280. #define AssertColorSame_3(color1, color2, message) do { \
  281. if (color1.r != color2.r || color1.g != color2.g || color1.b != color2.b || color1.a != color2.a) { \
  282. AssertFail_1(message); \
  283. }\
  284. } while (0)
  285. #define AssertColorSame_4(color1, color2, message, p1) AssertColorSame_3(color1, color2, TextFormat(message, p1))
  286. #define AssertColorSame_5(color1, color2, message, p1, p2) AssertColorSame_3(color1, color2, TextFormat(message, p1, p2))
  287. #define AssertColorSame_6(color1, color2, message, p1, p2, p3) AssertColorSame_3(color1, color2, TextFormat(message, p1, p2, p3))
  288. #define AssertColorSame_7(color1, color2, message, p1, p2, p3, p4) AssertColorSame_3(color1, color2, TextFormat(message, p1, p2, p3, p4))
  289. #ifdef __cplusplus
  290. }
  291. #endif
  292. #endif // RAYLIB_ASSERT_H