delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019