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 <[EMAIL PROTECTED]> * 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. */