1 #ifndef R_LOG_H
2 #define R_LOG_H
3 
4 #include <r_userconf.h>
5 
6 #if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)
7 #define MACRO_LOG_FUNC __FUNCTION__
8 #define MACRO_WEAK_SYM
9 // TODO: Windows weak symbols?
10 #elif defined(__EMSCRIPTEN__) // TODO: test upon Emscripten's version once it supports weak symbols
11 #define MACRO_LOG_FUNC __func__
12 #define MACRO_WEAK_SYM
13 #else
14 #define MACRO_LOG_FUNC __func__
15 #define MACRO_WEAK_SYM __attribute__ ((weak))
16 #endif
17 
18 typedef enum r_log_level {
19 	R_LOGLVL_SILLY = 0,
20 	R_LOGLVL_DEBUG = 1,
21 	R_LOGLVL_VERBOSE = 2,
22 	R_LOGLVL_INFO = 3,
23 	R_LOGLVL_WARN = 4,
24 	R_LOGLVL_ERROR = 5,
25 	R_LOGLVL_FATAL = 6, // This will call r_sys_breakpoint() and trap the process for debugging!
26 	R_LOGLVL_NONE = 0xFF
27 } RLogLevel;
28 
29 #if R_CHECKS_LEVEL >= 2
30 #define R_DEFAULT_LOGLVL R_LOGLVL_WARN
31 #else
32 #define R_DEFAULT_LOGLVL R_LOGLVL_ERROR
33 #endif
34 
35 typedef void (*RLogCallback) (const char *output, const char *funcname, const char *filename,
36 	ut32 lineno, RLogLevel level, const char *tag, const char *fmtstr, ...) R_PRINTF_CHECK(7, 8);
37 
38 #define R_VLOG(lvl, tag, fmtstr, args) r_vlog (MACRO_LOG_FUNC, __FILE__, \
39 	__LINE__, lvl, tag, fmtstr, args);
40 
41 #define R_LOG(lvl, tag, fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
42 	__LINE__, lvl, tag, fmtstr, ##__VA_ARGS__);
43 #define R_LOG_SILLY(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
44 	__LINE__, R_LOGLVL_SILLY, NULL, fmtstr, ##__VA_ARGS__);
45 #define R_LOG_DEBUG(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
46 	__LINE__, R_LOGLVL_DEBUG, NULL, fmtstr, ##__VA_ARGS__);
47 #define R_LOG_VERBOSE(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
48 	__LINE__, R_LOGLVL_VERBOSE, NULL, fmtstr, ##__VA_ARGS__);
49 #define R_LOG_INFO(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
50 	__LINE__, R_LOGLVL_INFO, NULL, fmtstr, ##__VA_ARGS__);
51 #define R_LOG_WARN(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
52 	__LINE__, R_LOGLVL_WARN, NULL, fmtstr, ##__VA_ARGS__);
53 #define R_LOG_ERROR(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
54 	__LINE__, R_LOGLVL_ERROR, NULL, fmtstr, ##__VA_ARGS__);
55 #define R_LOG_FATAL(fmtstr, ...) r_log (MACRO_LOG_FUNC, __FILE__, \
56 	__LINE__, R_LOGLVL_FATAL, NULL, fmtstr, ##__VA_ARGS__);
57 
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61 
62 // Called by r_core to set the configuration variables
63 R_API void r_log_set_level(RLogLevel level);
64 R_API void r_log_set_file(const char *filename);
65 R_API void r_log_set_srcinfo(bool show_info);
66 R_API void r_log_set_colors(bool show_colors);
67 R_API void r_log_set_traplevel(RLogLevel level);
68 // TODO: r_log_set_options(enum RLogOptions)
69 
70 // Functions for adding log callbacks
71 R_API void r_log_add_callback(RLogCallback cbfunc);
72 R_API void r_log_del_callback(RLogCallback cbfunc);
73 // TODO: r_log_get_callbacks()
74 
75 /* Define r_log as weak so it can be 'overwritten' externally
76    This allows another method of output redirection on POSIX (Windows?)
77    You can override this function to handle all logging logic / output yourself */
78 R_API MACRO_WEAK_SYM void r_log(const char *funcname, const char *filename,
79 	ut32 lineno, RLogLevel level, const char *tag, const char *fmtstr, ...) R_PRINTF_CHECK(6, 7);
80 
81 R_API MACRO_WEAK_SYM void r_vlog(const char *funcname, const char *filename,
82 	ut32 lineno, RLogLevel level, const char *tag, const char *fmtstr, va_list args);
83 
84 #ifdef __cplusplus
85 }
86 #endif
87 
88 #endif //  R_LOG_H
89