2002-08-02 19:57:46 +00:00
|
|
|
/*
|
|
|
|
* synergy -- mouse and keyboard sharing utility
|
|
|
|
* Copyright (C) 2002 Chris Schoeneman
|
|
|
|
*
|
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* found in the file COPYING that should have accompanied this file.
|
|
|
|
*
|
|
|
|
* This package is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
2001-10-14 14:38:45 +00:00
|
|
|
#ifndef CLOG_H
|
|
|
|
#define CLOG_H
|
|
|
|
|
2002-06-19 11:23:49 +00:00
|
|
|
#include "common.h"
|
|
|
|
#include <stdarg.h>
|
2001-10-14 14:38:45 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Logging facility
|
|
|
|
/*!
|
|
|
|
The logging class; all console output should go through this class.
|
|
|
|
It supports multithread safe operation, several message priority levels,
|
2002-10-15 21:29:44 +00:00
|
|
|
filtering by priority, and output redirection. The macros LOG() and
|
|
|
|
LOGC() provide convenient access.
|
2002-07-26 18:28:18 +00:00
|
|
|
*/
|
2001-10-14 14:38:45 +00:00
|
|
|
class CLog {
|
2002-04-29 14:40:01 +00:00
|
|
|
public:
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Log levels
|
|
|
|
/*!
|
|
|
|
The logging priority levels in order of highest to lowest priority.
|
|
|
|
*/
|
|
|
|
enum ELevel {
|
|
|
|
kFATAL, //!< For fatal errors
|
|
|
|
kERROR, //!< For serious errors
|
|
|
|
kWARNING, //!< For minor errors and warnings
|
|
|
|
kNOTE, //!< For messages about notable events
|
|
|
|
kINFO, //!< For informational messages
|
|
|
|
kDEBUG, //!< For important debugging messages
|
|
|
|
kDEBUG1, //!< For more detailed debugging messages
|
|
|
|
kDEBUG2 //!< For even more detailed debugging messages
|
2002-06-03 18:53:18 +00:00
|
|
|
};
|
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Outputter function.
|
|
|
|
/*!
|
|
|
|
Type of outputter function. The outputter should write \c message,
|
|
|
|
which has the given \c priority, to a log and return true. Or it can
|
|
|
|
return false to let CLog use the default outputter.
|
|
|
|
*/
|
|
|
|
typedef bool (*Outputter)(int priority, const char* message);
|
2002-06-08 21:48:00 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Locking function
|
|
|
|
/*!
|
|
|
|
Type of lock/unlock function. If \c lock is true then block other
|
|
|
|
threads that try to lock until this thread unlocks. If \c lock is
|
|
|
|
false then unlock and allow another (waiting) thread to lock.
|
|
|
|
*/
|
2002-05-31 14:25:26 +00:00
|
|
|
typedef void (*Lock)(bool lock);
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! @name manipulators
|
|
|
|
//@{
|
2002-05-31 14:25:26 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Set the function used to write the log
|
|
|
|
/*!
|
|
|
|
Sets the function used to write to the log. The outputter function
|
|
|
|
is called with the formatted string to write and the priority level.
|
|
|
|
CLog will have already filtered messages below the current filter
|
|
|
|
priority. A NULL outputter means to use the default which is to print
|
|
|
|
to stderr. Note that the outputter should not call CLog methods but,
|
|
|
|
if it does, the current lock function must permit recursive locks.
|
|
|
|
*/
|
2001-11-19 00:33:36 +00:00
|
|
|
static void setOutputter(Outputter);
|
2002-05-31 14:25:26 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Set the lock/unlock function
|
|
|
|
/*!
|
|
|
|
Set the lock/unlock function. Use setLock(NULL) to remove the
|
|
|
|
locking function. There is no default lock function; do not call
|
|
|
|
CLog from multiple threads unless a working lock function has been
|
|
|
|
installed.
|
|
|
|
*/
|
2002-05-31 14:25:26 +00:00
|
|
|
static void setLock(Lock);
|
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//! Set the minimum priority filter.
|
|
|
|
/*!
|
|
|
|
Set the filter. Messages below this priority are discarded.
|
|
|
|
The default priority is 4 (INFO) (unless built without NDEBUG
|
|
|
|
in which case it's 5 (DEBUG)). The default can be overridden
|
|
|
|
by setting the SYN_LOG_PRI env var to "FATAL", "ERROR", etc.
|
|
|
|
setFilter(const char*) returns true if the priority \c name was
|
|
|
|
recognized; if \c name is NULL then it simply returns true.
|
|
|
|
*/
|
2002-06-03 16:36:45 +00:00
|
|
|
static bool setFilter(const char* name);
|
2002-05-31 14:25:26 +00:00
|
|
|
static void setFilter(int);
|
2002-07-26 18:28:18 +00:00
|
|
|
|
|
|
|
//@}
|
|
|
|
//! @name accessors
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//! Print a log message
|
|
|
|
/*!
|
|
|
|
Print a log message using the printf-like \c format and arguments.
|
|
|
|
*/
|
|
|
|
static void print(const char* format, ...);
|
|
|
|
|
|
|
|
//! Print a log message
|
|
|
|
/*!
|
|
|
|
Print a log message using the printf-like \c format and arguments
|
|
|
|
preceded by the filename and line number.
|
|
|
|
*/
|
|
|
|
static void printt(const char* file, int line,
|
|
|
|
const char* format, ...);
|
|
|
|
|
|
|
|
//! Get the function used to write the log
|
|
|
|
static Outputter getOutputter();
|
|
|
|
|
|
|
|
//! Get the lock/unlock function
|
|
|
|
/*!
|
|
|
|
Get the lock/unlock function. Note that the lock function is
|
|
|
|
used when retrieving the lock function.
|
|
|
|
*/
|
|
|
|
static Lock getLock();
|
|
|
|
|
|
|
|
//! Get the minimum priority level.
|
2002-05-31 14:25:26 +00:00
|
|
|
static int getFilter();
|
2001-10-14 14:38:45 +00:00
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
//@}
|
|
|
|
|
2002-04-29 14:40:01 +00:00
|
|
|
private:
|
2002-05-31 14:25:26 +00:00
|
|
|
class CHoldLock {
|
|
|
|
public:
|
2002-06-01 19:26:11 +00:00
|
|
|
CHoldLock(Lock lock) : m_lock(lock) { m_lock(true); }
|
2002-05-31 14:25:26 +00:00
|
|
|
~CHoldLock() { m_lock(false); }
|
|
|
|
|
|
|
|
private:
|
2002-06-01 19:26:11 +00:00
|
|
|
Lock m_lock;
|
2002-05-31 14:25:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void dummyLock(bool);
|
|
|
|
static int getMaxPriority();
|
2001-11-19 00:33:36 +00:00
|
|
|
static void output(int priority, char* msg);
|
2002-06-19 11:23:49 +00:00
|
|
|
#if WINDOWS_LIKE
|
2002-05-22 17:01:17 +00:00
|
|
|
static void openConsole();
|
|
|
|
#endif
|
2001-11-19 00:33:36 +00:00
|
|
|
|
2002-04-29 14:40:01 +00:00
|
|
|
private:
|
2001-11-19 00:33:36 +00:00
|
|
|
static Outputter s_outputter;
|
2002-05-31 14:25:26 +00:00
|
|
|
static Lock s_lock;
|
|
|
|
static int s_maxPriority;
|
2001-10-14 14:38:45 +00:00
|
|
|
};
|
|
|
|
|
2002-07-26 18:28:18 +00:00
|
|
|
/*!
|
2002-10-15 21:29:44 +00:00
|
|
|
\def LOG(arg)
|
2002-07-26 18:28:18 +00:00
|
|
|
Write to the log. Because macros cannot accept variable arguments, this
|
|
|
|
should be invoked like so:
|
|
|
|
\code
|
2002-10-15 21:29:44 +00:00
|
|
|
LOG((CLOG_XXX "%d and %d are %s", x, y, x == y ? "equal" : "not equal"));
|
2002-07-26 18:28:18 +00:00
|
|
|
\endcode
|
|
|
|
In particular, notice the double open and close parentheses. Also note
|
|
|
|
that there is no comma after the \c CLOG_XXX. The \c XXX should be
|
|
|
|
replaced by one of enumerants in \c CLog::ELevel without the leading
|
|
|
|
\c k. For example, \c CLOG_INFO. The special \c CLOG_PRINT level will
|
|
|
|
not be filtered and is never prefixed by the filename and line number.
|
|
|
|
|
|
|
|
If \c NOLOGGING is defined during the build then this macro expands to
|
|
|
|
nothing. If \c NDEBUG is defined during the build then it expands to a
|
|
|
|
call to CLog::print. Otherwise it expands to a call to CLog::printt,
|
|
|
|
which includes the filename and line number.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
2002-10-15 21:29:44 +00:00
|
|
|
\def LOGC(expr, arg)
|
2002-07-26 18:28:18 +00:00
|
|
|
Write to the log if and only if expr is true. Because macros cannot accept
|
|
|
|
variable arguments, this should be invoked like so:
|
|
|
|
\code
|
2002-10-15 21:29:44 +00:00
|
|
|
LOGC(x == y, (CLOG_XXX "%d and %d are equal", x, y));
|
2002-07-26 18:28:18 +00:00
|
|
|
\endcode
|
|
|
|
In particular, notice the parentheses around everything after the boolean
|
|
|
|
expression. Also note that there is no comma after the \c CLOG_XXX.
|
|
|
|
The \c XXX should be replaced by one of enumerants in \c CLog::ELevel
|
|
|
|
without the leading \c k. For example, \c CLOG_INFO. The special
|
|
|
|
\c CLOG_PRINT level will not be filtered and is never prefixed by the
|
|
|
|
filename and line number.
|
|
|
|
|
|
|
|
If \c NOLOGGING is defined during the build then this macro expands to
|
|
|
|
nothing. If \c NDEBUG is defined during the build then it expands to a
|
|
|
|
call to CLog::print. Otherwise it expands to a call to CLog::printt,
|
|
|
|
which includes the filename and line number.
|
|
|
|
*/
|
|
|
|
|
2001-10-14 14:38:45 +00:00
|
|
|
#if defined(NOLOGGING)
|
2002-10-15 21:29:44 +00:00
|
|
|
#define LOG(_a1)
|
|
|
|
#define LOGC(_a1, _a2)
|
2001-10-14 14:38:45 +00:00
|
|
|
#define CLOG_TRACE
|
|
|
|
#elif defined(NDEBUG)
|
2002-10-15 21:29:44 +00:00
|
|
|
#define LOG(_a1) CLog::print _a1
|
|
|
|
#define LOGC(_a1, _a2) if (_a1) CLog::print _a2
|
2001-10-14 14:38:45 +00:00
|
|
|
#define CLOG_TRACE
|
|
|
|
#else
|
2002-10-15 21:29:44 +00:00
|
|
|
#define LOG(_a1) CLog::printt _a1
|
|
|
|
#define LOGC(_a1, _a2) if (_a1) CLog::printt _a2
|
2001-10-14 14:38:45 +00:00
|
|
|
#define CLOG_TRACE __FILE__, __LINE__,
|
|
|
|
#endif
|
|
|
|
|
2002-06-03 16:36:45 +00:00
|
|
|
#define CLOG_PRINT CLOG_TRACE "%z\057"
|
2001-10-14 14:38:45 +00:00
|
|
|
#define CLOG_CRIT CLOG_TRACE "%z\060"
|
|
|
|
#define CLOG_ERR CLOG_TRACE "%z\061"
|
|
|
|
#define CLOG_WARN CLOG_TRACE "%z\062"
|
|
|
|
#define CLOG_NOTE CLOG_TRACE "%z\063"
|
|
|
|
#define CLOG_INFO CLOG_TRACE "%z\064"
|
|
|
|
#define CLOG_DEBUG CLOG_TRACE "%z\065"
|
2002-04-27 18:49:03 +00:00
|
|
|
#define CLOG_DEBUG1 CLOG_TRACE "%z\066"
|
|
|
|
#define CLOG_DEBUG2 CLOG_TRACE "%z\067"
|
2001-10-14 14:38:45 +00:00
|
|
|
|
|
|
|
#endif
|