source: rtems-graphics-toolkit/fltk-1.1.10/src/vsnprintf.c @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * "$Id$"
3 *
4 * snprintf() and vsnprintf() functions for the Fast Light Tool Kit (FLTK).
5 *
6 * Copyright 1998-2007 by Bill Spitzak and others.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA.
22 *
23 * Please report all bugs and problems on the following page:
24 *
25 *     http://www.fltk.org/str.php
26 */
27
28#include <stdio.h>
29#include "flstring.h"
30
31#ifdef HAVE_SYS_STDTYPES_H
32#  include <sys/stdtypes.h>
33#endif /* HAVE_SYS_STDTYPES_H */
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) {
40  char          *bufptr,                /* Pointer to position in buffer */
41                *bufend,                /* Pointer to end of buffer */
42                sign,                   /* Sign of format width */
43                size,                   /* Size character (h, l, L) */
44                type;                   /* Format type character */
45  int           width,                  /* Width of field */
46                prec;                   /* Number of characters of precision */
47  char          tformat[100],           /* Temporary format string for sprintf() */
48                *tptr,                  /* Pointer into temporary format */
49                temp[1024];             /* Buffer for formatted numbers */
50  char          *s;                     /* Pointer to string */
51  int           slen;                   /* Length of string */
52  int           bytes;                  /* Total number of bytes needed */
53
54
55 /*
56  * Loop through the format string, formatting as needed...
57  */
58
59  bufptr = buffer;
60  bufend = buffer + bufsize - 1;
61  bytes  = 0;
62
63  while (*format) {
64    if (*format == '%') {
65      tptr = tformat;
66      *tptr++ = *format++;
67
68      if (*format == '%') {
69        if (bufptr && bufptr < bufend) *bufptr++ = *format;
70        bytes ++;
71        format ++;
72        continue;
73      } else if (strchr(" -+#\'", *format)) {
74        *tptr++ = *format;
75        sign = *format++;
76      } else sign = 0;
77
78      if (*format == '*') {
79        /* Get width from argument... */
80        format ++;
81        width = va_arg(ap, int);
82        snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width);
83        tptr += strlen(tptr);
84      } else {
85        width = 0;
86        while (isdigit(*format & 255)) {
87          if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
88          width = width * 10 + *format++ - '0';
89        }
90      }
91
92      if (*format == '.') {
93        if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
94        format ++;
95
96        if (*format == '*') {
97          /* Get precision from argument... */
98          format ++;
99          prec = va_arg(ap, int);
100          snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec);
101          tptr += strlen(tptr);
102        } else {
103          prec = 0;
104          while (isdigit(*format & 255)) {
105            if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
106            prec = prec * 10 + *format++ - '0';
107          }
108        }
109      } else prec = -1;
110
111      size = '\0';
112
113      if (*format == 'l' && format[1] == 'l') {
114        size = 'L';
115        if (tptr < (tformat + sizeof(tformat) - 2)) {
116          *tptr++ = 'l';
117          *tptr++ = 'l';
118        }
119        format += 2;
120      } else if (*format == 'h' || *format == 'l' || *format == 'L') {
121        if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
122        size = *format++;
123      }
124
125      if (!*format) break;
126
127      if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format;
128      type  = *format++;
129      *tptr = '\0';
130
131      switch (type) {
132        case 'E' : /* Floating point formats */
133        case 'G' :
134        case 'e' :
135        case 'f' :
136        case 'g' :
137          if ((width + 2) > sizeof(temp)) break;
138
139          sprintf(temp, tformat, va_arg(ap, double));
140
141          bytes += strlen(temp);
142
143          if (bufptr) {
144            if ((bufptr + strlen(temp)) > bufend) {
145              strncpy(bufptr, temp, (size_t)(bufend - bufptr));
146              bufptr = bufend;
147            } else {
148              strcpy(bufptr, temp);
149              bufptr += strlen(temp);
150            }
151          }
152          break;
153
154        case 'B' : /* Integer formats */
155        case 'X' :
156        case 'b' :
157        case 'd' :
158        case 'i' :
159        case 'o' :
160        case 'u' :
161        case 'x' :
162          if ((width + 2) > sizeof(temp)) break;
163
164#ifdef HAVE_LONG_LONG
165          if (size == 'L')
166            sprintf(temp, tformat, va_arg(ap, long long));
167          else
168#endif /* HAVE_LONG_LONG */
169          if (size == 'l')
170            sprintf(temp, tformat, va_arg(ap, long));
171          else
172            sprintf(temp, tformat, va_arg(ap, int));
173
174          bytes += strlen(temp);
175
176          if (bufptr) {
177            if ((bufptr + strlen(temp)) > bufend) {
178              strncpy(bufptr, temp, (size_t)(bufend - bufptr));
179              bufptr = bufend;
180            } else {
181              strcpy(bufptr, temp);
182              bufptr += strlen(temp);
183            }
184          }
185          break;
186           
187        case 'p' : /* Pointer value */
188          if ((width + 2) > sizeof(temp)) break;
189
190          sprintf(temp, tformat, va_arg(ap, void *));
191
192          bytes += strlen(temp);
193
194          if (bufptr) {
195            if ((bufptr + strlen(temp)) > bufend) {
196              strncpy(bufptr, temp, (size_t)(bufend - bufptr));
197              bufptr = bufend;
198            } else {
199              strcpy(bufptr, temp);
200              bufptr += strlen(temp);
201            }
202          }
203          break;
204
205        case 'c' : /* Character or character array */
206          bytes += width;
207
208          if (bufptr) {
209            if (width <= 1) *bufptr++ = va_arg(ap, int);
210            else {
211              if ((bufptr + width) > bufend) width = bufend - bufptr;
212
213              memcpy(bufptr, va_arg(ap, char *), (size_t)width);
214              bufptr += width;
215            }
216          }
217          break;
218
219        case 's' : /* String */
220          if ((s = va_arg(ap, char *)) == NULL) s = "(null)";
221
222          slen = strlen(s);
223          if (slen > width && prec != width) width = slen;
224
225          bytes += width;
226
227          if (bufptr) {
228            if ((bufptr + width) > bufend) width = bufend - bufptr;
229
230            if (slen > width) slen = width;
231
232            if (sign == '-') {
233              strncpy(bufptr, s, (size_t)slen);
234              memset(bufptr + slen, ' ', (size_t)(width - slen));
235            } else {
236              memset(bufptr, ' ', (size_t)(width - slen));
237              strncpy(bufptr + width - slen, s, (size_t)slen);
238            }
239
240            bufptr += width;
241          }
242          break;
243
244        case 'n' : /* Output number of chars so far */
245          *(va_arg(ap, int *)) = bytes;
246          break;
247      }
248    } else {
249      bytes ++;
250
251      if (bufptr && bufptr < bufend) *bufptr++ = *format;
252      format ++;
253    }
254  }
255
256 /*
257  * Nul-terminate the string and return the number of characters needed.
258  */
259
260  if (bufptr) *bufptr = '\0';
261
262  return (bytes);
263}
264
265int fl_snprintf(char* str, size_t size, const char* fmt, ...) {
266  int ret;
267  va_list ap;
268  va_start(ap, fmt);
269  ret = vsnprintf(str, size, fmt, ap);
270  va_end(ap);
271  return ret;
272}
273
274#ifdef __cplusplus
275}
276#endif
277
278/*
279 * End of "$Id$".
280 */
281
Note: See TracBrowser for help on using the repository browser.