| 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 | static 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 | DECLARE_CBTYPE_VV_AND_BUILDERS(CustomCallback, void); // defines makeCustomCallback |
|---|
| 104 | |
|---|
| 105 | static uint32_t traceChecksum; |
|---|
| 106 | const int BUFFERSIZE = 100; |
|---|
| 107 | static char traceBuffer[BUFFERSIZE]; |
|---|
| 108 | |
|---|
| 109 | __ATTR__FORMAT(1) static void tracef(const char *format, ...) { |
|---|
| 110 | va_list parg; |
|---|
| 111 | va_start(parg, format); |
|---|
| 112 | int printed = vsnprintf(traceBuffer, BUFFERSIZE, format, parg); |
|---|
| 113 | va_end(parg); |
|---|
| 114 | |
|---|
| 115 | #if defined(TRACE) |
|---|
| 116 | fputs(traceBuffer, stdout); |
|---|
| 117 | #endif |
|---|
| 118 | if (printed >= BUFFERSIZE) { |
|---|
| 119 | printf("\nprinted=%i\n", printed); |
|---|
| 120 | } |
|---|
| 121 | TEST_EXPECT(printed<BUFFERSIZE); |
|---|
| 122 | |
|---|
| 123 | traceChecksum = 0; |
|---|
| 124 | for (int p = 0; p<printed; ++p) { |
|---|
| 125 | traceChecksum = (traceChecksum<<1)^(traceChecksum>>31)^traceBuffer[p]; |
|---|
| 126 | } |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | static AW_root *fake_root = (AW_root*)1; |
|---|
| 130 | static AW_window *fake_win = (AW_window*)2; |
|---|
| 131 | static GBDATA *fake_gbd = (GBDATA*)3; |
|---|
| 132 | static AW_awar *fake_awar = (AW_awar*)4; |
|---|
| 133 | static bool fake_bool = false; |
|---|
| 134 | static GB_CB_TYPE fake_gbtype = GB_CB_CHANGED; |
|---|
| 135 | |
|---|
| 136 | static void rcb0(AW_root *r) { |
|---|
| 137 | TEST_EXPECT(r == fake_root); |
|---|
| 138 | tracef("rcb0()\n"); |
|---|
| 139 | } |
|---|
| 140 | static void rcb1(AW_root *r, const char *name) { |
|---|
| 141 | TEST_EXPECT(r == fake_root); |
|---|
| 142 | tracef("rcb1(%s)\n", name); |
|---|
| 143 | } |
|---|
| 144 | static void rcb2(AW_root *r, const char *name, int val) { |
|---|
| 145 | TEST_EXPECT(r == fake_root); |
|---|
| 146 | tracef("rcb2(%s=%i) [int]\n", name, val); |
|---|
| 147 | } |
|---|
| 148 | static void rcb2(AW_root *r, const char *name, long val) { |
|---|
| 149 | TEST_EXPECT(r == fake_root); |
|---|
| 150 | tracef("rcb2(%s=%li) [long]\n", name, val); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | static void wcb0(AW_window *w) { |
|---|
| 154 | TEST_EXPECT(w == fake_win); |
|---|
| 155 | tracef("wcb0()\n"); |
|---|
| 156 | } |
|---|
| 157 | static void wcb1(AW_window *w, const char *name) { |
|---|
| 158 | TEST_EXPECT(w == fake_win); |
|---|
| 159 | tracef("wcb1(%s)\n", name); |
|---|
| 160 | } |
|---|
| 161 | static void wcb1(AW_window *w, string *name) { |
|---|
| 162 | TEST_EXPECT(w == fake_win); |
|---|
| 163 | tracef("wcb1(%s) [string]\n", name->c_str()); |
|---|
| 164 | } |
|---|
| 165 | static void wcb2(AW_window *w, const char *name, const char *val) { |
|---|
| 166 | TEST_EXPECT(w == fake_win); |
|---|
| 167 | tracef("wcb2(%s=%s) [const char/const char]\n", name, val); |
|---|
| 168 | } |
|---|
| 169 | static void wcb2(AW_window *w, const string *name, const string *val) { |
|---|
| 170 | TEST_EXPECT(w == fake_win); |
|---|
| 171 | tracef("wcb2(%s=%s) [string/string]\n", name->c_str(), val->c_str()); |
|---|
| 172 | } |
|---|
| 173 | static void wcb2(AW_window *w, const char *name, int val) { |
|---|
| 174 | TEST_EXPECT(w == fake_win); |
|---|
| 175 | tracef("wcb2(%s=%i) [int]\n", name, val); |
|---|
| 176 | } |
|---|
| 177 | static void wcb2(AW_window *w, const char *name, long val) { |
|---|
| 178 | TEST_EXPECT(w == fake_win); |
|---|
| 179 | tracef("wcb2(%s=%li) [long]\n", name, val); |
|---|
| 180 | } |
|---|
| 181 | static void wcb2(AW_window *w, char c, long long val) { |
|---|
| 182 | TEST_EXPECT(w == fake_win); |
|---|
| 183 | tracef("wcb2(%c=%lli) [long long]\n", c, val); |
|---|
| 184 | } |
|---|
| 185 | |
|---|
| 186 | static void tacb0(AW_awar *a) { |
|---|
| 187 | TEST_EXPECT(a == fake_awar); |
|---|
| 188 | tracef("tacb0()\n"); |
|---|
| 189 | } |
|---|
| 190 | static void tacb1(AW_awar *a, bool b) { |
|---|
| 191 | TEST_EXPECT(a == fake_awar); |
|---|
| 192 | TEST_EXPECT(b == fake_bool); |
|---|
| 193 | tracef("tacb1()\n"); |
|---|
| 194 | } |
|---|
| 195 | static void tacb2(AW_awar *a, bool b, const char *name) { |
|---|
| 196 | TEST_EXPECT(a == fake_awar); |
|---|
| 197 | TEST_EXPECT(b == fake_bool); |
|---|
| 198 | tracef("tacb2(%s)\n", name); |
|---|
| 199 | } |
|---|
| 200 | static void tacb2(AW_awar *a, bool b, int val) { |
|---|
| 201 | TEST_EXPECT(a == fake_awar); |
|---|
| 202 | TEST_EXPECT(b == fake_bool); |
|---|
| 203 | tracef("tacb2(%i)\n", val); |
|---|
| 204 | } |
|---|
| 205 | |
|---|
| 206 | static void ucb0(UNFIXED) { |
|---|
| 207 | tracef("ucb0()\n"); |
|---|
| 208 | } |
|---|
| 209 | static void ucb1(UNFIXED, const char *name) { |
|---|
| 210 | tracef("ucb1(%s)\n", name); |
|---|
| 211 | } |
|---|
| 212 | static void ucb2(UNFIXED, const char *name, int val) { |
|---|
| 213 | tracef("ucb2(%s=%i) [int]\n", name, val); |
|---|
| 214 | } |
|---|
| 215 | static void ucb2(UNFIXED, const char *name, long val) { |
|---|
| 216 | tracef("ucb2(%s=%li) [long]\n", name, val); |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | static AW_window *cwcb0(AW_root *r) { |
|---|
| 220 | TEST_EXPECT(r == fake_root); |
|---|
| 221 | tracef("cwcb0()\n"); |
|---|
| 222 | return fake_win; |
|---|
| 223 | } |
|---|
| 224 | static AW_window *cwcb1(AW_root *r, int x) { |
|---|
| 225 | TEST_EXPECT(r == fake_root); |
|---|
| 226 | tracef("cwcb1(%i)\n", x); |
|---|
| 227 | return fake_win; |
|---|
| 228 | } |
|---|
| 229 | static AW_window *cwcb1(AW_root *r, const long *lp) { |
|---|
| 230 | TEST_EXPECT(r == fake_root); |
|---|
| 231 | tracef("cwcb1(%li) [long ptr]\n", *lp); |
|---|
| 232 | return fake_win; |
|---|
| 233 | } |
|---|
| 234 | static AW_window *cwcb1(AW_root *r, const int *x) { |
|---|
| 235 | TEST_EXPECT(r == fake_root); |
|---|
| 236 | tracef("cwcb1(%i) [const ptr]\n", *x); |
|---|
| 237 | return fake_win; |
|---|
| 238 | } |
|---|
| 239 | static AW_window *cwcb1(AW_root *r, int *x) { |
|---|
| 240 | TEST_EXPECT(r == fake_root); |
|---|
| 241 | tracef("cwcb1(%i) [mutable ptr]\n", *x); |
|---|
| 242 | *x *= 2; // modify callback argument! |
|---|
| 243 | return fake_win; |
|---|
| 244 | } |
|---|
| 245 | static AW_window *cwcb1(AW_root *r, char* s) { |
|---|
| 246 | TEST_EXPECT(r == fake_root); |
|---|
| 247 | tracef("cwcb1(%s) [mutable]\n", s); |
|---|
| 248 | return fake_win; |
|---|
| 249 | } |
|---|
| 250 | static AW_window *cwcb1(AW_root *r, const char* s) { |
|---|
| 251 | TEST_EXPECT(r == fake_root); |
|---|
| 252 | tracef("cwcb1(%s) [const]\n", s); |
|---|
| 253 | return fake_win; |
|---|
| 254 | } |
|---|
| 255 | static AW_window *cwcb2(AW_root *r, const char *s1, const char *s2) { |
|---|
| 256 | TEST_EXPECT(r == fake_root); |
|---|
| 257 | tracef("cwcb2(%s,%s) [const const]\n", s1, s2); |
|---|
| 258 | return fake_win; |
|---|
| 259 | } |
|---|
| 260 | static AW_window *cwcb2(AW_root *r, const char *s1, char *s2) { |
|---|
| 261 | TEST_EXPECT(r == fake_root); |
|---|
| 262 | tracef("cwcb2(%s,%s) [const mutable]\n", s1, s2); |
|---|
| 263 | return fake_win; |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | static AW_window *cwcb3(AW_root *r, const char *s1, const char *s2) { |
|---|
| 267 | TEST_EXPECT(r == fake_root); |
|---|
| 268 | tracef("cwcb3(%s,%s) [const const]\n", s1, s2); |
|---|
| 269 | return fake_win; |
|---|
| 270 | } |
|---|
| 271 | static AW_window *cwcb3(AW_root *r, const char *s1, char *s2) { |
|---|
| 272 | TEST_EXPECT(r == fake_root); |
|---|
| 273 | tracef("cwcb3(%s,%s) [const mutable]\n", s1, s2); |
|---|
| 274 | return fake_win; |
|---|
| 275 | } |
|---|
| 276 | static AW_window *cwcb3(AW_root *r, char *s1, const char *s2) { |
|---|
| 277 | TEST_EXPECT(r == fake_root); |
|---|
| 278 | tracef("cwcb3(%s,%s) [mutable const]\n", s1, s2); |
|---|
| 279 | return fake_win; |
|---|
| 280 | } |
|---|
| 281 | static AW_window *cwcb3(AW_root *r, char *s1, char *s2) { |
|---|
| 282 | TEST_EXPECT(r == fake_root); |
|---|
| 283 | tracef("cwcb3(%s,%s) [mutable mutable]\n", s1, s2); |
|---|
| 284 | return fake_win; |
|---|
| 285 | } |
|---|
| 286 | |
|---|
| 287 | static void dbcb01(GBDATA *gbd) { |
|---|
| 288 | TEST_EXPECT(gbd == fake_gbd); |
|---|
| 289 | tracef("dbcb01()\n"); |
|---|
| 290 | } |
|---|
| 291 | static void dbcb012(GBDATA *gbd, GB_CB_TYPE t) { |
|---|
| 292 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
|---|
| 293 | tracef("dbcb012()\n"); |
|---|
| 294 | } |
|---|
| 295 | static void dbcb02(GB_CB_TYPE t) { |
|---|
| 296 | tracef("dbcb02(%i)\n", int(t)); |
|---|
| 297 | } |
|---|
| 298 | static void dbcb1(GBDATA *gbd, int x, GB_CB_TYPE t) { |
|---|
| 299 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
|---|
| 300 | tracef("dbcb1(%i) [int]\n", x); |
|---|
| 301 | } |
|---|
| 302 | static void dbcb1(GBDATA *gbd, const char *n, GB_CB_TYPE t) { |
|---|
| 303 | TEST_EXPECT(gbd == fake_gbd && t == fake_gbtype); |
|---|
| 304 | tracef("dbcb1(%s) [const char]\n", n); |
|---|
| 305 | } |
|---|
| 306 | |
|---|
| 307 | static void ccb11(const char *str) { |
|---|
| 308 | tracef("ccb11(%s)\n", str); |
|---|
| 309 | } |
|---|
| 310 | static void ccb12(int i) { |
|---|
| 311 | tracef("ccb12(%i)\n", i); |
|---|
| 312 | } |
|---|
| 313 | static void ccb2(int i, const char *str) { |
|---|
| 314 | tracef("ccb2(%i,%s)\n", i, str); |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | static void plaincb() { |
|---|
| 318 | tracef("plaincb()\n"); |
|---|
| 319 | } |
|---|
| 320 | static AW_window *cwcb_plain() { |
|---|
| 321 | tracef("cwcb_plain()\n"); |
|---|
| 322 | return fake_win; |
|---|
| 323 | } |
|---|
| 324 | |
|---|
| 325 | inline void call(const RootCallback& rcb) { rcb(fake_root); } |
|---|
| 326 | inline void call(const WindowCallback& wcb) { wcb(fake_win); } |
|---|
| 327 | inline void call(const CreateWindowCallback& cwcb) { TEST_EXPECT(cwcb(fake_root) == fake_win); } |
|---|
| 328 | inline void call(const DatabaseCallback& dbcb) { dbcb(fake_gbd, fake_gbtype); } |
|---|
| 329 | inline void call(const TreeAwarCallback& tacb) { tacb(fake_awar, fake_bool); } |
|---|
| 330 | inline void call(const CustomCallback& ccb) { ccb(); } |
|---|
| 331 | |
|---|
| 332 | #define TEST_CB(cb,expectedChecksum) do { \ |
|---|
| 333 | traceChecksum = -666; \ |
|---|
| 334 | call(cb); \ |
|---|
| 335 | TEST_EXPECT_EQUAL(traceChecksum, (uint32_t)expectedChecksum); \ |
|---|
| 336 | } while(0) |
|---|
| 337 | |
|---|
| 338 | #define TEST_CB_TRACE(cb,expectedOutput) do { \ |
|---|
| 339 | call(cb); \ |
|---|
| 340 | TEST_EXPECT_EQUAL(traceBuffer, expectedOutput); \ |
|---|
| 341 | } while(0) |
|---|
| 342 | |
|---|
| 343 | #define TEST_CB_TRACE__BROKEN(cb,expectedOutput) do { \ |
|---|
| 344 | call(cb); \ |
|---|
| 345 | TEST_EXPECT_EQUAL__BROKEN(traceBuffer, expectedOutput); \ |
|---|
| 346 | } while(0) |
|---|
| 347 | |
|---|
| 348 | |
|---|
| 349 | static void freeCharp(char *str) { free(str); } |
|---|
| 350 | static void freeCharp(char *str1, char *str2) { free(str1); free(str2); } |
|---|
| 351 | static void deleteString(string *str) { delete str; } |
|---|
| 352 | static void deleteString(string *str1, string *str2) { delete str1; delete str2; } |
|---|
| 353 | |
|---|
| 354 | void TEST_cbs() { |
|---|
| 355 | // MISSING_TEST("please log"); |
|---|
| 356 | // for (int i = 0; i<100000; ++i) |
|---|
| 357 | { |
|---|
| 358 | TEST_CB_TRACE(makeRootCallback(plaincb), "plaincb()\n"); |
|---|
| 359 | TEST_CB_TRACE(makeRootCallback(rcb0), "rcb0()\n"); |
|---|
| 360 | TEST_CB_TRACE(makeRootCallback(rcb1, "dispatched"), "rcb1(dispatched)\n"); |
|---|
| 361 | TEST_CB_TRACE(makeRootCallback(rcb2, "age", 46), "rcb2(age=46) [int]\n"); |
|---|
| 362 | TEST_CB_TRACE(makeRootCallback(rcb2, "size", 178L), "rcb2(size=178) [long]\n"); |
|---|
| 363 | |
|---|
| 364 | TEST_CB_TRACE(makeWindowCallback(plaincb), "plaincb()\n"); |
|---|
| 365 | TEST_CB_TRACE(makeWindowCallback(wcb0), "wcb0()\n"); |
|---|
| 366 | TEST_CB_TRACE(makeWindowCallback(wcb1, "dispatched"), "wcb1(dispatched)\n"); |
|---|
| 367 | TEST_CB_TRACE(makeWindowCallback(wcb2, "age", 46), "wcb2(age=46) [int]\n"); |
|---|
| 368 | TEST_CB_TRACE(makeWindowCallback(wcb2, "size", 178L), "wcb2(size=178) [long]\n"); |
|---|
| 369 | |
|---|
| 370 | TEST_CB_TRACE(makeTreeAwarCallback(plaincb), "plaincb()\n"); |
|---|
| 371 | TEST_CB_TRACE(makeTreeAwarCallback(tacb0), "tacb0()\n"); |
|---|
| 372 | TEST_CB_TRACE(makeTreeAwarCallback(tacb1), "tacb1()\n"); |
|---|
| 373 | TEST_CB_TRACE(makeTreeAwarCallback(tacb2, "dispatched"), "tacb2(dispatched)\n"); |
|---|
| 374 | TEST_CB_TRACE(makeTreeAwarCallback(tacb2, 46), "tacb2(46)\n"); |
|---|
| 375 | |
|---|
| 376 | // declaring a cb with UNFIXED as fixed-argument allows to use callbacks as RootCallback AND as WindowCallback |
|---|
| 377 | // (when we use sigc++ in the future this should be changed to allowing functions w/o the UNFIXED-parameter) |
|---|
| 378 | |
|---|
| 379 | TEST_CB_TRACE(makeRootCallback(ucb0), "ucb0()\n"); |
|---|
| 380 | TEST_CB_TRACE(makeRootCallback(ucb1, "dispatched"), "ucb1(dispatched)\n"); |
|---|
| 381 | TEST_CB_TRACE(makeRootCallback(ucb2, "age", 46), "ucb2(age=46) [int]\n"); |
|---|
| 382 | TEST_CB_TRACE(makeRootCallback(ucb2, "size", 178L), "ucb2(size=178) [long]\n"); |
|---|
| 383 | |
|---|
| 384 | TEST_CB_TRACE(makeWindowCallback(ucb0), "ucb0()\n"); |
|---|
| 385 | TEST_CB_TRACE(makeWindowCallback(ucb1, "dispatched"), "ucb1(dispatched)\n"); |
|---|
| 386 | TEST_CB_TRACE(makeWindowCallback(ucb2, "age", 46), "ucb2(age=46) [int]\n"); |
|---|
| 387 | TEST_CB_TRACE(makeWindowCallback(ucb2, "size", 178L), "ucb2(size=178) [long]\n"); |
|---|
| 388 | |
|---|
| 389 | #if defined(ARB_64) |
|---|
| 390 | TEST_CB_TRACE(makeWindowCallback(wcb2, 'l', 49710827735915452LL), "wcb2(l=49710827735915452) [long long]\n"); |
|---|
| 391 | #endif |
|---|
| 392 | |
|---|
| 393 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb_plain), "cwcb_plain()\n"); |
|---|
| 394 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb0), "cwcb0()\n"); |
|---|
| 395 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, 77), "cwcb1(77)\n"); |
|---|
| 396 | |
|---|
| 397 | // TEST_CB(makeDatabaseCallback(plaincb), 44760); // does not work (ambiguous due to 2 fixed arguments of DatabaseCallback) |
|---|
| 398 | TEST_CB_TRACE(makeDatabaseCallback(dbcb01), "dbcb01()\n"); |
|---|
| 399 | TEST_CB_TRACE(makeDatabaseCallback(dbcb012), "dbcb012()\n"); |
|---|
| 400 | TEST_CB_TRACE(makeDatabaseCallback(dbcb02), "dbcb02(2)\n"); // call dbcb02 with fixed argument (i.e. with argument normally passed by ARBDB) |
|---|
| 401 | TEST_CB_TRACE(makeDatabaseCallback(dbcb1, 77), "dbcb1(77) [int]\n"); |
|---|
| 402 | |
|---|
| 403 | TEST_CB_TRACE(makeDatabaseCallback(dbcb1, freeCharp, strdup("test")), "dbcb1(test) [const char]\n"); |
|---|
| 404 | |
|---|
| 405 | // callbacks with deallocator |
|---|
| 406 | |
|---|
| 407 | // TEST_CB(makeWindowCallback(wcb1, strdup("leak")), 0x163ac); // leaks |
|---|
| 408 | TEST_CB_TRACE(makeWindowCallback(wcb1, freeCharp, strdup("leak")), "wcb1(leak)\n"); |
|---|
| 409 | // TEST_CB(makeWindowCallback(wcb1, freeCharp, "leak"), 0x163ac); // does not compile (can't call freeCharp with const char *) |
|---|
| 410 | TEST_CB_TRACE(makeWindowCallback(wcb1, deleteString, new string("leak")), "wcb1(leak) [string]\n"); |
|---|
| 411 | // TEST_CB(makeWindowCallback(wcb2, strdup("hue"), strdup("hott")), 0xe09d7b1); // leaks |
|---|
| 412 | TEST_CB_TRACE(makeWindowCallback(wcb2, freeCharp, strdup("hue"), strdup("hott")), "wcb2(hue=hott) [const char/const char]\n"); |
|---|
| 413 | TEST_CB_TRACE(makeWindowCallback(wcb2, deleteString, new string("hue"), new string("hott")), "wcb2(hue=hott) [string/string]\n"); |
|---|
| 414 | |
|---|
| 415 | // test const vs non-const pointers: |
|---|
| 416 | char *mut = strdup("mut"); |
|---|
| 417 | const char *con = "con"; |
|---|
| 418 | |
|---|
| 419 | // if only const/const and const/mutable exists -> shall always select as much mutable as possible |
|---|
| 420 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, con, con), "cwcb2(con,con) [const const]\n"); // exact match |
|---|
| 421 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, mut, con), "cwcb2(mut,con) [const const]\n"); // fallback to const/const |
|---|
| 422 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, con, mut), "cwcb2(con,mut) [const mutable]\n"); // exact match |
|---|
| 423 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb2, mut, mut), "cwcb2(mut,mut) [const mutable]\n"); // fallback to const/mutable |
|---|
| 424 | |
|---|
| 425 | // if all const/nonconst combinations exist -> shall always pick exact match |
|---|
| 426 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, con, con), "cwcb3(con,con) [const const]\n"); // exact match |
|---|
| 427 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, mut, con), "cwcb3(mut,con) [mutable const]\n"); // exact match |
|---|
| 428 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, con, mut), "cwcb3(con,mut) [const mutable]\n"); // exact match |
|---|
| 429 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb3, mut, mut), "cwcb3(mut,mut) [mutable mutable]\n"); // exact match |
|---|
| 430 | |
|---|
| 431 | // test reference arguments |
|---|
| 432 | int imut = 17; |
|---|
| 433 | const int icon = 23; |
|---|
| 434 | |
|---|
| 435 | const long lcon = 775L; |
|---|
| 436 | |
|---|
| 437 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, imut), "cwcb1(17)\n"); |
|---|
| 438 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, icon), "cwcb1(23)\n"); |
|---|
| 439 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &lcon), "cwcb1(775) [long ptr]\n"); |
|---|
| 440 | |
|---|
| 441 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &icon), "cwcb1(23) [const ptr]\n"); |
|---|
| 442 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &icon), "cwcb1(23) [const ptr]\n"); |
|---|
| 443 | |
|---|
| 444 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(17) [mutable ptr]\n"); // modifies 'imut' |
|---|
| 445 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(34) [mutable ptr]\n"); // modifies 'imut' |
|---|
| 446 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, &imut), "cwcb1(68) [mutable ptr]\n"); // modifies 'imut' |
|---|
| 447 | |
|---|
| 448 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, mut), "cwcb1(mut) [mutable]\n"); |
|---|
| 449 | TEST_CB_TRACE(makeCreateWindowCallback(cwcb1, con), "cwcb1(con) [const]\n"); |
|---|
| 450 | |
|---|
| 451 | free(mut); |
|---|
| 452 | |
|---|
| 453 | // test callbacks w/o fixed argument |
|---|
| 454 | TEST_CB_TRACE(makeCustomCallback(plaincb), "plaincb()\n"); |
|---|
| 455 | TEST_CB_TRACE(makeCustomCallback(ccb11, "helo"), "ccb11(helo)\n"); |
|---|
| 456 | TEST_CB_TRACE(makeCustomCallback(ccb12, 4711), "ccb12(4711)\n"); |
|---|
| 457 | TEST_CB_TRACE(makeCustomCallback(ccb2, 4711, "helo"), "ccb2(4711,helo)\n"); |
|---|
| 458 | |
|---|
| 459 | TEST_CB_TRACE(makeCustomCallback(ccb11, freeCharp, strdup("dup")), "ccb11(dup)\n"); |
|---|
| 460 | } |
|---|
| 461 | |
|---|
| 462 | } |
|---|
| 463 | TEST_PUBLISH(TEST_cbs); |
|---|
| 464 | |
|---|
| 465 | #endif // UNIT_TESTS |
|---|
| 466 | |
|---|
| 467 | |
|---|