rpms/dietlibc/F-8 dietlibc-0.31-printFG.patch,NONE,1.1

Enrico Scholz (ensc) fedora-extras-commits at redhat.com
Sat Jun 21 13:48:41 UTC 2008


Author: ensc

Update of /cvs/extras/rpms/dietlibc/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv24092

Added Files:
	dietlibc-0.31-printFG.patch 
Log Message:
This patch adds support for uppercase 'F' and 'G' printf format
specifiers.  It fixes handling of -INF values in __dtostr() too;
previously, there was

| unsigned int i;
| if ((i=isinf(d))) return copystring(buf,maxlen,i>0?"inf":"-inf");
                                                 ~~~
which evaluated to true everytime. The copystring() function worked
for 3-letter words only but not for '-inf'.


The last argument of __dtostr() was changed from a boolean flag to a
bitmask. Bit 0 encodes 'g' or 'f', and bit 1 lower-/uppercase.  There
should be probably added some macros for them; for now, these values
are used directly.

Please note that this might affect other applications (liblowfat?) too
which are using __dtostr().


dietlibc-0.31-printFG.patch:

--- NEW FILE dietlibc-0.31-printFG.patch ---
diff -up dietlibc-0.31.20080409/lib/__dtostr.c.printFG dietlibc-0.31.20080409/lib/__dtostr.c
--- dietlibc-0.31.20080409/lib/__dtostr.c.printFG	2006-07-04 05:33:02.000000000 +0200
+++ dietlibc-0.31.20080409/lib/__dtostr.c	2008-04-13 14:41:48.000000000 +0200
@@ -5,13 +5,15 @@
 
 static int copystring(char* buf,int maxlen, const char* s) {
   int i;
-  for (i=0; i<3&&i<maxlen; ++i)
+  for (i=0; i<maxlen; ++i) {
     buf[i]=s[i];
-  if (i<maxlen) { buf[i]=0; ++i; }
+    if (!s[i])
+      break;
+  }
   return i;
 }
 
-int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int g) {
+int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int flags) {
 #if 1
   union {
     unsigned long long l;
@@ -31,12 +33,17 @@ int __dtostr(double d,char *buf,unsigned
   signed long e10;
   /* step 3: calculate 10^e10 */
   unsigned int i;
+  int is_inf;
   double backup=d;
   double tmp;
   char *oldbuf=buf;
 
-  if ((i=isinf(d))) return copystring(buf,maxlen,i>0?"inf":"-inf");
-  if (isnan(d)) return copystring(buf,maxlen,"nan");
+  if ((is_inf=isinf(d)))
+    return copystring(buf,maxlen,
+		      (is_inf<0)?
+		      (flags&0x02?"-INF":"-inf"):
+		      (flags&0x02?"INF":"inf"));
+  if (isnan(d)) return copystring(buf,maxlen,flags&0x02?"NAN":"nan");
   e10=1+(long)(e*0.30102999566398119802); /* log10(2) */
   /* Wir iterieren von Links bis wir bei 0 sind oder maxlen erreicht
    * ist.  Wenn maxlen erreicht ist, machen wir das nochmal in
@@ -126,7 +133,7 @@ int __dtostr(double d,char *buf,unsigned
   if (prec2 || prec>(unsigned int)(buf-oldbuf)+1) {	/* more digits wanted */
     if (!maxlen) return 0; --maxlen;
     *buf='.'; ++buf;
-    if (g) {
+    if ((flags & 0x01)) {
       if (prec2) prec=prec2;
       prec-=buf-oldbuf-1;
     } else {
diff -up dietlibc-0.31.20080409/lib/__v_printf.c.printFG dietlibc-0.31.20080409/lib/__v_printf.c
--- dietlibc-0.31.20080409/lib/__v_printf.c.printFG	2008-02-19 01:28:13.000000000 +0100
+++ dietlibc-0.31.20080409/lib/__v_printf.c	2008-04-13 14:41:48.000000000 +0200
@@ -346,45 +346,49 @@ num_printf:
 #ifdef WANT_FLOATING_POINT_IN_PRINTF
       /* print a floating point value */
       case 'f':
+      case 'F':
       case 'g':
+      case 'G':
 	{
-	  int g=(ch=='g');
+	  int flags=(((ch&0x5f)=='G') ? 0x01 : 0x00) | ((ch&0x20) ? 0x00 : 0x02);
 	  double d=va_arg(arg_ptr,double);
 	  s=buf+1;
 	  if (width==0) width=1;
 	  if (!flag_dot) preci=6;
 	  if (flag_sign || d < +0.0) flag_in_sign=1;
 
-	  sz=__dtostr(d,s,sizeof(buf)-1,width,preci,g);
+	  sz=__dtostr(d,s,sizeof(buf)-1,width,preci,flags);
 
-	  if (flag_dot) {
-	    char *tmp;
-	    if ((tmp=strchr(s,'.'))) {
-	      if (preci || flag_hash) ++tmp;
-	      while (preci>0 && *++tmp) --preci;
-	      *tmp=0;
-	    } else if (flag_hash) {
-	      s[sz]='.';
-	      s[++sz]='\0';
+	  if (!isnan(d) && !isinf(d)) {		/* skip NaN + INF values */
+	    if (flag_dot) {
+	      char *tmp;
+	      if ((tmp=strchr(s,'.'))) {
+		if (preci || flag_hash) ++tmp;
+		while (preci>0 && *++tmp) --preci;
+		*tmp=0;
+	      } else if (flag_hash) {
+		s[sz]='.';
+		s[++sz]='\0';
+	      }
 	    }
-	  }
 
-	  if (g) {
-	    char *tmp,*tmp1;	/* boy, is _this_ ugly! */
-	    if ((tmp=strchr(s,'.'))) {
-	      tmp1=strchr(tmp,'e');
-	      while (*tmp) ++tmp;
-	      if (tmp1) tmp=tmp1;
-	      while (*--tmp=='0') ;
-	      if (*tmp!='.') ++tmp;
-	      *tmp=0;
-	      if (tmp1) strcpy(tmp,tmp1);
+	    if ((flags&0x01)) {
+	      char *tmp,*tmp1;	/* boy, is _this_ ugly! */
+	      if ((tmp=strchr(s,'.'))) {
+		tmp1=strchr(tmp,'e');
+		while (*tmp) ++tmp;
+		if (tmp1) tmp=tmp1;
+		while (*--tmp=='0') ;
+		if (*tmp!='.') ++tmp;
+		*tmp=0;
+		if (tmp1) strcpy(tmp,tmp1);
+	      }
 	    }
-	  }
 	  
-	  if ((flag_sign || flag_space) && d>=0) {
-	    *(--s)=(flag_sign)?'+':' ';
-	    ++sz;
+	    if ((flag_sign || flag_space) && d>=0) {
+	      *(--s)=(flag_sign)?'+':' ';
+	      ++sz;
+	    }
 	  }
 	  
 	  sz=strlen(s);
diff -up dietlibc-0.31.20080409/test/printf.c.printFG dietlibc-0.31.20080409/test/printf.c
--- dietlibc-0.31.20080409/test/printf.c.printFG	2008-02-19 01:28:13.000000000 +0100
+++ dietlibc-0.31.20080409/test/printf.c	2008-04-13 14:52:36.000000000 +0200
@@ -2,11 +2,24 @@
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <math.h>
+#include <float.h>
 #include <sys/param.h>
 #include <locale.h>
 
 #define ALGN		5
 
+#ifndef INFINITY
+#  define INFINITY	(DBL_MAX * DBL_MAX)
+#endif
+
+#ifndef NAN
+#  if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))
+#    define NAN		(__builtin_nan(""))
+#  endif
+#endif
+
+
 // https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=112986
 #if 0
 #undef  assert
@@ -131,6 +144,23 @@ int main()
   TEST("-01234",   "%6.5i", -1234);
   TEST("  1234",   "%6.5s", "1234");
 
+  TEST("inf",  	"%f", INFINITY);
+  TEST("-inf", 	"%f", -INFINITY);
+  TEST("INF",  	"%F", INFINITY);
+  TEST("-INF", 	"%F", -INFINITY);
+
+  TEST("inf",  	"%g", INFINITY);
+  TEST("-inf", 	"%g", -INFINITY);
+  TEST("INF",  	"%G", INFINITY);
+  TEST("-INF", 	"%G", -INFINITY);
+
+#ifdef NAN  
+  TEST("nan",  	"%f", NAN);
+  TEST("NAN",  	"%F", NAN);
+  TEST("nan",  	"%g", NAN);
+  TEST("NAN",  	"%G", NAN);
+#endif
+  
 #ifdef XSI_TESTS
   setlocale(LC_ALL, "de_DE");
   
diff -up dietlibc-0.31.20080409/include/stdlib.h.printFG dietlibc-0.31.20080409/include/stdlib.h
--- dietlibc-0.31.20080409/include/stdlib.h.printFG	2007-09-20 20:51:18.000000000 +0200
+++ dietlibc-0.31.20080409/include/stdlib.h	2008-04-13 14:41:48.000000000 +0200
@@ -28,8 +28,12 @@ long double strtold(const char *nptr, ch
 long int strtol(const char *nptr, char **endptr, int base) __THROW;
 unsigned long int strtoul(const char *nptr, char **endptr, int base) __THROW;
 
+/* HACK: used flags in __dtostr
+     0x01 ... 'g'
+     0x02 ... uppercase
+   Define some constants somewhere... */
 extern int __ltostr(char *s, unsigned int size, unsigned long i, unsigned int base, int UpCase) __THROW;
-extern int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int g) __THROW;
+extern int __dtostr(double d,char *buf,unsigned int maxlen,unsigned int prec,unsigned int prec2,int flags) __THROW;
 
 #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
 __extension__ long long int strtoll(const char *nptr, char **endptr, int base) __THROW;




More information about the fedora-extras-commits mailing list