Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #ifndef __RAPICORN_INOUT_HH__ 00003 #define __RAPICORN_INOUT_HH__ 00004 00005 #include <rcore/strings.hh> 00006 00007 // For convenience, redefine assert() to get backtraces, logging, etc. 00008 #if !defined (assert) && defined (RAPICORN_CONVENIENCE) // dont redefine an existing custom macro 00009 #include <assert.h> // import definition of assert() from libc 00010 #undef assert 00011 #define assert RAPICORN_ASSERT ///< Shorthand for #RAPICORN_ASSERT if RAPICORN_CONVENIENCE is defined. 00012 #endif // RAPICORN_CONVENIENCE 00013 00014 namespace Rapicorn { 00015 00016 // == Basic I/O == 00017 template<class... Args> void printout (const char *format, const Args &...args) RAPICORN_PRINTF (1, 0); 00018 template<class... Args> void printerr (const char *format, const Args &...args) RAPICORN_PRINTF (1, 0); 00019 00020 // === User Messages == 00021 class UserSource; 00022 template<class... Args> void user_notice (const UserSource &source, const char *format, const Args &...args) RAPICORN_PRINTF (2, 0); 00023 template<class... Args> void user_warning (const UserSource &source, const char *format, const Args &...args) RAPICORN_PRINTF (2, 0); 00024 00025 struct UserSource 00026 { 00027 String module, filename; int line; 00028 UserSource (const String &module, const String &filename = "", int line = 0); 00029 }; 00030 00031 // == Environment variable key functions == 00032 bool envkey_flipper_check (const char*, const char*, bool with_all_toggle = true, volatile bool* = NULL); 00033 bool envkey_debug_check (const char*, const char*, volatile bool* = NULL); 00034 void envkey_debug_message (const char*, const char*, const char*, int, const String&, volatile bool* = NULL); 00035 00036 // == Debugging Input/Output == 00037 void debug_envvar (const String &name); 00038 void debug_config_add (const String &option); 00039 void debug_config_del (const String &key); 00040 String debug_config_get (const String &key, const String &default_value = ""); 00041 bool debug_config_bool (const String &key, bool default_value = 0); 00042 bool debug_devel_check (); 00043 00044 // == Debugging Macros == 00045 #define RAPICORN_FLIPPER(key, blurb) Rapicorn::FlipperOption (key) 00046 #define RAPICORN_DEBUG_OPTION(key, blurb) Rapicorn::DebugOption (key) 00047 #define RAPICORN_KEY_DEBUG(key,...) do { if (RAPICORN_UNLIKELY (Rapicorn::_rapicorn_debug_check_cache)) Rapicorn::rapicorn_debug (key, RAPICORN_PRETTY_FILE, __LINE__, Rapicorn::string_format (__VA_ARGS__)); } while (0) 00048 #define RAPICORN_FATAL(...) do { Rapicorn::debug_fmessage (RAPICORN_PRETTY_FILE, __LINE__, Rapicorn::string_format (__VA_ARGS__)); } while (0) 00049 #define RAPICORN_ASSERT(cond) do { if (RAPICORN_LIKELY (cond)) break; Rapicorn::debug_fassert (RAPICORN_PRETTY_FILE, __LINE__, #cond); } while (0) 00050 #define RAPICORN_ASSERT_RETURN(cond, ...) do { if (RAPICORN_LIKELY (cond)) break; Rapicorn::debug_assert (RAPICORN_PRETTY_FILE, __LINE__, #cond); return __VA_ARGS__; } while (0) 00051 #define RAPICORN_ASSERT_UNREACHED() do { Rapicorn::debug_fassert (RAPICORN_PRETTY_FILE, __LINE__, "line must not be reached"); } while (0) 00052 #define RAPICORN_CRITICAL(...) do { Rapicorn::debug_message ('C', RAPICORN_PRETTY_FILE, __LINE__, Rapicorn::string_format (__VA_ARGS__)); } while (0) 00053 #define RAPICORN_CRITICAL_UNLESS(cond) do { if (RAPICORN_LIKELY (cond)) break; Rapicorn::debug_assert (RAPICORN_PRETTY_FILE, __LINE__, #cond); } while (0) 00054 #define RAPICORN_DIAG(...) do { Rapicorn::debug_message ('G', RAPICORN_PRETTY_FILE, __LINE__, Rapicorn::string_format (__VA_ARGS__)); } while (0) 00055 #define RAPICORN_STARTUP_ASSERT(expr) RAPICORN_STARTUP_ASSERT_decl (expr, RAPICORN_CPP_PASTE2 (StartupAssertion, __LINE__)) 00056 00057 // == Rapicorn Internals Debugging == 00058 void rapicorn_debug (const char *key, const char *file, int line, const String &msg); 00059 bool rapicorn_debug_check (const char *key = NULL); 00060 00061 // == AnsiColors == 00063 namespace AnsiColors { 00064 00066 enum Colors { 00067 NONE, 00068 RESET, 00069 BOLD, BOLD_OFF, 00070 ITALICS, ITALICS_OFF, 00071 UNDERLINE, UNDERLINE_OFF, 00072 INVERSE, INVERSE_OFF, 00073 STRIKETHROUGH, STRIKETHROUGH_OFF, 00074 FG_BLACK, FG_RED, FG_GREEN, FG_YELLOW, FG_BLUE, FG_MAGENTA, FG_CYAN, FG_WHITE, 00075 FG_DEFAULT, 00076 BG_BLACK, BG_RED, BG_GREEN, BG_YELLOW, BG_BLUE, BG_MAGENTA, BG_CYAN, BG_WHITE, 00077 BG_DEFAULT, 00078 }; 00079 00080 const char* color_code (Colors acolor); 00081 const char* color (Colors acolor); 00082 bool colorize_tty (int fd = 1); 00083 void color_envkey (const String &env_var, const String &key = ""); 00084 00085 } // AnsiColors 00086 00087 // == Convenience Macros == 00088 #ifdef RAPICORN_CONVENIENCE 00089 #define assert_unreached RAPICORN_ASSERT_UNREACHED ///< Shorthand for RAPICORN_ASSERT_UNREACHED() if RAPICORN_CONVENIENCE is defined. 00090 #define assert_return RAPICORN_ASSERT_RETURN ///< Shorthand for RAPICORN_ASSERT_RETURN() if RAPICORN_CONVENIENCE is defined. 00091 #define fatal RAPICORN_FATAL ///< Shorthand for RAPICORN_FATAL() if RAPICORN_CONVENIENCE is defined. 00092 #define critical_unless RAPICORN_CRITICAL_UNLESS ///< Shorthand for RAPICORN_CRITICAL_UNLESS() if RAPICORN_CONVENIENCE is defined. 00093 #define critical RAPICORN_CRITICAL ///< Shorthand for RAPICORN_CRITICAL() if RAPICORN_CONVENIENCE is defined. 00094 #define STARTUP_ASSERT RAPICORN_STARTUP_ASSERT ///< Shorthand for RAPICORN_STARTUP_ASSERT() if RAPICORN_CONVENIENCE is defined. 00095 #define STATIC_ASSERT RAPICORN_STATIC_ASSERT ///< Shorthand for RAPICORN_STATIC_ASSERT() if RAPICORN_CONVENIENCE is defined. 00096 #endif // RAPICORN_CONVENIENCE 00097 00098 // == Implementation (Undocumented) == 00100 00101 struct DebugOption { 00102 const char *const key; 00103 constexpr DebugOption (const char *_key) : key (_key) {} 00104 operator bool () { return debug_config_bool (key); } 00105 }; 00106 00107 struct FlipperOption { 00108 const char *const key; 00109 constexpr FlipperOption (const char *_key) : key (_key) {} 00110 operator bool () { return flipper_check (key); } 00111 private: 00112 static bool flipper_check (const char *key); 00113 }; 00114 00115 #define RAPICORN_STARTUP_ASSERT_decl(e, _N) namespace { static struct _N { inline _N() { RAPICORN_ASSERT (e); } } _N; } 00116 00117 #ifdef __RAPICORN_BUILD__ 00118 #define RAPICORN_STARTUP_DEBUG(...) RAPICORN_KEY_DEBUG ("StartUp", __VA_ARGS__) 00119 #endif 00120 00121 extern bool volatile _rapicorn_debug_check_cache; 00122 00123 inline bool 00124 rapicorn_debug_check (const char *key) 00125 { 00126 return (RAPICORN_UNLIKELY (_rapicorn_debug_check_cache) && 00127 envkey_debug_check ("RAPICORN_DEBUG", key, &_rapicorn_debug_check_cache)); 00128 } 00129 00130 void printout_string (const String &string); 00131 void printerr_string (const String &string); 00132 void user_notice_string (const UserSource &source, const String &string); 00133 void user_warning_string (const UserSource &source, const String &string); 00134 void debug_fmessage (const char *file, int line, const String &message) RAPICORN_NORETURN; 00135 void debug_message (char kind, const char *file, int line, const String &message); 00136 void debug_fassert (const char*, int, const char*) RAPICORN_NORETURN; 00137 void debug_assert (const char*, int, const char*); 00138 00140 00141 // == Implementation (Documented) == 00142 00144 template<class... Args> void 00145 printout (const char *format, const Args &...args) 00146 { 00147 printout_string (string_format (format, args...)); 00148 } 00149 00151 template<class... Args> void 00152 printerr (const char *format, const Args &...args) 00153 { 00154 printerr_string (string_format (format, args...)); 00155 } 00156 00158 template<class... Args> void 00159 user_notice (const UserSource &source, const char *format, const Args &...args) 00160 { 00161 user_notice_string (source, string_format (format, args...)); 00162 } 00163 00165 template<class... Args> void 00166 user_warning (const UserSource &source, const char *format, const Args &...args) 00167 { 00168 user_warning_string (source, string_format (format, args...)); 00169 } 00170 00171 } // Rapicorn 00172 00173 #endif /* __RAPICORN_INOUT_HH__ */