a3dfc1076f
gcc45. - avoid implicit int, declare void functions void - return values from non-void functions - put most external declarations properly in header files - use some static and const - fix up a big mess with function pointer casting - use standard includes, don't provide own decls of standard functions - use types matching libc when providing own malloc, printf, and putchar - use <ctype.h> functions correctly - silence assorted compiler warnings - fix some bugs exposed by compiler warnings - don't intentionally exercise signed overflow - remove some unused items - add patch comments to other patch (patch-aa) As this includes several fixes and removes some undefined behavior on a commonly reachable code path, bump PKGREVISION.
205 lines
4.5 KiB
Text
205 lines
4.5 KiB
Text
$NetBSD: patch-printf_c,v 1.1 2012/12/28 03:03:09 dholland Exp $
|
|
|
|
- use standard headers
|
|
(this is supposed to substitute for libc's printf, so it *must*
|
|
match stdio.h)
|
|
- use own headers
|
|
- declare local functions static
|
|
- avoid implicit int
|
|
- return values from non-void functions
|
|
- use const for string constants
|
|
- remove/replace code that intentionally uses signed overflow
|
|
|
|
--- printf.c.orig 2012-12-27 21:57:52.000000000 +0000
|
|
+++ printf.c
|
|
@@ -82,6 +82,8 @@ static char sccsid[] = "@(#)printf.c 1.1
|
|
/* The pwb version this is based on */
|
|
/* from printf.c:2.2 6/5/79 */
|
|
|
|
+#include <stdio.h>
|
|
+
|
|
#ifndef __STDC__
|
|
#include "varargs.h"
|
|
#else
|
|
@@ -95,6 +97,8 @@ extern nl_catd catd;
|
|
#define catgets(a, b, c, d) (d)
|
|
#endif
|
|
|
|
+#include "ex.h"
|
|
+#include "ex_proto.h"
|
|
#include "config.h"
|
|
|
|
/*
|
|
@@ -115,15 +119,13 @@ extern nl_catd catd;
|
|
|
|
static int width, sign, fill;
|
|
|
|
-extern int putchar __P((int));
|
|
-
|
|
-char *p_dconv __P((long, char *));
|
|
-int p_emit __P((char *, char *));
|
|
+static void p_emit __P((const char *, const char *));
|
|
|
|
#ifdef __STDC__
|
|
int vprintf(const char *fmt, va_list ap);
|
|
#endif
|
|
|
|
+int
|
|
#ifndef __STDC__
|
|
printf(va_alist)
|
|
va_dcl
|
|
@@ -155,14 +157,17 @@ printf(const char *fmt, ...)
|
|
return ret;
|
|
}
|
|
|
|
+int
|
|
vprintf(const char *fmt, va_list ap)
|
|
{
|
|
char fcode;
|
|
int prec;
|
|
int length,mask1,nbits,n;
|
|
long int mask2, num;
|
|
- register char *bptr;
|
|
- char *ptr;
|
|
+ unsigned long unum;
|
|
+ register const char *bptr;
|
|
+ register char *vbptr;
|
|
+ const char *ptr;
|
|
char buf[134];
|
|
#endif /* __STDC__ */
|
|
|
|
@@ -171,7 +176,7 @@ vprintf(const char *fmt, va_list ap)
|
|
while ((fcode = *fmt++)!='%') {
|
|
/* ordinary (non-%) character */
|
|
if (fcode=='\0')
|
|
- return;
|
|
+ return 0;
|
|
putchar(fcode);
|
|
}
|
|
/* length modifier: -1 for h, 1 for l, 0 for none */
|
|
@@ -288,18 +293,18 @@ vprintf(const char *fmt, va_list ap)
|
|
nbits = 4;
|
|
}
|
|
n = (num!=0);
|
|
- bptr = buf + MAXOCT + 3;
|
|
+ vbptr = buf + MAXOCT + 3;
|
|
/* shift and mask for speed */
|
|
do
|
|
if (((int) num & mask1) < 10)
|
|
- *--bptr = ((int) num & mask1) + 060;
|
|
+ *--vbptr = ((int) num & mask1) + 060;
|
|
else
|
|
- *--bptr = ((int) num & mask1) + 0127;
|
|
- while (num = (num >> nbits) & mask2);
|
|
+ *--vbptr = ((int) num & mask1) + 0127;
|
|
+ while ((num = (num >> nbits) & mask2) != 0);
|
|
|
|
if (fcode=='o') {
|
|
if (n)
|
|
- *--bptr = '0';
|
|
+ *--vbptr = '0';
|
|
}
|
|
else
|
|
if (!sign && fill <= 0) {
|
|
@@ -308,9 +313,10 @@ vprintf(const char *fmt, va_list ap)
|
|
width -= 2;
|
|
}
|
|
else {
|
|
- *--bptr = fcode;
|
|
- *--bptr = '0';
|
|
+ *--vbptr = fcode;
|
|
+ *--vbptr = '0';
|
|
}
|
|
+ bptr = vbptr;
|
|
ptr = buf + MAXOCT + 3;
|
|
break;
|
|
case 'D':
|
|
@@ -331,14 +337,20 @@ vprintf(const char *fmt, va_list ap)
|
|
else
|
|
num = (long) n;
|
|
}
|
|
- if (n = (fcode != 'u' && num < 0))
|
|
- num = -num;
|
|
+ if ((n = (fcode != 'u' && num < 0)) != 0) {
|
|
+ /* avoid overflow on -LONG_MAX */
|
|
+ unum = ((unsigned long)-(num + 1)) + 1;
|
|
+ }
|
|
+ else {
|
|
+ unum = (unsigned long) num;
|
|
+ }
|
|
/* now convert to digits */
|
|
- bptr = p_dconv(num, buf);
|
|
+ vbptr = p_dconv(unum, buf);
|
|
if (n)
|
|
- *--bptr = '-';
|
|
+ *--vbptr = '-';
|
|
if (fill == 0)
|
|
fill = -1;
|
|
+ bptr = vbptr;
|
|
ptr = buf + MAXDIGS + 1;
|
|
break;
|
|
default:
|
|
@@ -369,13 +381,15 @@ vprintf(const char *fmt, va_list ap)
|
|
*/
|
|
char *
|
|
p_dconv(value, buffer)
|
|
- long value;
|
|
+ unsigned long value;
|
|
char *buffer;
|
|
{
|
|
register char *bp;
|
|
- register int svalue;
|
|
+ register unsigned int svalue;
|
|
+#if 0
|
|
int n;
|
|
long lval;
|
|
+#endif
|
|
|
|
bp = buffer;
|
|
|
|
@@ -386,6 +400,7 @@ p_dconv(value, buffer)
|
|
return(bp);
|
|
}
|
|
|
|
+#if 0 /* original code, undefined behavior */
|
|
/* develop the leading digit of the value in "n" */
|
|
n = 0;
|
|
while (value < 0) {
|
|
@@ -399,6 +414,7 @@ p_dconv(value, buffer)
|
|
|
|
/* stash it in buffer[1] to allow for a sign */
|
|
bp[1] = n + '0';
|
|
+#endif
|
|
/*
|
|
* Now develop the rest of the digits. Since speed counts here,
|
|
* we do it in two loops. The first gets "value" down until it
|
|
@@ -417,13 +433,15 @@ p_dconv(value, buffer)
|
|
*--bp = (svalue % 10) + '0';
|
|
svalue /= 10;
|
|
}
|
|
-
|
|
+
|
|
+#if 0
|
|
/* fill in intermediate zeroes if needed */
|
|
if (buffer[1] != '0') {
|
|
while (bp > buffer + 2)
|
|
*--bp = '0';
|
|
--bp;
|
|
}
|
|
+#endif
|
|
return(bp);
|
|
}
|
|
|
|
@@ -439,9 +457,10 @@ p_dconv(value, buffer)
|
|
* any padding in right-justification (to avoid printing "-3" as
|
|
* "000-3" where "-0003" was intended).
|
|
*/
|
|
+static void
|
|
p_emit(s, send)
|
|
- register char *s;
|
|
- char *send;
|
|
+ register const char *s;
|
|
+ const char *send;
|
|
{
|
|
char cfill;
|
|
register int alen;
|