diff --git a/cpp/ycm/CustomAssert.cpp b/cpp/ycm/CustomAssert.cpp new file mode 100644 index 00000000..6de9e5b4 --- /dev/null +++ b/cpp/ycm/CustomAssert.cpp @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2008, Power of Two Games LLC +* 2010, Strahinja Markovic +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Power of Two Games LLC nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY POWER OF TWO GAMES LLC ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL POWER OF TWO GAMES LLC BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "CustomAssert.h" +#include +#include + +namespace assert_ns +{ + +namespace +{ + +Assert::FailBehavior DefaultHandler(const char* condition, + const char* msg, + const char* file, + const int line) +{ + std::printf("%s(%d): Assert Failure: ", file, line); + + if (condition != NULL) + std::printf("'%s' ", condition); + + if (msg != NULL) + std::printf("%s", msg); + + std::printf("\n"); + + return Assert::Halt; +} + +Assert::Handler& GetAssertHandlerInstance() +{ + static Assert::Handler s_handler = &DefaultHandler; + return s_handler; +} + +} + +Assert::Handler Assert::GetHandler() +{ + return GetAssertHandlerInstance(); +} + +void Assert::SetHandler(Assert::Handler newHandler) +{ + GetAssertHandlerInstance() = newHandler; +} + +Assert::FailBehavior Assert::ReportFailure(const char* condition, + const char* file, + const int line, + const char* msg, ...) +{ + const char* message = NULL; + if (msg != NULL) + { + char messageBuffer[1024]; + { + va_list args; + va_start(args, msg); + +#if defined(_MSC_VER) + vsnprintf_s(messageBuffer, 1024, 1024, msg, args); +#else + vsnprintf(messageBuffer, 1024, msg, args); +#endif + + va_end(args); + } + + message = messageBuffer; + } + + return GetAssertHandlerInstance()(condition, message, file, line); +} + +} diff --git a/cpp/ycm/CustomAssert.h b/cpp/ycm/CustomAssert.h new file mode 100644 index 00000000..df10a51e --- /dev/null +++ b/cpp/ycm/CustomAssert.h @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2008, Power of Two Games LLC +* 2010, Strahinja Markovic +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Power of Two Games LLC nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY POWER OF TWO GAMES LLC ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL POWER OF TWO GAMES LLC BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CUSTOM_ASSERT_H +#define CUSTOM_ASSERT_H + +namespace assert_ns { namespace Assert +{ + +enum FailBehavior +{ + Halt, + Continue, +}; + +typedef FailBehavior (*Handler)(const char* condition, + const char* msg, + const char* file, + int line); + +Handler GetHandler(); +void SetHandler(Handler newHandler); + +FailBehavior ReportFailure(const char* condition, + const char* file, + int line, + const char* msg, ...); +}} + +#if defined(_MSC_VER) +# define X_HALT() __debugbreak() +#elif defined(__GNUC__) +# define X_HALT() __builtin_trap() +#else +# define X_HALT() exit(__LINE__) +#endif + +#define X_UNUSED(x) do { (void)sizeof(x); } while(0) + +#ifndef NDEBUG + #define X_ASSERT(cond) \ + do \ + { \ + if (!(cond)) \ + { \ + if (assert_ns::Assert::ReportFailure(#cond, __FILE__, __LINE__, 0) == \ + assert_ns::Assert::Halt) \ + X_HALT(); \ + } \ + } while(0) + + #define X_ASSERT_MSG(cond, msg, ...) \ + do \ + { \ + if (!(cond)) \ + { \ + if (assert_ns::Assert::ReportFailure(#cond, __FILE__, __LINE__, (msg), __VA_ARGS__) == \ + assert_ns::Assert::Halt) \ + X_HALT(); \ + } \ + } while(0) + + #define X_ASSERT_FAIL(msg, ...) \ + do \ + { \ + if (assert_ns::Assert::ReportFailure(0, __FILE__, __LINE__, (msg), __VA_ARGS__) == \ + assert_ns::Assert::Halt) \ + X_HALT(); \ + } while(0) + + #define X_VERIFY(cond) X_ASSERT(cond) + #define X_VERIFY_MSG(cond, msg, ...) X_ASSERT_MSG(cond, msg, ##__VA_ARGS__) +#else + #define X_ASSERT(condition) \ + do { X_UNUSED(condition); } while(0) + #define X_ASSERT_MSG(condition, msg, ...) \ + do { X_UNUSED(condition); X_UNUSED(msg); } while(0) + #define X_ASSERT_FAIL(msg, ...) \ + do { X_UNUSED(msg); } while(0) + #define X_VERIFY(cond) (void)(cond) + #define X_VERIFY_MSG(cond, msg, ...) \ + do { (void)(cond); X_UNUSED(msg); } while(0) +#endif + +#define X_STATIC_ASSERT(x) \ + typedef char StaticAssert[(x) ? 1 : -1]; + +#endif // CUSTOM_ASSERT_H diff --git a/cpp/ycm/standard.h b/cpp/ycm/standard.h index 09f5be75..cc704e69 100644 --- a/cpp/ycm/standard.h +++ b/cpp/ycm/standard.h @@ -16,6 +16,7 @@ // along with YouCompleteMe. If not, see . #include +#include "CustomAssert.h" // We're most definitely not going to use // it as BOOST_FOREACH.