1 /*
2  * Copyright © 2005-2020 Rich Felker
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #define _GNU_SOURCE
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 
scmp(const void * a,const void * b)28 static int scmp(const void *a, const void *b)
29 {
30 	return strcmp(*(char **)a, *(char **)b);
31 }
32 
icmp(const void * a,const void * b)33 static int icmp(const void *a, const void *b)
34 {
35 	return *(int*)a - *(int*)b;
36 }
37 
38 struct three {
39     unsigned char b[3];
40 };
41 
42 #define i3(x)                                                    \
43         { (unsigned char) ((x) >> 16), (unsigned char) ((x) >> 8),      \
44                         (unsigned char) ((x) >> 0) }
45 
tcmp(const void * av,const void * bv)46 static int tcmp(const void *av, const void *bv)
47 {
48     const struct three *a = av, *b = bv;
49     int c;
50     int i;
51 
52     for (i = 0; i < 3; i++) {
53         c = (int) a->b[i] - (int) b->b[i];
54         if (c)
55             return c;
56     }
57     return 0;
58 }
59 
60 #define FAIL(m) do {                                            \
61         printf(__FILE__ ":%d: %s failed\n", __LINE__, m);       \
62         err++;                                                  \
63     } while(0)
64 
test_qsort(void)65 int test_qsort(void)
66 {
67 	int i;
68 	int err=0;
69 	/* 26 items -- even */
70 	char *s[] = {
71 		"Bob", "Alice", "John", "Ceres",
72 		"Helga", "Drepper", "Emeralda", "Zoran",
73 		"Momo", "Frank", "Pema", "Xavier",
74 		"Yeva", "Gedun", "Irina", "Nono",
75 		"Wiener", "Vincent", "Tsering", "Karnica",
76 		"Lulu", "Quincy", "Osama", "Riley",
77 		"Ursula", "Sam"
78 	};
79 	/* 23 items -- odd, prime */
80 	int n[] = {
81 		879045, 394, 99405644, 33434, 232323, 4334, 5454,
82 		343, 45545, 454, 324, 22, 34344, 233, 45345, 343,
83 		848405, 3434, 3434344, 3535, 93994, 2230404, 4334
84 	};
85 
86         struct three t[] = {
87                 i3(879045), i3(394), i3(99405644), i3(33434), i3(232323), i3(4334), i3(5454),
88                 i3(343), i3(45545), i3(454), i3(324), i3(22), i3(34344), i3(233), i3(45345), i3(343),
89                 i3(848405), i3(3434), i3(3434344), i3(3535), i3(93994), i3(2230404), i3(4334)
90         };
91 
92 	qsort(s, sizeof(s)/sizeof(char *), sizeof(char *), scmp);
93 	for (i=0; i<(int) (sizeof(s)/sizeof(char *)-1); i++) {
94 		if (strcmp(s[i], s[i+1]) > 0) {
95 			FAIL("string sort");
96 			for (i=0; i<(int)(sizeof(s)/sizeof(char *)); i++)
97 				printf("\t%s\n", s[i]);
98 			break;
99 		}
100 	}
101 
102 	qsort(n, sizeof(n)/sizeof(int), sizeof(int), icmp);
103 	for (i=0; i<(int)(sizeof(n)/sizeof(int)-1); i++) {
104 		if (n[i] > n[i+1]) {
105 			FAIL("integer sort");
106 			for (i=0; i<(int)(sizeof(n)/sizeof(int)); i++)
107 				printf("\t%d\n", n[i]);
108 			break;
109 		}
110 	}
111 
112         qsort(t, sizeof(t)/sizeof(t[0]), sizeof(t[0]), tcmp);
113 	for (i=0; i<(int)(sizeof(t)/sizeof(t[0])-1); i++) {
114                 if (tcmp(&t[i], &t[i+1]) > 0) {
115 			FAIL("three byte sort");
116 			for (i=0; i<(int)(sizeof(t)/sizeof(t[0])); i++)
117                                 printf("\t0x%02x%02x%02x\n", t[i].b[0], t[i].b[1], t[i].b[2]);
118 			break;
119 		}
120 	}
121 
122 
123 	return err;
124 }
125 
126 #undef qsort
127 #define TEST_NAME qsort
128 #include "testcase.h"
129