--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+
+/* platform-specific include files coming from the compiler */
+#include <limits.h>
+
+/* libc-specific include files
+ * The program may be built in 2 ways:
+ * $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined
+ * $(CC) -nostdlib -I/path/to/nolibc/sysroot
+ */
+#ifndef NOLIBC
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+/* will be used by nolibc by getenv() */
+char **environ;
+
+#define CASE_ERR(err) \
+ case err: return #err
+
+/* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0,
+ * or the decimal value for less common ones.
+ */
+const char *errorname(int err)
+{
+ switch (err) {
+ case 0: return "SUCCESS";
+ CASE_ERR(EPERM);
+ CASE_ERR(ENOENT);
+ CASE_ERR(ESRCH);
+ CASE_ERR(EINTR);
+ CASE_ERR(EIO);
+ CASE_ERR(ENXIO);
+ CASE_ERR(E2BIG);
+ CASE_ERR(ENOEXEC);
+ CASE_ERR(EBADF);
+ CASE_ERR(ECHILD);
+ CASE_ERR(EAGAIN);
+ CASE_ERR(ENOMEM);
+ CASE_ERR(EACCES);
+ CASE_ERR(EFAULT);
+ CASE_ERR(ENOTBLK);
+ CASE_ERR(EBUSY);
+ CASE_ERR(EEXIST);
+ CASE_ERR(EXDEV);
+ CASE_ERR(ENODEV);
+ CASE_ERR(ENOTDIR);
+ CASE_ERR(EISDIR);
+ CASE_ERR(EINVAL);
+ CASE_ERR(ENFILE);
+ CASE_ERR(EMFILE);
+ CASE_ERR(ENOTTY);
+ CASE_ERR(ETXTBSY);
+ CASE_ERR(EFBIG);
+ CASE_ERR(ENOSPC);
+ CASE_ERR(ESPIPE);
+ CASE_ERR(EROFS);
+ CASE_ERR(EMLINK);
+ CASE_ERR(EPIPE);
+ CASE_ERR(EDOM);
+ CASE_ERR(ERANGE);
+ CASE_ERR(ENOSYS);
+ default:
+ return itoa(err);
+ }
+}
+
+static int pad_spc(int llen, int cnt, const char *fmt, ...)
+{
+ va_list args;
+ int len;
+ int ret;
+
+ for (len = 0; len < cnt - llen; len++)
+ putchar(' ');
+
+ va_start(args, fmt);
+ ret = vfprintf(stdout, fmt, args);
+ va_end(args);
+ return ret < 0 ? ret : ret + len;
+}
+
+/* The tests below are intended to be used by the macroes, which evaluate
+ * expression <expr>, print the status to stdout, and update the "ret"
+ * variable to count failures. The functions themselves return the number
+ * of failures, thus either 0 or 1.
+ */
+
+#define EXPECT_ZR(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_zr(expr, llen); } while (0)
+
+static int expect_zr(int expr, int llen)
+{
+ int ret = !(expr == 0);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_NZ(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_nz(expr, llen; } while (0)
+
+static int expect_nz(int expr, int llen)
+{
+ int ret = !(expr != 0);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_EQ(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_eq(expr, llen, val); } while (0)
+
+static int expect_eq(int expr, int llen, int val)
+{
+ int ret = !(expr == val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_NE(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ne(expr, llen, val); } while (0)
+
+static int expect_ne(int expr, int llen, int val)
+{
+ int ret = !(expr != val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_GE(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ge(expr, llen, val); } while (0)
+
+static int expect_ge(int expr, int llen, int val)
+{
+ int ret = !(expr >= val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_GT(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_gt(expr, llen, val); } while (0)
+
+static int expect_gt(int expr, int llen, int val)
+{
+ int ret = !(expr > val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_LE(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_le(expr, llen, val); } while (0)
+
+static int expect_le(int expr, int llen, int val)
+{
+ int ret = !(expr <= val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_LT(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_lt(expr, llen, val); } while (0)
+
+static int expect_lt(int expr, int llen, int val)
+{
+ int ret = !(expr < val);
+
+ llen += printf(" = %d ", expr);
+ pad_spc(llen, 40, ret ? "[FAIL]\n" : " [OK]\n");
+ return ret;
+}
+
+
+#define EXPECT_SYSZR(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syszr(expr, llen); } while (0)
+
+static int expect_syszr(int expr, int llen)
+{
+ int ret = 0;
+
+ if (expr) {
+ ret = 1;
+ llen += printf(" = %d %s ", expr, errorname(errno));
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += printf(" = %d ", expr);
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_SYSEQ(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syseq(expr, llen, val); } while (0)
+
+static int expect_syseq(int expr, int llen, int val)
+{
+ int ret = 0;
+
+ if (expr != val) {
+ ret = 1;
+ llen += printf(" = %d %s ", expr, errorname(errno));
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += printf(" = %d ", expr);
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_SYSNE(cond, expr, val) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_sysne(expr, llen, val); } while (0)
+
+static int expect_sysne(int expr, int llen, int val)
+{
+ int ret = 0;
+
+ if (expr == val) {
+ ret = 1;
+ llen += printf(" = %d %s ", expr, errorname(errno));
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += printf(" = %d ", expr);
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_SYSER(cond, expr, expret, experr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_syserr(expr, expret, experr, llen); } while (0)
+
+static int expect_syserr(int expr, int expret, int experr, int llen)
+{
+ int ret = 0;
+ int _errno = errno;
+
+ llen += printf(" = %d %s ", expr, errorname(_errno));
+ if (expr != expret || _errno != experr) {
+ ret = 1;
+ llen += printf(" != (%d %s) ", expret, errorname(experr));
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_PTRZR(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrzr(expr, llen); } while (0)
+
+static int expect_ptrzr(const void *expr, int llen)
+{
+ int ret = 0;
+
+ llen += printf(" = <%p> ", expr);
+ if (expr) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_PTRNZ(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_ptrnz(expr, llen); } while (0)
+
+static int expect_ptrnz(const void *expr, int llen)
+{
+ int ret = 0;
+
+ llen += printf(" = <%p> ", expr);
+ if (!expr) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_STRZR(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
+
+static int expect_strzr(const char *expr, int llen)
+{
+ int ret = 0;
+
+ llen += printf(" = <%s> ", expr);
+ if (expr) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_STRNZ(cond, expr) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strnz(expr, llen); } while (0)
+
+static int expect_strnz(const char *expr, int llen)
+{
+ int ret = 0;
+
+ llen += printf(" = <%s> ", expr);
+ if (!expr) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_STREQ(cond, expr, cmp) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_streq(expr, llen, cmp); } while (0)
+
+static int expect_streq(const char *expr, int llen, const char *cmp)
+{
+ int ret = 0;
+
+ llen += printf(" = <%s> ", expr);
+ if (strcmp(expr, cmp) != 0) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+
+#define EXPECT_STRNE(cond, expr, cmp) \
+ do { if (!cond) pad_spc(llen, 40, "[SKIPPED]\n"); else ret += expect_strne(expr, llen, cmp); } while (0)
+
+static int expect_strne(const char *expr, int llen, const char *cmp)
+{
+ int ret = 0;
+
+ llen += printf(" = <%s> ", expr);
+ if (strcmp(expr, cmp) == 0) {
+ ret = 1;
+ llen += pad_spc(llen, 40, "[FAIL]\n");
+ } else {
+ llen += pad_spc(llen, 40, " [OK]\n");
+ }
+ return ret;
+}
+
+/* declare tests based on line numbers. There must be exactly one test per line. */
+#define CASE_TEST(name) \
+ case __LINE__: llen += printf("%d %s", test, #name);
+
+
+int main(int argc, char **argv, char **envp)
+{
+ int min = 0;
+ int max = __INT_MAX__;
+ int ret = 0;
+
+ environ = envp;
+
+ printf("Total number of errors: %d\n", ret);
+ printf("Exiting with status %d\n", !!ret);
+ return !!ret;
+}