1 /*
2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
5
6
7 #include <Collator.h>
8 #include <Locale.h>
9 #include <LocaleRoster.h>
10 #include <Message.h>
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <ctype.h>
16
17
18 const char *kStrings[] = {
19 "a-b-c",
20 "a b c",
21 "A.b.c",
22 "ä,b,c",
23 "abc",
24 "gehen",
25 "géhen",
26 "aus",
27 "äUß",
28 "auss",
29 "WO",
30 "wÖ",
31 "SO",
32 "so",
33 "açñ",
34 "acn",
35 "pêche",
36 "pêché",
37 "peché",
38 "peche",
39 "PECHE",
40 "PÊCHE",
41 "pecher",
42 "eñe",
43 "ene",
44 "nz",
45 "ña",
46 "llamar",
47 "luz",
48 };
49 const uint32 kNumStrings = sizeof(kStrings) / sizeof(kStrings[0]);
50
51 BCollator *gCollator;
52
53 bool gTestKeyGeneration = true;
54 bool gShowKeys = false;
55
56
57 int
compareStrings(const void * _a,const void * _b)58 compareStrings(const void *_a, const void *_b)
59 {
60 const char *a = *(const char **)_a;
61 const char *b = *(const char **)_b;
62
63 return gCollator->Compare(a, b);
64 }
65
66
67 void
printArray(const char * label,const char ** strings,size_t size)68 printArray(const char *label, const char **strings, size_t size)
69 {
70 puts(label);
71
72 uint32 bucket = 1;
73 for (uint32 i = 0; i < size; i++) {
74 if (i > 0) {
75 int compare = gCollator->Compare(strings[i], strings[i - 1]);
76 if (compare > 0)
77 printf("\n%2lu)", bucket++);
78 else if (compare < 0) {
79 printf("\t*** broken sort order, next is NOT %s\n", strings[i]);
80 exit(-1);
81 }
82
83 // Test sort key generation
84
85 if (gTestKeyGeneration) {
86 BString a, b;
87 gCollator->GetSortKey(strings[i - 1], &a);
88 gCollator->GetSortKey(strings[i], &b);
89
90 int keyCompare = strcmp(a.String(), b.String());
91 if (keyCompare > 0 || (keyCompare == 0 && compare != 0))
92 printf(" (*** \"%s\" wrong keys \"%s\" ***) ", a.String(), b.String());
93 }
94 } else
95 printf("%2lu)", bucket++);
96
97 printf("\t%s", strings[i]);
98
99 if (gShowKeys) {
100 BString key;
101 gCollator->GetSortKey(strings[i], &key);
102 printf(" (%s)", key.String());
103 }
104 }
105 putchar('\n');
106 }
107
108
109 void
usage()110 usage()
111 {
112 fprintf(stderr,
113 "usage: collatorTest [-ick] [<add-on path>]\n"
114 " -i\tignore punctuation (defaults to: punctuation matters)\n"
115 " -c\tcomparison only, no sort key test\n"
116 " -k\tshows the sort keys along the strings (sort keys doesn't have to be visually correct)\n");
117 exit(-1);
118 }
119
120
121 int
main(int argc,char ** argv)122 main(int argc, char **argv)
123 {
124 // Parse command line arguments
125
126 int strength = B_COLLATE_SECONDARY;
127 bool ignorePunctuation = false;
128 char *addon = NULL;
129
130 BCollator defaultCollator;
131 BLocaleRoster::Default()->GetDefaultLocale()->GetCollator(&defaultCollator);
132
133 while ((++argv)[0]) {
134 if (argv[0][0] == '-' && argv[0][1] != '-') {
135 char *arg = argv[0] + 1;
136 char c;
137 while ((c = *arg++)) {
138 if (c == 'i')
139 ignorePunctuation = true;
140 else if (c == 'c')
141 gTestKeyGeneration = false;
142 else if (c == 'k')
143 gShowKeys = true;
144 else if (isdigit(c)) {
145 int strength = c - '0';
146 if (strength < B_COLLATE_PRIMARY)
147 strength = B_COLLATE_PRIMARY;
148 else if (strength > B_COLLATE_IDENTICAL)
149 strength = B_COLLATE_IDENTICAL;
150 }
151 }
152 } else if (!strcmp(argv[0], "--help")) {
153 usage();
154 } else {
155 // this will be the add-on to be loaded
156 addon = argv[0];
157 }
158 }
159
160 // load the collator add-on if necessary
161
162 if (addon != NULL)
163 gCollator = new BCollator(addon, strength, true);
164
165 if (gCollator == NULL) {
166 printf("--------- Use standard collator! -----------\n");
167 gCollator = &defaultCollator;
168 }
169
170 printf("test archiving/unarchiving collator\n");
171
172 BMessage archive;
173 if (gCollator->Archive(&archive, true) != B_OK)
174 fprintf(stderr, "Archiving failed!\n");
175 else {
176 BArchivable *unarchived = instantiate_object(&archive);
177 gCollator = dynamic_cast<BCollator *>(unarchived);
178 if (gCollator == NULL) {
179 fprintf(stderr, "Unarchiving failed!\n");
180
181 delete unarchived;
182 gCollator = &defaultCollator;
183 }
184 }
185
186 printf(" Archived content :");
187 archive.PrintToStream();
188
189 printf("test the BCollator::Compare() and GetSortKey() methods\n");
190
191 const char *strengthLabels[] = {"primary: ", "secondary:", "tertiary: "};
192 uint32 strengths[] = {B_COLLATE_PRIMARY, B_COLLATE_SECONDARY, B_COLLATE_TERTIARY};
193
194 gCollator->SetIgnorePunctuation(ignorePunctuation);
195
196 for (uint32 i = 0; i < sizeof(strengths) / sizeof(strengths[0]); i++) {
197 gCollator->SetDefaultStrength(strengths[i]);
198 qsort(kStrings, kNumStrings, sizeof(char *), compareStrings);
199
200 printArray(strengthLabels[i], kStrings, kNumStrings);
201 }
202 }
203
204