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/arguments.h" 19 #include "pw_preprocessor/compiler.h" 20 #include "pw_preprocessor/util.h" 21 22 PW_EXTERN_C_START 23 24 struct pw_CapturedAssert { 25 // The capturing assert handler will set triggered = 1 upon entry, enabling 26 // detecting if an assert triggered by setting it to 0 before; for example 27 // 28 // captured_assert_arguments.triggered = 0; 29 // PW_CHECK_NE(1, 2, "Ruh roh!"); 30 // EXPECT_TRUE(captured_assert_arguments.triggered); 31 // 32 int triggered; 33 const char* file_name; 34 int line_number; 35 const char* function_name; 36 char message[150]; 37 }; 38 39 // The assert handler pushes arguments into this global, then returns. 40 extern struct pw_CapturedAssert pw_captured_assert; 41 42 // Crash, including a message with the listed attributes. 43 void pw_CaptureAssert(const char* file_name, 44 int line_number, 45 const char* function_name, 46 const char* message, 47 ...) PW_PRINTF_FORMAT(4, 5); 48 49 PW_EXTERN_C_END 50 51 // Capture the crash attributes for testing. 52 #define PW_HANDLE_CRASH(...) \ 53 pw_CaptureAssert(__FILE__, __LINE__, __func__ PW_COMMA_ARGS(__VA_ARGS__)) 54 55 // Capture the crash attributes for testing, including the condition string. 56 #define PW_HANDLE_ASSERT_FAILURE(condition_string, message, ...) \ 57 pw_CaptureAssert(__FILE__, \ 58 __LINE__, \ 59 __func__, \ 60 "Check failed: " condition_string \ 61 ". " message PW_COMMA_ARGS(__VA_ARGS__)) 62 63 // Sample assert failure message produced by the below implementation: 64 // 65 // Check failed: current_sensor (=610) < new_sensor (=50): More details! 66 // 67 // Putting the value next to the operand makes the string easier to read. 68 69 // clang-format off 70 // This is too hairy for clang format to handle and retain readability. 71 #define PW_HANDLE_ASSERT_BINARY_COMPARE_FAILURE(arg_a_str, \ 72 arg_a_val, \ 73 comparison_op_str, \ 74 arg_b_str, \ 75 arg_b_val, \ 76 type_fmt, \ 77 message, ...) \ 78 pw_CaptureAssert(__FILE__, \ 79 __LINE__, \ 80 __func__, \ 81 "Check failed: " \ 82 arg_a_str " (=" type_fmt ") " \ 83 comparison_op_str " " \ 84 arg_b_str " (=" type_fmt ")" \ 85 ". " message, \ 86 arg_a_val, arg_b_val PW_COMMA_ARGS(__VA_ARGS__)) 87 // clang-format on 88