Add support for snprintf and vsnprintf. Try and make the return value a bit

more standards-compliant.

--HG--
branch : dtrg-videocore
This commit is contained in:
David Given 2013-05-29 17:10:58 +01:00
parent d3e3e72860
commit 69953d016c
5 changed files with 82 additions and 21 deletions

View 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/fprintf.c)
$(call ackfile, lang/cem/libcc.ansi/stdio/printf.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/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/vfprintf.c)
$(call ackfile, lang/cem/libcc.ansi/stdio/vprintf.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/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/doprnt.c)
$(call ackfile, lang/cem/libcc.ansi/stdio/icompute.c) $(call ackfile, lang/cem/libcc.ansi/stdio/icompute.c)
$(call ackfile, lang/cem/libcc.ansi/stdio/fscanf.c) $(call ackfile, lang/cem/libcc.ansi/stdio/fscanf.c)

View file

@ -72,10 +72,12 @@ extern int fscanf(FILE *_stream, const char *_format, ...);
extern int printf(const char *_format, ...); extern int printf(const char *_format, ...);
extern int scanf(const char *_format, ...); extern int scanf(const char *_format, ...);
extern int sprintf(char *_s, 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 sscanf(const char *_s, const char *_format, ...);
extern int vfprintf(FILE *_stream, const char *_format, char *_arg); extern int vfprintf(FILE *_stream, const char *_format, char *_arg);
extern int vprintf(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 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 int fgetc(FILE *_stream);
extern char *fgets(char *_s, int _n, FILE *_stream); extern char *fgets(char *_s, int _n, FILE *_stream);
extern int fputc(int _c, FILE *_stream); extern int fputc(int _c, FILE *_stream);

View file

@ -38,6 +38,16 @@ gnum(register const char *f, int *ip, va_list *app)
#define set_pointer(flags) /* compilation might continue */ #define set_pointer(flags) /* compilation might continue */
#endif #endif
#define PUTC(c) \
do { \
int i = putc(c, stream); \
if (i == EOF) \
{ \
if (ferror(stream)) \
return -1; \
} \
} while (0)
/* print an ordinal number */ /* print an ordinal number */
static char * static char *
o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed) 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 != '%') { if (c != '%') {
#ifdef CPM #ifdef CPM
if (c == '\n') { if (c == '\n') {
if (putc('\r', stream) == EOF) PUTC('\r');
return nrchars ? -nrchars : -1;
nrchars++;
} }
#endif #endif
if (putc(c, stream) == EOF) PUTC(c);
return nrchars ? -nrchars : -1;
nrchars++; nrchars++;
continue; continue;
} }
@ -181,13 +188,11 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
default: default:
#ifdef CPM #ifdef CPM
if (c == '\n') { if (c == '\n') {
if (putc('\r', stream) == EOF) PUTC('\r');
return nrchars ? -nrchars : -1;
nrchars++; nrchars++;
} }
#endif #endif
if (putc(c, stream) == EOF) PUTC(c);
return nrchars ? -nrchars : -1;
nrchars++; nrchars++;
continue; continue;
case 'n': case 'n':
@ -280,31 +285,26 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream)
if (between_fill) { if (between_fill) {
if (flags & FL_SIGNEDCONV) { if (flags & FL_SIGNEDCONV) {
j--; nrchars++; j--; nrchars++;
if (putc(*s1++, stream) == EOF) PUTC(*s1++);
return nrchars ? -nrchars : -1;
} else { } else {
j -= 2; nrchars += 2; j -= 2; nrchars += 2;
if ((putc(*s1++, stream) == EOF) PUTC(*s1++);
|| (putc(*s1++, stream) == EOF)) PUTC(*s1++);
return nrchars ? -nrchars : -1;
} }
} }
do { do {
if (putc(zfill, stream) == EOF) PUTC(zfill);
return nrchars ? -nrchars : -1;
} while (--i); } while (--i);
} }
nrchars += j; nrchars += j;
while (--j >= 0) { while (--j >= 0) {
if (putc(*s1++, stream) == EOF) PUTC(*s1++);
return nrchars ? -nrchars : -1;
} }
if (i > 0) nrchars += i; if (i > 0) nrchars += i;
while (--i >= 0) while (--i >= 0)
if (putc(zfill, stream) == EOF) PUTC(zfill);
return nrchars ? -nrchars : -1;
} }
return nrchars; return nrchars;
} }

View file

@ -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;
}

View file

@ -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;
}