bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: vasnprintf fix


From: Bruno Haible
Subject: Re: vasnprintf fix
Date: Tue, 6 Nov 2007 00:45:57 +0100
User-agent: KMail/1.5.4

Hello Eric,

> Something's still fishy.  Now I'm getting aborts for test-vasprintf-posix.c 
> on 
> cygwin, with the following sequence of instructions in vasnprintf.c:
> 
> Breakpoint 1, test_function (my_asprintf=0x413052 <my_asprintf>)
>     at ../../tests/test-vasprintf-posix.c:173
> 173       int retval =
>       my_asprintf (&result, "%a %d", 3.1416015625, 33, 44, 55);
> 
> 
> 2690                  if (type == TYPE_LONGDOUBLE)
> (gdb) 
> 3055                      double arg = a.arg[dp->arg_index].a.a_double;
> (gdb) 
> 3057                      if (isnan (arg))
> (gdb) 
> 3070                          int sign = 0;
> (gdb) 
> 3072                          if (signbit (arg)) /* arg < 0.0 or negative 
> zero */
> (gdb) 
> 3078                          if (sign < 0)
> (gdb) 
> 3080                          else if (flags & FLAG_SHOWSIGN)
> (gdb) 
> 3082                          else if (flags & FLAG_SPACE)
> (gdb) 
> 3085                          if (arg > 0.0 && arg + arg == arg)
> (gdb) 
> 3099                              pad_ptr = p;
> (gdb) 
> 3101                              if (dp->conversion == 'f' || dp->conversion 
> == 'F')
> (gdb) 
> 3136                              else if (dp->conversion == 'e' || dp-
> >conversion == 'E')
> (gdb) 
> 3246                              else if (dp->conversion == 'g' || dp-
> >conversion == 'G')
> (gdb) 
> 3421                                abort ();
> (gdb) 

Now that you say it, it's obvious what is going on: the code has first
decided that it doesn't need the 'a'/'A' substitute (since Cygwin already
has it) and then decided that it needs to emulate 'A'/'A' (because Cygwin
either crashes in low-memory situations or has a crippled handling of the
precision).

Thanks for the single-stepping. I'm committing this, which will hopefully
fix it (untested).

2007-11-05  Bruno Haible  <address@hidden>

        * lib/vasnprintf.c (VASNPRINTF): Expand the NEED_PRINTF_DIRECTIVE_A
        code when NEED_PRINTF_LONG_DOUBLE or NEED_PRINTF_DOUBLE is set.
        Needed on Cygwin, where !NEED_PRINTF_DIRECTIVE_A && NEED_PRINTF_DOUBLE.
        Reported by Eric Blake.

*** lib/vasnprintf.c.orig       2007-11-06 00:40:28.000000000 +0100
--- lib/vasnprintf.c    2007-11-06 00:29:22.000000000 +0100
***************
*** 104,113 ****
  # include "fpucw.h"
  #endif
  
! #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
  # include <math.h>
  # include "isnan.h"
  # include "printf-frexp.h"
  # include "isnanl-nolibm.h"
  # include "printf-frexpl.h"
  # include "fpucw.h"
--- 104,117 ----
  # include "fpucw.h"
  #endif
  
! #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
  # include <math.h>
  # include "isnan.h"
  # include "printf-frexp.h"
+ #endif
+ 
+ #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined 
IN_LIBINTL
+ # include <math.h>
  # include "isnanl-nolibm.h"
  # include "printf-frexpl.h"
  # include "fpucw.h"
***************
*** 2033,2040 ****
                  }
              }
  #endif
! #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
!           else if (dp->conversion == 'a' || dp->conversion == 'A')
              {
                arg_type type = a.arg[dp->arg_index].type;
                int flags = dp->flags;
--- 2037,2055 ----
                  }
              }
  #endif
! #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || 
NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
!           else if ((dp->conversion == 'a' || dp->conversion == 'A')
! # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && 
NEED_PRINTF_DOUBLE))
!                    && (0
! #  if NEED_PRINTF_DOUBLE
!                        || a.arg[dp->arg_index].type == TYPE_DOUBLE
! #  endif
! #  if NEED_PRINTF_LONG_DOUBLE
!                        || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
! #  endif
!                       )
! # endif
!                   )
              {
                arg_type type = a.arg[dp->arg_index].type;
                int flags = dp->flags;
***************
*** 2152,2157 ****
--- 2167,2173 ----
                p = tmp;
                if (type == TYPE_LONGDOUBLE)
                  {
+ # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
                    long double arg = a.arg[dp->arg_index].a.a_longdouble;
  
                    if (isnanl (arg))
***************
*** 2271,2277 ****
                                }
                              }
                              *p++ = dp->conversion - 'A' + 'P';
! # if WIDE_CHAR_VERSION
                              {
                                static const wchar_t decimal_format[] =
                                  { '%', '+', 'd', '\0' };
--- 2287,2293 ----
                                }
                              }
                              *p++ = dp->conversion - 'A' + 'P';
! #  if WIDE_CHAR_VERSION
                              {
                                static const wchar_t decimal_format[] =
                                  { '%', '+', 'd', '\0' };
***************
*** 2279,2285 ****
                              }
                              while (*p != '\0')
                                p++;
! # else
                              if (sizeof (DCHAR_T) == 1)
                                {
                                  sprintf ((char *) p, "%+d", exponent);
--- 2295,2301 ----
                              }
                              while (*p != '\0')
                                p++;
! #  else
                              if (sizeof (DCHAR_T) == 1)
                                {
                                  sprintf ((char *) p, "%+d", exponent);
***************
*** 2294,2307 ****
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
                                    p++;
                                }
! # endif
                          }
  
                        END_LONG_DOUBLE_ROUNDING ();
                      }
                  }
                else
                  {
                    double arg = a.arg[dp->arg_index].a.a_double;
  
                    if (isnan (arg))
--- 2310,2327 ----
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
                                    p++;
                                }
! #  endif
                          }
  
                        END_LONG_DOUBLE_ROUNDING ();
                      }
+ # else
+                   abort ();
+ # endif
                  }
                else
                  {
+ # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
                    double arg = a.arg[dp->arg_index].a.a_double;
  
                    if (isnan (arg))
***************
*** 2418,2424 ****
                                }
                              }
                              *p++ = dp->conversion - 'A' + 'P';
! # if WIDE_CHAR_VERSION
                              {
                                static const wchar_t decimal_format[] =
                                  { '%', '+', 'd', '\0' };
--- 2438,2444 ----
                                }
                              }
                              *p++ = dp->conversion - 'A' + 'P';
! #  if WIDE_CHAR_VERSION
                              {
                                static const wchar_t decimal_format[] =
                                  { '%', '+', 'd', '\0' };
***************
*** 2426,2432 ****
                              }
                              while (*p != '\0')
                                p++;
! # else
                              if (sizeof (DCHAR_T) == 1)
                                {
                                  sprintf ((char *) p, "%+d", exponent);
--- 2446,2452 ----
                              }
                              while (*p != '\0')
                                p++;
! #  else
                              if (sizeof (DCHAR_T) == 1)
                                {
                                  sprintf ((char *) p, "%+d", exponent);
***************
*** 2441,2449 ****
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
                                    p++;
                                }
! # endif
                          }
                      }
                  }
                /* The generated string now extends from tmp to p, with the
                   zero padding insertion point being at pad_ptr.  */
--- 2461,2472 ----
                                  for (ep = expbuf; (*p = *ep) != '\0'; ep++)
                                    p++;
                                }
! #  endif
                          }
                      }
+ # else
+                   abort ();
+ # endif
                  }
                /* The generated string now extends from tmp to p, with the
                   zero padding insertion point being at pad_ptr.  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]