/*---------------------------------------------------------------------------* Project: Horizon File: dbg_Logger.cpp Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 22730 $ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include /****************************************************************************/ namespace nn { namespace dbg { namespace detail { /****************************************************************************/ char8* Logger::s_LevelStrings[] = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "FORCE" }; u32 Logger::s_UpperLevel = Logger::LEVEL_FATAL; u32 Logger::s_LowerLevel = NN_LOG_LEVEL; bool Logger::s_Initialized = false; u8 Logger::s_ShowFlag = 0; size_t Logger::MakeFuncName(const char8* src, char8* dest, size_t length) { // TODO: srcのNULLチェック // TODO: destのNULLチェック char8* pSrcTop = const_cast(src); char8* pSrcSigHead = ::std::strrchr(pSrcTop, '('); // 末尾を決定 // ENABLE_SIGNATURE ならば、srcの末尾 // そうでないなら、関数の ( の位置 char8* pSrcLast = (s_ShowFlag & ENABLE_SIGNATURE) ? pSrcTop + ::std::strlen(src) : pSrcSigHead; // 先頭を決定 // ENABLE_NAMESPACE ならば、srcの先頭、そうでなければ、 // 後ろから3つ目の:の位置 + 1 if(!(s_ShowFlag & ENABLE_NAMESPACE)) { pSrcTop = pSrcSigHead; for(int count = 0;pSrcTop != src && count < 3; pSrcTop--) { count = (*pSrcTop == ':') ? count + 1 : count; } pSrcTop += 2; } size_t copyLength = ::std::min(pSrcLast - pSrcTop, length - 1); ::std::memcpy(dest, pSrcTop, copyLength); dest[copyLength] = '\0'; return copyLength; } void Logger::PrintLog(const u32 level, const char8* funcName, const char8* fileName, const int line, const char8* fmt, ...) { #ifndef NN_SWITCH_DISABLE_DEBUG_PRINT // static int count = 0; // 設定レベル範囲外ならすぐ抜ける if(!s_Initialized) { s_LowerLevel = NN_LOG_LEVEL; } if(level != LEVEL_FORCE && (level < s_LowerLevel || s_UpperLevel < level)) { return; } { // funcNameを処理 char8 prefix[BUF_SIZE]; size_t len = std::min(::std::snprintf(prefix, sizeof(prefix), "[%s] ", s_LevelStrings[level]), sizeof(prefix)); len += MakeFuncName(funcName, &prefix[len], BUF_SIZE - len - 3); ::std::strncat(&prefix[len], " : ", BUF_SIZE - len - 3); len += 3; prefix[len] = '\0'; //nn::dbg::PrintfDebugString(prefix); //nn::dbg::PrintfDebugString("%s", prefix); //nn::dbg::detail::Printf("%s", prefix); nn::dbg::detail::PutString(prefix, len); } { char8 userMessage[BUF_SIZE]; // ログメッセージを展開 va_list vlist; va_start(vlist, fmt); size_t len = std::min(nn::nstd::TVSNPrintf(userMessage, sizeof(userMessage), fmt, vlist), sizeof(userMessage)); va_end(vlist); // userMessageの末尾に\nが入っている場合、削除する for (; len > 0 && userMessage[len - 1] == '\n'; --len) { userMessage[len - 1] = '\0'; } //nn::dbg::OutputDebugString(userMessage); //nn::dbg::PrintfDebugString("%s", userMessage); nn::dbg::detail::PutString(userMessage, len); } { // fileNameを処理 char8* pFileNameTop = NULL; if(!(s_ShowFlag & ENABLE_LONGPATH)) { pFileNameTop = (char8*)::std::strrchr(fileName, '\\'); if(pFileNameTop) { pFileNameTop++; } } if(!pFileNameTop) { pFileNameTop = (char8*)fileName; } // sprintf で出力文字列を作成 //nn::dbg::PrintfDebugString(" (%s:%d)\n", pFileNameTop, line); nn::dbg::detail::Printf(" (%s:%d)\n", pFileNameTop, line); } #else NN_UNUSED_VAR(level); NN_UNUSED_VAR(funcName); NN_UNUSED_VAR(fileName); NN_UNUSED_VAR(line); NN_UNUSED_VAR(fmt); #endif } /****************************************************************************/ /****************************************************************************/ } } // namespace dbg } // namespace nn