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