diff --git a/hecl/driver/ToolBase.hpp b/hecl/driver/ToolBase.hpp index 8eec2466f..c11af5ca9 100644 --- a/hecl/driver/ToolBase.hpp +++ b/hecl/driver/ToolBase.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -45,6 +44,9 @@ public: #define BOLD "\033[1m" #define NORMAL "\033[0m" +#define HIDE_CURSOR "\033[?25l" +#define SHOW_CURSOR "\033[?25h" + #define WRAP_INDENT 4 extern bool XTERM_COLOR; @@ -119,21 +121,8 @@ private: public: HelpOutput(HelpFunc helpFunc) - : m_sout(NULL), m_helpFunc(helpFunc) - { -#if _WIN32 - CONSOLE_SCREEN_BUFFER_INFO info; - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); - m_lineWidth = info.dwSize.X; -#else - struct winsize w; - m_lineWidth = 80; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) - m_lineWidth = w.ws_col; -#endif - if (m_lineWidth < 10) - m_lineWidth = 10; - } + : m_sout(NULL), m_helpFunc(helpFunc), m_lineWidth(HECL::ConsoleWidth()) + {} void go() { diff --git a/hecl/driver/ToolExtract.hpp b/hecl/driver/ToolExtract.hpp index 0f6e46087..69187158e 100644 --- a/hecl/driver/ToolExtract.hpp +++ b/hecl/driver/ToolExtract.hpp @@ -7,7 +7,14 @@ class ToolExtract final : public ToolBase { HECL::Database::IDataSpec::ExtractPassInfo m_einfo; - std::vector> m_dataSpecs; + struct SpecExtractPass + { + const HECL::Database::DataSpecEntry* m_entry; + std::unique_ptr m_instance; + SpecExtractPass(const HECL::Database::DataSpecEntry* entry, HECL::Database::IDataSpec* instance) + : m_entry(entry), m_instance(instance) {} + }; + std::vector m_specPasses; std::vector m_reps; public: ToolExtract(const ToolPassInfo& info) @@ -32,7 +39,7 @@ public: if (ds) { if (ds->canExtract(*m_info.project, m_einfo, m_reps)) - m_dataSpecs.emplace_back(ds); + m_specPasses.emplace_back(entry, ds); else delete ds; } @@ -85,7 +92,7 @@ public: int run() { - if (m_dataSpecs.empty()) + if (m_specPasses.empty()) { if (XTERM_COLOR) HECL::Printf(_S("" RED BOLD "NOTHING TO EXTRACT" NORMAL "\n")); @@ -119,8 +126,72 @@ public: break; } - for (std::unique_ptr& ds : m_dataSpecs) - ds->doExtract(*m_info.project, m_einfo); + for (SpecExtractPass& ds : m_specPasses) + { + if (XTERM_COLOR) + HECL::Printf(_S("" MAGENTA BOLD "Using DataSpec %s:" NORMAL "\n"), ds.m_entry->m_name.c_str()); + else + HECL::Printf(_S("Using DataSpec %s:\n"), ds.m_entry->m_name.c_str()); + + int lineIdx = 0; + ds.m_instance->doExtract(*m_info.project, m_einfo, + [&lineIdx](const HECL::SystemChar* message, int lidx, float factor) + { + if (XTERM_COLOR) + HECL::Printf(_S("" HIDE_CURSOR "")); + + if (lidx > lineIdx) + { + HECL::Printf(_S("\n ")); + lineIdx = lidx; + } + else + HECL::Printf(_S(" ")); + + int width = HECL::ConsoleWidth(); + int half = width / 2 - 2; + + size_t messageLen = HECL::StrLen(message); + if (messageLen > half) + HECL::Printf(_S("%.*s... "), half-3, message); + else + { + HECL::Printf(_S("%s"), message); + for (int i=half-messageLen ; i>=0 ; --i) + HECL::Printf(_S(" ")); + } + + if (XTERM_COLOR) + { + size_t blocks = half - 7; + size_t filled = blocks * factor; + size_t rem = blocks - filled; + HECL::Printf(_S("" BOLD "%3d%% ["), (int)(factor * 100.0)); + for (int b=0 ; b childOpts; }; + typedef std::function FExtractProgress; + virtual bool canExtract(Project& project, const ExtractPassInfo& info, std::vector& reps) {(void)project;(void)info;LogModule.report(LogVisor::Error, "not implemented");return false;} - virtual void doExtract(Project& project, const ExtractPassInfo& info) - {(void)project;(void)info;} + virtual void doExtract(Project& project, const ExtractPassInfo& info, FExtractProgress progress) + {(void)project;(void)info;(void)progress;} /** * @brief Cook Task Info diff --git a/hecl/include/HECL/HECL.hpp b/hecl/include/HECL/HECL.hpp index 4783852df..29327f4ec 100644 --- a/hecl/include/HECL/HECL.hpp +++ b/hecl/include/HECL/HECL.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ std::wstring UTF8ToWide(const std::string& src); #if HECL_UCS2 typedef wchar_t SystemChar; +static inline size_t StrLen(const SystemChar* str) {return wcslen(str);} typedef std::wstring SystemString; static inline void ToLower(SystemString& str) {std::transform(str.begin(), str.end(), str.begin(), towlower);} @@ -49,6 +51,7 @@ public: SystemUTF8View(const SystemString& str) : m_utf8(WideToUTF8(str)) {} inline operator const std::string&() const {return m_utf8;} + inline const std::string& str() const {return m_utf8;} inline std::string operator+(const std::string& other) const {return m_utf8 + other;} inline std::string operator+(const char* other) const {return m_utf8 + other;} }; @@ -61,6 +64,7 @@ public: SystemStringView(const std::string& str) : m_sys(UTF8ToWide(str)) {} inline operator const std::wstring&() const {return m_sys;} + inline const std::wstring& sys_str() const {return m_sys;} inline std::wstring operator+(const std::wstring& other) const {return m_sys + other;} inline std::wstring operator+(const wchar_t* other) const {return m_sys + other;} }; @@ -71,6 +75,7 @@ inline std::wstring operator+(const wchar_t* lhs, const SystemStringView& rhs) { #endif #else typedef char SystemChar; +static inline size_t StrLen(const SystemChar* str) {return strlen(str);} typedef std::string SystemString; static inline void ToLower(SystemString& str) {std::transform(str.begin(), str.end(), str.begin(), tolower);} @@ -83,6 +88,7 @@ public: SystemUTF8View(const SystemString& str) : m_utf8(str) {} inline operator const std::string&() const {return m_utf8;} + inline const std::string& str() const {return m_utf8;} inline std::string operator+(const std::string& other) const {return std::string(m_utf8) + other;} inline std::string operator+(const char* other) const {return std::string(m_utf8) + other;} }; @@ -95,6 +101,7 @@ public: SystemStringView(const std::string& str) : m_sys(str) {} inline operator const std::string&() const {return m_sys;} + inline const std::string& sys_str() const {return m_sys;} inline std::string operator+(const std::string& other) const {return m_sys + other;} inline std::string operator+(const char* other) const {return m_sys + other;} }; @@ -230,6 +237,23 @@ static inline std::string Format(const char* format, ...) return std::string(resultBuf, printSz); } +static inline int ConsoleWidth() +{ + int retval = 80; +#if _WIN32 + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); + m_lineWidth = info.dwSize.X; +#else + struct winsize w; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) + retval = w.ws_col; +#endif + if (retval < 10) + return 10; + return retval; +} + typedef std::basic_regex SystemRegex; typedef std::regex_token_iterator SystemRegexTokenIterator; typedef std::match_results SystemRegexMatch;