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
18const 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};
49const uint32 kNumStrings = sizeof(kStrings) / sizeof(kStrings[0]);
50
51BCollator *gCollator;
52
53bool gTestKeyGeneration = true;
54bool gShowKeys = false;
55
56
57int
58compareStrings(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
67void
68printArray(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
109void
110usage()
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
121int
122main(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