SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
SGIO.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Written (W) 1999-2009 Gunnar Raetsch
9  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
10  */
11 
12 #include <shogun/io/SGIO.h>
14 #include <shogun/lib/common.h>
15 #include <shogun/base/init.h>
16 #include <shogun/lib/memory.h>
17 #include <shogun/lib/Time.h>
19 #include <shogun/lib/RefCount.h>
20 
21 #include <stdarg.h>
22 #include <ctype.h>
23 #include <dirent.h>
24 #include <sys/stat.h>
25 #ifdef _WIN32
26 #include <io.h>
27 #else
28 #include <unistd.h>
29 #endif
30 #include <stdlib.h>
31 
32 #ifdef _WIN32
33 #define R_OK 4
34 #endif
35 
36 using namespace shogun;
37 
40 
41 const char* SGIO::message_strings[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
42  "[NOTICE] \0", "[WARN] \0", "[ERROR] \0",
43  "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
44 
45 const char* SGIO::message_strings_highlighted[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
46  "[NOTICE] \0", "\033[1;34m[WARN]\033[0m \0", "\033[1;31m[ERROR]\033[0m \0",
47  "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
48 
51 
54 
56 : target(stdout), last_progress_time(0), progress_start_time(0),
57  last_progress(0), show_progress(false), location_info(MSG_NONE),
58  syntax_highlight(true), loglevel(MSG_WARN)
59 {
60  m_refcount = new RefCount();
61 }
62 
63 SGIO::SGIO(const SGIO& orig)
64 : target(orig.get_target()), last_progress_time(0),
65  progress_start_time(0), last_progress(0),
66  show_progress(orig.get_show_progress()),
67  location_info(orig.get_location_info()),
68  syntax_highlight(orig.get_syntax_highlight()),
69  loglevel(orig.get_loglevel())
70 {
71  m_refcount = new RefCount();
72 }
73 
74 void SGIO::message(EMessageType prio, const char* function, const char* file,
75  int32_t line, const char *fmt, ... ) const
76 {
77  const char* msg_intro=get_msg_intro(prio);
78 
79  if (msg_intro)
80  {
81  char str[4096];
82  snprintf(str, sizeof(str), "%s", msg_intro);
83  int len=strlen(msg_intro);
84  char* s=str+len;
85 
86  /* file and line are shown for warnings and worse */
87  if (location_info==MSG_LINE_AND_FILE || prio==MSG_WARN || prio==MSG_ERROR)
88  {
89  snprintf(s, sizeof(str)-len, "In file %s line %d: ", file, line);
90  len=strlen(str);
91  s=str+len;
92  }
93  else if (location_info==MSG_FUNCTION)
94  {
95  snprintf(s, sizeof(str)-len, "%s: ", function);
96  len=strlen(str);
97  s=str+len;
98  }
99  else if (location_info==MSG_NONE)
100  {
101  ;
102  }
103 
104  va_list list;
105  va_start(list,fmt);
106  vsnprintf(s, sizeof(str)-len, fmt, list);
107  va_end(list);
108 
109  switch (prio)
110  {
111  case MSG_GCDEBUG:
112  case MSG_DEBUG:
113  case MSG_INFO:
114  case MSG_NOTICE:
115  case MSG_MESSAGEONLY:
116  if (sg_print_message)
117  sg_print_message(target, str);
118  break;
119 
120  case MSG_WARN:
121  if (sg_print_warning)
122  sg_print_warning(target, str);
123  break;
124 
125  case MSG_ERROR:
126  case MSG_CRITICAL:
127  case MSG_ALERT:
128  case MSG_EMERGENCY:
129  if (sg_print_error)
130  sg_print_error(target, str);
131  throw ShogunException(str);
132  break;
133  default:
134  break;
135  }
136 
137  fflush(target);
138  }
139 }
140 
141 void SGIO::buffered_message(EMessageType prio, const char *fmt, ... ) const
142 {
143  const char* msg_intro=get_msg_intro(prio);
144 
145  if (msg_intro)
146  {
147  fprintf(target, "%s", msg_intro);
148  va_list list;
149  va_start(list,fmt);
150  vfprintf(target,fmt,list);
151  va_end(list);
152  }
153 }
154 
156  float64_t current_val, float64_t min_val, float64_t max_val,
157  int32_t decimals, const char* prefix)
158 {
159  if (!show_progress)
160  return;
161 
162  float64_t runtime = CTime::get_curtime();
163 
164  char str[1000];
165  float64_t v=-1, estimate=0, total_estimate=0 ;
166 
167  if (max_val-min_val>0.0)
168  v=100*(current_val-min_val+1)/(max_val-min_val+1);
169  else
170  return;
171 
172  v=CMath::clamp(v,1e-5,100.0);
173 
174  if (decimals < 1)
175  decimals = 1;
176 
177  if (last_progress==0)
178  {
179  last_progress_time = runtime;
180  progress_start_time = runtime;
181  last_progress = v;
182  }
183  else
184  {
185  last_progress = v-1e-6;
186  if ((v!=100.0) && (runtime - last_progress_time<0.5))
187  {
188 
189  // This is made to display correctly the percentage
190  // if the algorithm execution is too fast
191  if (current_val >= max_val-1)
192  {
193  v = 100;
194  last_progress=v-1e-6;
195  snprintf(str, sizeof(str), "%%s %%%d.%df%%%% %%1.1f seconds remaining %%1.1f seconds total ",decimals+3, decimals);
196  message(MSG_MESSAGEONLY, "", "", -1, str, prefix, v, estimate, total_estimate);
197  message(MSG_MESSAGEONLY, "", "", -1, "\n");
198  }
199  return;
200  }
201 
202  last_progress_time = runtime;
203  estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
204  total_estimate = (last_progress_time-progress_start_time)/(v/100);
205  }
206 
207  if (estimate>120)
208  {
209  snprintf(str, sizeof(str), "%%s %%%d.%df%%%% %%1.1f minutes remaining %%1.1f minutes total \r",decimals+3, decimals);
210  message(MSG_MESSAGEONLY, "", "", -1, str, prefix, v, estimate/60, total_estimate/60);
211  }
212  else
213  {
214  snprintf(str, sizeof(str), "%%s %%%d.%df%%%% %%1.1f seconds remaining %%1.1f seconds total \r",decimals+3, decimals);
215  message(MSG_MESSAGEONLY, "", "", -1, str, prefix, v, estimate, total_estimate);
216  }
217 
218  // Print a new line if the execution is completed
219  // to prevent bad display
220  if (current_val >= max_val-1)
221  {
222  message(MSG_MESSAGEONLY, "", "", -1, "\n");
223  }
224 
225  fflush(target);
226 }
227 
229  float64_t current_val, float64_t val, float64_t min_val, float64_t max_val,
230  int32_t decimals, const char* prefix)
231 {
232  if (!show_progress)
233  return;
234 
235  float64_t runtime = CTime::get_curtime();
236 
237  char str[1000];
238  float64_t v=-1, estimate=0, total_estimate=0 ;
239 
240  if (max_val-min_val>0)
241  v=100*(val-min_val+1)/(max_val-min_val+1);
242 
243  if (decimals < 1)
244  decimals = 1;
245 
246  if (last_progress>v)
247  {
248  last_progress_time = runtime;
249  progress_start_time = runtime;
250  last_progress = v;
251  }
252  else
253  {
254  v=CMath::clamp(v,1e-5,100.0);
255  last_progress = v-1e-6;
256 
257  if ((v!=100.0) && (runtime - last_progress_time<100))
258  return;
259 
260  last_progress_time = runtime;
261  estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
262  total_estimate = (last_progress_time-progress_start_time)/(v/100);
263  }
264 
265  if (estimate>120)
266  {
267  snprintf(str, sizeof(str), "%%s %%%d.%df %%1.1f minutes remaining %%1.1f minutes total \r",decimals+3, decimals);
268  message(MSG_MESSAGEONLY, "", "", -1, str, prefix, current_val, estimate/60, total_estimate/60);
269  }
270  else
271  {
272  snprintf(str, sizeof(str), "%%s %%%d.%df %%1.1f seconds remaining %%1.1f seconds total \r",decimals+3, decimals);
273  message(MSG_MESSAGEONLY, "", "", -1, str, prefix, current_val, estimate, total_estimate);
274  }
275 
276  fflush(target);
277 }
278 
280 {
281  if (!show_progress)
282  return;
283 
284  message(MSG_INFO, "", "", -1, "done.\n");
285 }
286 
287 char* SGIO::skip_spaces(char* str)
288 {
289  int32_t i=0;
290 
291  if (str)
292  {
293  for (i=0; isspace(str[i]); i++);
294 
295  return &str[i];
296  }
297  else
298  return str;
299 }
300 
301 char* SGIO::skip_blanks(char* str)
302 {
303  int32_t i=0;
304 
305  if (str)
306  {
307  for (i=0; isblank(str[i]); i++);
308 
309  return &str[i];
310  }
311  else
312  return str;
313 }
314 
316 {
317  return loglevel;
318 }
319 
321 {
322  loglevel=level;
323 }
324 
325 void SGIO::set_target(FILE* t)
326 {
327  target=t;
328 }
329 
330 const char* SGIO::get_msg_intro(EMessageType prio) const
331 {
332  for (int32_t i=NUM_LOG_LEVELS-1; i>=0; i--)
333  {
334  // ignore msg if prio's level is under loglevel,
335  // but not if prio's level higher than MSG_WARN
336  if (levels[i]<loglevel && prio<=MSG_WARN)
337  return NULL;
338 
339  if (levels[i]==prio)
340  {
341  if (syntax_highlight)
342  return message_strings_highlighted[i];
343  else
344  return message_strings[i];
345  }
346  }
347 
348  return NULL;
349 }
350 
352 {
353  uint32_t len = s.end - s.start+1;
354  char* ret = SG_CALLOC(char, len);
355  sg_memcpy(ret,s.start,len-1);
356  return ret;
357 }
358 
360 {
361  char* c_string = c_string_of_substring(s);
362  SG_SPRINT("%s\n", c_string)
363  SG_FREE(c_string);
364 }
365 
367 {
368  char* endptr = s.end;
369  float32_t f = strtof(s.start,&endptr);
370  if (endptr == s.start && s.start != s.end)
371  SG_SERROR("error: %s is not a float!\n", c_string_of_substring(s))
372 
373  return f;
374 }
375 
377 {
378  char* endptr = s.end;
379  float64_t f = strtod(s.start,&endptr);
380  if (endptr == s.start && s.start != s.end)
381  SG_SERROR("Error!:%s is not a double!\n", c_string_of_substring(s))
382 
383  return f;
384 }
385 
387 {
388  char* c_string = c_string_of_substring(s);
389  int32_t int_val = atoi(c_string);
390  SG_FREE(c_string);
391 
392  return int_val;
393 }
394 
396 {
397  return strtoul(s.start,NULL,10);
398 }
399 
401 {
402  return (s.end - s.start);
403 }
404 
405 char* SGIO::concat_filename(const char* filename)
406 {
407 #ifdef WIN32
408  if (snprintf(file_buffer, FBUFSIZE, "%s\\%s", directory_name, filename) > FBUFSIZE)
409 #else
410  if (snprintf(file_buffer, FBUFSIZE, "%s/%s", directory_name, filename) > FBUFSIZE)
411 #endif
412  SG_SERROR("filename too long")
413 
414  SG_SDEBUG("filename=\"%s\"\n", file_buffer)
415  return file_buffer;
416 }
417 
419 {
420  if (d)
421  {
422  char* fname=concat_filename(d->d_name);
423 
424  if (!access(fname, R_OK))
425  {
426  struct stat s;
427  if (!stat(fname, &s) && S_ISREG(s.st_mode))
428  return 1;
429  }
430  }
431 
432  return 0;
433 }
434 
436 {
437  delete m_refcount;
438 }
439 
440 int32_t SGIO::ref()
441 {
442  return m_refcount->ref();
443 }
444 
445 int32_t SGIO::ref_count() const
446 {
447  return m_refcount->ref_count();
448 }
449 
450 int32_t SGIO::unref()
451 {
452  int32_t rc = m_refcount->unref();
453  if (rc==0)
454  {
455  delete this;
456  return 0;
457  }
458 
459  return rc;
460 }
int32_t unref()
Definition: SGIO.cpp:450
void set_loglevel(EMessageType level)
Definition: SGIO.cpp:320
virtual ~SGIO()
Definition: SGIO.cpp:435
static char * skip_spaces(char *str)
Definition: SGIO.cpp:287
int32_t ref_count() const
Definition: SGIO.cpp:445
static uint32_t ss_length(substring s)
Definition: SGIO.cpp:400
void buffered_message(EMessageType prio, const char *fmt,...) const
Definition: SGIO.cpp:141
char * end
Definition: SGIO.h:233
#define NUM_LOG_LEVELS
Definition: SGIO.h:67
void set_target(FILE *target)
Definition: SGIO.cpp:325
Class ShogunException defines an exception which is thrown whenever an error inside of shogun occurs...
void(* sg_print_warning)(FILE *target, const char *str)
function called to print warning messages
Definition: init.cpp:48
float64_t last_progress
Definition: SGIO.h:575
char * start
Definition: SGIO.h:231
SG_FORCED_INLINE int32_t ref()
Definition: RefCount.h:26
static char * skip_blanks(char *str)
Definition: SGIO.cpp:301
static int filter(CONST_DIRENT_T *d)
Definition: SGIO.cpp:418
struct Substring, specified by start position and end position.
Definition: SGIO.h:228
static float64_t get_curtime()
Definition: Time.h:116
static char file_buffer[FBUFSIZE]
file name buffer
Definition: SGIO.h:594
#define SG_SPRINT(...)
Definition: SGIO.h:179
void(* sg_print_error)(FILE *target, const char *str)
function called to print error messages
Definition: init.cpp:51
#define FBUFSIZE
Definition: SGIO.h:68
void message(EMessageType prio, const char *function, const char *file, int32_t line, const char *fmt,...) const
Definition: SGIO.cpp:74
FILE * target
Definition: SGIO.h:569
SG_FORCED_INLINE int32_t unref()
Definition: RefCount.h:35
static char * c_string_of_substring(substring s)
Definition: SGIO.cpp:351
float64_t last_progress_time
Definition: SGIO.h:571
double float64_t
Definition: common.h:60
int32_t ref()
Definition: SGIO.cpp:440
static float32_t float_of_substring(substring s)
Definition: SGIO.cpp:366
static uint32_t ulong_of_substring(substring s)
Definition: SGIO.cpp:395
static const char * message_strings[NUM_LOG_LEVELS]
Definition: SGIO.h:591
static void print_substring(substring s)
Definition: SGIO.cpp:359
EMessageType get_loglevel() const
Definition: SGIO.cpp:315
#define CONST_DIRENT_T
Definition: SGIO.h:81
float64_t progress_start_time
Definition: SGIO.h:573
float float32_t
Definition: common.h:59
void(* sg_print_message)(FILE *target, const char *str)
function called to print normal messages
Definition: init.cpp:45
static int32_t int_of_substring(substring s)
Definition: SGIO.cpp:386
EMessageType
Definition: SGIO.h:43
EMessageLocation location_info
Definition: SGIO.h:580
EMessageType loglevel
Definition: SGIO.h:585
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
#define SG_SDEBUG(...)
Definition: SGIO.h:167
const char * get_msg_intro(EMessageType prio) const
Definition: SGIO.cpp:330
#define SG_SERROR(...)
Definition: SGIO.h:178
static char directory_name[FBUFSIZE]
directory name buffer
Definition: SGIO.h:596
void progress(float64_t current_val, float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1, const char *prefix="PROGRESS:\t")
Definition: SGIO.cpp:155
void absolute_progress(float64_t current_val, float64_t val, float64_t min_val=0.0, float64_t max_val=1.0, int32_t decimals=1, const char *prefix="PROGRESS:\t")
Definition: SGIO.cpp:228
SG_FORCED_INLINE int32_t ref_count()
Definition: RefCount.h:44
static char * concat_filename(const char *filename)
Definition: SGIO.cpp:405
Class SGIO, used to do input output operations throughout shogun.
Definition: SGIO.h:242
bool show_progress
Definition: SGIO.h:577
bool syntax_highlight
Definition: SGIO.h:582
static T clamp(T value, T lb, T ub)
Definition: Math.h:240
static float64_t double_of_substring(substring s)
Definition: SGIO.cpp:376
static const EMessageType levels[NUM_LOG_LEVELS]
Definition: SGIO.h:587
static const char * message_strings_highlighted[NUM_LOG_LEVELS]
Definition: SGIO.h:589
void done()
Definition: SGIO.cpp:279

SHOGUN Machine Learning Toolbox - Documentation