Coverage Report

Created: 2025-11-16 07:40

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