Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GNASH_LOG_H
00020 #define GNASH_LOG_H
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "gnashconfig.h"
00024 #endif
00025
00026 #include "rc.h"
00027 #include "dsodefs.h"
00028
00029 #include <fstream>
00030 #include <boost/thread/thread.hpp>
00031 #include <boost/thread/mutex.hpp>
00032 #include <boost/format.hpp>
00033
00034
00035 #define DEFAULT_LOGFILE "gnash-dbg.log"
00036
00037
00038 #include "gettext.h"
00039 #define _(String) gettext (String)
00040 #define N_(String) gettext_noop (String)
00041
00042
00043
00044 #define LOG_ONCE(x) { \
00045 static bool warned = false; \
00046 if (!warned) { warned = true; x; } \
00047 }
00048
00049 # include <boost/preprocessor/arithmetic/inc.hpp>
00050 # include <boost/preprocessor/repetition/enum_params.hpp>
00051 # include <boost/preprocessor/repetition/repeat.hpp>
00052 # include <boost/preprocessor/repetition/repeat_from_to.hpp>
00053 # include <boost/preprocessor/seq/for_each.hpp>
00054
00055
00056
00057 #ifndef __FUNCDNAME__
00058 #define __FUNCDNAME__ __FUNCTION__
00059 #endif
00060
00061 namespace gnash {
00062
00063
00064 class DSOEXPORT LogFile
00065 {
00066 public:
00067
00068 static LogFile& getDefaultInstance();
00069
00070 ~LogFile();
00071
00072 enum LogLevel {
00073 LOG_SILENT,
00074 LOG_NORMAL,
00075 LOG_DEBUG,
00076 LOG_EXTRA
00077 };
00078
00079 enum FileState {
00080 CLOSED,
00081 OPEN,
00082 INPROGRESS,
00083 IDLE
00084 };
00085
00087
00094 void log(const std::string& label, const std::string& msg);
00095
00097
00101 void log(const std::string& msg);
00102
00104
00107 bool removeLog();
00108
00110
00113 bool closeLog();
00114
00116
00121 void setLogFilename(const std::string& fname);
00122
00123
00124 void setVerbosity() {
00125 ++_verbose;
00126 }
00127
00128 void setVerbosity(int x) {
00129 _verbose = x;
00130 }
00131
00132 int getVerbosity() const {
00133 return _verbose;
00134 }
00135
00136 void setActionDump(int x) {
00137 _actiondump = x;
00138 }
00139
00140 void setNetwork(int x) {
00141 _network = x;
00142 }
00143
00144 int getActionDump() const {
00145 return _actiondump;
00146 }
00147
00148 int getNetwork() const {
00149 return _network;
00150 }
00151
00152 void setParserDump (int x) {
00153 _parserdump = x;
00154 }
00155
00156 int getParserDump() const {
00157 return _parserdump;
00158 }
00159
00160 void setStamp (bool b) {
00161 _stamp = b;
00162 }
00163
00164 bool getStamp() const {
00165 return _stamp;
00166 }
00167
00169 void setWriteDisk(bool b);
00170
00171 bool getWriteDisk() const {
00172 return _write;
00173 }
00174
00175 typedef void (*logListener)(const std::string& s);
00176
00177 void registerLogCallback(logListener l) { _listener = l; }
00178
00179 private:
00180
00182
00187 bool openLog(const std::string& filespec);
00188
00192
00199 bool openLogIfNeeded();
00200
00201
00202 LogFile ();
00203
00205 boost::mutex _ioMutex;
00206
00208 std::ofstream _outstream;
00209
00211 int _verbose;
00212
00214 bool _actiondump;
00215
00217 bool _network;
00218
00220 bool _parserdump;
00221
00223 FileState _state;
00224
00225 bool _stamp;
00226
00228 bool _write;
00229
00230 std::string _filespec;
00231
00232 std::string _logFilename;
00233
00234 logListener _listener;
00235
00236 };
00237
00238 DSOEXPORT void processLog_network(const boost::format& fmt);
00239 DSOEXPORT void processLog_error(const boost::format& fmt);
00240 DSOEXPORT void processLog_unimpl(const boost::format& fmt);
00241 DSOEXPORT void processLog_trace(const boost::format& fmt);
00242 DSOEXPORT void processLog_debug(const boost::format& fmt);
00243 DSOEXPORT void processLog_action(const boost::format& fmt);
00244 DSOEXPORT void processLog_parse(const boost::format& fmt);
00245 DSOEXPORT void processLog_security(const boost::format& fmt);
00246 DSOEXPORT void processLog_swferror(const boost::format& fmt);
00247 DSOEXPORT void processLog_amferror(const boost::format& fmt);
00248 DSOEXPORT void processLog_aserror(const boost::format& fmt);
00249 DSOEXPORT void processLog_abc(const boost::format& fmt);
00250
00253
00256 #define TOKENIZE_FORMAT(z, n, t) % t##n
00257
00261 #define TOKENIZE_ARGS(z, n, t) BOOST_PP_COMMA_IF(n) const T##n& t##n
00262
00266 #define LOG_TYPES (error) (debug) (unimpl) (aserror) (swferror) \
00267 (amferror) (security) (action) (parse) (trace) (abc) (network)
00268
00271
00287 #define LOG_TEMPLATES(z, n, data)\
00288 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename T)>\
00289 inline void log_##data(BOOST_PP_REPEAT(BOOST_PP_INC(n), TOKENIZE_ARGS, t)) \
00290 {\
00291 if (LogFile::getDefaultInstance().getVerbosity() == 0) return; \
00292 boost::format f(t0); \
00293 using namespace boost::io; \
00294 f.exceptions(all_error_bits ^ (too_many_args_bit | \
00295 too_few_args_bit | \
00296 bad_format_string_bit)); \
00297 processLog_##data(f BOOST_PP_REPEAT_FROM_TO(1, \
00298 BOOST_PP_INC(n), \
00299 TOKENIZE_FORMAT, t));\
00300 }
00301
00303
00306 #define ARG_NUMBER 10
00307
00311 #define GENERATE_LOG_TYPES(r, _, t) \
00312 BOOST_PP_REPEAT(ARG_NUMBER, LOG_TEMPLATES, t)
00313
00316 BOOST_PP_SEQ_FOR_EACH(GENERATE_LOG_TYPES, _, LOG_TYPES)
00317
00318 #undef TOKENIZE_ARGS
00319 #undef TOKENIZE_FORMAT
00320 #undef GENERATE_LOG_TYPES
00321 #undef LOG_TEMPLATES
00322 #undef ARG_NUMBER
00323
00325
00331 DSOEXPORT std::string hexify(const unsigned char *bytes, size_t length,
00332 bool ascii);
00333
00334
00335 #ifndef VERBOSE_PARSE
00336 #define VERBOSE_PARSE 1
00337 #endif
00338
00339
00340 #ifndef VERBOSE_ACTION
00341 #define VERBOSE_ACTION 1
00342 #endif
00343
00344
00345 #ifndef VERBOSE_ASCODING_ERRORS
00346 #define VERBOSE_ASCODING_ERRORS 1
00347 #endif
00348
00349
00350 #ifndef VERBOSE_MALFORMED_SWF
00351 #define VERBOSE_MALFORMED_SWF 1
00352 #endif
00353
00354
00355 #ifndef VERBOSE_MALFORMED_AMF
00356 #define VERBOSE_MALFORMED_AMF 1
00357 #endif
00358
00359
00360 #ifndef VERBOSE_NETWORKING
00361 #define VERBOSE_NETWORKING 1
00362 #endif
00363
00364 #if VERBOSE_PARSE
00365 #define IF_VERBOSE_PARSE(x) do { if ( LogFile::getDefaultInstance().getParserDump() ) { x; } } while (0);
00366 #else
00367 #define IF_VERBOSE_PARSE(x)
00368 #endif
00369
00370 #if VERBOSE_ACTION
00371 #define IF_VERBOSE_ACTION(x) do { if ( LogFile::getDefaultInstance().getActionDump() ) { x; } } while (0);
00372 #else
00373 #define IF_VERBOSE_ACTION(x)
00374 #endif
00375
00376 #if VERBOSE_ACTION
00377 #define IF_VERBOSE_NETWORK(x) do { if ( LogFile::getDefaultInstance().getNetwork() ) { x; } } while (0);
00378 #else
00379 #define IF_VERBOSE_NETWORK(x)
00380 #endif
00381
00382 #if VERBOSE_ASCODING_ERRORS
00383
00384 #define IF_VERBOSE_ASCODING_ERRORS(x) { if ( gnash::RcInitFile::getDefaultInstance().showASCodingErrors() ) { x; } }
00385 #else
00386 #define IF_VERBOSE_ASCODING_ERRORS(x)
00387 #endif
00388
00389 #if VERBOSE_MALFORMED_SWF
00390
00391 #define IF_VERBOSE_MALFORMED_SWF(x) { if ( gnash::RcInitFile::getDefaultInstance().showMalformedSWFErrors() ) { x; } }
00392 #else
00393 #define IF_VERBOSE_MALFORMED_SWF(x)
00394 #endif
00395
00396 #if VERBOSE_MALFORMED_AMF
00397
00398 #define IF_VERBOSE_MALFORMED_AMF(x) { if ( gnash::RcInitFile::getDefaultInstance().showMalformedAMFErrors() ) { x; } }
00399 #else
00400 #define IF_VERBOSE_MALFORMED_AMF(x)
00401 #endif
00402
00403 class DSOEXPORT __Host_Function_Report__
00404 {
00405 public:
00406 const char *func;
00407
00408
00409
00410 __Host_Function_Report__(void) {
00411 log_debug("entering");
00412 }
00413
00414 __Host_Function_Report__(char *_func) {
00415 func = _func;
00416 log_debug("%s enter", func);
00417 }
00418
00419 __Host_Function_Report__(const char *_func) {
00420 func = _func;
00421 if (func) {
00422 log_debug("%s enter", func);
00423 }
00424 else {
00425 log_debug("No Function Name! enter");
00426 }
00427 }
00428
00429 ~__Host_Function_Report__(void) {
00430 log_debug("%s returning", func);
00431 }
00432 };
00433
00434 #ifndef HAVE_FUNCTION
00435 #ifndef HAVE_func
00436 #define dummystr(x) # x
00437 #define dummyestr(x) dummystr(x)
00438 #define __FUNCTION__ __FILE__":"dummyestr(__LINE__)
00439 #else
00440 #define __FUNCTION__ __func__
00441 #endif
00442 #endif
00443
00444 #ifndef HAVE_PRETTY_FUNCTION
00445 #define __PRETTY_FUNCTION__ __FUNCTION__
00446 #endif
00447
00448 #if defined(__cplusplus) && defined(__GNUC__)
00449 #define GNASH_REPORT_FUNCTION \
00450 gnash::__Host_Function_Report__ __host_function_report__( __PRETTY_FUNCTION__)
00451 #define GNASH_REPORT_RETURN
00452 #else
00453 #define GNASH_REPORT_FUNCTION \
00454 gnash::log_debug("entering")
00455
00456 #define GNASH_REPORT_RETURN \
00457 gnash::log_debug("returning")
00458 #endif
00459
00460 }
00461
00462
00463 #endif // GNASH_LOG_H
00464
00465
00466
00467
00468
00469