platformTools.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #ifndef TOOLS_H_INCLUDE
  2. #define TOOLS_H_INCLUDE
  3. #include "config.h"
  4. #include <signal.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #ifdef _WIN32
  8. #include <Windows.h>
  9. inline void assertFuncProduction(
  10. const char *expression,
  11. const char *file_name,
  12. unsigned const line_number,
  13. const char *comment = "---")
  14. {
  15. char c[1024] = {};
  16. sprintf(c,
  17. "Assertion failed\n\n"
  18. "File:\n"
  19. "%s\n\n"
  20. "Line:\n"
  21. "%u\n\n"
  22. "Expresion:\n"
  23. "%s\n\n"
  24. "Comment:\n"
  25. "%s"
  26. "\n\nPlease report this error to the developer.",
  27. file_name,
  28. line_number,
  29. expression,
  30. comment
  31. );
  32. int const action = MessageBox(0, c, "Platform Layer", MB_TASKMODAL
  33. | MB_ICONHAND | MB_OK | MB_SETFOREGROUND);
  34. switch (action)
  35. {
  36. case IDOK: // Abort the program:
  37. {
  38. raise(SIGABRT);
  39. // We won't usually get here, but it's possible that a user-registered
  40. // abort handler returns, so exit the program immediately. Note that
  41. // even though we are "aborting," we do not call abort() because we do
  42. // not want to invoke Watson (the user has already had an opportunity
  43. // to debug the error and chose not to).
  44. _exit(3);
  45. }
  46. default:
  47. {
  48. _exit(3);
  49. }
  50. }
  51. }
  52. inline void assertFuncInternal(
  53. const char *expression,
  54. const char *file_name,
  55. unsigned const line_number,
  56. const char *comment = "---")
  57. {
  58. char c[1024] = {};
  59. sprintf(c,
  60. "Assertion failed\n\n"
  61. "File:\n"
  62. "%s\n\n"
  63. "Line:\n"
  64. "%u\n\n"
  65. "Expresion:\n"
  66. "%s\n\n"
  67. "Comment:\n"
  68. "%s"
  69. "\n\nPress retry to debug.",
  70. file_name,
  71. line_number,
  72. expression,
  73. comment
  74. );
  75. int const action = MessageBox(0, c, "Platform Layer", MB_TASKMODAL
  76. | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND);
  77. switch (action)
  78. {
  79. case IDABORT: // Abort the program:
  80. {
  81. raise(SIGABRT);
  82. // We won't usually get here, but it's possible that a user-registered
  83. // abort handler returns, so exit the program immediately. Note that
  84. // even though we are "aborting," we do not call abort() because we do
  85. // not want to invoke Watson (the user has already had an opportunity
  86. // to debug the error and chose not to).
  87. _exit(3);
  88. }
  89. case IDRETRY: // Break into the debugger then return control to caller
  90. {
  91. __debugbreak();
  92. return;
  93. }
  94. case IDIGNORE: // Return control to caller
  95. {
  96. return;
  97. }
  98. default: // This should not happen; treat as fatal error:
  99. {
  100. abort();
  101. }
  102. }
  103. }
  104. #if INTERNAL_BUILD == 1
  105. #define permaAssert(expression) (void)( \
  106. (!!(expression)) || \
  107. (assertFuncInternal(#expression, __FILE__, (unsigned)(__LINE__)), 0) \
  108. )
  109. #define permaAssertComment(expression, comment) (void)( \
  110. (!!(expression)) || \
  111. (assertFuncInternal(#expression, __FILE__, (unsigned)(__LINE__), comment), 1)\
  112. )
  113. #else
  114. #define permaAssert(expression) (void)( \
  115. (!!(expression)) || \
  116. (assertFuncProduction(#expression, __FILE__, (unsigned)(__LINE__)), 0) \
  117. )
  118. #define permaAssertComment(expression, comment) (void)( \
  119. (!!(expression)) || \
  120. (assertFuncProduction(#expression, __FILE__, (unsigned)(__LINE__), comment), 1) \
  121. )
  122. #endif
  123. #else //linux or others
  124. inline void assertFuncProduction(
  125. const char *expression,
  126. const char *file_name,
  127. unsigned const line_number,
  128. const char *comment = "---")
  129. {
  130. raise(SIGABRT);
  131. }
  132. inline void assertFuncInternal(
  133. const char* expression,
  134. const char* file_name,
  135. unsigned const line_number,
  136. const char* comment = "---")
  137. {
  138. raise(SIGABRT);
  139. }
  140. #if INTERNAL_BUILD == 1
  141. #define permaAssert(expression) (void)( \
  142. (!!(expression)) || \
  143. (assertFuncInternal(#expression, __FILE__, (unsigned)(__LINE__)), 0) \
  144. )
  145. #define permaAssertComment(expression, comment) (void)( \
  146. (!!(expression)) || \
  147. (assertFuncInternal(#expression, __FILE__, (unsigned)(__LINE__), comment), 1)\
  148. )
  149. #else
  150. #define permaAssert(expression) (void)( \
  151. (!!(expression)) || \
  152. (assertFuncProduction(#expression, __FILE__, (unsigned)(__LINE__)), 0) \
  153. )
  154. #define permaAssertComment(expression, comment) (void)( \
  155. (!!(expression)) || \
  156. (assertFuncProduction(#expression, __FILE__, (unsigned)(__LINE__), comment), 1) \
  157. )
  158. #endif
  159. #endif
  160. #endif