Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -38,11 +38,10 @@ enable_shared="no" enable_threads="no" enable_sockets="no" enable_files="no" - ac_cv_snprintf_useful_ret="yes" ;; m68k-*-amigaos*) AS_IF([test x"$OBJCFLAGS" = x""], [ OBJCFLAGS="-O0" ]) @@ -52,11 +51,10 @@ LDFLAGS="$LDFLAGS -noixemul" enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" - ac_cv_snprintf_useful_ret="yes" AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt68k.library) AC_SUBST(SFDC_TARGET, m68k-amigaos) AC_SUBST(SFD_FILE, amigaos3.sfd) @@ -828,46 +826,28 @@ AC_CHECK_LIB(m, fmod, LIBS="$LIBS -lm") AC_CHECK_LIB(complex, creal, TESTS_LIBS="$TESTS_LIBS -lcomplex") AC_CHECK_FUNC(asprintf, [ case "$host" in + *-*-mingw*) + dnl asprintf from MinGW is broken on older Windows + dnl versions + have_asprintf="no" + ;; *-psp-*) - dnl asprintf is broken on the PSP, but snprintf works. + dnl asprintf is broken on the PSP have_asprintf="no" - ac_cv_snprintf_useful_ret="yes" ;; *) have_asprintf="yes" AC_DEFINE(HAVE_ASPRINTF, 1, [Whether we have asprintf()]) ;; esac ], [ have_asprintf="no" - - AC_MSG_CHECKING(whether snprintf returns something useful) - AC_CACHE_VAL(ac_cv_snprintf_useful_ret, [ - AC_TRY_RUN([ - #include - - int - main() - { - return (snprintf(NULL, 0, "asd") == 3 ? 0 : 1); - } - ], [ - ac_cv_snprintf_useful_ret="yes" - ], [ - ac_cv_snprintf_useful_ret="no" - ], [ - ac_cv_snprintf_useful_ret="no" - ]) - ]) - AC_MSG_RESULT($ac_cv_snprintf_useful_ret) -]) -test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \ - AC_MSG_ERROR(No asprintf and no snprintf returning required space!) +]) AC_ARG_ENABLE(unicode-tables, AS_HELP_STRING([--disable-unicode-tables], [Disable Unicode tables])) AS_IF([test x"$enable_unicode_tables" != x"no"], [ AC_DEFINE(OF_HAVE_UNICODE_TABLES, 1, Index: src/of_asprintf.m ================================================================== --- src/of_asprintf.m +++ src/of_asprintf.m @@ -97,21 +97,47 @@ #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { - int length; + int expectedLength, length; va_list argumentsCopy; va_copy(argumentsCopy, arguments); - if ((length = vsnprintf(NULL, 0, format, argumentsCopy)) < 0) - return length; - if ((*string = malloc((size_t)length + 1)) == NULL) + expectedLength = vsnprintf(NULL, 0, format, argumentsCopy); + if (expectedLength == -1) + /* + * We have no way to know how large it is. Let's try 64 KB and + * hope. + */ + expectedLength = 65535; + + if ((*string = malloc((size_t)expectedLength + 1)) == NULL) + return -1; + + length = vsnprintf(*string, (size_t)expectedLength + 1, + format, arguments); + + if (length == -1 || length > expectedLength) { + free(*string); + *string = NULL; return -1; + } - return vsnprintf(*string, (size_t)length + 1, format, arguments); + /* + * In case we could not determine the size, resize to the actual size + * needed, but ignore any failure to do so. + */ + if (length < expectedLength) { + char *resized; + + if ((resized = realloc(*string, length + 1)) != NULL) + *string = resized; + } + + return length; } static int asprintf(char **string, const char *format, ...) { @@ -549,10 +575,13 @@ default: return false; } #ifndef HAVE_ASPRINTF_L + if (tmpLen == -1) + return false; + /* * If there's no asprintf_l, we have no other choice than to * use this ugly hack to replace the locale's decimal point * back to ".". */