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