]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/localize.c
2 * "$Id: localize.c 6686 2007-07-16 23:11:59Z mike $"
4 * PPD custom option routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * PostScript is a trademark of Adobe Systems, Inc.
17 * This code and any derivative of it may be used and distributed
18 * freely under the terms of the GNU General Public License when
19 * used with GNU Ghostscript or its derivatives. Use of the code
20 * (or any derivative of it) with software other than GNU
21 * GhostScript (or its derivatives) is governed by the CUPS license
24 * This file is subject to the Apple OS-Developed Software exception.
28 * ppdLocalize() - Localize the PPD file to the current locale.
29 * ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason
31 * ppd_ll_CC() - Get the current locale names.
32 * ppd_localized_attr() - Find a localized attribute.
36 * Include necessary headers.
47 static void ppd_ll_CC(char *ll_CC
, char *ll
);
48 static ppd_attr_t
*ppd_localized_attr(ppd_file_t
*ppd
,
50 const char *spec
, const char *ll_CC
,
55 * 'ppdLocalize()' - Localize the PPD file to the current locale.
57 * All groups, options, and choices are localized, as are ICC profile
58 * descriptions, printer presets, and custom option parameters. Each
59 * localized string uses the UTF-8 character encoding.
64 int /* O - 0 on success, -1 on error */
65 ppdLocalize(ppd_file_t
*ppd
) /* I - PPD file */
67 int i
, j
, k
; /* Looping vars */
68 ppd_group_t
*group
; /* Current group */
69 ppd_option_t
*option
; /* Current option */
70 ppd_choice_t
*choice
; /* Current choice */
71 ppd_coption_t
*coption
; /* Current custom option */
72 ppd_cparam_t
*cparam
; /* Current custom parameter */
73 ppd_attr_t
*attr
, /* Current attribute */
74 *locattr
; /* Localized attribute */
75 char ckeyword
[PPD_MAX_NAME
], /* Custom keyword */
76 ll_CC
[6], /* Language + country locale */
77 ll
[3]; /* Language locale */
81 * Range check input...
84 DEBUG_printf(("ppdLocalize(ppd=%p)\n", ppd
));
90 * Get the default language...
96 * Now lookup all of the groups, options, choices, etc.
99 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
101 if ((locattr
= ppd_localized_attr(ppd
, "Translation", group
->name
,
103 strlcpy(group
->text
, locattr
->text
, sizeof(group
->text
));
105 for (j
= group
->num_options
, option
= group
->options
; j
> 0; j
--, option
++)
107 if ((locattr
= ppd_localized_attr(ppd
, "Translation", option
->keyword
,
109 strlcpy(option
->text
, locattr
->text
, sizeof(option
->text
));
111 for (k
= option
->num_choices
, choice
= option
->choices
;
115 if (strcmp(choice
->choice
, "Custom"))
116 locattr
= ppd_localized_attr(ppd
, option
->keyword
, choice
->choice
,
120 snprintf(ckeyword
, sizeof(ckeyword
), "Custom%s", option
->keyword
);
122 locattr
= ppd_localized_attr(ppd
, ckeyword
, "True", ll_CC
, ll
);
126 strlcpy(choice
->text
, locattr
->text
, sizeof(choice
->text
));
132 * Translate any custom parameters...
135 for (coption
= (ppd_coption_t
*)cupsArrayFirst(ppd
->coptions
);
137 coption
= (ppd_coption_t
*)cupsArrayNext(ppd
->coptions
))
139 for (cparam
= (ppd_cparam_t
*)cupsArrayFirst(coption
->params
);
141 cparam
= (ppd_cparam_t
*)cupsArrayNext(coption
->params
))
143 snprintf(ckeyword
, sizeof(ckeyword
), "ParamCustom%s", coption
->keyword
);
145 if ((locattr
= ppd_localized_attr(ppd
, ckeyword
, cparam
->name
,
147 strlcpy(cparam
->text
, locattr
->text
, sizeof(cparam
->text
));
152 * Translate ICC profile names...
155 if ((attr
= ppdFindAttr(ppd
, "APCustomColorMatchingName", NULL
)) != NULL
)
157 if ((locattr
= ppd_localized_attr(ppd
, "APCustomColorMatchingName",
158 attr
->spec
, ll_CC
, ll
)) != NULL
)
159 strlcpy(attr
->text
, locattr
->text
, sizeof(attr
->text
));
162 for (attr
= ppdFindAttr(ppd
, "cupsICCProfile", NULL
);
164 attr
= ppdFindNextAttr(ppd
, "cupsICCProfile", NULL
))
166 cupsArraySave(ppd
->sorted_attrs
);
168 if ((locattr
= ppd_localized_attr(ppd
, "cupsICCProfile", attr
->spec
,
170 strlcpy(attr
->text
, locattr
->text
, sizeof(attr
->text
));
172 cupsArrayRestore(ppd
->sorted_attrs
);
176 * Translate printer presets...
179 for (attr
= ppdFindAttr(ppd
, "APPrinterPreset", NULL
);
181 attr
= ppdFindNextAttr(ppd
, "APPrinterPreset", NULL
))
183 cupsArraySave(ppd
->sorted_attrs
);
185 if ((locattr
= ppd_localized_attr(ppd
, "APPrinterPreset", attr
->spec
,
187 strlcpy(attr
->text
, locattr
->text
, sizeof(attr
->text
));
189 cupsArrayRestore(ppd
->sorted_attrs
);
197 * 'ppdLocalizeIPPReason()' - Get the localized version of a cupsIPPReason
200 * This function uses the current locale to find the corresponding reason
201 * text or URI from the attribute value. If "scheme" is NULL or "text",
202 * the returned value contains human-readable (UTF-8) text from the translation
203 * string or attribute value. Otherwise the corresponding URI is returned.
205 * If no value of the requested scheme can be found, NULL is returned.
210 const char * /* O - Value or NULL if not found */
211 ppdLocalizeIPPReason(
212 ppd_file_t
*ppd
, /* I - PPD file */
213 const char *reason
, /* I - IPP reason keyword to look up */
214 const char *scheme
, /* I - URI scheme or NULL for text */
215 char *buffer
, /* I - Value buffer */
216 size_t bufsize
) /* I - Size of value buffer */
218 ppd_attr_t
*locattr
; /* Localized attribute */
219 char ll_CC
[6], /* Language + country locale */
220 ll
[3], /* Language locale */
221 *bufptr
, /* Pointer into buffer */
222 *bufend
, /* Pointer to end of buffer */
223 *valptr
; /* Pointer into value */
224 int ch
, /* Hex-encoded character */
225 schemelen
; /* Length of scheme name */
229 * Range check input...
235 if (!ppd
|| !reason
|| (scheme
&& !*scheme
) ||
236 !buffer
|| bufsize
< PPD_MAX_TEXT
)
240 * Get the default language...
243 ppd_ll_CC(ll_CC
, ll
);
246 * Find the localized attribute...
249 if ((locattr
= ppd_localized_attr(ppd
, "cupsIPPReason", reason
,
251 locattr
= ppdFindAttr(ppd
, "cupsIPPReason", reason
);
257 * Now find the value we need...
260 bufend
= buffer
+ bufsize
- 1;
262 if (!scheme
|| !strcmp(scheme
, "text"))
265 * Copy a text value (either the translation text or text:... URIs from
269 strlcpy(buffer
, locattr
->text
, bufsize
);
271 for (valptr
= locattr
->value
, bufptr
= buffer
; *valptr
&& bufptr
< bufend
;)
273 if (!strncmp(valptr
, "text:", 5))
276 * Decode text: URI and add to the buffer...
280 *bufptr
++ = ' '; /* Add leading whitespace */
284 while (*valptr
&& !isspace(*valptr
& 255) && bufptr
< bufend
)
286 if (*valptr
== '%' && isxdigit(valptr
[1] & 255) &&
287 isxdigit(valptr
[2] & 255))
290 * Pull a hex-encoded character from the URI...
295 if (isdigit(*valptr
& 255))
296 ch
= (*valptr
- '0') << 4;
298 ch
= (tolower(*valptr
) - 'a' + 10) << 4;
301 if (isdigit(*valptr
& 255))
302 *bufptr
++ = ch
| (*valptr
- '0');
304 *bufptr
++ = ch
| (tolower(*valptr
) - 'a' + 10);
307 else if (*valptr
== '+')
313 *bufptr
++ = *valptr
++;
322 while (*valptr
&& !isspace(*valptr
& 255))
330 while (isspace(*valptr
& 255))
345 schemelen
= strlen(scheme
);
346 if (scheme
[schemelen
- 1] == ':') /* Force scheme to be just the name */
349 for (valptr
= locattr
->value
, bufptr
= buffer
; *valptr
&& bufptr
< bufend
;)
351 if ((!strncmp(valptr
, scheme
, schemelen
) && valptr
[schemelen
] == ':') ||
352 (*valptr
== '/' && !strcmp(scheme
, "file")))
358 while (*valptr
&& !isspace(*valptr
& 255) && bufptr
< bufend
)
359 *bufptr
++ = *valptr
++;
371 while (*valptr
&& !isspace(*valptr
& 255))
379 while (isspace(*valptr
& 255))
389 * 'ppd_ll_CC()' - Get the current locale names.
393 ppd_ll_CC(char *ll_CC
, /* O - Country-specific locale name */
394 char *ll
) /* O - Generic locale name */
397 cups_lang_t
*lang
; /* Current language */
401 * Get the current locale...
404 if ((lang
= cupsLangDefault()) == NULL
)
406 strcpy(ll_CC
, "en_US");
412 * Copy the locale name...
415 strlcpy(ll_CC
, lang
->language
, sizeof(ll_CC
));
416 strlcpy(ll
, lang
->language
, sizeof(ll
));
418 if (strlen(ll_CC
) == 2)
421 * Map "ll" to primary/origin country locales to have the best
422 * chance of finding a match...
425 if (!strcmp(ll_CC
, "cs"))
426 strcpy(ll_CC
, "cs_CZ");
427 else if (!strcmp(ll_CC
, "en"))
428 strcpy(ll_CC
, "en_US");
429 else if (!strcmp(ll_CC
, "ja"))
430 strcpy(ll_CC
, "ja_JP");
431 else if (!strcmp(ll_CC
, "sv"))
432 strcpy(ll_CC
, "sv_SE");
433 else if (!strcmp(ll_CC
, "zh"))
434 strcpy(ll_CC
, "zh_CN"); /* Simplified Chinese */
438 ll_CC
[3] = toupper(ll_CC
[0] & 255);
439 ll_CC
[4] = toupper(ll_CC
[1] & 255);
444 DEBUG_printf(("ppd_ll_CC: lang->language=\"%s\", ll=\"%s\", ll_CC=\"%s\"...\n",
445 lang
->language
, ll
, ll_CC
));
450 * 'ppd_localized_attr()' - Find a localized attribute.
453 static ppd_attr_t
* /* O - Localized attribute or NULL */
454 ppd_localized_attr(ppd_file_t
*ppd
, /* I - PPD file */
455 const char *keyword
, /* I - Main keyword */
456 const char *spec
, /* I - Option keyword */
457 const char *ll_CC
, /* I - Language + country locale */
458 const char *ll
) /* I - Language locale */
460 char lkeyword
[PPD_MAX_NAME
]; /* Localization keyword */
461 ppd_attr_t
*attr
; /* Current attribute */
464 DEBUG_printf(("ppd_text(ppd=%p, keyword=\"%s\", spec=\"%s\", "
465 "ll_CC=\"%s\", ll=\"%s\")\n",
466 ppd
, keyword
, spec
, ll_CC
, ll
));
469 * Look for Keyword.ll_CC, then Keyword.ll...
472 snprintf(lkeyword
, sizeof(lkeyword
), "%s.%s", ll_CC
, keyword
);
473 if ((attr
= ppdFindAttr(ppd
, lkeyword
, spec
)) == NULL
)
475 snprintf(lkeyword
, sizeof(lkeyword
), "%s.%s", ll
, keyword
);
476 attr
= ppdFindAttr(ppd
, lkeyword
, spec
);
478 if (!attr
&& !strcmp(ll
, "ja"))
481 * Due to a bug in the CUPS DDK 1.1.0 ppdmerge program, Japanese
482 * PPD files were incorrectly assigned "jp" as the locale name
483 * instead of "ja". Support both the old (incorrect) and new
484 * locale names for Japanese...
487 snprintf(lkeyword
, sizeof(lkeyword
), "jp.%s", keyword
);
488 attr
= ppdFindAttr(ppd
, lkeyword
, spec
);
494 printf(" *%s %s/%s: \"%s\"\n", attr
->name
, attr
->spec
, attr
->text
,
495 attr
->value
? attr
->value
: "");
505 * End of "$Id: localize.c 6686 2007-07-16 23:11:59Z mike $".