Gnash
0.8.10
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 00003 // Free Software Foundation, Inc 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 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" // for IF_VERBOSE_* implementation 00027 #include "dsodefs.h" // for DSOEXPORT 00028 00029 #include <fstream> 00030 #include <boost/thread/mutex.hpp> 00031 #include <boost/format.hpp> 00032 00033 // the default name for the debug log 00034 #define DEFAULT_LOGFILE "gnash-dbg.log" 00035 00036 // Support compilation with (or without) native language support 00037 #include "gettext.h" 00038 #define _(String) gettext (String) 00039 #define N_(String) gettext_noop (String) 00040 00041 // Macro to prevent repeated logging calls for the same 00042 // event 00043 #define LOG_ONCE(x) { \ 00044 static bool warned = false; \ 00045 if (!warned) { warned = true; x; } \ 00046 } 00047 00048 # include <boost/preprocessor/arithmetic/inc.hpp> 00049 # include <boost/preprocessor/repetition/enum_params.hpp> 00050 # include <boost/preprocessor/repetition/repeat.hpp> 00051 # include <boost/preprocessor/repetition/repeat_from_to.hpp> 00052 # include <boost/preprocessor/seq/for_each.hpp> 00053 00054 // Mingw32 (win32 console) doesn't use the standard GCC defines that 00055 // Gnash used for debug messages, so make it so... 00056 #ifndef __FUNCDNAME__ 00057 #define __FUNCDNAME__ __FUNCTION__ 00058 #endif 00059 00060 namespace gnash { 00061 00062 // This is a basic file logging class 00063 class DSOEXPORT LogFile 00064 { 00065 public: 00066 00067 static LogFile& getDefaultInstance(); 00068 00069 ~LogFile(); 00070 00071 enum LogLevel { 00072 LOG_SILENT, 00073 LOG_NORMAL, 00074 LOG_DEBUG, 00075 LOG_EXTRA 00076 }; 00077 00078 enum FileState { 00079 CLOSED, 00080 OPEN, 00081 INPROGRESS, 00082 IDLE 00083 }; 00084 00086 // 00093 void log(const std::string& label, const std::string& msg); 00094 00096 // 00100 void log(const std::string& msg); 00101 00103 // 00106 bool removeLog(); 00107 00109 // 00112 bool closeLog(); 00113 00115 // 00120 void setLogFilename(const std::string& fname); 00121 00122 // accessors for the verbose level 00123 void setVerbosity() { 00124 ++_verbose; 00125 } 00126 00127 void setVerbosity(int x) { 00128 _verbose = x; 00129 } 00130 00131 int getVerbosity() const { 00132 return _verbose; 00133 } 00134 00135 void setActionDump(int x) { 00136 _actiondump = x; 00137 } 00138 00139 void setNetwork(int x) { 00140 _network = x; 00141 } 00142 00143 int getActionDump() const { 00144 return _actiondump; 00145 } 00146 00147 int getNetwork() const { 00148 return _network; 00149 } 00150 00151 void setParserDump (int x) { 00152 _parserdump = x; 00153 } 00154 00155 int getParserDump() const { 00156 return _parserdump; 00157 } 00158 00159 void setStamp (bool b) { 00160 _stamp = b; 00161 } 00162 00163 bool getStamp() const { 00164 return _stamp; 00165 } 00166 00168 void setWriteDisk(bool b); 00169 00170 bool getWriteDisk() const { 00171 return _write; 00172 } 00173 00174 typedef void (*logListener)(const std::string& s); 00175 00176 void registerLogCallback(logListener l) { _listener = l; } 00177 00178 private: 00179 00181 // 00186 bool openLog(const std::string& filespec); 00187 00191 // 00198 bool openLogIfNeeded(); 00199 00200 // Use getDefaultInstance for getting the singleton 00201 LogFile (); 00202 00204 boost::mutex _ioMutex; 00205 00207 std::ofstream _outstream; 00208 00210 int _verbose; 00211 00213 bool _actiondump; 00214 00216 bool _network; 00217 00219 bool _parserdump; 00220 00222 FileState _state; 00223 00224 bool _stamp; 00225 00227 bool _write; 00228 00229 std::string _filespec; 00230 00231 std::string _logFilename; 00232 00233 logListener _listener; 00234 00235 }; 00236 00237 DSOEXPORT void processLog_network(const boost::format& fmt); 00238 DSOEXPORT void processLog_error(const boost::format& fmt); 00239 DSOEXPORT void processLog_unimpl(const boost::format& fmt); 00240 DSOEXPORT void processLog_trace(const boost::format& fmt); 00241 DSOEXPORT void processLog_debug(const boost::format& fmt); 00242 DSOEXPORT void processLog_action(const boost::format& fmt); 00243 DSOEXPORT void processLog_parse(const boost::format& fmt); 00244 DSOEXPORT void processLog_security(const boost::format& fmt); 00245 DSOEXPORT void processLog_swferror(const boost::format& fmt); 00246 DSOEXPORT void processLog_aserror(const boost::format& fmt); 00247 DSOEXPORT void processLog_abc(const boost::format& fmt); 00248 00251 // 00254 #define TOKENIZE_FORMAT(z, n, t) % t##n 00255 00259 #define TOKENIZE_ARGS(z, n, t) BOOST_PP_COMMA_IF(n) const T##n& t##n 00260 00264 #define LOG_TYPES (error) (debug) (unimpl) (aserror) (swferror) \ 00265 (security) (action) (parse) (trace) (abc) (network) 00266 00269 // 00285 #define LOG_TEMPLATES(z, n, data)\ 00286 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename T)>\ 00287 inline void log_##data(BOOST_PP_REPEAT(BOOST_PP_INC(n), TOKENIZE_ARGS, t)) \ 00288 {\ 00289 if (LogFile::getDefaultInstance().getVerbosity() == 0) return; \ 00290 boost::format f(t0); \ 00291 using namespace boost::io; \ 00292 f.exceptions(all_error_bits ^ (too_many_args_bit | \ 00293 too_few_args_bit | \ 00294 bad_format_string_bit)); \ 00295 processLog_##data(f BOOST_PP_REPEAT_FROM_TO(1, \ 00296 BOOST_PP_INC(n), \ 00297 TOKENIZE_FORMAT, t));\ 00298 } 00299 00301 // 00304 #define ARG_NUMBER 10 00305 00309 #define GENERATE_LOG_TYPES(r, _, t) \ 00310 BOOST_PP_REPEAT(ARG_NUMBER, LOG_TEMPLATES, t) 00311 00314 BOOST_PP_SEQ_FOR_EACH(GENERATE_LOG_TYPES, _, LOG_TYPES) 00315 00316 #undef TOKENIZE_ARGS 00317 #undef TOKENIZE_FORMAT 00318 #undef GENERATE_LOG_TYPES 00319 #undef LOG_TEMPLATES 00320 #undef ARG_NUMBER 00321 00323 // 00329 DSOEXPORT std::string hexify(const unsigned char *bytes, size_t length, 00330 bool ascii); 00331 00332 // Define to 0 to completely remove parse debugging at compile-time 00333 #ifndef VERBOSE_PARSE 00334 #define VERBOSE_PARSE 1 00335 #endif 00336 00337 // Define to 0 to completely remove action debugging at compile-time 00338 #ifndef VERBOSE_ACTION 00339 #define VERBOSE_ACTION 1 00340 #endif 00341 00342 // Define to 0 to remove ActionScript errors verbosity at compile-time 00343 #ifndef VERBOSE_ASCODING_ERRORS 00344 #define VERBOSE_ASCODING_ERRORS 1 00345 #endif 00346 00347 // Define to 0 this to remove invalid SWF verbosity at compile-time 00348 #ifndef VERBOSE_MALFORMED_SWF 00349 #define VERBOSE_MALFORMED_SWF 1 00350 #endif 00351 00352 // Define to 0 this to remove Networking verbosity at compile-time 00353 #ifndef VERBOSE_NETWORKING 00354 #define VERBOSE_NETWORKING 1 00355 #endif 00356 00357 #if VERBOSE_PARSE 00358 #define IF_VERBOSE_PARSE(x) do { if ( LogFile::getDefaultInstance().getParserDump() ) { x; } } while (0); 00359 #else 00360 #define IF_VERBOSE_PARSE(x) 00361 #endif 00362 00363 #if VERBOSE_ACTION 00364 #define IF_VERBOSE_ACTION(x) do { if ( LogFile::getDefaultInstance().getActionDump() ) { x; } } while (0); 00365 #else 00366 #define IF_VERBOSE_ACTION(x) 00367 #endif 00368 00369 #if VERBOSE_ACTION 00370 #define IF_VERBOSE_NETWORK(x) do { if ( LogFile::getDefaultInstance().getNetwork() ) { x; } } while (0); 00371 #else 00372 #define IF_VERBOSE_NETWORK(x) 00373 #endif 00374 00375 #if VERBOSE_ASCODING_ERRORS 00376 // TODO: check if it's worth to check verbosity level too... 00377 #define IF_VERBOSE_ASCODING_ERRORS(x) { if ( gnash::RcInitFile::getDefaultInstance().showASCodingErrors() ) { x; } } 00378 #else 00379 #define IF_VERBOSE_ASCODING_ERRORS(x) 00380 #endif 00381 00382 #if VERBOSE_MALFORMED_SWF 00383 // TODO: check if it's worth to check verbosity level too... 00384 #define IF_VERBOSE_MALFORMED_SWF(x) { if ( gnash::RcInitFile::getDefaultInstance().showMalformedSWFErrors() ) { x; } } 00385 #else 00386 #define IF_VERBOSE_MALFORMED_SWF(x) 00387 #endif 00388 00389 class DSOEXPORT HostFunctionReport 00390 { 00391 public: 00392 // Only print function tracing messages when multiple -v 00393 // options have been supplied. 00394 HostFunctionReport() : _func(0) { 00395 log_debug("entering"); 00396 } 00397 00398 HostFunctionReport(const char* func) : _func(func) { 00399 if (func) { 00400 log_debug("%s enter", func); 00401 } 00402 else { 00403 log_debug("No Function Name! enter"); 00404 } 00405 } 00406 ~HostFunctionReport() { 00407 log_debug("%s returning", _func); 00408 } 00409 private: 00410 const char* _func; 00411 }; 00412 00413 #ifndef HAVE_FUNCTION 00414 #ifndef HAVE_func 00415 #define dummystr(x) # x 00416 #define dummyestr(x) dummystr(x) 00417 #define __FUNCTION__ __FILE__":"dummyestr(__LINE__) 00418 #else 00419 #define __FUNCTION__ __func__ 00420 #endif 00421 #endif 00422 00423 #ifndef HAVE_PRETTY_FUNCTION 00424 #define __PRETTY_FUNCTION__ __FUNCTION__ 00425 #endif 00426 00427 #if defined(__cplusplus) && defined(__GNUC__) 00428 #define GNASH_REPORT_FUNCTION \ 00429 const gnash::HostFunctionReport hfr(__PRETTY_FUNCTION__) 00430 #define GNASH_REPORT_RETURN 00431 #else 00432 #define GNASH_REPORT_FUNCTION \ 00433 gnash::log_debug("entering") 00434 00435 #define GNASH_REPORT_RETURN \ 00436 gnash::log_debug("returning") 00437 #endif 00438 00439 } 00440 00441 00442 #endif // GNASH_LOG_H 00443 00444 00445 // Local Variables: 00446 // mode: C++ 00447 // indent-tabs-mode: nil 00448 // End: