From c5a61f404ade9c4413b892258cc76b217a17c8ff Mon Sep 17 00:00:00 2001
From: Marco Amagliani <marco.amagliani@autodesk.com>
Date: Mon, 2 Nov 2015 18:33:00 +0000
Subject: [PATCH] new deb selection filter based on configuration file.
 https://jira.autodesk.com/browse/REFORM-57

[git-p4: depot-paths = "//ReForm/ReForm/main/Base/": change = 13163]
---
 Debug/DebOut.hh    |   1 -
 Debug/DebStream.cc | 192 +++++++++++++++++++++++++++------------------
 Debug/DebUtils.hh  |   3 -
 3 files changed, 116 insertions(+), 80 deletions(-)

diff --git a/Debug/DebOut.hh b/Debug/DebOut.hh
index 76acac2..679bf53 100644
--- a/Debug/DebOut.hh
+++ b/Debug/DebOut.hh
@@ -107,7 +107,6 @@ public:
                     a call stack or exit trace. */
   int deb_lines_; /*!< Number of call stack indents including this call. */
   const char* flnm_;  /*!< File name for this DEB_enter. */
-  const char* module_;  /*!< Module name for this DEB_enter. Not used. */
 
   Enter(const char* const _flnm, const char* const _funcname, const int _count);
   ~Enter();
diff --git a/Debug/DebStream.cc b/Debug/DebStream.cc
index db05898..ae85967 100644
--- a/Debug/DebStream.cc
+++ b/Debug/DebStream.cc
@@ -19,6 +19,10 @@
 #include <vector>
 #include <iostream>
 #include <map>
+#include <memory>
+#include <list>
+#include <map>
+#include <sstream>
 
 namespace { // LOCAL_PROC
 bool is_html_filename(const char* const str)
@@ -170,7 +174,7 @@ public:
     --depth_;
   }
 
-  const FunctionCallSequence* call(int _up = 0)
+  const FunctionCallSequence* call(int _up = 0) const
   {
     int num = (int)calls_.size();
     if (_up < num) return &calls_[num - 1 - _up];
@@ -222,10 +226,45 @@ private:
     module_stats(int _lev = 0) : lev_(_lev), col_(0x808080) {}
     ~module_stats() {}
   };
+  
+  // We use this data to decide the debug level of a function in a file.
+  class FilterLevelSelector
+  {
+  public:
+    void add_file_string(const std::string& _str) { file_selct_strngs_.push_back(_str); }
+    void add_func_string(const std::string& _str) { func_selct_strngs_.push_back(_str); }
+
+    bool select_file(const char* _flnm) const
+    {
+      std::string flnm(_flnm);
+      const std::string root_dir("ReForm");
+      auto pos = flnm.rfind(root_dir);
+      if (pos != std::string::npos)
+        flnm = flnm.substr(pos + root_dir.size());
+      return search(flnm, file_selct_strngs_);
+    }
+
+    bool select_function(const char* _func) const
+    {
+      return search(_func, func_selct_strngs_);
+    }
 
-  std::map<std::string, module_stats> module_map_;
-  typedef std::map<std::string, module_stats>::iterator module_map_itr;
-  typedef std::map<std::string, module_stats>::const_iterator const_module_map_itr;
+  private:
+    static bool search(const std::string& _name,
+      const std::list<std::string>& _sel_strings)
+    {
+      for (const auto& sel : _sel_strings)
+      {
+        if (_name.find(sel) != std::string::npos)
+          return true;
+      }
+      return false;
+    }
+
+  private:
+    std::list<std::string> file_selct_strngs_; // list of strings to be found inside the file name.
+    std::list<std::string> func_selct_strngs_; // list of strings to be found inside the function name.
+  };
 
   Stream::StreamType type_;
   int lev_;
@@ -233,6 +272,8 @@ private:
   int priority_; // Last permission granted
   int indent_size_;
 
+  std::map<int, FilterLevelSelector> level_selc_map_; // A map filter_level ==> filter_selector
+
   bool at_line_start_;
 
   std::string current_;
@@ -663,7 +704,6 @@ public:
     flush();
   }
 
-
   void set_file_name(const char* _name)
   {
     file_name_ = _name ? _name : "";
@@ -671,45 +711,25 @@ public:
       type_ = (Stream::StreamType)(type_ | Stream::StreamType::HTML);
   }
 
-  void set_module_level(const char* const _module, const int _lev)
+  int permission(const int _lev, const int _warn, const char* const _flnm)
   {
-    std::pair<module_map_itr, bool> ins =  module_map_.insert(
-        std::pair<std::string, module_stats>(_module, module_stats(_lev)));
-    if (!ins.second) ins.first->second.lev_ = _lev;
-  }
-
-  int module_level(const char* const _module) const
-  {
-    const_module_map_itr it = module_map_.find(std::string(_module));
-    if (it == module_map_.end()) return lev_;
-    return it->second.lev_;
-  }
-
-  void set_module_color(const char* const _module, const int _col)
-  {
-    std::pair<module_map_itr, bool> ins =  module_map_.insert(
-        std::pair<std::string, module_stats>(_module, module_stats(lev_)));
-    ins.first->second.col_ = _col;
-  }
-
-  int get_module_color(const char* const _module) const
-  {
-    const_module_map_itr it = module_map_.find(std::string(_module));
-    if (it == module_map_.end())
+    _warn;
+    int lev = lev_;
+    for (const auto& fltrs : level_selc_map_)
     {
-      if (is_white_on_black()) return 0xFFFFFF;
-      else return 0x000000;
+      if (fltrs.second.select_file(_flnm) ||
+          fltrs.second.select_function(call_stack_.call()->name()))
+      {
+        lev = fltrs.first;
+        break;
+      }
     }
-    return it->second.col_;
-  }
 
-  int permission(const int _lev, const int _warn, const char* const _module)
-  {
-    _warn;
-    int lev = module_level(_module);
     lev -= _lev;
-    if (lev < 0) lev = 0;
-    if (lev > 0) priority_ = lev;
+    if (lev > 0)
+      priority_ = lev;
+    else if (lev < 0)
+      lev = 0;
     return lev;
   }
 
@@ -718,37 +738,69 @@ public:
     return at_line_start_;
   }
 
-
   File(
     Stream* _deb_stream,
     Stream::StreamType _type = (Stream::StreamType)(Stream::APPEND | Stream::RETAIN),
     const char* _file_name = nullptr) :
     type_(_type), lev_(5), deb_stream_(_deb_stream), num_flush_(0)
   {
+    read_debug_config();
     set_file_name(_file_name);
     indent_size_ = 3;
     at_line_start_ = false; // Don't want to indent header
-    //    indent_string_ = ".";
-    set_module_color("PARA", 0xFF8000);
-    set_module_color("SOLV", 0x00FF00);
-    set_module_color("NSLV", 0xFFFF00);
-    set_module_color("FELD", 0x0080FF);
-    set_module_color("CURV", 0x00FFFF);
-    set_module_color("QMGN", 0xFF00FF);
-    // Don't set a TEST module colour here because Test is not part of Reform
-
-#if 0  // Such custom setting calls really belong in Test
-    set_module_level("PARA", 1);
-    set_module_level("CFLD", 0);
-    set_module_level("NSLV", 0);
-    set_module_level("QMGN", 0);
-    set_module_level("CURV", 5);
-    set_module_level("SOLV", 0);
-    set_module_level("FELD", 0);
-#endif
-
+  }
 
+  void read_debug_config()
+  {
+    std::string flnm("reform_deb.cfg");
+#ifdef WIN32
+    size_t size;
+    getenv_s(&size, nullptr, 0, "REFORM_DEB_CONFIG");
+    if (size > 0)
+    {
+      std::unique_ptr<char[]> bufer(new char[size]);
+      getenv_s(&size, bufer.get(), size, "REFORM_DEB_CONFIG");
+      flnm = bufer.get();
+    }
+#else
+    const char* deb_flnm = getenv("REFORM_DEB_CONFIG");
+    if (deb_flnm != nullptr)
+      flnm = deb_flnm;
+#endif
+    std::ifstream deb_stream(flnm.c_str());
+    std::string line;
+    while(std::getline(deb_stream, line))
+    {
+      std::stringstream line_stream(line);
+      std::string type;
+      line_stream >> type;
+      void (FilterLevelSelector::*add_string)(const std::string&) = nullptr;
+      if (type == "all") {}
+      else if (type == "file")
+        add_string = &FilterLevelSelector::add_file_string;
+      else if (type == "func")
+        add_string = &FilterLevelSelector::add_func_string;
+      else
+        continue;
+      int lev;
+      line_stream >> lev;
+      if (lev < 0 || lev > 15)
+        continue;
+      if (add_string == nullptr)
+      {
+        lev_ = lev; // We have red the default level.
+        continue;
+      }
+      char colon;
+      line_stream >> colon;
+      if (colon != ':')
+        continue;
+      std::string select_str;
+      while(line_stream >> select_str)
+        (level_selc_map_[lev].*add_string)(select_str);
+    }
   }
+
 }; // endclass File
 
 // =====================================
@@ -756,7 +808,7 @@ public:
 // =====================================
 
 Enter::Enter(const char* const _flnm, const char* const _funcname, const int _count) :
-  flnm_(_flnm), deb_outs_(0), deb_lines_(0), count_(_count), module_("")
+  flnm_(_flnm), deb_outs_(0), deb_lines_(0), count_(_count)
 {
   // TODO: this might have to be atomic
   static int id_cnt = 0;
@@ -786,11 +838,10 @@ Stream& Enter::stream(const int _warn, const bool _print)
   {
     if (impl->is_html())
     {
-      bool is_deb_error = (_warn == 2);
+      // bool is_deb_error = (_warn == 2);
       // DEB_error font powerup goes here. BLINK is deprecated sadly.
       // if (is_deb_error)  impl->print_direct("<BLINK>");
-      int col = impl->get_module_color(module_);
-      if (is_deb_error) col = 0xFF0000; // RED
+      const int col = 0xFF0000; // RED
       char buffer[256];
       sprintf_s(buffer, sizeof(buffer), "<FONT COLOR=\"#%06X\" SIZE=%i>",
                 col, impl->priority() + 1);
@@ -828,7 +879,7 @@ Stream& Enter::stream(const int _warn, const bool _print)
 
 int Enter::permission(const int _lev, const int _warn)
 {
-  int res = Stream::get_global().dfile()->permission(_lev, _warn, module_);
+  int res = Stream::get_global().dfile()->permission(_lev, _warn, flnm_);
   return res;
 }
 
@@ -847,7 +898,7 @@ void FunctionCallSequence::get_indent(std::string& _str, File* _dfile, bool _is_
       L is the first letter of the module name */
       char hovert[1024];
       sprintf_s(hovert, sizeof(hovert), "%s[%i]", func_name_.c_str(), deb->count_);
-      int col = _dfile->get_module_color(deb->module_);
+      int col = 0xFFFFFF;
       char buffer[1024];
       sprintf_s(buffer, sizeof(buffer), "<FONT COLOR=\"#%06X\">.", col);
 
@@ -1014,22 +1065,11 @@ Stream& operator<<(Stream& _ds, const ThrowInfo& _thrw_info)
 //  Controller member funcs (currently all static)
 // ==================================================
 
-void Controller::set_module_level(const char* _mod , const int _lev)
-{
-  Stream::get_global().dfile()->set_module_level(_mod, _lev);
-}
-
-
 void Controller::set_double_format(const char* _fmt)
 {
   Stream::get_global().dfile()->set_double_format(_fmt);
 }
 
-int Controller::module_level(const char* _mod)
-{
-  return Stream::get_global().dfile()->module_level(_mod);
-}
-
 const char* Controller::double_format()
 {
   return Stream::get_global().dfile()->double_format();
diff --git a/Debug/DebUtils.hh b/Debug/DebUtils.hh
index c97c168..6f688e2 100644
--- a/Debug/DebUtils.hh
+++ b/Debug/DebUtils.hh
@@ -22,9 +22,6 @@ exploited by DebStream. */
 class Controller
 {
 public:
-  static void set_module_level(const char* _mod, const int _lev);
-  static int module_level(const char* _mod);
-
   //! Set printf style format string used for double (and float) numeric print
   static void set_double_format(const char* _fmt);
   static const char* double_format();
-- 
GitLab