From e8955f17eaa5600ce533fb6dd0c3f7b39dc160bd Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Fri, 11 Oct 2013 04:06:52 -0400 Subject: [PATCH] More cleanups, gmqcc.h doesn't need to include stdio.h now! --- ansi.c | 28 ++++++++++++++++++++++++ gmqcc.h | 2 +- msvc.c | 24 ++++++++++++++++++++ platform.h | 1 + util.c | 64 ++---------------------------------------------------- 5 files changed, 56 insertions(+), 63 deletions(-) diff --git a/ansi.c b/ansi.c index a6b2eda..52399df 100644 --- a/ansi.c +++ b/ansi.c @@ -25,6 +25,7 @@ #include #include "platform.h" +#include "gmqcc.h" int platform_vsnprintf(char *buffer, size_t bytes, const char *format, va_list arg) { return vsnprintf(buffer, bytes, format, arg); @@ -72,6 +73,33 @@ int platform_snprintf(char *src, size_t bytes, const char *format, ...) { return rt; } +int platform_vasprintf(char **dat, const char *fmt, va_list args) { + int ret; + int len; + char *tmp = NULL; + char buf[128]; + va_list cpy; + + va_copy(cpy, args); + len = vsnprintf(buf, sizeof(buf), fmt, cpy); + va_end (cpy); + + if (len < (int)sizeof(buf)) { + *dat = util_strdup(buf); + return len; + } + + tmp = (char*)mem_a(len + 1); + if ((ret = vsnprintf(tmp, len + 1, fmt, args)) != len) { + mem_d(tmp); + *dat = NULL; + return -1; + } + + *dat = tmp; + return len; +} + char *platform_strcat(char *dest, const char *src) { return strcat(dest, src); } diff --git a/gmqcc.h b/gmqcc.h index b7f1f8f..3649ea4 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -24,7 +24,7 @@ #ifndef GMQCC_HDR #define GMQCC_HDR #include -#include /* TODO: remove this */ +#include /* * Disable some over protective warnings in visual studio because fixing them is a waste diff --git a/msvc.c b/msvc.c index 225cd1c..2c6a3ed 100644 --- a/msvc.c +++ b/msvc.c @@ -101,6 +101,30 @@ int platform_snprintf(char *src, size_t bytes, const char *format, ...) { return rt; } +/* + * TODO: this isn't exactly 'accurate' for MSVC but it seems to work, + * at least to some extent. + */ +int platform_vasprintf(char **dat, const char *fmt, va_list args) { + int ret; + int len; + char *tmp = NULL; + + if ((len = _vscprintf(fmt, args)) < 0) { + *dat = NULL; + return -1; + } + + tmp = (char*)mem_a(len + 1); + if ((ret = _vsnprintf_s(tmp, len+1, len+1, fmt, args)) != len) { + mem_d(tmp); + *dat = NULL; + return -1; + } + *dat = tmp; + return len; +} + char *platform_strcat(char *dest, const char *src) { strcat_s(dest, strlen(src), src); return dest; diff --git a/platform.h b/platform.h index e2aee71..f1116ad 100644 --- a/platform.h +++ b/platform.h @@ -76,6 +76,7 @@ char *platform_strncat(char *dest, const char *src, size_t num); const char *platform_tmpnam(char *str); const char *platform_getenv(char *var); int platform_snprintf(char *src, size_t bytes, const char *format, ...); +int platform_vasprintf(char **dat, const char *fmt, va_list args); char *platform_strcat(char *dest, const char *src); char *platform_strncpy(char *dest, const char *src, size_t num); const char *platform_strerror(int err); diff --git a/util.c b/util.c index f454ae7..113bc93 100644 --- a/util.c +++ b/util.c @@ -25,6 +25,7 @@ #include #include "gmqcc.h" +#include "platform.h" /* * Initially this was handled with a table in the gmqcc.h header, but @@ -224,72 +225,11 @@ size_t util_optimizationtostr(const char *in, char *out, size_t outsz) { return util_strtransform(in, out, outsz, "_ ", 'a'-'A'); } -/* - * Portable implementation of vasprintf/asprintf. Assumes vsnprintf - * exists, otherwise compiler error. - * - * TODO: fix for MSVC .... - */ -int util_vasprintf(char **dat, const char *fmt, va_list args) { - int ret; - int len; - char *tmp = NULL; - - /* - * For visual studio _vsnprintf doesn't tell you the length of a - * formatted string if it overflows. However there is a MSVC - * intrinsic (which is documented wrong) called _vcsprintf which - * will return the required amount to allocate. - */ - #ifdef _MSC_VER - if ((len = _vscprintf(fmt, args)) < 0) { - *dat = NULL; - return -1; - } - - tmp = (char*)mem_a(len + 1); - if ((ret = _vsnprintf_s(tmp, len+1, len+1, fmt, args)) != len) { - mem_d(tmp); - *dat = NULL; - return -1; - } - *dat = tmp; - return len; - #else - /* - * For everything else we have a decent conforming vsnprintf that - * returns the number of bytes needed. We give it a try though on - * a short buffer, since efficiently speaking, it could be nice to - * above a second vsnprintf call. - */ - char buf[128]; - va_list cpy; - va_copy(cpy, args); - len = vsnprintf(buf, sizeof(buf), fmt, cpy); - va_end (cpy); - - if (len < (int)sizeof(buf)) { - *dat = util_strdup(buf); - return len; - } - - /* not large enough ... */ - tmp = (char*)mem_a(len + 1); - if ((ret = vsnprintf(tmp, len + 1, fmt, args)) != len) { - mem_d(tmp); - *dat = NULL; - return -1; - } - - *dat = tmp; - return len; - #endif -} int util_asprintf(char **ret, const char *fmt, ...) { va_list args; int read; va_start(args, fmt); - read = util_vasprintf(ret, fmt, args); + read = platform_vasprintf(ret, fmt, args); va_end (args); return read; -- 2.39.2