1362aecb2SWilly Tarreau // SPDX-License-Identifier: GPL-2.0 2362aecb2SWilly Tarreau 3362aecb2SWilly Tarreau /* platform-specific include files coming from the compiler */ 4362aecb2SWilly Tarreau #include <limits.h> 5362aecb2SWilly Tarreau 6362aecb2SWilly Tarreau /* libc-specific include files 7362aecb2SWilly Tarreau * The program may be built in 2 ways: 8362aecb2SWilly Tarreau * $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined 9362aecb2SWilly Tarreau * $(CC) -nostdlib -I/path/to/nolibc/sysroot 10362aecb2SWilly Tarreau */ 11362aecb2SWilly Tarreau #ifndef NOLIBC 12362aecb2SWilly Tarreau #include <stdio.h> 13362aecb2SWilly Tarreau #include <stdlib.h> 14362aecb2SWilly Tarreau #include <string.h> 15362aecb2SWilly Tarreau #endif 16362aecb2SWilly Tarreau 17362aecb2SWilly Tarreau /* will be used by nolibc by getenv() */ 18362aecb2SWilly Tarreau char **environ; 19362aecb2SWilly Tarreau 20*23da7bc9SWilly Tarreau /* definition of a series of tests */ 21*23da7bc9SWilly Tarreau struct test { 22*23da7bc9SWilly Tarreau const char *name; // test name 23*23da7bc9SWilly Tarreau int (*func)(int min, int max); // handler 24*23da7bc9SWilly Tarreau }; 25*23da7bc9SWilly Tarreau 26362aecb2SWilly Tarreau #define CASE_ERR(err) \ 27362aecb2SWilly Tarreau case err: return #err 28362aecb2SWilly Tarreau 29362aecb2SWilly Tarreau /* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0, 30362aecb2SWilly Tarreau * or the decimal value for less common ones. 31362aecb2SWilly Tarreau */ 32362aecb2SWilly Tarreau const char *errorname(int err) 33362aecb2SWilly Tarreau { 34362aecb2SWilly Tarreau switch (err) { 35362aecb2SWilly Tarreau case 0: return "SUCCESS"; 36362aecb2SWilly Tarreau CASE_ERR(EPERM); 37362aecb2SWilly Tarreau CASE_ERR(ENOENT); 38362aecb2SWilly Tarreau CASE_ERR(ESRCH); 39362aecb2SWilly Tarreau CASE_ERR(EINTR); 40362aecb2SWilly Tarreau CASE_ERR(EIO); 41362aecb2SWilly Tarreau CASE_ERR(ENXIO); 42362aecb2SWilly Tarreau CASE_ERR(E2BIG); 43362aecb2SWilly Tarreau CASE_ERR(ENOEXEC); 44362aecb2SWilly Tarreau CASE_ERR(EBADF); 45362aecb2SWilly Tarreau CASE_ERR(ECHILD); 46362aecb2SWilly Tarreau CASE_ERR(EAGAIN); 47362aecb2SWilly Tarreau CASE_ERR(ENOMEM); 48362aecb2SWilly Tarreau CASE_ERR(EACCES); 49362aecb2SWilly Tarreau CASE_ERR(EFAULT); 50362aecb2SWilly Tarreau CASE_ERR(ENOTBLK); 51362aecb2SWilly Tarreau CASE_ERR(EBUSY); 52362aecb2SWilly Tarreau CASE_ERR(EEXIST); 53362aecb2SWilly Tarreau CASE_ERR(EXDEV); 54362aecb2SWilly Tarreau CASE_ERR(ENODEV); 55362aecb2SWilly Tarreau CASE_ERR(ENOTDIR); 56362aecb2SWilly Tarreau CASE_ERR(EISDIR); 57362aecb2SWilly Tarreau CASE_ERR(EINVAL); 58362aecb2SWilly Tarreau CASE_ERR(ENFILE); 59362aecb2SWilly Tarreau CASE_ERR(EMFILE); 60362aecb2SWilly Tarreau CASE_ERR(ENOTTY); 61362aecb2SWilly Tarreau CASE_ERR(ETXTBSY); 62362aecb2SWilly Tarreau CASE_ERR(EFBIG); 63362aecb2SWilly Tarreau CASE_ERR(ENOSPC); 64362aecb2SWilly Tarreau CASE_ERR(ESPIPE); 65362aecb2SWilly Tarreau CASE_ERR(EROFS); 66362aecb2SWilly Tarreau CASE_ERR(EMLINK); 67362aecb2SWilly Tarreau CASE_ERR(EPIPE); 68362aecb2SWilly Tarreau CASE_ERR(EDOM); 69362aecb2SWilly Tarreau CASE_ERR(ERANGE); 70362aecb2SWilly Tarreau CASE_ERR(ENOSYS); 71362aecb2SWilly Tarreau default: 72362aecb2SWilly Tarreau return itoa(err); 73362aecb2SWilly Tarreau } 74362aecb2SWilly Tarreau } 75362aecb2SWilly Tarreau 76362aecb2SWilly Tarreau static int pad_spc(int llen, int cnt, const char *fmt, ...) 77362aecb2SWilly Tarreau { 78362aecb2SWilly Tarreau va_list args; 79362aecb2SWilly Tarreau int len; 80362aecb2SWilly Tarreau int ret; 81362aecb2SWilly Tarreau 82362aecb2SWilly Tarreau for (len = 0; len < cnt - llen; len++) 83362aecb2SWilly Tarreau putchar(' '); 84362aecb2SWilly Tarreau 85362aecb2SWilly Tarreau va_start(args, fmt); 86362aecb2SWilly Tarreau ret = vfprintf(stdout, fmt, args); 87362aecb2SWilly Tarreau va_end(args); 88362aecb2SWilly Tarreau return ret < 0 ? ret : ret + len; 89362aecb2SWilly Tarreau } 90362aecb2SWilly Tarreau 91362aecb2SWilly Tarreau /* The tests below are intended to be used by the macroes, which evaluate 92362aecb2SWilly Tarreau * expression <expr>, print the status to stdout, and update the "ret" 93362aecb2SWilly Tarreau * variable to count failures. The functions themselves return the number 94362aecb2SWilly Tarreau * of failures, thus either 0 or 1. 95362aecb2SWilly Tarreau */ 96362aecb2SWilly Tarreau 97362aecb2SWilly Tarreau #define EXPECT_ZR(cond, expr) \ 98362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0) 99362aecb2SWilly Tarreau 100362aecb2SWilly Tarreau static int expect_zr(int expr, int llen) 101362aecb2SWilly Tarreau { 102362aecb2SWilly Tarreau int ret = !(expr == 0); 103362aecb2SWilly Tarreau 104362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 105362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 106362aecb2SWilly Tarreau return ret; 107362aecb2SWilly Tarreau } 108362aecb2SWilly Tarreau 109362aecb2SWilly Tarreau 110362aecb2SWilly Tarreau #define EXPECT_NZ(cond, expr, val) \ 111362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0) 112362aecb2SWilly Tarreau 113362aecb2SWilly Tarreau static int expect_nz(int expr, int llen) 114362aecb2SWilly Tarreau { 115362aecb2SWilly Tarreau int ret = !(expr != 0); 116362aecb2SWilly Tarreau 117362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 118362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 119362aecb2SWilly Tarreau return ret; 120362aecb2SWilly Tarreau } 121362aecb2SWilly Tarreau 122362aecb2SWilly Tarreau 123362aecb2SWilly Tarreau #define EXPECT_EQ(cond, expr, val) \ 124362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0) 125362aecb2SWilly Tarreau 126362aecb2SWilly Tarreau static int expect_eq(int expr, int llen, int val) 127362aecb2SWilly Tarreau { 128362aecb2SWilly Tarreau int ret = !(expr == val); 129362aecb2SWilly Tarreau 130362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 131362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 132362aecb2SWilly Tarreau return ret; 133362aecb2SWilly Tarreau } 134362aecb2SWilly Tarreau 135362aecb2SWilly Tarreau 136362aecb2SWilly Tarreau #define EXPECT_NE(cond, expr, val) \ 137362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0) 138362aecb2SWilly Tarreau 139362aecb2SWilly Tarreau static int expect_ne(int expr, int llen, int val) 140362aecb2SWilly Tarreau { 141362aecb2SWilly Tarreau int ret = !(expr != val); 142362aecb2SWilly Tarreau 143362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 144362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 145362aecb2SWilly Tarreau return ret; 146362aecb2SWilly Tarreau } 147362aecb2SWilly Tarreau 148362aecb2SWilly Tarreau 149362aecb2SWilly Tarreau #define EXPECT_GE(cond, expr, val) \ 150362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0) 151362aecb2SWilly Tarreau 152362aecb2SWilly Tarreau static int expect_ge(int expr, int llen, int val) 153362aecb2SWilly Tarreau { 154362aecb2SWilly Tarreau int ret = !(expr >= val); 155362aecb2SWilly Tarreau 156362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 157362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 158362aecb2SWilly Tarreau return ret; 159362aecb2SWilly Tarreau } 160362aecb2SWilly Tarreau 161362aecb2SWilly Tarreau 162362aecb2SWilly Tarreau #define EXPECT_GT(cond, expr, val) \ 163362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0) 164362aecb2SWilly Tarreau 165362aecb2SWilly Tarreau static int expect_gt(int expr, int llen, int val) 166362aecb2SWilly Tarreau { 167362aecb2SWilly Tarreau int ret = !(expr > val); 168362aecb2SWilly Tarreau 169362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 170362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 171362aecb2SWilly Tarreau return ret; 172362aecb2SWilly Tarreau } 173362aecb2SWilly Tarreau 174362aecb2SWilly Tarreau 175362aecb2SWilly Tarreau #define EXPECT_LE(cond, expr, val) \ 176362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0) 177362aecb2SWilly Tarreau 178362aecb2SWilly Tarreau static int expect_le(int expr, int llen, int val) 179362aecb2SWilly Tarreau { 180362aecb2SWilly Tarreau int ret = !(expr <= val); 181362aecb2SWilly Tarreau 182362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 183362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 184362aecb2SWilly Tarreau return ret; 185362aecb2SWilly Tarreau } 186362aecb2SWilly Tarreau 187362aecb2SWilly Tarreau 188362aecb2SWilly Tarreau #define EXPECT_LT(cond, expr, val) \ 189362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0) 190362aecb2SWilly Tarreau 191362aecb2SWilly Tarreau static int expect_lt(int expr, int llen, int val) 192362aecb2SWilly Tarreau { 193362aecb2SWilly Tarreau int ret = !(expr < val); 194362aecb2SWilly Tarreau 195362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 196362aecb2SWilly Tarreau pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n"); 197362aecb2SWilly Tarreau return ret; 198362aecb2SWilly Tarreau } 199362aecb2SWilly Tarreau 200362aecb2SWilly Tarreau 201362aecb2SWilly Tarreau #define EXPECT_SYSZR(cond, expr) \ 202362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0) 203362aecb2SWilly Tarreau 204362aecb2SWilly Tarreau static int expect_syszr(int expr, int llen) 205362aecb2SWilly Tarreau { 206362aecb2SWilly Tarreau int ret = 0; 207362aecb2SWilly Tarreau 208362aecb2SWilly Tarreau if (expr) { 209362aecb2SWilly Tarreau ret = 1; 210362aecb2SWilly Tarreau llen += printf(" = %d %s ", expr, errorname(errno)); 211362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 212362aecb2SWilly Tarreau } else { 213362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 214362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 215362aecb2SWilly Tarreau } 216362aecb2SWilly Tarreau return ret; 217362aecb2SWilly Tarreau } 218362aecb2SWilly Tarreau 219362aecb2SWilly Tarreau 220362aecb2SWilly Tarreau #define EXPECT_SYSEQ(cond, expr, val) \ 221362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0) 222362aecb2SWilly Tarreau 223362aecb2SWilly Tarreau static int expect_syseq(int expr, int llen, int val) 224362aecb2SWilly Tarreau { 225362aecb2SWilly Tarreau int ret = 0; 226362aecb2SWilly Tarreau 227362aecb2SWilly Tarreau if (expr != val) { 228362aecb2SWilly Tarreau ret = 1; 229362aecb2SWilly Tarreau llen += printf(" = %d %s ", expr, errorname(errno)); 230362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 231362aecb2SWilly Tarreau } else { 232362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 233362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 234362aecb2SWilly Tarreau } 235362aecb2SWilly Tarreau return ret; 236362aecb2SWilly Tarreau } 237362aecb2SWilly Tarreau 238362aecb2SWilly Tarreau 239362aecb2SWilly Tarreau #define EXPECT_SYSNE(cond, expr, val) \ 240362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0) 241362aecb2SWilly Tarreau 242362aecb2SWilly Tarreau static int expect_sysne(int expr, int llen, int val) 243362aecb2SWilly Tarreau { 244362aecb2SWilly Tarreau int ret = 0; 245362aecb2SWilly Tarreau 246362aecb2SWilly Tarreau if (expr == val) { 247362aecb2SWilly Tarreau ret = 1; 248362aecb2SWilly Tarreau llen += printf(" = %d %s ", expr, errorname(errno)); 249362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 250362aecb2SWilly Tarreau } else { 251362aecb2SWilly Tarreau llen += printf(" = %d ", expr); 252362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 253362aecb2SWilly Tarreau } 254362aecb2SWilly Tarreau return ret; 255362aecb2SWilly Tarreau } 256362aecb2SWilly Tarreau 257362aecb2SWilly Tarreau 258362aecb2SWilly Tarreau #define EXPECT_SYSER(cond, expr, expret, experr) \ 259362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0) 260362aecb2SWilly Tarreau 261362aecb2SWilly Tarreau static int expect_syserr(int expr, int expret, int experr, int llen) 262362aecb2SWilly Tarreau { 263362aecb2SWilly Tarreau int ret = 0; 264362aecb2SWilly Tarreau int _errno = errno; 265362aecb2SWilly Tarreau 266362aecb2SWilly Tarreau llen += printf(" = %d %s ", expr, errorname(_errno)); 267362aecb2SWilly Tarreau if (expr != expret || _errno != experr) { 268362aecb2SWilly Tarreau ret = 1; 269362aecb2SWilly Tarreau llen += printf(" != (%d %s) ", expret, errorname(experr)); 270362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 271362aecb2SWilly Tarreau } else { 272362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 273362aecb2SWilly Tarreau } 274362aecb2SWilly Tarreau return ret; 275362aecb2SWilly Tarreau } 276362aecb2SWilly Tarreau 277362aecb2SWilly Tarreau 278362aecb2SWilly Tarreau #define EXPECT_PTRZR(cond, expr) \ 279362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0) 280362aecb2SWilly Tarreau 281362aecb2SWilly Tarreau static int expect_ptrzr(const void *expr, int llen) 282362aecb2SWilly Tarreau { 283362aecb2SWilly Tarreau int ret = 0; 284362aecb2SWilly Tarreau 285362aecb2SWilly Tarreau llen += printf(" = <%p> ", expr); 286362aecb2SWilly Tarreau if (expr) { 287362aecb2SWilly Tarreau ret = 1; 288362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 289362aecb2SWilly Tarreau } else { 290362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 291362aecb2SWilly Tarreau } 292362aecb2SWilly Tarreau return ret; 293362aecb2SWilly Tarreau } 294362aecb2SWilly Tarreau 295362aecb2SWilly Tarreau 296362aecb2SWilly Tarreau #define EXPECT_PTRNZ(cond, expr) \ 297362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0) 298362aecb2SWilly Tarreau 299362aecb2SWilly Tarreau static int expect_ptrnz(const void *expr, int llen) 300362aecb2SWilly Tarreau { 301362aecb2SWilly Tarreau int ret = 0; 302362aecb2SWilly Tarreau 303362aecb2SWilly Tarreau llen += printf(" = <%p> ", expr); 304362aecb2SWilly Tarreau if (!expr) { 305362aecb2SWilly Tarreau ret = 1; 306362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 307362aecb2SWilly Tarreau } else { 308362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 309362aecb2SWilly Tarreau } 310362aecb2SWilly Tarreau return ret; 311362aecb2SWilly Tarreau } 312362aecb2SWilly Tarreau 313362aecb2SWilly Tarreau 314362aecb2SWilly Tarreau #define EXPECT_STRZR(cond, expr) \ 315362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0) 316362aecb2SWilly Tarreau 317362aecb2SWilly Tarreau static int expect_strzr(const char *expr, int llen) 318362aecb2SWilly Tarreau { 319362aecb2SWilly Tarreau int ret = 0; 320362aecb2SWilly Tarreau 321362aecb2SWilly Tarreau llen += printf(" = <%s> ", expr); 322362aecb2SWilly Tarreau if (expr) { 323362aecb2SWilly Tarreau ret = 1; 324362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 325362aecb2SWilly Tarreau } else { 326362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 327362aecb2SWilly Tarreau } 328362aecb2SWilly Tarreau return ret; 329362aecb2SWilly Tarreau } 330362aecb2SWilly Tarreau 331362aecb2SWilly Tarreau 332362aecb2SWilly Tarreau #define EXPECT_STRNZ(cond, expr) \ 333362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0) 334362aecb2SWilly Tarreau 335362aecb2SWilly Tarreau static int expect_strnz(const char *expr, int llen) 336362aecb2SWilly Tarreau { 337362aecb2SWilly Tarreau int ret = 0; 338362aecb2SWilly Tarreau 339362aecb2SWilly Tarreau llen += printf(" = <%s> ", expr); 340362aecb2SWilly Tarreau if (!expr) { 341362aecb2SWilly Tarreau ret = 1; 342362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 343362aecb2SWilly Tarreau } else { 344362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 345362aecb2SWilly Tarreau } 346362aecb2SWilly Tarreau return ret; 347362aecb2SWilly Tarreau } 348362aecb2SWilly Tarreau 349362aecb2SWilly Tarreau 350362aecb2SWilly Tarreau #define EXPECT_STREQ(cond, expr, cmp) \ 351362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0) 352362aecb2SWilly Tarreau 353362aecb2SWilly Tarreau static int expect_streq(const char *expr, int llen, const char *cmp) 354362aecb2SWilly Tarreau { 355362aecb2SWilly Tarreau int ret = 0; 356362aecb2SWilly Tarreau 357362aecb2SWilly Tarreau llen += printf(" = <%s> ", expr); 358362aecb2SWilly Tarreau if (strcmp(expr, cmp) != 0) { 359362aecb2SWilly Tarreau ret = 1; 360362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 361362aecb2SWilly Tarreau } else { 362362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 363362aecb2SWilly Tarreau } 364362aecb2SWilly Tarreau return ret; 365362aecb2SWilly Tarreau } 366362aecb2SWilly Tarreau 367362aecb2SWilly Tarreau 368362aecb2SWilly Tarreau #define EXPECT_STRNE(cond, expr, cmp) \ 369362aecb2SWilly Tarreau do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0) 370362aecb2SWilly Tarreau 371362aecb2SWilly Tarreau static int expect_strne(const char *expr, int llen, const char *cmp) 372362aecb2SWilly Tarreau { 373362aecb2SWilly Tarreau int ret = 0; 374362aecb2SWilly Tarreau 375362aecb2SWilly Tarreau llen += printf(" = <%s> ", expr); 376362aecb2SWilly Tarreau if (strcmp(expr, cmp) == 0) { 377362aecb2SWilly Tarreau ret = 1; 378362aecb2SWilly Tarreau llen += pad_spc(llen, 40, "[FAIL]\n"); 379362aecb2SWilly Tarreau } else { 380362aecb2SWilly Tarreau llen += pad_spc(llen, 40, " [OK]\n"); 381362aecb2SWilly Tarreau } 382362aecb2SWilly Tarreau return ret; 383362aecb2SWilly Tarreau } 384362aecb2SWilly Tarreau 385*23da7bc9SWilly Tarreau 386362aecb2SWilly Tarreau /* declare tests based on line numbers. There must be exactly one test per line. */ 387362aecb2SWilly Tarreau #define CASE_TEST(name) \ 388362aecb2SWilly Tarreau case __LINE__: llen += printf("%d %s", test, #name); 389362aecb2SWilly Tarreau 390362aecb2SWilly Tarreau 391*23da7bc9SWilly Tarreau /* This is the definition of known test names, with their functions */ 392*23da7bc9SWilly Tarreau static struct test test_names[] = { 393*23da7bc9SWilly Tarreau /* add new tests here */ 394*23da7bc9SWilly Tarreau { 0 } 395*23da7bc9SWilly Tarreau }; 396*23da7bc9SWilly Tarreau 397362aecb2SWilly Tarreau int main(int argc, char **argv, char **envp) 398362aecb2SWilly Tarreau { 399362aecb2SWilly Tarreau int min = 0; 400362aecb2SWilly Tarreau int max = __INT_MAX__; 401362aecb2SWilly Tarreau int ret = 0; 402*23da7bc9SWilly Tarreau int err; 403*23da7bc9SWilly Tarreau int idx; 404*23da7bc9SWilly Tarreau char *test; 405362aecb2SWilly Tarreau 406362aecb2SWilly Tarreau environ = envp; 407362aecb2SWilly Tarreau 408*23da7bc9SWilly Tarreau /* the definition of a series of tests comes from either argv[1] or the 409*23da7bc9SWilly Tarreau * "NOLIBC_TEST" environment variable. It's made of a comma-delimited 410*23da7bc9SWilly Tarreau * series of test names and optional ranges: 411*23da7bc9SWilly Tarreau * syscall:5-15[:.*],stdlib:8-10 412*23da7bc9SWilly Tarreau */ 413*23da7bc9SWilly Tarreau test = argv[1]; 414*23da7bc9SWilly Tarreau if (!test) 415*23da7bc9SWilly Tarreau test = getenv("NOLIBC_TEST"); 416*23da7bc9SWilly Tarreau 417*23da7bc9SWilly Tarreau if (test) { 418*23da7bc9SWilly Tarreau char *comma, *colon, *dash, *value; 419*23da7bc9SWilly Tarreau 420*23da7bc9SWilly Tarreau do { 421*23da7bc9SWilly Tarreau comma = strchr(test, ','); 422*23da7bc9SWilly Tarreau if (comma) 423*23da7bc9SWilly Tarreau *(comma++) = '\0'; 424*23da7bc9SWilly Tarreau 425*23da7bc9SWilly Tarreau colon = strchr(test, ':'); 426*23da7bc9SWilly Tarreau if (colon) 427*23da7bc9SWilly Tarreau *(colon++) = '\0'; 428*23da7bc9SWilly Tarreau 429*23da7bc9SWilly Tarreau for (idx = 0; test_names[idx].name; idx++) { 430*23da7bc9SWilly Tarreau if (strcmp(test, test_names[idx].name) == 0) 431*23da7bc9SWilly Tarreau break; 432*23da7bc9SWilly Tarreau } 433*23da7bc9SWilly Tarreau 434*23da7bc9SWilly Tarreau if (test_names[idx].name) { 435*23da7bc9SWilly Tarreau /* The test was named, it will be called at least 436*23da7bc9SWilly Tarreau * once. We may have an optional range at <colon> 437*23da7bc9SWilly Tarreau * here, which defaults to the full range. 438*23da7bc9SWilly Tarreau */ 439*23da7bc9SWilly Tarreau do { 440*23da7bc9SWilly Tarreau min = 0; max = __INT_MAX__; 441*23da7bc9SWilly Tarreau value = colon; 442*23da7bc9SWilly Tarreau if (value && *value) { 443*23da7bc9SWilly Tarreau colon = strchr(value, ':'); 444*23da7bc9SWilly Tarreau if (colon) 445*23da7bc9SWilly Tarreau *(colon++) = '\0'; 446*23da7bc9SWilly Tarreau 447*23da7bc9SWilly Tarreau dash = strchr(value, '-'); 448*23da7bc9SWilly Tarreau if (dash) 449*23da7bc9SWilly Tarreau *(dash++) = '\0'; 450*23da7bc9SWilly Tarreau 451*23da7bc9SWilly Tarreau /* support :val: :min-max: :min-: :-max: */ 452*23da7bc9SWilly Tarreau if (*value) 453*23da7bc9SWilly Tarreau min = atoi(value); 454*23da7bc9SWilly Tarreau if (!dash) 455*23da7bc9SWilly Tarreau max = min; 456*23da7bc9SWilly Tarreau else if (*dash) 457*23da7bc9SWilly Tarreau max = atoi(dash); 458*23da7bc9SWilly Tarreau 459*23da7bc9SWilly Tarreau value = colon; 460*23da7bc9SWilly Tarreau } 461*23da7bc9SWilly Tarreau 462*23da7bc9SWilly Tarreau /* now's time to call the test */ 463*23da7bc9SWilly Tarreau printf("Running test '%s'\n", test_names[idx].name); 464*23da7bc9SWilly Tarreau err = test_names[idx].func(min, max); 465*23da7bc9SWilly Tarreau ret += err; 466*23da7bc9SWilly Tarreau printf("Errors during this test: %d\n\n", err); 467*23da7bc9SWilly Tarreau } while (colon && *colon); 468*23da7bc9SWilly Tarreau } else 469*23da7bc9SWilly Tarreau printf("Ignoring unknown test name '%s'\n", test); 470*23da7bc9SWilly Tarreau 471*23da7bc9SWilly Tarreau test = comma; 472*23da7bc9SWilly Tarreau } while (test && *test); 473*23da7bc9SWilly Tarreau } else { 474*23da7bc9SWilly Tarreau /* no test mentioned, run everything */ 475*23da7bc9SWilly Tarreau for (idx = 0; test_names[idx].name; idx++) { 476*23da7bc9SWilly Tarreau printf("Running test '%s'\n", test_names[idx].name); 477*23da7bc9SWilly Tarreau err = test_names[idx].func(min, max); 478*23da7bc9SWilly Tarreau ret += err; 479*23da7bc9SWilly Tarreau printf("Errors during this test: %d\n\n", err); 480*23da7bc9SWilly Tarreau } 481*23da7bc9SWilly Tarreau } 482*23da7bc9SWilly Tarreau 483362aecb2SWilly Tarreau printf("Total number of errors: %d\n", ret); 484362aecb2SWilly Tarreau printf("Exiting with status %d\n", !!ret); 485362aecb2SWilly Tarreau return !!ret; 486362aecb2SWilly Tarreau } 487