1 | // ============================================================== // |
---|
2 | // // |
---|
3 | // File : cb.cxx // |
---|
4 | // Purpose : currently only a test sandbox // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in August 2011 // |
---|
7 | // Institute of Microbiology (Technical University Munich) // |
---|
8 | // http://www.arb-home.de/ // |
---|
9 | // // |
---|
10 | // ============================================================== // |
---|
11 | |
---|
12 | #include <cb.h> |
---|
13 | #include <string> |
---|
14 | #include <stdint.h> |
---|
15 | |
---|
16 | using namespace std; |
---|
17 | |
---|
18 | STATIC_ASSERT(sizeof(int*) == sizeof(AW_CL)); // important for casted db-callback type (GB_CB vs GB_CB_wanted..) |
---|
19 | |
---|
20 | // -------------------------------------------------------------------------------- |
---|
21 | |
---|
22 | #ifdef UNIT_TESTS |
---|
23 | #include <test_unit.h> |
---|
24 | |
---|
25 | // --------------------------------------------- |
---|
26 | // compile time test of type inspection |
---|
27 | |
---|
28 | #define COMPILE_ASSERT_POINTER_TO(ISTYPE,POINTER) \ |
---|
29 | STATIC_ASSERT(TypeT<POINTER>::IsPtrT && \ |
---|
30 | TypeT<CompountT<POINTER>::BaseT>::ISTYPE) |
---|
31 | |
---|
32 | typedef int (*somefun)(const char *); |
---|
33 | int myfun(const char *) { return 0; } |
---|
34 | static somefun sfun = myfun; |
---|
35 | |
---|
36 | enum someenum { A, B }; |
---|
37 | |
---|
38 | class someclass { public : int memfun() { return -1; } }; |
---|
39 | |
---|
40 | |
---|
41 | STATIC_ASSERT(IsFundaT<void>::No); |
---|
42 | STATIC_ASSERT(IsFundaT<bool>::Yes); |
---|
43 | STATIC_ASSERT(IsFundaT<int>::Yes); |
---|
44 | STATIC_ASSERT(IsFundaT<long>::Yes); |
---|
45 | STATIC_ASSERT(IsFundaT<double>::Yes); |
---|
46 | |
---|
47 | STATIC_ASSERT(IsFundaT<int*>::No); |
---|
48 | COMPILE_ASSERT_POINTER_TO(IsFundaT, int*); |
---|
49 | COMPILE_ASSERT_POINTER_TO(IsPtrT, int**); |
---|
50 | STATIC_ASSERT(IsFundaT<int&>::No); |
---|
51 | |
---|
52 | STATIC_ASSERT(IsFundaT<somefun>::No); |
---|
53 | STATIC_ASSERT(IsFundaT<typeof(myfun)>::No); |
---|
54 | STATIC_ASSERT(IsFundaT<someenum>::No); |
---|
55 | |
---|
56 | STATIC_ASSERT(IsFunctionT<typeof(myfun)>::Yes); |
---|
57 | |
---|
58 | STATIC_ASSERT(IsFunctionT<somefun>::No); // somefun is pointer to functiontype |
---|
59 | COMPILE_ASSERT_POINTER_TO(IsFuncT, somefun); |
---|
60 | STATIC_ASSERT(IsFunctionT<typeof(sfun)>::No); // sfun is pointer to functiontype |
---|
61 | COMPILE_ASSERT_POINTER_TO(IsFuncT, typeof(sfun)); |
---|
62 | STATIC_ASSERT(IsFunctionT<void>::No); |
---|
63 | STATIC_ASSERT(IsFunctionT<int>::No); |
---|
64 | STATIC_ASSERT(IsFunctionT<bool>::No); |
---|
65 | |
---|
66 | STATIC_ASSERT(CompountT<const int&>::IsRefT); |
---|
67 | STATIC_ASSERT(CompountT<int&>::IsRefT); |
---|
68 | |
---|
69 | STATIC_ASSERT(IsEnumT<someenum>::Yes); |
---|
70 | COMPILE_ASSERT_POINTER_TO(IsEnumT, someenum*); |
---|
71 | |
---|
72 | STATIC_ASSERT(IsEnumT<int>::No); |
---|
73 | STATIC_ASSERT(IsEnumT<int*>::No); |
---|
74 | STATIC_ASSERT(IsEnumT<int&>::No); |
---|
75 | STATIC_ASSERT(IsEnumT<somefun>::No); |
---|
76 | STATIC_ASSERT(IsEnumT<typeof(myfun)>::No); |
---|
77 | |
---|
78 | STATIC_ASSERT(IsClassT<someclass>::Yes); |
---|
79 | COMPILE_ASSERT_POINTER_TO(IsClassT, someclass*); |
---|
80 | |
---|
81 | STATIC_ASSERT(IsClassT<int>::No); |
---|
82 | STATIC_ASSERT(IsClassT<int*>::No); |
---|
83 | STATIC_ASSERT(IsClassT<int&>::No); |
---|
84 | STATIC_ASSERT(IsClassT<someenum>::No); |
---|
85 | STATIC_ASSERT(IsClassT<somefun>::No); |
---|
86 | STATIC_ASSERT(IsClassT<typeof(myfun)>::No); |
---|
87 | |
---|
88 | STATIC_ASSERT(TypeT<int>::IsFundaT); |
---|
89 | STATIC_ASSERT(TypeT<int*>::IsPtrT); |
---|
90 | STATIC_ASSERT(TypeT<int&>::IsRefT); |
---|
91 | STATIC_ASSERT(TypeT<int[]>::IsArrayT); |
---|
92 | STATIC_ASSERT(TypeT<int[7]>::IsArrayT); |
---|
93 | STATIC_ASSERT(TypeT<typeof(myfun)>::IsFuncT); |
---|
94 | STATIC_ASSERT(TypeT<typeof(&someclass::memfun)>::IsPtrMemT); |
---|
95 | STATIC_ASSERT(TypeT<someenum>::IsEnumT); |
---|
96 | STATIC_ASSERT(TypeT<someclass>::IsClassT); |
---|
97 | |
---|
98 | // ----------------------- |
---|
99 | // test callbacks |
---|
100 | |
---|
101 | #define TRACE |
---|
102 | |
---|
103 | static uint32_t traceChecksum; |
---|
104 | const int BUFFERSIZE = 100; |
---|
105 | char traceBuffer[BUFFERSIZE]; |
---|
106 | |
---|
107 | __ATTR__FORMAT(1) static void tracef(const char *format, ...) { |
---|
108 | va_list parg; |
---|
109 | va_start(parg, format); |
---|
110 | int printed = vsnprintf(traceBuffer, BUFFERSIZE, format, parg); |
---|
111 | va_end(parg); |
---|
112 | |
---|
113 | #if defined(TRACE) |
---|
114 | fputs(traceBuffer, stdout); |
---|
115 | #endif |
---|
116 | if (printed >= BUFFERSIZE) { |
---|
117 | printf("\nprinted=%i\n", printed); |
---|
118 | } |
---|
119 | TEST_EXPECT(printed<BUFFERSIZE); |
---|
120 | |
---|
121 | traceChecksum = 0; |
---|
122 | for (int p = 0; p<printed; ++p) { |
---|
123 | traceChecksum = (traceChecksum<<1)^(traceChecksum>>31)^traceBuffer[p]; |
---|
124 | } |
---|
125 | } |
---|
126 | |
---|
127 | static AW_root *fake_root = (AW_root*)1; |
---|
128 | static AW_window *fake_win = (AW_window*)2; |
---|
129 | static GBDATA *fake_gbd = (GBDATA*)3; |
---|
130 | static AW_awar *fake_awar = (AW_awar*)4; |
---|
131 | static bool fake_bool = false; |
---|
132 | static GB_CB_TYPE fake_gbtype = GB_CB_CHANGED; |
---|
133 | |
---|
134 | static void rcb0(AW_root *r) { |
---|
135 | TEST_EXPECT(r == fake_root); |
---|
136 | tracef("rcb0()\n"); |
---|
137 | } |
---|
138 | static void rcb1(AW_root *r, const char *name) { |
---|
139 | TEST_EXPECT(r == fake_root); |
---|
140 | tracef("rcb1(%s)\n", name); |
---|
141 | } |
---|
142 | static void rcb2(AW_root *r, const char *name, int val) { |
---|
143 | TEST_EXPECT(r == fake_root); |
---|
144 | tracef("rcb2(%s=%i) [int]\n", name, val); |
---|
145 | } |
---|
146 | static void rcb2(AW_root *r, const char *name, long val) { |
---|
147 | TEST_EXPECT(r == fake_root); |
---|
148 | tracef("rcb2(%s=%li) [long]\n", name, val); |
---|
149 | } |
---|
150 | |
---|
151 | static void wcb0(AW_window *w) { |
---|
152 | TEST_EXPECT(w == fake_win); |
---|
153 | tracef("wcb0()\n"); |
---|
154 | } |
---|
155 | static void wcb1(AW_window *w, const char *name) { |
---|
156 | TEST_EXPECT(w == fake_win); |
---|
157 | tracef("wcb1(%s)\n", name); |
---|
158 | } |
---|
159 | static void wcb1(AW_window *w, string *name) { |
---|
160 | TEST_EXPECT(w == fake_win); |
---|
161 | tracef("wcb1(%s) [string]\n", name->c_str()); |
---|
162 | } |
---|
163 | static void wcb2(AW_window *w, const char *name, const char *val) { |
---|
164 | TEST_EXPECT(w == fake_win); |
---|
165 | tracef("wcb2(%s=%s) [const char/const char]\n", name, val); |
---|
166 | } |
---|
167 | static void wcb2(AW_window *w, const string *name, const string *val) { |
---|
168 | TEST_EXPECT(w == fake_win); |
---|
169 | tracef("wcb2(%s=%s) [string/string]\n", name->c_str(), val->c_str()); |
---|
170 | } |
---|
171 | static void wcb2(AW_window *w, const char *name, int val) { |
---|
172 | TEST_EXPECT(w == fake_win); |
---|
173 | tracef("wcb2(%s=%i) [int]\n", name, val); |
---|
174 | } |
---|
175 | static void wcb2(AW_window *w, const char *name, long val) { |
---|
176 | TEST_EXPECT(w == fake_win); |
---|
177 | tracef("wcb2(%s=%li) [long]\n", name, val); |
---|
178 | } |
---|
179 | static void wcb2(AW_window *w, char c, long long val) { |
---|
180 | TEST_EXPECT(w == fake_win); |
---|
181 | tracef("wcb2(%c=%lli) [long long]\n", c, val); |
---|
182 | } |
---|
183 | |
---|
184 | static void tacb0(AW_awar *a) { |
---|
185 | TEST_EXPECT(a == fake_awar); |
---|
186 | tracef("tacb0()\n"); |
---|
187 | } |
---|
188 | static void tacb1(AW_awar *a, bool b) { |
---|
189 | TEST_EXPECT(a == fake_awar); |
---|
190 | TEST_EXPECT(b == fake_bool); |
---|
191 | tracef("tacb1()\n"); |
---|
192 | } |
---|
193 | static void tacb2(AW_awar *a, bool b, const char *name) { |
---|
194 | TEST_EXPECT(a == fake_awar); |
---|
195 | TEST_EXPECT(b == fake_bool); |
---|
196 | tracef("tacb2(%s)\n", name); |
---|
197 | } |
---|
198 | static void tacb2(AW_awar *a, bool b, int val) { |
---|
199 | TEST_EXPECT(a == fake_awar); |
---|
200 | TEST_EXPECT(b == fake_bool); |
---|
201 | tracef("tacb2(%i)\n", val); |
---|
202 | } |
---|
203 | |
---|
204 | static void ucb0(UNFIXED) { |
---|
205 | tracef("ucb0()\n"); |
---|
206 | } |
---|
207 | static void ucb1(UNFIXED, const char *name) { |
---|
208 | tracef("ucb1(%s)\n", name); |
---|
209 | } |
---|
210 | static void ucb2(UNFIXED, const char *name, int val) { |
---|
211 | tracef("ucb2(%s=%i) [int]\n", name, val); |
---|
212 | } |
---|
213 | static void ucb2(UNFIXED, const char *name, long val) { |
---|
214 | tracef("ucb2(%s=%li) [long]\n", name, val); |
---|
215 | } |
---|
216 | |
---|
217 | static AW_window *cwcb0(AW_root *r) { |
---|
218 | TEST_EXPECT(r == fake_root); |
---|
219 | tracef("cwcb0()\n"); |
---|
220 | return fake_win; |
---|
221 | } |
---|
222 | static AW_window *cwcb1(AW_root *r, int x) { |
---|
223 | TEST_EXPECT(r == fake_root); |
---|
224 | tracef("cwcb1(%i)\n", x); |
---|
225 | return fake_win; |
---|
226 | } |
---|
227 | static AW_window *cwcb1(AW_root *r, const long *lp) { |
---|
228 | TEST_EXPECT(r == fake_root); |
---|
229 | tracef("cwcb1(%li) [long ptr]\n", *lp); |
---|
230 | return fake_win; |
---|
231 | } |
---|
232 | static AW_window *cwcb1(AW_root *r, const int *x) { |
---|
233 | TEST_EXPECT(r == fake_root); |
---|
234 | tracef("cwcb1(%i) [const ptr]\n", *x); |
---|
235 | return fake_win; |
---|
236 | } |
---|
237 | static AW_window *cwcb1(AW_root *r, int *x) { |
---|
238 | TEST_EXPECT(r == fake_root); |
---|
239 | tracef("cwcb1(%i) [mutable ptr]\n", *x); |
---|
240 | *x *= 2; // modify callback argument! |
---|
241 | return fake_win; |
---|
242 | } |
---|
243 | static AW_window *cwcb1(AW_root *r, char* s) { |
---|
244 | TEST_EXPECT(r == fake_root); |
---|
245 | tracef("cwcb1(%s) [mutable]\n", s); |
---|
246 | return fake_win; |
---|
247 | } |
---|
248 | static AW_window *cwcb1(AW_root *r, const char* s) { |
---|
249 | TEST_EXPECT(r == fake_root); |
---|
250 | tracef("cwcb1(%s) [const]\n", s); |
---|
251 | return fake_win; |
---|
252 | } |
---|
253 | static AW_window *cwcb2(AW_root *r, const char *s1, const char *s2) { |
---|
254 | TEST_EXPECT(r == fake_root); |
---|
255 | tracef("cwcb2(%s,%s) [const const]\n", s1, s2); |
---|
256 | return fake_win; |
---|
257 | } |
---|
258 | static AW_window *cwcb2(AW_root *r, const char *s1, char *s2) { |
---|
259 | TEST_EXPECT(r == fake_root); |
---|
260 | tracef("cwcb2(%s,%s) [const mutable]\n", s1, s2); |
---|
261 | return fake_win; |
---|
262 | } |
---|
263 | |
---|
264 | static AW_window *cwcb3(AW_root *r, const char *s1, const char *s2) { |
---|
265 | TEST_EXPECT(r == fake_root); |
---|
266 | tracef("cwcb3(%s,%s) [const const]\n", s1, s2); |
---|
267 | return fake_win; |
---|
268 | } |
---|
269 | static AW_window *cwcb3(AW_root *r, const char *s1, char *s2) { |
---|
270 | TEST_EXPECT(r == fake_root); |
---|
271 | tracef("cwcb3(%s,%s) [const mutable]\n", s1, s2); |
---|
272 | return fake_win; |
---|
273 | } |
---|
274 | static AW_window *cwcb3(AW_root *r, char *s1, const char *s2) { |
---|
275 | TEST_EXPECT(r == fake_root); |
---|
276 | tracef("cwcb3(%s,%s) [mutable const]\n", s1, s2); |
---|
277 | return fake_win; |
---|
278 | } |
---|
279 | static AW_window *cwcb3(AW_root *r, char *s1, char *s2) { |
---|
280 | TEST_EXPECT(r == fake_root); |
---|
281 | tracef("cwcb3(%s,%s) [mutable mutable]\n", s1, s2); |
---|
282 | return fake_win; |
---|
283 | } |
---|
284 | |
---|
285 | static void dbcb01(GBDATA *gbd) { |
---|
286 | TEST_EXPECT(gbd == fake_gbd); |
---|
287 | tracef("dbcb01()\n"); |
---|
288 | } |
---|
289 | static void dbcb012(GBDATA *gbd, GB_CB_TYPE t) { |
---|
290 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
---|
291 | tracef("dbcb012()\n"); |
---|
292 | } |
---|
293 | static void dbcb02(GB_CB_TYPE t) { |
---|
294 | tracef("dbcb02(%i)\n", int(t)); |
---|
295 | } |
---|
296 | static void dbcb1(GBDATA *gbd, int x, GB_CB_TYPE t) { |
---|
297 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
---|
298 | tracef("dbcb1(%i) [int]\n", x); |
---|
299 | } |
---|
300 | static void dbcb1(GBDATA *gbd, const char *n, GB_CB_TYPE t) { |
---|
301 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
---|
302 | tracef("dbcb1(%s) [const char]\n", n); |
---|
303 | } |
---|
304 | |
---|
305 | static void plaincb() { |
---|
306 | tracef("plaincb()\n"); |
---|
307 | } |
---|
308 | static AW_window *cwcb_plain() { |
---|
309 | tracef("cwcb_plain()\n"); |
---|
310 | return fake_win; |
---|
311 | } |
---|
312 | |
---|
313 | inline void call(const RootCallback& rcb) { rcb(fake_root); } |
---|
314 | inline void call(const WindowCallback& wcb) { wcb(fake_win); } |
---|
315 | inline void call(const CreateWindowCallback& cwcb) { TEST_EXPECT(cwcb(fake_root) == fake_win); } |
---|
316 | inline void call(const DatabaseCallback& dbcb) { dbcb(fake_gbd, fake_gbtype); } |
---|
317 | inline void call(const TreeAwarCallback& tacb) { tacb(fake_awar, fake_bool); } |
---|
318 | |
---|
319 | #define TEST_CB(cb,expectedChecksum) do { \ |
---|
320 | traceChecksum = -666; \ |
---|
321 | call(cb); \ |
---|
322 | TEST_EXPECT_EQUAL(traceChecksum, (uint32_t)expectedChecksum); \ |
---|
323 | } while(0) |
---|
324 | |
---|
325 | #define TEST_CB_TRACE(cb,expectedOutput) do { \ |
---|
326 | call(cb); \ |
---|
327 | TEST_EXPECT_EQUAL(traceBuffer, expectedOutput); \ |
---|
328 | } while(0) |
---|
329 | |
---|
330 | #define TEST_CB_TRACE__BROKEN(cb,expectedOutput) do { \ |
---|
331 | call(cb); \ |
---|
332 | TEST_EXPECT_EQUAL__BROKEN(traceBuffer, expectedOutput); \ |
---|
333 | } while(0) |
---|
334 | |
---|
335 | |
---|
336 | static void freeCharp(char *str) { free(str); } |
---|
337 | static void freeCharp(char *str1, char *str2) { free(str1); free(str2); } |
---|
338 | static void deleteString(string *str) { delete str; } |
---|
339 | static void deleteString(string *str1, string *str2) { delete str1; delete str2; } |
---|
340 | |
---|
341 | void TEST_cbs() { |
---|
342 | // MISSING_TEST("please log"); |
---|
343 | // for (int i = 0; i<100000; ++i) |
---|
344 | { |
---|
345 | TEST_CB_TRACE(makeRootCallback(plaincb), "plaincb()\n"); |
---|
346 | TEST_CB_TRACE(makeRootCallback(rcb0), "rcb0()\n"); |
---|
347 | TEST_CB_TRACE(makeRootCallback(rcb1, "dispatched"), "rcb1(dispatched)\n"); |
---|
348 | TEST_CB_TRACE(makeRootCallback(rcb2, "age", 46), "rcb2(age=46) [int]\n"); |
---|
349 | TEST_CB_TRACE(makeRootCallback(rcb2, "size", 178L), "rcb2(size=178) [long]\n"); |
---|
350 | |
---|
351 | TEST_CB_TRACE(makeWindowCallback(plaincb), "plaincb()\n"); |
---|
352 | TEST_CB_TRACE(makeWindowCallback(wcb0), "wcb0()\n"); |
---|
353 | TEST_CB_TRACE(makeWindowCallback(wcb1, "dispatched"), "wcb1(dispatched)\n"); |
---|
354 | TEST_CB_TRACE(makeWindowCallback(wcb2, "age", 46), "wcb2(age=46) [int]\n"); |
---|
355 | TEST_CB_TRACE(makeWindowCallback(wcb2, "size", 178L), "wcb2(size=178) [long]\n"); |
---|
356 | |
---|
357 | TEST_CB_TRACE(makeTreeAwarCallback(plaincb), "plaincb()\n"); |
---|
358 | TEST_CB_TRACE(makeTreeAwarCallback(tacb0), "tacb0()\n"); |
---|
359 | TEST_CB_TRACE(makeTreeAwarCallback(tacb1), "tacb1()\n"); |
---|
360 | TEST_CB_TRACE(makeTreeAwarCallback(tacb2, "dispatched"), "tacb2(dispatched)\n"); |
---|
361 | TEST_CB_TRACE(makeTreeAwarCallback(tacb2, 46), "tacb2(46)\n"); |
---|
362 | |
---|
363 | // declaring a cb with UNFIXED as fixed-argument allows to use callbacks as RootCallback AND as WindowCallback |
---|
364 | // (when we use sigc++ in the future this should be changed to allowing functions w/o the UNFIXED-parameter) |
---|
365 | |
---|
366 | TEST_CB_TRACE(makeRootCallback(ucb0), "ucb0()\n"); |
---|
367 | TEST_CB_TRACE(makeRootCallback(ucb1, "dispatched"), "ucb1(dispatched)\n"); |
---|
368 | TEST_CB_TRACE(makeRootCallback(ucb2, "age", 46), "ucb2(age=46) [int]\n"); |
---|
369 | TEST_CB_TRACE(makeRootCallback(ucb2, "size", 178L), "ucb2(size=178) [long]\n"); |
---|
370 | |
---|
371 | TEST_CB_TRACE(makeWindowCallback(ucb0), "ucb0()\n"); |
---|
372 | TEST_CB_TRACE(makeWindowCallback(ucb1, "dispatched"), "ucb1(dispatched)\n"); |
---|
373 | TEST_CB_TRACE(makeWindowCallback(ucb2, "age", 46), "ucb2(age=46) [int]\n"); |
---|
374 | TEST_CB_TRACE(makeWindowCallback(ucb2, "size", 178L), "ucb2(size=178) [long]\n"); |
---|
375 | |
---|
376 | #if defined(ARB_64) |
---|
377 | TEST_CB_TRACE(makeWindowCallback(wcb2, 'l', 49710827735915452LL), "wcb2(l=49710827735915452) [long long]\n"); |
---|
378 | #endif |
---|
379 | |
---|
380 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb_plain), "cwcb_plain()\n"); |
---|
381 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb0), "cwcb0()\n"); |
---|
382 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, 77), "cwcb1(77)\n"); |
---|
383 | |
---|
384 | // TEST_CB(makeDatabaseCallback(plaincb), 44760); // does not work (ambiguous due to 2 fixed arguments of DatabaseCallback) |
---|
385 | TEST_CB_TRACE(makeDatabaseCallback(dbcb01), "dbcb01()\n"); |
---|
386 | TEST_CB_TRACE(makeDatabaseCallback(dbcb012), "dbcb012()\n"); |
---|
387 | TEST_CB_TRACE(makeDatabaseCallback(dbcb02), "dbcb02(2)\n"); // call dbcb02 with fixed argument (i.e. with argument normally passed by ARBDB) |
---|
388 | TEST_CB_TRACE(makeDatabaseCallback(dbcb1, 77), "dbcb1(77) [int]\n"); |
---|
389 | |
---|
390 | TEST_CB_TRACE(makeDatabaseCallback(dbcb1, freeCharp, strdup("test")), "dbcb1(test) [const char]\n"); |
---|
391 | |
---|
392 | // callbacks with deallocator |
---|
393 | |
---|
394 | // TEST_CB(makeWindowCallback(wcb1, strdup("leak")), 0x163ac); // leaks |
---|
395 | TEST_CB_TRACE(makeWindowCallback(wcb1, freeCharp, strdup("leak")), "wcb1(leak)\n"); |
---|
396 | // TEST_CB(makeWindowCallback(wcb1, freeCharp, "leak"), 0x163ac); // does not compile (can't call freeCharp with const char *) |
---|
397 | TEST_CB_TRACE(makeWindowCallback(wcb1, deleteString, new string("leak")), "wcb1(leak) [string]\n"); |
---|
398 | // TEST_CB(makeWindowCallback(wcb2, strdup("hue"), strdup("hott")), 0xe09d7b1); // leaks |
---|
399 | TEST_CB_TRACE(makeWindowCallback(wcb2, freeCharp, strdup("hue"), strdup("hott")), "wcb2(hue=hott) [const char/const char]\n"); |
---|
400 | TEST_CB_TRACE(makeWindowCallback(wcb2, deleteString, new string("hue"), new string("hott")), "wcb2(hue=hott) [string/string]\n"); |
---|
401 | |
---|
402 | // test const vs non-const pointers: |
---|
403 | char *mut = strdup("mut"); |
---|
404 | const char *con = "con"; |
---|
405 | |
---|
406 | // if only const/const and const/mutable exists -> shall always select as much mutable as possible |
---|
407 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, con, con), "cwcb2(con,con) [const const]\n"); // exact match |
---|
408 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, mut, con), "cwcb2(mut,con) [const const]\n"); // fallback to const/const |
---|
409 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, con, mut), "cwcb2(con,mut) [const mutable]\n"); // exact match |
---|
410 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, mut, mut), "cwcb2(mut,mut) [const mutable]\n"); // fallback to const/mutable |
---|
411 | |
---|
412 | // if all const/nonconst combinations exist -> shall always pick exact match |
---|
413 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, con, con), "cwcb3(con,con) [const const]\n"); // exact match |
---|
414 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, mut, con), "cwcb3(mut,con) [mutable const]\n"); // exact match |
---|
415 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, con, mut), "cwcb3(con,mut) [const mutable]\n"); // exact match |
---|
416 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, mut, mut), "cwcb3(mut,mut) [mutable mutable]\n"); // exact match |
---|
417 | |
---|
418 | // test reference arguments |
---|
419 | int imut = 17; |
---|
420 | const int icon = 23; |
---|
421 | |
---|
422 | const long lcon = 775L; |
---|
423 | |
---|
424 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, imut), "cwcb1(17)\n"); |
---|
425 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, icon), "cwcb1(23)\n"); |
---|
426 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &lcon), "cwcb1(775) [long ptr]\n"); |
---|
427 | |
---|
428 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &icon), "cwcb1(23) [const ptr]\n"); |
---|
429 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &icon), "cwcb1(23) [const ptr]\n"); |
---|
430 | |
---|
431 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(17) [mutable ptr]\n"); // modifies 'imut' |
---|
432 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(34) [mutable ptr]\n"); // modifies 'imut' |
---|
433 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(68) [mutable ptr]\n"); // modifies 'imut' |
---|
434 | |
---|
435 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, mut), "cwcb1(mut) [mutable]\n"); |
---|
436 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, con), "cwcb1(con) [const]\n"); |
---|
437 | |
---|
438 | free(mut); |
---|
439 | } |
---|
440 | |
---|
441 | } |
---|
442 | |
---|
443 | #endif // UNIT_TESTS |
---|
444 | |
---|
445 | |
---|