catch_assert.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * SPDX-License-Identifier: MIT
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. /*
  24. * How to catch an assert:
  25. * - save a jump buffer where execution will resume after the assert
  26. * - setup a handler for the abort signal, call longjmp within
  27. * - optional - close stderr ( fd 2 ) to discard the assert message
  28. *
  29. * Unity also does a longjmp within its TEST_ASSERT* macros,
  30. * so the macro below restores stderr and the prior abort handler
  31. * before calling the Unity macro.
  32. */
  33. #ifndef CATCH_ASSERT_H_
  34. #define CATCH_ASSERT_H_
  35. #include <setjmp.h>
  36. #include <signal.h>
  37. #include <unistd.h>
  38. #ifndef CATCH_JMPBUF
  39. #define CATCH_JMPBUF waypoint_
  40. #endif
  41. static jmp_buf CATCH_JMPBUF;
  42. #pragma GCC diagnostic push
  43. #pragma GCC diagnostic ignored "-Wunused-function"
  44. static void catchHandler_( int signal )
  45. {
  46. longjmp( CATCH_JMPBUF, signal );
  47. }
  48. #pragma GCC diagnostic pop
  49. #define catch_assert( x ) \
  50. do { \
  51. int try = 0, catch = 0; \
  52. int saveFd = dup( 2 ); \
  53. struct sigaction sa = { 0 }, saveSa; \
  54. sa.sa_handler = catchHandler_; \
  55. sigaction( SIGABRT, &sa, &saveSa ); \
  56. close( 2 ); \
  57. if( setjmp( CATCH_JMPBUF ) == 0 ) \
  58. { \
  59. try++; \
  60. x; \
  61. } \
  62. else \
  63. { \
  64. catch++; \
  65. } \
  66. sigaction( SIGABRT, &saveSa, NULL ); \
  67. dup2( saveFd, 2 ); \
  68. close( saveFd ); \
  69. TEST_ASSERT_EQUAL( try, catch ); \
  70. } while( 0 )
  71. #endif /* ifndef CATCH_ASSERT_H_ */