From 1c6b9baa733fe04d9faf2aa140ffbdf26d100372 Mon Sep 17 00:00:00 2001 From: Meep-Eep Date: Sat, 28 Nov 2009 18:00:46 +0000 Subject: [PATCH] Make snprintf/vsnprintf more compatible with the C standard on MSVC. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3361 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/libs/uio/uioport.h | 33 +++++++++++++++++++++++++++++---- sc2/src/port.c | 33 +++++++++++++++++++++++++++++++++ sc2/src/port.h | 9 +++++---- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/sc2/src/libs/uio/uioport.h b/sc2/src/libs/uio/uioport.h index e0e2f56b7..ebdbec5be 100644 --- a/sc2/src/libs/uio/uioport.h +++ b/sc2/src/libs/uio/uioport.h @@ -171,11 +171,36 @@ typedef unsigned short mode_t; // String formatting #ifdef _MSC_VER -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#endif +# include +# include +// MSVC does not have snprintf() and vsnprintf(). It does have a _snprintf() +// and _vsnprintf(), but these do not terminate a truncated string as +// the C standard prescribes. +static inline int +snprintf(char *str, size_t size, const char *format, ...) +{ + int result; + va_list args; + + va_start (args, format); + result = _vsnprintf (str, size, format, args); + if (str != NULL && size != 0) + str[size - 1] = '\0'; + va_end (args); + + return result; +} + +static inline int +vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + int result = _vsnprintf (str, size, format, args); + if (str != NULL && size != 0) + str[size - 1] = '\0'; + return result; +} +#endif /* _MSC_VER */ #endif /* _UIOPORT_H */ - diff --git a/sc2/src/port.c b/sc2/src/port.c index e7aeaa394..dc25f1639 100644 --- a/sc2/src/port.c +++ b/sc2/src/port.c @@ -24,6 +24,10 @@ #include #include +#ifdef _MSC_VER +# include +# include +#endif /* _MSC_VER */ #include #include #if !defined (_MSC_VER) && !defined (HAVE_READDIR_R) @@ -110,3 +114,32 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { } #endif +#ifdef _MSC_VER +// MSVC does not have snprintf() and vsnprintf(). It does have a _snprintf() +// and _vsnprintf(), but these do not terminate a truncated string as +// the C standard prescribes. +int +snprintf(char *str, size_t size, const char *format, ...) +{ + int result; + va_list args; + + va_start (args, format); + result = _vsnprintf (str, size, format, args); + if (str != NULL && size != 0) + str[size - 1] = '\0'; + va_end (args); + + return result; +} + +int +vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + int result = _vsnprintf (str, size, format, args); + if (str != NULL && size != 0) + str[size - 1] = '\0'; + return result; +} +#endif /* _MSC_VER */ + diff --git a/sc2/src/port.h b/sc2/src/port.h index 2d805ae36..5f6522334 100644 --- a/sc2/src/port.h +++ b/sc2/src/port.h @@ -140,11 +140,12 @@ typedef unsigned short mode_t; # include #endif -// Printf +// String formatting #ifdef _MSC_VER -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#endif +// Defined in port.c +int snprintf(char *str, size_t size, const char *format, ...); +int vsnprintf(char *str, size_t size, const char *format, va_list args); +#endif /* _MSC_VER */ // setenv() #ifndef HAVE_SETENV