summaryrefslogtreecommitdiff
path: root/debian/patches/0001-Update-testlang-to-test-all-locales-Issue-85.patch
diff options
context:
space:
mode:
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.patch573
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.");
+ }