From 27474060e1287a67c45cd790d29b9095b35b2bdf Mon Sep 17 00:00:00 2001 From: ShizZy Date: Thu, 29 Aug 2013 23:35:09 -0400 Subject: adding initial project layout --- src/common/src/log.h | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 src/common/src/log.h (limited to 'src/common/src/log.h') diff --git a/src/common/src/log.h b/src/common/src/log.h new file mode 100644 index 00000000..9ce3a30a --- /dev/null +++ b/src/common/src/log.h @@ -0,0 +1,216 @@ +/** + * Copyright (C) 2005-2012 Gekko Emulator + * + * @file log.h + * @author ShizZy + * @date 2012-02-11 + * @brief Common logging routines used throughout the project + * + * @section LICENSE + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details at + * http://www.gnu.org/copyleft/gpl.html + * + * Official project repository can be found at: + * http://code.google.com/p/gekko-gc-emu/ + */ + +#ifndef COMMON_LOG_H_ +#define COMMON_LOG_H_ + +#include "SDL.h" // Used for threading/mutexes + +#include "common.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Logging Macros + +#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING) +/// Debug mode, show all logs +#define MAX_LOG_LEVEL logger::LDEBUG +#else +/// Non debug mode, only show critical logs +#define MAX_LOG_LEVEL logger::LWARNING +#endif + +/// Logs a message ** Don't use directly ** +#define _LOG_GENERIC(level, type, ...) \ + if (level <= MAX_LOG_LEVEL) { \ + LogGeneric(level, type, __FILE__, __LINE__, false, __VA_ARGS__); \ + } + +/// Used for appending to the last logged message +#define LOG_APPEND(level, type, ...) \ + if (logger::level <= MAX_LOG_LEVEL) { \ + logger::LogGeneric(logger::level, logger::type, __FILE__, __LINE__, true, __VA_ARGS__); \ + } + +/// Use this for printing an IMPORTANT notice to the logger +#define LOG_NOTICE(type, ...) _LOG_GENERIC(logger::LNOTICE, logger::type, __VA_ARGS__) + +/// Use this for printing an error message to the logger +#define LOG_ERROR(type, ...) _LOG_GENERIC(logger::LERROR, logger::type, __VA_ARGS__) + +/// Use this for printing a crash report to the logger +#define LOG_CRASH(type, ...) _LOG_GENERIC(logger::LCRASH, logger::type, __VA_ARGS__) + +/// Use this for printing a warning to the logger +#define LOG_WARNING(type, ...) _LOG_GENERIC(logger::LWARNING, logger::type, __VA_ARGS__) + +/// Use this for printing general information to the logger +#define LOG_INFO(type, ...) _LOG_GENERIC(logger::LINFO, logger::type, __VA_ARGS__) + +#if defined(_DEBUG) || defined(DEBUG) || defined(LOGGING) + +/// Use this for printing a debug message to the logger +#define LOG_DEBUG(type, ...) _LOG_GENERIC(logger::LDEBUG, logger::type, __VA_ARGS__) + +/// Used for debug-mode assertions +#define _ASSERT_DBG(_type_, _cond_) \ + if (!(_cond_)) { \ + LOG_ERROR(_type_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n", \ + __LINE__, __FILE__, __TIME__); \ + if (!logger::AskYesNo("*** Assertion (see log)***\n")) logger::Crash(); \ + } + +/// Used for message-specified debug-mode assertions +#define _ASSERT_DBG_MSG(_type_, _cond_, ...) \ + if (!(_cond_)) { \ + LOG_ERROR(_type_, __VA_ARGS__); \ + if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \ + } +#else +#define _ASSERT_DBG(_type_, _cond_, ...) +#define _ASSERT_DBG_MSG(_type_, _cond_, ...) +#define LOG_DEBUG(type, ...) +#endif + +/// Used for general purpose assertions, CRITICAL operations only +#define _ASSERT_MSG(_type_, _cond_, ...) \ + if (!(_cond_)) { \ + if (!logger::AskYesNo(__VA_ARGS__)) logger::Crash(); \ + } + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Logger + +namespace logger { + +const int kMaxMsgLength = 1024; ///< Maximum message length + +/// Used for handling responses to system functions that require them +typedef enum { + SYS_USER_NO = 0, ///< User response for 'No' + SYS_USER_YES, ///< User response for 'Yes' + SYS_USER_OK, ///< User response for 'Okay' + SYS_USER_ABORT, ///< User response for 'Abort' + SYS_USER_RETRY, ///< User response for 'Retry' + SYS_USER_CANCEL, ///< User response for 'Cancel' +} SysUserResponse; + +/// Level of logging +typedef enum { + LNULL = 0, ///< Logs with this level won't get logged + LNOTICE, ///< Notice: A general message to the user + LERROR, ///< Error: For failure messages + LCRASH, ///< Crash: Used for crash reports + LWARNING, ///< Warning: For potentially bad things, but not fatal + LINFO, ///< Info: Information message + LDEBUG ///< Debug: Debug-only information +} LogLevel; + +/// Type of logging +typedef enum { + TNULL = 0, + TAI, + TBOOT, + TCOMMON, + TCONFIG, + TCORE, + TCP, + TDI, + TDSP, + TDVD, + TEXI, + TGP, + THLE, + THW, + TJOYPAD, + TMASTER, + TMEM, + TMI, + TOS_HLE, + TOS_REPORT, + TPE, + TPI, + TPOWERPC, + TSI, + TVI, + TVIDEO, + NUMBER_OF_LOGS ///< Number of logs - must be last +} LogType; + +/// Used for implementing a logger for a subsystem +class LogContainer +{ +public: + LogContainer(const char* name, const char* desc, bool enable); + ~LogContainer() {} + + const char* name() const { return name_; } + const char* desc() const { return desc_; } + + bool enabled() const { return enabled_; } + void set_enabled(bool enabled) { enabled_ = enabled; } + + LogLevel level() const { return level_; } + void set_level(LogLevel level) { level_ = level; } + +private: + char name_[32]; ///< Name of the logger (e.g. "SI") + char desc_[128]; ///< Description of the logger (e.g. "Serial Interface") + bool enabled_; ///< Whether or not the logger is enabled + + LogLevel level_; ///< Level of the logger (e.g. Notice, Error, Warning, etc.) + + SDL_mutex* listener_lock_; ///< Mutex for multithreaded access + + DISALLOW_COPY_AND_ASSIGN(LogContainer); +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Function Prototypes + +/*! + * \brief Log routine used by everything + * \param level Log level to use + * \param type Log type to use + * \param file Filename of file where error occured + * \param line Linenumber of file where error occured + * \param fmt Formatted message + */ +void LogGeneric(LogLevel level, LogType type, const char *file, int line, bool append, const char* fmt, ...); + +/// Forces a controlled system crash rather before it catches fire (debug) +void Crash(); + +/*! + * \brief Asks the user a yes or no question + * \param fmt Question formatted message + * \return SysUserResponse response + */ +SysUserResponse AskYesNo(const char* fmt, ...); + +/// Initialize the logging system +void Init(); + +} // namespace log + +#endif // COMMON_LOG_H -- cgit v1.2.3