stamen

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

commit d5a343ef60d087a9e9ed648a14478f491ffe5a56
parent 08ff305c12bb4a7f9cc10610f51616b096647aa6
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Thu, 30 Nov 2023 19:32:28 +0000

Improve naming, consistency and decomposition

Diffstat:
MCMakeLists.txt | 2+-
Mdemo/main.c | 2+-
Mdemo/main.cpp | 4+---
Ainclude/shared.h | 15+++++++++++++++
Minclude/stamen.h | 36++++++++++++++----------------------
Minclude/stamenc.h | 15+++------------
Msrc/generate.cpp | 16+++++++++-------
Msrc/stamen.cpp | 5++---
Msrc/stamenc.cpp | 6++----
9 files changed, 48 insertions(+), 53 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project( Stamen - VERSION 0.0.13 + VERSION 0.0.14 DESCRIPTION "Static menu generator" LANGUAGES C CXX ) diff --git a/demo/main.c b/demo/main.c @@ -4,7 +4,7 @@ #include <stdio.h> #include <stdlib.h> -const display_f display = stamen_builtin_display; +const stamen_display_f stamen_display = stamen_builtin_display; int operation1(void) { printf("operation 1\n"); diff --git a/demo/main.cpp b/demo/main.cpp @@ -3,11 +3,9 @@ #include <iostream> -using stamen::Menu; - // need to link against stamen library // in order to use stamen::BuiltinDisplay -const Menu::display_f Menu::display = stamen::builtinDisplay; +const stamen_display_f stamen_display = stamen::builtinDisplay; int operation1(void) { std::cout << "operation 1" << std::endl; diff --git a/include/shared.h b/include/shared.h @@ -0,0 +1,15 @@ +#ifndef STAMEN_SHARED_H +#define STAMEN_SHARED_H + +typedef int (*stamen_callback_f)(void); + +typedef struct item_t item_t; +struct item_t { + stamen_callback_f callback; + const char *prompt; +}; + +typedef int (*stamen_display_f)(const char *, const item_t[], int); +extern const stamen_display_f stamen_display; + +#endif diff --git a/include/stamen.h b/include/stamen.h @@ -1,7 +1,7 @@ #ifndef STAMEN_H #define STAMEN_H -#include "stamenc.h" +#include "shared.h" #include <exception> #include <format> @@ -16,15 +16,17 @@ namespace stamen { class Menu { + struct private_ctor_t {}; + public: friend class Generator; - typedef int (*callback_f)(void); + + typedef stamen_callback_f callback_f; + typedef stamen_display_f display_f; Menu(const Menu &) = delete; Menu &operator=(const Menu &) = delete; - struct private_ctor_t {}; - // Tag type dispatch Menu(private_ctor_t, const std::string &code, const std::string &prompt) : Menu(code, prompt) {} @@ -32,14 +34,10 @@ public: Menu(private_ctor_t, const std::string &code, const callback_f callback) : Menu(code, callback) {} - typedef int (*display_f)(const std::string &, const ::item_t[], std::size_t); - static const display_f display; - static void read(const std::string &s); + static void print(const std::string &entry) { internal_print(entry, 1); } static void insert(const std::string &code, const callback_f callback); - static void print(const std::string &entry) { print(entry, 1); } - private: Menu(const std::string &code, const std::string &prompt) : code(code), title(prompt) {} @@ -53,7 +51,7 @@ private: return lookup; } - static void print(const std::string &entry, const int depth); + static void internal_print(const std::string &entry, const int depth); static const Menu *getMenu(const std::string &code) { static lookup_t &lookup = getLookup(); @@ -65,12 +63,7 @@ private: const std::string code, title; const callback_f callback = nullptr; - struct lookup_item_t { - lookup_item_t(const std::string &code, const std::string &prompt) - : code(code), prompt(prompt) {} - const std::string code, prompt; - }; - + typedef std::pair<std::string, std::string> lookup_item_t; std::vector<lookup_item_t> items; }; @@ -102,23 +95,22 @@ inline void Menu::insert(const std::string &code, const callback_f callback) { std::forward_as_tuple(private_ctor_t{}, code, callback)); } -inline void Menu::print(const std::string &code, const int depth) { +inline void Menu::internal_print(const std::string &code, const int depth) { const Menu *menu = getMenu(code); if (!menu) return; if (depth == 1) std::cout << std::format("{}({})\n", menu->title, code); if (!menu->callback) { - for (const auto &item : menu->items) { + for (const auto &[code, prompt] : menu->items) { std::cout << std::format("{}{} ({})\n", std::string(depth << 1, ' '), - item.prompt, item.code); - menu->print(item.code, depth + 1); + prompt, code); + menu->internal_print(code, depth + 1); } } } -int builtinDisplay(const std::string &title, const ::item_t items[], - std::size_t size); +int builtinDisplay(const char *title, const ::item_t items[], int size); } // namespace stamen diff --git a/include/stamenc.h b/include/stamenc.h @@ -1,26 +1,17 @@ #ifndef CSTAMEN_H #define CSTAMEN_H +#include "shared.h" + #ifdef __cplusplus #define EXTERNC extern "C" #else #define EXTERNC extern #endif -typedef int (*callback_f)(void); - -typedef struct item_t item_t; -struct item_t { - callback_f callback; - const char *prompt; -}; - -typedef int (*display_f)(const char *, const item_t[], int); -extern const display_f display; - EXTERNC void stamen_read(const char *file); EXTERNC void stamen_print(const char *entry); -EXTERNC void stamen_insert(const char *code, callback_f callback); +EXTERNC void stamen_insert(const char *code, stamen_callback_f callback); EXTERNC int stamen_builtin_display(const char *title, const item_t items[], int size); #endif diff --git a/src/generate.cpp b/src/generate.cpp @@ -28,26 +28,28 @@ public: } static void generateSource(std::ostream &os, bool cpp) { - os << std::format("#include <stamen{}.h>\n", !cpp ? "c" : ""); + os << "#include <stamenc.h>\n"; os << "#include \"shared.h\"\n\n"; - if (cpp) os << "namespace stamen {\n"; + if (cpp) os << "namespace stamen {\n\n"; for (const auto &[code, _] : Menu::getLookup()) { const Menu *menu = Menu::getMenu(code); if (!menu) throw EGenerate(); if (menu->callback) continue; os << std::format("int {}(void) {{\n", menu->code); + os << std::format("\tstatic const item_t items[] = {{\n"); - for (const auto &item : menu->items) { - os << std::format("\t\t{{ {}, \"{}\" }},\n", item.code, item.prompt); + for (const auto &[code, prompt] : menu->items) { + os << std::format("\t\t{{ {}, \"{}\" }},\n", code, prompt); } os << std::format("\t}};\n"); - os << std::format("\treturn {}display(\"{}\", items, " + + os << std::format("\treturn stamen_display(\"{}\", items, " "sizeof(items) / sizeof(item_t));\n", - cpp ? "Menu::" : "", menu->title); + menu->title); os << std::format("}}\n\n"); } - if (cpp) os << "\n}\n"; + if (cpp) os << "}\n"; } }; diff --git a/src/stamen.cpp b/src/stamen.cpp @@ -7,10 +7,9 @@ namespace stamen { -int builtinDisplay(const std::string &title, const ::item_t items[], - std::size_t size) { - int choice; +int builtinDisplay(const char *title, const ::item_t items[], int size) { const int digits = std::log10(size) + 1; + int choice; while (true) { std::cout << std::format("{}:\n", title); diff --git a/src/stamenc.cpp b/src/stamenc.cpp @@ -1,13 +1,11 @@ -#include "../include/stamen.h" #include "../include/stamenc.h" +#include "../include/stamen.h" using namespace stamen; -const Menu::display_f Menu::display = nullptr; - void stamen_read(const char *file) { stamen::Menu::read(file); } void stamen_print(const char *entry) { stamen::Menu::print(entry); } -void stamen_insert(const char *code, callback_f callback) { +void stamen_insert(const char *code, stamen_callback_f callback) { Menu::insert(code, callback); }