From 69953d016c2898c166d02db2a6e54cc896633bb0 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 29 May 2013 17:10:58 +0100 Subject: [PATCH] Add support for snprintf and vsnprintf. Try and make the return value a bit more standards-compliant. --HG-- branch : dtrg-videocore --- lang/cem/libcc.ansi/build.mk | 2 ++ lang/cem/libcc.ansi/headers/stdio.h | 2 ++ lang/cem/libcc.ansi/stdio/doprnt.c | 42 +++++++++++++-------------- lang/cem/libcc.ansi/stdio/snprintf.c | 31 ++++++++++++++++++++ lang/cem/libcc.ansi/stdio/vsnprintf.c | 26 +++++++++++++++++ 5 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 lang/cem/libcc.ansi/stdio/snprintf.c create mode 100644 lang/cem/libcc.ansi/stdio/vsnprintf.c diff --git a/lang/cem/libcc.ansi/build.mk b/lang/cem/libcc.ansi/build.mk index a9434ceb4..6140b4b50 100644 --- a/lang/cem/libcc.ansi/build.mk +++ b/lang/cem/libcc.ansi/build.mk @@ -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) diff --git a/lang/cem/libcc.ansi/headers/stdio.h b/lang/cem/libcc.ansi/headers/stdio.h index 4c5a42a08..52f286f20 100644 --- a/lang/cem/libcc.ansi/headers/stdio.h +++ b/lang/cem/libcc.ansi/headers/stdio.h @@ -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); diff --git a/lang/cem/libcc.ansi/stdio/doprnt.c b/lang/cem/libcc.ansi/stdio/doprnt.c index 81714de47..395c45704 100644 --- a/lang/cem/libcc.ansi/stdio/doprnt.c +++ b/lang/cem/libcc.ansi/stdio/doprnt.c @@ -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 index 000000000..7d428118c --- /dev/null +++ b/lang/cem/libcc.ansi/stdio/snprintf.c @@ -0,0 +1,31 @@ +/* + * sprintf - print formatted output on an array + */ +/* $Id$ */ + +#include +#include +#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 index 000000000..870e23df2 --- /dev/null +++ b/lang/cem/libcc.ansi/stdio/vsnprintf.c @@ -0,0 +1,26 @@ +/* + * vsprintf - print formatted output without ellipsis on an array + */ +/* $Id$ */ + +#include +#include +#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; +}