]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/snprintf.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / cups / snprintf.c
CommitLineData
ef416fc2 1/*
503b54c9 2 * snprintf functions for CUPS.
ef416fc2 3 *
503b54c9
MS
4 * Copyright 2007-2013 by Apple Inc.
5 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 6 *
503b54c9
MS
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
57b7b66b 11 * missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 12 *
503b54c9 13 * This file is subject to the Apple OS-Developed Software exception.
ef416fc2 14 */
15
16/*
17 * Include necessary headers...
18 */
19
71e16022 20#include "string-private.h"
ef416fc2 21
22
23#ifndef HAVE_VSNPRINTF
24/*
25 * '_cups_vsnprintf()' - Format a string into a fixed size buffer.
26 */
27
28int /* O - Number of bytes formatted */
29_cups_vsnprintf(char *buffer, /* O - Output buffer */
30 size_t bufsize, /* O - Size of output buffer */
31 const char *format, /* I - printf-style format string */
32 va_list ap) /* I - Pointer to additional arguments */
33{
34 char *bufptr, /* Pointer to position in buffer */
35 *bufend, /* Pointer to end of buffer */
36 sign, /* Sign of format width */
37 size, /* Size character (h, l, L) */
38 type; /* Format type character */
39 int width, /* Width of field */
40 prec; /* Number of characters of precision */
41 char tformat[100], /* Temporary format string for sprintf() */
42 *tptr, /* Pointer into temporary format */
43 temp[1024]; /* Buffer for formatted numbers */
5a9febac 44 size_t templen; /* Length of "temp" */
ef416fc2 45 char *s; /* Pointer to string */
46 int slen; /* Length of string */
47 int bytes; /* Total number of bytes needed */
48
49
50 /*
51 * Loop through the format string, formatting as needed...
52 */
53
54 bufptr = buffer;
55 bufend = buffer + bufsize - 1;
56 bytes = 0;
57
58 while (*format)
59 {
60 if (*format == '%')
61 {
62 tptr = tformat;
63 *tptr++ = *format++;
64
65 if (*format == '%')
66 {
67 if (bufptr && bufptr < bufend) *bufptr++ = *format;
68 bytes ++;
69 format ++;
70 continue;
71 }
72 else if (strchr(" -+#\'", *format))
73 {
74 *tptr++ = *format;
75 sign = *format++;
76 }
77 else
78 sign = 0;
79
80 if (*format == '*')
81 {
f301802f 82 /*
83 * Get width from argument...
84 */
85
ef416fc2 86 format ++;
87 width = va_arg(ap, int);
88
89 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
90 tptr += strlen(tptr);
91 }
92 else
93 {
94 width = 0;
95
96 while (isdigit(*format & 255))
97 {
98 if (tptr < (tformat + sizeof(tformat) - 1))
99 *tptr++ = *format;
100
101 width = width * 10 + *format++ - '0';
102 }
103 }
104
105 if (*format == '.')
106 {
107 if (tptr < (tformat + sizeof(tformat) - 1))
108 *tptr++ = *format;
109
110 format ++;
111
112 if (*format == '*')
113 {
f301802f 114 /*
115 * Get precision from argument...
116 */
117
ef416fc2 118 format ++;
119 prec = va_arg(ap, int);
120
121 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
122 tptr += strlen(tptr);
123 }
124 else
125 {
126 prec = 0;
127
128 while (isdigit(*format & 255))
129 {
130 if (tptr < (tformat + sizeof(tformat) - 1))
131 *tptr++ = *format;
132
133 prec = prec * 10 + *format++ - '0';
134 }
135 }
136 }
137 else
138 prec = -1;
139
140 if (*format == 'l' && format[1] == 'l')
141 {
142 size = 'L';
143
144 if (tptr < (tformat + sizeof(tformat) - 2))
145 {
146 *tptr++ = 'l';
147 *tptr++ = 'l';
148 }
149
150 format += 2;
151 }
152 else if (*format == 'h' || *format == 'l' || *format == 'L')
153 {
154 if (tptr < (tformat + sizeof(tformat) - 1))
155 *tptr++ = *format;
156
157 size = *format++;
158 }
159
160 if (!*format)
161 break;
162
163 if (tptr < (tformat + sizeof(tformat) - 1))
164 *tptr++ = *format;
165
166 type = *format++;
167 *tptr = '\0';
168
169 switch (type)
170 {
171 case 'E' : /* Floating point formats */
172 case 'G' :
173 case 'e' :
174 case 'f' :
175 case 'g' :
176 if ((width + 2) > sizeof(temp))
177 break;
178
179 sprintf(temp, tformat, va_arg(ap, double));
5a9febac 180 templen = strlen(temp):
ef416fc2 181
5a9febac 182 bytes += (int)templen;
ef416fc2 183
184 if (bufptr)
185 {
5a9febac 186 if ((bufptr + templen) > bufend)
ef416fc2 187 {
5a9febac 188 strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
ef416fc2 189 bufptr = bufend;
190 }
191 else
192 {
5a9febac
MS
193 memcpy(bufptr, temp, templen + 1);
194 bufptr += templen;
ef416fc2 195 }
196 }
197 break;
198
199 case 'B' : /* Integer formats */
200 case 'X' :
201 case 'b' :
202 case 'd' :
203 case 'i' :
204 case 'o' :
205 case 'u' :
206 case 'x' :
207 if ((width + 2) > sizeof(temp))
208 break;
209
210 sprintf(temp, tformat, va_arg(ap, int));
5a9febac 211 templen = strlen(temp):
ef416fc2 212
5a9febac 213 bytes += (int)templen;
ef416fc2 214
215 if (bufptr)
216 {
5a9febac 217 if ((bufptr + templen) > bufend)
ef416fc2 218 {
5a9febac 219 strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
ef416fc2 220 bufptr = bufend;
221 }
222 else
223 {
5a9febac
MS
224 memcpy(bufptr, temp, templen + 1);
225 bufptr += templen;
ef416fc2 226 }
227 }
228 break;
229
230 case 'p' : /* Pointer value */
231 if ((width + 2) > sizeof(temp))
232 break;
233
234 sprintf(temp, tformat, va_arg(ap, void *));
5a9febac 235 templen = strlen(temp):
ef416fc2 236
5a9febac 237 bytes += (int)templen;
ef416fc2 238
239 if (bufptr)
240 {
5a9febac 241 if ((bufptr + templen) > bufend)
ef416fc2 242 {
5a9febac 243 strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
ef416fc2 244 bufptr = bufend;
245 }
246 else
247 {
5a9febac
MS
248 memcpy(bufptr, temp, templen + 1);
249 bufptr += templen;
ef416fc2 250 }
251 }
252 break;
253
254 case 'c' : /* Character or character array */
255 bytes += width;
256
257 if (bufptr)
258 {
259 if (width <= 1)
260 *bufptr++ = va_arg(ap, int);
261 else
262 {
263 if ((bufptr + width) > bufend)
b86bc4cf 264 width = (int)(bufend - bufptr);
ef416fc2 265
266 memcpy(bufptr, va_arg(ap, char *), (size_t)width);
267 bufptr += width;
268 }
269 }
270 break;
271
272 case 's' : /* String */
273 if ((s = va_arg(ap, char *)) == NULL)
274 s = "(null)";
275
b86bc4cf 276 slen = (int)strlen(s);
ef416fc2 277 if (slen > width && prec != width)
278 width = slen;
279
280 bytes += width;
281
282 if (bufptr)
283 {
284 if ((bufptr + width) > bufend)
b86bc4cf 285 width = (int)(bufend - bufptr);
ef416fc2 286
287 if (slen > width)
288 slen = width;
289
290 if (sign == '-')
291 {
db8b865d 292 memcpy(bufptr, s, (size_t)slen);
ef416fc2 293 memset(bufptr + slen, ' ', (size_t)(width - slen));
294 }
295 else
296 {
297 memset(bufptr, ' ', (size_t)(width - slen));
db8b865d 298 memcpy(bufptr + width - slen, s, (size_t)slen);
ef416fc2 299 }
300
301 bufptr += width;
302 }
303 break;
304
305 case 'n' : /* Output number of chars so far */
306 *(va_arg(ap, int *)) = bytes;
307 break;
308 }
309 }
310 else
311 {
312 bytes ++;
313
314 if (bufptr && bufptr < bufend)
315 *bufptr++ = *format;
316
317 format ++;
318 }
319 }
320
321 /*
322 * Nul-terminate the string and return the number of characters needed.
323 */
324
325 *bufptr = '\0';
326
327 return (bytes);
328}
329#endif /* !HAVE_VSNPRINT */
330
331
332#ifndef HAVE_SNPRINTF
333/*
334 * '_cups_snprintf()' - Format a string into a fixed size buffer.
335 */
336
337int /* O - Number of bytes formatted */
338_cups_snprintf(char *buffer, /* O - Output buffer */
339 size_t bufsize, /* O - Size of output buffer */
340 const char *format, /* I - printf-style format string */
341 ...) /* I - Additional arguments as needed */
342{
343 int bytes; /* Number of bytes formatted */
344 va_list ap; /* Pointer to additional arguments */
345
346
347 va_start(ap, format);
348 bytes = vsnprintf(buffer, bufsize, format, ap);
349 va_end(ap);
350
351 return (bytes);
352}
353#endif /* !HAVE_SNPRINTF */