Gnash  0.8.11dev
log.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef GNASH_LOG_H
20 #define GNASH_LOG_H
21 
22 #ifdef HAVE_CONFIG_H
23 #include "gnashconfig.h"
24 #endif
25 
26 #include "rc.h" // for IF_VERBOSE_* implementation
27 #include "dsodefs.h" // for DSOEXPORT
28 
29 #include <fstream>
30 #include <boost/thread/mutex.hpp>
31 #include <boost/format.hpp>
32 
33 // the default name for the debug log
34 #define DEFAULT_LOGFILE "gnash-dbg.log"
35 
36 // Support compilation with (or without) native language support
37 #include "gettext.h"
38 #define _(String) gettext (String)
39 #define N_(String) gettext_noop (String)
40 
41 // Macro to prevent repeated logging calls for the same
42 // event
43 #define LOG_ONCE(x) { \
44  static bool warned = false; \
45  if (!warned) { warned = true; x; } \
46 }
47 
48 # include <boost/preprocessor/arithmetic/inc.hpp>
49 # include <boost/preprocessor/repetition/enum_params.hpp>
50 # include <boost/preprocessor/repetition/repeat.hpp>
51 # include <boost/preprocessor/repetition/repeat_from_to.hpp>
52 # include <boost/preprocessor/seq/for_each.hpp>
53 
54 // Mingw32 (win32 console) doesn't use the standard GCC defines that
55 // Gnash used for debug messages, so make it so...
56 #ifndef __FUNCDNAME__
57 #define __FUNCDNAME__ __FUNCTION__
58 #endif
59 
60 namespace gnash {
61 
62 // This is a basic file logging class
64 {
65 public:
66 
67  static LogFile& getDefaultInstance();
68 
69  ~LogFile();
70 
71  enum LogLevel {
75  LOG_EXTRA
76  };
77 
78  enum FileState {
82  IDLE
83  };
84 
86  //
93  void log(const std::string& label, const std::string& msg);
94 
96  //
100  void log(const std::string& msg);
101 
103  //
106  bool removeLog();
107 
109  //
112  bool closeLog();
113 
115  //
120  void setLogFilename(const std::string& fname);
121 
122  // accessors for the verbose level
123  void setVerbosity() {
124  ++_verbose;
125  }
126 
127  void setVerbosity(int x) {
128  _verbose = x;
129  }
130 
131  int getVerbosity() const {
132  return _verbose;
133  }
134 
135  void setActionDump(int x) {
136  _actiondump = x;
137  }
138 
139  void setNetwork(int x) {
140  _network = x;
141  }
142 
143  int getActionDump() const {
144  return _actiondump;
145  }
146 
147  int getNetwork() const {
148  return _network;
149  }
150 
151  void setParserDump (int x) {
152  _parserdump = x;
153  }
154 
155  int getParserDump() const {
156  return _parserdump;
157  }
158 
159  void setStamp (bool b) {
160  _stamp = b;
161  }
162 
163  bool getStamp() const {
164  return _stamp;
165  }
166 
168  void setWriteDisk(bool b);
169 
170  bool getWriteDisk() const {
171  return _write;
172  }
173 
174  typedef void (*logListener)(const std::string& s);
175 
176  void registerLogCallback(logListener l) { _listener = l; }
177 
178 private:
179 
181  //
186  bool openLog(const std::string& filespec);
187 
191  //
198  bool openLogIfNeeded();
199 
200  // Use getDefaultInstance for getting the singleton
201  LogFile ();
202 
204  boost::mutex _ioMutex;
205 
207  std::ofstream _outstream;
208 
210  int _verbose;
211 
213  bool _actiondump;
214 
216  bool _network;
217 
219  bool _parserdump;
220 
222  FileState _state;
223 
224  bool _stamp;
225 
227  bool _write;
228 
229  std::string _filespec;
230 
231  std::string _logFilename;
232 
233  logListener _listener;
234 
235 };
236 
237 DSOEXPORT void processLog_network(const boost::format& fmt);
238 DSOEXPORT void processLog_error(const boost::format& fmt);
239 DSOEXPORT void processLog_unimpl(const boost::format& fmt);
240 DSOEXPORT void processLog_trace(const boost::format& fmt);
241 DSOEXPORT void processLog_debug(const boost::format& fmt);
242 DSOEXPORT void processLog_action(const boost::format& fmt);
243 DSOEXPORT void processLog_parse(const boost::format& fmt);
244 DSOEXPORT void processLog_security(const boost::format& fmt);
245 DSOEXPORT void processLog_swferror(const boost::format& fmt);
246 DSOEXPORT void processLog_aserror(const boost::format& fmt);
247 DSOEXPORT void processLog_abc(const boost::format& fmt);
248 
251 //
254 #define TOKENIZE_FORMAT(z, n, t) % t##n
255 
259 #define TOKENIZE_ARGS(z, n, t) BOOST_PP_COMMA_IF(n) const T##n& t##n
260 
264 #define LOG_TYPES (error) (debug) (unimpl) (aserror) (swferror) \
265  (security) (action) (parse) (trace) (abc) (network)
266 
269 //
285 #define LOG_TEMPLATES(z, n, data)\
286 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename T)>\
287 inline void log_##data(BOOST_PP_REPEAT(BOOST_PP_INC(n), TOKENIZE_ARGS, t)) \
288 {\
289  if (LogFile::getDefaultInstance().getVerbosity() == 0) return; \
290  boost::format f(t0); \
291  using namespace boost::io; \
292  f.exceptions(all_error_bits ^ (too_many_args_bit | \
293  too_few_args_bit | \
294  bad_format_string_bit)); \
295  processLog_##data(f BOOST_PP_REPEAT_FROM_TO(1, \
296  BOOST_PP_INC(n), \
297  TOKENIZE_FORMAT, t));\
298 }
299 
301 //
304 #define ARG_NUMBER 10
305 
309 #define GENERATE_LOG_TYPES(r, _, t) \
310  BOOST_PP_REPEAT(ARG_NUMBER, LOG_TEMPLATES, t)
311 
314 BOOST_PP_SEQ_FOR_EACH(GENERATE_LOG_TYPES, _, LOG_TYPES)
315 
316 #undef TOKENIZE_ARGS
317 #undef TOKENIZE_FORMAT
318 #undef GENERATE_LOG_TYPES
319 #undef LOG_TEMPLATES
320 #undef ARG_NUMBER
321 
323 //
329 DSOEXPORT std::string hexify(const unsigned char *bytes, size_t length,
330  bool ascii);
331 
332 // Define to 0 to completely remove parse debugging at compile-time
333 #ifndef VERBOSE_PARSE
334 #define VERBOSE_PARSE 1
335 #endif
336 
337 // Define to 0 to completely remove action debugging at compile-time
338 #ifndef VERBOSE_ACTION
339 #define VERBOSE_ACTION 1
340 #endif
341 
342 // Define to 0 to remove ActionScript errors verbosity at compile-time
343 #ifndef VERBOSE_ASCODING_ERRORS
344 #define VERBOSE_ASCODING_ERRORS 1
345 #endif
346 
347 // Define to 0 this to remove invalid SWF verbosity at compile-time
348 #ifndef VERBOSE_MALFORMED_SWF
349 #define VERBOSE_MALFORMED_SWF 1
350 #endif
351 
352 // Define to 0 this to remove Networking verbosity at compile-time
353 #ifndef VERBOSE_NETWORKING
354 #define VERBOSE_NETWORKING 1
355 #endif
356 
357 #if VERBOSE_PARSE
358 #define IF_VERBOSE_PARSE(x) do { if ( LogFile::getDefaultInstance().getParserDump() ) { x; } } while (0);
359 #else
360 #define IF_VERBOSE_PARSE(x)
361 #endif
362 
363 #if VERBOSE_ACTION
364 #define IF_VERBOSE_ACTION(x) do { if ( LogFile::getDefaultInstance().getActionDump() ) { x; } } while (0);
365 #else
366 #define IF_VERBOSE_ACTION(x)
367 #endif
368 
369 #if VERBOSE_ACTION
370 #define IF_VERBOSE_NETWORK(x) do { if ( LogFile::getDefaultInstance().getNetwork() ) { x; } } while (0);
371 #else
372 #define IF_VERBOSE_NETWORK(x)
373 #endif
374 
375 #if VERBOSE_ASCODING_ERRORS
376 // TODO: check if it's worth to check verbosity level too...
377 #define IF_VERBOSE_ASCODING_ERRORS(x) { if ( gnash::RcInitFile::getDefaultInstance().showASCodingErrors() ) { x; } }
378 #else
379 #define IF_VERBOSE_ASCODING_ERRORS(x)
380 #endif
381 
382 #if VERBOSE_MALFORMED_SWF
383 // TODO: check if it's worth to check verbosity level too...
384 #define IF_VERBOSE_MALFORMED_SWF(x) { if ( gnash::RcInitFile::getDefaultInstance().showMalformedSWFErrors() ) { x; } }
385 #else
386 #define IF_VERBOSE_MALFORMED_SWF(x)
387 #endif
388 
390 {
391 public:
392  // Only print function tracing messages when multiple -v
393  // options have been supplied.
394  HostFunctionReport() : _func(0) {
395  log_debug("entering");
396  }
397 
398  HostFunctionReport(const char* func) : _func(func) {
399  if (func) {
400  log_debug("%s enter", func);
401  }
402  else {
403  log_debug("No Function Name! enter");
404  }
405  }
407  log_debug("%s returning", _func);
408  }
409 private:
410  const char* _func;
411 };
412 
413 #ifndef HAVE_FUNCTION
414  #ifndef HAVE_func
415  #define dummystr(x) # x
416  #define dummyestr(x) dummystr(x)
417  #define __FUNCTION__ __FILE__":"dummyestr(__LINE__)
418  #else
419  #define __FUNCTION__ __func__
420  #endif
421 #endif
422 
423 #ifndef HAVE_PRETTY_FUNCTION
424  #define __PRETTY_FUNCTION__ __FUNCTION__
425 #endif
426 
427 #if defined(__cplusplus) && defined(__GNUC__)
428 #define GNASH_REPORT_FUNCTION \
429  const gnash::HostFunctionReport hfr(__PRETTY_FUNCTION__)
430 #define GNASH_REPORT_RETURN
431 #else
432 #define GNASH_REPORT_FUNCTION \
433  gnash::log_debug("entering")
434 
435 #define GNASH_REPORT_RETURN \
436  gnash::log_debug("returning")
437 #endif
438 
439 }
440 
441 
442 #endif // GNASH_LOG_H
443 
444 
445 // Local Variables:
446 // mode: C++
447 // indent-tabs-mode: nil
448 // End: