CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/Log.cpp
Views: 1401
// Copyright (C) 2003 Dolphin Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official SVN repository and contact information can be found at15// http://code.google.com/p/dolphin-emu/1617#include <string>18#include <mutex>1920#include "ppsspp_config.h"2122#include "Common/CommonTypes.h"23#include "Common/Log.h"24#include "StringUtils.h"25#include "Common/Data/Encoding/Utf8.h"26#include "Common/Thread/ThreadUtil.h"27#include "Common/TimeUtil.h"2829#if PPSSPP_PLATFORM(ANDROID)30#include <android/log.h>31#elif PPSSPP_PLATFORM(WINDOWS)32#include "CommonWindows.h"33#endif3435#define LOG_BUF_SIZE 20483637static bool hitAnyAsserts = false;3839static std::mutex g_extraAssertInfoMutex;40static std::string g_extraAssertInfo = "menu";41static double g_assertInfoTime = 0.0;42static bool g_exitOnAssert;4344void SetExtraAssertInfo(const char *info) {45std::lock_guard<std::mutex> guard(g_extraAssertInfoMutex);46g_extraAssertInfo = info ? info : "menu";47g_assertInfoTime = time_now_d();48}4950void SetCleanExitOnAssert() {51g_exitOnAssert = true;52}5354bool HandleAssert(const char *function, const char *file, int line, const char *expression, const char* format, ...) {55// Read message and write it to the log56char text[LOG_BUF_SIZE];57const char *caption = "Critical";58va_list args;59va_start(args, format);60vsnprintf(text, sizeof(text), format, args);61va_end(args);6263// Secondary formatting. Wonder if this can be combined into the vsnprintf somehow.64char formatted[LOG_BUF_SIZE + 128];65{66std::lock_guard<std::mutex> guard(g_extraAssertInfoMutex);67double delta = time_now_d() - g_assertInfoTime;68snprintf(formatted, sizeof(formatted), "(%s:%s:%d): [%s] (%s, %0.1fs) %s", file, function, line, expression, g_extraAssertInfo.c_str(), delta, text);69}7071// Normal logging (will also log to Android log)72ERROR_LOG(Log::System, "%s", formatted);73// Also do a simple printf for good measure, in case logging of System is disabled (should we disallow that?)74fprintf(stderr, "%s\n", formatted);7576hitAnyAsserts = true;7778#if defined(USING_WIN_UI)79// Avoid hanging on CI.80if (!getenv("CI")) {81int msgBoxStyle = MB_ICONINFORMATION | MB_YESNO;82std::wstring wtext = ConvertUTF8ToWString(formatted) + L"\n\nTry to continue?";83std::wstring wcaption = ConvertUTF8ToWString(std::string(caption) + " " + GetCurrentThreadName());84OutputDebugString(wtext.c_str());85printf("%s\n", formatted);86if (IDYES != MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle)) {87if (g_exitOnAssert) {88// Hard exit.89ExitProcess(1);90return false;91}92} else {93return true;94}95}96return false;97#elif PPSSPP_PLATFORM(ANDROID)98__android_log_assert(expression, "PPSSPP", "%s", formatted);99// Doesn't matter what we return here.100return false;101#else102OutputDebugStringUTF8(text);103return false;104#endif105}106107// These are mainly used for unit testing.108bool HitAnyAsserts() {109return hitAnyAsserts;110}111void ResetHitAnyAsserts() {112hitAnyAsserts = false;113}114115116