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