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