stamen

Stamen - static menu generator
git clone git://git.dimitrijedobrota.com/stamen.git
Log | Files | Refs | README | LICENSE

commit 327abb09023582d7a9310440fd011cf012ae4195
parent 12c5ce88ce059481256dc028f9c672c1861655ca
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Fri, 14 Jun 2024 01:15:43 +0200

Option to include system or user stamen header

Diffstat:
Mdemo/CMakeLists.txt | 4++--
Minclude/menu.h | 11+++++------
Msrc/generate.cpp | 99+++++++++++++++++++++++++++++++++++++++++--------------------------------------
3 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt @@ -4,7 +4,7 @@ configure_file(demo_menu.conf ${GENERATE_OUT}/demo_menu.conf COPYONLY) add_custom_command( OUTPUT ${GENERATE_OUT}/demo_menu.hpp ${GENERATE_OUT}/demo_menu.cpp - COMMAND ${GENERATE_OUT}/stamen-generate --cpp ${GENERATE_OUT}/demo_menu.conf + COMMAND ${GENERATE_OUT}/stamen-generate --user --cpp ${GENERATE_OUT}/demo_menu.conf DEPENDS demo_menu.conf stamen-generate COMMENT "Generating menu files" ) @@ -23,7 +23,7 @@ set_target_properties(demo PROPERTIES add_custom_command( OUTPUT ${GENERATE_OUT}/demo_menu.h ${GENERATE_OUT}/demo_menu.c - COMMAND ${GENERATE_OUT}/stamen-generate --c ${GENERATE_OUT}/demo_menu.conf + COMMAND ${GENERATE_OUT}/stamen-generate --user --c ${GENERATE_OUT}/demo_menu.conf DEPENDS demo_menu.conf stamen-generate COMMENT "Generating cmenu files" ) diff --git a/include/menu.h b/include/menu.h @@ -12,12 +12,6 @@ namespace stamen { class Menu { - friend class Generator; - - static std::unordered_map<std::string, Menu> menu_lookup; - static std::unordered_map<std::string, callback_f> free_lookup; - static std::string display_stub_default; - struct private_ctor_t {}; public: @@ -59,6 +53,8 @@ class Menu { return entries.items[idx].callback; } + static std::unordered_map<std::string, Menu> menu_lookup; + private: Menu(std::string code, std::string prompt) : code(std::move(code)), title(std::move(prompt)) {} @@ -93,6 +89,9 @@ class Menu { const std::string code, title; Entries entries; + + static std::unordered_map<std::string, callback_f> free_lookup; + static std::string display_stub_default; }; } // namespace stamen diff --git a/src/generate.cpp b/src/generate.cpp @@ -8,63 +8,65 @@ #include <iostream> #include <string> -namespace stamen { - -const stamen_display_f stamen_display = stamen::builtin_display; - -class Generator { - public: - static void generateInclude(std::ostream &os, bool cpp) { - os << "#ifndef STAMEN_MENU_H\n"; - os << "#define STAMEN_MENU_H\n\n"; +struct arguments_t { + std::string config; + bool cpp = false; + bool user = false; +} opt; - if (cpp) os << "#include \"stamen.hpp\"\n\n"; +void generateIncludeHeaders(std::ostream &os) { + if (opt.user) { + if (opt.cpp) os << "#include \"stamen.hpp\"\n\n"; else os << "#include \"stamen.h\"\n\n"; + } else { + if (opt.cpp) os << "#include <stamen/stamen.hpp>\n\n"; + else os << "#include <stamen/stamen.h>\n\n"; + } +} - for (const auto &[code, menu] : Menu::menu_lookup) { - os << std::format("int {}(int);\n", menu.getCode()); - } +void generateInclude(std::ostream &os) { + os << "#ifndef STAMEN_MENU_H\n"; + os << "#define STAMEN_MENU_H\n\n"; - os << "\n#endif\n"; - } + generateIncludeHeaders(os); - static void generateSource(std::ostream &os, bool cpp) { - if (cpp) os << "#include \"stamen.hpp\"\n\n"; - else os << "#include \"stamen.h\"\n\n"; + for (const auto &[code, menu] : stamen::Menu::menu_lookup) { + os << std::format("int {}(int);\n", menu.getCode()); + } - os << "#include \"shared.h\"\n\n"; - for (const auto &[code, menu] : Menu::menu_lookup) { - os << std::format("int {}(int) {{\n", menu.getCode()); + os << "\n#endif\n"; +} - if (cpp) os << "\tstatic const stamen::item_t items[] = "; - else os << "\tstatic const stamen_item_t items[] = "; +void generateSource(std::ostream &os) { + os << "#include \"shared.h\"\n"; + generateIncludeHeaders(os); - os << "{\n"; - for (int i = 0; i < menu.getSize(); i++) { - os << "\t\t{ " << menu.getCode(i); - os << ", \"" << menu.getPrompt(i) << "\" },\n"; - } - os << "\t};\n"; + for (const auto &[code, menu] : stamen::Menu::menu_lookup) { + os << std::format("int {}(int) {{\n", menu.getCode()); - if (cpp) os << "\treturn stamen::stamen_display"; - else os << "\treturn stamen_display"; + if (opt.cpp) os << "\tstatic const stamen::item_t items[] = "; + else os << "\tstatic const stamen_item_t items[] = "; - os << std::format("(\"{}\"", menu.getTitle()); - os << ", items, sizeof(items) / sizeof(items[0]));\n"; - os << "}\n\n"; + os << "{\n"; + for (int i = 0; i < menu.getSize(); i++) { + os << "\t\t{ " << menu.getCode(i); + os << ", \"" << menu.getPrompt(i) << "\" },\n"; } - } -}; -} // namespace stamen + os << "\t};\n"; -struct arguments_t { - std::string config; - bool cpp = false; -}; + if (opt.cpp) os << "\treturn stamen::stamen_display"; + else os << "\treturn stamen_display"; + + os << std::format("(\"{}\"", menu.getTitle()); + os << ", items, sizeof(items) / sizeof(items[0]));\n"; + os << "}\n\n"; + } +} int parse_opt(int key, const char *arg, args::Parser *parser) { auto arguments = (arguments_t *)parser->input(); switch (key) { + case 'u': arguments->user = true; break; case 666: arguments->cpp = false; break; case 777: arguments->cpp = true; break; case args::ARG: @@ -84,6 +86,8 @@ static const args::option_t options[]{ {0, 0, 0, 0, "Output mode", 1}, {"c", 666, 0, 0, "Generate files for C"}, {"cpp", 777, 0, 0, "Generate files for C++"}, + {0, 0, 0, 0, "Output settings", 2}, + {"user", 'u', 0, 0, "Include user stamen headers"}, {0, 0, 0, 0, "Informational Options", -1}, {0}, }; @@ -96,23 +100,22 @@ static const args::argp_t argp{ }; int main(int argc, char *argv[]) { - arguments_t arguments; - if (args::parse(&argp, argc, argv, 0, &arguments)) { + if (args::parse(&argp, argc, argv, 0, &opt)) { std::cerr << "There was an error while parsing arguments"; return 0; } - const auto &config = arguments.config; + const auto &config = opt.config; stamen::Menu::read(config); - std::string::size_type pos = arguments.config.rfind('.'); + std::string::size_type pos = opt.config.rfind('.'); std::string base = pos != std::string::npos ? config.substr(0, pos) : config; - std::string ext = arguments.cpp ? "pp" : ""; + std::string ext = opt.cpp ? "pp" : ""; std::ofstream source(base + ".c" + ext), include(base + ".h" + ext); - stamen::Generator::generateSource(source, arguments.cpp); - stamen::Generator::generateInclude(include, arguments.cpp); + generateInclude(include); + generateSource(source); return 0; }