SHOGUN v0.9.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 __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 // printf like funktions (with additional severity level) 00069 // for object derived from CSGObject 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 // printf like function using the global sg_io object 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 // static functions like CSVM::classify_example_helper call SG_PROGRESS 00264 if (sg_io!=this) 00265 sg_io->enable_progress(); 00266 } 00267 00269 inline void disable_progress() 00270 { 00271 show_progress=false; 00272 00273 // static functions like CSVM::classify_example_helper call SG_PROGRESS 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__