]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/snprintf.c
2 * snprintf functions for CUPS.
4 * Copyright © 2007-2019 by Apple Inc.
5 * Copyright © 1997-2007 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
12 * Include necessary headers...
15 #include "string-private.h"
18 #ifndef HAVE_VSNPRINTF
20 * '_cups_vsnprintf()' - Format a string into a fixed size buffer.
23 int /* O - Number of bytes formatted */
24 _cups_vsnprintf(char *buffer
, /* O - Output buffer */
25 size_t bufsize
, /* O - Size of output buffer */
26 const char *format
, /* I - printf-style format string */
27 va_list ap
) /* I - Pointer to additional arguments */
29 char *bufptr
, /* Pointer to position in buffer */
30 *bufend
, /* Pointer to end of buffer */
31 sign
, /* Sign of format width */
32 size
, /* Size character (h, l, L) */
33 type
; /* Format type character */
34 int width
, /* Width of field */
35 prec
; /* Number of characters of precision */
36 char tformat
[100], /* Temporary format string for sprintf() */
37 *tptr
, /* Pointer into temporary format */
38 temp
[1024]; /* Buffer for formatted numbers */
39 size_t templen
; /* Length of "temp" */
40 char *s
; /* Pointer to string */
41 int slen
; /* Length of string */
42 int bytes
; /* Total number of bytes needed */
46 * Loop through the format string, formatting as needed...
50 bufend
= buffer
+ bufsize
- 1;
62 if (bufptr
&& bufptr
< bufend
) *bufptr
++ = *format
;
67 else if (strchr(" -+#\'", *format
))
78 * Get width from argument...
82 width
= va_arg(ap
, int);
84 /* Note: Can't use snprintf here since we are implementing this function... */
85 sprintf(tptr
, "%d", width
);
92 while (isdigit(*format
& 255))
94 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
97 width
= width
* 10 + *format
++ - '0';
103 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
111 * Get precision from argument...
115 prec
= va_arg(ap
, int);
117 /* Note: Can't use snprintf here since we are implementing this function... */
118 sprintf(tptr
, "%d", prec
);
119 tptr
+= strlen(tptr
);
125 while (isdigit(*format
& 255))
127 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
130 prec
= prec
* 10 + *format
++ - '0';
137 if (*format
== 'l' && format
[1] == 'l')
141 if (tptr
< (tformat
+ sizeof(tformat
) - 2))
149 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
151 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
160 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
168 case 'E' : /* Floating point formats */
173 if ((width
+ 2) > sizeof(temp
))
176 /* Note: Can't use snprintf here since we are implementing this function... */
177 sprintf(temp
, tformat
, va_arg(ap
, double));
178 templen
= strlen(temp
);
180 bytes
+= (int)templen
;
184 if ((bufptr
+ templen
) > bufend
)
186 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
191 memcpy(bufptr
, temp
, templen
+ 1);
197 case 'B' : /* Integer formats */
205 if ((width
+ 2) > sizeof(temp
))
208 /* Note: Can't use snprintf here since we are implementing this function... */
209 sprintf(temp
, tformat
, va_arg(ap
, int));
210 templen
= strlen(temp
);
212 bytes
+= (int)templen
;
216 if ((bufptr
+ templen
) > bufend
)
218 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
223 memcpy(bufptr
, temp
, templen
+ 1);
229 case 'p' : /* Pointer value */
230 if ((width
+ 2) > sizeof(temp
))
233 /* Note: Can't use snprintf here since we are implementing this function... */
234 sprintf(temp
, tformat
, va_arg(ap
, void *));
235 templen
= strlen(temp
);
237 bytes
+= (int)templen
;
241 if ((bufptr
+ templen
) > bufend
)
243 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
248 memcpy(bufptr
, temp
, templen
+ 1);
254 case 'c' : /* Character or character array */
260 *bufptr
++ = va_arg(ap
, int);
263 if ((bufptr
+ width
) > bufend
)
264 width
= (int)(bufend
- bufptr
);
266 memcpy(bufptr
, va_arg(ap
, char *), (size_t)width
);
272 case 's' : /* String */
273 if ((s
= va_arg(ap
, char *)) == NULL
)
276 slen
= (int)strlen(s
);
277 if (slen
> width
&& prec
!= width
)
284 if ((bufptr
+ width
) > bufend
)
285 width
= (int)(bufend
- bufptr
);
292 memcpy(bufptr
, s
, (size_t)slen
);
293 memset(bufptr
+ slen
, ' ', (size_t)(width
- slen
));
297 memset(bufptr
, ' ', (size_t)(width
- slen
));
298 memcpy(bufptr
+ width
- slen
, s
, (size_t)slen
);
305 case 'n' : /* Output number of chars so far */
306 *(va_arg(ap
, int *)) = bytes
;
314 if (bufptr
&& bufptr
< bufend
)
322 * Nul-terminate the string and return the number of characters needed.
329 #endif /* !HAVE_VSNPRINT */
332 #ifndef HAVE_SNPRINTF
334 * '_cups_snprintf()' - Format a string into a fixed size buffer.
337 int /* 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 */
343 int bytes
; /* Number of bytes formatted */
344 va_list ap
; /* Pointer to additional arguments */
347 va_start(ap
, format
);
348 bytes
= vsnprintf(buffer
, bufsize
, format
, ap
);
353 #endif /* !HAVE_SNPRINTF */