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