2 * "$Id: snprintf.c 9042 2010-03-24 00:45:34Z mike $"
4 * snprintf functions for CUPS.
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * _cups_vsnprintf() - Format a string into a fixed size buffer.
20 * _cups_snprintf() - Format a string into a fixed size buffer.
24 * Include necessary headers...
27 #include "string-private.h"
30 #ifndef HAVE_VSNPRINTF
32 * '_cups_vsnprintf()' - Format a string into a fixed size buffer.
35 int /* 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 */
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 */
57 * Loop through the format string, formatting as needed...
61 bufend = buffer + bufsize - 1;
73 if (bufptr && bufptr < bufend) *bufptr++ = *format;
78 else if (strchr(" -+#\'", *format))
89 * Get width from argument...
93 width = va_arg(ap, int);
95 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
102 while (isdigit(*format & 255))
104 if (tptr < (tformat + sizeof(tformat) - 1))
107 width = width * 10 + *format++ - '0';
113 if (tptr < (tformat + sizeof(tformat) - 1))
121 * Get precision from argument...
125 prec = va_arg(ap, int);
127 snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
128 tptr += strlen(tptr);
134 while (isdigit(*format & 255))
136 if (tptr < (tformat + sizeof(tformat) - 1))
139 prec = prec * 10 + *format++ - '0';
146 if (*format == 'l' && format[1] == 'l')
150 if (tptr < (tformat + sizeof(tformat) - 2))
158 else if (*format == 'h' || *format == 'l' || *format == 'L')
160 if (tptr < (tformat + sizeof(tformat) - 1))
169 if (tptr < (tformat + sizeof(tformat) - 1))
177 case 'E' : /* Floating point formats */
182 if ((width + 2) > sizeof(temp))
185 sprintf(temp, tformat, va_arg(ap, double));
187 bytes += (int)strlen(temp);
191 if ((bufptr + strlen(temp)) > bufend)
193 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
198 strcpy(bufptr, temp);
199 bufptr += strlen(temp);
204 case 'B' : /* Integer formats */
212 if ((width + 2) > sizeof(temp))
215 sprintf(temp, tformat, va_arg(ap, int));
217 bytes += (int)strlen(temp);
221 if ((bufptr + strlen(temp)) > bufend)
223 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
228 strcpy(bufptr, temp);
229 bufptr += strlen(temp);
234 case 'p' : /* Pointer value */
235 if ((width + 2) > sizeof(temp))
238 sprintf(temp, tformat, va_arg(ap, void *));
240 bytes += (int)strlen(temp);
244 if ((bufptr + strlen(temp)) > bufend)
246 strncpy(bufptr, temp, (size_t)(bufend - bufptr));
251 strcpy(bufptr, temp);
252 bufptr += strlen(temp);
257 case 'c' : /* Character or character array */
263 *bufptr++ = va_arg(ap, int);
266 if ((bufptr + width) > bufend)
267 width = (int)(bufend - bufptr);
269 memcpy(bufptr, va_arg(ap, char *), (size_t)width);
275 case 's' : /* String */
276 if ((s = va_arg(ap, char *)) == NULL)
279 slen = (int)strlen(s);
280 if (slen > width && prec != width)
287 if ((bufptr + width) > bufend)
288 width = (int)(bufend - bufptr);
295 strncpy(bufptr, s, (size_t)slen);
296 memset(bufptr + slen, ' ', (size_t)(width - slen));
300 memset(bufptr, ' ', (size_t)(width - slen));
301 strncpy(bufptr + width - slen, s, (size_t)slen);
308 case 'n' : /* Output number of chars so far */
309 *(va_arg(ap, int *)) = bytes;
317 if (bufptr && bufptr < bufend)
325 * Nul-terminate the string and return the number of characters needed.
332 #endif /* !HAVE_VSNPRINT */
335 #ifndef HAVE_SNPRINTF
337 * '_cups_snprintf()' - Format a string into a fixed size buffer.
340 int /* 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 */
346 int bytes; /* Number of bytes formatted */
347 va_list ap; /* Pointer to additional arguments */
350 va_start(ap, format);
351 bytes = vsnprintf(buffer, bufsize, format, ap);
356 #endif /* !HAVE_SNPRINTF */
360 * End of "$Id: snprintf.c 9042 2010-03-24 00:45:34Z mike $".