]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
7e86f2f6 | 2 | * Localized printf/puts functions for CUPS. |
ef416fc2 | 3 | * |
7e86f2f6 MS |
4 | * Copyright 2007-2014 by Apple Inc. |
5 | * Copyright 2002-2007 by Easy Software Products. | |
ef416fc2 | 6 | * |
7e86f2f6 MS |
7 | * These coded instructions, statements, and computer programs are the |
8 | * property of Apple Inc. and are protected by Federal copyright | |
9 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
10 | * which should have been included with this file. If this file is | |
11 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 12 | * |
7e86f2f6 | 13 | * This file is subject to the Apple OS-Developed Software exception. |
ef416fc2 | 14 | */ |
15 | ||
16 | /* | |
17 | * Include necessary headers... | |
18 | */ | |
19 | ||
71e16022 | 20 | #include "cups-private.h" |
080811b1 MS |
21 | |
22 | ||
23 | /* | |
24 | * '_cupsLangPrintError()' - Print a message followed by a standard error. | |
25 | */ | |
26 | ||
27 | void | |
0837b7e8 MS |
28 | _cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */ |
29 | const char *message)/* I - Message */ | |
080811b1 | 30 | { |
7e86f2f6 | 31 | ssize_t bytes; /* Number of bytes formatted */ |
080811b1 MS |
32 | int last_errno; /* Last error */ |
33 | char buffer[2048], /* Message buffer */ | |
84315f46 | 34 | *bufptr, /* Pointer into buffer */ |
080811b1 MS |
35 | output[8192]; /* Output buffer */ |
36 | _cups_globals_t *cg; /* Global data */ | |
37 | ||
38 | ||
39 | /* | |
40 | * Range check... | |
41 | */ | |
42 | ||
43 | if (!message) | |
44 | return; | |
45 | ||
46 | /* | |
47 | * Save the errno value... | |
48 | */ | |
49 | ||
50 | last_errno = errno; | |
51 | ||
52 | /* | |
53 | * Get the message catalog... | |
54 | */ | |
55 | ||
56 | cg = _cupsGlobals(); | |
57 | ||
58 | if (!cg->lang_default) | |
59 | cg->lang_default = cupsLangDefault(); | |
60 | ||
61 | /* | |
62 | * Format the message... | |
63 | */ | |
64 | ||
84315f46 MS |
65 | if (prefix) |
66 | { | |
67 | snprintf(buffer, sizeof(buffer), "%s:", prefix); | |
68 | bufptr = buffer + strlen(buffer); | |
69 | } | |
70 | else | |
71 | bufptr = buffer; | |
72 | ||
7e86f2f6 | 73 | snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), |
84315f46 MS |
74 | /* TRANSLATORS: Message is "subject: error" */ |
75 | _cupsLangString(cg->lang_default, _("%s: %s")), | |
1f0275e3 | 76 | _cupsLangString(cg->lang_default, message), strerror(last_errno)); |
84315f46 | 77 | strlcat(buffer, "\n", sizeof(buffer)); |
080811b1 MS |
78 | |
79 | /* | |
80 | * Convert and write to stderr... | |
81 | */ | |
82 | ||
83 | bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), | |
84 | cg->lang_default->encoding); | |
85 | ||
86 | if (bytes > 0) | |
7e86f2f6 | 87 | fwrite(output, 1, (size_t)bytes, stderr); |
080811b1 | 88 | } |
ef416fc2 | 89 | |
90 | ||
0837b7e8 MS |
91 | /* |
92 | * '_cupsLangPrintFilter()' - Print a formatted filter message string to a file. | |
93 | */ | |
94 | ||
95 | int /* O - Number of bytes written */ | |
96 | _cupsLangPrintFilter( | |
97 | FILE *fp, /* I - File to write to */ | |
98 | const char *prefix, /* I - Non-localized message prefix */ | |
99 | const char *message, /* I - Message string to use */ | |
100 | ...) /* I - Additional arguments as needed */ | |
101 | { | |
7e86f2f6 | 102 | ssize_t bytes; /* Number of bytes formatted */ |
0837b7e8 MS |
103 | char temp[2048], /* Temporary format buffer */ |
104 | buffer[2048], /* Message buffer */ | |
105 | output[8192]; /* Output buffer */ | |
106 | va_list ap; /* Pointer to additional arguments */ | |
107 | _cups_globals_t *cg; /* Global data */ | |
108 | ||
109 | ||
110 | /* | |
111 | * Range check... | |
112 | */ | |
113 | ||
114 | if (!fp || !message) | |
115 | return (-1); | |
116 | ||
117 | cg = _cupsGlobals(); | |
118 | ||
119 | if (!cg->lang_default) | |
120 | cg->lang_default = cupsLangDefault(); | |
121 | ||
122 | /* | |
123 | * Format the string... | |
124 | */ | |
125 | ||
126 | va_start(ap, message); | |
127 | snprintf(temp, sizeof(temp), "%s: %s\n", prefix, | |
128 | _cupsLangString(cg->lang_default, message)); | |
129 | vsnprintf(buffer, sizeof(buffer), temp, ap); | |
130 | va_end(ap); | |
131 | ||
132 | /* | |
133 | * Transcode to the destination charset... | |
134 | */ | |
135 | ||
136 | bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), | |
137 | cg->lang_default->encoding); | |
138 | ||
139 | /* | |
140 | * Write the string and return the number of bytes written... | |
141 | */ | |
142 | ||
143 | if (bytes > 0) | |
7e86f2f6 | 144 | return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
0837b7e8 | 145 | else |
7e86f2f6 | 146 | return ((int)bytes); |
0837b7e8 MS |
147 | } |
148 | ||
149 | ||
ef416fc2 | 150 | /* |
151 | * '_cupsLangPrintf()' - Print a formatted message string to a file. | |
152 | */ | |
153 | ||
154 | int /* O - Number of bytes written */ | |
0837b7e8 MS |
155 | _cupsLangPrintf(FILE *fp, /* I - File to write to */ |
156 | const char *message, /* I - Message string to use */ | |
ef416fc2 | 157 | ...) /* I - Additional arguments as needed */ |
158 | { | |
7e86f2f6 | 159 | ssize_t bytes; /* Number of bytes formatted */ |
ef416fc2 | 160 | char buffer[2048], /* Message buffer */ |
161 | output[8192]; /* Output buffer */ | |
162 | va_list ap; /* Pointer to additional arguments */ | |
fa73b229 | 163 | _cups_globals_t *cg; /* Global data */ |
ef416fc2 | 164 | |
165 | ||
166 | /* | |
167 | * Range check... | |
168 | */ | |
169 | ||
170 | if (!fp || !message) | |
171 | return (-1); | |
172 | ||
fa73b229 | 173 | cg = _cupsGlobals(); |
174 | ||
175 | if (!cg->lang_default) | |
176 | cg->lang_default = cupsLangDefault(); | |
ef416fc2 | 177 | |
178 | /* | |
179 | * Format the string... | |
180 | */ | |
181 | ||
182 | va_start(ap, message); | |
0837b7e8 MS |
183 | vsnprintf(buffer, sizeof(buffer) - 1, |
184 | _cupsLangString(cg->lang_default, message), ap); | |
ef416fc2 | 185 | va_end(ap); |
186 | ||
0837b7e8 MS |
187 | strlcat(buffer, "\n", sizeof(buffer)); |
188 | ||
ef416fc2 | 189 | /* |
190 | * Transcode to the destination charset... | |
191 | */ | |
192 | ||
193 | bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), | |
fa73b229 | 194 | cg->lang_default->encoding); |
ef416fc2 | 195 | |
196 | /* | |
197 | * Write the string and return the number of bytes written... | |
198 | */ | |
199 | ||
200 | if (bytes > 0) | |
7e86f2f6 | 201 | return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
ef416fc2 | 202 | else |
7e86f2f6 | 203 | return ((int)bytes); |
ef416fc2 | 204 | } |
205 | ||
206 | ||
207 | /* | |
208 | * '_cupsLangPuts()' - Print a static message string to a file. | |
209 | */ | |
210 | ||
211 | int /* O - Number of bytes written */ | |
0837b7e8 MS |
212 | _cupsLangPuts(FILE *fp, /* I - File to write to */ |
213 | const char *message) /* I - Message string to use */ | |
ef416fc2 | 214 | { |
7e86f2f6 | 215 | ssize_t bytes; /* Number of bytes formatted */ |
0837b7e8 | 216 | char output[8192]; /* Message buffer */ |
fa73b229 | 217 | _cups_globals_t *cg; /* Global data */ |
ef416fc2 | 218 | |
219 | ||
220 | /* | |
221 | * Range check... | |
222 | */ | |
223 | ||
224 | if (!fp || !message) | |
225 | return (-1); | |
226 | ||
fa73b229 | 227 | cg = _cupsGlobals(); |
228 | ||
229 | if (!cg->lang_default) | |
230 | cg->lang_default = cupsLangDefault(); | |
ef416fc2 | 231 | |
232 | /* | |
233 | * Transcode to the destination charset... | |
234 | */ | |
235 | ||
236 | bytes = cupsUTF8ToCharset(output, | |
0837b7e8 MS |
237 | (cups_utf8_t *)_cupsLangString(cg->lang_default, |
238 | message), | |
239 | sizeof(output) - 4, cg->lang_default->encoding); | |
7e86f2f6 | 240 | bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", (int)(sizeof(output) - (size_t)bytes), cg->lang_default->encoding); |
ef416fc2 | 241 | |
242 | /* | |
243 | * Write the string and return the number of bytes written... | |
244 | */ | |
245 | ||
246 | if (bytes > 0) | |
7e86f2f6 | 247 | return ((int)fwrite(output, 1, (size_t)bytes, fp)); |
ef416fc2 | 248 | else |
7e86f2f6 | 249 | return ((int)bytes); |
ef416fc2 | 250 | } |
251 | ||
252 | ||
253 | /* | |
07725fee | 254 | * '_cupsSetLocale()' - Set the current locale and transcode the command-line. |
d09495fa | 255 | */ |
256 | ||
257 | void | |
07725fee | 258 | _cupsSetLocale(char *argv[]) /* IO - Command-line arguments */ |
d09495fa | 259 | { |
07725fee | 260 | int i; /* Looping var */ |
261 | char buffer[8192]; /* Command-line argument buffer */ | |
262 | _cups_globals_t *cg; /* Global data */ | |
d09495fa | 263 | #ifdef LC_TIME |
07725fee | 264 | const char *lc_time; /* Current LC_TIME value */ |
265 | char new_lc_time[255], /* New LC_TIME value */ | |
d09495fa | 266 | *charset; /* Pointer to character set */ |
267 | #endif /* LC_TIME */ | |
268 | ||
269 | ||
270 | /* | |
271 | * Set the locale so that times, etc. are displayed properly. | |
272 | * | |
273 | * Unfortunately, while we need the localized time value, we *don't* | |
274 | * want to use the localized charset for the time value, so we need | |
275 | * to set LC_TIME to the locale name with .UTF-8 on the end (if | |
276 | * the locale includes a character set specifier...) | |
277 | */ | |
278 | ||
279 | setlocale(LC_ALL, ""); | |
280 | ||
281 | #ifdef LC_TIME | |
282 | if ((lc_time = setlocale(LC_TIME, NULL)) == NULL) | |
283 | lc_time = setlocale(LC_ALL, NULL); | |
284 | ||
285 | if (lc_time) | |
286 | { | |
287 | strlcpy(new_lc_time, lc_time, sizeof(new_lc_time)); | |
288 | if ((charset = strchr(new_lc_time, '.')) == NULL) | |
289 | charset = new_lc_time + strlen(new_lc_time); | |
290 | ||
7e86f2f6 | 291 | strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time)); |
d09495fa | 292 | } |
293 | else | |
5a9febac | 294 | strlcpy(new_lc_time, "C", sizeof(new_lc_time)); |
d09495fa | 295 | |
296 | setlocale(LC_TIME, new_lc_time); | |
297 | #endif /* LC_TIME */ | |
07725fee | 298 | |
299 | /* | |
300 | * Initialize the default language info... | |
301 | */ | |
302 | ||
303 | cg = _cupsGlobals(); | |
304 | ||
305 | if (!cg->lang_default) | |
306 | cg->lang_default = cupsLangDefault(); | |
307 | ||
308 | /* | |
309 | * Transcode the command-line arguments from the locale charset to | |
310 | * UTF-8... | |
311 | */ | |
312 | ||
313 | if (cg->lang_default->encoding != CUPS_US_ASCII && | |
314 | cg->lang_default->encoding != CUPS_UTF8) | |
315 | { | |
316 | for (i = 1; argv[i]; i ++) | |
317 | { | |
318 | /* | |
319 | * Try converting from the locale charset to UTF-8... | |
320 | */ | |
321 | ||
322 | if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer), | |
323 | cg->lang_default->encoding) < 0) | |
324 | continue; | |
325 | ||
326 | /* | |
327 | * Save the new string if it differs from the original... | |
328 | */ | |
329 | ||
330 | if (strcmp(buffer, argv[i])) | |
331 | argv[i] = strdup(buffer); | |
332 | } | |
333 | } | |
d09495fa | 334 | } |