00001
00002 #ifndef AMROC_CLESLOG_H
00003 #define AMROC_CLESLOG_H
00004
00005
00006
00007
00008
00009
00010
00011 #include <string>
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <ctype.h>
00015 #include "DAGH.h"
00016 #include "../weno/src/generic/cles.h"
00017
00018 #define CLESLOG_MSGMAXLEN 256
00019 #define CLESLOG_KEYMAXLEN 24
00020 #define CLESLOG_MAXINDENT 100
00021 #define CLESLOG_HEADERLEN 72
00022
00023 #define CLESLOG_DEBUG 0
00024 #define CLESLOG_WARNING 1
00025 #define CLESLOG_ERROR 2
00026
00027 #define CLESLOG_CBC 1
00028 #define CLESLOG_CBC_EIGENSYSTEM 1
00029 #define CLESLOG_CBC_REFPRESSURE 2
00030
00031 #define CLESLOG_ROE 2
00032 #define CLESLOG_ROE_STATES 1
00033
00034 #define CLESLOG_TCD 3
00035 #define CLESLOG_TCD_STENCIL 1
00036
00037 class CLESLog {
00038
00039 public:
00040
00041
00042 struct ldtype {
00043 int _active;
00044 int _mod;
00045 int _loc;
00046 int _lev;
00047 char _msg[CLESLOG_MSGMAXLEN];
00048 char _mod_msg[CLESLOG_KEYMAXLEN];
00049 char _loc_msg[CLESLOG_KEYMAXLEN];
00050 };
00051
00052 void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00053 ControlDevice LocCtrl = Ctrl.getSubDevice(prefix+"Logging");
00054
00055 RegisterAt(LocCtrl,"ActiveLogs",_DefFile);
00056 RegisterAt(LocCtrl,"Trace",_trace);
00057
00058 }
00059
00060
00061 void jerror(const char* msg) {
00062 fprintf(stderr, "Error: ");
00063 fprintf(stderr, msg);
00064 fprintf(stderr, "\n");
00065 fflush(stderr);
00066 }
00067
00068 char* trim(char* input) {
00069
00070 int len = std::strlen(input);
00071 for ( int i = 0 ; i < len && isspace(input[i]) ; i ++ )
00072 input ++;
00073
00074 len = std::strlen(input);
00075 for ( int i = len-1; i>=0 && isspace(input[i]) ; i-- )
00076 input[i] = '\0';
00077 return input;
00078 }
00079
00080
00081 ldtype* lookup(int mod, int loc) {
00082 for ( int i=0 ; i < log_table_size ; i++ ) {
00083 ldtype* p = &(logtable[i]);
00084 if ( p->_mod == mod && p->_loc == loc )
00085 return p;
00086 }
00087
00088 return NULL;
00089 }
00090
00091 ldtype* lookup(char* mod, char* loc) {
00092 for ( int i=0 ; i < log_table_size ; i++ ) {
00093 ldtype* p = &(logtable[i]);
00094 if ( std::strncmp(p->_mod_msg,mod,CLESLOG_KEYMAXLEN-1) == 0 &&
00095 std::strncmp(p->_loc_msg, loc,CLESLOG_KEYMAXLEN-1) == 0 )
00096 return p;
00097 }
00098
00099 return NULL;
00100 }
00101
00102
00103 void header() {
00104 char header[CLESLOG_HEADERLEN+1];
00105 header[0] = '#';
00106 for ( int i = 1; i < CLESLOG_HEADERLEN-1 ; i++ )
00107 header[i] = ( i%2 == 0 ? '/' : '\\' );
00108 header[CLESLOG_HEADERLEN-1] = '#';
00109 header[CLESLOG_HEADERLEN] = 0;
00110 for ( int i = 0 ; i < log_indent ; i++ )
00111 comm_service::log() << " " ;
00112
00113 (comm_service::log() << header << "\n").flush();
00114 }
00115
00116 void mark(ldtype* p) {
00117 log_indent ++;
00118 requested_last[log_indent] = p;
00119 }
00120
00121 void unmark() {
00122 requested_last[log_indent] = NULL;
00123 log_indent --;
00124 }
00125
00126
00127 static int reporting_level ;
00128 static bool active_log ;
00129 static ldtype* requested_last[CLESLOG_MAXINDENT];
00130 static ldtype logtable[];
00131 static std::string _DefFile;
00132 static int log_table_size;
00133 static int log_indent;
00134 static int _trace;
00135 static int trace_indent;
00136
00137 CLESLog() { }
00138 ~CLESLog() { }
00139
00140
00141 int inactive() {
00142 if ( active_log == false ) return 1;
00143 if ( requested_last[log_indent] == NULL ) return 1;
00144 if ( requested_last[log_indent]->_active == false ) return 1;
00145 return 0;
00146 }
00147
00148
00149 void initialize() {
00150 for ( int i = 0 ; i < CLESLOG_MAXINDENT ; i ++ )
00151 requested_last[i] = NULL;
00152
00153 if ( _DefFile.length() ) {
00154 active_log = true;
00155
00156 FILE* pfile = fopen(_DefFile.c_str(), "r");
00157 if ( pfile == NULL ) return;
00158
00159 char mod[CLESLOG_KEYMAXLEN];
00160 char loc[CLESLOG_KEYMAXLEN];
00161
00162 while(feof(pfile) == 0) {
00163 if ( fscanf(pfile, "%s %s", mod, loc) == EOF ) break;
00164
00165 ldtype* entry = lookup(mod, loc);
00166 if ( entry != NULL ) entry->_active = true;
00167 }
00168 fclose(pfile);
00169 }
00170 }
00171
00172
00173 void finalize() {
00174
00175 }
00176
00177 };
00178
00179
00180 int CLESLog::_trace = 0;
00181 int CLESLog::trace_indent = 0;
00182
00183
00184 int CLESLog::reporting_level = CLESLOG_ERROR;
00185
00186 bool CLESLog::active_log = false;
00187
00188 CLESLog::ldtype* CLESLog::requested_last[CLESLOG_MAXINDENT];
00189
00190 CLESLog::ldtype CLESLog::logtable[] = {
00191 {false, CLESLOG_CBC, CLESLOG_CBC_EIGENSYSTEM, CLESLOG_DEBUG,
00192 "CBC->EIGENSYSTEM", "CBC", "EIGENSYSTEM" },
00193 {false, CLESLOG_CBC, CLESLOG_CBC_REFPRESSURE, CLESLOG_DEBUG,
00194 "CBC->REFPRESSURE", "CBC", "REFPRESSURE" },
00195 {false, CLESLOG_ROE, CLESLOG_ROE_STATES, CLESLOG_DEBUG,
00196 "ROE->STATES", "ROE", "STATES" },
00197 {false, CLESLOG_TCD, CLESLOG_TCD_STENCIL, CLESLOG_DEBUG,
00198 "TCD->STENCIL", "TCD", "STENCIL" }};
00199
00200
00201 int CLESLog::log_table_size = sizeof(CLESLog::logtable)/sizeof(CLESLog::ldtype);
00202 int CLESLog::log_indent = -1;
00203
00204 std::string CLESLog::_DefFile = "";
00205
00206 extern "C" {
00207
00208
00209 #define f_cleslog_active FORTRAN_NAME_(cleslog_active, CLESLOG_ACTIVE)
00210 int f_cleslog_active(int& module, int& loc) {
00211 CLESLog me;
00212 CLESLog::ldtype* p;
00213
00214 if ( me.active_log == false ) return CLES_FALSE;
00215 if ( (p=me.lookup(module, loc)) == NULL ) return CLES_FALSE;
00216 if ( p->_active == false ) return CLES_FALSE;
00217
00218 me.mark(p);
00219 me.header();
00220
00221 const char * header;
00222 switch ( me.requested_last[me.log_indent]->_lev ) {
00223 case CLESLOG_DEBUG: header = "DEBUG: "; break;
00224 case CLESLOG_WARNING: header = "WARNING: "; break;
00225 case CLESLOG_ERROR: header = "ERROR: "; break;
00226 default: header = "UNKNOWN: ";
00227 }
00228 for ( int i = 0 ; i < me.log_indent ; i++ )
00229 comm_service::log() << "\t" ;
00230 (comm_service::log() << header <<
00231 me.requested_last[me.log_indent]->_msg << "\n").flush();
00232 return CLES_TRUE;
00233 }
00234
00235
00236 #define f_cleslog_activate FORTRAN_NAME_(cleslog_activate, CLESLOG_ACTIVATE)
00237 int f_cleslog_activate(int& module, int& loc) {
00238 CLESLog me;
00239 CLESLog::ldtype* p;
00240
00241 if ( (p=me.lookup(module, loc)) == NULL ) return CLES_FALSE;
00242 if ( p->_lev > CLESLOG_DEBUG ) {
00243 me.active_log = true;
00244 p->_active = true;
00245 return f_cleslog_active(module, loc);
00246 }
00247 return CLES_FALSE;
00248 }
00249
00250
00251 #define f_cleslog_log FORTRAN_NAME_(cleslog_log, CLESLOG_LOG)
00252 void f_cleslog_log(char* msg) {
00253 CLESLog me;
00254
00255 if ( me.inactive() ) return;
00256
00257 for ( int i = 0 ; i < me.log_indent ; i++ )
00258 comm_service::log() << " " ;
00259
00260
00261
00262
00263 (comm_service::log() << msg << "\n").flush();
00264
00265 }
00266
00267
00268 #define f_cleslog_log_flush FORTRAN_NAME_(cleslog_log_flush, CLESLOG_LOG)
00269 void f_cleslog_log_flush(void) {
00270 CLESLog me;
00271
00272 if ( me.inactive() ) return;
00273
00274 me.header();
00275 me.unmark();
00276 }
00277
00278 #define f_cleslog_trace_enter FORTRAN_NAME_(cleslog_trace_enter, CLESLOG_TRACE_ENTER)
00279 void f_cleslog_trace_enter(char* msg) {
00280 CLESLog me;
00281
00282 if ( me._trace == 0 ) return;
00283
00284 for ( int i = 0 ; i < me.trace_indent ; i++ )
00285 comm_service::log() << "\t" ;
00286
00287 (comm_service::log() << "<*> Entering: " << msg << "\n").flush();
00288 me.trace_indent ++;
00289 }
00290
00291 #define f_cleslog_trace_exit FORTRAN_NAME_(cleslog_trace_exit, CLESLOG_TRACE_EXIT)
00292 void f_cleslog_trace_exit(char* msg) {
00293 CLESLog me;
00294
00295 if ( me._trace == 0 ) return;
00296
00297 me.trace_indent --;
00298 for ( int i = 0 ; i < me.trace_indent ; i++ )
00299 comm_service::log() << "\t" ;
00300
00301 (comm_service::log() << "<*> Exiting: " << msg << "\n").flush();
00302
00303 }
00304
00305 }
00306
00307 #endif