/*
|
* =====================================================================================
|
*
|
* Filename: box.cpp
|
*
|
* Description:
|
*
|
* Version: 1.0
|
* Created: 2021年04月13日 15时21分44秒
|
* Revision: none
|
* Compiler: gcc
|
*
|
* Author: Li Chao (), lichao@aiotlink.com
|
* Organization:
|
*
|
* =====================================================================================
|
*/
|
#include "box.h"
|
#include <boost/filesystem/path.hpp>
|
#include <map>
|
#include <unordered_map>
|
|
namespace fs = boost::filesystem;
|
|
namespace
|
{
|
|
class Box
|
{
|
public:
|
bool Install(const std::string &name, MainFunc const &func, const std::string &desc)
|
{
|
return functions_.emplace(name, FuncInfo{name, func, desc}).second;
|
}
|
bool Find(const std::string &name, MainFunc &func)
|
{
|
auto pos = functions_.find(name);
|
if (pos != functions_.end()) {
|
func = pos->second.func_;
|
return true;
|
}
|
return false;
|
}
|
void Apply(std::function<void(const std::string &id, const std::string &desc)> f) const
|
{
|
for (auto &kv : functions_) {
|
f(kv.second.id_, kv.second.desc_);
|
}
|
}
|
|
private:
|
struct FuncInfo {
|
std::string id_;
|
MainFunc func_;
|
std::string desc_;
|
};
|
std::unordered_map<std::string, FuncInfo> functions_;
|
};
|
|
Box &TheBox()
|
{
|
static Box box;
|
return box;
|
}
|
|
} // namespace
|
|
bool BoxInstall(const std::string &name, MainFunc const &func, const std::string &desc)
|
{
|
return TheBox().Install(name, func, desc);
|
}
|
|
bool BoxFind(const std::string &name, MainFunc &func)
|
{
|
return TheBox().Find(name, func);
|
}
|
|
const std::string kOrigName("bhshmqbox");
|
|
inline void PrintLn() { putchar('\n'); }
|
|
template <class... Params>
|
void PrintLn(const char *fmt, Params &&...t)
|
{
|
printf(fmt, std::forward<decltype(t)>(t)...);
|
PrintLn();
|
}
|
|
void Help()
|
{
|
PrintLn("%s : bhome shared memory message queue box application.", kOrigName.c_str());
|
PrintLn("usage:");
|
PrintLn("\t1) %s [function [options]...]", kOrigName.c_str());
|
PrintLn("\t2) rename or link %s to a function name then run it directly.", kOrigName.c_str());
|
PrintLn();
|
PrintLn("supported functions:");
|
std::map<std::string, std::string> funcs;
|
auto getInfo = [&](const std::string &name, const std::string &desc) {
|
funcs[name] = desc;
|
};
|
TheBox().Apply(getInfo);
|
auto cmp_name_len = [](auto &a, auto &b) { return a.first.size() < b.first.size(); };
|
int max_len = std::max_element(funcs.begin(), funcs.end(), cmp_name_len)->first.size();
|
for (auto &kv : funcs) {
|
int npad = max_len - kv.first.size();
|
PrintLn();
|
PrintLn("\t%s%s : %s", kv.first.c_str(), std::string(npad, ' ').c_str(), kv.second.c_str());
|
}
|
PrintLn();
|
}
|
|
int BoxMain(int argc, const char *argv[])
|
{
|
fs::path exe(argv[0]);
|
auto name = exe.filename().string();
|
|
MainFunc func;
|
if (BoxFind(name, func)) {
|
return func(argc, argv);
|
} else {
|
PrintLn("%s : function not found!", name.c_str());
|
// Help();
|
}
|
return 0;
|
}
|
|
int main(int argc, const char *argv[])
|
{
|
BoxInstall(
|
"help", [](int, const char **) { Help(); return 0; }, "show this help message.");
|
|
fs::path exe(argv[0]);
|
auto name = exe.filename().string();
|
// PrintLn("name: %s", name.c_str());
|
|
if (name == kOrigName) {
|
if (argc > 1) {
|
argc--;
|
argv++;
|
} else {
|
Help();
|
return 0;
|
}
|
}
|
return BoxMain(argc, argv);
|
}
|