Add support for snprintf and vsnprintf. Try and make the return value a bit
authorDavid Given <dg@cowlark.com>
Wed, 29 May 2013 16:10:58 +0000 (17:10 +0100)
committerDavid Given <dg@cowlark.com>
Wed, 29 May 2013 16:10:58 +0000 (17:10 +0100)
more standards-compliant.

--HG--
branch : dtrg-videocore

lang/cem/libcc.ansi/build.mk
lang/cem/libcc.ansi/headers/stdio.h
lang/cem/libcc.ansi/stdio/doprnt.c
lang/cem/libcc.ansi/stdio/snprintf.c [new file with mode: 0644]
lang/cem/libcc.ansi/stdio/vsnprintf.c [new file with mode: 0644]

index a9434ce..6140b4b 100644 (file)
@@ -133,9 +133,11 @@ $(call ackfile, lang/cem/libcc.ansi/stdio/perror.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/fprintf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/printf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/sprintf.c)
+$(call ackfile, lang/cem/libcc.ansi/stdio/snprintf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/vfprintf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/vprintf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/vsprintf.c)
+$(call ackfile, lang/cem/libcc.ansi/stdio/vsnprintf.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/doprnt.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/icompute.c)
 $(call ackfile, lang/cem/libcc.ansi/stdio/fscanf.c)
index 4c5a42a..52f286f 100644 (file)
@@ -72,10 +72,12 @@ extern int  fscanf(FILE *_stream, const char *_format, ...);
 extern int     printf(const char *_format, ...);
 extern int     scanf(const char *_format, ...);
 extern int     sprintf(char *_s, const char *_format, ...);
+extern int     snprintf(char *_s, size_t _len, const char *_format, ...);
 extern int     sscanf(const char *_s, const char *_format, ...);
 extern int     vfprintf(FILE *_stream, const char *_format, char *_arg);
 extern int     vprintf(const char *_format, char *_arg);
 extern int     vsprintf(char *_s, const char *_format, char *_arg);
+extern int     vsnprintf(char *_s, size_t _len, const char *_format, char *_arg);
 extern int     fgetc(FILE *_stream);
 extern char    *fgets(char *_s, int _n, FILE *_stream);
 extern int     fputc(int _c, FILE *_stream);
index 81714de..395c457 100644 (file)
@@ -38,6 +38,16 @@ gnum(register const char *f, int *ip, va_list *app)
 #define set_pointer(flags)             /* compilation might continue */
 #endif
 
+#define PUTC(c) \
+       do { \
+               int i = putc(c, stream); \
+               if (i == EOF) \
+               { \
+                       if (ferror(stream)) \
+                               return -1; \
+               } \
+       } while (0)
+
 /* print an ordinal number */
 static char *
 o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed)
@@ -125,13 +135,10 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
                if (c != '%') {
 #ifdef CPM
                        if (c == '\n') {
-                               if (putc('\r', stream) == EOF)
-                                       return nrchars ? -nrchars : -1;
-                               nrchars++;
+                               PUTC('\r');
                        }
 #endif
-                       if (putc(c, stream) == EOF)
-                               return nrchars ? -nrchars : -1;
+                       PUTC(c);
                        nrchars++;
                        continue;
                }
@@ -181,13 +188,11 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
                default:
 #ifdef CPM
                        if (c == '\n') {
-                               if (putc('\r', stream) == EOF)
-                                       return nrchars ? -nrchars : -1;
+                               PUTC('\r');
                                nrchars++;
                        }
 #endif
-                       if (putc(c, stream) == EOF)
-                               return nrchars ? -nrchars : -1;
+                       PUTC(c);
                        nrchars++;
                        continue;
                case 'n':
@@ -280,31 +285,26 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
                                if (between_fill) {
                                    if (flags & FL_SIGNEDCONV) {
                                        j--; nrchars++;
-                                       if (putc(*s1++, stream) == EOF)
-                                               return nrchars ? -nrchars : -1;
+                                       PUTC(*s1++);
                                    } else {
                                        j -= 2; nrchars += 2;
-                                       if ((putc(*s1++, stream) == EOF)
-                                           || (putc(*s1++, stream) == EOF))
-                                               return nrchars ? -nrchars : -1;
-                                   }
+                                       PUTC(*s1++);
+                                       PUTC(*s1++);
+                                       }
                                }
                                do {
-                                       if (putc(zfill, stream) == EOF)
-                                               return nrchars ? -nrchars : -1;
+                                       PUTC(zfill);
                                } while (--i);
                        }
 
                nrchars += j;
                while (--j >= 0) {
-                       if (putc(*s1++, stream) == EOF)
-                               return nrchars ? -nrchars : -1;
+                       PUTC(*s1++);
                }
 
                if (i > 0) nrchars += i;
                while (--i >= 0)
-                       if (putc(zfill, stream) == EOF)
-                               return nrchars ? -nrchars : -1;
+                       PUTC(zfill);
        }
        return nrchars;
 }
diff --git a/lang/cem/libcc.ansi/stdio/snprintf.c b/lang/cem/libcc.ansi/stdio/snprintf.c
new file mode 100644 (file)
index 0000000..7d42811
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * sprintf - print formatted output on an array
+ */
+/* $Id$ */
+
+#include       <stdio.h>
+#include       <stdarg.h>
+#include       "loc_incl.h"
+
+int
+snprintf(char * s, size_t len, const char *format, ...)
+{
+       va_list ap;
+       int retval;
+       FILE tmp_stream;
+
+       va_start(ap, format);
+
+       tmp_stream._fd     = -1;
+       tmp_stream._flags  = _IOWRITE + _IONBF + _IOWRITING;
+       tmp_stream._buf    = (unsigned char *) s;
+       tmp_stream._ptr    = (unsigned char *) s;
+       tmp_stream._count  = len;
+
+       retval = _doprnt(format, ap, &tmp_stream);
+       putc('\0',&tmp_stream);
+
+       va_end(ap);
+
+       return retval;
+}
diff --git a/lang/cem/libcc.ansi/stdio/vsnprintf.c b/lang/cem/libcc.ansi/stdio/vsnprintf.c
new file mode 100644 (file)
index 0000000..870e23d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * vsprintf - print formatted output without ellipsis on an array
+ */
+/* $Id$ */
+
+#include       <stdio.h>
+#include       <stdarg.h>
+#include       "loc_incl.h"
+
+int
+vsnprintf(char *s, size_t len, const char *format, va_list arg)
+{
+       int retval;
+       FILE tmp_stream;
+
+       tmp_stream._fd     = -1;
+       tmp_stream._flags  = _IOWRITE + _IONBF + _IOWRITING;
+       tmp_stream._buf    = (unsigned char *) s;
+       tmp_stream._ptr    = (unsigned char *) s;
+       tmp_stream._count  = len;
+
+       retval = _doprnt(format, arg, &tmp_stream);
+       putc('\0',&tmp_stream);
+
+       return retval;
+}