1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 6 #ifndef ADBG_H 7 #define ADBG_H 8 #include <stdarg.h> 9 #include <stdbool.h> 10 #include <stddef.h> 11 #include <stdint.h> 12 #include <sys/queue.h> 13 14 #define ADBG_STRING_LENGTH_MAX (1024) 15 16 /* 17 * Case definitions 18 */ 19 20 /** 21 * Defines a test case 22 * 23 * Used in the follwing way for readability: 24 */ 25 #if 0 /* #if 0 to avoid nested comments */ 26 ADBG_CASE_DEFINE(TEST_1001, TEST_Test_1001, 27 /* Title */ 28 "My test case title", 29 ); 30 #endif 31 32 typedef struct ADBG_Case ADBG_Case_t; 33 34 typedef struct adbg_case_def { 35 const char *TestID_p; 36 const char *Title_p; 37 void (*Run_fp)(ADBG_Case_t *ADBG_Case_pp); 38 TAILQ_ENTRY(adbg_case_def) link; 39 } ADBG_Case_Definition_t; 40 41 TAILQ_HEAD(adbg_case_def_head, adbg_case_def); 42 43 typedef struct adbg_suite_def { 44 const char *SuiteID_p; 45 struct adbg_case_def_head cases; 46 } ADBG_Suite_Definition_t; 47 48 #define ADBG_CASE_DEFINE(Suite, TestID, Run, Title) \ 49 __attribute__((constructor)) static void \ 50 __adbg_test_case_ ## TestID(void) \ 51 { \ 52 static ADBG_Case_Definition_t case_def = { \ 53 .TestID_p = #Suite "_" #TestID, \ 54 .Title_p = Title, \ 55 .Run_fp = Run, \ 56 }; \ 57 struct adbg_case_def_head *ch = &(ADBG_Suite_ ## Suite).cases; \ 58 struct adbg_case_def *cd = NULL; \ 59 \ 60 TAILQ_FOREACH(cd, ch, link) \ 61 if (strcmp(case_def.TestID_p, cd->TestID_p) < 0) \ 62 break; \ 63 if (cd) \ 64 TAILQ_INSERT_BEFORE(cd, &case_def, link); \ 65 else \ 66 TAILQ_INSERT_TAIL(ch, &case_def, link); \ 67 } 68 69 /* 70 * Suite definitions 71 */ 72 73 /** 74 * Declares a suite defined in a C-file. 75 */ 76 #define ADBG_SUITE_DECLARE(Name) \ 77 extern ADBG_Suite_Definition_t ADBG_Suite_ ## Name 78 79 #define ADBG_SUITE_DEFINE(Name) \ 80 ADBG_Suite_Definition_t ADBG_Suite_ ## Name = { \ 81 .SuiteID_p = #Name, \ 82 .cases = TAILQ_HEAD_INITIALIZER(ADBG_Suite_ ## Name.cases), \ 83 } 84 85 /* 86 * Enum table definitions 87 */ 88 89 #define ADBG_ENUM_TABLE_DECLARE(Name) \ 90 extern const ADBG_EnumTable_t ADBG_EnumTable_ ## Name[] 91 92 #define ADBG_ENUM_TABLE_DEFINE_BEGIN(Name) \ 93 const ADBG_EnumTable_t ADBG_EnumTable_ ## Name[] = { 94 #define ADBG_ENUM_TABLE_ENTRY(Value) { Value, #Value } 95 96 #define ADBG_ENUM_TABLE_DEFINE_END(Name) , { 0, NULL } } 97 98 typedef struct { 99 int Value; 100 const char *const Name_p; 101 } ADBG_EnumEntry_t; 102 103 typedef ADBG_EnumEntry_t ADBG_EnumTable_t; 104 105 ADBG_ENUM_TABLE_DECLARE(Boolean); 106 107 /* 108 * Expect functions/macros 109 */ 110 111 #define ADBG_EXPECT(Case_p, Expected, Got) \ 112 ADBG_EXPECT_ENUM(Case_p, Expected, Got, NULL) 113 114 #define ADBG_EXPECT_NOT(Case_p, Expected, Got) \ 115 ADBG_EXPECT_NOT_ENUM(Case_p, Expected, Got, NULL) 116 117 #define ADBG_EXPECT_ENUM(Case_p, Expected, Got, EnumTable_p) \ 118 Do_ADBG_Expect(Case_p, __FILE__, __LINE__, Expected, Got, #Got, \ 119 EnumTable_p) 120 121 #define ADBG_EXPECT_NOT_ENUM(Case_p, NotExpected, Got, EnumTable_p) \ 122 Do_ADBG_ExpectNot(Case_p, __FILE__, __LINE__, \ 123 NotExpected, Got, #Got, EnumTable_p) 124 125 #define ADBG_EXPECT_BOOLEAN(Case_p, Expected, Got) \ 126 ADBG_EXPECT_ENUM(Case_p, Expected, Got, ADBG_EnumTable_Boolean) 127 128 #define ADBG_EXPECT_TRUE(Case_p, Got) \ 129 ADBG_EXPECT_ENUM(Case_p, true, Got, ADBG_EnumTable_Boolean) 130 131 #define ADBG_EXPECT_EQUAL(Case_p, Buf1_p, Buf2_p, Length) \ 132 ADBG_EXPECT(Case_p, 0, memcmp(Buf1_p, Buf2_p, Length)) 133 134 #define ADBG_EXPECT_BUFFER(Case_p, ExpBuf_p, ExpBufLen, GotBuf_p, GotBufLen) \ 135 Do_ADBG_ExpectBuffer(Case_p, __FILE__, __LINE__, \ 136 ExpBuf_p, ExpBufLen, #GotBuf_p, GotBuf_p, \ 137 #GotBufLen, GotBufLen) 138 139 #define ADBG_EXPECT_POINTER(Case_p, Expected, Got) \ 140 Do_ADBG_ExpectPointer(Case_p, __FILE__, __LINE__, Expected, Got, #Got) 141 142 #define ADBG_EXPECT_NOT_NULL(Case_p, Got) \ 143 Do_ADBG_ExpectPointerNotNULL(Case_p, __FILE__, __LINE__, Got, #Got) 144 145 #define ADBG_EXPECT_COMPARE_SIGNED(Case_p, Val1, Compar, Val2) \ 146 Do_ADBG_ExpectCompareSigned(Case_p, __FILE__, __LINE__, \ 147 Val1, Val2, (Val1)Compar( \ 148 Val2), #Val1, #Compar, #Val2) 149 150 #define ADBG_EXPECT_COMPARE_UNSIGNED(Case_p, Val1, Compar, Val2) \ 151 Do_ADBG_ExpectCompareUnsigned(Case_p, __FILE__, __LINE__, \ 152 Val1, Val2, (Val1)Compar( \ 153 Val2), #Val1, #Compar, #Val2) 154 155 #define ADBG_EXPECT_COMPARE_POINTER(Case_p, Val1, Compar, Val2) \ 156 Do_ADBG_ExpectComparePointer(Case_p, __FILE__, __LINE__, \ 157 Val1, Val2, (Val1)Compar( \ 158 Val2), #Val1, #Compar, #Val2) 159 160 #define ADBG_REQUIRE(Case_p, Recovery, Expected, Got) {\ 161 if (!ADBG_EXPECT(Case_p, Expected, Got)) \ 162 Recovery } 163 164 #define ADBG_REQUIRE_ENUM(Case_p, Recovery, Expected, Got, EnumTable_p) {\ 165 if (!ADBG_EXPECT_ENUM(Case_p, Expected, Got, EnumTable_p)) \ 166 Recovery } 167 168 #define ADBG_REQUIRE_BOOLEAN(Case_p, Recovery, Expected, Got) {\ 169 if (!ADBG_EXPECT_BOOLEAN(Case_p, Expected, Got)) \ 170 Recovery } 171 172 #define ADBG_REQUIRE_TRUE(Case_p, Recovery, Got) {\ 173 if (!ADBG_EXPECT_TRUE(Case_p, Got)) \ 174 Recovery } 175 176 #define ADBG_REQUIRE_EQUAL(Case_p, Recovery, Buf1_p, Buf2_p, Length) {\ 177 if (!ADBG_EXPECT_EQUAL(Case_p, Buf1_p, Buf2_p, Length)) \ 178 Recovery } 179 180 #define ADBG_REQUIRE_BUFFER(Case_p, Recovery, ExpBuf_p, ExpBufLen, GotBuf_p, \ 181 GotBufLen) {\ 182 if (!ADBG_EXPECT_BUFFER(Case_p, ExpBuf_p, ExpBufLen, GotBuf_p, \ 183 GotBufLen)) \ 184 Recovery } 185 186 #define ADBG_REQUIRE_POINTER(Case_p, Recovery, Expected, Got) {\ 187 if (!ADBG_EXPECT_POINTER(Case_p, Expected, Got)) \ 188 Recovery } 189 190 #define ADBG_REQUIRE_NOT_NULL(Case_p, Recovery, Got) {\ 191 if (!ADBG_EXPECT_NOT_NULL(Case_p, Got)) \ 192 Recovery } 193 194 #define ADBG_REQUIRE_COMPARE_SIGNED(Case_p, Recovery, Val1, Compar, Val2) {\ 195 if (!ADBG_EXPECT_COMPARE_SIGNED(Case_p, Val1, Compar, Val2)) \ 196 Recovery } 197 198 #define ADBG_REQUIRE_COMPARE_UNSIGNED(Case_p, Recovery, Val1, Compar, Val2) {\ 199 if (!ADBG_EXPECT_COMPARE_UNSIGNED(Case_p, Val1, Compar, Val2)) \ 200 Recovery } 201 202 #define ADBG_REQUIRE_COMPARE_POINTER(Case_p, Recovery, Val1, Compar, Val2) {\ 203 if (!ADBG_EXPECT_COMPARE_POINTER(Case_p, Val1, Compar, Val2)) \ 204 Recovery } 205 206 bool Do_ADBG_Expect(ADBG_Case_t *const Case_p, const char *const FileName_p, 207 const int LineNumber, const int Expected, const int Got, 208 const char *const GotVarName_p, 209 const ADBG_EnumTable_t *const EnumTable_p); 210 211 bool Do_ADBG_ExpectNot(ADBG_Case_t *const Case_p, const char *const FileName_p, 212 const int LineNumber, const int NotExpected, 213 const int Got, const char *const GotVarName_p, 214 const ADBG_EnumTable_t *const EnumTable_p); 215 216 bool Do_ADBG_ExpectBuffer(ADBG_Case_t *const Case_p, 217 const char *const FileName_p, const int LineNumber, 218 const void *const ExpectedBuffer_p, 219 const size_t ExpectedBufferLength, 220 const char *const GotBufferName_p, 221 const void *const GotBuffer_p, 222 const char *const GotBufferLengthName_p, 223 const size_t GotBufferLength); 224 225 bool Do_ADBG_ExpectPointer(ADBG_Case_t *const Case_p, 226 const char *const FileName_p, const int LineNumber, 227 const void *Expected_p, const void *Got_p, 228 const char *const GotVarName_p); 229 230 bool Do_ADBG_ExpectPointerNotNULL(ADBG_Case_t *const Case_p, 231 const char *const FileName_p, 232 const int LineNumber, const void *Got_p, 233 const char *const GotVarName_p); 234 235 bool Do_ADBG_ExpectCompareSigned(ADBG_Case_t *const Case_p, 236 const char *const FileName_p, 237 const int LineNumber, const long Value1, 238 const long Value2, const bool Result, 239 const char *const Value1Str_p, 240 const char *const ComparStr_p, 241 const char *const Value2Str_p); 242 243 bool Do_ADBG_ExpectCompareUnsigned(ADBG_Case_t *const Case_p, 244 const char *const FileName_p, 245 const int LineNumber, 246 const unsigned long Value1, 247 const unsigned long Value2, 248 const bool Result, 249 const char *const Value1Str_p, 250 const char *const ComparStr_p, 251 const char *const Value2Str_p); 252 253 bool Do_ADBG_ExpectComparePointer(ADBG_Case_t *const Case_p, 254 const char *const FileName_p, 255 const int LineNumber, 256 const void *const Value1_p, 257 const void *const Value2_p, const bool Result, 258 const char *const Value1Str_p, 259 const char *const ComparStr_p, 260 const char *const Value2Str_p); 261 262 const char *Do_ADBG_GetEnumName(const int Value, 263 const ADBG_EnumTable_t *const EnumTable_p); 264 265 /** 266 * Writes a string to output. 267 * String length max is defined by ADBG_STRING_LENGTH_MAX 268 * 269 * @param Format_p The formatting string as in printf 270 */ 271 void Do_ADBG_Log(const char *const Format_p, ...) 272 __attribute__((__format__(__printf__, 1, 2))); 273 274 /** 275 * Writes out the contents of buf_p formatted so that each line will 276 * have cols number of columns. 277 * 278 * @param[in] Buf_p Buffer to print 279 * @param[in] Size Size of buffer (in bytes) 280 * @param[in] Cols Number of columns. 281 */ 282 void Do_ADBG_HexLog(const void *const Buf_p, const size_t Size, 283 const size_t Cols); 284 285 /* 286 * Suite functions 287 */ 288 289 int Do_ADBG_RunSuite(const ADBG_Suite_Definition_t *Suite_p, int argc, 290 char *argv[]); 291 int Do_ADBG_AppendToSuite(ADBG_Suite_Definition_t *Dest_p, 292 ADBG_Suite_Definition_t *Source_p); 293 294 /* 295 * SubCase functions 296 */ 297 void Do_ADBG_BeginSubCase(ADBG_Case_t *const Case_p, 298 const char *const FormatTitle_p, 299 ...) __attribute__((__format__(__printf__, 2, 3))); 300 301 void Do_ADBG_EndSubCase(ADBG_Case_t *const Case_p, 302 const char *const FormatTitle_p, 303 ...) __attribute__((__format__(__printf__, 2, 3))); 304 305 #endif /* ADBG_H */ 306