aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2011-06-01 22:04:31 +0200
committerJohannes Schickel2011-06-01 22:18:28 +0200
commitd2a8e8023e0f1173746c31eb7232d24cc544d2c9 (patch)
tree73bc771f5f493a0b3b1b5d724e8f7a07d8e1c0d1
parentc0d70b6dbb4dc18b74e810015472eae30785ec69 (diff)
downloadscummvm-rg350-d2a8e8023e0f1173746c31eb7232d24cc544d2c9.tar.gz
scummvm-rg350-d2a8e8023e0f1173746c31eb7232d24cc544d2c9.tar.bz2
scummvm-rg350-d2a8e8023e0f1173746c31eb7232d24cc544d2c9.zip
COMMON: Implement two simple workaround wrappers for _vsnprintf and _snprintf for MSVC.
This should assure vsnprintf and snprintf will now also always null terminate the result even for MSVC. Currently the functions are placed in scummsys.h, but that causes us to include two standard C library headers there (for MSVC at least). This is not particulary nice, so we should think of a better solution here.
-rw-r--r--common/scummsys.h46
1 files changed, 31 insertions, 15 deletions
diff --git a/common/scummsys.h b/common/scummsys.h
index b6d5263791..a425befecf 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -40,26 +40,42 @@
#if defined(WIN32)
#ifdef _MSC_VER
- // vnsprintf was introduced with Visual Studio 2008. The 2003 edition
- // only included a function called _vsnprintf. We do not officially
- // support MSVC 2003 anymore, but it should not hurt to still have
- // this around here.
- #if (_MSC_VER < 1500)
- #define vsnprintf _vsnprintf
- #endif
+
+ // FIXME: The placement of the workaround functions for MSVC below
+ // require us to include stdio.h and stdarg.h for MSVC here. This
+ // is not exactly nice...
+ // We should think of a better way of doing this.
+ #include <stdio.h>
+ #include <stdarg.h>
+
+ // MSVC's vsnprintf is either non-existant (2003) or bugged since it
+ // does not always include a terminating NULL (2005+). To work around
+ // that we fix up the _vsnprintf included. Note that the return value
+ // will still not match C99's specs!
+ inline int vsnprintf_msvc(char *str, size_t size, const char *format, va_list args) {
+ // We do not pass size - 1 here, to ensure we would get the same
+ // return value as when we would use _vsnprintf directly, since
+ // for example Common::String::format relies on this.
+ int retValue = _vsnprintf(str, size, format, args);
+ str[size - 1] = 0;
+ return retValue;
+ }
+
+ #define vsnprintf vsnprintf_msvc
+
// Visual Studio does not include snprintf in its standard C library.
// Instead it includes a function called _snprintf with somewhat
// similar semantics. The minor difference is that the return value in
// case the formatted string exceeds the buffer size is different.
// A much more dangerous one is that _snprintf does not always include
- // a terminating null (Whoops!).
- //
- // FIXME: Provide a proper snprintf function for MSVC. It should at
- // least always include a terminating null!
- //
- // See here for more details:
- // http://msdn.microsoft.com/en-us/library/2ts7cx93%28v=VS.100%29.aspx
- #define snprintf _snprintf
+ // a terminating null (Whoops!). Instead we map to our fixed vsnprintf.
+ inline int snprintf(char *str, size_t size, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ int len = vsnprintf(str, size, format, args);
+ va_end(args);
+ return len;
+ }
#endif
#if !defined(_WIN32_WCE)