|
|
Message-Id: <20210808112908.44345-1-galibert@pobox.com>
Date: Sun, 8 Aug 2021 13:29:09 +0200
From: Olivier Galibert <galibert@...ox.com>
To: musl@...ts.openwall.com
Cc: Olivier Galibert <galibert@...ox.com>
Subject: [PATCH] stdlib: Add test for the qsort_r extension
This allows to validate the associated musl patch.
---
src/functional/qsort_r.c | 202 +++++++++++++++++++++++++++++++++++++++
1 file changed, 202 insertions(+)
create mode 100644 src/functional/qsort_r.c
diff --git a/src/functional/qsort_r.c b/src/functional/qsort_r.c
new file mode 100644
index 0000000..97a48c2
--- /dev/null
+++ b/src/functional/qsort_r.c
@@ -0,0 +1,202 @@
+#define _GNU_SOURCE
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "test.h"
+
+void *expected_arg;
+
+static int scmp(const void *a, const void *b, void *arg)
+{
+ if (arg != expected_arg) {
+ t_error("argument passing failed\n");
+ t_printf("\tgot: %p\n", arg);
+ t_printf("\twant: %p\n", expected_arg);
+ }
+
+ return strcmp(*(char **)a, *(char **)b);
+}
+
+static int icmp(const void *a, const void *b, void *arg)
+{
+ if (arg != expected_arg) {
+ t_error("argument passing failed\n");
+ t_printf("\tgot: %p\n", arg);
+ t_printf("\twant: %p\n", expected_arg);
+ }
+
+ return *(int*)a - *(int*)b;
+}
+
+static int ccmp(const void *a, const void *b, void *arg)
+{
+ if (arg != expected_arg) {
+ t_error("argument passing failed\n");
+ t_printf("\tgot: %p\n", arg);
+ t_printf("\twant: %p\n", expected_arg);
+ }
+
+ return *(char*)a - *(char*)b;
+}
+
+static int cmp64(const void *a, const void *b, void *arg)
+{
+ if (arg != expected_arg) {
+ t_error("argument passing failed\n");
+ t_printf("\tgot: %p\n", arg);
+ t_printf("\twant: %p\n", expected_arg);
+ }
+
+ const uint64_t *ua = a, *ub = b;
+ return *ua < *ub ? -1 : *ua != *ub;
+}
+
+/* 26 items -- even */
+static const char *s[] = {
+ "Bob", "Alice", "John", "Ceres",
+ "Helga", "Drepper", "Emeralda", "Zoran",
+ "Momo", "Frank", "Pema", "Xavier",
+ "Yeva", "Gedun", "Irina", "Nono",
+ "Wiener", "Vincent", "Tsering", "Karnica",
+ "Lulu", "Quincy", "Osama", "Riley",
+ "Ursula", "Sam"
+};
+static const char *s_sorted[] = {
+ "Alice", "Bob", "Ceres", "Drepper",
+ "Emeralda", "Frank", "Gedun", "Helga",
+ "Irina", "John", "Karnica", "Lulu",
+ "Momo", "Nono", "Osama", "Pema",
+ "Quincy", "Riley", "Sam", "Tsering",
+ "Ursula", "Vincent", "Wiener", "Xavier",
+ "Yeva", "Zoran"
+};
+
+/* 23 items -- odd, prime */
+static int n[] = {
+ 879045, 394, 99405644, 33434, 232323, 4334, 5454,
+ 343, 45545, 454, 324, 22, 34344, 233, 45345, 343,
+ 848405, 3434, 3434344, 3535, 93994, 2230404, 4334
+};
+static int n_sorted[] = {
+ 22, 233, 324, 343, 343, 394, 454, 3434,
+ 3535, 4334, 4334, 5454, 33434, 34344, 45345, 45545,
+ 93994, 232323, 848405, 879045, 2230404, 3434344, 99405644
+};
+
+static void str_test(const char **a, const char **a_sorted, int len)
+{
+ int i;
+ qsort_r(a, len, sizeof *a, scmp, expected_arg);
+ for (i=0; i<len; i++) {
+ if (strcmp(a[i], a_sorted[i]) != 0) {
+ t_error("string sort failed at index %d\n", i);
+ t_printf("\ti\tgot\twant\n");
+ for (i=0; i<len; i++)
+ t_printf("\t%d\t%s\t%s\n", i, a[i], a_sorted[i]);
+ break;
+ }
+ }
+}
+
+static void int_test(int *a, int *a_sorted, int len)
+{
+ int i;
+ qsort_r(a, len, sizeof *a, icmp, expected_arg);
+ for (i=0; i<len; i++) {
+ if (a[i] != a_sorted[i]) {
+ t_error("integer sort failed at index %d\n", i);
+ t_printf("\ti\tgot\twant\n");
+ for (i=0; i<len; i++)
+ t_printf("\t%d\t%d\t%d\n", i, a[i], a_sorted[i]);
+ break;
+ }
+ }
+}
+
+static void uint64_gen(uint64_t *p, uint64_t *p_sorted, int n)
+{
+ int i;
+ uint64_t r = 0;
+ t_randseed(n);
+ for (i = 0; i < n; i++) {
+ r += t_randn(20);
+ p[i] = r;
+ }
+ memcpy(p_sorted, p, n * sizeof *p);
+ t_shuffle(p, n);
+}
+
+static void uint64_test(uint64_t *a, uint64_t *a_sorted, int len)
+{
+ int i;
+ qsort_r(a, len, sizeof *a, cmp64, expected_arg);
+ for (i=0; i<len; i++) {
+ if (a[i] != a_sorted[i]) {
+ t_error("uint64 sort failed at index %d\n", i);
+ t_printf("\ti\tgot\twant\n");
+ for (i=0; i<len; i++)
+ t_printf("\t%d\t%" PRIu64 "\t%" PRIu64 "\n", i, a[i], a_sorted[i]);
+ break;
+ }
+ }
+}
+
+#define T(a, a_sorted) do { \
+ char p[] = a; \
+ qsort_r(p, sizeof p - 1, 1, ccmp, expected_arg); \
+ if (memcmp(p, a_sorted, sizeof p) != 0) { \
+ t_error("character sort failed\n"); \
+ t_printf("\tgot: \"%s\"\n", p); \
+ t_printf("\twant: \"%s\"\n", a_sorted); \
+ } \
+} while(0)
+
+static void char_test(void)
+{
+ T("", "");
+ T("1", "1");
+ T("11", "11");
+ T("12", "12");
+ T("21", "12");
+ T("111", "111");
+ T("211", "112");
+ T("121", "112");
+ T("112", "112");
+ T("221", "122");
+ T("212", "122");
+ T("122", "122");
+ T("123", "123");
+ T("132", "123");
+ T("213", "123");
+ T("231", "123");
+ T("321", "123");
+ T("312", "123");
+ T("1423", "1234");
+ T("51342", "12345");
+ T("261435", "123456");
+ T("4517263", "1234567");
+ T("37245618", "12345678");
+ T("812436597", "123456789");
+ T("987654321", "123456789");
+ T("321321321", "111222333");
+ T("49735862185236174", "11223344556677889");
+}
+
+int main(void)
+{
+ int i;
+
+ expected_arg = &expected_arg;
+
+ str_test(s, s_sorted, sizeof s/sizeof*s);
+ int_test(n, n_sorted, sizeof n/sizeof*n);
+ char_test();
+ for (i = 1023; i<=1026; i++) {
+ uint64_t p[1026], p_sorted[1026];
+ uint64_gen(p, p_sorted, i);
+ uint64_test(p, p_sorted, i);
+ }
+ return t_status;
+}
--
2.32.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.