00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __CIO_H__
00013 #define __CIO_H__
00014
00015 #include <stdio.h>
00016 #include <stdarg.h>
00017 #include <string.h>
00018 #include <dirent.h>
00019 #include <unistd.h>
00020
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023
00024 #include "lib/common.h"
00025 #include "base/init.h"
00026
00027 namespace shogun
00028 {
00029 class CIO;
00030 extern CIO* sg_io;
00031 }
00032
00033
00034 namespace shogun
00035 {
00040 enum EMessageType
00041 {
00042 MSG_GCDEBUG,
00043 MSG_DEBUG,
00044 MSG_INFO,
00045 MSG_NOTICE,
00046 MSG_WARN,
00047 MSG_ERROR,
00048 MSG_CRITICAL,
00049 MSG_ALERT,
00050 MSG_EMERGENCY,
00051 MSG_MESSAGEONLY
00052 };
00053
00054
00055 #define NUM_LOG_LEVELS 10
00056 #define FBUFSIZE 4096
00057
00058 #ifdef DARWIN
00059 #define CONST_DIRENT_T struct dirent
00060 #else //DARWIN
00061 #define CONST_DIRENT_T const struct dirent
00062 #endif //DARWIN
00063
00064
00065
00066 #define SG_GCDEBUG(...) io->message(MSG_GCDEBUG, __FILE__, __LINE__, __VA_ARGS__)
00067 #define SG_DEBUG(...) io->message(MSG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
00068 #define SG_INFO(...) io->message(MSG_INFO, __FILE__, __LINE__, __VA_ARGS__)
00069 #define SG_WARNING(...) io->message(MSG_WARN, __FILE__, __LINE__, __VA_ARGS__)
00070 #define SG_ERROR(...) io->message(MSG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
00071
00072 #define SG_PRINT(...) io->message(MSG_MESSAGEONLY, __FILE__, __LINE__, __VA_ARGS__)
00073 #define SG_NOTIMPLEMENTED io->not_implemented(__FILE__, __LINE__)
00074 #define SG_DEPRECATED io->deprecated(__FILE__, __LINE__)
00075
00076 #define SG_PROGRESS(...) io->progress(__VA_ARGS__)
00077 #define SG_ABS_PROGRESS(...) io->absolute_progress(__VA_ARGS__)
00078 #define SG_DONE() io->done()
00079
00080
00081 #define SG_SGCDEBUG(...) sg_io->message(MSG_GCDEBUG,__FILE__, __LINE__, __VA_ARGS__)
00082 #define SG_SDEBUG(...) sg_io->message(MSG_DEBUG,__FILE__, __LINE__, __VA_ARGS__)
00083 #define SG_SINFO(...) sg_io->message(MSG_INFO,__FILE__, __LINE__, __VA_ARGS__)
00084 #define SG_SWARNING(...) sg_io->message(MSG_WARN,__FILE__, __LINE__, __VA_ARGS__)
00085 #define SG_SERROR(...) sg_io->message(MSG_ERROR,__FILE__, __LINE__, __VA_ARGS__)
00086 #define SG_SPRINT(...) sg_io->message(MSG_MESSAGEONLY,__FILE__, __LINE__, __VA_ARGS__)
00087 #define SG_SPROGRESS(...) sg_io->progress(__VA_ARGS__)
00088 #define SG_SABS_PROGRESS(...) sg_io->absolute_progress(__VA_ARGS__)
00089 #define SG_SDONE() sg_io->done()
00090 #define SG_SNOTIMPLEMENTED sg_io->not_implemented(__FILE__, __LINE__)
00091 #define SG_SDEPRECATED sg_io->deprecated(__FILE__, __LINE__)
00092
00093 #define ASSERT(x) { if (!(x)) SG_SERROR("assertion %s failed in file %s line %d\n",#x, __FILE__, __LINE__);}
00094
00095
00102 class CIO
00103 {
00104 public:
00106 CIO();
00108 CIO(const CIO& orig);
00109
00114 void set_loglevel(EMessageType level);
00115
00120 EMessageType get_loglevel() const;
00121
00126 inline bool get_show_progress() const
00127 {
00128 return show_progress;
00129 }
00130
00135 inline bool get_show_file_and_line() const
00136 {
00137 return show_file_and_line;
00138 }
00139
00144 inline bool get_syntax_highlight() const
00145 {
00146 return syntax_highlight;
00147 }
00148
00159 void message(EMessageType prio, const char* file,
00160 int32_t line, const char *fmt, ... ) const;
00161
00170 void progress(
00171 float64_t current_val,
00172 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00173 const char* prefix="PROGRESS:\t");
00174
00184 void absolute_progress(
00185 float64_t current_val, float64_t val,
00186 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00187 const char* prefix="PROGRESS:\t");
00188
00193 void done();
00194
00196 inline void not_implemented(const char* file, int32_t line) const
00197 {
00198 message(MSG_ERROR, file, line, "Sorry, not yet implemented .\n");
00199 }
00200
00202 inline void deprecated(const char* file, int32_t line) const
00203 {
00204 message(MSG_WARN, file, line,
00205 "This function is deprecated and will be removed soon.\n");
00206 }
00207
00213 void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00214
00220 static char* skip_spaces(char* str);
00221
00227 static char* skip_blanks(char* str);
00228
00233 inline FILE* get_target() const
00234 {
00235 return target;
00236 }
00237
00242 void set_target(FILE* target);
00243
00245 inline void set_target_to_stderr() { set_target(stderr); }
00246
00248 inline void set_target_to_stdout() { set_target(stdout); }
00249
00251 inline void enable_progress()
00252 {
00253 show_progress=true;
00254
00255
00256 if (sg_io!=this)
00257 sg_io->enable_progress();
00258 }
00259
00261 inline void disable_progress()
00262 {
00263 show_progress=false;
00264
00265
00266 if (sg_io!=this)
00267 sg_io->disable_progress();
00268 }
00269
00271 inline void enable_file_and_line()
00272 {
00273 show_file_and_line=true;
00274
00275 if (sg_io!=this)
00276 sg_io->enable_file_and_line();
00277 }
00278
00280 inline void disable_file_and_line()
00281 {
00282 show_file_and_line=false;
00283
00284 if (sg_io!=this)
00285 sg_io->disable_file_and_line();
00286 }
00287
00289 inline void enable_syntax_highlighting()
00290 {
00291 syntax_highlight=true;
00292
00293 if (sg_io!=this)
00294 sg_io->enable_syntax_highlighting();
00295 }
00296
00298 inline void disable_syntax_highlighting()
00299 {
00300 syntax_highlight=false;
00301
00302 if (sg_io!=this)
00303 sg_io->disable_syntax_highlighting();
00304 }
00305
00310 static inline void set_dirname(const char* dirname)
00311 {
00312 strncpy(directory_name, dirname, FBUFSIZE);
00313 }
00314
00321 static inline char* concat_filename(const char* filename)
00322 {
00323 if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
00324 SG_SERROR("filename too long");
00325 SG_SDEBUG("filename=\"%s\"\n", file_buffer);
00326 return file_buffer;
00327 }
00328
00334 static inline int filter(CONST_DIRENT_T* d)
00335 {
00336 if (d)
00337 {
00338 char* fname=concat_filename(d->d_name);
00339
00340 if (!access(fname, R_OK))
00341 {
00342 struct stat s;
00343 if (!stat(fname, &s) && S_ISREG(s.st_mode))
00344 return 1;
00345 }
00346 }
00347
00348 return 0;
00349 }
00350
00355 inline int32_t ref()
00356 {
00357 ++refcount;
00358 return refcount;
00359 }
00360
00365 inline int32_t ref_count() const
00366 {
00367 return refcount;
00368 }
00369
00375 inline int32_t unref()
00376 {
00377 if (refcount==0 || --refcount==0)
00378 {
00379 delete this;
00380 return 0;
00381 }
00382 else
00383 return refcount;
00384 }
00385
00387 inline const char* get_name() { return "IO"; }
00388
00389 protected:
00396 const char* get_msg_intro(EMessageType prio) const;
00397
00398 protected:
00400 FILE* target;
00402 float64_t last_progress_time;
00404 float64_t progress_start_time;
00406 float64_t last_progress;
00408 bool show_progress;
00411 bool show_file_and_line;
00413 bool syntax_highlight;
00414
00416 EMessageType loglevel;
00418 static const EMessageType levels[NUM_LOG_LEVELS];
00420 static const char* message_strings_highlighted[NUM_LOG_LEVELS];
00422 static const char* message_strings[NUM_LOG_LEVELS];
00423
00425 static char file_buffer[FBUFSIZE];
00427 static char directory_name[FBUFSIZE];
00428
00429 private:
00430 int32_t refcount;
00431 };
00432 }
00433 #endif // __CIO_H__