pkgsrc/editors/ex/patches/patch-printf_c
dholland a3dfc1076f Fix legacy C. Pass -Wall -W -Wmissing-declarations -Wwrite-strings on
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.
2012-12-28 03:03:08 +00:00

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;