00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __SGIO_H__
00013 #define __SGIO_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 <shogun/lib/common.h>
00026 #include <shogun/base/init.h>
00027
00028 namespace shogun
00029 {
00030 class SGIO;
00032 extern SGIO* sg_io;
00033 }
00034
00035
00036 namespace shogun
00037 {
00042 enum EMessageType
00043 {
00044 MSG_GCDEBUG,
00045 MSG_DEBUG,
00046 MSG_INFO,
00047 MSG_NOTICE,
00048 MSG_WARN,
00049 MSG_ERROR,
00050 MSG_CRITICAL,
00051 MSG_ALERT,
00052 MSG_EMERGENCY,
00053 MSG_MESSAGEONLY
00054 };
00055
00056
00057 #define NUM_LOG_LEVELS 10
00058 #define FBUFSIZE 4096
00059
00060 #ifdef DARWIN
00061 #define CONST_DIRENT_T struct dirent
00062 #else //DARWIN
00063 #define CONST_DIRENT_T const struct dirent
00064 #endif //DARWIN
00065
00066 #define SG_SET_LOCALE_C setlocale(LC_ALL, "C")
00067 #define SG_RESET_LOCALE setlocale(LC_ALL, "")
00068
00069
00070
00071 #define SG_GCDEBUG(...) io->message(MSG_GCDEBUG, __FILE__, __LINE__, __VA_ARGS__)
00072 #define SG_DEBUG(...) io->message(MSG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
00073 #define SG_INFO(...) io->message(MSG_INFO, __FILE__, __LINE__, __VA_ARGS__)
00074 #define SG_WARNING(...) io->message(MSG_WARN, __FILE__, __LINE__, __VA_ARGS__)
00075 #define SG_ERROR(...) io->message(MSG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
00076 #define SG_UNSTABLE(func, ...) io->message(MSG_WARN, __FILE__, __LINE__, \
00077 __FILE__ ":" func ": Unstable method! Please report if it seems to " \
00078 "work or not to the Shogun mailing list. Thanking you in " \
00079 "anticipation. " __VA_ARGS__)
00080
00081 #define SG_PRINT(...) io->message(MSG_MESSAGEONLY, __FILE__, __LINE__, __VA_ARGS__)
00082 #define SG_NOTIMPLEMENTED io->not_implemented(__FILE__, __LINE__)
00083 #define SG_DEPRECATED io->deprecated(__FILE__, __LINE__)
00084
00085 #define SG_PROGRESS(...) io->progress(__VA_ARGS__)
00086 #define SG_ABS_PROGRESS(...) io->absolute_progress(__VA_ARGS__)
00087 #define SG_DONE() io->done()
00088
00089
00090 #define SG_SGCDEBUG(...) sg_io->message(MSG_GCDEBUG,__FILE__, __LINE__, __VA_ARGS__)
00091 #define SG_SDEBUG(...) sg_io->message(MSG_DEBUG,__FILE__, __LINE__, __VA_ARGS__)
00092 #define SG_SINFO(...) sg_io->message(MSG_INFO,__FILE__, __LINE__, __VA_ARGS__)
00093 #define SG_SWARNING(...) sg_io->message(MSG_WARN,__FILE__, __LINE__, __VA_ARGS__)
00094 #define SG_SERROR(...) sg_io->message(MSG_ERROR,__FILE__, __LINE__, __VA_ARGS__)
00095 #define SG_SPRINT(...) sg_io->message(MSG_MESSAGEONLY,__FILE__, __LINE__, __VA_ARGS__)
00096 #define SG_SPROGRESS(...) sg_io->progress(__VA_ARGS__)
00097 #define SG_SABS_PROGRESS(...) sg_io->absolute_progress(__VA_ARGS__)
00098 #define SG_SDONE() sg_io->done()
00099 #define SG_SNOTIMPLEMENTED sg_io->not_implemented(__FILE__, __LINE__)
00100 #define SG_SDEPRECATED sg_io->deprecated(__FILE__, __LINE__)
00101
00102 #define ASSERT(x) { if (!(x)) SG_SERROR("assertion %s failed in file %s line %d\n",#x, __FILE__, __LINE__);}
00103
00104
00111 class SGIO
00112 {
00113 public:
00115 SGIO();
00117 SGIO(const SGIO& orig);
00118
00123 void set_loglevel(EMessageType level);
00124
00129 EMessageType get_loglevel() const;
00130
00135 inline bool get_show_progress() const
00136 {
00137 return show_progress;
00138 }
00139
00144 inline bool get_show_file_and_line() const
00145 {
00146 return show_file_and_line;
00147 }
00148
00153 inline bool get_syntax_highlight() const
00154 {
00155 return syntax_highlight;
00156 }
00157
00168 void message(EMessageType prio, const char* file,
00169 int32_t line, const char *fmt, ... ) const;
00170
00179 void progress(
00180 float64_t current_val,
00181 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00182 const char* prefix="PROGRESS:\t");
00183
00193 void absolute_progress(
00194 float64_t current_val, float64_t val,
00195 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00196 const char* prefix="PROGRESS:\t");
00197
00202 void done();
00203
00205 inline void not_implemented(const char* file, int32_t line) const
00206 {
00207 message(MSG_ERROR, file, line, "Sorry, not yet implemented .\n");
00208 }
00209
00211 inline void deprecated(const char* file, int32_t line) const
00212 {
00213 message(MSG_WARN, file, line,
00214 "This function is deprecated and will be removed soon.\n");
00215 }
00216
00222 void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00223
00229 static char* skip_spaces(char* str);
00230
00236 static char* skip_blanks(char* str);
00237
00242 inline FILE* get_target() const
00243 {
00244 return target;
00245 }
00246
00251 void set_target(FILE* target);
00252
00254 inline void set_target_to_stderr() { set_target(stderr); }
00255
00257 inline void set_target_to_stdout() { set_target(stdout); }
00258
00260 inline void enable_progress()
00261 {
00262 show_progress=true;
00263
00264
00265 if (sg_io!=this)
00266 sg_io->enable_progress();
00267 }
00268
00270 inline void disable_progress()
00271 {
00272 show_progress=false;
00273
00274
00275 if (sg_io!=this)
00276 sg_io->disable_progress();
00277 }
00278
00280 inline void enable_file_and_line()
00281 {
00282 show_file_and_line=true;
00283
00284 if (sg_io!=this)
00285 sg_io->enable_file_and_line();
00286 }
00287
00289 inline void disable_file_and_line()
00290 {
00291 show_file_and_line=false;
00292
00293 if (sg_io!=this)
00294 sg_io->disable_file_and_line();
00295 }
00296
00298 inline void enable_syntax_highlighting()
00299 {
00300 syntax_highlight=true;
00301
00302 if (sg_io!=this)
00303 sg_io->enable_syntax_highlighting();
00304 }
00305
00307 inline void disable_syntax_highlighting()
00308 {
00309 syntax_highlight=false;
00310
00311 if (sg_io!=this)
00312 sg_io->disable_syntax_highlighting();
00313 }
00314
00319 static inline void set_dirname(const char* dirname)
00320 {
00321 strncpy(directory_name, dirname, FBUFSIZE);
00322 }
00323
00330 static inline char* concat_filename(const char* filename)
00331 {
00332 if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
00333 SG_SERROR("filename too long");
00334 SG_SDEBUG("filename=\"%s\"\n", file_buffer);
00335 return file_buffer;
00336 }
00337
00343 static inline int filter(CONST_DIRENT_T* d)
00344 {
00345 if (d)
00346 {
00347 char* fname=concat_filename(d->d_name);
00348
00349 if (!access(fname, R_OK))
00350 {
00351 struct stat s;
00352 if (!stat(fname, &s) && S_ISREG(s.st_mode))
00353 return 1;
00354 }
00355 }
00356
00357 return 0;
00358 }
00359
00364 inline int32_t ref()
00365 {
00366 ++refcount;
00367 return refcount;
00368 }
00369
00374 inline int32_t ref_count() const
00375 {
00376 return refcount;
00377 }
00378
00384 inline int32_t unref()
00385 {
00386 if (refcount==0 || --refcount==0)
00387 {
00388 delete this;
00389 return 0;
00390 }
00391 else
00392 return refcount;
00393 }
00394
00396 inline const char* get_name() { return "SGIO"; }
00397
00398 protected:
00405 const char* get_msg_intro(EMessageType prio) const;
00406
00407 protected:
00409 FILE* target;
00411 float64_t last_progress_time;
00413 float64_t progress_start_time;
00415 float64_t last_progress;
00417 bool show_progress;
00420 bool show_file_and_line;
00422 bool syntax_highlight;
00423
00425 EMessageType loglevel;
00427 static const EMessageType levels[NUM_LOG_LEVELS];
00429 static const char* message_strings_highlighted[NUM_LOG_LEVELS];
00431 static const char* message_strings[NUM_LOG_LEVELS];
00432
00434 static char file_buffer[FBUFSIZE];
00436 static char directory_name[FBUFSIZE];
00437
00438 private:
00439 int32_t refcount;
00440 };
00441
00449 struct substring
00450 {
00452 char *start;
00454 char *end;
00455 };
00456
00457
00463 inline char* c_string_of_substring(substring s)
00464 {
00465 uint32_t len = s.end - s.start+1;
00466 char* ret = SG_CALLOC(char, len);
00467 memcpy(ret,s.start,len-1);
00468 return ret;
00469 }
00470
00475 inline void print_substring(substring s)
00476 {
00477 char* c_string = c_string_of_substring(s);
00478 SG_SPRINT("%s\n", c_string);
00479 SG_FREE(c_string);
00480 }
00481
00488 inline float32_t float_of_substring(substring s)
00489 {
00490 char* endptr = s.end;
00491 float32_t f = strtof(s.start,&endptr);
00492 if (endptr == s.start && s.start != s.end)
00493 SG_SERROR("error: %s is not a float!\n", c_string_of_substring(s));
00494
00495 return f;
00496 }
00497
00503 inline float64_t double_of_substring(substring s)
00504 {
00505 char* endptr = s.end;
00506 float64_t f = strtod(s.start,&endptr);
00507 if (endptr == s.start && s.start != s.end)
00508 SG_SERROR("Error!:%s is not a double!\n", c_string_of_substring(s));
00509
00510 return f;
00511 }
00512
00518 inline int32_t int_of_substring(substring s)
00519 {
00520 char* c_string = c_string_of_substring(s);
00521 int32_t int_val = atoi(c_string);
00522 SG_FREE(c_string);
00523
00524 return int_val;
00525 }
00526
00532 inline uint32_t ulong_of_substring(substring s)
00533 {
00534 return strtoul(s.start,NULL,10);
00535 }
00536
00542 inline uint32_t ss_length(substring s)
00543 {
00544 return (s.end - s.start);
00545 }
00546
00547 }
00548 #endif // __SGIO_H__