• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Localization test program for CUPS.
3  *
4  * Usage:
5  *
6  *   ./testlang [-l locale] [-p ppd] ["String to localize"]
7  *
8  * Copyright 2007-2017 by Apple Inc.
9  * Copyright 1997-2006 by Easy Software Products.
10  *
11  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
12  */
13 
14 /*
15  * Include necessary headers...
16  */
17 
18 #include "cups-private.h"
19 #include "ppd-private.h"
20 #ifdef __APPLE__
21 #  include <CoreFoundation/CoreFoundation.h>
22 #endif /* __APPLE__ */
23 
24 
25 /*
26  * Local functions...
27  */
28 
29 static int	show_ppd(const char *filename);
30 static int	test_string(cups_lang_t *language, const char *msgid);
31 static void	usage(void);
32 
33 
34 /*
35  * 'main()' - Load the specified language and show the strings for yes and no.
36  */
37 
38 int					/* O - Exit status */
main(int argc,char * argv[])39 main(int  argc,				/* I - Number of command-line arguments */
40      char *argv[])			/* I - Command-line arguments */
41 {
42   int			i;		/* Looping var */
43   const char		*opt;		/* Current option */
44   int			errors = 0;	/* Number of errors */
45   int			dotests = 1;	/* Do standard tests? */
46   cups_lang_t		*language = NULL;/* Message catalog */
47   cups_lang_t		*language2 = NULL;
48 					/* Message catalog (second time) */
49   struct lconv		*loc;		/* Locale data */
50   char			buffer[1024];	/* String buffer */
51   double		number;		/* Number */
52   static const char * const tests[] =	/* Test strings */
53   {
54     "1",
55     "-1",
56     "3",
57     "5.125"
58   };
59 
60 
61  /*
62   * Parse command-line...
63   */
64 
65   _cupsSetLocale(argv);
66 
67   for (i = 1; i < argc; i ++)
68   {
69     if (argv[i][0] == '-')
70     {
71       if (!strcmp(argv[i], "--help"))
72       {
73         usage();
74       }
75       else
76       {
77         for (opt = argv[i] + 1; *opt; opt ++)
78         {
79           switch (*opt)
80           {
81             case 'l' :
82                 i ++;
83                 if (i >= argc)
84                 {
85                   usage();
86                   return (1);
87                 }
88 
89 		language  = cupsLangGet(argv[i]);
90 		language2 = cupsLangGet(argv[i]);
91 
92 		setenv("LANG", argv[i], 1);
93 		setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1);
94 		break;
95 
96 	    case 'p' :
97                 i ++;
98                 if (i >= argc)
99                 {
100                   usage();
101                   return (1);
102                 }
103 
104                 if (!language)
105                 {
106 		  language  = cupsLangDefault();
107 		  language2 = cupsLangDefault();
108 		}
109 
110 		dotests = 0;
111 		errors += show_ppd(argv[i]);
112                 break;
113 
114             default :
115                 usage();
116                 return (1);
117 	  }
118         }
119       }
120     }
121     else
122     {
123       if (!language)
124       {
125 	language  = cupsLangDefault();
126 	language2 = cupsLangDefault();
127       }
128 
129       dotests = 0;
130       errors += test_string(language, argv[i]);
131     }
132   }
133 
134   if (!language)
135   {
136     language  = cupsLangDefault();
137     language2 = cupsLangDefault();
138   }
139 
140   if (language != language2)
141   {
142     errors ++;
143 
144     puts("**** ERROR: Language cache did not work! ****");
145     puts("First result from cupsLangGet:");
146   }
147 
148   printf("Language = \"%s\"\n", language->language);
149   printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding));
150 
151   if (dotests)
152   {
153     errors += test_string(language, "No");
154     errors += test_string(language, "Yes");
155 
156     if (language != language2)
157     {
158       puts("Second result from cupsLangGet:");
159 
160       printf("Language = \"%s\"\n", language2->language);
161       printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding));
162       printf("No       = \"%s\"\n", _cupsLangString(language2, "No"));
163       printf("Yes      = \"%s\"\n", _cupsLangString(language2, "Yes"));
164     }
165 
166     loc = localeconv();
167 
168     for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++)
169     {
170       number = _cupsStrScand(tests[i], NULL, loc);
171 
172       printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number);
173 
174       _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc);
175 
176       printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer);
177 
178       if (strcmp(buffer, tests[i]))
179       {
180 	errors ++;
181 	puts("**** ERROR: Bad formatted number! ****");
182       }
183     }
184 
185 #ifdef __APPLE__
186    /*
187     * Test all possible language IDs for compatibility with _cupsAppleLocale...
188     */
189 
190     CFIndex     j,                      /* Looping var */
191                 num_locales;            /* Number of locales */
192     CFArrayRef  locales;                /* Locales */
193     CFStringRef locale_id,              /* Current locale ID */
194                 language_id;            /* Current language ID */
195     char        locale_str[256],        /* Locale ID C string */
196                 language_str[256],      /* Language ID C string */
197                 *bufptr;                /* Pointer to ".UTF-8" in POSIX locale */
198     size_t      buflen;                 /* Length of POSIX locale */
199 #  if TEST_COUNTRY_CODES
200     CFIndex     k,                      /* Looping var */
201                 num_country_codes;      /* Number of country codes */
202     CFArrayRef  country_codes;          /* Country codes */
203     CFStringRef country_code,           /* Current country code */
204                 temp_id;                /* Temporary language ID */
205     char        country_str[256];       /* Country code C string */
206 #  endif /* TEST_COUNTRY_CODES */
207 
208     locales     = CFLocaleCopyAvailableLocaleIdentifiers();
209     num_locales = CFArrayGetCount(locales);
210 
211 #  if TEST_COUNTRY_CODES
212     country_codes     = CFLocaleCopyISOCountryCodes();
213     num_country_codes = CFArrayGetCount(country_codes);
214 #  endif /* TEST_COUNTRY_CODES */
215 
216     printf("%d locales are available:\n", (int)num_locales);
217 
218     for (j = 0; j < num_locales; j ++)
219     {
220       locale_id   = CFArrayGetValueAtIndex(locales, j);
221       language_id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, locale_id);
222 
223       if (!locale_id || !CFStringGetCString(locale_id, locale_str, (CFIndex)sizeof(locale_str), kCFStringEncodingASCII))
224       {
225         printf("%d: FAIL (unable to get locale ID string)\n", (int)j + 1);
226         errors ++;
227         continue;
228       }
229 
230       if (!language_id || !CFStringGetCString(language_id, language_str, (CFIndex)sizeof(language_str), kCFStringEncodingASCII))
231       {
232         printf("%d %s: FAIL (unable to get language ID string)\n", (int)j + 1, locale_str);
233         errors ++;
234         continue;
235       }
236 
237       if (!_cupsAppleLocale(language_id, buffer, sizeof(buffer)))
238       {
239         printf("%d %s(%s): FAIL (unable to convert language ID string to POSIX locale)\n", (int)j + 1, locale_str, language_str);
240         errors ++;
241         continue;
242       }
243 
244       if ((bufptr = strstr(buffer, ".UTF-8")) != NULL)
245         buflen = (size_t)(bufptr - buffer);
246       else
247         buflen = strlen(buffer);
248 
249       if ((language = cupsLangGet(buffer)) == NULL)
250       {
251         printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\")\n", (int)j + 1, locale_str, language_str, buffer);
252         errors ++;
253         continue;
254       }
255 
256       if (strncasecmp(language->language, buffer, buflen))
257       {
258         printf("%d %s(%s): FAIL (unable to load POSIX locale \"%s\", got \"%s\")\n", (int)j + 1, locale_str, language_str, buffer, language->language);
259         errors ++;
260         continue;
261       }
262 
263       printf("%d %s(%s): PASS (POSIX locale is \"%s\")\n", (int)j + 1, locale_str, language_str, buffer);
264     }
265 
266     CFRelease(locales);
267 
268 #  if TEST_COUNTRY_CODES
269     CFRelease(country_codes);
270 #  endif /* TEST_COUNTRY_CODES */
271 #endif /* __APPLE__ */
272   }
273 
274   if (errors == 0 && dotests)
275     puts("ALL TESTS PASSED");
276 
277   return (errors > 0);
278 }
279 
280 
281 /*
282  * 'show_ppd()' - Show localized strings in a PPD file.
283  */
284 
285 static int				/* O - Number of errors */
show_ppd(const char * filename)286 show_ppd(const char *filename)		/* I - Filename */
287 {
288   ppd_file_t	*ppd;			/* PPD file */
289   ppd_option_t	*option;		/* PageSize option */
290   ppd_choice_t	*choice;		/* PageSize/Letter choice */
291   char		buffer[1024];		/* String buffer */
292 
293 
294   if ((ppd = ppdOpenFile(filename)) == NULL)
295   {
296     printf("Unable to open PPD file \"%s\".\n", filename);
297     return (1);
298   }
299 
300   ppdLocalize(ppd);
301 
302   if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
303   {
304     puts("No PageSize option.");
305     return (1);
306   }
307   else
308   {
309     printf("PageSize: %s\n", option->text);
310 
311     if ((choice = ppdFindChoice(option, "Letter")) == NULL)
312     {
313       puts("No Letter PageSize choice.");
314       return (1);
315     }
316     else
317     {
318       printf("Letter: %s\n", choice->text);
319     }
320   }
321 
322   printf("media-empty: %s\n", ppdLocalizeIPPReason(ppd, "media-empty", NULL, buffer, sizeof(buffer)));
323 
324   ppdClose(ppd);
325 
326   return (0);
327 }
328 
329 
330 /*
331  * 'test_string()' - Test the localization of a string.
332  */
333 
334 static int                            /* O - 1 on failure, 0 on success */
test_string(cups_lang_t * language,const char * msgid)335 test_string(cups_lang_t *language,    /* I - Language */
336             const char  *msgid)       /* I - Message */
337 {
338   const char  *msgstr;                /* Localized string */
339 
340 
341  /*
342   * Get the localized string and then see if we got what we expected.
343   *
344   * For the POSIX locale, the string pointers should be the same.
345   * For any other locale, the string pointers should be different.
346   */
347 
348   msgstr = _cupsLangString(language, msgid);
349   if (strcmp(language->language, "C") && msgid == msgstr)
350   {
351     printf("%-8s = \"%s\" (FAIL - no message catalog loaded)\n", msgid, msgstr);
352     return (1);
353   }
354   else if (!strcmp(language->language, "C") && msgid != msgstr)
355   {
356     printf("%-8s = \"%s\" (FAIL - POSIX locale is localized)\n", msgid, msgstr);
357     return (1);
358   }
359 
360   printf("%-8s = \"%s\" (PASS)\n", msgid, msgstr);
361 
362   return (0);
363 }
364 
365 
366 /*
367  * 'usage()' - Show program usage.
368  */
369 
370 static void
usage(void)371 usage(void)
372 {
373   puts("./testlang [-l locale] [-p ppd] [\"String to localize\"]");
374 }
375