[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[leafnode-list] PATCH: leafnode-1.9.39 cannot display pseudo article on some operating systems



Hi,

Christian Ullrich reported a bug on some operating systems (incidentally
those with a broken snprintf implementation) that leafnode aborts
instead of showing a pseudo article.

If leafnode said "no" when checking your system's snprintf function at
/configure time, please apply this patch and report if it works for
you. (You can force using the replacement snprintf.c function by
editing the config.h file (after you've run ./configure, that is) and
changing the "#define HAVE_WORKING_SNPRINTF 1" line to
#undef HAVE_WORKING_SNPRINTF

Please test this patch:

Index: snprintf.c
===================================================================
RCS file: /var/CVS/leafnode-1/snprintf.c,v
retrieving revision 1.10
diff -u -r1.10 snprintf.c
--- snprintf.c	23 Apr 2003 11:04:04 -0000	1.10
+++ snprintf.c	7 May 2003 13:31:11 -0000
@@ -2,7 +2,7 @@
  * poor man's snprintf() - for systems which don't have their own
  *
  * This version of snprintf() currently supports only %s, %c, %d, %u,
- * %ld, %lu, %li, %i. It supports the 0 and width modifiers only for decimal
+ * %ld, %lu, %li, %i. It supports the 0, + and width modifiers only for decimal
  * output (%[l]{d|u|i}).
  *
  * Copyright (c) Cornelius Krasel 2000.
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <stdio.h>
 
+/** format unsigned value u into p */
 static void fmtu(char *p, unsigned long u) {
     unsigned int len = 0;
     unsigned long i = u, ni;
@@ -51,12 +52,16 @@
     *p = '\0';
 }
 
-static inline void fmts(char *p, long u) {
-    if (u < 0) {
+/** format signed value s into p, prefix asign if its nonzero and the
+ * value is positive. asign is usually '+' or ' '. */
+static inline void fmts(char *p, long s, char asign) {
+    if (s < 0) {
 	*p++ = '-';
-	fmtu(p, -u);
+	fmtu(p, -s);
     } else {
-	fmtu(p, u);
+	if (asign)
+	    *p++ = asign;
+	fmtu(p, s);
     }
 }
 
@@ -69,6 +74,7 @@
     size_t width = 0;
     char fill = ' ';
     int lflag = 0;		/* checking for longs */
+    int asign = 0;		/* always show sign */
     size_t i = 1;		/* because the terminating \0 also counts */
     size_t len, olen;
     char buf[30];		/* buffer for converting longs and ints */
@@ -82,6 +88,7 @@
 	if ((*p == '%') && !flag) {
 	    lflag = 0;
 	    flag = 1;
+	    asign = 0; /* can be 0, '+' or later ' ' (' ' is unimplemented) */
 	    fill = ' ';
 	    width = 0;
 	    p++;
@@ -117,13 +124,24 @@
 		    } else {
 			l = (long)va_arg(ap, int);
 		    }
-		    fmts(buf, l);
+		    fmts(buf, l, asign);
 printdec:
 		    olen = len = strlen(buf);
 		    if (width) {
-		       if (len < width) {
-			   memmove(buf + width - len, buf, len + 1);
-			   memset(buf, fill, width - len);
+			int off = !!asign;
+			if (len < width) {
+			    switch (fill) {
+				case ' ':
+				    memmove(buf + width - len, buf, len + 1);
+				    memset(buf, fill, width - len);
+				    break;
+				case '0':
+				    memmove(buf + off + width - len, buf + off, len + 1 - off);
+				    memset(buf + off, fill, width - len);
+				    break;
+				default:
+				    abort();
+			    }
 		       }
 		       olen = len = strlen(buf);
 		    }
@@ -133,7 +151,6 @@
 		    strncat(q, buf, len);
 		    q += len;
 		    i += olen;
-		    lflag = 0;
 		    flag = 0;
 		    p++;
 		    break;
@@ -146,7 +163,6 @@
 		}
 	    case 'c':{
 		    c = va_arg(ap, int);
-		    lflag = 0;
 		    flag = 0;
 		    if (i < n)
 			*q++ = c;
@@ -155,7 +171,6 @@
 		    break;
 		}
 	    case '%':{
-		    lflag = 0;
 		    flag = 0;
 		    if (i < n)
 			*q++ = *p++;
@@ -174,12 +189,15 @@
 		     width = width * 10 + *p - '0';
 		     p++;
 		     break;
+	    case '+':
+		     asign = '+';
+		     p++;
+		     break;
 	    default:
 		     abort();
 		     break;
 	    }
 	} else {
-	    lflag = 0;
 	    if (i < n) {
 		*q++ = *p;
 	    }

-- 
Matthias Andree

-- 
leafnode-list@xxxxxxxxxxxxxxxxxxxxxxxxxxxx -- mailing list for leafnode
To unsubscribe, send mail with "unsubscribe" in the subject to the list