/* * ===================================================================================== * * 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 #include #include 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 const &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 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 void PrintLn(const char *fmt, Params &&...t) { printf(fmt, std::forward(t)...); PrintLn(); } void Help() { PrintLn("%s : bhome shared memory message queue box application.", kOrigName.c_str()); PrintLn("%s", "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("%s", "supported functions:"); std::map 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); }