1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include <stdbool.h> 17 18 #include "pw_preprocessor/compiler.h" 19 #include "pw_preprocessor/util.h" 20 21 PW_EXTERN_C_START 22 23 struct pw_CapturedAssert { 24 // The capturing assert handler will set triggered = 1 upon entry, enabling 25 // detecting if an assert triggered by setting it to 0 before; for example 26 // 27 // captured_assert_arguments.triggered = 0; 28 // PW_CHECK_NE(1, 2, "Ruh roh!"); 29 // EXPECT_TRUE(captured_assert_arguments.triggered); 30 // 31 int triggered; 32 const char* file_name; 33 int line_number; 34 const char* function_name; 35 char message[150]; 36 }; 37 38 // The assert handler pushes arguments into this global, then returns. 39 extern struct pw_CapturedAssert pw_captured_assert; 40 41 // Crash, including a message with the listed attributes. 42 void pw_CaptureAssert(const char* file_name, 43 int line_number, 44 const char* function_name, 45 const char* message, 46 ...) PW_PRINTF_FORMAT(4, 5); 47 48 PW_EXTERN_C_END 49 50 // Capture the crash attributes for testing. 51 #define PW_HANDLE_CRASH(...) \ 52 pw_CaptureAssert(__FILE__, __LINE__, __func__ PW_COMMA_ARGS(__VA_ARGS__)) 53 54 // Capture the crash attributes for testing, including the condition string. 55 #define PW_HANDLE_ASSERT_FAILURE(condition_string, message, ...) \ 56 pw_CaptureAssert(__FILE__, \ 57 __LINE__, \ 58 __func__, \ 59 "Check failed: " condition_string \ 60 ". " message PW_COMMA_ARGS(__VA_ARGS__)) 61 62 // Sample assert failure message produced by the below implementation: 63 // 64 // Check failed: current_sensor (=610) < new_sensor (=50): More details! 65 // 66 // Putting the value next to the operand makes the string easier to read. 67 68 // clang-format off 69 // This is too hairy for clang format to handle and retain readability. 70 #define PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(arg_a_str, \ 71 arg_a_val, \ 72 comparison_op_str, \ 73 arg_b_str, \ 74 arg_b_val, \ 75 type_fmt, \ 76 message, ...) \ 77 pw_CaptureAssert(__FILE__, \ 78 __LINE__, \ 79 __func__, \ 80 "Check failed: " \ 81 arg_a_str " (=" type_fmt ") " \ 82 comparison_op_str " " \ 83 arg_b_str " (=" type_fmt ")" \ 84 ". " message, \ 85 arg_a_val, arg_b_val PW_COMMA_ARGS(__VA_ARGS__)) 86 // clang-format on 87