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