From 50a6ca39ad4ed01922aa4f755f0ca579788226cf Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Thu, 6 May 2010 21:04:40 +0000 Subject: Move c/h files implementing/defining standard library stuff into a new libc directory, also standard'ify some parts of the code base (almost entirely #include fixes). This is to a) to cleanup firmware/common and firmware/include a bit, but also b) for Rockbox as an application which should use the host system's c library and headers, separating makes it easy to exclude our files from the build. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25850 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/format.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 firmware/common/format.c (limited to 'firmware/common/format.c') diff --git a/firmware/common/format.c b/firmware/common/format.c new file mode 100644 index 0000000000..987af417da --- /dev/null +++ b/firmware/common/format.c @@ -0,0 +1,227 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Gary Czvitkovicz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include +#include +#include +#include "file.h" + +static const char hexdigit[] = "0123456789ABCDEF"; + +int format( + /* call 'push()' for each output letter */ + int (*push)(void *userp, unsigned char data), + void *userp, + const char *fmt, + va_list ap) +{ + char *str; + char tmpbuf[12], pad; + int ch, width, val, sign, precision; + long lval, lsign; + unsigned int uval; + unsigned long ulval; + bool ok = true; + + tmpbuf[sizeof tmpbuf - 1] = '\0'; + + while ((ch = *fmt++) != '\0' && ok) + { + if (ch == '%') + { + ch = *fmt++; + pad = ' '; + if (ch == '0') + pad = '0'; + + width = 0; + while (ch >= '0' && ch <= '9') + { + width = 10*width + ch - '0'; + ch = *fmt++; + } + + precision = 0; + if(ch == '.') + { + ch = *fmt++; + while (ch >= '0' && ch <= '9') + { + precision = 10*precision + ch - '0'; + ch = *fmt++; + } + } else { + precision = INT_MAX; + } + + str = tmpbuf + sizeof tmpbuf - 1; + switch (ch) + { + case 'c': + *--str = va_arg (ap, int); + break; + + case 's': + str = va_arg (ap, char*); + break; + + case 'd': + val = sign = va_arg (ap, int); + if (val < 0) + val = -val; + do + { + *--str = (val % 10) + '0'; + val /= 10; + } + while (val > 0); + if (sign < 0) + *--str = '-'; + break; + + case 'u': + uval = va_arg(ap, unsigned int); + do + { + *--str = (uval % 10) + '0'; + uval /= 10; + } + while (uval > 0); + break; + + case 'x': + case 'X': + pad='0'; + uval = va_arg (ap, int); + do + { + *--str = hexdigit[uval & 0xf]; + uval >>= 4; + } + while (uval); + break; + + case 'l': + ch = *fmt++; + switch(ch) { + case 'x': + case 'X': + pad='0'; + ulval = va_arg (ap, long); + do + { + *--str = hexdigit[ulval & 0xf]; + ulval >>= 4; + } + while (ulval); + break; + case 'd': + lval = lsign = va_arg (ap, long); + if (lval < 0) + lval = -lval; + do + { + *--str = (lval % 10) + '0'; + lval /= 10; + } + while (lval > 0); + if (lsign < 0) + *--str = '-'; + break; + + case 'u': + ulval = va_arg(ap, unsigned long); + do + { + *--str = (ulval % 10) + '0'; + ulval /= 10; + } + while (ulval > 0); + break; + + default: + *--str = 'l'; + *--str = ch; + } + + break; + + default: + *--str = ch; + break; + } + + if (width > 0) + { + width -= strlen (str); + while (width-- > 0 && ok) + ok=push(userp, pad); + } + while (*str != '\0' && ok && precision--) + ok=push(userp, *str++); + } + else + ok=push(userp, ch); + } + return ok; /* true means good */ +} + +struct for_fprintf { + int fd; /* where to store it */ + int bytes; /* amount stored */ +}; + +static int fprfunc(void *pr, unsigned char letter) +{ + struct for_fprintf *fpr = (struct for_fprintf *)pr; + int rc = write(fpr->fd, &letter, 1); + + if(rc > 0) { + fpr->bytes++; /* count them */ + return true; /* we are ok */ + } + + return false; /* failure */ +} + + +int fdprintf(int fd, const char *fmt, ...) +{ + bool ok; + va_list ap; + struct for_fprintf fpr; + + fpr.fd=fd; + fpr.bytes=0; + + va_start(ap, fmt); + ok = format(fprfunc, &fpr, fmt, ap); + va_end(ap); + + return fpr.bytes; /* return 0 on error */ +} + +int vuprintf(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap) +{ + return format(push, userp, fmt, ap); +} -- cgit v1.2.3