]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/snprintf.c
e185fe38e4c2208be62254017468a3f1d2dc1d6d
[thirdparty/cups.git] / cups / snprintf.c
1 /*
2 * "$Id: snprintf.c,v 1.6 2002/03/01 19:53:30 mike Exp $"
3 *
4 * snprintf functions for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2002 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-3111 USA
19 *
20 * Voice: (301) 373-9603
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 * vsnprintf() - Format a string into a fixed size buffer.
29 * 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 * 'vsnprintf()' - Format a string into a fixed size buffer.
44 */
45
46 int /* O - Number of bytes formatted */
47 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 const char *bufformat; /* Start of format */
58 int width, /* Width of field */
59 prec; /* Number of characters of precision */
60 char tformat[100], /* Temporary format string for sprintf() */
61 temp[1024]; /* Buffer for formatted numbers */
62 int *chars; /* Pointer to integer for %p */
63 char *s; /* Pointer to string */
64 int slen; /* Length of string */
65
66
67 /*
68 * Loop through the format string, formatting as needed...
69 */
70
71 bufptr = buffer;
72 bufend = buffer + bufsize - 1;
73
74 while (*format && bufptr < bufend)
75 {
76 if (*format == '%')
77 {
78 bufformat = format;
79 format ++;
80
81 if (*format == '%')
82 {
83 *bufptr++ = *format++;
84 continue;
85 }
86 else if (strchr(" -+#\'", *format))
87 sign = *format++;
88 else
89 sign = 0;
90
91 width = 0;
92 while (isdigit(*format))
93 width = width * 10 + *format++ - '0';
94
95 if (*format == '.')
96 {
97 format ++;
98 prec = 0;
99
100 while (isdigit(*format))
101 prec = prec * 10 + *format++ - '0';
102 }
103 else
104 prec = -1;
105
106 if (*format == 'l' && format[1] == 'l')
107 {
108 size = 'L';
109 format += 2;
110 }
111 else if (*format == 'h' || *format == 'l' || *format == 'L')
112 size = *format++;
113
114 if (!*format)
115 break;
116
117 type = *format++;
118
119 switch (type)
120 {
121 case 'E' : /* Floating point formats */
122 case 'G' :
123 case 'e' :
124 case 'f' :
125 case 'g' :
126 if ((format - bufformat + 1) > sizeof(tformat) ||
127 (width + 2) > sizeof(temp))
128 break;
129
130 strncpy(tformat, bufformat, format - bufformat);
131 tformat[format - bufformat] = '\0';
132
133 sprintf(temp, tformat, va_arg(ap, double));
134
135 if ((bufptr + strlen(temp)) > bufend)
136 {
137 strncpy(bufptr, temp, bufend - bufptr);
138 bufptr = bufend;
139 break;
140 }
141 else
142 {
143 strcpy(bufptr, temp);
144 bufptr += strlen(temp);
145 }
146 break;
147
148 case 'B' : /* Integer formats */
149 case 'X' :
150 case 'b' :
151 case 'd' :
152 case 'i' :
153 case 'o' :
154 case 'u' :
155 case 'x' :
156 if ((format - bufformat + 1) > sizeof(tformat) ||
157 (width + 2) > sizeof(temp))
158 break;
159
160 strncpy(tformat, bufformat, format - bufformat);
161 tformat[format - bufformat] = '\0';
162
163 sprintf(temp, tformat, va_arg(ap, int));
164
165 if ((bufptr + strlen(temp)) > bufend)
166 {
167 strncpy(bufptr, temp, bufend - bufptr);
168 bufptr = bufend;
169 break;
170 }
171 else
172 {
173 strcpy(bufptr, temp);
174 bufptr += strlen(temp);
175 }
176 break;
177
178 case 'p' : /* Pointer value */
179 if ((chars = va_arg(ap, int *)) != NULL)
180 *chars = bufptr - buffer;
181 break;
182
183 case 'c' : /* Character or character array */
184 if (width <= 1)
185 *bufptr++ = va_arg(ap, int);
186 else
187 {
188 if ((bufptr + width) > bufend)
189 width = bufend - bufptr;
190
191 memcpy(bufptr, va_arg(ap, char *), width);
192 bufptr += width;
193 }
194 break;
195
196 case 's' : /* String */
197 if ((s = va_arg(ap, char *)) == NULL)
198 s = "(null)";
199
200 slen = strlen(s);
201 if (slen > width && prec != width)
202 width = slen;
203
204 if ((bufptr + width) > bufend)
205 width = bufend - bufptr;
206
207 if (slen > width)
208 slen = width;
209
210 if (sign == '-')
211 {
212 strncpy(bufptr, s, slen);
213 memset(bufptr + slen, ' ', width - slen);
214 }
215 else
216 {
217 memset(bufptr, ' ', width - slen);
218 strncpy(bufptr + width - slen, s, slen);
219 }
220
221 bufptr += width;
222 break;
223
224 case 'n' : /* Output number of chars so far */
225 if ((format - bufformat + 1) > sizeof(tformat) ||
226 (width + 2) > sizeof(temp))
227 break;
228
229 strncpy(tformat, bufformat, format - bufformat);
230 tformat[format - bufformat] = '\0';
231
232 sprintf(temp, tformat, va_arg(ap, int));
233
234 if ((bufptr + strlen(temp)) > bufend)
235 {
236 strncpy(bufptr, temp, bufend - bufptr);
237 bufptr = bufend;
238 break;
239 }
240 else
241 {
242 strcpy(bufptr, temp);
243 bufptr += strlen(temp);
244 }
245 break;
246 }
247 }
248 else
249 *bufptr++ = *format++;
250 }
251
252 /*
253 * Nul-terminate the string and return the number of characters in it.
254 */
255
256 *bufptr = '\0';
257 return (bufptr - buffer);
258 }
259 #endif /* !HAVE_VSNPRINT */
260
261
262 #ifndef HAVE_SNPRINTF
263 /*
264 * 'snprintf()' - Format a string into a fixed size buffer.
265 */
266
267 int /* O - Number of bytes formatted */
268 snprintf(char *buffer, /* O - Output buffer */
269 size_t bufsize, /* O - Size of output buffer */
270 const char *format, /* I - printf-style format string */
271 ...) /* I - Additional arguments as needed */
272 {
273 int bytes; /* Number of bytes formatted */
274 va_list ap; /* Pointer to additional arguments */
275
276
277 va_start(ap, format);
278 bytes = vsnprintf(buffer, bufsize, format, ap);
279 va_end(ap);
280
281 return (bytes);
282 }
283 #endif /* !HAVE_SNPRINTF */
284
285
286 /*
287 * End of "$Id: snprintf.c,v 1.6 2002/03/01 19:53:30 mike Exp $".
288 */
289