#include #include #include "global.hpp" #include "error.hpp" #include "formatter.hpp" // Disable annoying warning 4996: "'function' was declared deprecated" #if CHECK_MSC_VERSION(14, 0) # pragma warning(push) # pragma warning(disable: 4996) #endif namespace Check { void Formatter::allocateBuffer(const size_t newSize) { char *newBuffer = static_cast(realloc(buffer, newSize)); if (newBuffer == NULL) { deallocateBuffer(); incite(); } buffer = newBuffer; bufferSize = newSize; } Formatter &Formatter::printArgs(const char *format, const va_list argList) { int length = -1; size_t size = bufferSize; while (true) { length = vsnprintf(buffer, size - 1, format, argList); if (errno == EILSEQ || errno == EINVAL) incite(UnhandledError, "Invalid format string"); if (length < 0 || size <= static_cast(length)) { size *= 3; size /= 2; } else break; allocateBuffer(size); } str.append(buffer, length); if (MaxBufferSize < size) allocateBuffer(DefaultBufferSize); return *this; } Formatter &Formatter::print(const char *format, ...) { va_list argList; va_start(argList, format); printArgs(format, argList); va_end(argList); return *this; } std::string format(const char *format, ...) { va_list argList; va_start(argList, format); std::string result = Formatter().printArgs(format, argList).text(); va_end(argList); return result; } namespace Auxiliary { const size_t DefaultQuoteLookSize = 10; std::string quote( const char *text, const size_t length, const size_t index, const size_t lookSize) { std::string result; // Here 9 equals to 1 (for central symbol) + 2 * strlen("...\'") result.reserve(2 * lookSize + 9); const size_t begin = (lookSize < index ? index - lookSize : 0); const size_t last = index + lookSize; const size_t end = (last < length ? last + 1 : length); if (0 < begin) result += "..."; result += '\''; result.append(text + begin, end - begin); result += '\''; if (end < length) result += "..."; return result; } } } #if CHECK_MSC_VERSION(14, 0) # pragma warning(pop) #endif