1 /* 2 * Localization test program for CUPS. 3 * 4 * Copyright 2007-2017 by Apple Inc. 5 * Copyright 1997-2006 by Easy Software Products. 6 * 7 * These coded instructions, statements, and computer programs are the 8 * property of Apple Inc. and are protected by Federal copyright 9 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 10 * which should have been included with this file. If this file is 11 * missing or damaged, see the license at "http://www.cups.org/". 12 * 13 * This file is subject to the Apple OS-Developed Software exception. 14 */ 15 16 /* 17 * Include necessary headers... 18 */ 19 20 #include "cups-private.h" 21 #include "ppd-private.h" 22 #ifdef __APPLE__ 23 # include <CoreFoundation/CoreFoundation.h> 24 #endif /* __APPLE__ */ 25 26 27 /* 28 * Local functions... 29 */ 30 31 static int test_string(cups_lang_t *language, const char *msgid); 32 33 34 /* 35 * 'main()' - Load the specified language and show the strings for yes and no. 36 */ 37 38 int /* O - Exit status */ 39 main(int argc, /* I - Number of command-line arguments */ 40 char *argv[]) /* I - Command-line arguments */ 41 { 42 int i; /* Looping var */ 43 int errors = 0; /* Number of errors */ 44 cups_lang_t *language; /* Message catalog */ 45 cups_lang_t *language2; /* Message catalog */ 46 struct lconv *loc; /* Locale data */ 47 char buffer[1024]; /* String buffer */ 48 double number; /* Number */ 49 static const char * const tests[] = /* Test strings */ 50 { 51 "1", 52 "-1", 53 "3", 54 "5.125" 55 }; 56 57 58 if (argc == 1) 59 { 60 language = cupsLangDefault(); 61 language2 = cupsLangDefault(); 62 } 63 else 64 { 65 language = cupsLangGet(argv[1]); 66 language2 = cupsLangGet(argv[1]); 67 68 setenv("LANG", argv[1], 1); 69 setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1); 70 } 71 72 _cupsSetLocale(argv); 73 74 if (language != language2) 75 { 76 errors ++; 77 78 puts("**** ERROR: Language cache did not work! ****"); 79 puts("First result from cupsLangGet:"); 80 } 81 82 printf("Language = \"%s\"\n", language->language); 83 printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding)); 84 85 errors += test_string(language, "No"); 86 errors += test_string(language, "Yes"); 87 88 if (language != language2) 89 { 90 puts("Second result from cupsLangGet:"); 91 92 printf("Language = \"%s\"\n", language2->language); 93 printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); 94 printf("No = \"%s\"\n", _cupsLangString(language2, "No")); 95 printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); 96 } 97 98 loc = localeconv(); 99 100 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) 101 { 102 number = _cupsStrScand(tests[i], NULL, loc); 103 104 printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); 105 106 _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); 107 108 printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); 109 110 if (strcmp(buffer, tests[i])) 111 { 112 errors ++; 113 puts("**** ERROR: Bad formatted number! ****"); 114 } 115 } 116 117 if (argc == 3) 118 { 119 ppd_file_t *ppd; /* PPD file */ 120 ppd_option_t *option; /* PageSize option */ 121 ppd_choice_t *choice; /* PageSize/Letter choice */ 122 123 if ((ppd = ppdOpenFile(argv[2])) == NULL) 124 { 125 printf("Unable to open PPD file \"%s\".\n", argv[2]); 126 errors ++; 127 } 128 else 129 { 130 ppdLocalize(ppd); 131 132 if ((option = ppdFindOption(ppd, "PageSize")) == NULL) 133 { 134 puts("No PageSize option."); 135 errors ++; 136 } 137 else 138 { 139 printf("PageSize: %s\n", option->text); 140 141 if ((choice = ppdFindChoice(option, "Letter")) == NULL) 142 { 143 puts("No Letter PageSize choice."); 144 errors ++; 145 } 146 else 147 { 148 printf("Letter: %s\n", choice->text); 149 } 150 } 151 152 printf("media-empty: %s\n", ppdLocalizeIPPReason(ppd, "media-empty", NULL, buffer, sizeof(buffer))); 153 154 ppdClose(ppd); 155 } 156 } 157 #ifdef __APPLE__ 158 else 159 { 160 /* 161 * Test all possible language IDs for compatibility with _cupsAppleLocale... 162 */ 163 164 CFIndex j, /* Looping var */ 165 num_locales; /* Number of locales */ 166 CFArrayRef locales; /* Locales */ 167 CFStringRef locale_id, /* Current locale ID */ 168 language_id; /* Current language ID */ 169 char locale_str[256], /* Locale ID C string */ 170 language_str[256], /* Language ID C string */ 171 *bufptr; /* Pointer to ".UTF-8" in POSIX locale */ 172 size_t buflen; /* Length of POSIX locale */ 173 # if TEST_COUNTRY_CODES 174 CFIndex k, /* Looping var */ 175 num_country_codes; /* Number of country codes */ 176 CFArrayRef country_codes; /* Country codes */ 177 CFStringRef country_code, /* Current country code */ 178 temp_id; /* Temporary language ID */ 179 char country_str[256]; /* Country code C string */ 180 # endif /* TEST_COUNTRY_CODES */ 181 182 locales = CFLocaleCopyAvailableLocaleIdentifiers(); 183 num_locales = CFArrayGetCount(locales); 184 185 # if TEST_COUNTRY_CODES 186 country_codes = CFLocaleCopyISOCountryCodes(); 187 num_country_codes = CFArrayGetCount(country_codes); 188 # endif /* TEST_COUNTRY_CODES */ 189 190 printf("%d locales are available:\n", (int)num_locales); 191 192 for (j = 0; j < num_locales; j ++) 193 { 194 locale_id = CFArrayGetValueAtIndex(locales, j); 195 language_id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, locale_id); 196 197 if (!locale_id || !CFStringGetCString(locale_id, locale_str, (CFIndex)sizeof(locale_str), kCFStringEncodingASCII)) 198 { 199 printf("%d: FAIL (unable to get locale ID string)\n", (int)j + 1); 200 errors ++; 201 continue; 202 } 203 204 if (!language_id || !CFStringGetCString(language_id, language_str, (CFIndex)sizeof(language_str), kCFStringEncodingASCII)) 205 { 206 printf("%d %s: FAIL (unable to get language ID string)\n", (int)j + 1, locale_str); 207 errors ++; 208 continue; 209 } 210 211 if (!_cupsAppleLocale(language_id, buffer, sizeof(buffer))) 212 { 213 printf("%d %s(%s): FAIL (unable to convert language ID string to POSIX locale)\n", (int)j + 1, locale_str, language_str); 214 errors ++; 215 continue; 216 } 217 218 if ((bufptr = strstr(buffer, ".UTF-8")) != NULL) 219 buflen = (size_t)(bufptr - buffer); 220 else 221 buflen = strlen(buffer); 222 223 if ((language = cupsLangGet(buffer)) == NULL) 224 { 225 printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); 226 errors ++; 227 continue; 228 } 229 230 if (strncasecmp(language->language, buffer, buflen)) 231 { 232 printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\", got \"%s\")\n", (int)j + 1, locale_str, language_str, buffer, language->language); 233 errors ++; 234 continue; 235 } 236 237 printf("%d %s(%s): PASS (POSIX locale is \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); 238 } 239 240 CFRelease(locales); 241 242 # if TEST_COUNTRY_CODES 243 CFRelease(country_codes); 244 # endif /* TEST_COUNTRY_CODES */ 245 } 246 #endif /* __APPLE__ */ 247 248 if (errors == 0) 249 puts("ALL TESTS PASSED"); 250 251 return (errors > 0); 252 } 253 254 255 /* 256 * 'test_string()' - Test the localization of a string. 257 */ 258 259 static int /* O - 1 on failure, 0 on success */ 260 test_string(cups_lang_t *language, /* I - Language */ 261 const char *msgid) /* I - Message */ 262 { 263 const char *msgstr; /* Localized string */ 264 265 266 /* 267 * Get the localized string and then see if we got what we expected. 268 * 269 * For the POSIX locale, the string pointers should be the same. 270 * For any other locale, the string pointers should be different. 271 */ 272 273 msgstr = _cupsLangString(language, msgid); 274 if (strcmp(language->language, "C") && msgid == msgstr) 275 { 276 printf("%-8s = \"%s\" (FAIL - no message catalog loaded)\n", msgid, msgstr); 277 return (1); 278 } 279 else if (!strcmp(language->language, "C") && msgid != msgstr) 280 { 281 printf("%-8s = \"%s\" (FAIL - POSIX locale is localized)\n", msgid, msgstr); 282 return (1); 283 } 284 285 printf("%-8s = \"%s\" (PASS)\n", msgid, msgstr); 286 287 return (0); 288 } 289 290