diff --git a/libuuu/CMakeLists.txt b/libuuu/CMakeLists.txt index 0ff96952..fa9d8a9a 100644 --- a/libuuu/CMakeLists.txt +++ b/libuuu/CMakeLists.txt @@ -62,3 +62,4 @@ include_directories(${generated_files_dir}) #add_library( uuc SHARED ${SOURCES} )) add_library( uuc_s STATIC ${SOURCES} ) +target_include_directories(uuc_s PUBLIC include) diff --git a/libuuu/libcomm.h b/libuuu/include/libcomm.h similarity index 98% rename from libuuu/libcomm.h rename to libuuu/include/libcomm.h index 81191fda..30205f99 100644 --- a/libuuu/libcomm.h +++ b/libuuu/include/libcomm.h @@ -57,7 +57,7 @@ class string_ex : public std::string this->resize(len); va_start(args, fmt); - std::vsnprintf((char*)c_str(), len+1, fmt, args); + std::vsnprintf((char*)c_str(), len + 1, fmt, args); va_end(args); return 0; diff --git a/libuuu/libuuu.h b/libuuu/include/libuuu.h similarity index 100% rename from libuuu/libuuu.h rename to libuuu/include/libuuu.h diff --git a/msvc/libuuu.vcxproj b/msvc/libuuu.vcxproj index 6a84e20f..05ae3eb4 100644 --- a/msvc/libuuu.vcxproj +++ b/msvc/libuuu.vcxproj @@ -46,9 +46,9 @@ - + - + diff --git a/msvc/libuuu.vcxproj.filters b/msvc/libuuu.vcxproj.filters index 9970701f..dcdc17ec 100644 --- a/msvc/libuuu.vcxproj.filters +++ b/msvc/libuuu.vcxproj.filters @@ -15,10 +15,10 @@ Header Files - + Header Files - + Header Files diff --git a/uuu/CMakeLists.txt b/uuu/CMakeLists.txt index 217f32f5..4557c504 100644 --- a/uuu/CMakeLists.txt +++ b/uuu/CMakeLists.txt @@ -63,6 +63,7 @@ include_directories(${generated_files_dir}) set(SOURCES uuu.cpp + print_helpers.cpp buildincmd.cpp autocomplete.cpp ${CLSTS} diff --git a/uuu/autocomplete.cpp b/uuu/autocomplete.cpp index 57f0ac2b..49a2b27b 100644 --- a/uuu/autocomplete.cpp +++ b/uuu/autocomplete.cpp @@ -29,6 +29,8 @@ * */ +#include "autocomplete.h" + #include #include #include @@ -45,7 +47,7 @@ #include #include "buildincmd.h" -#include "../libuuu/libuuu.h" +#include "libuuu.h" #ifndef _MSC_VER #include @@ -54,6 +56,8 @@ #include #endif +using namespace std; + void linux_auto_arg(const char *space = " ", const char * filter = "") { string str = filter; diff --git a/uuu/autocomplete.h b/uuu/autocomplete.h new file mode 100644 index 00000000..a6a41896 --- /dev/null +++ b/uuu/autocomplete.h @@ -0,0 +1,35 @@ +/* +* Copyright 2020 NXP. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright notice, this +* list of conditions and the following disclaimer in the documentation and/or +* other materials provided with the distribution. +* +* Neither the name of the NXP Semiconductor nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +*/ + +#pragma once + +int auto_complete(int argc, char**argv); +void print_autocomplete_help(); diff --git a/uuu/buildincmd.cpp b/uuu/buildincmd.cpp index 7d632d2b..e809880e 100644 --- a/uuu/buildincmd.cpp +++ b/uuu/buildincmd.cpp @@ -31,53 +31,265 @@ #include "buildincmd.h" -BuildCmd g_buildin_cmd[] = +#include + +using namespace std; +constexpr BuildCmd::BuildCmd(const char * const cmd, const char * const buildcmd, + const char * const desc) : + m_cmd{cmd}, + m_buildcmd{buildcmd}, + m_desc{desc} { - { +} + +static constexpr std::array g_buildin_cmd +{ + BuildCmd{ "emmc", #include "emmc_burn_loader.clst" ,"burn boot loader to eMMC boot partition" }, - { + BuildCmd{ "emmc_all", #include "emmc_burn_all.clst" ,"burn whole image to eMMC" }, - { + BuildCmd{ "fat_write", #include "fat_write.clst" ,"update one file in fat partition, require uboot fastboot running in board" }, - { + BuildCmd{ "nand", #include "nand_burn_loader.clst" ,"burn boot loader to NAND flash" }, - { + BuildCmd{ "qspi", #include "qspi_burn_loader.clst" ,"burn boot loader to qspi nor flash" }, - { + BuildCmd{ "sd", #include "sd_burn_loader.clst" ,"burn boot loader to sd card" }, - { + BuildCmd{ "sd_all", #include "sd_burn_all.clst" ,"burn whole image to sd card" }, - { + BuildCmd{ "spl", #include "spl_boot.clst" ,"boot spl and uboot" - }, - { - NULL, - NULL, - NULL, } }; BuildInScriptVector g_BuildScripts(g_buildin_cmd); + +int Arg::parser(const string &option) +{ + size_t pos; + pos = option.find('['); + if (pos == std::string::npos) + return 0; + m_options = option.substr(pos + 1, option.find(']') - pos - 1); + m_flags = ARG_OPTION | ARG_OPTION_KEY; + return 0; +} + +BuildInScript::BuildInScript(const BuildCmd &p) : + m_script{p.m_buildcmd} +{ + if (p.m_desc) + { + m_desc = p.m_desc; + } + if (p.m_cmd) + { + m_cmd = p.m_cmd; + } + + for (size_t i = 1; i < m_script.size(); i++) + { + string param; + if (m_script[i] == '_' + && (m_script[i - 1] == '@' || m_script[i - 1] == ' ')) + { + size_t off = m_script.find(' ', i); + size_t off_tab = m_script.find('\t', i); + size_t ofn = m_script.find('\n', i); + if (off_tab < off) + off = off_tab; + if (ofn < off) + off = ofn; + + if (off == std::string::npos) + off = m_script.size() + 1; + + param = m_script.substr(i, off - i); + if (!find_args(param)) + { + Arg a{param}; + a.m_flags = Arg::ARG_MUST; + m_args.push_back(a); + } + } + } + + for (size_t i = 0; i < m_args.size(); i++) + { + size_t pos = 0; + std::string str; + str += "@"; + str += m_args[i].get_arg(); + pos = m_script.find(str); + if (pos != std::string::npos) { + std::string def; + size_t start_descript; + start_descript = m_script.find('|', pos); + if (start_descript != std::string::npos) + { + m_args[i].m_desc = m_script.substr(start_descript + 1, + m_script.find('\n', start_descript) - start_descript - 1); + def = m_script.substr(pos, start_descript - pos); + m_args[i].parser(def); + } + } + } +} + +bool BuildInScript::find_args(const string &arg) const +{ + for (const auto &arg_ref : m_args) + { + if (arg_ref.get_arg() == arg) + { + return true; + } + } + return false; +} + +string BuildInScript::replace_script_args(vector args) +{ + string script{m_script}; + for (size_t i = 0; i < args.size() && i < m_args.size(); i++) + { + script = replace_str(script, m_args[i].get_arg(), args[i]); + } + + //handle option args; + for (size_t i = args.size(); i < m_args.size(); i++) + { + if (m_args[i].m_flags & Arg::ARG_OPTION_KEY) + { + for (size_t j = 0; j < args.size(); j++) + { + if (m_args[j].get_arg() == m_args[i].get_options()) + { + script = replace_str(script, m_args[i].get_arg(), args[j]); + break; + } + } + } + } + return script; +} + +string BuildInScript::replace_str(string str, const string &key, string replace) +{ + if (replace.size() > 4) + { + if (str_to_upper(replace.substr(replace.size() - 4)) == ".BZ2") + { + replace += "/*"; + } + } + + for (size_t j = 0; (j = str.find(key, j)) != std::string::npos;) + { + str.replace(j, key.size(), replace); + j += key.size(); + } + return str; +} + +void BuildInScript::show_cmd() const +{ + printf("\t%s%s%s\t%s\n", g_vt_boldwhite, m_cmd.c_str(), g_vt_default, m_desc.c_str()); + for (size_t i = 0; i < m_args.size(); i++) + { + string desc{m_args[i].get_arg()}; + if (m_args[i].m_flags & Arg::ARG_OPTION) + { + desc += g_vt_boldwhite; + desc += "[Optional]"; + desc += g_vt_default; + } + desc += " "; + desc += m_args[i].m_desc; + printf("\t\targ%d: %s\n", static_cast(i), desc.c_str()); + } +} + +string BuildInScript::str_to_upper(const string &str) +{ + const std::locale loc; + std::string s; + s.reserve(str.size()); + + for (size_t i = 0; i < str.size(); i++) + { + s.push_back(std::toupper(str[i], loc)); + } + + return s; +} + +BuildInScriptVector::BuildInScriptVector(const array &build_cmds) +{ + for (const auto &build_cmd : build_cmds) { + BuildInScript one{build_cmd}; + (*this)[one.get_cmd()] = one; + } +} + +void BuildInScriptVector::PrintAutoComplete(const string &match, const char *space) +{ + for (const auto &str_n_script : *this) + { + if(str_n_script.first.substr(0, match.size()) == match) + { + printf("%s%s\n", str_n_script.first.c_str(), space); + } + } +} + +void BuildInScriptVector::ShowAll() const +{ + for (const auto &str_n_script : *this) + { + str_n_script.second.show_cmd(); + } +} + +void BuildInScriptVector::ShowCmds() const +{ + printf("<"); + for (auto iCol = cbegin(); iCol != cend(); ++iCol) + { + // Print the current command's name + printf("%s%s%s", g_vt_boldwhite, iCol->first.c_str(), g_vt_default); + + // Check if it's the last command and if not print a separating bar + auto i = iCol; + ++i; + if(i != cend()) + { + printf("|"); + } + } + printf(">"); +} diff --git a/uuu/buildincmd.h b/uuu/buildincmd.h index d01edaea..906c8fdd 100644 --- a/uuu/buildincmd.h +++ b/uuu/buildincmd.h @@ -28,14 +28,12 @@ * POSSIBILITY OF SUCH DAMAGE. * */ + #pragma once +#include #include #include -#include -#include - -using namespace std; extern const char * g_vt_yellow ; extern const char * g_vt_default ; @@ -46,6 +44,10 @@ extern const char * g_vt_boldwhite ; struct BuildCmd { + BuildCmd() = default; + constexpr BuildCmd(const char * const cmd, const char * const buildcmd, + const char * const desc); + const char *m_cmd; const char *m_buildcmd; const char *m_desc; @@ -54,231 +56,59 @@ struct BuildCmd class Arg { public: - string m_arg; - string m_desc; - uint32_t m_flags; - string m_options; enum { ARG_MUST = 0x1, ARG_OPTION = 0x2, ARG_OPTION_KEY = 0x4, }; - Arg() { m_flags = ARG_MUST; } - int parser(string option) - { - size_t pos; - pos = option.find('['); - if (pos == string::npos) - return 0; - m_options = option.substr(pos + 1, option.find(']') - pos - 1); - m_flags = ARG_OPTION | ARG_OPTION_KEY; - return 0; - } + + Arg(const std::string &arg) : m_arg{arg} {} + + const std::string &get_arg() const noexcept { return m_arg; } + const std::string &get_options() const noexcept { return m_options; } + int parser(const std::string &option); + + std::string m_desc; + uint32_t m_flags = ARG_MUST; + +private: + std::string m_arg; + std::string m_options; }; class BuildInScript { public: - string m_script; - string m_desc; - string m_cmd; - vector m_args; - bool find_args(string arg) - { - for (size_t i = 0; i < m_args.size(); i++) - { - if (m_args[i].m_arg == arg) - return true; - } - return false; - } BuildInScript() {}; - BuildInScript(BuildCmd*p) - { - m_script = p->m_buildcmd; - if(p->m_desc) - m_desc = p->m_desc; - if(p->m_cmd) - m_cmd = p->m_cmd; - - for (size_t i = 1; i < m_script.size(); i++) - { - size_t off; - size_t off_tab; - string param; - if (m_script[i] == '_' - && (m_script[i - 1] == '@' || m_script[i - 1] == ' ')) - { - off = m_script.find(' ', i); - off_tab = m_script.find('\t', i); - size_t ofn = m_script.find('\n', i); - if (off_tab < off) - off = off_tab; - if (ofn < off) - off = ofn; - - if (off == string::npos) - off = m_script.size() + 1; - - param = m_script.substr(i, off - i); - if (!find_args(param)) - { - Arg a; - a.m_arg = param; - a.m_flags = Arg::ARG_MUST; - m_args.push_back(a); - } - } - } - - for (size_t i = 0; i < m_args.size(); i++) - { - size_t pos = 0; - string str; - str += "@"; - str += m_args[i].m_arg; - pos = m_script.find(str); - if (pos != string::npos) { - string def; - size_t start_descript; - start_descript = m_script.find('|', pos); - if (start_descript != string::npos) - { - m_args[i].m_desc = m_script.substr(start_descript + 1, - m_script.find('\n', start_descript) - start_descript - 1); - def = m_script.substr(pos, start_descript - pos); - m_args[i].parser(def); - } - } - } - } - - void show() - { - printf("%s\n", m_script.c_str()); - } - - void show_cmd() - { - printf("\t%s%s%s\t%s\n", g_vt_boldwhite, m_cmd.c_str(), g_vt_default, m_desc.c_str()); - for (size_t i=0; i < m_args.size(); i++) - { - string desc; - desc += m_args[i].m_arg; - if (m_args[i].m_flags & Arg::ARG_OPTION) - { - desc += g_vt_boldwhite; - desc += "[Optional]"; - desc += g_vt_default; - } - desc += " "; - desc += m_args[i].m_desc; - printf("\t\targ%d: %s\n", (int)i, desc.c_str()); - } - } - - inline string str_to_upper(string str) - { - std::locale loc; - string s; + BuildInScript(const BuildCmd &p); - for (size_t i = 0; i < str.size(); i++) - s.push_back(std::toupper(str[i], loc)); + inline const std::string &get_cmd() const noexcept { return m_cmd; } + inline const std::string &get_script() const noexcept { return m_script; } + std::string replace_script_args(std::vector args); + inline void show() { printf("%s\n", m_script.c_str()); } + void show_cmd() const; - return s; - } +private: + bool find_args(const std::string &arg) const; + static std::string replace_str(std::string str, const std::string &key, std::string replace); + static std::string str_to_upper(const std::string &str); - string replace_str(string str, string key, string replace) - { - if (replace.size() > 4) - { - if (str_to_upper(replace.substr(replace.size() - 4)) == ".BZ2") - { - replace += "/*"; - } - } - - for (size_t j = 0; (j = str.find(key, j)) != string::npos;) - { - str.replace(j, key.size(), replace); - j += key.size(); - } - return str; - } - - string replace_script_args(vector args) - { - string script = m_script; - for (size_t i = 0; i < args.size() && i < m_args.size(); i++) - { - script = replace_str(script, m_args[i].m_arg, args[i]); - } - //handle option args; - for (size_t i = args.size(); i < m_args.size(); i++) - { - if (m_args[i].m_flags & Arg::ARG_OPTION_KEY) - { - for (size_t j = 0; j < args.size(); j++) - { - if (m_args[j].m_arg == m_args[i].m_options) - { - script = replace_str(script, m_args[i].m_arg, args[j]); - break; - } - } - } - } - return script; - } + std::string m_script; + std::string m_desc; + std::string m_cmd; + std::vector m_args; }; -class BuildInScriptVector : public map +class BuildInScriptVector : public std::map { public: - BuildInScriptVector(BuildCmd*p) - { - while (p->m_cmd) - { - BuildInScript one(p); - (*this)[one.m_cmd] = one; - p++; - } - } - - void ShowAll() - { - for (auto iCol = begin(); iCol != end(); ++iCol) - { - iCol->second.show_cmd(); - } - } - - void ShowCmds() - { - printf("<"); - for (auto iCol = begin(); iCol != end(); ++iCol) - { - printf("%s%s%s", g_vt_boldwhite, iCol->first.c_str(), g_vt_default); - - auto i = iCol; - i++; - if(i != end()) - printf("|"); - } - printf(">"); - } - - void PrintAutoComplete(string match, const char *space=" " ) - { - for (auto iCol = begin(); iCol != end(); ++iCol) - { - if(iCol->first.substr(0, match.size()) == match) - printf("%s%s\n", iCol->first.c_str(), space); - } - } + BuildInScriptVector(const std::array &build_cmds); + void PrintAutoComplete(const std::string &match, const char *space=" " ); + void ShowAll() const; + void ShowCmds() const; }; extern BuildInScriptVector g_BuildScripts; diff --git a/uuu/print_helpers.cpp b/uuu/print_helpers.cpp new file mode 100644 index 00000000..6f6e3bdd --- /dev/null +++ b/uuu/print_helpers.cpp @@ -0,0 +1,168 @@ +#include "print_helpers.h" + +#include "libcomm.h" +#include "libuuu.h" + +#include +#include +#include + +using namespace std; + +AutoReactivateCursor::~AutoReactivateCursor() +{ + printf("\x1b[?25h\n\n\n"); +} + +string build_progress_bar(size_t width, size_t pos, size_t total, + const char * vt_default, const char * vt_yellow) +{ + string str; + str.resize(width, ' '); + str[0] = '['; + str[width - 1] = ']'; + + if (total == 0) + { + if (pos == 0) + return str; + + string_ex loc; + size_t s = pos / (1024 * 1024); + loc.format("%dM", s); + str.replace(1, loc.size(), loc); + return str; + } + + size_t i; + + if (pos > total) + pos = total; + + for (i = 1; i < (width-2) * pos / total; i++) + { + str[i] = '='; + } + + if (i > 1) + str[i] = '>'; + + if (pos == total) + str[str.size() - 2] = '='; + + string_ex per; + per.format("%d%%", pos * 100 / total); + + size_t start = (width - per.size()) / 2; + str.replace(start, per.size(), per); + str.insert(start, vt_yellow); + str.insert(start + per.size() + strlen(vt_yellow), vt_default); + return str; +} + +void print_auto_scroll(string str, size_t len, size_t start) +{ + if (str.size() <= len) + { + str.resize(len, ' '); + cout << str; + return; + } + + if(str.size()) + start = start % str.size(); + else + start = 0; + + string s = str.substr(start, len); + s.resize(len, ' '); + cout << s; +} + +int print_cfg(const char *pro, const char * chip, const char * /*compatible*/, + uint16_t pid, uint16_t vid, uint16_t bcdmin, uint16_t bcdmax, void * /*p*/) +{ + const char *ext; + if (strlen(chip) >= 7) + ext = ""; + else + ext = "\t"; + + if (bcdmin == 0 && bcdmax == 0xFFFF) + printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\n", pro, chip, ext, pid, vid); + else + printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\t [0x%04x..0x%04x]\n", pro, chip, ext, pid, vid, bcdmin, bcdmax); + return 0; +} + +void print_lsusb() +{ + cout << "Connected Known USB Devices\n"; + printf("\tPath\t Chip\t Pro\t Vid\t Pid\t BcdVersion\n"); + printf("\t==================================================\n"); + + uuu_for_each_devices(print_usb_device, nullptr); +} + +void print_oneline(string str, int console_width) +{ + size_t w = static_cast(console_width); + if (w <= 3) + return; + + if (str.size() >= w) + { + str.resize(w - 1); + str[str.size() - 1] = '.'; + str[str.size() - 2] = '.'; + str[str.size() - 3] = '.'; + } + else + { + str.resize(w, ' '); + } + cout << str << endl; + +} + +void print_udev() +{ + uuu_for_each_cfg(print_udev_rule, nullptr); + fprintf(stderr, "\n1: put above udev run into /etc/udev/rules.d/99-uuu.rules\n"); + fprintf(stderr, "\tsudo sh -c \"uuu -udev >> /etc/udev/rules.d/99-uuu.rules\"\n"); + fprintf(stderr, "2: update udev rule\n"); + fprintf(stderr, "\tsudo udevadm control --reload-rules\n"); +} + +int print_udev_rule(const char * /*pro*/, const char * /*chip*/, const char * /*compatible*/, + uint16_t vid, uint16_t pid, uint16_t /*bcdmin*/, uint16_t /*bcdmax*/, void * /*p*/) +{ + printf("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", MODE=\"0666\"\n", + vid, pid); + return 0; +} + +int print_usb_device(const char *path, const char *chip, const char *pro, + uint16_t vid, uint16_t pid, uint16_t bcd, void * /*p*/) +{ + printf("\t%s\t %s\t %s\t 0x%04X\t0x%04X\t 0x%04X\n", path, chip, pro, vid, pid, bcd); + return 0; +} + +void print_usb_filter(const vector &usb_path_filters) +{ + if (!usb_path_filters.empty()) + { + cout << " at path "; + for (const auto &usb_path_filter : usb_path_filters) + { + cout << usb_path_filter << " "; + } + } +} + +void print_version() +{ + printf("uuu (Universal Update Utility) for nxp imx chips -- %s\n\n", + uuu_get_version_string()); +} diff --git a/uuu/print_helpers.h b/uuu/print_helpers.h new file mode 100644 index 00000000..4affbd51 --- /dev/null +++ b/uuu/print_helpers.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +class AutoReactivateCursor +{ +public: + ~AutoReactivateCursor(); +}; + +std::string build_progress_bar(size_t width, size_t pos, size_t total, + const char * vt_default, const char * vt_yellow); +void print_auto_scroll(std::string str, size_t len, size_t start); +int print_cfg(const char *pro, const char * chip, const char * /*compatible*/, + uint16_t pid, uint16_t vid, uint16_t bcdmin, uint16_t bcdmax, void * /*p*/); +void print_lsusb(); +void print_oneline(std::string str, int console_width); +void print_udev(); +int print_udev_rule(const char * /*pro*/, const char * /*chip*/, const char * /*compatible*/, + uint16_t vid, uint16_t pid, uint16_t /*bcdmin*/, uint16_t /*bcdmax*/, void * /*p*/); +int print_usb_device(const char *path, const char *chip, const char *pro, + uint16_t vid, uint16_t pid, uint16_t bcd, void * /*p*/); +void print_usb_filter(const std::vector &usb_path_filters); +void print_version(); diff --git a/uuu/uuu.cpp b/uuu/uuu.cpp index 4968c011..4fdec723 100644 --- a/uuu/uuu.cpp +++ b/uuu/uuu.cpp @@ -29,6 +29,8 @@ * */ +#include "autocomplete.h" +#include "print_helpers.h" #include #include #include @@ -36,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -44,10 +45,10 @@ #include #include #include "buildincmd.h" -#include #include -#include "../libuuu/libuuu.h" +#include "libcomm.h" +#include "libuuu.h" const char * g_vt_yellow = "\x1B[93m"; const char * g_vt_default = "\x1B[0m"; @@ -69,60 +70,27 @@ void clean_vt_color() noexcept using namespace std; int get_console_width(); -void print_oneline(string str); -int auto_complete(int argc, char**argv); -void print_autocomplete_help(); -char g_sample_cmd_list[] = { -#include "uuu.clst" -}; - -vector g_usb_path_filter; +static vector g_usb_path_filter; -int g_verbose = 0; +static int g_verbose = 0; static bool g_start_usb_transfer; -class AutoCursor -{ -public: - ~AutoCursor() - { - printf("\x1b[?25h\n\n\n"); - } -}; - void ctrl_c_handle(int) { do { - AutoCursor a; + AutoReactivateCursor a; } while(0); exit(1); } -class string_ex : public std::string -{ -public: - int format(const char *fmt, ...) - { - va_list args; - va_start(args, fmt); - size_t len = std::vsnprintf(NULL, 0, fmt, args); - va_end(args); - - this->resize(len); - - va_start(args, fmt); - std::vsnprintf((char*)c_str(), len + 1, fmt, args); - va_end(args); - - return 0; - } -}; - void print_help(bool detail = false) { - const char help[] = + static char g_sample_cmd_list[] = { + #include "uuu.clst" + }; + static constexpr char help[] = "uuu [-d -m -v -V] <" "bootloader|cmdlists|cmd" ">\n\n" " bootloader download bootloader to board by usb\n" " cmdlist run all commands in cmdlist file\n" @@ -181,106 +149,14 @@ void print_help(bool detail = false) start = pos; } } -void print_version() -{ - printf("uuu (Universal Update Utility) for nxp imx chips -- %s\n\n", uuu_get_version_string()); -} - -int print_cfg(const char *pro, const char * chip, const char * /*compatible*/, uint16_t pid, uint16_t vid, uint16_t bcdmin, uint16_t bcdmax, void * /*p*/) -{ - const char *ext; - if (strlen(chip) >= 7) - ext = ""; - else - ext = "\t"; - - if (bcdmin == 0 && bcdmax == 0xFFFF) - printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\n", pro, chip, ext, pid, vid); - else - printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\t [0x%04x..0x%04x]\n", pro, chip, ext, pid, vid, bcdmin, bcdmax); - return 0; -} - -int print_udev_rule(const char * /*pro*/, const char * /*chip*/, const char * /*compatible*/, - uint16_t vid, uint16_t pid, uint16_t /*bcdmin*/, uint16_t /*bcdmax*/, void * /*p*/) -{ - printf("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", MODE=\"0666\"\n", - vid, pid); - return 0; -} int polling_usb(std::atomic& bexit); -int g_overall_status; -int g_overall_okay; -int g_overall_failure; -char g_wait[] = "|/-\\"; -int g_wait_index; - - -string build_process_bar(size_t width, size_t pos, size_t total) -{ - string str; - str.resize(width, ' '); - str[0] = '['; - str[width - 1] = ']'; - - if (total == 0) - { - if (pos == 0) - return str; - - string_ex loc; - size_t s = pos / (1024 * 1024); - loc.format("%dM", s); - str.replace(1, loc.size(), loc); - return str; - } - - size_t i; - - if (pos > total) - pos = total; - - for (i = 1; i < (width-2) * pos / total; i++) - { - str[i] = '='; - } - - if (i > 1) - str[i] = '>'; - - if (pos == total) - str[str.size() - 2] = '='; - - string_ex per; - per.format("%d%%", pos * 100 / total); - - size_t start = (width - per.size()) / 2; - str.replace(start, per.size(), per); - str.insert(start, g_vt_yellow); - str.insert(start + per.size() + strlen(g_vt_yellow), g_vt_default); - return str; -} - -void print_auto_scroll(string str, size_t len, size_t start) -{ - if (str.size() <= len) - { - str.resize(len, ' '); - cout << str; - return; - } - - if(str.size()) - start = start % str.size(); - else - start = 0; - - string s = str.substr(start, len); - s.resize(len, ' '); - cout << s; -} +static int g_overall_status; +static int g_overall_okay; +static int g_overall_failure; +static char g_wait[] = "|/-\\"; +static int g_wait_index; class ShowNotify { public: @@ -436,7 +312,7 @@ class ShowNotify cout << "Download file:" << nt->str << endl; } - void print(int verbose = 0, uuu_notify*nt=NULL) + void print(int verbose = 0, uuu_notify*nt = nullptr) { verbose ? print_verbose(nt) : print_simple(); } @@ -473,7 +349,7 @@ class ShowNotify str += g_wait[(g_wait_index++) & 0x3]; - print_oneline(str); + print_oneline(str, get_console_width()); return ; } else @@ -507,7 +383,7 @@ class ShowNotify } cout << str; } else { - cout << build_process_bar(bar, m_trans_pos, m_trans_size); + cout << build_progress_bar(bar, m_trans_pos, m_trans_size, g_vt_yellow, g_vt_default); } cout << " "; print_auto_scroll(m_cmd, width - bar - info-1, m_start_pos); @@ -525,28 +401,7 @@ return; }; static map g_map_path_nt; -mutex g_callback_mutex; - -void print_oneline(string str) -{ - size_t w = get_console_width(); - if (w <= 3) - return; - - if (str.size() >= w) - { - str.resize(w - 1); - str[str.size() - 1] = '.'; - str[str.size() - 2] = '.'; - str[str.size() - 3] = '.'; - } - else - { - str.resize(w, ' '); - } - cout << str << endl; - -} +static mutex g_callback_mutex; ShowNotify Summary(map *np) { @@ -575,7 +430,7 @@ ShowNotify Summary(map *np) int progress(uuu_notify nt, void *p) { - map *np = (map*)p; + map *np = reinterpret_cast*>(p); map::iterator it; std::lock_guard lock(g_callback_mutex); @@ -608,13 +463,14 @@ int progress(uuu_notify nt, void *p) str += g_usb_path_filter[i] + " "; } - print_oneline(str); - print_oneline(""); + const int console_width = get_console_width(); + print_oneline(str, console_width); + print_oneline("", console_width); if ((*np)[nt.id].m_dev == "Prep" && !g_start_usb_transfer) { Summary(np).print(); }else - print_oneline(""); + print_oneline("", console_width); for (it = g_map_path_nt.begin(); it != g_map_path_nt.end(); it++) it->second.print(); @@ -683,15 +539,6 @@ int get_console_width() return w.ws_col; } #endif -void print_usb_filter() -{ - if (!g_usb_path_filter.empty()) - { - cout << " at path "; - for (size_t i = 0; i < g_usb_path_filter.size(); i++) - cout << g_usb_path_filter[i] << " "; - } -} int runshell(int shell) { @@ -757,30 +604,6 @@ int runshell(int shell) return -1; } -void print_udev() -{ - uuu_for_each_cfg(print_udev_rule, NULL); - fprintf(stderr, "\n1: put above udev run into /etc/udev/rules.d/99-uuu.rules\n"); - fprintf(stderr, "\tsudo sh -c \"uuu -udev >> /etc/udev/rules.d/99-uuu.rules\"\n"); - fprintf(stderr, "2: update udev rule\n"); - fprintf(stderr, "\tsudo udevadm control --reload-rules\n"); -} - -int print_usb_device(const char *path, const char *chip, const char *pro, uint16_t vid, uint16_t pid, uint16_t bcd, void * /*p*/) -{ - printf("\t%s\t %s\t %s\t 0x%04X\t0x%04X\t 0x%04X\n", path, chip, pro, vid, pid, bcd); - return 0; -} - -void print_lsusb() -{ - cout << "Connected Known USB Devices\n"; - printf("\tPath\t Chip\t Pro\t Vid\t Pid\t BcdVersion\n"); - printf("\t==================================================\n"); - - uuu_for_each_devices(print_usb_device, NULL); -} - int main(int argc, char **argv) { if (auto_complete(argc, argv) == 0) @@ -796,7 +619,7 @@ int main(int argc, char **argv) } } - AutoCursor a; + AutoReactivateCursor a; print_version(); @@ -931,7 +754,7 @@ int main(int argc, char **argv) tmpCmd.m_desc = "Script loaded from file"; - BuildInScript tmpBuildInScript(&tmpCmd); + BuildInScript tmpBuildInScript(tmpCmd); g_BuildScripts[tmpCmdFileName] = tmpBuildInScript; cmd_script = g_BuildScripts[tmpCmdFileName].replace_script_args(args); @@ -952,7 +775,7 @@ int main(int argc, char **argv) } else { - printf("%s", g_BuildScripts[argv[i + 1]].m_script.c_str()); + printf("%s", g_BuildScripts[argv[i + 1]].get_script().c_str()); return 0; } } @@ -1009,7 +832,7 @@ int main(int argc, char **argv) printf("%sBuild in config:%s\n", g_vt_boldwhite, g_vt_default); printf("\tPctl\t Chip\t\t Vid\t Pid\t BcdVersion\n"); printf("\t==================================================\n"); - uuu_for_each_cfg(print_cfg, NULL); + uuu_for_each_cfg(print_cfg, nullptr); if (!cmd_script.empty()) printf("\n%sRun built-in script:%s\n %s\n\n", g_vt_boldwhite, g_vt_default, cmd_script.c_str()); @@ -1017,13 +840,13 @@ int main(int argc, char **argv) if (!shell) cout << "Wait for Known USB Device Appear..."; - print_usb_filter(); + print_usb_filter(g_usb_path_filter); printf("\n"); } else { cout << "Wait for Known USB Device Appear..."; - print_usb_filter(); + print_usb_filter(g_usb_path_filter); cout << "\r"; cout << "\x1b[?25l"; cout.flush();