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