• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

log.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
00003 //   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/thread.hpp>
00031 #include <boost/thread/mutex.hpp>
00032 #include <boost/format.hpp>
00033 
00034 // the default name for the debug log
00035 #define DEFAULT_LOGFILE "gnash-dbg.log"
00036 
00037 // Support compilation with (or without) native language support
00038 #include "gettext.h"
00039 #define    _(String) gettext (String)
00040 #define N_(String) gettext_noop (String)
00041 
00042 // Macro to prevent repeated logging calls for the same
00043 // event
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 // Mingw32 (win32 console) doesn't use the standard GCC defines that
00056 // Gnash used for debug messages, so make it so...
00057 #ifndef __FUNCDNAME__
00058 #define __FUNCDNAME__ __FUNCTION__
00059 #endif
00060 
00061 namespace gnash {
00062 
00063 // This is a basic file logging class
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     // accessors for the verbose level
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     // Use getDefaultInstance for getting the singleton
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 // Define to 0 to completely remove parse debugging at compile-time
00335 #ifndef VERBOSE_PARSE
00336 #define VERBOSE_PARSE 1
00337 #endif
00338 
00339 // Define to 0 to completely remove action debugging at compile-time
00340 #ifndef VERBOSE_ACTION
00341 #define VERBOSE_ACTION 1
00342 #endif
00343 
00344 // Define to 0 to remove ActionScript errors verbosity at compile-time
00345 #ifndef VERBOSE_ASCODING_ERRORS
00346 #define VERBOSE_ASCODING_ERRORS  1
00347 #endif
00348 
00349 // Define to 0 this to remove invalid SWF verbosity at compile-time
00350 #ifndef VERBOSE_MALFORMED_SWF
00351 #define VERBOSE_MALFORMED_SWF 1
00352 #endif
00353 
00354 // Define to 0 this to remove invalid AMF verbosity at compile-time
00355 #ifndef VERBOSE_MALFORMED_AMF
00356 #define VERBOSE_MALFORMED_AMF 1
00357 #endif
00358 
00359 // Define to 0 this to remove Networking verbosity at compile-time
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 // TODO: check if it's worth to check verbosity level too...
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 // TODO: check if it's worth to check verbosity level too... 
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 // TODO: check if it's worth to check verbosity level too... 
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     // Only print function tracing messages when multiple -v
00409     // options have been supplied. 
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 // Local Variables:
00467 // mode: C++
00468 // indent-tabs-mode: nil
00469 // End:

Generated on Thu Sep 30 2010 14:35:00 for Gnash by  doxygen 1.7.1