Mail Archives: djgpp-workers/2014/01/10/13:26:12
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
X-Recipient: | djgpp-workers AT delorie DOT com
|
Message-ID: | <52D02D96.9000000@gmx.de>
|
Date: | Fri, 10 Jan 2014 18:27:50 +0100
|
From: | Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
|
User-Agent: | Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
|
MIME-Version: | 1.0
|
To: | djgpp-workers AT delorie DOT com
|
Subject: | Re: _doprnt bug fix if mantissa fraction precision exceeds the default
|
| of 39 decimal digits.
|
References: | <52CB29B1 DOT 3010904 AT gmx DOT de>
|
In-Reply-To: | <52CB29B1.3010904@gmx.de>
|
X-Provags-ID: | V03:K0:2RI7mdWOfUZfdr77bGVVcTeWB/KTZbq0H0FY7ig3l81JCItfjcF
|
| gNWmHNKbHHX/OzOHht0sMO6hTKkDtFXSDcEOZyfglRE7OMoCbahCWGGiXDEdOM3lGJcVYtJ
|
| AiuTcvZ1+PQ8SZqW9qcGbBuhx0mPYR1AALHERj5yFBDVp9aDZGNBV3CMZV3j5W1CQqMb+Vy
|
| jTZpYPAp4+R4HbXE7Yrvw==
|
Reply-To: | djgpp-workers AT delorie DOT com
|
Am 06.01.2014 23:09, schrieb Juan Manuel Guerrero:
> Please look at the following code snippet:
>
> #include <stdio.h>
>
> int main(void)
> {
> printf("%.60Le\n", 1.75L);
> return 0;
> }
>
>
> It must produce the following output (linux):
> 1.750000000000000000000000000000000000000000000000000000000000e+00
> but it produces the following output:
> 1.750000000000000000000000000000000000000e+00000000000000000000000
[snip]
OFYI, I committed the patch below to fix the bug reported concerning the field
width specifier for the AEFG conversion specifiers. I added a check for this issue
and fixed some signed-unsigned issues in other checks.
Regards,
Juan M. Guerrero
# cvs ci -m"Fix some -Werror=sign-compare occurrences." djgpp/tests/libc/ansi/stdio/append.c
# cvs ci -m"Fix some -Werror=sign-compare occurrences." djgpp/tests/libc/ansi/stdio/fseek.c
# cvs ci -m"Fix some -Werror=sign-compare occurrences." djgpp/tests/libc/ansi/stdio/tscanf3.c
# cvs ci -m"Fix some -Werror=sign-compare occurrences." djgpp/tests/libc/ansi/stdio/tsnprtf.c
# cvs ci -m"Handle case when field width specifier for AEFG conversion specifiers exceeds max default precision of 39 decimal digits." djgpp/src/libc/ansi/stdio/doprnt.c
# cvs ci -m"Check added to targets list." djgpp/tests/libc/ansi/stdio/makefile
# cd djgpp/tests/libc/ansi/stdio
# cvs ci -m"Check of field width specifier for AEFG conversion specifiers." djgpp/tests/libc/ansi/stdio/printf6.c
# cd ~
2014-01-06 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* djgpp/src/libc/ansi/stdio/doprnt.c: Handle case when field width specifier for AEFG conversion specifiers exceeds max default precision of 39 decimal digits.
* djgpp/tests/libc/ansi/stdio/makefile: Check added to targets list.
* djgpp/tests/libc/ansi/stdio/printf6.c: Check of field width specifier for AEFG conversion specifiers.
* djgpp/tests/libc/ansi/stdio/append.c: Fix some -Werror=sign-compare occurrences.
* djgpp/tests/libc/ansi/stdio/fseek.c: Fix some -Werror=sign-compare occurrences.
* djgpp/tests/libc/ansi/stdio/tscanf3.c: Fix some -Werror=sign-compare occurrences.
* djgpp/tests/libc/ansi/stdio/tsnprtf.c: Fix some -Werror=sign-compare occurrences.
diff -aprNU5 djgpp.orig/src/libc/ansi/stdio/doprnt.c djgpp/src/libc/ansi/stdio/doprnt.c
--- djgpp.orig/src/libc/ansi/stdio/doprnt.c 2014-01-09 22:00:02 +0100
+++ djgpp/src/libc/ansi/stdio/doprnt.c 2014-01-09 22:01:46 +0100
@@ -1,5 +1,6 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2013 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2012 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
@@ -404,12 +405,13 @@ rflag:
* cvt may have to round up past the "start" of the
* buffer, i.e. ``intf("%.2f", (double)9.999);'';
* if the first char isn't NUL, it did.
*/
*buf = '\0';
- size = doprnt_cvtl(_ldouble, prec, flags, &softsign, *fmt, buf,
+ size = doprnt_cvtl(_ldouble, prec + fpprec, flags, &softsign, *fmt, buf,
buf + sizeof(buf));
+ fpprec = 0; /* Floating point fraction precision already adjusted in doprnt_cvtl. */
/*
* If the format specifier requested an explicit sign,
* we print a negative sign even if no significant digits
* will be shown, and we also print a sign for a NaN. In
* other words, "%+f" might print -0.000000, +NaN and -NaN.
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/append.c djgpp/tests/libc/ansi/stdio/append.c
--- djgpp.orig/tests/libc/ansi/stdio/append.c 2001-05-22 22:52:26 +0100
+++ djgpp/tests/libc/ansi/stdio/append.c 2014-01-09 22:01:46 +0100
@@ -8,11 +8,11 @@ int
main(void)
{
FILE *f;
int status = 0; /* Return value. */
struct stat s;
- size_t len;
+ off_t len;
f = fopen(FILE_NAME, "w");
fprintf(f, "hello, there\n");
fclose(f);
stat(FILE_NAME, &s);
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/fseek.c djgpp/tests/libc/ansi/stdio/fseek.c
--- djgpp.orig/tests/libc/ansi/stdio/fseek.c 1996-02-05 02:40:26 +0100
+++ djgpp/tests/libc/ansi/stdio/fseek.c 2014-01-09 22:01:46 +0100
@@ -65,11 +65,12 @@ int main (int argc, char *argv[])
char *source = (char *)malloc (strlen (*argv) + 3);
if (source)
{
FILE *fp;
- long flen, buflen;
+ long flen;
+ size_t buflen;
char *buf1 = 0;
char *buf2 = 0;
char *buf3 = 0;
long fpos1 = 0;
int i;
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/makefile djgpp/tests/libc/ansi/stdio/makefile
--- djgpp.orig/tests/libc/ansi/stdio/makefile 2012-12-24 19:04:10 +0100
+++ djgpp/tests/libc/ansi/stdio/makefile 2014-01-09 22:01:46 +0100
@@ -16,10 +16,11 @@ SRC += hello.c
SRC += mktemp.c
SRC += printf.c
SRC += printf2.c
SRC += printf3.c
SRC += printf4.c
+SRC += printf6.c
SRC += sscanf.c
SRC += sscanf2.c
SRC += sscanf3.c
SRC += tmpnam.c
SRC += tremove.c
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/printf6.c djgpp/tests/libc/ansi/stdio/printf6.c
--- djgpp.orig/tests/libc/ansi/stdio/printf6.c 1970-01-01 01:00:00 +0100
+++ djgpp/tests/libc/ansi/stdio/printf6.c 2014-01-09 22:01:46 +0100
@@ -0,0 +1,90 @@
+/*
+ * printf6.c
+ * Test cases for field width specifier for different floating point conversions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define SIZE 128
+
+
+int
+main(void)
+{
+ const char *should_be[] = {
+ /* Created with linux libc. */
+ "0xe.10624dd2f1a9fbe000000000000000000000000000000000000000000000p-3",
+ "1.757999999999999999949693019196672594262054190039634704589844e+00",
+ "1.757999999999999999949693019196672594262054190039634704589844",
+ "1.757999999999999999949693019196672594262054190039634704589844",
+ "0xe.000000000000000000000000000000000000000000000000000000000000p-3",
+ "1.750000000000000000000000000000000000000000000000000000000000e+00",
+ "1.750000000000000000000000000000000000000000000000000000000000",
+ "1.75"
+ };
+ char result[SIZE];
+ int failures = 0;
+
+
+ snprintf(result, SIZE, "%.60La", 1.758L);
+ if (strcmp(result, should_be[0]))
+ {
+ printf("Check 0 \"%%.60La\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[0]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Le", 1.758L);
+ if (strcmp(result, should_be[1]))
+ {
+ printf("Check 1 \"%%.60Le\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[1]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Lf", 1.758L);
+ if (strcmp(result, should_be[2]))
+ {
+ printf("Check 2 \"%%.60Lf\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[2]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Lg", 1.758L);
+ if (strcmp(result, should_be[3]))
+ {
+ printf("Check 3 \"%%.60Lg\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[3]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60La", 1.75L);
+ if (strcmp(result, should_be[4]))
+ {
+ printf("Check 4 \"%%.60La\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[4]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Le", 1.75L);
+ if (strcmp(result, should_be[5]))
+ {
+ printf("Check 5 \"%%.60Le\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[5]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Lf", 1.75L);
+ if (strcmp(result, should_be[6]))
+ {
+ printf("Check 6 \"%%.60Lf\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[6]);
+ failures++;
+ }
+
+ snprintf(result, SIZE, "%.60Lg", 1.75L);
+ if (strcmp(result, should_be[7]))
+ {
+ printf("Check 7 \"%%.60Lg\":\nresult = '%s'\nshould be = '%s'\n", result, should_be[7]);
+ failures++;
+ }
+
+ printf("%d checks failed.\n", failures);
+
+
+ return failures;
+}
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/tscanf3.c djgpp/tests/libc/ansi/stdio/tscanf3.c
--- djgpp.orig/tests/libc/ansi/stdio/tscanf3.c 2012-12-24 19:09:56 +0100
+++ djgpp/tests/libc/ansi/stdio/tscanf3.c 2014-01-09 22:01:46 +0100
@@ -32,11 +32,12 @@ int main(void)
{ 2012, "diciembre", 21, 1, 2, 3}, /* spanish */
{ 2012, "Dezember", 21, 1, 2, 3}, /* german */
{ 2012, "december", 21, 1, 2, 3} /* english */
};
char month[10];
- int year, day, hour, min, sec, i, status;
+ int year, day, hour, min, sec;
+ size_t i, status;
for (status = i = 0; i < (sizeof buffer / sizeof buffer[0]);)
{
printf("This string will be scanned:\n%s\n\n", buffer[i]);
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/tsnprtf.c djgpp/tests/libc/ansi/stdio/tsnprtf.c
--- djgpp.orig/tests/libc/ansi/stdio/tsnprtf.c 2002-06-08 15:54:30 +0100
+++ djgpp/tests/libc/ansi/stdio/tsnprtf.c 2014-01-09 22:01:46 +0100
@@ -10,11 +10,11 @@
int
main (void)
{
char BIG[] = "Hello this is a too big string for the buffer";
char holder[24];
- int i, j;
+ size_t i, j;
i = snprintf(holder, sizeof(holder), "%s\n", BIG);
printf("%s\n", BIG);
printf("%s\n", holder);
/*
@@ -25,11 +25,11 @@ main (void)
*/
if (i != strlen(BIG) + 1 /* nul */)
{
fprintf(stderr, "FAILED snprintf\n");
fprintf(stderr,
- "sizeof (%lu), snprintf(%d), strlen(%lu)\n",
+ "sizeof (%lu), snprintf(%zd), strlen(%lu)\n",
sizeof(holder), i, strlen(BIG)) ;
exit(EXIT_FAILURE);
}
/*
@@ -48,17 +48,17 @@ main (void)
printf(line);
j = printf(holder);
if (i != j)
{
fprintf(stderr, "FAILED snprintf\n");
- fprintf(stderr, "snprintf (%d) != printf (%d)\n", i, j);
+ fprintf(stderr, "snprintf (%zd) != printf (%zd)\n", i, j);
exit(EXIT_FAILURE);
}
}
else
{
- printf("sscanf (%d)\n", i);
+ printf("sscanf (%zd)\n", i);
printf("FAILED sscanf\n");
exit(EXIT_FAILURE);
}
}
@@ -97,34 +97,34 @@ main (void)
exit(EXIT_FAILURE);
}
/* Test padding a field to larger than buffer size. */
{
- int s = sizeof(holder) * 16;
+ size_t s = sizeof(holder) * 16;
- i = snprintf(holder, sizeof(holder), "%*s", s, BIG);
+ i = snprintf(holder, sizeof(holder), "%*s", (int)s, BIG);
if ((i != s) || ((strlen(holder) + 1) != sizeof(holder)))
{
fprintf(stderr,
- "FAILED with padding larger than buffer: %d output, "
+ "FAILED with padding larger than buffer: %zd output, "
"%lu written to buffer\n",
i, strlen(holder));
exit(EXIT_FAILURE);
}
}
/* Test precision to larger than buffer size. */
{
- int s = sizeof(holder) * 4;
+ size_t s = sizeof(holder) * 4;
- i = snprintf(holder, sizeof(holder), "%*.*e", s, s, 1e0);
+ i = snprintf(holder, sizeof(holder), "%*.*e", (int)s, (int)s, 1e0);
if ((i <= s) || ((strlen(holder) + 1) != sizeof(holder)))
{
fprintf(stderr,
- "FAILED with precision larger than buffer: %d output, "
+ "FAILED with precision larger than buffer: %zd output, "
"%lu written to buffer\n",
i, strlen(holder));
exit(EXIT_FAILURE);
}
}
- Raw text -