1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Gary Czvitkovicz
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 * Minimal printf and snprintf formatting functions
23 * These support %c %s %d and %x
24 * Field width and zero-padding flag only
32 #include "file.h" /* for write(), used in fprintf() */
33 #include "sprintf.h" /* to allow the simulator magic */
35 static const char hexdigit
[] = "0123456789ABCDEF";
38 /* call 'push()' for each output letter */
39 int (*push
)(void *userp
, unsigned char data
),
46 int ch
, width
, val
, sign
, precision
;
52 tmpbuf
[sizeof tmpbuf
- 1] = '\0';
54 while ((ch
= *fmt
++) != '\0' && ok
)
64 while (ch
>= '0' && ch
<= '9')
66 width
= 10*width
+ ch
- '0';
74 while (ch
>= '0' && ch
<= '9')
76 precision
= 10*precision
+ ch
- '0';
83 str
= tmpbuf
+ sizeof tmpbuf
- 1;
87 *--str
= va_arg (ap
, int);
91 str
= va_arg (ap
, char*);
95 val
= sign
= va_arg (ap
, int);
100 *--str
= (val
% 10) + '0';
109 uval
= va_arg(ap
, unsigned int);
112 *--str
= (uval
% 10) + '0';
120 uval
= va_arg (ap
, int);
123 *--str
= hexdigit
[uval
& 0xf];
134 ulval
= va_arg (ap
, long);
137 *--str
= hexdigit
[ulval
& 0xf];
143 lval
= lsign
= va_arg (ap
, long);
148 *--str
= (lval
% 10) + '0';
157 ulval
= va_arg(ap
, unsigned long);
160 *--str
= (ulval
% 10) + '0';
180 width
-= strlen (str
);
181 while (width
-- > 0 && ok
)
184 while (*str
!= '\0' && ok
&& precision
--)
185 ok
=push(userp
, *str
++);
190 return ok
; /* true means good */
193 #if !defined(SIMULATOR) || !defined(linux)
194 /* ALSA library requires a more advanced snprintf, so let's not
195 override it in simulator for Linux. Note that Cygwin requires
196 our snprintf or it produces garbled output after a while. */
198 struct for_snprintf
{
199 unsigned char *ptr
; /* where to store it */
200 int bytes
; /* amount already stored */
201 int max
; /* max amount to store */
204 static int sprfunc(void *ptr
, unsigned char letter
)
206 struct for_snprintf
*pr
= (struct for_snprintf
*)ptr
;
207 if(pr
->bytes
< pr
->max
) {
213 return false; /* filled buffer */
217 int snprintf(char *buf
, size_t size
, const char *fmt
, ...)
221 struct for_snprintf pr
;
223 pr
.ptr
= (unsigned char *)buf
;
228 ok
= format(sprfunc
, &pr
, fmt
, ap
);
231 /* make sure it ends with a trailing zero */
232 pr
.ptr
[(pr
.bytes
< pr
.max
) ? 0 : -1] = '\0';
237 int vsnprintf(char *buf
, int size
, const char *fmt
, va_list ap
)
240 struct for_snprintf pr
;
242 pr
.ptr
= (unsigned char *)buf
;
246 ok
= format(sprfunc
, &pr
, fmt
, ap
);
248 /* make sure it ends with a trailing zero */
249 pr
.ptr
[(pr
.bytes
< pr
.max
) ? 0 : -1] = '\0';
254 #endif /* Linux SIMULATOR */
257 int fd
; /* where to store it */
258 int bytes
; /* amount stored */
261 static int fprfunc(void *pr
, unsigned char letter
)
263 struct for_fprintf
*fpr
= (struct for_fprintf
*)pr
;
264 int rc
= write(fpr
->fd
, &letter
, 1);
267 fpr
->bytes
++; /* count them */
268 return true; /* we are ok */
271 return false; /* failure */
275 int fdprintf(int fd
, const char *fmt
, ...)
279 struct for_fprintf fpr
;
285 ok
= format(fprfunc
, &fpr
, fmt
, ap
);
288 return fpr
.bytes
; /* return 0 on error */