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