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