Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
inout.hh
Go to the documentation of this file.
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__ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines