Commit 6ed6785b authored by Martin Marinov's avatar Martin Marinov

Merge branch 'ReForm-master' into merge-from-ReForm

parents 7de4bcb9 169fdc3a
// (C) Copyright 2016 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
#ifndef BASE_CODELINK_HH_INCLUDED
#define BASE_CODELINK_HH_INCLUDED
namespace Base {
class IOutputStream;
//! Convenient wrapper around a preprocessor source code link
struct CodeLink
{
CodeLink(
const char* _fnct,
const char* _file,
const int _line
)
: fnct(_fnct), file(_file), line(_line)
{}
const char* fnct;
const char* file;
int line;
};
IOutputStream& operator<<(IOutputStream& _os, const CodeLink& _lnk);
}//namespace Base
#define BASE_CODELINK ::Base::CodeLink(__FUNCTION__, __FILE__, __LINE__)
#endif//BASE_CODELINK_HH_INCLUDED
// (C) Copyright 2016 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
#ifndef BASE_DEBDEFAULT_HH_INCLUDED
#define BASE_DEBDEFAULT_HH_INCLUDED
namespace Debug {
namespace Default {
const char* const LOG_FILENAME = "reform_deb_out.txt";
}//Default
}//Debug
#endif//BASE_DEBDEFAULT_HH_INCLUDED
......@@ -15,9 +15,9 @@
#include <Base/Utils/BaseError.hh>
#include <Base/Debug/DebOut.hh>
namespace Debug {
namespace Base {
inline Stream& operator<<(Stream& _ds, const Base::Error& _err)
inline IOutputStream& operator<<(IOutputStream& _ds, const Base::Error& _err)
{
_ds << "\"" << _err.message() << "\"";
return _ds;
......
......@@ -13,7 +13,7 @@
#ifdef DEB_ON
#include <string>
#include "../Config/BaseDefines.hh"
#include <Base/Config/BaseDefines.hh>
namespace Debug {
......
// (C) Copyright 2014 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
#ifndef BASE_DEBOUT_HH_INCLUDED
#define BASE_DEBOUT_HH_INCLUDED
// DEB_ON is defined, or not, in CMakeLists.txt for primary project
#ifndef DEB_ON
#define DEB_module(SS)
#define DEB_enter_func
#define DEB_only(CC)
#define DEB_exec(LL, AA) {}
#define DEB_exec_if(CC, LL, AA) {}
#define DEB_out(LL, AA) {}
#define DEB_out_if(CC, LL, AA) {}
#define DEB_line(LL, AA) {}
#define DEB_line_if(CC, LL, AA) {}
#define DEB_warning(LL, AA) {}
#define DEB_warning_if(CC, LL, AA) {}
#define DEB_mesh_if(CC, LL, FF, MM) {}
#define DEB_error(AA) {}
#define DEB_error_if(CC, AA) {}
#else // DEB_ON
#include <string>
#include <sstream>
#include <vector>
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__))
#include <array>
#endif
#include "../Config/BaseDefines.hh"
namespace Debug {
const int INVALID_LEVEL = -1;
class Stream;
class BASEDLLEXPORT Command
{
public:
enum CommandType
{
END = 0x01,
END_LF = 0x03,
END_ERR = 0x07
};
CommandType com_;
CommandType com() const
{
return com_;
}
Command(CommandType _com) : com_(_com) {}
};
// Class used to maintain Stream's CallStack
// This does not currently contain a pointer to the file streamer used
// but might do in future.
class BASEDLLEXPORT Enter
{
public:
const char* flnm_; //!< File name for this DEB_enter
int nmbr_; //!< deb_nmbr for this function.
int lvl_; //!< deb_level for this function.
int id_; /*!< Unique identifier for this Enter (used in ANCHORS) */
int outs_; /*!< Number of DEB_outs encountered within this function
determining whether a given DEB_out should include or omit
a call stack or exit trace. */
int lns_; /*!< Number of call stack indents including this call. */
Enter(const char* const _flnm, const char* const _fnct, int& _nmbr, int& _lvl);
~Enter();
//! pass the output on the level or not?
bool pass(const int _lvl) const { return _lvl <= lvl_; }
Stream& stream(const int _warn = 0, const bool _print = true);
Command end() const { return Command(Command::END); }
Command end_lf() const { return Command(Command::END_LF); }
Command end_err() const { return Command(Command::END_ERR); }
};
class File;
class BASEDLLEXPORT Stream
{
public:
enum StreamType
{
APPEND = 0x01,
HTML = 0x02,
RETAIN = 0x04,
KEEP_OPEN = 0x08
};
private:
File* dfile_;
public:
File* dfile() const
{
return dfile_;
}
//! Constructor.
Stream(
const char* _file_name = NULL, //!< [in] File name if file based.
const StreamType _type = APPEND //!< [in] bitsfield enum type identifier
) ;
~Stream();
const char* string_out() const;
Stream& print(const int);
Stream& print(const double);
Stream& print(const char* const, bool fork = true);
Stream& print(const char);
Stream& print(const Command&);
//! Get the currently active Stream
static Stream& get_global(int _warn = 0);
private:
// inhibit copy
Stream(const Stream&);
Stream& operator=(const Stream&);
};
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const int i);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const double d);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const size_t i);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const unsigned int i);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const float d);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const char c);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const char* const s);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const std::string& s);
BASEDLLEXPORT
Stream& operator<<(Stream& _ds, const Command& co);
// Stream operator for std::vector<>
template< typename ElementT>
Stream& operator<<(Stream& _ds, const std::vector<ElementT>& _vec)
{
_ds << "[ ";
for (typename std::vector<ElementT>::const_iterator el_it = _vec.begin(); el_it != _vec.end(); ++el_it)
_ds << *el_it << " ";
_ds << "]";
return _ds;
}
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__))
// Stream operator for std::array<>
template< typename ElementT, size_t _el_nmbr>
Stream& operator<<(Stream& _ds, const std::array<ElementT, _el_nmbr>& _vec)
{
_ds << "[ ";
for (const auto el : _vec)
_ds << el << " ";
_ds << "]";
return _ds;
}
#endif
// Stream operator for fixed size arrays
template <typename ElementT, size_t _el_nmbr>
Stream& operator<<(Stream& _ds, const ElementT(&_arr)[_el_nmbr])
{
_ds << "[ ";
for (unsigned int i = 0; i < _el_nmbr; ++i)
_ds << _arr[i] << " ";
_ds << "]";
return _ds;
}
// Stream std::pair<>
template <typename T0, typename T1>
Stream& operator<<(Stream& _ds, const std::pair<T0, T1>& _pair)
{
_ds << "(" << _pair.first << ", " << _pair.second << ")";
return _ds;
}
#define DEB_module(MODULE)
//TODO: This should use an atomic thread-safe static int(s)
#define DEB_enter_func static int deb_nmbr = 0; \
static int deb_lvl = Debug::INVALID_LEVEL; \
Debug::Enter deb(__FILE__, __FUNCTION__, deb_nmbr, deb_lvl);
#define DEB_only(CC) CC
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
#define DEB_exec_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) { AA; } }
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
#define DEB_out_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << deb.end(); } }
#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
#define DEB_line_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << deb.end_lf(); } }
#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream(1) << "WARNING: " << AA << deb.end_lf(); } }
#define DEB_error(AA) { deb.stream(2) << "ERROR: " << AA << deb.end_err(); }
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }
// Stream does not fulfill ostream. If you want to exploit an existing
// ostream streamer to DEB_out a class as text without exploiting any
// numeric processing or custom Stream streamers then use this macro thus
// DEB_out(1, "my_class is " << DEB_os_str(my_c) )
#if (_MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__))
#define DEB_os_str(AA) \
dynamic_cast<std::ostringstream &&>((std::ostringstream() << AA )).str()
#else
template <typename T>
std::string toString(const T& t)
{
std::ostringstream ss;
ss << t;
return ss.str();
}
#define DEB_os_str(AA) \
Debug::toString(AA)
#endif
}//namespace Debug
#endif // DEB_ON
#endif // BASE_DEBOUT_HH_INCLUDED
// (C) Copyright 2014 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
#ifndef BASE_DEBOUT_HH_INCLUDED
#define BASE_DEBOUT_HH_INCLUDED
// DEB_ON is defined, or not, in CMakeLists.txt for primary project
#ifndef DEB_ON
#define DEB_module(SS)
#define DEB_enter_func
#define DEB_only(CC)
#define DEB_exec(LL, AA) {}
#define DEB_exec_if(CC, LL, AA) {}
#define DEB_out(LL, AA) {}
#define DEB_out_if(CC, LL, AA) {}
#define DEB_line(LL, AA) {}
#define DEB_line_if(CC, LL, AA) {}
#define DEB_warning(LL, AA) {}
#define DEB_warning_if(CC, LL, AA) {}
#define DEB_mesh_if(CC, LL, FF, MM) {}
#define DEB_error(AA) {}
#define DEB_error_if(CC, AA) {}
#else // DEB_ON
#include "Base/Code/CodeLink.hh"
#include "Base/Utils/OStringStream.hh"
#include <string>
#include <vector>
#include <array>
namespace Debug {
typedef unsigned int uint;
const int INVALID_LEVEL = -1;
const char* const ERROR = "ERROR";
const char* const WARNING = "WARNING";
class Stream;
// Class used to maintain Stream's CallStack
// This does not currently contain a pointer to the file streamer used
// but might do in future.
class Enter
{
public:
const char* flnm_; //!< File name for this DEB_enter
const char* fnct_; //!< Function name for this DEB_enter
int nmbr_; //!< deb_nmbr for this function.
int lvl_; //!< deb_level for this function.
int id_; /*!< Unique identifier for this Enter (used in ANCHORS) */
int outs_; /*!< Number of DEB_outs encountered within this function
determining whether a given DEB_out should include or omit
a call stack or exit trace. */
int lns_; /*!< Number of call stack indents including this call. */
Enter(const char* const _flnm, const char* const _fnct, int& _nmbr, int& _lvl);
~Enter();
//! pass the output on the level or not?
bool pass(const int _lvl) const { return _lvl <= lvl_; }
Stream& stream();
};
//! This is a private implementation for Stream
class File;
class Stream : public Base::IOutputStream
{
public:
enum Flags
{
APPEND = 0x01,
HTML = 0x02,
RETAIN = 0x04,
KEEP_OPEN = 0x08
};
public:
//! Constructor.
Stream(
const char* _flnm = nullptr, //!< [in] Filename if file based.
const uint _flags = APPEND //!< [in] bit-field type identifier
);
~Stream();
Base::IOutputStream& print(const int);
Base::IOutputStream& print(const size_t);
Base::IOutputStream& print(const double);
Base::IOutputStream& print(const char* const);
Base::IOutputStream& print(const char);
Base::IOutputStream& print(const Base::Command&);
private:
File* dfile_;
private:
// inhibit copy
Stream(const Stream&);
Stream& operator=(const Stream&);
File* dfile() const { return dfile_; }
friend class Enter;
friend class Controller;
};
extern void warning(const std::string& _wrng, const ::Base::CodeLink& _lnk);
extern void error(const std::string& _err, const ::Base::CodeLink& _lnk);
}//namespace Debug
#define DEB_module(MODULE)
//TODO: This should use an atomic thread-safe static int(s)
#define DEB_enter_func static int deb_nmbr = 0; \
static int deb_lvl = Debug::INVALID_LEVEL; \
::Debug::Enter deb(__FILE__, __FUNCTION__, deb_nmbr, deb_lvl);
#define DEB_only(CC) CC
#define DEB_exec(LL, AA) DEB_exec_if(true, LL, AA)
#define DEB_exec_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) { AA; } }
#define DEB_out(LL, AA) DEB_out_if(true, LL, AA)
#define DEB_out_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << ::Base::Command::END; } }
#define DEB_line(LL, AA) DEB_line_if(true, LL, AA)
#define DEB_line_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ deb.stream() << AA << ::Base::LF; } }
#define DEB_warning(LL, AA) DEB_warning_if(true, LL, AA)
#define DEB_warning_if(CC, LL, AA) { if (deb.pass(LL) && (CC)) \
{ ::Base::OStringStream strm; strm << AA; \
::Debug::warning(strm.str, BASE_CODELINK); } }
#define DEB_error(AA) { ::Base::OStringStream strm; strm << AA; \
::Debug::error(strm.str, BASE_CODELINK); }
#define DEB_error_if(CC, AA) { if (CC) DEB_error(AA); }
// Stream does not fulfill ostream. If you want to exploit an existing
// ostream streamer to DEB_out a class as text without exploiting any
// numeric processing or custom Stream streamers then use this macro thus
// DEB_out(1, "my_class is " << DEB_os_str(my_c) )
#define DEB_os_str(AA) \
dynamic_cast<std::ostringstream &&>((std::ostringstream() << AA )).str()
#endif // DEB_ON
#endif // BASE_DEBOUT_HH_INCLUDED
// (C) Copyright 2014 by Autodesk, Inc.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
#include "DebUtils.hh"
#include "Base/Utils/ThrowError.hh"
#ifdef DEB_ON
#include <string>
#include <fstream>
#include <time.h>
#include <vector>
#include <iostream>
#include <map>
#include <memory>
#include <list>
#include <map>
#include <sstream>
#include <cstring>
#include <time.h>
#include <cstdlib>
#ifndef _MSC_VER
#define sprintf_s snprintf
#endif
#ifndef nullptr
#define nullptr NULL
#endif
namespace { // LOCAL_PROC
bool is_html_filename(const char* const str)
{
if (str == nullptr) return false;
const char* dot = strrchr(str, '.');
if (dot == nullptr) return false;
++dot;
return (!strncmp(dot, "htm", 3)) || (!strncmp(dot, "HTM", 3)) ;
}
}
namespace Debug {
class FunctionCallSequence
{
std::string func_name_;
std::vector<Enter*> debs_; // These may not have sequential counts when multithreaded.
public:
FunctionCallSequence(const char* _func_name, Enter* _deb)
: func_name_(_func_name)
{
debs_.push_back(_deb);
}
~FunctionCallSequence() {}
bool add(const char* _func_name, Enter* _deb)
{
if (func_name_ == _func_name)
{
debs_.push_back(_deb);
return true;
}
return false;
}
bool pop()
{
if (debs_.size() > 1)
{
debs_.pop_back();
return true;
}
debs_.clear();
return false;
}
int number_calls() const
{
if (!this) return 0;
return (int)debs_.size();
}
int count(int i = 0) const
{
int num = number_calls();
if (i < num) return debs_[num - 1 - i]->nmbr_;
return -1;
}
const char* name() const
{
return func_name_.c_str();
}
// Replace interior of < > in function name with . for brevity
void compact_name(std::string& str) const
{
int cnt = 0;
const char* ptr = func_name_.c_str();
while (ptr && (*ptr != '\0'))
{
char c = *ptr;
if (c == '>') --cnt;
if (cnt == 0) str.append(1, c);
if (c == '<')
{
if (cnt == 0) str.append(".");
++cnt;
}
++ptr;
}
}
// Get single call stack element string
void get(std::string& _str, const bool _strip_angled, bool _with_counts) const
{
if (_strip_angled) compact_name(_str);
else _str.append(name());
_str.append("[");
if (_with_counts)
{
int num = number_calls();
int prev = -2;
int seq_cnt = 0;
for (int i = 0; i < num; ++i)
{
int cnt = debs_[i]->nmbr_;
if (cnt != prev + 1)
{
char buffer[64];