]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/snprintf.c
2 * snprintf functions for CUPS.
4 * Copyright © 2021 by OpenPrinting
5 * Copyright © 2007-2019 by Apple Inc.
6 * Copyright © 1997-2007 by Easy Software Products.
8 * Licensed under Apache License v2.0. See the file "LICENSE" for more
13 * Include necessary headers...
16 #include "string-private.h"
19 #ifndef HAVE_VSNPRINTF
21 * '_cups_vsnprintf()' - Format a string into a fixed size buffer.
24 int /* O - Number of bytes formatted */
25 _cups_vsnprintf(char *buffer
, /* O - Output buffer */
26 size_t bufsize
, /* O - Size of output buffer */
27 const char *format
, /* I - printf-style format string */
28 va_list ap
) /* I - Pointer to additional arguments */
30 char *bufptr
, /* Pointer to position in buffer */
31 *bufend
, /* Pointer to end of buffer */
32 sign
, /* Sign of format width */
33 size
, /* Size character (h, l, L) */
34 type
; /* Format type character */
35 int width
, /* Width of field */
36 prec
; /* Number of characters of precision */
37 char tformat
[100], /* Temporary format string for sprintf() */
38 *tptr
, /* Pointer into temporary format */
39 temp
[1024]; /* Buffer for formatted numbers */
40 size_t templen
; /* Length of "temp" */
41 char *s
; /* Pointer to string */
42 int slen
; /* Length of string */
43 int bytes
; /* Total number of bytes needed */
47 * Loop through the format string, formatting as needed...
51 bufend
= buffer
+ bufsize
- 1;
63 if (bufptr
&& bufptr
< bufend
) *bufptr
++ = *format
;
68 else if (strchr(" -+#\'", *format
))
79 * Get width from argument...
83 width
= va_arg(ap
, int);
85 /* Note: Can't use snprintf here since we are implementing this function... */
86 sprintf(tptr
, "%d", width
);
93 while (isdigit(*format
& 255))
95 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
98 width
= width
* 10 + *format
++ - '0';
104 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
112 * Get precision from argument...
116 prec
= va_arg(ap
, int);
118 /* Note: Can't use snprintf here since we are implementing this function... */
119 sprintf(tptr
, "%d", prec
);
120 tptr
+= strlen(tptr
);
126 while (isdigit(*format
& 255))
128 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
131 prec
= prec
* 10 + *format
++ - '0';
138 if (*format
== 'l' && format
[1] == 'l')
142 if (tptr
< (tformat
+ sizeof(tformat
) - 2))
150 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
152 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
161 if (tptr
< (tformat
+ sizeof(tformat
) - 1))
169 case 'E' : /* Floating point formats */
174 if ((width
+ 2) > sizeof(temp
))
177 /* Note: Can't use snprintf here since we are implementing this function... */
178 sprintf(temp
, tformat
, va_arg(ap
, double));
179 templen
= strlen(temp
);
181 bytes
+= (int)templen
;
185 if ((bufptr
+ templen
) > bufend
)
187 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
192 memcpy(bufptr
, temp
, templen
+ 1);
198 case 'B' : /* Integer formats */
206 if ((width
+ 2) > sizeof(temp
))
209 /* Note: Can't use snprintf here since we are implementing this function... */
210 sprintf(temp
, tformat
, va_arg(ap
, int));
211 templen
= strlen(temp
);
213 bytes
+= (int)templen
;
217 if ((bufptr
+ templen
) > bufend
)
219 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
224 memcpy(bufptr
, temp
, templen
+ 1);
230 case 'p' : /* Pointer value */
231 if ((width
+ 2) > sizeof(temp
))
234 /* Note: Can't use snprintf here since we are implementing this function... */
235 sprintf(temp
, tformat
, va_arg(ap
, void *));
236 templen
= strlen(temp
);
238 bytes
+= (int)templen
;
242 if ((bufptr
+ templen
) > bufend
)
244 strlcpy(bufptr
, temp
, (size_t)(bufend
- bufptr
));
249 memcpy(bufptr
, temp
, templen
+ 1);
255 case 'c' : /* Character or character array */
261 *bufptr
++ = va_arg(ap
, int);
264 if ((bufptr
+ width
) > bufend
)
265 width
= (int)(bufend
- bufptr
);
267 memcpy(bufptr
, va_arg(ap
, char *), (size_t)width
);
273 case 's' : /* String */
274 if ((s
= va_arg(ap
, char *)) == NULL
)
277 slen
= (int)strlen(s
);
278 if (slen
> width
&& prec
!= width
)
285 if ((bufptr
+ width
) > bufend
)
286 width
= (int)(bufend
- bufptr
);
293 memcpy(bufptr
, s
, (size_t)slen
);
294 memset(bufptr
+ slen
, ' ', (size_t)(width
- slen
));
298 memset(bufptr
, ' ', (size_t)(width
- slen
));
299 memcpy(bufptr
+ width
- slen
, s
, (size_t)slen
);
306 case 'n' : /* Output number of chars so far */
307 *(va_arg(ap
, int *)) = bytes
;
315 if (bufptr
&& bufptr
< bufend
)
323 * Nul-terminate the string and return the number of characters needed.
331 #endif /* !HAVE_VSNPRINT */
334 #ifndef HAVE_SNPRINTF
336 * '_cups_snprintf()' - Format a string into a fixed size buffer.
339 int /* O - Number of bytes formatted */
340 _cups_snprintf(char *buffer
, /* O - Output buffer */
341 size_t bufsize
, /* O - Size of output buffer */
342 const char *format
, /* I - printf-style format string */
343 ...) /* I - Additional arguments as needed */
345 int bytes
; /* Number of bytes formatted */
346 va_list ap
; /* Pointer to additional arguments */
349 va_start(ap
, format
);
350 bytes
= vsnprintf(buffer
, bufsize
, format
, ap
);
355 #endif /* !HAVE_SNPRINTF */