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().
This commit is contained in:
parent
4927ab8208
commit
ddfc4b59ef
1 changed files with 199 additions and 0 deletions
199
dietlibc-0.31-printFG.patch
Normal file
199
dietlibc-0.31-printFG.patch
Normal file
|
|
@ -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&&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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue