00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __IO_H__
00013 #define __IO_H__
00014
00015 #include <stdio.h>
00016 #include <stdarg.h>
00017 #include <string.h>
00018 #include <dirent.h>
00019 #include <unistd.h>
00020 #include <locale.h>
00021
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include "lib/common.h"
00026 #include "base/init.h"
00027
00028 namespace shogun
00029 {
00030 class IO;
00031 extern IO* sg_io;
00032 }
00033
00034
00035 namespace shogun
00036 {
00041 enum EMessageType
00042 {
00043 MSG_GCDEBUG,
00044 MSG_DEBUG,
00045 MSG_INFO,
00046 MSG_NOTICE,
00047 MSG_WARN,
00048 MSG_ERROR,
00049 MSG_CRITICAL,
00050 MSG_ALERT,
00051 MSG_EMERGENCY,
00052 MSG_MESSAGEONLY
00053 };
00054
00055
00056 #define NUM_LOG_LEVELS 10
00057 #define FBUFSIZE 4096
00058
00059 #ifdef DARWIN
00060 #define CONST_DIRENT_T struct dirent
00061 #else //DARWIN
00062 #define CONST_DIRENT_T const struct dirent
00063 #endif //DARWIN
00064
00065 #define SG_SET_LOCALE_C setlocale(LC_ALL, "C")
00066 #define SG_RESET_LOCALE setlocale(LC_ALL, "")
00067
00068
00069
00070 #define SG_GCDEBUG(...) io->message(MSG_GCDEBUG, __FILE__, __LINE__, __VA_ARGS__)
00071 #define SG_DEBUG(...) io->message(MSG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
00072 #define SG_INFO(...) io->message(MSG_INFO, __FILE__, __LINE__, __VA_ARGS__)
00073 #define SG_WARNING(...) io->message(MSG_WARN, __FILE__, __LINE__, __VA_ARGS__)
00074 #define SG_ERROR(...) io->message(MSG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
00075 #define SG_UNSTABLE(func, ...) io->message(MSG_WARN, __FILE__, __LINE__, \
00076 __FILE__ ":" func ": Unstable method! Please report if it seems to " \
00077 "work or not to the Shogun mailing list. Thanking you in " \
00078 "anticipation. " __VA_ARGS__)
00079
00080 #define SG_PRINT(...) io->message(MSG_MESSAGEONLY, __FILE__, __LINE__, __VA_ARGS__)
00081 #define SG_NOTIMPLEMENTED io->not_implemented(__FILE__, __LINE__)
00082 #define SG_DEPRECATED io->deprecated(__FILE__, __LINE__)
00083
00084 #define SG_PROGRESS(...) io->progress(__VA_ARGS__)
00085 #define SG_ABS_PROGRESS(...) io->absolute_progress(__VA_ARGS__)
00086 #define SG_DONE() io->done()
00087
00088
00089 #define SG_SGCDEBUG(...) sg_io->message(MSG_GCDEBUG,__FILE__, __LINE__, __VA_ARGS__)
00090 #define SG_SDEBUG(...) sg_io->message(MSG_DEBUG,__FILE__, __LINE__, __VA_ARGS__)
00091 #define SG_SINFO(...) sg_io->message(MSG_INFO,__FILE__, __LINE__, __VA_ARGS__)
00092 #define SG_SWARNING(...) sg_io->message(MSG_WARN,__FILE__, __LINE__, __VA_ARGS__)
00093 #define SG_SERROR(...) sg_io->message(MSG_ERROR,__FILE__, __LINE__, __VA_ARGS__)
00094 #define SG_SPRINT(...) sg_io->message(MSG_MESSAGEONLY,__FILE__, __LINE__, __VA_ARGS__)
00095 #define SG_SPROGRESS(...) sg_io->progress(__VA_ARGS__)
00096 #define SG_SABS_PROGRESS(...) sg_io->absolute_progress(__VA_ARGS__)
00097 #define SG_SDONE() sg_io->done()
00098 #define SG_SNOTIMPLEMENTED sg_io->not_implemented(__FILE__, __LINE__)
00099 #define SG_SDEPRECATED sg_io->deprecated(__FILE__, __LINE__)
00100
00101 #define ASSERT(x) { if (!(x)) SG_SERROR("assertion %s failed in file %s line %d\n",#x, __FILE__, __LINE__);}
00102
00103
00110 class IO
00111 {
00112 public:
00114 IO();
00116 IO(const IO& orig);
00117
00122 void set_loglevel(EMessageType level);
00123
00128 EMessageType get_loglevel() const;
00129
00134 inline bool get_show_progress() const
00135 {
00136 return show_progress;
00137 }
00138
00143 inline bool get_show_file_and_line() const
00144 {
00145 return show_file_and_line;
00146 }
00147
00152 inline bool get_syntax_highlight() const
00153 {
00154 return syntax_highlight;
00155 }
00156
00167 void message(EMessageType prio, const char* file,
00168 int32_t line, const char *fmt, ... ) const;
00169
00178 void progress(
00179 float64_t current_val,
00180 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00181 const char* prefix="PROGRESS:\t");
00182
00192 void absolute_progress(
00193 float64_t current_val, float64_t val,
00194 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00195 const char* prefix="PROGRESS:\t");
00196
00201 void done();
00202
00204 inline void not_implemented(const char* file, int32_t line) const
00205 {
00206 message(MSG_ERROR, file, line, "Sorry, not yet implemented .\n");
00207 }
00208
00210 inline void deprecated(const char* file, int32_t line) const
00211 {
00212 message(MSG_WARN, file, line,
00213 "This function is deprecated and will be removed soon.\n");
00214 }
00215
00221 void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00222
00228 static char* skip_spaces(char* str);
00229
00235 static char* skip_blanks(char* str);
00236
00241 inline FILE* get_target() const
00242 {
00243 return target;
00244 }
00245
00250 void set_target(FILE* target);
00251
00253 inline void set_target_to_stderr() { set_target(stderr); }
00254
00256 inline void set_target_to_stdout() { set_target(stdout); }
00257
00259 inline void enable_progress()
00260 {
00261 show_progress=true;
00262
00263
00264 if (sg_io!=this)
00265 sg_io->enable_progress();
00266 }
00267
00269 inline void disable_progress()
00270 {
00271 show_progress=false;
00272
00273
00274 if (sg_io!=this)
00275 sg_io->disable_progress();
00276 }
00277
00279 inline void enable_file_and_line()
00280 {
00281 show_file_and_line=true;
00282
00283 if (sg_io!=this)
00284 sg_io->enable_file_and_line();
00285 }
00286
00288 inline void disable_file_and_line()
00289 {
00290 show_file_and_line=false;
00291
00292 if (sg_io!=this)
00293 sg_io->disable_file_and_line();
00294 }
00295
00297 inline void enable_syntax_highlighting()
00298 {
00299 syntax_highlight=true;
00300
00301 if (sg_io!=this)
00302 sg_io->enable_syntax_highlighting();
00303 }
00304
00306 inline void disable_syntax_highlighting()
00307 {
00308 syntax_highlight=false;
00309
00310 if (sg_io!=this)
00311 sg_io->disable_syntax_highlighting();
00312 }
00313
00318 static inline void set_dirname(const char* dirname)
00319 {
00320 strncpy(directory_name, dirname, FBUFSIZE);
00321 }
00322
00329 static inline char* concat_filename(const char* filename)
00330 {
00331 if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
00332 SG_SERROR("filename too long");
00333 SG_SDEBUG("filename=\"%s\"\n", file_buffer);
00334 return file_buffer;
00335 }
00336
00342 static inline int filter(CONST_DIRENT_T* d)
00343 {
00344 if (d)
00345 {
00346 char* fname=concat_filename(d->d_name);
00347
00348 if (!access(fname, R_OK))
00349 {
00350 struct stat s;
00351 if (!stat(fname, &s) && S_ISREG(s.st_mode))
00352 return 1;
00353 }
00354 }
00355
00356 return 0;
00357 }
00358
00363 inline int32_t ref()
00364 {
00365 ++refcount;
00366 return refcount;
00367 }
00368
00373 inline int32_t ref_count() const
00374 {
00375 return refcount;
00376 }
00377
00383 inline int32_t unref()
00384 {
00385 if (refcount==0 || --refcount==0)
00386 {
00387 delete this;
00388 return 0;
00389 }
00390 else
00391 return refcount;
00392 }
00393
00395 inline const char* get_name() { return "IO"; }
00396
00397 protected:
00404 const char* get_msg_intro(EMessageType prio) const;
00405
00406 protected:
00408 FILE* target;
00410 float64_t last_progress_time;
00412 float64_t progress_start_time;
00414 float64_t last_progress;
00416 bool show_progress;
00419 bool show_file_and_line;
00421 bool syntax_highlight;
00422
00424 EMessageType loglevel;
00426 static const EMessageType levels[NUM_LOG_LEVELS];
00428 static const char* message_strings_highlighted[NUM_LOG_LEVELS];
00430 static const char* message_strings[NUM_LOG_LEVELS];
00431
00433 static char file_buffer[FBUFSIZE];
00435 static char directory_name[FBUFSIZE];
00436
00437 private:
00438 int32_t refcount;
00439 };
00440 }
00441 #endif // __IO_H__