commit 8fe2a8b55ac5c587ad03da22c3e5cc080b7e5687
parent 327abb09023582d7a9310440fd011cf012ae4195
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Fri, 14 Jun 2024 01:53:18 +0200
No more stamen_display
* In dynamic mode pass display function when starting
* stamen-generate now takes display function name as an option
* Improve code consistency
Diffstat:
11 files changed, 33 insertions(+), 29 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 --user --cpp ${GENERATE_OUT}/demo_menu.conf
+ COMMAND ${GENERATE_OUT}/stamen-generate --user -d test_display --cpp ${GENERATE_OUT}/demo_menu.conf
DEPENDS demo_menu.conf stamen-generate
COMMENT "Generating menu files"
)
diff --git a/demo/dynamic.cpp b/demo/dynamic.cpp
@@ -1,10 +1,6 @@
#include "stamen.hpp"
#include <iostream>
-// still need to link against stamen library
-// as builtin_display is being used
-// because there is no override
-
int finish(int) { exit(1); }
int operation1(int) {
@@ -33,6 +29,6 @@ int main() {
stamen::insert("operation3", operation3);
// start the menu on specific panel
- stamen::dynamic("menu_main");
+ stamen::dynamic("menu_main", stamen::builtin_display);
return 0;
}
diff --git a/demo/main.c b/demo/main.c
@@ -4,10 +4,6 @@
#include <stdio.h>
#include <stdlib.h>
-// need to link against stamen library
-// in order to use stamen_builtin_display
-const stamen_display_f stamen_display = stamen_builtin_display;
-
int operation1(void) {
printf("operation 1\n");
printf("Some operation is done\n");
diff --git a/demo/main.cpp b/demo/main.cpp
@@ -12,9 +12,6 @@ int test_display(const char *title, const stamen::item_t itemv[], int size) {
return 0;
}
-// no need to link against stamen library as custom display is provided
-const stamen::display_f stamen::stamen_display = test_display;
-
int operation1(int) {
std::cout << "operation 1" << std::endl;
std::cout << "Some operation is done" << std::endl;
diff --git a/include/menu.h b/include/menu.h
@@ -22,8 +22,9 @@ class Menu {
Menu(const Menu &) = delete;
Menu &operator=(const Menu &) = delete;
- static int dynamic(const std::string &code) {
- display_stub_default = code;
+ static int dynamic(const std::string &code, display_f display) {
+ Menu::display_stub_default = code;
+ Menu::display = display;
return display_stub(-1);
};
@@ -92,6 +93,7 @@ class Menu {
static std::unordered_map<std::string, callback_f> free_lookup;
static std::string display_stub_default;
+ static display_f display;
};
} // namespace stamen
diff --git a/include/stamen.h b/include/stamen.h
@@ -15,14 +15,13 @@ struct stamen_item_t {
};
typedef int (*stamen_display_f)(const char *, const stamen_item_t[], int);
-extern const stamen_display_f stamen_display;
#if !defined __cplusplus || defined WITH_C_BINDINGS
void stamen_read(const char *filename);
void stamen_insert(const char *code, stamen_callback_f callback);
-int stamen_dynamic(const char *code);
+int stamen_dynamic(const char *code, stamen_display_f display);
int stamen_builtin_display(const char *title, const stamen_item_t itemv[],
int size);
diff --git a/include/stamen.hpp b/include/stamen.hpp
@@ -12,7 +12,7 @@ using item_t = stamen_item_t;
void read(const char *filename);
void insert(const char *code, callback_f callback);
-int dynamic(const char *code);
+int dynamic(const char *code, display_f display);
int builtin_display(const char *title, const item_t itemv[], int size);
} // namespace stamen
diff --git a/src/c_bindings.cpp b/src/c_bindings.cpp
@@ -3,14 +3,16 @@
namespace stamen {
-int stamen_dynamic(const char *code) { return dynamic(code); }
-
void stamen_read(const char *filename) { return read(filename); }
void stamen_insert(const char *code, stamen_callback_f callback) {
return insert(code, callback);
}
+int stamen_dynamic(const char *code, stamen_display_f display) {
+ return dynamic(code, display);
+}
+
int stamen_builtin_display(const char *title, const stamen_item_t itemv[],
int size) {
return builtin_display(title, itemv, size);
diff --git a/src/generate.cpp b/src/generate.cpp
@@ -10,6 +10,7 @@
struct arguments_t {
std::string config;
+ std::string display;
bool cpp = false;
bool user = false;
} opt;
@@ -41,6 +42,10 @@ void generateSource(std::ostream &os) {
os << "#include \"shared.h\"\n";
generateIncludeHeaders(os);
+ os << std::format("extern int {}(const char *title, ", opt.display);
+ if (opt.cpp) os << "const stamen::item_t itemv[], int size);\n\n";
+ else os << "const stamen_item_t itemv[], int size);\n\n";
+
for (const auto &[code, menu] : stamen::Menu::menu_lookup) {
os << std::format("int {}(int) {{\n", menu.getCode());
@@ -54,10 +59,7 @@ void generateSource(std::ostream &os) {
}
os << "\t};\n";
- if (opt.cpp) os << "\treturn stamen::stamen_display";
- else os << "\treturn stamen_display";
-
- os << std::format("(\"{}\"", menu.getTitle());
+ os << std::format("\treturn {}(\"{}\"", opt.display, menu.getTitle());
os << ", items, sizeof(items) / sizeof(items[0]));\n";
os << "}\n\n";
}
@@ -67,6 +69,7 @@ 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 'd': arguments->display = arg; break;
case 666: arguments->cpp = false; break;
case 777: arguments->cpp = true; break;
case args::ARG:
@@ -78,6 +81,12 @@ int parse_opt(int key, const char *arg, args::Parser *parser) {
case args::NO_ARGS:
args::failure(parser, 0, 0, "Missing an argument");
args::help(parser, stderr, args::STD_USAGE);
+ case args::END:
+ if (arguments->display.empty()) {
+ if (arguments->cpp) arguments->display = "stamen::builtin_display";
+ else arguments->display = "stamen_builtin_display";
+ }
+ break;
}
return 0;
}
@@ -87,6 +96,7 @@ static const args::option_t options[]{
{"c", 666, 0, 0, "Generate files for C"},
{"cpp", 777, 0, 0, "Generate files for C++"},
{0, 0, 0, 0, "Output settings", 2},
+ {"display", 'd', "FUNC", 0, "Set display function to be called"},
{"user", 'u', 0, 0, "Include user stamen headers"},
{0, 0, 0, 0, "Informational Options", -1},
{0},
diff --git a/src/menu.cpp b/src/menu.cpp
@@ -13,6 +13,7 @@ namespace stamen {
std::unordered_map<std::string, Menu> Menu::menu_lookup;
std::unordered_map<std::string, callback_f> Menu::free_lookup;
std::string Menu::display_stub_default;
+display_f Menu::display;
void Menu::read(const std::string &s) {
std::string line, delim, code, prompt;
@@ -61,7 +62,7 @@ int Menu::display_stub(int idx) {
if (ml_it != menu_lookup.end()) {
const Menu &menu = ml_it->second;
st.push_back(&menu);
- int ret = stamen_display(menu.title.c_str(), menu.getItemv(), menu.getSize());
+ int ret = display(menu.title.c_str(), menu.getItemv(), menu.getSize());
st.pop_back();
return ret;
}
diff --git a/src/stamen.cpp b/src/stamen.cpp
@@ -10,15 +10,16 @@
namespace stamen {
-__attribute__((weak))
-extern const stamen_display_f stamen_display = stamen_builtin_display;
-
-int dynamic(const char *code) { return Menu::dynamic(code); }
void read(const char *filename) { Menu::read(filename); }
+
void insert(const char *code, callback_f callback) {
Menu::insert(code, callback);
}
+int dynamic(const char *code, display_f display) {
+ return Menu::dynamic(code, display);
+}
+
int builtin_display(const char *title, const item_t itemv[], int size) {
const size_t digits = size_t(std::log10(size)) + 1;
const auto items = std::span(itemv, size_t(size));