summaryrefslogtreecommitdiffstats
path: root/testutil/test-search.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-12-17 13:23:51 +0100
committerMattias Andrée <maandree@kth.se>2023-12-17 13:23:51 +0100
commit2e7b4df9f7dfd6a4a6796cd2fcee010ea78427ea (patch)
treea321a6a0b4bc93cbc1b7704239a675c490383b6d /testutil/test-search.c
parentTell the user whether signals and errors are signed or unsigned (diff)
downloadlibsyscalls-2e7b4df9f7dfd6a4a6796cd2fcee010ea78427ea.tar.gz
libsyscalls-2e7b4df9f7dfd6a4a6796cd2fcee010ea78427ea.tar.bz2
libsyscalls-2e7b4df9f7dfd6a4a6796cd2fcee010ea78427ea.tar.xz
Miscellaneous improvements
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'testutil/test-search.c')
-rw-r--r--testutil/test-search.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/testutil/test-search.c b/testutil/test-search.c
new file mode 100644
index 0000000..93d6d03
--- /dev/null
+++ b/testutil/test-search.c
@@ -0,0 +1,114 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
+
+static struct libsyscalls_named_number not_found;
+static size_t not_found_count = 0;
+static char **argv;
+
+static void
+check(unsigned long long int key, const struct libsyscalls_named_number *base, size_t n, int is_signed)
+{
+ static int first = 1;
+
+ const struct libsyscalls_named_number *found;
+ found = libsyscalls_find_named_number(key, is_signed, base, n);
+ if (found) {
+ if (first)
+ not_found.number.u = key + 1;
+ if (found->number.u != key) {
+ fprintf(stderr, "test-search %s %s %s: found incorrect element: %llu instead of %llu\n",
+ argv[1], argv[4], argv[5], found->number.u, key);
+ exit(1);
+ }
+ } else {
+ if (first) {
+ fprintf(stderr, "test-search %s %s %s: did not find first element\n", argv[1], argv[4], argv[5]);
+ exit(1);
+ }
+ not_found.number.u = key;
+ not_found_count += 1;
+ }
+
+ first = 0;
+}
+
+
+int
+main(int argc, char **argv_)
+{
+ int os, arch, search_singals, is_signed;
+ enum libsyscalls_error err;
+ const struct libsyscalls_named_number *base, *min, *max;
+ unsigned long long int ukey;
+ signed long long int skey;
+ size_t n, expected_not_found_count;
+
+ argv = argv_;
+
+ if (argc != 6) {
+ usage:
+ fprintf(stderr, "usage error\n");
+ return 1;
+ }
+
+ if (!strcmp(argv[1], "signals"))
+ search_singals = 1;
+ else if (!strcmp(argv[1], "errors"))
+ search_singals = 0;
+ else
+ goto usage;
+ os = atoi(argv[2]);
+ arch = atoi(argv[3]);
+
+ if (search_singals)
+ err = libsyscalls_get_signals((enum libsyscalls_os)os, (enum libsyscalls_arch)arch, &base, &n, &is_signed);
+ else
+ err = libsyscalls_get_syscall_errors((enum libsyscalls_os)os, (enum libsyscalls_arch)arch, &base, &n, &is_signed);
+ if (err) {
+ fprintf(stderr, "test-search %s %s %s: ", argv[1], argv[4], argv[5]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ if (!n)
+ return 0;
+
+ min = &base[0];
+ max = &base[n - 1];
+
+ if (is_signed) {
+ skey = min->number.s;
+ do {
+ check(*(unsigned long long int *)&skey, base, n, is_signed);
+ } while (skey++ != max->number.s);
+ expected_not_found_count = (size_t)((unsigned long long int)max->number.s -
+ (unsigned long long int)min->number.s -
+ (unsigned long long int)n + 1);
+ } else {
+ ukey = min->number.u;
+ do {
+ check(ukey, base, n, is_signed);
+ } while (ukey++ != max->number.u);
+ expected_not_found_count = (size_t)(max->number.u - min->number.u - (unsigned long long int)n + 1);
+ }
+
+ if (not_found.number.u == max->number.u) {
+ fprintf(stderr, "test-search %s %s %s: did not find last element\n", argv[1], argv[4], argv[5]);
+ return 1;
+ }
+ if (not_found_count != expected_not_found_count) {
+ fprintf(stderr, "test-search %s %s %s: did not find all elements\n", argv[1], argv[4], argv[5]);
+ return 1;
+ }
+
+ return 0;
+}