SHOGUN
v1.1.0
|
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-2009 Soeren Sonnenburg 00008 * Written (W) 1999-2008 Gunnar Raetsch 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 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 // printf like funktions (with additional severity level) 00070 // for object derived from CSGObject 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 // printf like function using the global sg_io object 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 // static functions like CSVM::classify_example_helper call SG_PROGRESS 00265 if (sg_io!=this) 00266 sg_io->enable_progress(); 00267 } 00268 00270 inline void disable_progress() 00271 { 00272 show_progress=false; 00273 00274 // static functions like CSVM::classify_example_helper call SG_PROGRESS 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__