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