Gnash  0.8.10
log.h
Go to the documentation of this file.
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: