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/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)

View 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);

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

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