Commit 5e38f629 authored by Max Lyon's avatar Max Lyon

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

Merge from ReForm

See merge request !10
parents 3623fbdf 6542e0c7
---
BasedOnStyle: LLVM
BreakBeforeBraces: Allman
SortIncludes: 'false'
PointerAlignment: 'Left'
AlignAfterOpenBracket: 'DontAlign'
AlignEscapedNewlines: 'DontAlign'
SpacesInContainerLiterals: 'false'
...
// (C) Copyright 2016 by Autodesk, Inc. // (C) Copyright 2019 by Autodesk, Inc.
#ifndef BASE_CODELINK_HH_INCLUDED #ifndef BASE_CODELINK_HH_INCLUDED
#define BASE_CODELINK_HH_INCLUDED #define BASE_CODELINK_HH_INCLUDED
......
// (C) Copyright 2015 by Autodesk, Inc. // (C) Copyright 2019 by Autodesk, Inc.
#ifndef QUALITY_HH_INCLUDED #ifndef QUALITY_HH_INCLUDED
#define QUALITY_HH_INCLUDED #define QUALITY_HH_INCLUDED
// This file contains various definitions related to enforcing certain code // This file contains various definitions related to enforcing certain code
// quality rules, e.g., applying W4 // quality rules, e.g., applying W4
// only test this in MSVC
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Some warnings are disabled permanently since the cannot be controlled on // Some warnings are disabled permanently since the cannot be controlled on
// section basis. // section basis.
//function 'function' marked as __forceinline not inlined //function 'function' marked as __forceinline not inlined
#pragma warning (disable: 4714) #pragma warning (disable: 4714)
#define LOW_CODE_QUALITY_SECTION_BEGIN __pragma(warning(push, 1)) #define LOW_CODE_QUALITY_SECTION_BEGIN1 __pragma(warning(push, 1))
#define LOW_CODE_QUALITY_SECTION_END __pragma(warning(pop)) #define LOW_CODE_QUALITY_SECTION_BEGIN3 __pragma(warning(push, 3))
#define LOW_CODE_QUALITY_SECTION_END __pragma(warning(pop))
#define LOW_CODE_QUALITY_VARIABLE_ALLOW(FOO) static_cast<void>(FOO);
#else #else // not on MSVC
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#ifdef __clang__ #ifdef __clang__
#define LOW_CODE_QUALITY_SECTION_BEGIN \ #define LOW_CODE_QUALITY_SECTION_BEGIN1 \
_Pragma("clang diagnostic push") \ _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-register\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated-register\"") \
_Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \ _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
_Pragma("clang diagnostic ignored \"-Wshift-negative-value\"") _Pragma("clang diagnostic ignored \"-Wshift-negative-value\"")
//TODO: ignore more warnings as needed //TODO: ignore more warnings as needed
#define LOW_CODE_QUALITY_SECTION_END \ #define LOW_CODE_QUALITY_SECTION_END \
_Pragma("clang diagnostic pop") _Pragma("clang diagnostic pop")
#elif defined(__GNUG__) #elif defined(__GNUG__)
#define LOW_CODE_QUALITY_SECTION_BEGIN \ #define LOW_CODE_QUALITY_SECTION_BEGIN1 \
_Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wall\"") //TODO: ignore more warnings as needed _Pragma("GCC diagnostic ignored \"-Wall\"") //TODO: ignore more warnings as needed
#define LOW_CODE_QUALITY_SECTION_END \ #define LOW_CODE_QUALITY_SECTION_END \
_Pragma("GCC diagnostic pop") _Pragma("GCC diagnostic pop")
#else #else
#define LOW_CODE_QUALITY_SECTION_BEGIN #define LOW_CODE_QUALITY_SECTION_END
#define LOW_CODE_QUALITY_SECTION_END
#endif #endif
#else #else // __cplusplus < 201103L
#define LOW_CODE_QUALITY_SECTION_BEGIN #define LOW_CODE_QUALITY_SECTION_BEGIN1
#define LOW_CODE_QUALITY_SECTION_END #define LOW_CODE_QUALITY_SECTION_END
#endif #endif // __cplusplus >= 201103L
#define LOW_CODE_QUALITY_SECTION_BEGIN3
#define LOW_CODE_QUALITY_VARIABLE_ALLOW(FOO) static_cast<void>(sizeof(FOO));
#endif // ifdef _MSC_VER #endif // ifdef _MSC_VER
// backwards-compatible name for LOW_CODE_QUALITY_SECTION_BEGIN1
#define LOW_CODE_QUALITY_SECTION_BEGIN LOW_CODE_QUALITY_SECTION_BEGIN1
#endif // QUALITY_HH_INCLUDED #endif // QUALITY_HH_INCLUDED
// (C) Copyright 2019 by Autodesk, Inc.
#ifndef BASEDLLEXPORT #ifndef BASEDLLEXPORT
#if defined(WIN32) || defined(_WIN32) #if defined(WIN32) || defined(_WIN32)
...@@ -44,4 +45,7 @@ ...@@ -44,4 +45,7 @@
#define STD_ARRAY_AVAILABLE #define STD_ARRAY_AVAILABLE
#endif #endif
#ifndef _MSC_VER
#define sprintf_s snprintf
#endif
// (C) Copyright 2016 by Autodesk, Inc. // (C) Copyright 2019 by Autodesk, Inc.
#ifdef DEB_ON #ifdef DEB_ON
...@@ -6,10 +6,6 @@ ...@@ -6,10 +6,6 @@
#include "DebOut.hh" #include "DebOut.hh"
#include <cstring> #include <cstring>
#ifndef WIN32
#include <cstdio>
#endif
namespace Debug { namespace Debug {
namespace { namespace {
...@@ -36,13 +32,13 @@ void append_function(std::string& _str, const char* const _func) ...@@ -36,13 +32,13 @@ void append_function(std::string& _str, const char* const _func)
void append_entry(std::string& _str, const Enter* const _entr, void append_entry(std::string& _str, const Enter* const _entr,
const bool _cmpct, const bool _entr_nmbr, const Enter* const _prev_entr) const bool _cmpct, const bool _entr_nmbr, const Enter* const _prev_entr)
{ {
if (_prev_entr != NULL && // there is a previous entry and it is the same? if (_prev_entr != nullptr && // there is a previous entry and it is the same?
strcmp(_prev_entr->function(), _entr->function()) == 0) strcmp(_prev_entr->function(), _entr->function()) == 0)
{// ... so do nothing {// ... so do nothing
return; return;
} }
if (_prev_entr != NULL) if (_prev_entr != nullptr)
_str.append("/"); _str.append("/");
if (_cmpct) if (_cmpct)
...@@ -52,10 +48,8 @@ void append_entry(std::string& _str, const Enter* const _entr, ...@@ -52,10 +48,8 @@ void append_entry(std::string& _str, const Enter* const _entr,
if (_entr_nmbr) if (_entr_nmbr)
{ {
_str.append("."); _str += '.';
std::stringstream ss; _str += std::to_string(_entr->number());
ss << _entr->number();
_str.append(ss.str());
} }
} }
...@@ -73,50 +67,21 @@ const CallStack& CallStack::query() ...@@ -73,50 +67,21 @@ const CallStack& CallStack::query()
return modify(); return modify();
} }
// Read a particular call stack element
//bool read(int _up, const char*& _funcname, int& _count)
//{
// const Enter* fcs = call(_up);
// if (fcs != NULL)
// {
// _funcname = fcs->function();
// _count = fcs->number(); // Return most recent deb_enter_count
// return true;
// }
// return false;
//}
//
void CallStack::append(std::string& _str, const bool _entr_nmbr) const void CallStack::append(std::string& _str, const bool _entr_nmbr) const
{ {
const Enter* prev = NULL; const Enter* prev = nullptr;
for (size_t i = 0, n = depth(); i < n; prev = calls_[i++]) for (size_t i = 0, n = depth(); i < n; prev = calls_[i++])
append_entry(_str, calls_[i], true, _entr_nmbr, prev); append_entry(_str, calls_[i], true, _entr_nmbr, prev);
} }
void CallStack::append_indent(std::string& _str, const int _indt, void CallStack::append_indent(std::string& _str, const int _indt) const
const bool _html) const
{ {
if (_indt == 0) if (_indt == 0)
return; return;
if (_html)
{
char buffer[64];
#ifndef WIN32
sprintf(buffer, "<FONT SIZE=%i>", _indt);
#else
sprintf_s(buffer, sizeof(buffer), "<FONT SIZE=%i>", _indt);
#endif
_str.append(buffer);
}
int num = (int)calls_.size(); int num = (int)calls_.size();
int i0 = 0; int i0 = 1;
if (!_html)
++i0; // Don't waste whitespace on first level indent if .txt
for (int i = i0; i < num; ++i) for (int i = i0; i < num; ++i)
_str.append(" "); _str.append(" ");
if (_html)
_str.append(":&nbsp;</FONT>\n");
} }
}//namespace Debug }//namespace Debug
......
// (C) Copyright 2016 by Autodesk, Inc. // (C) Copyright 2019 by Autodesk, Inc.
#ifndef BASE_DEBCALLSTACK_HH_INCLUDED #ifndef BASE_DEBCALLSTACK_HH_INCLUDED
#define BASE_DEBCALLSTACK_HH_INCLUDED #define BASE_DEBCALLSTACK_HH_INCLUDED
...@@ -32,19 +32,14 @@ public: ...@@ -32,19 +32,14 @@ public:
if (_up < (int)n) if (_up < (int)n)
return calls_[n - 1 - _up]; return calls_[n - 1 - _up];
else else
return NULL; return nullptr;
} }
/*! //! Append the full call stack.
Append the full call stack.
*/
void append(std::string& _str, const bool _entr_nmbr = true) const; void append(std::string& _str, const bool _entr_nmbr = true) const;
/*! //! Append and indent to the string
Append and indent to the string void append_indent(std::string& _str, const int _indt) const;
*/
void append_indent(std::string& _str, const int _indt, const bool _html
) const;
private: private:
std::vector<const Enter*> calls_; std::vector<const Enter*> calls_;
......
// (C) Copyright 2016 by Autodesk, Inc. // (C) Copyright 2019 by Autodesk, Inc.
#ifdef DEB_ON #ifdef DEB_ON
#include "DebConfig.hh" #include "DebConfig.hh"
#include "DebDefault.hh"
#include "DebFile.hh" #include "DebFile.hh"
#include "Base/Utils/Environment.hh" #include "Base/Utils/Environment.hh"
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <iostream>
#include <list> #include <list>
#include <string> #include <string>
#include <map> #include <map>
...@@ -49,54 +49,42 @@ public: ...@@ -49,54 +49,42 @@ public:
} }
private: private:
static bool search(const std::string& _flnm, typedef std::list<std::string> StringList;
const std::list<std::string>& _sel_strings)
// list of strings to be found inside the file name.
StringList file_selct_strngs_;
// list of strings to be found inside the function name.
StringList func_selct_strngs_;
private:
static bool search(const std::string& _str, const StringList& _slcts)
{ {
for (std::list<std::string>::const_iterator sel_it = _sel_strings.begin(); sel_it != _sel_strings.end(); ++sel_it) for (const auto& slct : _slcts)
{ {
const std::string& sel = *sel_it; if (_str.find(slct) != std::string::npos)
if (_flnm.find(sel) != std::string::npos)
return true; return true;
} }
return false; return false;
} }
private:
// list of strings to be found inside the file name.
std::list<std::string> file_selct_strngs_;
// list of strings to be found inside the function name.
std::list<std::string> func_selct_strngs_;
}; };
}//namespace }//namespace
class Config::Impl void print_char_to_cerr(const char _c) { std::cerr << _c; }
{
public:
Impl() : dflt_lvl_(Default::LEVEL) { read(); }
void read(); class Config::LevelFilterMap : public std::map<int, FilterLevelSelector> {};
int level(const char* const _flnm, const char* const _fnct) const;
private: bool Config::load(const char* const _cnfg_envr, const char* const _cnfg_flnm)
int dflt_lvl_;
typedef std::map<int, FilterLevelSelector> LevelFilterMap;
LevelFilterMap lvl_fltrs_; // filters for each level
};
void Config::Impl::read()
{ {
// const std::string flnm = const auto flnm = System::Environment::variable(_cnfg_envr, _cnfg_flnm);
// System::Environment::variable("REFORM_DEB_CONFIG", "reform_deb.cfg");
std::string flnm; std::ifstream cnfg_strm(flnm.c_str());
if (!System::Environment::variable("REFORM_DEB_CONFIG", flnm)) // For ReForm compatibility. Can this be removed? if (!cnfg_strm.is_open())
{ return false;
flnm = System::Environment::variable("COMISO_DEB_CONFIG", "comiso_deb.cfg");
}
delete lvl_fltrs_;
lvl_fltrs_ = new LevelFilterMap;
std::ifstream cnfg_strm(flnm.c_str());
std::string line; std::string line;
while (std::getline(cnfg_strm, line)) while (std::getline(cnfg_strm, line))
{ {
...@@ -104,7 +92,7 @@ void Config::Impl::read() ...@@ -104,7 +92,7 @@ void Config::Impl::read()
std::string type; std::string type;
line_stream >> type; line_stream >> type;
void (FilterLevelSelector::*add_string)(const std::string&) = NULL; void (FilterLevelSelector::*add_string)(const std::string&) = nullptr;
if (type == "all") if (type == "all")
{} {}
...@@ -117,9 +105,9 @@ void Config::Impl::read() ...@@ -117,9 +105,9 @@ void Config::Impl::read()
int lvl; int lvl;
line_stream >> lvl; line_stream >> lvl;
if (add_string == NULL) if (add_string == nullptr)
{ {
dflt_lvl_ = lvl; // We have read the default level. output_level = lvl; // We have read the default level.
continue; continue;
} }
char colon; char colon;
...@@ -127,21 +115,19 @@ void Config::Impl::read() ...@@ -127,21 +115,19 @@ void Config::Impl::read()
if (colon != ':') if (colon != ':')
continue; continue;
std::string select_str; std::string select_str;
while(line_stream >> select_str) while (line_stream >> select_str)
(lvl_fltrs_[lvl].*add_string)(select_str); ((*lvl_fltrs_)[lvl].*add_string)(select_str);
} }
return true;
} }
int Config::Impl::level(const char* const _flnm, const char* const _fnct) const int Config::custom_level(const char* const _flnm, const char* const _fnct) const
{ {
int lvl = dflt_lvl_; if (lvl_fltrs_ == nullptr)
for (LevelFilterMap::const_iterator fltr_it = lvl_fltrs_.begin(); return output_level;
fltr_it != lvl_fltrs_.end(); ++fltr_it) int lvl = output_level;
for (const auto& fltr : *lvl_fltrs_)
{// continue this iteration until the maximum allowed level if found {// continue this iteration until the maximum allowed level if found
const LevelFilterMap::value_type& fltr = *fltr_it;
// The following two lines where commented out to allow lowering the threshold.
// if (lvl >= fltr.first) // can this filter increase the current level?
// continue;
if (fltr.second.select_file(_flnm) || fltr.second.select_function(_fnct)) if (fltr.second.select_file(_flnm) || fltr.second.select_function(_fnct))
lvl = fltr.first; lvl = fltr.first;
} }
...@@ -160,20 +146,15 @@ const Config& Config::query() ...@@ -160,20 +146,15 @@ const Config& Config::query()
return modify(); return modify();
} }
Config::Config() : impl_(new Impl) {} const Config& Config::defaults()
Config::~Config() { delete impl_; }
int Config::level(const char* const _flnm, const char* const _fnct) const
{ {
return impl_->level(_flnm, _fnct); static Config dflt_cnfg;
return dflt_cnfg;
} }
void Config::set_console(const bool _on) { File::modify().set_console(_on); } Config::Config() {}
bool Config::console() const { return File::query().console(); }
void Config::set_logfile(bool _on) { File::modify().set_logfile(_on); } Config::~Config() { delete lvl_fltrs_; }
bool Config::logfile() const { return File::query().logfile(); }
}//namespace Debug }//namespace Debug
......
// (C) Copyright 2016 by Autodesk, Inc. // (C) Copyright 2020 by Autodesk, Inc.
#ifndef BASE_DEBCONFIG_HH_INCLUDED #ifndef BASE_DEBCONFIG_HH_INCLUDED
#define BASE_DEBCONFIG_HH_INCLUDED #define BASE_DEBCONFIG_HH_INCLUDED
...@@ -6,39 +6,65 @@ ...@@ -6,39 +6,65 @@
#include <Base/Config/BaseDefines.hh> #include <Base/Config/BaseDefines.hh>
#include <string> #include <string>
#include <vector>
namespace Debug { namespace Debug
{
void print_char_to_cerr(const char _c); //!< print a char to cerr
/*! /*!
Access the global, per-process, configuration options of the Debug system. Access the global, per-process, configuration options of the Debug system.
\todo Make this a per-thread configuration. \todo Make this a per-thread configuration.
*/ */
class BASEDLLEXPORT Config class BASEDLLEXPORT Config
{ {
public: public:
static const Config& query(); //! Define the function type to print a character on the console
typedef void (*print_function)(const char);
public:
//! Modify the current configuration.
static Config& modify(); static Config& modify();
//! Query the current configuration.
static const Config& query();
//! Query the default configuration.
static const Config& defaults();
public: public:
//! Turn on/off the console. This could be extended to redirect it. //! The output level for all code in the absence of a config file.
void set_console(const bool _on = true); int output_level = 5;
//! Get if the console is turned on/off. //! The deb out log filename, nullptr disables the debug output log file.
bool console() const; const char* log_filename = nullptr;
//! Turn on/off the logfile. This could be extended to provide a FILE*. //! Get if the log file output is enabled
void set_logfile(const bool _on); bool logfile() const { return log_filename != nullptr; }
//! Get if the logfile is turned on/off. //! Function to deb out on the console, nullptr if output disabled.
bool logfile() const; print_function console_print = print_char_to_cerr;
//! Get the level for this filename and function //! Get if the console
int level(const char* const _flnm, const char* const _fnct) const; bool console() const { return console_print != nullptr; }
public:
//! The output level for the given filename and function.
int custom_level(const char* const _flnm, const char* const _fnct) const;
/*!
Load the configuration file specified either by the environment variable
or the filename if the the environment variable is not set.
\todo Document the config format.
\return true if the configuration file was loaded properly, false otherwise.
*/
bool load(const char* const _cnfg_envr, const char* const _cnfg_flnm);
private:
class LevelFilterMap;
private: private:
class Impl; LevelFilterMap* lvl_fltrs_ = nullptr;
Impl* impl_;