SGIO.cpp

Go to the documentation of this file.
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-2009 Gunnar Raetsch
00009  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00010  */
00011 
00012 #include <shogun/lib/config.h>
00013 
00014 #include <shogun/io/SGIO.h>
00015 #include <shogun/lib/ShogunException.h>
00016 #include <shogun/lib/Signal.h>
00017 #include <shogun/lib/common.h>
00018 #include <shogun/lib/Time.h>
00019 #include <shogun/mathematics/Math.h>
00020 
00021 #include <stdio.h>
00022 #include <stdarg.h>
00023 #include <ctype.h>
00024 
00025 #include <stdlib.h>
00026 
00027 using namespace shogun;
00028 
00029 const EMessageType SGIO::levels[NUM_LOG_LEVELS]={MSG_GCDEBUG, MSG_DEBUG, MSG_INFO, MSG_NOTICE,
00030     MSG_WARN, MSG_ERROR, MSG_CRITICAL, MSG_ALERT, MSG_EMERGENCY, MSG_MESSAGEONLY};
00031 
00032 const char* SGIO::message_strings[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
00033     "[NOTICE] \0", "[WARN] \0", "[ERROR] \0",
00034     "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
00035 
00036 const char* SGIO::message_strings_highlighted[NUM_LOG_LEVELS]={"[GCDEBUG] \0", "[DEBUG] \0", "[INFO] \0",
00037     "[NOTICE] \0", "\033[1;34m[WARN]\033[0m \0", "\033[1;31m[ERROR]\033[0m \0",
00038     "[CRITICAL] \0", "[ALERT] \0", "[EMERGENCY] \0", "\0"};
00039 
00041 char SGIO::file_buffer[FBUFSIZE];
00042 
00044 char SGIO::directory_name[FBUFSIZE];
00045 
00046 SGIO::SGIO()
00047 : target(stdout), last_progress_time(0), progress_start_time(0),
00048     last_progress(1), show_progress(false), show_file_and_line(false),
00049     syntax_highlight(true), loglevel(MSG_WARN), refcount(0)
00050 {
00051 }
00052 
00053 SGIO::SGIO(const SGIO& orig)
00054 : target(orig.get_target()), last_progress_time(0),
00055     progress_start_time(0), last_progress(1),
00056     show_progress(orig.get_show_progress()),
00057     show_file_and_line(orig.get_show_file_and_line()),
00058     syntax_highlight(orig.get_syntax_highlight()),
00059     loglevel(orig.get_loglevel()), refcount(0)
00060 {
00061 }
00062 
00063 void SGIO::message(EMessageType prio, const char* file,
00064         int32_t line, const char *fmt, ... ) const
00065 {
00066     const char* msg_intro=get_msg_intro(prio);
00067 
00068     if (msg_intro)
00069     {
00070         char str[4096];
00071         snprintf(str, sizeof(str), "%s", msg_intro);
00072         int len=strlen(msg_intro);
00073         char* s=str+len;
00074 
00075         if (show_file_and_line && line>=0)
00076         {
00077             snprintf(s, sizeof(str)-len, "In file %s line %d: ", file, line);
00078             len=strlen(str);
00079             s=str+len;
00080         }
00081 
00082         va_list list;
00083         va_start(list,fmt);
00084         vsnprintf(s, sizeof(str)-len, fmt, list);
00085         va_end(list);
00086 
00087         switch (prio)
00088         {
00089             case MSG_GCDEBUG:
00090             case MSG_DEBUG:
00091             case MSG_INFO:
00092             case MSG_NOTICE:
00093             case MSG_MESSAGEONLY:
00094                 if (sg_print_message)
00095                     sg_print_message(target, str);
00096                 break;
00097 
00098             case MSG_WARN:
00099                 if (sg_print_warning)
00100                     sg_print_warning(target, str);
00101                 break;
00102 
00103             case MSG_ERROR:
00104             case MSG_CRITICAL:
00105             case MSG_ALERT:
00106             case MSG_EMERGENCY:
00107                 if (sg_print_error)
00108                     sg_print_error(target, str);
00109                 throw ShogunException(str);
00110                 break;
00111             default:
00112                 break;
00113         }
00114 
00115         fflush(target);
00116     }
00117 }
00118 
00119 void SGIO::buffered_message(EMessageType prio, const char *fmt, ... ) const
00120 {
00121     const char* msg_intro=get_msg_intro(prio);
00122 
00123     if (msg_intro)
00124     {
00125         fprintf(target, "%s", msg_intro);
00126         va_list list;
00127         va_start(list,fmt);
00128         vfprintf(target,fmt,list);
00129         va_end(list);
00130     }
00131 }
00132 
00133 void SGIO::progress(
00134     float64_t current_val, float64_t min_val, float64_t max_val,
00135     int32_t decimals, const char* prefix)
00136 {
00137     if (!show_progress)
00138         return;
00139 
00140     float64_t runtime = CTime::get_curtime();
00141 
00142     char str[1000];
00143     float64_t v=-1, estimate=0, total_estimate=0 ;
00144 
00145     if (max_val-min_val>0.0)
00146         v=100*(current_val-min_val+1)/(max_val-min_val+1);
00147 
00148     if (decimals < 1)
00149         decimals = 1;
00150 
00151     if (last_progress>v)
00152     {
00153         last_progress_time = runtime;
00154         progress_start_time = runtime;
00155         last_progress = v;
00156     }
00157     else
00158     {
00159         v=CMath::clamp(v,1e-5,100.0);
00160         last_progress = v-1e-6;
00161 
00162         if ((v!=100.0) && (runtime - last_progress_time<0.5))
00163             return;
00164 
00165         last_progress_time = runtime;
00166         estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
00167         total_estimate = (last_progress_time-progress_start_time)/(v/100);
00168     }
00169 
00170     if (estimate>120)
00171     {
00172         snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
00173         message(MSG_MESSAGEONLY, "", -1, str, prefix, v, estimate/60, total_estimate/60);
00174     }
00175     else
00176     {
00177         snprintf(str, sizeof(str), "%%s %%%d.%df%%%%    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
00178         message(MSG_MESSAGEONLY, "", -1, str, prefix, v, estimate, total_estimate);
00179     }
00180 
00181     fflush(target);
00182 }
00183 
00184 void SGIO::absolute_progress(
00185     float64_t current_val, float64_t val, float64_t min_val, float64_t max_val,
00186     int32_t decimals, const char* prefix)
00187 {
00188     if (!show_progress)
00189         return;
00190 
00191     float64_t runtime = CTime::get_curtime();
00192 
00193     char str[1000];
00194     float64_t v=-1, estimate=0, total_estimate=0 ;
00195 
00196     if (max_val-min_val>0)
00197         v=100*(val-min_val+1)/(max_val-min_val+1);
00198 
00199     if (decimals < 1)
00200         decimals = 1;
00201 
00202     if (last_progress>v)
00203     {
00204         last_progress_time = runtime;
00205         progress_start_time = runtime;
00206         last_progress = v;
00207     }
00208     else
00209     {
00210         v=CMath::clamp(v,1e-5,100.0);
00211         last_progress = v-1e-6;
00212 
00213         if ((v!=100.0) && (runtime - last_progress_time<100))
00214             return;
00215 
00216         last_progress_time = runtime;
00217         estimate = (1-v/100)*(last_progress_time-progress_start_time)/(v/100);
00218         total_estimate = (last_progress_time-progress_start_time)/(v/100);
00219     }
00220 
00221     if (estimate>120)
00222     {
00223         snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f minutes remaining    %%1.1f minutes total    \r",decimals+3, decimals);
00224         message(MSG_MESSAGEONLY, "", -1, str, prefix, current_val, estimate/60, total_estimate/60);
00225     }
00226     else
00227     {
00228         snprintf(str, sizeof(str), "%%s %%%d.%df    %%1.1f seconds remaining    %%1.1f seconds total    \r",decimals+3, decimals);
00229         message(MSG_MESSAGEONLY, "", -1, str, prefix, current_val, estimate, total_estimate);
00230     }
00231 
00232     fflush(target);
00233 }
00234 
00235 void SGIO::done()
00236 {
00237     if (!show_progress)
00238         return;
00239 
00240     message(MSG_INFO, "", -1, "done.\n");
00241 }
00242 
00243 char* SGIO::skip_spaces(char* str)
00244 {
00245     int32_t i=0;
00246 
00247     if (str)
00248     {
00249         for (i=0; isspace(str[i]); i++);
00250 
00251         return &str[i];
00252     }
00253     else
00254         return str;
00255 }
00256 
00257 char* SGIO::skip_blanks(char* str)
00258 {
00259     int32_t i=0;
00260 
00261     if (str)
00262     {
00263         for (i=0; isblank(str[i]); i++);
00264 
00265         return &str[i];
00266     }
00267     else
00268         return str;
00269 }
00270 
00271 EMessageType SGIO::get_loglevel() const
00272 {
00273     return loglevel;
00274 }
00275 
00276 void SGIO::set_loglevel(EMessageType level)
00277 {
00278     loglevel=level;
00279 }
00280 
00281 void SGIO::set_target(FILE* t)
00282 {
00283     target=t;
00284 }
00285 
00286 const char* SGIO::get_msg_intro(EMessageType prio) const
00287 {
00288     for (int32_t i=NUM_LOG_LEVELS-1; i>=0; i--)
00289     {
00290         // ignore msg if prio's level is under loglevel,
00291         // but not if prio's level higher than MSG_WARN
00292         if (levels[i]<loglevel && prio<=MSG_WARN)
00293             return NULL;
00294 
00295         if (levels[i]==prio)
00296         {
00297             if (syntax_highlight)
00298                 return message_strings_highlighted[i];
00299             else
00300                 return message_strings[i];
00301         }
00302     }
00303 
00304     return NULL;
00305 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation