Windows specific vsnprintf fixes.
authorErik de Castro Lopo <erikd@mega-nerd.com>
Mon, 22 Sep 2014 08:29:32 +0000 (18:29 +1000)
committerErik de Castro Lopo <erikd@mega-nerd.com>
Mon, 22 Sep 2014 08:29:36 +0000 (18:29 +1000)
* Changes flac_snprintf (in src/share/grabbag/snprintf.c) and its copy
  local_snprintf (src/libFLAC/metadata_iterators.c) to be almost sane.

* Adds flac_vsnprintf (src/share/grabbag/snprintf.c) and its copy
  local_vsnprintf (src/share/win_utf8_io/win_utf8_io.c).

* Changes stats_print_info in src/flac/utils.c so it uses flac_vsnprintf
  instead of vsnprintf. This makes return value checking unnecessary.

Patch-from: lvqcl <lvqcl.mail@gmail.com>

include/share/compat.h
src/flac/utils.c
src/libFLAC/metadata_iterators.c
src/share/grabbag/snprintf.c
src/share/win_utf8_io/win_utf8_io.c

index 3ae9d8d..db5f7ca 100644 (file)
  *
  * This function wraps the MS version to behave more like the the ISO version.
  */
+#include <stdarg.h>
 #ifdef __cplusplus
 extern "C" {
 #endif
 int flac_snprintf(char *str, size_t size, const char *fmt, ...);
+int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
 #ifdef __cplusplus
 };
 #endif
index d0102b4..59dd845 100644 (file)
@@ -247,12 +247,8 @@ void stats_print_info(int level, const char *format, ...)
        if (flac__utils_verbosity_ >= level) {
                va_list args;
                va_start(args, format);
-               len = vsnprintf(tmp, sizeof(tmp), format, args);
+               len = flac_vsnprintf(tmp, sizeof(tmp), format, args);
                va_end(args);
-               if (len < 0 || len == sizeof(tmp)) {
-                       tmp[sizeof(tmp)-1] = '\0';
-                       len = sizeof(tmp)-1;
-               }
                stats_clear();
                if (len >= console_chars_left) {
                        clear_len = console_chars_left;
index 778bb8c..d50df39 100644 (file)
@@ -3201,13 +3201,18 @@ static int
 local_snprintf(char *str, size_t size, const char *fmt, ...)
 {
        va_list va;
-       int rc ;
+       int rc;
 
        va_start (va, fmt);
 
-#ifdef _MSC_VER
+#if defined _MSC_VER
+       if (size == 0)
+               return 1024;
        rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
-       rc = (rc > 0) ? rc : (size == 0 ? 1024 : size * 2);
+       if (rc < 0)
+               rc = size - 1;
+#elif defined __MINGW32__
+       rc = __mingw_vsnprintf (str, size, fmt, va);
 #else
        rc = vsnprintf (str, size, fmt, va);
 #endif
index 3a0661f..d19e42c 100644 (file)
@@ -49,7 +49,7 @@
  * does not over-write the end of the buffer. MS's snprintf_s in this case
  * returns -1.
  *
- * The _MSC_VER code below attempts to modify the return code for snprintf_s
+ * The _MSC_VER code below attempts to modify the return code for vsnprintf_s
  * to something that is more compatible with the behaviour of the ISO C version.
  */
 
@@ -57,13 +57,18 @@ int
 flac_snprintf(char *str, size_t size, const char *fmt, ...)
 {
        va_list va;
-       int rc ;
+       int rc;
 
        va_start (va, fmt);
 
-#ifdef _MSC_VER
+#if defined _MSC_VER
+       if (size == 0)
+               return 1024;
        rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
-       rc = (rc > 0) ? rc : (size == 0 ? 1024 : size * 2);
+       if (rc < 0)
+               rc = size - 1;
+#elif defined __MINGW32__
+       rc = __mingw_vsnprintf (str, size, fmt, va);
 #else
        rc = vsnprintf (str, size, fmt, va);
 #endif
@@ -71,3 +76,23 @@ flac_snprintf(char *str, size_t size, const char *fmt, ...)
 
        return rc;
 }
+
+int
+flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
+{
+       int rc;
+
+#if defined _MSC_VER
+       if (size == 0)
+               return 1024;
+       rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
+       if (rc < 0)
+               rc = size - 1;
+#elif defined __MINGW32__
+       rc = __mingw_vsnprintf (str, size, fmt, va);
+#else
+       rc = vsnprintf (str, size, fmt, va);
+#endif
+
+       return rc;
+}
index 31b4443..d7a2d09 100644 (file)
 
 #include "share/win_utf8_io.h"
 
+#define UTF8_BUFFER_SIZE 32768
+
+static
+int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
+{
+       int rc;
+
+#if defined _MSC_VER
+       if (size == 0)
+               return 1024;
+       rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
+       if (rc < 0)
+               rc = size - 1;
+#elif defined __MINGW32__
+       rc = __mingw_vsnprintf (str, size, fmt, va);
+#else
+       rc = vsnprintf (str, size, fmt, va);
+#endif
+
+       return rc;
+}
+
 static UINT win_utf8_io_codepage = CP_ACP;
 
 /* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */
@@ -177,9 +199,9 @@ int printf_utf8(const char *format, ...)
 
        while (1) {
                va_list argptr;
-               if (!(utmp = (char *)malloc(32768*sizeof(char)))) break;
+               if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
                va_start(argptr, format);
-               ret = vsnprintf_s(utmp, 32768, _TRUNCATE, format, argptr);
+               ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
                va_end(argptr);
                if (ret < 0) break;
                if (!(wout = wchar_from_utf8(utmp))) {
@@ -203,9 +225,9 @@ int fprintf_utf8(FILE *stream, const char *format, ...)
 
        while (1) {
                va_list argptr;
-               if (!(utmp = (char *)malloc(32768*sizeof(char)))) break;
+               if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
                va_start(argptr, format);
-               ret = vsnprintf_s(utmp, 32768, _TRUNCATE, format, argptr);
+               ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
                va_end(argptr);
                if (ret < 0) break;
                if (!(wout = wchar_from_utf8(utmp))) {
@@ -228,8 +250,8 @@ int vfprintf_utf8(FILE *stream, const char *format, va_list argptr)
        int ret = -1;
 
        while (1) {
-               if (!(utmp = (char *)malloc(32768*sizeof(char)))) break;
-               if ((ret = vsnprintf_s(utmp, 32768, _TRUNCATE, format, argptr)) < 0) break;
+               if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
+               if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) < 0) break;
                if (!(wout = wchar_from_utf8(utmp))) {
                        ret = -1;
                        break;