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 #include <Availability.h>
00062 #ifndef __MAC_10_8
00063 #define __MAC_10_8 1080
00064 #endif
00065 #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
00066 #define CONST_DIRENT_T struct dirent
00067 #else
00068 #define CONST_DIRENT_T const struct dirent
00069 #endif // Lion or earlier
00070 #else //DARWIN
00071 #define CONST_DIRENT_T const struct dirent
00072 #endif //DARWIN
00073
00074 #define SG_SET_LOCALE_C setlocale(LC_ALL, "C")
00075 #define SG_RESET_LOCALE setlocale(LC_ALL, "")
00076
00077
00078
00079 #define SG_GCDEBUG(...) io->message(MSG_GCDEBUG, __FILE__, __LINE__, __VA_ARGS__)
00080 #define SG_DEBUG(...) io->message(MSG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
00081 #define SG_INFO(...) io->message(MSG_INFO, __FILE__, __LINE__, __VA_ARGS__)
00082 #define SG_WARNING(...) io->message(MSG_WARN, __FILE__, __LINE__, __VA_ARGS__)
00083 #define SG_ERROR(...) io->message(MSG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
00084 #define SG_UNSTABLE(func, ...) io->message(MSG_WARN, __FILE__, __LINE__, \
00085 __FILE__ ":" func ": Unstable method! Please report if it seems to " \
00086 "work or not to the Shogun mailing list. Thanking you in " \
00087 "anticipation. " __VA_ARGS__)
00088
00089 #define SG_PRINT(...) io->message(MSG_MESSAGEONLY, __FILE__, __LINE__, __VA_ARGS__)
00090 #define SG_NOTIMPLEMENTED io->not_implemented(__FILE__, __LINE__)
00091 #define SG_DEPRECATED io->deprecated(__FILE__, __LINE__)
00092
00093 #define SG_PROGRESS(...) io->progress(__VA_ARGS__)
00094 #define SG_ABS_PROGRESS(...) io->absolute_progress(__VA_ARGS__)
00095 #define SG_DONE() io->done()
00096
00097
00098 #define SG_SGCDEBUG(...) sg_io->message(MSG_GCDEBUG,__FILE__, __LINE__, __VA_ARGS__)
00099 #define SG_SDEBUG(...) sg_io->message(MSG_DEBUG,__FILE__, __LINE__, __VA_ARGS__)
00100 #define SG_SINFO(...) sg_io->message(MSG_INFO,__FILE__, __LINE__, __VA_ARGS__)
00101 #define SG_SWARNING(...) sg_io->message(MSG_WARN,__FILE__, __LINE__, __VA_ARGS__)
00102 #define SG_SERROR(...) sg_io->message(MSG_ERROR,__FILE__, __LINE__, __VA_ARGS__)
00103 #define SG_SPRINT(...) sg_io->message(MSG_MESSAGEONLY,__FILE__, __LINE__, __VA_ARGS__)
00104 #define SG_SPROGRESS(...) sg_io->progress(__VA_ARGS__)
00105 #define SG_SABS_PROGRESS(...) sg_io->absolute_progress(__VA_ARGS__)
00106 #define SG_SDONE() sg_io->done()
00107 #define SG_SNOTIMPLEMENTED sg_io->not_implemented(__FILE__, __LINE__)
00108 #define SG_SDEPRECATED sg_io->deprecated(__FILE__, __LINE__)
00109
00110 #define ASSERT(x) { if (!(x)) SG_SERROR("assertion %s failed in file %s line %d\n",#x, __FILE__, __LINE__);}
00111 #define REQUIRE(x, ...) { if (!(x)) SG_SERROR(__VA_ARGS__); }
00112
00113
00120 class SGIO
00121 {
00122 public:
00124 SGIO();
00126 SGIO(const SGIO& orig);
00127
00132 void set_loglevel(EMessageType level);
00133
00138 EMessageType get_loglevel() const;
00139
00144 inline bool get_show_progress() const
00145 {
00146 return show_progress;
00147 }
00148
00153 inline bool get_show_file_and_line() const
00154 {
00155 return show_file_and_line;
00156 }
00157
00162 inline bool get_syntax_highlight() const
00163 {
00164 return syntax_highlight;
00165 }
00166
00177 void message(EMessageType prio, const char* file,
00178 int32_t line, const char *fmt, ... ) const;
00179
00188 void progress(
00189 float64_t current_val,
00190 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00191 const char* prefix="PROGRESS:\t");
00192
00202 void absolute_progress(
00203 float64_t current_val, float64_t val,
00204 float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1,
00205 const char* prefix="PROGRESS:\t");
00206
00211 void done();
00212
00214 inline void not_implemented(const char* file, int32_t line) const
00215 {
00216 message(MSG_ERROR, file, line, "Sorry, not yet implemented .\n");
00217 }
00218
00220 inline void deprecated(const char* file, int32_t line) const
00221 {
00222 message(MSG_WARN, file, line,
00223 "This function is deprecated and will be removed soon.\n");
00224 }
00225
00231 void buffered_message(EMessageType prio, const char *fmt, ... ) const;
00232
00238 static char* skip_spaces(char* str);
00239
00245 static char* skip_blanks(char* str);
00246
00251 inline FILE* get_target() const
00252 {
00253 return target;
00254 }
00255
00260 void set_target(FILE* target);
00261
00263 inline void set_target_to_stderr() { set_target(stderr); }
00264
00266 inline void set_target_to_stdout() { set_target(stdout); }
00267
00269 inline void enable_progress()
00270 {
00271 show_progress=true;
00272
00273
00274 if (sg_io!=this)
00275 sg_io->enable_progress();
00276 }
00277
00279 inline void disable_progress()
00280 {
00281 show_progress=false;
00282
00283
00284 if (sg_io!=this)
00285 sg_io->disable_progress();
00286 }
00287
00289 inline void enable_file_and_line()
00290 {
00291 show_file_and_line=true;
00292
00293 if (sg_io!=this)
00294 sg_io->enable_file_and_line();
00295 }
00296
00298 inline void disable_file_and_line()
00299 {
00300 show_file_and_line=false;
00301
00302 if (sg_io!=this)
00303 sg_io->disable_file_and_line();
00304 }
00305
00307 inline void enable_syntax_highlighting()
00308 {
00309 syntax_highlight=true;
00310
00311 if (sg_io!=this)
00312 sg_io->enable_syntax_highlighting();
00313 }
00314
00316 inline void disable_syntax_highlighting()
00317 {
00318 syntax_highlight=false;
00319
00320 if (sg_io!=this)
00321 sg_io->disable_syntax_highlighting();
00322 }
00323
00328 static inline void set_dirname(const char* dirname)
00329 {
00330 strncpy(directory_name, dirname, FBUFSIZE);
00331 }
00332
00339 static inline char* concat_filename(const char* filename)
00340 {
00341 if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
00342 SG_SERROR("filename too long");
00343 SG_SDEBUG("filename=\"%s\"\n", file_buffer);
00344 return file_buffer;
00345 }
00346
00352 static inline int filter(CONST_DIRENT_T* d)
00353 {
00354 if (d)
00355 {
00356 char* fname=concat_filename(d->d_name);
00357
00358 if (!access(fname, R_OK))
00359 {
00360 struct stat s;
00361 if (!stat(fname, &s) && S_ISREG(s.st_mode))
00362 return 1;
00363 }
00364 }
00365
00366 return 0;
00367 }
00368
00373 inline int32_t ref()
00374 {
00375 ++refcount;
00376 return refcount;
00377 }
00378
00383 inline int32_t ref_count() const
00384 {
00385 return refcount;
00386 }
00387
00393 inline int32_t unref()
00394 {
00395 if (refcount==0 || --refcount==0)
00396 {
00397 delete this;
00398 return 0;
00399 }
00400 else
00401 return refcount;
00402 }
00403
00405 inline const char* get_name() { return "SGIO"; }
00406
00407 protected:
00414 const char* get_msg_intro(EMessageType prio) const;
00415
00416 protected:
00418 FILE* target;
00420 float64_t last_progress_time;
00422 float64_t progress_start_time;
00424 float64_t last_progress;
00426 bool show_progress;
00429 bool show_file_and_line;
00431 bool syntax_highlight;
00432
00434 EMessageType loglevel;
00436 static const EMessageType levels[NUM_LOG_LEVELS];
00438 static const char* message_strings_highlighted[NUM_LOG_LEVELS];
00440 static const char* message_strings[NUM_LOG_LEVELS];
00441
00443 static char file_buffer[FBUFSIZE];
00445 static char directory_name[FBUFSIZE];
00446
00447 private:
00448 int32_t refcount;
00449 };
00450
00458 struct substring
00459 {
00461 char *start;
00463 char *end;
00464 };
00465
00466
00472 inline char* c_string_of_substring(substring s)
00473 {
00474 uint32_t len = s.end - s.start+1;
00475 char* ret = SG_CALLOC(char, len);
00476 memcpy(ret,s.start,len-1);
00477 return ret;
00478 }
00479
00484 inline void print_substring(substring s)
00485 {
00486 char* c_string = c_string_of_substring(s);
00487 SG_SPRINT("%s\n", c_string);
00488 SG_FREE(c_string);
00489 }
00490
00497 inline float32_t float_of_substring(substring s)
00498 {
00499 char* endptr = s.end;
00500 float32_t f = strtof(s.start,&endptr);
00501 if (endptr == s.start && s.start != s.end)
00502 SG_SERROR("error: %s is not a float!\n", c_string_of_substring(s));
00503
00504 return f;
00505 }
00506
00512 inline float64_t double_of_substring(substring s)
00513 {
00514 char* endptr = s.end;
00515 float64_t f = strtod(s.start,&endptr);
00516 if (endptr == s.start && s.start != s.end)
00517 SG_SERROR("Error!:%s is not a double!\n", c_string_of_substring(s));
00518
00519 return f;
00520 }
00521
00527 inline int32_t int_of_substring(substring s)
00528 {
00529 char* c_string = c_string_of_substring(s);
00530 int32_t int_val = atoi(c_string);
00531 SG_FREE(c_string);
00532
00533 return int_val;
00534 }
00535
00541 inline uint32_t ulong_of_substring(substring s)
00542 {
00543 return strtoul(s.start,NULL,10);
00544 }
00545
00551 inline uint32_t ss_length(substring s)
00552 {
00553 return (s.end - s.start);
00554 }
00555
00556 }
00557 #endif // __SGIO_H__