]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/language.c
2 * "$Id: language.c,v 1.20.2.12 2003/01/24 20:45:13 mike Exp $"
4 * I18N/language support for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2003 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * cupsEncodingName() - Return the character encoding name string
29 * for the given encoding enumeration.
30 * cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
31 * for the given language.
32 * cupsLangFlush() - Flush all language data out of the cache.
33 * cupsLangFree() - Free language data.
34 * cupsLangGet() - Get a language.
38 * Include necessary headers...
52 static cups_lang_t
*lang_cache
= NULL
; /* Language string cache */
53 static const char *lang_blank
= ""; /* Blank constant string */
54 static const char * const lang_encodings
[] = /* Encoding strings */
56 "us-ascii", "iso-8859-1",
57 "iso-8859-2", "iso-8859-3",
58 "iso-8859-4", "iso-8859-5",
59 "iso-8859-6", "iso-8859-7",
60 "iso-8859-8", "iso-8859-9",
61 "iso-8859-10", "utf-8",
62 "iso-8859-13", "iso-8859-14",
63 "iso-8859-15", "windows-874",
64 "windows-1250", "windows-1251",
65 "windows-1252", "windows-1253",
66 "windows-1254", "windows-1255",
67 "windows-1256", "windows-1257",
68 "windows-1258", "koi8-r",
69 "koi8-u", "iso-8859-11",
70 "iso-8859-16", "unknown",
88 "windows-932", "windows-936",
89 "windows-949", "windows-950",
90 "windows-1361", "unknown",
100 "unknown", "unknown",
101 "unknown", "unknown",
102 "unknown", "unknown",
103 "unknown", "unknown",
104 "unknown", "unknown",
105 "unknown", "unknown",
106 "unknown", "unknown",
107 "unknown", "unknown",
108 "unknown", "unknown",
109 "unknown", "unknown",
110 "unknown", "unknown",
111 "unknown", "unknown",
112 "unknown", "unknown",
113 "unknown", "unknown",
114 "unknown", "unknown",
115 "unknown", "unknown",
116 "unknown", "unknown",
117 "unknown", "unknown",
118 "unknown", "unknown",
119 "unknown", "unknown",
123 static const char *const lang_default
[] = /* Default POSIX locale */
131 * 'cupsEncodingName()' - Return the character encoding name string
132 * for the given encoding enumeration.
135 const char * /* O - Character encoding */
136 cupsEncodingName(cups_encoding_t encoding
)
137 /* I - Encoding enum */
140 encoding
>= (sizeof(lang_encodings
) / sizeof(const char *)))
141 return (lang_encodings
[0]);
143 return (lang_encodings
[encoding
]);
148 * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.)
149 * for the given language.
152 const char * /* O - Character encoding */
153 cupsLangEncoding(cups_lang_t
*lang
) /* I - Language data */
156 return ((char*)lang_encodings
[0]);
158 return ((char*)lang_encodings
[lang
->encoding
]);
163 * 'cupsLangFlush()' - Flush all language data out of the cache.
169 int i
; /* Looping var */
170 cups_lang_t
*lang
, /* Current language */
171 *next
; /* Next language */
174 for (lang
= lang_cache
; lang
!= NULL
; lang
= next
)
176 for (i
= 0; i
< CUPS_MSG_MAX
; i
++)
177 if (lang
->messages
[i
] != NULL
&& lang
->messages
[i
] != lang_blank
)
178 free(lang
->messages
[i
]);
187 * 'cupsLangFree()' - Free language data.
189 * This does not actually free anything; use cupsLangFlush() for that.
193 cupsLangFree(cups_lang_t
*lang
) /* I - Language to free */
195 if (lang
!= NULL
&& lang
->used
> 0)
201 * 'cupsLangGet()' - Get a language.
204 cups_lang_t
* /* O - Language data */
205 cupsLangGet(const char *language
) /* I - Language or locale */
207 int i
, count
; /* Looping vars */
208 char langname
[32], /* Requested language name */
209 *langptr
, /* Pointer into language name */
210 real
[32], /* Real language name */
211 *realptr
, /* Pointer into real language name */
212 filename
[1024], /* Filename for language locale file */
213 *localedir
; /* Directory for locale files */
214 FILE *fp
; /* Language locale file pointer */
215 char line
[1024]; /* Line from file */
216 cups_msg_t msg
; /* Message number */
217 char *text
; /* Message text */
218 cups_lang_t
*lang
; /* Current language... */
222 * Convert the language string passed in to a locale string. "C" is the
223 * standard POSIX locale and is copied unchanged. Otherwise the
224 * language string is converted from ll-cc (language-country) to ll_cc
225 * to match the file naming convention used by all POSIX-compliant
229 if (language
== NULL
|| language
[0] == '\0' ||
230 strcmp(language
, "POSIX") == 0)
231 strcpy(langname
, "C");
235 * Copy the locale string over safely...
238 strlcpy(langname
, language
, sizeof(langname
));
241 if (strlen(langname
) < 2)
246 * Convert the language name to a normalized form, e.g.:
251 real
[0] = tolower(langname
[0]);
252 real
[1] = tolower(langname
[1]);
254 langptr
= langname
+ 2;
256 if (*langptr
== '_' || *langptr
== '-')
259 * Add country code...
265 *realptr
++ = toupper(*langptr
++);
266 *realptr
++ = toupper(*langptr
++);
280 if ((realptr
- real
) < (sizeof(real
) - 1) &&
281 *langptr
!= '-' && *langptr
!= '_')
282 *realptr
++ = tolower(*langptr
++);
292 * See if we already have this language loaded...
295 for (lang
= lang_cache
; lang
!= NULL
; lang
= lang
->next
)
296 if (strcmp(lang
->language
, langname
) == 0)
305 * Next try to open a locale file; we will try the charset-localized
306 * file first, then the country-localized file, and finally look for
307 * a generic language file. If all else fails we will use the POSIX
311 if ((localedir
= getenv("LOCALEDIR")) == NULL
)
312 localedir
= CUPS_LOCALEDIR
;
316 snprintf(filename
, sizeof(filename
), "%s/%s/cups_%s", localedir
,
319 if ((fp
= fopen(filename
, "r")) == NULL
)
321 if ((realptr
= strchr(real
, '.')) != NULL
)
323 else if ((realptr
= strchr(real
, '_')) != NULL
)
327 while (fp
== NULL
&& strchr(real
, '_') != NULL
&& strchr(real
, '.') != NULL
);
330 * OK, we have an open messages file; the first line will contain the
331 * language encoding (us-ascii, iso-8859-1, etc.), and the rest will
332 * be messages consisting of:
334 * #### SP message text
340 * If the line starts with a number, then message processing picks up
341 * where the number indicates. Otherwise the last message number is
344 * All leading whitespace is deleted.
348 strlcpy(line
, lang_default
[0], sizeof(line
));
349 else if (fgets(line
, sizeof(line
), fp
) == NULL
)
352 * Can't read encoding!
359 i
= strlen(line
) - 1;
361 line
[i
] = '\0'; /* Strip LF */
364 * See if there is a free language available; if so, use that
368 for (lang
= lang_cache
; lang
!= NULL
; lang
= lang
->next
)
375 * Allocate memory for the language and add it to the cache.
378 if ((lang
= calloc(sizeof(cups_lang_t
), 1)) == NULL
)
384 lang
->next
= lang_cache
;
389 * Free all old strings as needed...
392 for (i
= 0; i
< CUPS_MSG_MAX
; i
++)
394 if (lang
->messages
[i
] != NULL
&& lang
->messages
[i
] != lang_blank
)
395 free(lang
->messages
[i
]);
397 lang
->messages
[i
] = (char *)lang_blank
;
401 * Then assign the language and encoding fields...
405 strlcpy(lang
->language
, langname
, sizeof(lang
->language
));
407 for (i
= 0; i
< (sizeof(lang_encodings
) / sizeof(lang_encodings
[0])); i
++)
408 if (strcmp(lang_encodings
[i
], line
) == 0)
410 lang
->encoding
= (cups_encoding_t
)i
;
415 * Read the strings from the file...
418 msg
= (cups_msg_t
)-1;
424 * Read a line from memory or from a file...
429 if (lang_default
[count
] == NULL
)
432 strlcpy(line
, lang_default
[count
], sizeof(line
));
434 else if (fgets(line
, sizeof(line
), fp
) == NULL
)
440 * Ignore blank lines...
443 i
= strlen(line
) - 1;
445 line
[i
] = '\0'; /* Strip LF */
451 * Grab the message number and text...
454 if (isdigit(line
[0]))
455 msg
= (cups_msg_t
)atoi(line
);
459 if (msg
< 0 || msg
>= CUPS_MSG_MAX
)
463 while (isdigit(*text
))
465 while (isspace(*text
))
468 lang
->messages
[msg
] = strdup(text
);
472 * Close the file and return...
483 * End of "$Id: language.c,v 1.20.2.12 2003/01/24 20:45:13 mike Exp $".