SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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/lib/config.h>
13 
14 #include <shogun/io/SGIO.h>
16 #include <shogun/lib/Signal.h>
17 #include <shogun/lib/common.h>
18 #include <shogun/lib/Time.h>
20 
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <ctype.h>
24 
25 #include <stdlib.h>
26 
27 using namespace shogun;
28 
31 
32 const char* SGIO::message_strings[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
33  "[NOTICE] \0", "[WARN] \0", "[ERROR] \0",
34  "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
35 
36 const char* SGIO::message_strings_highlighted[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
37  "[NOTICE] \0", "\033[1;34m[WARN]\033[0m \0", "\033[1;31m[ERROR]\033[0m \0",
38  "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
39 
42 
45 
47 : target(stdout), last_progress_time(0), progress_start_time(0),
48  last_progress(1), show_progress(false), show_file_and_line(false),
49  syntax_highlight(true), loglevel(MSG_WARN), refcount(0)
50 {
51 }
52 
53 SGIO::SGIO(const SGIO& orig)
54 : target(orig.get_target()), last_progress_time(0),
55  progress_start_time(0), last_progress(1),
56  show_progress(orig.get_show_progress()),
57  show_file_and_line(orig.get_show_file_and_line()),
58  syntax_highlight(orig.get_syntax_highlight()),
59  loglevel(orig.get_loglevel()), refcount(0)
60 {
61 }
62 
63 void SGIO::message(EMessageType prio, const char* file,
64  int32_t line, const char *fmt, ... ) const
65 {
66  const char* msg_intro=get_msg_intro(prio);
67 
68  if (msg_intro)
69  {
70  char str[4096];
71  snprintf(str, sizeof(str), "%s", msg_intro);
72  int len=strlen(msg_intro);
73  char* s=str+len;
74 
75  if (show_file_and_line && line>=0)
76  {
77  snprintf(s, sizeof(str)-len, "In file %s line %d: ", file, line);
78  len=strlen(str);
79  s=str+len;
80  }
81 
82  va_list list;
83  va_start(list,fmt);
84  vsnprintf(s, sizeof(str)-len, fmt, list);
85  va_end(list);
86 
87  switch (prio)
88  {
89  case MSG_GCDEBUG:
90  case MSG_DEBUG:
91  case MSG_INFO:
92  case MSG_NOTICE:
93  case MSG_MESSAGEONLY:
94  if (sg_print_message)
96  break;
97 
98  case MSG_WARN:
99  if (sg_print_warning)
100  sg_print_warning(target, str);
101  break;
102 
103  case MSG_ERROR:
104  case MSG_CRITICAL:
105  case MSG_ALERT:
106  case MSG_EMERGENCY:
107  if (sg_print_error)
108  sg_print_error(target, str);
109  throw ShogunException(str);
110  break;
111  default:
112  break;
113  }
114 
115  fflush(target);
116  }
117 }
118 
119 void SGIO::buffered_message(EMessageType prio, const char *fmt, ... ) const
120 {
121  const char* msg_intro=get_msg_intro(prio);
122 
123  if (msg_intro)
124  {
125  fprintf(target, "%s", msg_intro);
126  va_list list;
127  va_start(list,fmt);
128  vfprintf(target,fmt,list);
129  va_end(list);
130  }
131 }
132 
134  float64_t current_val, float64_t min_val, float64_t max_val,
135  int32_t decimals, const char* prefix)
136 {
137  if (!show_progress)
138  return;
139 
140  float64_t runtime = CTime::get_curtime();
141 
142  char str[1000];
143  float64_t v=-1, estimate=0, total_estimate=0 ;
144 
145  if (max_val-min_val>0.0)
146  v=100*(current_val-min_val+1)/(max_val-min_val+1);
147 
148  if (decimals < 1)
149  decimals = 1;
150 
151  if (last_progress>v)
152  {
153  last_progress_time = runtime;
154  progress_start_time = runtime;
155  last_progress = v;
156  }
157  else
158  {
159  v=CMath::clamp(v,1e-5,100.0);
160  last_progress = v-1e-6;
161 
162  if ((v!=100.0) && (runtime - last_progress_time<0.5))
163  return;
164 
165  last_progress_time = runtime;
166  estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
167  total_estimate = (last_progress_time-progress_start_time)/(v/100);
168  }
169 
170  if (estimate>120)
171  {
172  snprintf(str, sizeof(str), "%%s %%%d.%df%%%% %%1.1f minutes remaining %%1.1f minutes total \r",decimals+3, decimals);
173  message(MSG_MESSAGEONLY, "", -1, str, prefix, v, estimate/60, total_estimate/60);
174  }
175  else
176  {
177  snprintf(str, sizeof(str), "%%s %%%d.%df%%%% %%1.1f seconds remaining %%1.1f seconds total \r",decimals+3, decimals);
178  message(MSG_MESSAGEONLY, "", -1, str, prefix, v, estimate, total_estimate);
179  }
180 
181  fflush(target);
182 }
183 
185  float64_t current_val, float64_t val, float64_t min_val, float64_t max_val,
186  int32_t decimals, const char* prefix)
187 {
188  if (!show_progress)
189  return;
190 
191  float64_t runtime = CTime::get_curtime();
192 
193  char str[1000];
194  float64_t v=-1, estimate=0, total_estimate=0 ;
195 
196  if (max_val-min_val>0)
197  v=100*(val-min_val+1)/(max_val-min_val+1);
198 
199  if (decimals < 1)
200  decimals = 1;
201 
202  if (last_progress>v)
203  {
204  last_progress_time = runtime;
205  progress_start_time = runtime;
206  last_progress = v;
207  }
208  else
209  {
210  v=CMath::clamp(v,1e-5,100.0);
211  last_progress = v-1e-6;
212 
213  if ((v!=100.0) && (runtime - last_progress_time<100))
214  return;
215 
216  last_progress_time = runtime;
217  estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
218  total_estimate = (last_progress_time-progress_start_time)/(v/100);
219  }
220 
221  if (estimate>120)
222  {
223  snprintf(str, sizeof(str), "%%s %%%d.%df %%1.1f minutes remaining %%1.1f minutes total \r",decimals+3, decimals);
224  message(MSG_MESSAGEONLY, "", -1, str, prefix, current_val, estimate/60, total_estimate/60);
225  }
226  else
227  {
228  snprintf(str, sizeof(str), "%%s %%%d.%df %%1.1f seconds remaining %%1.1f seconds total \r",decimals+3, decimals);
229  message(MSG_MESSAGEONLY, "", -1, str, prefix, current_val, estimate, total_estimate);
230  }
231 
232  fflush(target);
233 }
234 
236 {
237  if (!show_progress)
238  return;
239 
240  message(MSG_INFO, "", -1, "done.\n");
241 }
242 
243 char* SGIO::skip_spaces(char* str)
244 {
245  int32_t i=0;
246 
247  if (str)
248  {
249  for (i=0; isspace(str[i]); i++);
250 
251  return &str[i];
252  }
253  else
254  return str;
255 }
256 
257 char* SGIO::skip_blanks(char* str)
258 {
259  int32_t i=0;
260 
261  if (str)
262  {
263  for (i=0; isblank(str[i]); i++);
264 
265  return &str[i];
266  }
267  else
268  return str;
269 }
270 
272 {
273  return loglevel;
274 }
275 
277 {
278  loglevel=level;
279 }
280 
281 void SGIO::set_target(FILE* t)
282 {
283  target=t;
284 }
285 
286 const char* SGIO::get_msg_intro(EMessageType prio) const
287 {
288  for (int32_t i=NUM_LOG_LEVELS-1; i>=0; i--)
289  {
290  // ignore msg if prio's level is under loglevel,
291  // but not if prio's level higher than MSG_WARN
292  if (levels[i]<loglevel && prio<=MSG_WARN)
293  return NULL;
294 
295  if (levels[i]==prio)
296  {
297  if (syntax_highlight)
298  return message_strings_highlighted[i];
299  else
300  return message_strings[i];
301  }
302  }
303 
304  return NULL;
305 }

SHOGUN Machine Learning Toolbox - Documentation