1 // log.cpp: Message logging functions, for gnash.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include <boost/format.hpp>
34 #include <unistd.h> // for getpid
37 #include "GnashAlgorithm.h"
44 // Convert each byte into its hex representation
46 hexify(const unsigned char *p
, size_t length
, bool ascii
)
49 const std::vector
<unsigned char> bytes(p
, p
+ length
);
51 std::ostringstream ss
;
53 // For hex output, fill single-digit numbers with a leading 0.
54 if (!ascii
) ss
<< std::hex
<< std::setfill('0');
56 for (std::vector
<unsigned char>::const_iterator i
= bytes
.begin(),
57 e
= bytes
.end(); i
!= e
; ++i
)
60 if (std::isprint(*i
) || *i
== 0xd) {
67 ss
<< std::setw(2) << static_cast<int>(*i
) << " ";
76 timestamp(std::ostream
& o
)
79 const char fmt
[] = "%H:%M:%S";
85 std::strftime(buf
, sizeof buf
, fmt
, std::localtime(&t
));
87 static std::map
<int, int> threadMap
;
88 int tid
= get_thread_id();
89 int& htid
= threadMap
[tid
];
91 htid
= threadMap
.size();
92 // TODO: notify actual thread id for index
95 o
<< getpid() << ":" << htid
<< "] " << buf
;
101 LogFile::getDefaultInstance()
108 LogFile
& dbglogfile
= LogFile::getDefaultInstance();
111 // boost format functions to process the objects
112 // created by our hundreds of templates
115 processLog_trace(const boost::format
& fmt
)
117 dbglogfile
.log(N_("TRACE"), fmt
.str());
121 processLog_debug(const boost::format
& fmt
)
123 if (dbglogfile
.getVerbosity() < LogFile::LOG_DEBUG
) return;
124 dbglogfile
.log(N_("DEBUG"), fmt
.str());
128 processLog_abc(const boost::format
& fmt
)
130 if (dbglogfile
.getVerbosity() < LogFile::LOG_EXTRA
) return;
131 dbglogfile
.log(N_("ABC"), fmt
.str());
135 processLog_parse(const boost::format
& fmt
)
137 dbglogfile
.log(fmt
.str());
141 processLog_network(const boost::format
& fmt
)
143 dbglogfile
.log(N_("NETWORK"), fmt
.str());
147 processLog_error(const boost::format
& fmt
)
149 dbglogfile
.log(N_("ERROR"), fmt
.str());
153 processLog_unimpl(const boost::format
& fmt
)
155 dbglogfile
.log(N_("UNIMPLEMENTED"), fmt
.str());
159 processLog_security(const boost::format
& fmt
)
161 dbglogfile
.log(N_("SECURITY"), fmt
.str());
165 processLog_swferror(const boost::format
& fmt
)
167 dbglogfile
.log(N_("MALFORMED SWF"), fmt
.str());
171 processLog_amferror(const boost::format
& fmt
)
173 dbglogfile
.log(N_("MALFORMED AMF"), fmt
.str());
177 processLog_aserror(const boost::format
& fmt
)
179 dbglogfile
.log(N_("ACTIONSCRIPT ERROR"), fmt
.str());
183 processLog_action(const boost::format
& fmt
)
185 bool stamp
= dbglogfile
.getStamp();
186 dbglogfile
.setStamp(false);
187 dbglogfile
.log(fmt
.str());
188 dbglogfile
.setStamp(stamp
);
192 LogFile::log(const std::string
& msg
)
195 boost::mutex::scoped_lock
lock(_ioMutex
);
197 if ( !_verbose
) return; // nothing to do if not verbose
199 if (openLogIfNeeded()) {
201 _outstream
<< timestamp
<< ": " << msg
<< "\n";
203 _outstream
<< msg
<< "\n";
209 cout
<< timestamp
<< " " << msg
<< endl
;
221 LogFile::log(const std::string
& label
, const std::string
& msg
)
223 log(label
+ ": " + msg
);
227 LogFile::setLogFilename(const std::string
& fname
)
230 _logFilename
= fname
;
234 LogFile::setWriteDisk(bool use
)
236 if (!use
) closeLog();
240 // Default constructor
255 if (_state
== OPEN
) closeLog();
259 LogFile::openLogIfNeeded()
261 if (_state
!= CLOSED
) return true;
262 if (!_write
) return false;
264 if (_logFilename
.empty()) _logFilename
= DEFAULT_LOGFILE
;
266 // TODO: expand ~ to getenv("HOME") !!
268 return openLog(_logFilename
);
272 LogFile::openLog(const std::string
& filespec
)
276 // don't need to lock the mutex here, as this method
277 // is intended to be called only by openLogIfNeeded,
278 // which in turn is called by operator<< which is called
279 // by the public log_xxx functions that log themselves
281 if (_state
!= CLOSED
) {
282 cout
<< "Closing previously opened stream" << endl
;
287 // Append, don't truncate, the log file
288 _outstream
.open(filespec
.c_str(), std::ios::app
|std::ios::out
); // ios::out
289 if( _outstream
.fail() ) {
290 // Can't use log_error here...
291 cout
<< "ERROR: can't open debug log file " << filespec
<<
292 " for appending." << endl
;
296 _filespec
= filespec
;
305 boost::mutex::scoped_lock
lock(_ioMutex
);
306 if (_state
== OPEN
) {
318 if (_state
== OPEN
) {
322 // Ignore the error, we don't care
323 unlink(_filespec
.c_str());
329 } // end of gnash namespace
334 // indent-tabs-mode: t