From 18f173e3e61e1dc571c19b15b62314ca2f75d248 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 10 Jul 2017 10:30:49 +0800 Subject: [PATCH] Fixed vsnprintf compatibility with vc12 and vc14 (#18040) * Fixed vsnprintf compatibility with vc12 and vc14 see reference: https://github.com/halx99/cocos2d-x/pull/30 * Update CCConsole.cpp * Add comment. --- cocos/base/CCConsole.cpp | 43 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/cocos/base/CCConsole.cpp b/cocos/base/CCConsole.cpp index 0a48afa7ae..b6a085bc06 100644 --- a/cocos/base/CCConsole.cpp +++ b/cocos/base/CCConsole.cpp @@ -128,26 +128,39 @@ namespace { { int bufferSize = MAX_LOG_LENGTH; char* buf = nullptr; - + int nret = 0; do { buf = new (std::nothrow) char[bufferSize]; if (buf == nullptr) - return; // not enough memory - - int ret = vsnprintf(buf, bufferSize - 3, format, args); - if (ret < 0) - { - bufferSize *= 2; - - delete [] buf; + return; + /* + pitfall: The behavior of vsnprintf between VS2013 and VS2015/2017 is different + VS2013 or Unix-Like System will return -1 when buffer not enough, but VS2015/2017 will return the actural needed length for buffer at this station + The _vsnprintf behavior is compatible API which always return -1 when buffer isn't enough at VS2013/2015/2017 + Yes, The vsnprintf is more efficient implemented by MSVC 19.0 or later, AND it's also standard-compliant, see reference: http://www.cplusplus.com/reference/cstdio/vsnprintf/ + */ + nret = vsnprintf(buf, bufferSize - 3, format, args); + if (nret >= 0) + { // VS2015/2017 + if (nret <= bufferSize - 3) + {// success, so don't need to realloc + break; + } + else + { + bufferSize = nret + 3; + delete[] buf; + } + } + else // < 0 + { // VS2013 or Unix-like System(GCC) + bufferSize *= 2; + delete[] buf; } - else - break; - } while (true); - - strcat(buf, "\n"); + buf[nret] = '\n'; + buf[++nret] = '\0'; #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID __android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", "%s", buf); @@ -155,7 +168,7 @@ namespace { #elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT int pos = 0; - int len = strlen(buf); + int len = nret; char tempBuf[MAX_LOG_LENGTH + 1] = { 0 }; WCHAR wszBuf[MAX_LOG_LENGTH + 1] = { 0 };