]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/langprintf.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / cups / langprintf.c
1 /*
2 * Localized printf/puts functions for CUPS.
3 *
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 2002-2007 by Easy Software Products.
6 *
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8 */
9
10 /*
11 * Include necessary headers...
12 */
13
14 #include "cups-private.h"
15
16
17 /*
18 * '_cupsLangPrintError()' - Print a message followed by a standard error.
19 */
20
21 void
22 _cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */
23 const char *message)/* I - Message */
24 {
25 ssize_t bytes; /* Number of bytes formatted */
26 int last_errno; /* Last error */
27 char buffer[2048], /* Message buffer */
28 *bufptr, /* Pointer into buffer */
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
59 if (prefix)
60 {
61 snprintf(buffer, sizeof(buffer), "%s:", prefix);
62 bufptr = buffer + strlen(buffer);
63 }
64 else
65 bufptr = buffer;
66
67 snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer),
68 /* TRANSLATORS: Message is "subject: error" */
69 _cupsLangString(cg->lang_default, _("%s: %s")),
70 _cupsLangString(cg->lang_default, message), strerror(last_errno));
71 strlcat(buffer, "\n", sizeof(buffer));
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)
81 fwrite(output, 1, (size_t)bytes, stderr);
82 }
83
84
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 {
96 ssize_t bytes; /* Number of bytes formatted */
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)
138 return ((int)fwrite(output, 1, (size_t)bytes, fp));
139 else
140 return ((int)bytes);
141 }
142
143
144 /*
145 * '_cupsLangPrintf()' - Print a formatted message string to a file.
146 */
147
148 int /* O - Number of bytes written */
149 _cupsLangPrintf(FILE *fp, /* I - File to write to */
150 const char *message, /* I - Message string to use */
151 ...) /* I - Additional arguments as needed */
152 {
153 ssize_t bytes; /* Number of bytes formatted */
154 char buffer[2048], /* Message buffer */
155 output[8192]; /* Output buffer */
156 va_list ap; /* Pointer to additional arguments */
157 _cups_globals_t *cg; /* Global data */
158
159
160 /*
161 * Range check...
162 */
163
164 if (!fp || !message)
165 return (-1);
166
167 cg = _cupsGlobals();
168
169 if (!cg->lang_default)
170 cg->lang_default = cupsLangDefault();
171
172 /*
173 * Format the string...
174 */
175
176 va_start(ap, message);
177 vsnprintf(buffer, sizeof(buffer) - 1,
178 _cupsLangString(cg->lang_default, message), ap);
179 va_end(ap);
180
181 strlcat(buffer, "\n", sizeof(buffer));
182
183 /*
184 * Transcode to the destination charset...
185 */
186
187 bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
188 cg->lang_default->encoding);
189
190 /*
191 * Write the string and return the number of bytes written...
192 */
193
194 if (bytes > 0)
195 return ((int)fwrite(output, 1, (size_t)bytes, fp));
196 else
197 return ((int)bytes);
198 }
199
200
201 /*
202 * '_cupsLangPuts()' - Print a static message string to a file.
203 */
204
205 int /* O - Number of bytes written */
206 _cupsLangPuts(FILE *fp, /* I - File to write to */
207 const char *message) /* I - Message string to use */
208 {
209 ssize_t bytes; /* Number of bytes formatted */
210 char output[8192]; /* Message buffer */
211 _cups_globals_t *cg; /* Global data */
212
213
214 /*
215 * Range check...
216 */
217
218 if (!fp || !message)
219 return (-1);
220
221 cg = _cupsGlobals();
222
223 if (!cg->lang_default)
224 cg->lang_default = cupsLangDefault();
225
226 /*
227 * Transcode to the destination charset...
228 */
229
230 bytes = cupsUTF8ToCharset(output,
231 (cups_utf8_t *)_cupsLangString(cg->lang_default,
232 message),
233 sizeof(output) - 4, cg->lang_default->encoding);
234 bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", (int)(sizeof(output) - (size_t)bytes), cg->lang_default->encoding);
235
236 /*
237 * Write the string and return the number of bytes written...
238 */
239
240 if (bytes > 0)
241 return ((int)fwrite(output, 1, (size_t)bytes, fp));
242 else
243 return ((int)bytes);
244 }
245
246
247 /*
248 * '_cupsSetLocale()' - Set the current locale and transcode the command-line.
249 */
250
251 void
252 _cupsSetLocale(char *argv[]) /* IO - Command-line arguments */
253 {
254 int i; /* Looping var */
255 char buffer[8192]; /* Command-line argument buffer */
256 _cups_globals_t *cg; /* Global data */
257 #ifdef LC_TIME
258 const char *lc_time; /* Current LC_TIME value */
259 char new_lc_time[255], /* New LC_TIME value */
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
285 strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time));
286 }
287 else
288 strlcpy(new_lc_time, "C", sizeof(new_lc_time));
289
290 setlocale(LC_TIME, new_lc_time);
291 #endif /* LC_TIME */
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 }
328 }