]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/snprintf.c
Remove svn:keywords since they cause svn_load_dirs.pl to complain about every file.
[thirdparty/cups.git] / cups / snprintf.c
CommitLineData
ef416fc2 1/*
c07d5b2d 2 * "$Id: snprintf.c 177 2006-06-21 00:20:03Z jlovell $"
ef416fc2 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
46int /* 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 {
f301802f 99 /*
100 * Get width from argument...
101 */
102
ef416fc2 103 format ++;
104 width = va_arg(ap, int);
105
106 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
107 tptr += strlen(tptr);
108 }
109 else
110 {
111 width = 0;
112
113 while (isdigit(*format & 255))
114 {
115 if (tptr < (tformat + sizeof(tformat) - 1))
116 *tptr++ = *format;
117
118 width = width * 10 + *format++ - '0';
119 }
120 }
121
122 if (*format == '.')
123 {
124 if (tptr < (tformat + sizeof(tformat) - 1))
125 *tptr++ = *format;
126
127 format ++;
128
129 if (*format == '*')
130 {
f301802f 131 /*
132 * Get precision from argument...
133 */
134
ef416fc2 135 format ++;
136 prec = va_arg(ap, int);
137
138 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
139 tptr += strlen(tptr);
140 }
141 else
142 {
143 prec = 0;
144
145 while (isdigit(*format & 255))
146 {
147 if (tptr < (tformat + sizeof(tformat) - 1))
148 *tptr++ = *format;
149
150 prec = prec * 10 + *format++ - '0';
151 }
152 }
153 }
154 else
155 prec = -1;
156
157 if (*format == 'l' && format[1] == 'l')
158 {
159 size = 'L';
160
161 if (tptr < (tformat + sizeof(tformat) - 2))
162 {
163 *tptr++ = 'l';
164 *tptr++ = 'l';
165 }
166
167 format += 2;
168 }
169 else if (*format == 'h' || *format == 'l' || *format == 'L')
170 {
171 if (tptr < (tformat + sizeof(tformat) - 1))
172 *tptr++ = *format;
173
174 size = *format++;
175 }
176
177 if (!*format)
178 break;
179
180 if (tptr < (tformat + sizeof(tformat) - 1))
181 *tptr++ = *format;
182
183 type = *format++;
184 *tptr = '\0';
185
186 switch (type)
187 {
188 case 'E' : /* Floating point formats */
189 case 'G' :
190 case 'e' :
191 case 'f' :
192 case 'g' :
193 if ((width + 2) > sizeof(temp))
194 break;
195
196 sprintf(temp, tformat, va_arg(ap, double));
197
198 bytes += strlen(temp);
199
200 if (bufptr)
201 {
202 if ((bufptr + strlen(temp)) > bufend)
203 {
204 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
205 bufptr = bufend;
206 }
207 else
208 {
209 strcpy(bufptr, temp);
210 bufptr += strlen(temp);
211 }
212 }
213 break;
214
215 case 'B' : /* Integer formats */
216 case 'X' :
217 case 'b' :
218 case 'd' :
219 case 'i' :
220 case 'o' :
221 case 'u' :
222 case 'x' :
223 if ((width + 2) > sizeof(temp))
224 break;
225
226 sprintf(temp, tformat, va_arg(ap, int));
227
228 bytes += strlen(temp);
229
230 if (bufptr)
231 {
232 if ((bufptr + strlen(temp)) > bufend)
233 {
234 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
235 bufptr = bufend;
236 }
237 else
238 {
239 strcpy(bufptr, temp);
240 bufptr += strlen(temp);
241 }
242 }
243 break;
244
245 case 'p' : /* Pointer value */
246 if ((width + 2) > sizeof(temp))
247 break;
248
249 sprintf(temp, tformat, va_arg(ap, void *));
250
251 bytes += strlen(temp);
252
253 if (bufptr)
254 {
255 if ((bufptr + strlen(temp)) > bufend)
256 {
257 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
258 bufptr = bufend;
259 }
260 else
261 {
262 strcpy(bufptr, temp);
263 bufptr += strlen(temp);
264 }
265 }
266 break;
267
268 case 'c' : /* Character or character array */
269 bytes += width;
270
271 if (bufptr)
272 {
273 if (width <= 1)
274 *bufptr++ = va_arg(ap, int);
275 else
276 {
277 if ((bufptr + width) > bufend)
278 width = bufend - bufptr;
279
280 memcpy(bufptr, va_arg(ap, char *), (size_t)width);
281 bufptr += width;
282 }
283 }
284 break;
285
286 case 's' : /* String */
287 if ((s = va_arg(ap, char *)) == NULL)
288 s = "(null)";
289
290 slen = strlen(s);
291 if (slen > width && prec != width)
292 width = slen;
293
294 bytes += width;
295
296 if (bufptr)
297 {
298 if ((bufptr + width) > bufend)
299 width = bufend - bufptr;
300
301 if (slen > width)
302 slen = width;
303
304 if (sign == '-')
305 {
306 strncpy(bufptr, s, (size_t)slen);
307 memset(bufptr + slen, ' ', (size_t)(width - slen));
308 }
309 else
310 {
311 memset(bufptr, ' ', (size_t)(width - slen));
312 strncpy(bufptr + width - slen, s, (size_t)slen);
313 }
314
315 bufptr += width;
316 }
317 break;
318
319 case 'n' : /* Output number of chars so far */
320 *(va_arg(ap, int *)) = bytes;
321 break;
322 }
323 }
324 else
325 {
326 bytes ++;
327
328 if (bufptr && bufptr < bufend)
329 *bufptr++ = *format;
330
331 format ++;
332 }
333 }
334
335 /*
336 * Nul-terminate the string and return the number of characters needed.
337 */
338
339 *bufptr = '\0';
340
341 return (bytes);
342}
343#endif /* !HAVE_VSNPRINT */
344
345
346#ifndef HAVE_SNPRINTF
347/*
348 * '_cups_snprintf()' - Format a string into a fixed size buffer.
349 */
350
351int /* O - Number of bytes formatted */
352_cups_snprintf(char *buffer, /* O - Output buffer */
353 size_t bufsize, /* O - Size of output buffer */
354 const char *format, /* I - printf-style format string */
355 ...) /* I - Additional arguments as needed */
356{
357 int bytes; /* Number of bytes formatted */
358 va_list ap; /* Pointer to additional arguments */
359
360
361 va_start(ap, format);
362 bytes = vsnprintf(buffer, bufsize, format, ap);
363 va_end(ap);
364
365 return (bytes);
366}
367#endif /* !HAVE_SNPRINTF */
368
369
370/*
c07d5b2d 371 * End of "$Id: snprintf.c 177 2006-06-21 00:20:03Z jlovell $".
ef416fc2 372 */
373