diff options
Diffstat (limited to 'debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch')
-rw-r--r-- | debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch | 573 |
1 files changed, 573 insertions, 0 deletions
diff --git a/debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch b/debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch new file mode 100644 index 000000000..f04c69d89 --- /dev/null +++ b/debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch @@ -0,0 +1,573 @@ +From: Michael R Sweet <msweet@msweet.org> +Date: Mon, 1 Mar 2021 07:26:58 -0500 +Subject: Update testlang to test all locales (Issue #85) + +Also refactored the locale test code into a separate function, updated the +output to be consistent with the other unit tests, and split out the macOS +language identifier tests. Still need to move the PPD tests to the testppd +program. +--- + cups/testlang.c | 442 +++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 275 insertions(+), 167 deletions(-) + +diff --git a/cups/testlang.c b/cups/testlang.c +index 613ae32..057de84 100644 +--- a/cups/testlang.c ++++ b/cups/testlang.c +@@ -5,10 +5,12 @@ + * + * ./testlang [-l locale] [-p ppd] ["String to localize"] + * +- * Copyright 2007-2017 by Apple Inc. +- * Copyright 1997-2006 by Easy Software Products. ++ * Copyright © 2021 by OpenPrinting. ++ * Copyright © 2007-2017 by Apple Inc. ++ * Copyright © 1997-2006 by Easy Software Products. + * +- * Licensed under Apache License v2.0. See the file "LICENSE" for more information. ++ * Licensed under Apache License v2.0. See the file "LICENSE" for more ++ * information. + */ + + /* +@@ -20,6 +22,7 @@ + #ifdef __APPLE__ + # include <CoreFoundation/CoreFoundation.h> + #endif /* __APPLE__ */ ++#include <cups/dir.h> + + + /* +@@ -27,6 +30,10 @@ + */ + + static int show_ppd(const char *filename); ++#ifdef __APPLE__ ++static int test_apple(void); ++#endif // __APPLE__ ++static int test_language(const char *locale); + static int test_string(cups_lang_t *language, const char *msgid); + static void usage(void); + +@@ -39,23 +46,12 @@ int /* O - Exit status */ + main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ + { +- int i; /* Looping var */ +- const char *opt; /* Current option */ +- int errors = 0; /* Number of errors */ +- int dotests = 1; /* Do standard tests? */ +- cups_lang_t *language = NULL;/* Message catalog */ +- cups_lang_t *language2 = NULL; +- /* Message catalog (second time) */ +- struct lconv *loc; /* Locale data */ +- char buffer[1024]; /* String buffer */ +- double number; /* Number */ +- static const char * const tests[] = /* Test strings */ +- { +- "1", +- "-1", +- "3", +- "5.125" +- }; ++ int i; /* Looping var */ ++ const char *opt; /* Current option */ ++ int errors = 0; /* Number of errors */ ++ int dotests = 1; /* Do standard tests? */ ++ const char *lang; /* Single language test? */ ++ cups_lang_t *language = NULL; /* Message catalog */ + + + /* +@@ -86,11 +82,7 @@ main(int argc, /* I - Number of command-line arguments */ + return (1); + } + +- language = cupsLangGet(argv[i]); +- language2 = cupsLangGet(argv[i]); +- +- setenv("LANG", argv[i], 1); +- setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1); ++ lang = argv[i]; + break; + + case 'p' : +@@ -101,12 +93,6 @@ main(int argc, /* I - Number of command-line arguments */ + return (1); + } + +- if (!language) +- { +- language = cupsLangDefault(); +- language2 = cupsLangDefault(); +- } +- + dotests = 0; + errors += show_ppd(argv[i]); + break; +@@ -121,165 +107,62 @@ main(int argc, /* I - Number of command-line arguments */ + else + { + if (!language) +- { +- language = cupsLangDefault(); +- language2 = cupsLangDefault(); +- } ++ language = cupsLangGet(lang); + + dotests = 0; + errors += test_string(language, argv[i]); + } + } + +- if (!language) +- { +- language = cupsLangDefault(); +- language2 = cupsLangDefault(); +- } +- +- if (language != language2) +- { +- errors ++; +- +- puts("**** ERROR: Language cache did not work! ****"); +- puts("First result from cupsLangGet:"); +- } +- +- printf("Language = \"%s\"\n", language->language); +- printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding)); +- + if (dotests) + { +- errors += test_string(language, "No"); +- errors += test_string(language, "Yes"); +- +- if (language != language2) ++ if (lang) + { +- puts("Second result from cupsLangGet:"); ++ /* ++ * Test a single language... ++ */ + +- printf("Language = \"%s\"\n", language2->language); +- printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); +- printf("No = \"%s\"\n", _cupsLangString(language2, "No")); +- printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); ++ errors += test_language(lang); + } +- +- loc = localeconv(); +- +- for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) +- { +- number = _cupsStrScand(tests[i], NULL, loc); +- +- printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); +- +- _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); +- +- printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); +- +- if (strcmp(buffer, tests[i])) +- { +- errors ++; +- puts("**** ERROR: Bad formatted number! ****"); +- } +- } +- +-#ifdef __APPLE__ +- /* +- * Test all possible language IDs for compatibility with _cupsAppleLocale... +- */ +- +- CFIndex j, /* Looping var */ +- num_locales; /* Number of locales */ +- CFArrayRef locales; /* Locales */ +- CFStringRef locale_id, /* Current locale ID */ +- language_id; /* Current language ID */ +- char locale_str[256], /* Locale ID C string */ +- language_str[256], /* Language ID C string */ +- *bufptr; /* Pointer to ".UTF-8" in POSIX locale */ +- size_t buflen; /* Length of POSIX locale */ +-# if TEST_COUNTRY_CODES +- CFIndex k, /* Looping var */ +- num_country_codes; /* Number of country codes */ +- CFArrayRef country_codes; /* Country codes */ +- CFStringRef country_code, /* Current country code */ +- temp_id; /* Temporary language ID */ +- char country_str[256]; /* Country code C string */ +-# endif /* TEST_COUNTRY_CODES */ +- +- locales = CFLocaleCopyAvailableLocaleIdentifiers(); +- num_locales = CFArrayGetCount(locales); +- +-# if TEST_COUNTRY_CODES +- country_codes = CFLocaleCopyISOCountryCodes(); +- num_country_codes = CFArrayGetCount(country_codes); +-# endif /* TEST_COUNTRY_CODES */ +- +- printf("%d locales are available:\n", (int)num_locales); +- +- for (j = 0; j < num_locales; j ++) ++ else + { +- locale_id = CFArrayGetValueAtIndex(locales, j); +- language_id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, locale_id); ++ /* ++ * Test all locales we find in LOCALEDIR... ++ */ + +- if (!locale_id || !CFStringGetCString(locale_id, locale_str, (CFIndex)sizeof(locale_str), kCFStringEncodingASCII)) +- { +- printf("%d: FAIL (unable to get locale ID string)\n", (int)j + 1); +- errors ++; +- continue; +- } ++ cups_dir_t *dir; /* Locale directory */ ++ cups_dentry_t *dent; /* Directory entry */ + +- if (!language_id || !CFStringGetCString(language_id, language_str, (CFIndex)sizeof(language_str), kCFStringEncodingASCII)) ++ if ((dir = cupsDirOpen(getenv("LOCALEDIR"))) != NULL) + { +- printf("%d %s: FAIL (unable to get language ID string)\n", (int)j + 1, locale_str); +- errors ++; +- continue; ++ while ((dent = cupsDirRead(dir)) != NULL) ++ errors += test_language(dent->filename); + } +- +- if (!_cupsAppleLocale(language_id, buffer, sizeof(buffer))) +- { +- printf("%d %s(%s): FAIL (unable to convert language ID string to POSIX locale)\n", (int)j + 1, locale_str, language_str); +- errors ++; +- continue; +- } +- +- if ((bufptr = strstr(buffer, ".UTF-8")) != NULL) +- buflen = (size_t)(bufptr - buffer); + else +- buflen = strlen(buffer); +- +- if ((language = cupsLangGet(buffer)) == NULL) +- { +- printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); +- errors ++; +- continue; +- } +- +- if (strncasecmp(language->language, buffer, buflen)) + { +- printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\", got \"%s\")\n", (int)j + 1, locale_str, language_str, buffer, language->language); +- errors ++; +- continue; ++ // No LOCALEDIR, just use the default language... ++ errors += test_language(NULL); + } + +- printf("%d %s(%s): PASS (POSIX locale is \"%s\")\n", (int)j + 1, locale_str, language_str, buffer); ++ cupsDirClose(dir); + } + +- CFRelease(locales); ++#ifdef __APPLE__ ++ errors += test_apple(); ++#endif // __APPLE__ + +-# if TEST_COUNTRY_CODES +- CFRelease(country_codes); +-# endif /* TEST_COUNTRY_CODES */ +-#endif /* __APPLE__ */ ++ if (!errors) ++ puts("ALL TESTS PASSED"); + } + +- if (errors == 0 && dotests) +- puts("ALL TESTS PASSED"); +- + return (errors > 0); + } + + + /* + * 'show_ppd()' - Show localized strings in a PPD file. ++ * ++ * TODO: Move this to the testppd program. + */ + + static int /* O - Number of errors */ +@@ -327,15 +210,237 @@ show_ppd(const char *filename) /* I - Filename */ + } + + ++#ifdef __APPLE__ ++/* ++ * 'test_apple()' - Test macOS locale handing... ++ */ ++ ++static int /* O - Number of errors */ ++test_apple(void) ++{ ++ int errors = 0; /* Number of errors */ ++ CFIndex i, /* Looping var */ ++ num_locales; /* Number of locales */ ++ CFArrayRef locales; /* Locales */ ++ CFStringRef locale_id, /* Current locale ID */ ++ language_id; /* Current language ID */ ++ cups_lang_t *language = NULL; /* Message catalog */ ++ char locale_str[256], /* Locale ID C string */ ++ language_str[256], /* Language ID C string */ ++ buffer[1024], /* String buffer */ ++ *bufptr; /* Pointer to ".UTF-8" in POSIX locale */ ++ size_t buflen; /* Length of POSIX locale */ ++ ++ ++ /* ++ * Test all possible language IDs for compatibility with _cupsAppleLocale... ++ */ ++ ++ locales = CFLocaleCopyAvailableLocaleIdentifiers(); ++ num_locales = CFArrayGetCount(locales); ++ ++ printf("CFLocaleCopyAvailableLocaleIdentifiers: %d locales\n", (int)num_locales); ++ ++ for (i = 0; i < num_locales; i ++) ++ { ++ locale_id = CFArrayGetValueAtIndex(locales, i); ++ language_id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, locale_id); ++ ++ printf("CFStringGetCString(locale_id %d): ", (int)i); ++ if (!locale_id || !CFStringGetCString(locale_id, locale_str, (CFIndex)sizeof(locale_str), kCFStringEncodingASCII)) ++ { ++ puts("FAIL"); ++ errors ++; ++ continue; ++ } ++ else ++ printf("PASS (\"%s\")\n", locale_str); ++ ++ printf("CFStringGetCString(language_id %d): ", (int)i); ++ if (!language_id || !CFStringGetCString(language_id, language_str, (CFIndex)sizeof(language_str), kCFStringEncodingASCII)) ++ { ++ printf("%d %s: FAIL (unable to get language ID string)\n", (int)i + 1, locale_str); ++ errors ++; ++ continue; ++ } ++ else ++ printf("PASS (\"%s\")\n", language_str); ++ ++ printf("_cupsAppleLocale(\"%s\"): ", language_str); ++ if (!_cupsAppleLocale(language_id, buffer, sizeof(buffer))) ++ { ++ puts("FAIL"); ++ errors ++; ++ continue; ++ } ++ else ++ printf("PASS (\"%s\")\n", buffer); ++ ++ if ((bufptr = strstr(buffer, ".UTF-8")) != NULL) ++ buflen = (size_t)(bufptr - buffer); ++ else ++ buflen = strlen(buffer); ++ ++ printf("cupsLangGet(\"%s\"): ", buffer); ++ if ((language = cupsLangGet(buffer)) == NULL) ++ { ++ puts("FAIL"); ++ errors ++; ++ continue; ++ } ++ else if (strncasecmp(language->language, buffer, buflen)) ++ { ++ printf("FAIL (got \"%s\")\n", language->language); ++ errors ++; ++ continue; ++ } ++ else ++ puts("PASS"); ++ } ++ ++ CFRelease(locales); ++ ++ return (errors); ++} ++#endif // __APPLE__ ++ ++ ++/* ++ * 'test_language()' - Test a specific language... ++ */ ++ ++static int /* O - Number of errors */ ++test_language(const char *lang) /* I - Locale language code, NULL for default */ ++{ ++ int i; /* Looping var */ ++ int errors = 0; /* Number of errors */ ++ cups_lang_t *language = NULL, /* Message catalog */ ++ *language2 = NULL; /* Message catalog (second time) */ ++ struct lconv *loc; /* Locale data */ ++ char buffer[1024]; /* String buffer */ ++ double number; /* Number */ ++ static const char * const tests[] = /* Test strings */ ++ { ++ "1", ++ "-1", ++ "3", ++ "5.125" ++ }; ++ ++ ++ // Override the locale environment as needed... ++ if (lang) ++ { ++ // Test the specified locale code... ++ setenv("LANG", lang, 1); ++ setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1); ++ ++ printf("cupsLangGet(\"%s\"): ", lang); ++ if ((language = cupsLangGet(lang)) == NULL) ++ { ++ puts("FAIL"); ++ errors ++; ++ } ++ else if (strcasecmp(language->language, lang)) ++ { ++ printf("FAIL (got \"%s\")\n", language->language); ++ errors ++; ++ } ++ else ++ puts("PASS"); ++ ++ printf("cupsLangGet(\"%s\") again: ", lang); ++ if ((language2 = cupsLangGet(lang)) == NULL) ++ { ++ puts("FAIL"); ++ errors ++; ++ } ++ else if (strcasecmp(language2->language, lang)) ++ { ++ printf("FAIL (got \"%s\")\n", language2->language); ++ errors ++; ++ } ++ else if (language2 != language) ++ { ++ puts("FAIL (cache failure)"); ++ errors ++; ++ } ++ else ++ puts("PASS"); ++ } ++ else ++ { ++ // Test the default locale... ++ fputs("cupsLangDefault: ", stdout); ++ if ((language = cupsLangDefault()) == NULL) ++ { ++ puts("FAIL"); ++ errors ++; ++ } ++ else ++ puts("PASS"); ++ ++ fputs("cupsLangDefault again: ", stdout); ++ if ((language2 = cupsLangDefault()) == NULL) ++ { ++ puts("FAIL"); ++ errors ++; ++ } ++ else if (language2 != language) ++ { ++ puts("FAIL (cache failure)"); ++ errors ++; ++ } ++ else ++ puts("PASS"); ++ } ++ ++ printf("language->language: \"%s\"\n", language->language); ++ printf("_cupsEncodingName(language): \"%s\"\n", _cupsEncodingName(language->encoding)); ++ ++ errors += test_string(language, "No"); ++ errors += test_string(language, "Yes"); ++ ++ if (language != language2) ++ { ++ printf("language2->language: \"%s\"\n", language2->language); ++ printf("_cupsEncodingName(language2): \"%s\"\n", _cupsEncodingName(language2->encoding)); ++ } ++ ++ loc = localeconv(); ++ ++ for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) ++ { ++ number = _cupsStrScand(tests[i], NULL, loc); ++ ++ printf("_cupsStrScand(\"%s\"): %f\n", tests[i], number); ++ ++ _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); ++ ++ printf("_cupsStrFormatd(%f): ", number); ++ ++ if (strcmp(buffer, tests[i])) ++ { ++ errors ++; ++ printf("FAIL (got \"%s\")\n", buffer); ++ } ++ else ++ puts("PASS"); ++ } ++ ++ return (errors); ++} ++ ++ + /* + * 'test_string()' - Test the localization of a string. + */ + +-static int /* O - 1 on failure, 0 on success */ +-test_string(cups_lang_t *language, /* I - Language */ +- const char *msgid) /* I - Message */ ++static int /* O - 1 on failure, 0 on success */ ++test_string(cups_lang_t *language, /* I - Language */ ++ const char *msgid) /* I - Message */ + { +- const char *msgstr; /* Localized string */ ++ const char *msgstr; /* Localized string */ + + + /* +@@ -345,19 +450,20 @@ test_string(cups_lang_t *language, /* I - Language */ + * For any other locale, the string pointers should be different. + */ + ++ printf("_cupsLangString(\"%s\"): ", msgid); + msgstr = _cupsLangString(language, msgid); + if (strcmp(language->language, "C") && msgid == msgstr) + { +- printf("%-8s = \"%s\" (FAIL - no message catalog loaded)\n", msgid, msgstr); ++ puts("FAIL (no message catalog loaded)"); + return (1); + } + else if (!strcmp(language->language, "C") && msgid != msgstr) + { +- printf("%-8s = \"%s\" (FAIL - POSIX locale is localized)\n", msgid, msgstr); ++ puts("FAIL (POSIX locale is localized)"); + return (1); + } + +- printf("%-8s = \"%s\" (PASS)\n", msgid, msgstr); ++ printf("PASS (\"%s\")\n", msgstr); + + return (0); + } +@@ -370,5 +476,7 @@ test_string(cups_lang_t *language, /* I - Language */ + static void + usage(void) + { +- puts("./testlang [-l locale] [-p ppd] [\"String to localize\"]"); ++ puts("Usage: ./testlang [-l locale] [-p ppd] [\"String to localize\"]"); ++ puts(""); ++ puts("If no arguments are specified, all locales are tested."); + } |