]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/language.c
Fixed all constant arrays to use "const" modifier.
[thirdparty/cups.git] / cups / language.c
1 /*
2 * "$Id: language.c,v 1.10 1999/07/12 16:09:37 mike Exp $"
3 *
4 * I18N/language support for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-1999 by Easy Software Products.
7 *
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
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 * cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
27 * for the given language.
28 * cupsLangFlush() - Flush all language data out of the cache.
29 * cupsLangFree() - Free language data.
30 * cupsLangGet() - Get a language.
31 */
32
33 /*
34 * Include necessary headers...
35 */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include "string.h"
41 #include "language.h"
42
43
44 /*
45 * Local globals...
46 */
47
48 static cups_lang_t *lang_cache = NULL; /* Language string cache */
49 static char *lang_blank = ""; /* Blank constant string */
50 static char *lang_encodings[] = /* Encoding strings */
51 {
52 "us-ascii",
53 "iso8859-1",
54 "iso8859-2",
55 "iso8859-3",
56 "iso8859-4",
57 "iso8859-5",
58 "iso8859-6",
59 "iso8859-7",
60 "iso8859-8",
61 "iso8859-9",
62 "iso8859-10",
63 "utf8"
64 };
65 static char *lang_default[] = /* Default POSIX locale */
66 {
67 #include "cups_C.h"
68 NULL
69 };
70
71
72 /*
73 * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.)
74 * for the given language.
75 */
76
77 char * /* O - Character encoding */
78 cupsLangEncoding(cups_lang_t *lang) /* I - Language data */
79 {
80 if (lang == NULL)
81 return (lang_encodings[0]);
82 else
83 return (lang_encodings[lang->encoding]);
84 }
85
86
87 /*
88 * 'cupsLangFlush()' - Flush all language data out of the cache.
89 */
90
91 void
92 cupsLangFlush(void)
93 {
94 int i; /* Looping var */
95 cups_lang_t *lang, /* Current language */
96 *next; /* Next language */
97
98
99 for (lang = lang_cache; lang != NULL; lang = next)
100 {
101 for (i = 0; i < CUPS_MSG_MAX; i ++)
102 if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
103 free(lang->messages[i]);
104
105 next = lang->next;
106 free(lang);
107 }
108 }
109
110
111 /*
112 * 'cupsLangFree()' - Free language data.
113 *
114 * This does not actually free anything; use cupsLangFlush() for that.
115 */
116
117 void
118 cupsLangFree(cups_lang_t *lang) /* I - Language to free */
119 {
120 if (lang != NULL && lang->used > 0)
121 lang->used --;
122 }
123
124
125 /*
126 * 'cupsLangGet()' - Get a language.
127 */
128
129 cups_lang_t * /* O - Language data */
130 cupsLangGet(const char *language) /* I - Language or locale */
131 {
132 int i, count; /* Looping vars */
133 char langname[16], /* Requested language name */
134 real[16], /* Real language name */
135 filename[1024], /* Filename for language locale file */
136 *localedir; /* Directory for locale files */
137 FILE *fp; /* Language locale file pointer */
138 char line[1024]; /* Line from file */
139 cups_msg_t msg; /* Message number */
140 char *text; /* Message text */
141 cups_lang_t *lang; /* Current language... */
142
143
144 /*
145 * Convert the language string passed in to a locale string. "C" is the
146 * standard POSIX locale and is copied unchanged. Otherwise the
147 * language string is converted from ll-cc (language-country) to ll_CC
148 * to match the file naming convention used by all POSIX-compliant
149 * operating systems.
150 */
151
152 if (language == NULL || language[0] == '\0')
153 strcpy(langname, "C");
154 else
155 strcpy(langname, language);
156
157 if (strlen(langname) < 2)
158 strcpy(real, "C");
159 else
160 {
161 real[0] = tolower(langname[0]);
162 real[1] = tolower(langname[1]);
163
164 if (langname[2] == '_' || langname[2] == '-')
165 {
166 real[2] = '_';
167 real[3] = toupper(langname[3]);
168 real[4] = toupper(langname[4]);
169 real[5] = '\0';
170 langname[5] = '\0';
171 }
172 else
173 {
174 langname[2] = '\0';
175 real[2] = '\0';
176 }
177 }
178
179 /*
180 * Next try to open a locale file; we will try the country-localized file
181 * first, and then look for generic language file. If all else fails we
182 * will use the POSIX locale.
183 */
184
185 if ((localedir = getenv("LOCALEDIR")) == NULL)
186 localedir = CUPS_LOCALEDIR;
187
188 sprintf(filename, "%s/%s/cups_%s", localedir, real, real);
189
190 if ((fp = fopen(filename, "r")) == NULL)
191 if (strlen(real) > 2)
192 {
193 /*
194 * Nope, see if we can open a generic language file...
195 */
196
197 real[2] = '\0';
198 sprintf(filename, "%s/%s/cups_%s", localedir, real, real);
199 fp = fopen(filename, "r");
200 }
201
202 /*
203 * Then see if we already have this language loaded...
204 */
205
206 for (lang = lang_cache; lang != NULL; lang = lang->next)
207 if (strcmp(lang->language, langname) == 0)
208 {
209 lang->used ++;
210
211 if (fp != NULL)
212 fclose(fp);
213
214 return (lang);
215 }
216
217 /*
218 * OK, we have an open messages file; the first line will contain the
219 * language encoding (us-ascii, iso-8859-1, etc.), and the rest will
220 * be messages consisting of:
221 *
222 * #### SP message text
223 *
224 * or:
225 *
226 * message text
227 *
228 * If the line starts with a number, then message processing picks up
229 * where the number indicates. Otherwise the last message number is
230 * incremented.
231 *
232 * All leading whitespace is deleted.
233 */
234
235 if (fp == NULL)
236 strcpy(line, lang_default[0]);
237 else if (fgets(line, sizeof(line), fp) == NULL)
238 {
239 /*
240 * Can't read encoding!
241 */
242
243 fclose(fp);
244 return (NULL);
245 }
246
247 i = strlen(line) - 1;
248 if (line[i] == '\n')
249 line[i] = '\0'; /* Strip LF */
250
251 /*
252 * See if there is a free language available; if so, use that
253 * record...
254 */
255
256 for (lang = lang_cache; lang != NULL; lang = lang->next)
257 if (lang->used == 0)
258 break;
259
260 if (lang == NULL)
261 {
262 /*
263 * Allocate memory for the language and add it to the cache.
264 */
265
266 if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL)
267 {
268 fclose(fp);
269 return (NULL);
270 }
271
272 lang->next = lang_cache;
273 lang_cache = lang;
274 }
275
276
277 /*
278 * Free all old strings as needed...
279 */
280
281 for (i = 0; i < CUPS_MSG_MAX; i ++)
282 {
283 if (lang->messages[i] != NULL && lang->messages[i] != lang_blank)
284 free(lang->messages[i]);
285
286 lang->messages[i] = lang_blank;
287 }
288
289 /*
290 * Then assign the language and encoding fields...
291 */
292
293 lang->used ++;
294 strcpy(lang->language, langname);
295
296 for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++)
297 if (strcmp(lang_encodings[i], line) == 0)
298 {
299 lang->encoding = (cups_encoding_t)i;
300 break;
301 }
302
303 /*
304 * Read the strings from the file...
305 */
306
307 msg = (cups_msg_t)-1;
308 count = 1;
309
310 for (;;)
311 {
312 /*
313 * Read a line from memory or from a file...
314 */
315
316 if (fp == NULL)
317 {
318 if (lang_default[count] == NULL)
319 break;
320
321 strcpy(line, lang_default[count]);
322 }
323 else if (fgets(line, sizeof(line), fp) == NULL)
324 break;
325
326 count ++;
327
328 /*
329 * Ignore blank lines...
330 */
331
332 i = strlen(line) - 1;
333 if (line[i] == '\n')
334 line[i] = '\0'; /* Strip LF */
335
336 if (line[0] == '\0')
337 continue;
338
339 /*
340 * Grab the message number and text...
341 */
342
343 if (isdigit(line[0]))
344 msg = (cups_msg_t)atoi(line);
345 else
346 msg ++;
347
348 if (msg < 0 || msg >= CUPS_MSG_MAX)
349 continue;
350
351 text = line;
352 while (isdigit(*text))
353 text ++;
354 while (isspace(*text))
355 text ++;
356
357 lang->messages[msg] = strdup(text);
358 }
359
360 /*
361 * Close the file and return...
362 */
363
364 if (fp != NULL)
365 fclose(fp);
366
367 return (lang);
368 }
369
370
371 /*
372 * End of "$Id: language.c,v 1.10 1999/07/12 16:09:37 mike Exp $".
373 */