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