From ddfc4b59ef35362fcafb48cb1acfe16285f21924 Mon Sep 17 00:00:00 2001 From: ensc Date: Sun, 13 Apr 2008 13:43:05 +0000 Subject: [PATCH] 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 | 199 ++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 dietlibc-0.31-printFG.patch diff --git a/dietlibc-0.31-printFG.patch b/dietlibc-0.31-printFG.patch new file mode 100644 index 0000000..9a11b80 --- /dev/null +++ b/dietlibc-0.31-printFG.patch @@ -0,0 +1,199 @@ +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&&i0?"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 + #include + #include ++#include ++#include + #include + #include + + #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;