357 lines
8.5 KiB
Objective-C
357 lines
8.5 KiB
Objective-C
#ifndef _UTILS_H
|
|
#define _UTILS_H
|
|
|
|
#include <system.hh>
|
|
|
|
namespace ledger {
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Default values
|
|
*/
|
|
|
|
#if defined(FULL_DEBUG)
|
|
#define VERIFY_ON 1
|
|
#define TRACING_ON 1
|
|
#define DEBUG_ON 1
|
|
#define TIMERS_ON 1
|
|
#elif defined(NO_DEBUG)
|
|
#define NO_ASSERTS 1
|
|
#define NO_LOGGING 1
|
|
#else
|
|
#define TIMERS_ON 1 // jww (2007-04-25): is this correct?
|
|
#endif
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Assertions
|
|
*/
|
|
|
|
#ifdef assert
|
|
#undef assert
|
|
#endif
|
|
|
|
#if ! defined(NO_ASSERTS)
|
|
#define ASSERTS_ON 1
|
|
#endif
|
|
#if defined(ASSERTS_ON)
|
|
|
|
#include <boost/current_function.hpp>
|
|
|
|
void debug_assert(const ledger::string& reason,
|
|
const ledger::string& func,
|
|
const ledger::string& file,
|
|
unsigned long line);
|
|
|
|
#define assert(x) \
|
|
((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \
|
|
__FILE__, __LINE__)
|
|
|
|
#endif // ASSERTS_ON
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Verification (basically, very slow asserts)
|
|
*/
|
|
|
|
#if defined(VERIFY_ON)
|
|
|
|
extern bool verify_enabled;
|
|
|
|
#define verify(x) (verify_enabled ? assert(x) : ((void)0))
|
|
|
|
extern int new_calls;
|
|
extern unsigned long new_size;
|
|
|
|
void * operator new(std::size_t) throw(std::bad_alloc);
|
|
void * operator new[](std::size_t) throw(std::bad_alloc);
|
|
void operator delete(void*) throw();
|
|
void operator delete[](void*) throw();
|
|
void * operator new(std::size_t, const std::nothrow_t&) throw();
|
|
void * operator new[](std::size_t, const std::nothrow_t&) throw();
|
|
void operator delete(void*, const std::nothrow_t&) throw();
|
|
void operator delete[](void*, const std::nothrow_t&) throw();
|
|
|
|
typedef std::multimap<void *, std::string> live_objects_map;
|
|
typedef std::pair<void *, std::string> live_objects_pair;
|
|
typedef std::pair<unsigned int, std::size_t> count_size_pair;
|
|
typedef std::map<std::string, count_size_pair> object_count_map;
|
|
typedef std::pair<std::string, count_size_pair> object_count_pair;
|
|
|
|
extern live_objects_map live_objects;
|
|
extern object_count_map live_count;
|
|
extern object_count_map ctor_count;
|
|
extern object_count_map object_count;
|
|
|
|
bool trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
|
std::size_t cls_size);
|
|
bool trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size);
|
|
|
|
#define trace_ctor(cls, args) \
|
|
verify(trace_ctor_func(this, #cls, args, sizeof(cls)))
|
|
#define trace_dtor(cls) \
|
|
verify(trace_dtor_func(this, #cls, sizeof(cls)))
|
|
|
|
void report_memory(std::ostream& out);
|
|
|
|
#if ! defined(USE_BOOST_PYTHON)
|
|
|
|
class string : public std::string
|
|
{
|
|
public:
|
|
string();
|
|
string(const string& str);
|
|
string(const std::string& str);
|
|
string(const int len, char x);
|
|
string(const char * str);
|
|
string(const char * str, const char * end);
|
|
string(const string& str, int x);
|
|
string(const string& str, int x, int y);
|
|
string(const char * str, int x);
|
|
string(const char * str, int x, int y);
|
|
~string();
|
|
};
|
|
|
|
inline string operator+(const string& __lhs, const string& __rhs)
|
|
{
|
|
string __str(__lhs);
|
|
__str.append(__rhs);
|
|
return __str;
|
|
}
|
|
|
|
string operator+(const char* __lhs, const string& __rhs);
|
|
string operator+(char __lhs, const string& __rhs);
|
|
|
|
inline string operator+(const string& __lhs, const char* __rhs)
|
|
{
|
|
string __str(__lhs);
|
|
__str.append(__rhs);
|
|
return __str;
|
|
}
|
|
|
|
inline string operator+(const string& __lhs, char __rhs)
|
|
{
|
|
typedef string __string_type;
|
|
typedef string::size_type __size_type;
|
|
__string_type __str(__lhs);
|
|
__str.append(__size_type(1), __rhs);
|
|
return __str;
|
|
}
|
|
|
|
inline bool operator==(const string& __lhs, const string& __rhs)
|
|
{ return __lhs.compare(__rhs) == 0; }
|
|
|
|
inline bool operator==(const char* __lhs, const string& __rhs)
|
|
{ return __rhs.compare(__lhs) == 0; }
|
|
|
|
inline bool operator==(const string& __lhs, const char* __rhs)
|
|
{ return __lhs.compare(__rhs) == 0; }
|
|
|
|
inline bool operator!=(const string& __lhs, const string& __rhs)
|
|
{ return __rhs.compare(__lhs) != 0; }
|
|
|
|
inline bool operator!=(const char* __lhs, const string& __rhs)
|
|
{ return __rhs.compare(__lhs) != 0; }
|
|
|
|
inline bool operator!=(const string& __lhs, const char* __rhs)
|
|
{ return __lhs.compare(__rhs) != 0; }
|
|
|
|
#endif
|
|
|
|
#else // ! VERIFY_ON
|
|
|
|
#define verify(x)
|
|
#define trace_ctor(cls, args)
|
|
#define trace_dtor(cls)
|
|
|
|
#endif // VERIFY_ON
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Logging
|
|
*/
|
|
|
|
#if ! defined(NO_LOGGING)
|
|
#define LOGGING_ON 1
|
|
#endif
|
|
#if defined(LOGGING_ON)
|
|
|
|
// Logging
|
|
|
|
enum log_level_t {
|
|
LOG_OFF = 0,
|
|
LOG_CRIT,
|
|
LOG_FATAL,
|
|
LOG_ASSERT,
|
|
LOG_ERROR,
|
|
LOG_VERIFY,
|
|
LOG_WARN,
|
|
LOG_INFO,
|
|
LOG_EXCEPT,
|
|
LOG_DEBUG,
|
|
LOG_TRACE,
|
|
LOG_ALL
|
|
};
|
|
|
|
extern log_level_t _log_level;
|
|
extern unsigned int _trace_level;
|
|
extern std::string _log_category;
|
|
extern std::ostream * _log_stream;
|
|
extern std::ostringstream _log_buffer;
|
|
|
|
#define category(cat) \
|
|
static const char * const _this_category = (cat)
|
|
|
|
bool logger(log_level_t level);
|
|
|
|
#if defined(TRACING_ON)
|
|
#define trace(lvl, msg) \
|
|
(_log_level >= LOG_TRACE && lvl >= _trace_level ? \
|
|
((_log_buffer << msg), logger(LOG_TRACE)) : false)
|
|
#else
|
|
#define trace(lvl, msg)
|
|
#endif
|
|
|
|
#if defined(DEBUG_ON)
|
|
#define debug_(cat, msg) \
|
|
(_log_level >= LOG_DEBUG && \
|
|
(_log_category == cat || \
|
|
_log_category.find(cat ".") == 0) ? \
|
|
((_log_buffer << msg), logger(LOG_DEBUG)) : false)
|
|
#define debug(msg) debug_(_this_category, msg)
|
|
#else
|
|
#define debug_(cat, msg)
|
|
#define debug(msg)
|
|
#endif
|
|
|
|
#define exception_occurred(msg) \
|
|
log_macro(LOG_EXCEPT, msg)
|
|
|
|
#define info_(cat, msg) \
|
|
(_log_level >= LOG_INFO && \
|
|
(_log_category == cat || \
|
|
_log_category.find(cat ".") == 0) ? \
|
|
((_log_buffer << msg), logger(LOG_INFO)) : false)
|
|
#define info(msg) info_(_this_category, msg)
|
|
|
|
#define log_macro(level, msg) \
|
|
(_log_level >= level ? \
|
|
((_log_buffer << msg), logger(level)) : false)
|
|
|
|
#define warn(msg) log_macro(LOG_WARN, msg)
|
|
#define error(msg) log_macro(LOG_ERROR, msg)
|
|
#define fatal(msg) log_macro(LOG_FATAL, msg)
|
|
#define critical(msg) log_macro(LOG_CRIT, msg)
|
|
|
|
#else // ! LOGGING_ON
|
|
|
|
#define category(cat)
|
|
#define trace(lvl, msg)
|
|
#define debug(msg)
|
|
#define debug_(cat, msg)
|
|
#define info(msg)
|
|
#define info_(cat, msg)
|
|
#define warn(msg)
|
|
#define error(msg)
|
|
#define fatal(msg)
|
|
#define critical(msg)
|
|
|
|
#endif // LOGGING_ON
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Timers (allows log entries to specify cumulative time spent)
|
|
*/
|
|
|
|
#if defined(LOGGING_ON) && defined(TIMERS_ON)
|
|
|
|
struct timer_t {
|
|
std::clock_t count;
|
|
std::string message;
|
|
};
|
|
|
|
typedef std::map<std::string, timer_t> timing_map;
|
|
typedef timing_map::value_type timing_pair;
|
|
|
|
void start_timer(const char * name);
|
|
void stop_timer(const char * name);
|
|
void finish_timer(const char * name);
|
|
|
|
#if defined(TRACING_ON)
|
|
#define trace_start(name, lvl, msg) \
|
|
(trace(lvl, msg) && start_timer(name))
|
|
#define trace_stop(name) stop_timer(name)
|
|
#define trace_finish(name) finish_timer(name)
|
|
#else
|
|
#define trace_start(name, lvl, msg)
|
|
#define trace_stop(name)
|
|
#define trace_finish(name)
|
|
#endif
|
|
|
|
#if defined(DEBUG_ON)
|
|
#define debug_start(name, msg) \
|
|
(debug(msg) && start_timer(name))
|
|
#define debug_start_(name, cat, msg) \
|
|
(debug_(cat, msg) && start_timer(name))
|
|
#define debug_stop(name) stop_timer(name)
|
|
#define debug_finish(name) finish_timer(name)
|
|
#else
|
|
#define debug_start(name, msg)
|
|
#define debug_start_(name, cat, msg)
|
|
#define debug_stop(name)
|
|
#define debug_finish(name)
|
|
#endif
|
|
|
|
#define info_start(name, msg) \
|
|
(info(msg) && start_timer(name))
|
|
#define info_start_(name, cat, msg)
|
|
#define info_stop(name) stop_timer(name)
|
|
#define info_finish(name) finish_timer(name)
|
|
|
|
#else // ! (LOGGING_ON && TIMERS_ON)
|
|
|
|
#define trace_start(lvl, msg, name)
|
|
#define trace_stop(name)
|
|
#define trace_finish(name)
|
|
|
|
#define debug_start(name, msg)
|
|
#define debug_start_(name, cat, msg)
|
|
#define debug_stop(name)
|
|
#define debug_finish(name)
|
|
|
|
#define info_start(name, msg)
|
|
#define info_start_(name, cat, msg)
|
|
#define info_stop(name)
|
|
#define info_finish(name)
|
|
|
|
#endif // TIMERS_ON
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Debug macros
|
|
*/
|
|
|
|
#if defined(DEBUG_ON)
|
|
|
|
#define if_debug_(cat) \
|
|
if (_log_level >= LOG_DEBUG && \
|
|
(_log_category == cat || \
|
|
_log_category.find(cat ".") == 0))
|
|
#define if_debug() if_debug_(_this_category)
|
|
|
|
#else // ! DEBUG_ON
|
|
|
|
#define if_debug(cat) if (false)
|
|
|
|
#endif // DEBUG_ON
|
|
|
|
/**********************************************************************
|
|
*
|
|
* Exception handling
|
|
*/
|
|
|
|
#import "error.h"
|
|
|
|
// } namespace ledger
|
|
|
|
#endif // _UTILS_H
|