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 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 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 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 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