SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SGIO.h
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 1999-2013 Soeren Sonnenburg
00008  * Written (W) 1999-2008 Gunnar Raetsch
00009  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00010  * Copyright (C) 2010-2013 Soeren Sonnenburg
00011  */
00012 
00013 #ifndef __SGIO_H__
00014 #define __SGIO_H__
00015 
00016 #include <stdio.h>
00017 #include <stdarg.h>
00018 #include <string.h>
00019 #include <dirent.h>
00020 #ifndef _WIN32
00021 #include <unistd.h>
00022 #endif
00023 #include <locale.h>
00024 
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 
00028 #include <shogun/lib/common.h>
00029 #include <shogun/base/init.h>
00030 
00031 namespace shogun
00032 {
00033     class RefCount;
00034     class SGIO;
00036     extern SGIO* sg_io;
00037 }
00038 
00039 
00040 namespace shogun
00041 {
00046 enum EMessageType
00047 {
00048     MSG_GCDEBUG=0,
00049     MSG_DEBUG=1,
00050     MSG_INFO=2,
00051     MSG_NOTICE=3,
00052     MSG_WARN=4,
00053     MSG_ERROR=5,
00054     MSG_CRITICAL=6,
00055     MSG_ALERT=7,
00056     MSG_EMERGENCY=8,
00057     MSG_MESSAGEONLY=9
00058 };
00059 
00063 enum EMessageLocation
00064 {
00065     MSG_NONE=0,
00066     MSG_FUNCTION=1,
00067     MSG_LINE_AND_FILE=2
00068 };
00069 
00070 #define NUM_LOG_LEVELS 10
00071 #define FBUFSIZE 4096
00072 
00073 #ifdef DARWIN
00074 #include <Availability.h>
00075 #ifndef __MAC_10_8
00076 #define __MAC_10_8 1080
00077 #endif
00078 #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
00079 #define CONST_DIRENT_T struct dirent
00080 #else
00081 #define CONST_DIRENT_T const struct dirent
00082 #endif // Lion or earlier
00083 #else //DARWIN
00084 #define CONST_DIRENT_T const struct dirent
00085 #endif //DARWIN
00086 
00087 #define SG_SET_LOCALE_C setlocale(LC_ALL, "C")
00088 #define SG_RESET_LOCALE setlocale(LC_ALL, "")
00089 
00090 #if !defined(SG_UNLIKELY)
00091 #if __GNUC__ >= 3
00092 #define SG_UNLIKELY(expr) __builtin_expect(expr, 0)
00093 #else
00094 #define SG_UNLIKELY(expr) expr
00095 #endif
00096 #endif
00097 
00098 #ifdef _WIN32
00099 #define __PRETTY_FUNCTION__ __FUNCTION__
00100 #endif
00101 
00102 // printf like funktions (with additional severity level)
00103 // for object derived from CSGObject
00104 #define SG_GCDEBUG(...) {                                           \
00105     if (SG_UNLIKELY(io->loglevel_above(MSG_GCDEBUG)))               \
00106         io->message(MSG_GCDEBUG, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); \
00107 }
00108 
00109 #define SG_DEBUG(...) {                                             \
00110     if (SG_UNLIKELY(io->loglevel_above(MSG_DEBUG)))                 \
00111         io->message(MSG_DEBUG, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);   \
00112 }
00113 
00114 #define SG_OBJ_DEBUG(o,...) {                                       \
00115     if (SG_UNLIKELY(o->io->loglevel_above(MSG_DEBUG)))              \
00116         o->io->message(MSG_DEBUG, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);    \
00117 }
00118 
00119 
00120 #define SG_INFO(...) {                                              \
00121     if (SG_UNLIKELY(io->loglevel_above(MSG_INFO)))                  \
00122         io->message(MSG_INFO, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);        \
00123 }
00124 
00125 #define SG_CLASS_INFO(c, ...) {                                     \
00126     if (SG_UNLIKELY(c::io->loglevel_above(MSG_INFO)))               \
00127         c::io->message(MSG_INFO, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); \
00128 }
00129 
00130 #define SG_WARNING(...) { io->message(MSG_WARN, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00131 #define SG_ERROR(...) { io->message(MSG_ERROR, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00132 #define SG_OBJ_ERROR(o, ...) { o->io->message(MSG_ERROR, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00133 #define SG_CLASS_ERROR(c, ...) { c::io->message(MSG_ERROR, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00134 #define SG_UNSTABLE(func, ...) { io->message(MSG_WARN, __PRETTY_FUNCTION__, __FILE__, __LINE__, \
00135 __FILE__ ":" func ": Unstable method!  Please report if it seems to " \
00136 "work or not to the Shogun mailing list.  Thanking you in " \
00137 "anticipation.  " __VA_ARGS__); }
00138 
00139 #define SG_PRINT(...) { io->message(MSG_MESSAGEONLY, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00140 #define SG_OBJ_PRINT(o, ...) { o->io->message(MSG_MESSAGEONLY, __PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00141 #define SG_NOTIMPLEMENTED { io->not_implemented(__PRETTY_FUNCTION__, __FILE__, __LINE__); }
00142 #define SG_DEPRECATED { io->deprecated(__PRETTY_FUNCTION__, __FILE__, __LINE__); }
00143 
00144 #define SG_PROGRESS(...) {                      \
00145     if (SG_UNLIKELY(io->get_show_progress()))   \
00146         io->progress(__VA_ARGS__);              \
00147 }
00148 
00149 #define SG_OBJ_PROGRESS(o, ...) {               \
00150     if (SG_UNLIKELY(o->io->get_show_progress()))\
00151         o->io->progress(__VA_ARGS__);           \
00152 }
00153 
00154 #define SG_ABS_PROGRESS(...) {                  \
00155     if (SG_UNLIKELY(io->get_show_progress()))   \
00156         io->absolute_progress(__VA_ARGS__);     \
00157 }
00158 
00159 #define SG_DONE() {                             \
00160     if (SG_UNLIKELY(io->get_show_progress()))   \
00161         io->done();                             \
00162 }
00163 
00164 // printf like function using the global sg_io object
00165 #define SG_SGCDEBUG(...) {                                          \
00166     if (SG_UNLIKELY(sg_io->loglevel_above(MSG_GCDEBUG)))            \
00167         sg_io->message(MSG_GCDEBUG,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);\
00168 }
00169 
00170 #define SG_SDEBUG(...) {                                            \
00171     if (SG_UNLIKELY(sg_io->loglevel_above(MSG_DEBUG)))          \
00172         sg_io->message(MSG_DEBUG,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); \
00173 }
00174 
00175 #define SG_SINFO(...) {                                             \
00176     if (SG_UNLIKELY(sg_io->loglevel_above(MSG_INFO)))               \
00177         sg_io->message(MSG_INFO,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__);  \
00178 }
00179 
00180 #define SG_SWARNING(...) { sg_io->message(MSG_WARN,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00181 #define SG_SERROR(...) { sg_io->message(MSG_ERROR,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00182 #define SG_SPRINT(...) { sg_io->message(MSG_MESSAGEONLY,__PRETTY_FUNCTION__, __FILE__, __LINE__, __VA_ARGS__); }
00183 
00184 
00185 #define SG_SPROGRESS(...) {                         \
00186     if (SG_UNLIKELY(sg_io->get_show_progress()))    \
00187         sg_io->progress(__VA_ARGS__);               \
00188 }
00189 
00190 #define SG_SABS_PROGRESS(...) {                     \
00191     if (SG_UNLIKELY(sg_io->get_show_progress()))    \
00192         sg_io->absolute_progress(__VA_ARGS__);      \
00193 }
00194 
00195 #define SG_SDONE() {                                \
00196     if (SG_UNLIKELY(sg_io->get_show_progress()))    \
00197         sg_io->done();                              \
00198 }
00199 
00200 #define SG_SNOTIMPLEMENTED { sg_io->not_implemented(__PRETTY_FUNCTION__, __FILE__, __LINE__); }
00201 #define SG_SDEPRECATED { sg_io->deprecated(__PRETTY_FUNCTION__, __FILE__, __LINE__); }
00202 
00203 #define ASSERT(x) {                                                                 \
00204     if (SG_UNLIKELY(!(x)))                                                              \
00205         SG_SERROR("assertion %s failed in %s file %s line %d\n",#x, __PRETTY_FUNCTION__, __FILE__, __LINE__)    \
00206 }
00207 
00208 #define REQUIRE(x, ...) {       \
00209     if (SG_UNLIKELY(!(x)))      \
00210         SG_SERROR(__VA_ARGS__)  \
00211 }
00212 
00213 /* help clang static analyzer to identify custom assertation functions */
00214 #ifdef __clang_analyzer__
00215 void _clang_fail(void) __attribute__((analyzer_noreturn));
00216 
00217 #undef SG_ERROR(...)
00218 #undef SG_SERROR(...)
00219 #define SG_ERROR(...) _clang_fail();
00220 #define SG_SERROR(...) _clang_fail();
00221 
00222 #endif /* __clang_analyzer__ */
00223 
00231 struct substring
00232 {
00234     char *start;
00236     char *end;
00237 };
00238 
00245 class SGIO
00246 {
00247     public:
00249         SGIO();
00251         SGIO(const SGIO& orig);
00252 
00254         virtual ~SGIO();
00255 
00260         void set_loglevel(EMessageType level);
00261 
00266         EMessageType get_loglevel() const;
00267 
00273         inline bool loglevel_above(EMessageType type) const
00274         {
00275             return loglevel <= type;
00276         }
00277 
00282         inline bool get_show_progress() const
00283         {
00284             return show_progress;
00285         }
00286 
00289         inline EMessageLocation get_location_info() const
00290         {
00291             return location_info;
00292         }
00293 
00298         inline bool get_syntax_highlight() const
00299         {
00300             return syntax_highlight;
00301         }
00302 
00314         void message(EMessageType prio, const char* function, const char* file,
00315                 int32_t line, const char *fmt, ... ) const;
00316 
00325         void progress(
00326             float64_t current_val,
00327             float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00328             const char* prefix="PROGRESS:\t");
00329 
00339         void absolute_progress(
00340             float64_t current_val, float64_t val,
00341             float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00342             const char* prefix="PROGRESS:\t");
00343 
00348         void done();
00349 
00351         inline void not_implemented(const char* function, const char* file, int32_t line) const
00352         {
00353             message(MSG_ERROR, function, file, line, "Sorry, not yet implemented .\n");
00354         }
00355 
00357         inline void deprecated(const char* function, const char* file, int32_t line) const
00358         {
00359             message(MSG_WARN, function, file, line,
00360                     "This function is deprecated and will be removed soon.\n");
00361         }
00362 
00368         void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00369 
00375         static char* skip_spaces(char* str);
00376 
00382         static char* skip_blanks(char* str);
00383 
00388         inline FILE* get_target() const
00389         {
00390             return target;
00391         }
00392 
00397         void set_target(FILE* target);
00398 
00400         inline void set_target_to_stderr() { set_target(stderr); }
00401 
00403         inline void set_target_to_stdout() { set_target(stdout); }
00404 
00406         inline void enable_progress()
00407         {
00408             show_progress=true;
00409 
00410             // static functions like CSVM::classify_example_helper call SG_PROGRESS
00411             if (sg_io!=this)
00412                 sg_io->enable_progress();
00413         }
00414 
00416         inline void disable_progress()
00417         {
00418             show_progress=false;
00419 
00420             // static functions like CSVM::classify_example_helper call SG_PROGRESS
00421             if (sg_io!=this)
00422                 sg_io->disable_progress();
00423         }
00424 
00430         inline void set_location_info(EMessageLocation location)
00431         {
00432             location_info = location;
00433 
00434             if (sg_io!=this)
00435                 sg_io->set_location_info(location);
00436         }
00437 
00439         inline void enable_syntax_highlighting()
00440         {
00441             syntax_highlight=true;
00442 
00443             if (sg_io!=this)
00444                 sg_io->enable_syntax_highlighting();
00445         }
00446 
00448         inline void disable_syntax_highlighting()
00449         {
00450             syntax_highlight=false;
00451 
00452             if (sg_io!=this)
00453                 sg_io->disable_syntax_highlighting();
00454         }
00455 
00460         static inline void set_dirname(const char* dirname)
00461         {
00462             strncpy(directory_name, dirname, FBUFSIZE);
00463         }
00464 
00471         static char* concat_filename(const char* filename);
00472 
00478         static int filter(CONST_DIRENT_T* d);
00479 
00485         static char* c_string_of_substring(substring s);
00486 
00491         static void print_substring(substring s);
00492 
00499         static float32_t float_of_substring(substring s);
00500 
00506         static float64_t double_of_substring(substring s);
00507 
00513         static int32_t int_of_substring(substring s);
00514 
00520         static uint32_t ulong_of_substring(substring s);
00521 
00527         static uint32_t ss_length(substring s);
00528 
00533         int32_t ref();
00534 
00539         int32_t ref_count() const;
00540 
00546         int32_t unref();
00547 
00549         inline const char* get_name() { return "SGIO"; }
00550 
00551     protected:
00558         const char* get_msg_intro(EMessageType prio) const;
00559 
00560     protected:
00562         FILE* target;
00564         float64_t last_progress_time;
00566         float64_t progress_start_time;
00568         float64_t last_progress;
00570         bool show_progress;
00573         EMessageLocation location_info;
00575         bool syntax_highlight;
00576 
00578         EMessageType loglevel;
00580         static const EMessageType levels[NUM_LOG_LEVELS];
00582         static const char* message_strings_highlighted[NUM_LOG_LEVELS];
00584         static const char* message_strings[NUM_LOG_LEVELS];
00585 
00587         static char file_buffer[FBUFSIZE];
00589         static char directory_name[FBUFSIZE];
00590 
00591     private:
00592         RefCount* m_refcount;
00593 };
00594 }
00595 #endif // __SGIO_H__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation