Commits

dtrg  committed a19eb60

Add support for snprintf and vsnprintf. Try and make the return value a bit
more standards-compliant.

  • Participants
  • Parent commits dacb9bc
  • Branches dtrg-videocore

Comments (0)

Files changed (5)

File lang/cem/libcc.ansi/build.mk

 $(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)

File lang/cem/libcc.ansi/headers/stdio.h

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

File lang/cem/libcc.ansi/stdio/doprnt.c

 #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)
 		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;
 		}
 		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':
 				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;
 }

File lang/cem/libcc.ansi/stdio/snprintf.c

+/*
+ * 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;
+}

File lang/cem/libcc.ansi/stdio/vsnprintf.c

+/*
+ * 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;
+}