[runtime] Support formatted output in the runtime assertions
This commit is contained in:
committed by
Stanislav Erokhin
parent
6fb5e43f62
commit
e3bc247557
@@ -1,29 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "KAssert.h"
|
||||
#include <cstdarg>
|
||||
#include "Porting.h"
|
||||
|
||||
void RuntimeAssertFailed(const char* location, const char* message) {
|
||||
// TODO: produce stacktrace and such.
|
||||
char buf[1024];
|
||||
if (location != nullptr)
|
||||
konan::snprintf(buf, sizeof(buf), "%s: runtime assert: %s\n", location, message);
|
||||
else
|
||||
konan::snprintf(buf, sizeof(buf), "runtime assert: %s\n", message);
|
||||
konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf)));
|
||||
konan::abort();
|
||||
RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* format, ...) {
|
||||
char buf[1024];
|
||||
int written = -1;
|
||||
|
||||
// Write the title with a source location.
|
||||
if (location != nullptr) {
|
||||
written = konan::snprintf(buf, sizeof(buf), "%s: runtime assert: ", location);
|
||||
} else {
|
||||
written = konan::snprintf(buf, sizeof(buf), "runtime assert: ");
|
||||
}
|
||||
|
||||
// Write the message.
|
||||
if (written >= 0 && static_cast<size_t>(written) < sizeof(buf)) {
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
konan::vsnprintf(buf + written, sizeof(buf) - written, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf)));
|
||||
konan::consoleErrorf("\n");
|
||||
// TODO: Write the stacktrace.
|
||||
konan::abort();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message);
|
||||
RUNTIME_NORETURN void RuntimeAssertFailed(const char* location, const char* message, ...);
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -46,9 +46,9 @@ extern "C" const int KonanNeedDebugInfo;
|
||||
|
||||
#if KONAN_ENABLE_ASSERT
|
||||
// Use RuntimeAssert() in internal state checks, which could be ignored in production.
|
||||
#define RuntimeAssert(condition, message) \
|
||||
if (KonanNeedDebugInfo && (!(condition))) { \
|
||||
RuntimeAssertFailed( __FILE__ ":" TOSTRING(__LINE__), message); \
|
||||
#define RuntimeAssert(condition, format, ...) \
|
||||
if (KonanNeedDebugInfo && (!(condition))) { \
|
||||
RuntimeAssertFailed( __FILE__ ":" TOSTRING(__LINE__), format, ##__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define RuntimeAssert(condition, message)
|
||||
@@ -56,9 +56,9 @@ if (KonanNeedDebugInfo && (!(condition))) { \
|
||||
|
||||
// Use RuntimeCheck() in runtime checks that could fail due to external condition and shall lead
|
||||
// to program termination. Never compiled out.
|
||||
#define RuntimeCheck(condition, message) \
|
||||
if (!(condition)) { \
|
||||
RuntimeAssertFailed(nullptr, message); \
|
||||
#define RuntimeCheck(condition, format, ...) \
|
||||
if (!(condition)) { \
|
||||
RuntimeAssertFailed(nullptr, format, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define TODO(...) \
|
||||
|
||||
@@ -273,11 +273,15 @@ void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLe
|
||||
int snprintf(char* buffer, size_t size, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int rv = vsnprintf_impl(buffer, size, format, args);
|
||||
int rv = vsnprintf(buffer, size, format, args);
|
||||
va_end(args);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int vsnprintf(char* buffer, size_t size, const char* format, va_list args) {
|
||||
return vsnprintf_impl(buffer, size, format, args);
|
||||
}
|
||||
|
||||
size_t strnlen(const char* buffer, size_t maxSize) {
|
||||
return ::strnlen(buffer, maxSize);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef RUNTIME_PORTING_H
|
||||
#define RUNTIME_PORTING_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -46,6 +47,7 @@ void onThreadExit(void (*destructor)(void*), void* destructorParameter);
|
||||
// by C compiler.
|
||||
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen);
|
||||
int snprintf(char* buffer, size_t size, const char* format, ...);
|
||||
int vsnprintf(char* buffer, size_t size, const char* format, va_list args);
|
||||
size_t strnlen(const char* buffer, size_t maxSize);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user