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