Skip to content

Commit

Permalink
ENH: MSVS 2013 snprintf compatible substitute
Browse files Browse the repository at this point in the history
Simplify the backwards compatible snprintf configuration for pre
1900 version of MSVC.  Otherwise prefer C++11 syntax using std::snprintf.
  • Loading branch information
hjmjohnson authored and cdunn2001 committed Dec 30, 2018
1 parent ccd077f commit 5c8e539
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 27 deletions.
8 changes: 8 additions & 0 deletions include/json/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
#define JSON_API
#endif

#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...);
# define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
# define jsoncpp_snprintf std::snprintf
#endif

// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
Expand Down
12 changes: 2 additions & 10 deletions src/jsontestrunner/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ struct Options {

static JSONCPP_STRING normalizeFloatingPointStr(double value) {
char buffer[32];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "%.16g", value);
#else
snprintf(buffer, sizeof(buffer), "%.16g", value);
#endif
jsoncpp_snprintf(buffer, sizeof(buffer), "%.16g", value);
buffer[sizeof(buffer) - 1] = 0;
JSONCPP_STRING s(buffer);
JSONCPP_STRING::size_type index = s.find_last_of("eE");
Expand Down Expand Up @@ -105,11 +101,7 @@ static void printValueTree(FILE* fout,
Json::ArrayIndex size = value.size();
for (Json::ArrayIndex index = 0; index < size; ++index) {
static char buffer[16];
#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "[%u]", index);
#else
snprintf(buffer, sizeof(buffer), "[%u]", index);
#endif
jsoncpp_snprintf(buffer, sizeof(buffer), "[%u]", index);
printValueTree(fout, value[index], path + buffer);
}
} break;
Expand Down
13 changes: 3 additions & 10 deletions src/lib_json/json_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,14 @@
#if __cplusplus >= 201103L
#include <cstdio>

#if !defined(snprintf)
#define snprintf std::snprintf
#endif

#if !defined(sscanf)
#define sscanf std::sscanf
#endif
#else
#include <stdio.h>
#include <cstdio>

#if defined(_MSC_VER)
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#if !defined(snprintf)
#define snprintf _snprintf
#endif
#endif
#endif

Expand Down Expand Up @@ -813,7 +806,7 @@ JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const {
int line, column;
getLocationLineAndColumn(location, line, column);
char buffer[18 + 16 + 16 + 1];
snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
return buffer;
}

Expand Down Expand Up @@ -1833,7 +1826,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
int line, column;
getLocationLineAndColumn(location, line, column);
char buffer[18 + 16 + 16 + 1];
snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
return buffer;
}

Expand Down
23 changes: 23 additions & 0 deletions src/lib_json/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,29 @@
#include <algorithm> // min()
#include <cstddef> // size_t

// Provide implementation equivalent of std::snprintf for older _MSC compilers
#if defined(_MSC_VER) && _MSC_VER < 1900
#include <stdarg.h>
static int msvc_pre1900_c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}

int JSON_API msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
va_list ap;
va_start(ap, format);
const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif

// Disable warning C4702 : unreachable code
#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above
#pragma warning(disable : 4702)
Expand Down
8 changes: 1 addition & 7 deletions src/lib_json/json_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
#define isfinite std::isfinite
#endif

#if !defined(snprintf)
#define snprintf std::snprintf
#endif
#else
#include <math.h>
#include <stdio.h>
Expand All @@ -46,9 +43,6 @@
#endif

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#if !defined(snprintf)
#define snprintf _snprintf
#endif
#endif

#if defined(__sun) && defined(__SVR4) // Solaris
Expand Down Expand Up @@ -145,7 +139,7 @@ JSONCPP_STRING valueToString(double value,

JSONCPP_STRING buffer(size_t(36), '\0');
while (true) {
int len = snprintf(
int len = jsoncpp_snprintf(
&*buffer.begin(), buffer.size(),
(precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
precision, value);
Expand Down

0 comments on commit 5c8e539

Please sign in to comment.