summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2003-03-16 19:43:28 +0000
committerDaniel Stenberg <daniel@haxx.se>2003-03-16 19:43:28 +0000
commit758a2c823a1bd19cf45104b8f6d2055cca5ad016 (patch)
tree960fb7c3f774611c2d8cfd42ced5aa1b7562b1c6 /firmware
parent2955a2ead367c14169a74cfc2557d0ceb2bd334f (diff)
downloadrockbox-758a2c823a1bd19cf45104b8f6d2055cca5ad016.tar.gz
rockbox-758a2c823a1bd19cf45104b8f6d2055cca5ad016.zip
introducing fprintf():
int fprintf(int fd, const char *fmt, ...) Returns number of bytes written to the file descriptor. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3450 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/common/sprintf.c119
1 files changed, 101 insertions, 18 deletions
diff --git a/firmware/common/sprintf.c b/firmware/common/sprintf.c
index c18a390b44..ddbae9a473 100644
--- a/firmware/common/sprintf.c
+++ b/firmware/common/sprintf.c
@@ -26,21 +26,27 @@
#include <stdarg.h>
#include <string.h>
+#include <stdbool.h>
+
+#include "file.h" /* for write(), used in fprintf() */
static const char hexdigit[] = "0123456789ABCDEF";
-int vsnprintf (char *buf, int size, const char *fmt, va_list ap)
+static int format(
+ /* call 'push()' for each output letter */
+ int (*push)(void *userp, unsigned char data),
+ void *userp,
+ const char *fmt,
+ va_list ap)
{
- char *bp = buf;
- char *end = buf + size - 1;
-
char *str;
char tmpbuf[12], pad;
int ch, width, val, sign;
+ bool ok = true;
tmpbuf[sizeof tmpbuf - 1] = '\0';
- while ((ch = *fmt++) != '\0' && bp < end)
+ while ((ch = *fmt++) != '\0' && ok)
{
if (ch == '%')
{
@@ -100,28 +106,105 @@ int vsnprintf (char *buf, int size, const char *fmt, va_list ap)
if (width > 0)
{
width -= strlen (str);
- while (width-- > 0 && bp < end)
- *bp++ = pad;
+ while (width-- > 0 && ok)
+ ok=push(userp, pad);
}
- while (*str != '\0' && bp < end)
- *bp++ = *str++;
+ while (*str != '\0' && ok)
+ ok=push(userp, *str++);
}
else
- *bp++ = ch;
+ ok=push(userp, ch);
+ }
+ return ok; /* true means good */
+}
+
+struct for_snprintf {
+ unsigned char *ptr; /* where to store it */
+ int bytes; /* amount already stored */
+ int max; /* max amount to store */
+};
+
+static int sprfunc(void *ptr, unsigned char letter)
+{
+ struct for_snprintf *pr = (struct for_snprintf *)ptr;
+ if(pr->bytes < pr->max) {
+ *pr->ptr = letter;
+ pr->ptr++;
+ pr->bytes++;
+ return true;
+ }
+ return false; /* filled buffer */
+}
+
+
+int snprintf(char *buf, int size, const char *fmt, ...)
+{
+ bool ok;
+ va_list ap;
+ struct for_snprintf pr;
+
+ pr.ptr = buf;
+ pr.bytes = 0;
+ pr.max = size;
+
+ va_start(ap, fmt);
+ ok = format(sprfunc, &pr, fmt, ap);
+ va_end(ap);
+
+ /* make sure it ends with a trailing zero */
+ pr.ptr[ok?0:-1]='\0';
+
+ return pr.bytes;
+}
+
+int vsnprintf(char *buf, int size, const char *fmt, va_list ap)
+{
+ bool ok;
+ struct for_snprintf pr;
+
+ pr.ptr = buf;
+ pr.bytes = 0;
+ pr.max = size;
+
+ ok = format(sprfunc, &pr, fmt, ap);
+
+ /* make sure it ends with a trailing zero */
+ pr.ptr[ok?0:-1]='\0';
+
+ return pr.bytes;
+}
+
+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 */
}
- *bp++ = '\0';
- return bp - buf - 1;
+ return false; /* failure */
}
-int snprintf (char *buf, int size, const char *fmt, ...)
+
+int fprintf(int fd, const char *fmt, ...)
{
- int n;
+ bool ok;
va_list ap;
+ struct for_fprintf fpr;
+
+ fpr.fd=fd;
+ fpr.bytes=0;
- va_start (ap, fmt);
- n = vsnprintf (buf, size, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ ok = format(fprfunc, &fpr, fmt, ap);
+ va_end(ap);
- return n;
+ return fpr.bytes; /* return 0 on error */
}