1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include <ctype.h>
22: #include <error.h>
23: #include <locale.h>
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <string.h>
27:
28:
29: struct lines
30: {
31: char *key;
32: char *line;
33: };
34:
35: static int xstrcoll (const void *, const void *);
36:
37: int
38: main (int argc, char *argv[])
39: {
40: int result = 0;
41: size_t nstrings, nstrings_max;
42: struct lines *strings;
43: char *line = NULL;
44: size_t len = 0;
45: size_t n;
46:
47: if (argc < 2)
48: error (1, 0, "usage: %s <random seed>", argv[0]);
49:
50: setlocale (LC_ALL, "");
51:
52: nstrings_max = 100;
53: nstrings = 0;
54: strings = (struct lines *) malloc (nstrings_max * sizeof (struct lines));
55: if (strings == NULL)
56: {
57: perror (argv[0]);
58: exit (1);
59: }
60:
61: while (1)
62: {
63: int l;
64: if (getline (&line, &len, stdin) < 0)
65: break;
66:
67: if (nstrings == nstrings_max)
68: {
69: strings = (struct lines *) realloc (strings,
70: (nstrings_max *= 2)
71: * sizeof (*strings));
72: if (strings == NULL)
73: {
74: perror (argv[0]);
75: exit (1);
76: }
77: }
78: strings[nstrings].line = strdup (line);
79: l = strcspn (line, ":(;");
80: while (l > 0 && isspace (line[l - 1]))
81: --l;
82: strings[nstrings].key = strndup (line, l);
83: ++nstrings;
84: }
85: free (line);
86:
87:
88: srandom (atoi (argv[1]));
89: for (n = 0; n < 10 * nstrings; ++n)
90: {
91: int r1, r2, r;
92: size_t idx1 = random () % nstrings;
93: size_t idx2 = random () % nstrings;
94: struct lines tmp = strings[idx1];
95: strings[idx1] = strings[idx2];
96: strings[idx2] = tmp;
97:
98:
99: r1 = strcoll (strings[idx1].key, strings[idx2].key);
100: r2 = strcoll (strings[idx2].key, strings[idx1].key);
101: r = r1 * r2;
102:
103: if (r > 0 || (r == 0 && r1 != 0) || (r == 0 && r2 != 0))
104: printf ("`%s' and `%s' collate wrong: %d vs. %d\n",
105: strings[idx1].key, strings[idx2].key, r1, r2);
106: }
107:
108:
109: qsort (strings, nstrings, sizeof (struct lines), xstrcoll);
110:
111:
112: for (n = 0; n < nstrings; ++n)
113: {
114: fputs (strings[n].line, stdout);
115: free (strings[n].line);
116: free (strings[n].key);
117: }
118: free (strings);
119:
120: return result;
121: }
122:
123:
124: static int
125: xstrcoll (ptr1, ptr2)
126: const void *ptr1;
127: const void *ptr2;
128: {
129: const struct lines *l1 = (const struct lines *) ptr1;
130: const struct lines *l2 = (const struct lines *) ptr2;
131:
132: return strcoll (l1->key, l2->key);
133: }