YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
Debug.cpp
浏览该文件的文档.
1 /*
2  © 2009-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #include "YCLib/YModules.h"
29 #include YFM_YCLib_Debug
30 #include YFM_YCLib_Input
31 #include YFM_YCLib_Video // for platform::ColorSpace;
32 #include <cstdarg>
33 #include <ystdex/string.hpp>
34 #if YCL_Android
35 # include <android/log.h>
36 #endif
37 
38 namespace platform
39 {
40 
41 namespace
42 {
43 
44 static bool bDebugStatus(true);
45 
46 #if YCL_Android
47 
49 template<typename... _tParams>
50 inline int
51 PrintAndroidLog(Descriptions::RecordLevel lv, const char* tag, const char *fmt,
52  _tParams&&... args)
53 {
54  YAssertNonnull(tag), YAssertNonnull(fmt);
55  return ::__android_log_print(platform_ex::MapAndroidLogLevel(lv), tag, fmt,
56  yforward(args)...);
57 }
58 #endif
59 
60 } // unnamed namespace;
61 
62 void
64 {
65  bDebugStatus = s;
66 }
67 
68 bool
70 {
71  return bDebugStatus;
72 }
73 
74 void
76 {
77  if(bDebugStatus)
79 }
80 
81 void
83 {
84  if(bDebugStatus)
85  {
86  YDebugBegin();
87  WaitForInput();
88  }
89 }
90 void
91 YDebug(const char* s)
92 {
93  if(bDebugStatus)
94  {
95  YDebugBegin();
96  std::puts(s);
97  WaitForInput();
98  }
99 }
100 
101 int
102 yprintf(const char* str, ...)
103 {
104  int t = -1;
105 
106  if(bDebugStatus)
107  {
108  YDebugBegin();
109 
110  std::va_list list;
111 
112  va_start(list, str);
113 
114  t = std::vprintf(str, list);
115 
116  va_end(list);
117  WaitForInput();
118  }
119  return t;
120 }
121 
122 void
123 Logger::SetFilter(Filter f)
124 {
125  if(f)
126  filter = std::move(f);
127 }
128 void
130 {
131  if(s)
132  sender = std::move(s);
133 }
134 
135 bool
137 {
138  return lv <= logger.FilterLevel;
139 }
140 
141 void
143 {
144  YAssertNonnull(str);
145  std::fprintf(stderr, "[%#X]: %s\n", unsigned(lv), str);
146 }
147 
148 void
149 Logger::DoLog(Level level, const char* str)
150 {
151  if(str)
152  {
153 #if YF_Multithread == 1
154  std::lock_guard<std::recursive_mutex> lck(record_mtx);
155 #endif
156 
157  sender(level, *this, str);
158  }
159 }
160 
161 void
162 Logger::DoLogException(Level level, const std::exception& e) ynothrow
163 {
164  try
165  {
166  // XXX: Log demangled type name.
167  DoLog(level, ystdex::sfmt("<%s>: %s.", typeid(e).name(), e.what()));
168  }
169  catch(std::exception& e)
170  {
171  try
172  {
174  "Another exception thrown when handling exception.");
175  DoLog(Descriptions::Emergent, e.what());
176  }
177  catch(...)
178  {
180  __FILE__, __LINE__, "Logging error: unhandled exception#1.");
181  }
182  }
183  catch(...)
184  {
185  try
186  {
188  "Another unknown exception thrown when handling exception.");
189  }
190  catch(...)
191  {
193  __FILE__, __LINE__, "Logging error: unhandled exception#2.");
194  }
195  }
196 }
197 
200 {
201 #if YCL_Android
202  return platform_ex::AndroidLogSender(tag);
203 #else
204  yunused(tag);
205 
206  return DefaultSendLog;
207 #endif
208 }
209 
210 
211 Logger&
213 {
214 #if YF_Multithread
215  static std::mutex mtx;
216  std::lock_guard<std::mutex> lck(mtx);
217 #endif
218  static Logger logger;
219 
220  return logger;
221 }
222 
223 
225 LogWithSource(const char* file, int line, const char* fmt, ...)
226 {
227  YAssertNonnull(file), YAssertNonnull(fmt);
228 
229  std::va_list args;
230 
231  va_start(args, fmt);
232 
233  std::string str(ystdex::vsfmt(fmt, args));
234 
235  va_end(args);
236  return ystdex::sfmt("\"%s\":%i:\n", file, line) + std::move(str);
237 }
238 
239 } // namespace platform;
240 
241 using namespace platform;
242 
243 namespace platform_ex
244 {
245 
246 #if YCL_Android
247 void
248 LogAssert(bool expr, const char* expr_str, const char* file, int line,
249  const char* msg)
250 {
251  if(YB_UNLIKELY(!expr))
252  ::__android_log_assert(expr_str, "YFramework",
253  "Assertion failed @ \"%s\":%i:\n %s .\nMessage: \n%s\n", file, line,
254  expr_str, msg);
255 }
256 
257 
258 int
259 MapAndroidLogLevel(Descriptions::RecordLevel lv)
260 {
261  return lv < Descriptions::Critical ? ANDROID_LOG_FATAL
262  : ANDROID_LOG_FATAL - (std::uint8_t(lv) - 0x40) / 0x20;
263 }
264 
265 
266 AndroidLogSender::AndroidLogSender(const std::string& t)
267  : tag(t)
268 {}
269 AndroidLogSender::~AndroidLogSender()
270 {}
271 
272 void
273 AndroidLogSender::operator()(Level lv, Logger& logger, const char* str) const
274 {
275  Logger::DefaultSendLog(lv, logger, str);
276  if(lv < Descriptions::Critical)
277  ::__android_log_assert("", "YFramework", "[%#X]: %s\n",
278  unsigned(lv), str);
279  else
280  PrintAndroidLog(lv, tag.c_str(), "[%#X]: %s\n", unsigned(lv), str);
281 }
282 
283 #endif
284 
285 } // namespace platform_ex;
286 
ISO C++ 标准字符串扩展。
#define ynothrowv
YSLib 无异常抛出保证验证:有条件地使用无异常抛出规范。
Definition: ydef.h:494
#define yunused(...)
标记未使用的表达式。
Definition: ydef.h:697
yconstfn const string _tParams && args
Definition: Loader.h:111
YF_API void YDebugBegin()
调试模式:显示控制台。
Definition: Debug.cpp:75
void SetWriter(Sender)
设置发送器。
Definition: Debug.cpp:129
static Sender FetchDefaultSender(const std::string &="YFramework")
取新建的平台相关的默认发送:按指定的标签取平台相关实现。
Definition: Debug.cpp:199
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
void ytrace(std::FILE *, std::uint8_t, std::uint8_t, const char *, int, const char *,...)
YCLib 调试跟踪函数。
YF_API void YDebugSetStatus(bool=true)
调试模式:设置状态。
Definition: Debug.cpp:63
std::size_t size ynothrow
std::basic_string< _tChar > vsfmt(const _tChar *fmt, std::va_list args)
以 C 标准输出格式的输出 std::basic_string 实例的对象。
Definition: string.hpp:382
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
YF_API void WaitForInput()
等待任意按键。
Definition: Input.cpp:47
std::string LogWithSource(const char *file, int line, const char *fmt,...)
Definition: Debug.cpp:225
yconstfn const string & name
Definition: Loader.h:110
void DoLog(Level, const char *)
转发等级和日志至发送器。
Definition: Debug.cpp:149
日志记录器。
Definition: Debug.h:134
static bool DefaultFilter(Level, Logger &) ynothrow
默认过滤:仅允许等级不大于阈值的日志被记录。
Definition: Debug.cpp:136
GSStringTemplate< char >::basic_string string
Definition: ycont.h:164
YF_API void YConsoleInit(std::uint8_t dspIndex, Color fc=ColorSpace::White, Color bc=ColorSpace::Black)
启动控制台。
YF_API Logger & FetchCommonLogger()
取公共日志记录器。
Definition: Debug.cpp:212
#define YAssertNonnull(_expr)
Definition: cassert.h:81
RecordLevel
记录等级。
Definition: ycommon.h:69
_tWidget _fCallable && f
Definition: ywgtevt.h:597
Sender sender
Definition: Debug.h:147
YF_API bool YDebugGetStatus()
调试模式:取得状态。
Definition: Debug.cpp:69
YF_API int yprintf(const char *,...)
调试模式 printf :显示控制台格式化输出 ,按键继续。
Definition: Debug.cpp:102
static void DefaultSendLog(Level, Logger &, const char *) ynothrowv
默认发送器:使用 stderr 输出。
Definition: Debug.cpp:142
std::basic_string< _tChar > sfmt(const _tChar *fmt,...)
以 C 标准输出格式的输出 std::basic_string 实例的对象。
Definition: string.hpp:399
YF_API void YDebug()
调试模式:按键继续。
Definition: Debug.cpp:82
std::function< void(Level, Logger &, const char *)> Sender
Definition: Debug.h:139
Filter filter
Definition: Debug.h:145