commit 199eba24714cb83271e636100315011def07ded9
parent 8fe2a8b55ac5c587ad03da22c3e5cc080b7e5687
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Fri, 14 Jun 2024 11:13:49 +0200
General code improvement
Diffstat:
4 files changed, 82 insertions(+), 87 deletions(-)
diff --git a/demo/demo_menu.conf b/demo/demo_menu.conf
@@ -1,25 +1,28 @@
-+ menu_main Main Menu
++ menu_main Main Menu
-- submenu_1 Enter Submenu 1
-- submenu_2 Enter Submenu 2
+- submenu_1 Enter Submenu 1
+- submenu_2 Enter Submenu 2
- finish Quit
+
+ submenu_1 Submenu 1
-- submenu_3 Enter Submenu 3
-- operation1 Operation 1
-- operation2 Operation 2
-- operation3 Operation 3
+- submenu_3 Enter Submenu 3
+- operation1 Operation 1
+- operation2 Operation 2
+- operation3 Operation 3
+
+ submenu_2 Submenu 2
-- submenu_3 Enter Submenu 3
-- operation1 Operation 1
-- operation2 Operation 2
-- operation3 Operation 3
+- submenu_3 Enter Submenu 3
+- operation1 Operation 1
+- operation2 Operation 2
+- operation3 Operation 3
+
-+ submenu_3 Submenu 3
++ submenu_3 Submenu 3
-- operation1 Operation 1
-- operation2 Operation 2
-- operation3 Operation 3
+- operation1 Operation 1
+- operation2 Operation 2
+- operation3 Operation 3
diff --git a/include/menu.h b/include/menu.h
@@ -21,6 +21,9 @@ class Menu {
Menu(const Menu &) = delete;
Menu &operator=(const Menu &) = delete;
+ Menu(Menu &&) = delete;
+ Menu &operator=(Menu &&) = delete;
+ ~Menu() noexcept = default;
static int dynamic(const std::string &code, display_f display) {
Menu::display_stub_default = code;
@@ -29,30 +32,19 @@ class Menu {
};
static void read(const std::string &s);
- static void print(const std::string &entry) { print(entry, 1); }
static void insert(const std::string &s, callback_f callback) {
free_lookup.emplace(s, callback);
}
- [[nodiscard]] const std::string &getCode() const { return code; }
- [[nodiscard]] const std::string &getTitle() const { return title; }
+ const std::string &getCode() const { return code; }
+ const std::string &getTitle() const { return title; }
- [[nodiscard]] const item_t *getItemv() const {
- return entries.items.data();
- }
- [[nodiscard]] std::size_t getSize() const { return entries.items.size(); }
-
- [[nodiscard]] const std::string &getCode(std::size_t idx) const {
- return entries.codes[idx].code;
- }
+ const item_t *getItemv() const { return entries.items.data(); }
+ std::size_t getSize() const { return entries.items.size(); }
- [[nodiscard]] const std::string &getPrompt(std::size_t idx) const {
- return entries.codes[idx].prompt;
- }
-
- [[nodiscard]] callback_f getCallback(std::size_t idx) const {
- return entries.items[idx].callback;
- }
+ callback_f getCallback(std::size_t idx) const;
+ const std::string &getCode(std::size_t idx) const;
+ const std::string &getPrompt(std::size_t idx) const;
static std::unordered_map<std::string, Menu> menu_lookup;
@@ -60,36 +52,34 @@ class Menu {
Menu(std::string code, std::string prompt)
: code(std::move(code)), title(std::move(prompt)) {}
- static void print(const std::string &entry, const int depth);
- static int display_stub(int idx);
+ struct entries_t {
+ entries_t() = default;
+ entries_t(const entries_t &) = delete;
+ entries_t &operator=(const entries_t &) = delete;
+ entries_t(entries_t &&) = delete;
+ entries_t &operator=(entries_t &&) = delete;
+ ~entries_t() noexcept {
+ for (const auto [_, prompt] : items) {
+ delete[] prompt;
+ }
+ }
+
+ void insert(const std::string &code, const std::string &prompt,
+ callback_f callback = display_stub);
- struct Entries {
struct code_t {
std::string code;
std::string prompt;
};
- ~Entries() {
- for (const auto [_, prompt] : items) {
- delete[] prompt;
- }
- }
-
std::vector<code_t> codes;
std::vector<item_t> items;
-
- void insert(const std::string &code, const std::string &prompt,
- callback_f callback = display_stub) {
- char *buffer = new char[prompt.size() + 1];
- strcpy(buffer, prompt.c_str());
- items.emplace_back(callback, buffer);
-
- codes.emplace_back(code, prompt);
- }
};
const std::string code, title;
- Entries entries;
+ entries_t entries;
+
+ static int display_stub(int idx);
static std::unordered_map<std::string, callback_f> free_lookup;
static std::string display_stub_default;
diff --git a/src/menu.cpp b/src/menu.cpp
@@ -15,48 +15,54 @@ std::unordered_map<std::string, callback_f> Menu::free_lookup;
std::string Menu::display_stub_default;
display_f Menu::display;
+void Menu::entries_t::insert(const std::string &code,
+ const std::string &prompt, callback_f callback) {
+ char *buffer = new char[prompt.size() + 1];
+ strcpy(buffer, prompt.c_str());
+
+ items.emplace_back(callback, buffer);
+ codes.emplace_back(code, prompt);
+}
+
+const std::string &Menu::getCode(std::size_t idx) const {
+ return entries.codes[idx].code;
+}
+
+const std::string &Menu::getPrompt(std::size_t idx) const {
+ return entries.codes[idx].prompt;
+}
+
+callback_f Menu::getCallback(std::size_t idx) const {
+ return entries.items[idx].callback;
+}
+
void Menu::read(const std::string &s) {
std::string line, delim, code, prompt;
std::fstream fs(s);
- char tmp = 0;
auto last = menu_lookup.end();
while (std::getline(fs, line)) {
if (line.empty()) continue;
+
std::istringstream ss(line);
- ss >> delim >> code;
- ss.ignore(1, ' '), std::getline(ss, prompt);
- if (delim == "+") {
+ ss >> delim >> code >> std::ws;
+ std::getline(ss, prompt);
+
+ if (delim != "+") last->second.entries.insert(code, prompt);
+ else {
const auto [iter, succ] = menu_lookup.emplace(
std::piecewise_construct, std::forward_as_tuple(code),
std::forward_as_tuple(private_ctor_t{}, code, prompt));
last = iter;
- } else {
- last->second.entries.insert(code, prompt);
}
}
}
-void Menu::print(const std::string &code, const int depth) {
- const auto it = menu_lookup.find(code);
- if (it == menu_lookup.end()) return;
- const Menu *menu = &it->second;
-
- if (depth == 1) std::cout << std::format("{}({})\n", menu->title, code);
-
- for (int i = 0; i < menu->getSize(); i++) {
- std::cout << std::string(depth << 1, ' ');
- std::cout << menu->getPrompt(i);
- std::cout << std::format(" ({})\n", menu->getCode(i));
- menu->print(code, depth + 1);
- }
-}
-
int Menu::display_stub(int idx) {
static std::deque<const Menu *> st;
const std::string &code =
- st.size() ? st.back()->getCode(idx) : display_stub_default;
+ !st.empty() ? st.back()->getCode(idx) : display_stub_default;
const auto ml_it = menu_lookup.find(code);
if (ml_it != menu_lookup.end()) {
@@ -68,7 +74,7 @@ int Menu::display_stub(int idx) {
}
const auto fl_it = free_lookup.find(code);
- if (fl_it != free_lookup.end()) { return fl_it->second(0); }
+ if (fl_it != free_lookup.end()) return fl_it->second(0);
std::cout << "Stamen: nothing to do..." << std::endl;
return 1;
diff --git a/src/stamen.cpp b/src/stamen.cpp
@@ -7,7 +7,6 @@
#include <ostream>
#include <variant>
-
namespace stamen {
void read(const char *filename) { Menu::read(filename); }
@@ -21,15 +20,14 @@ int dynamic(const char *code, display_f 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));
+ const size_t dgts = size_t(std::log10(size)) + 1;
int choice = 0;
while (true) {
std::cout << std::format("{}:\n", title);
for (auto i = 0ul; i < size; i++) {
- std::cout << std::format(" {:{}}. {}\n", i, digits,
- items[i].prompt);
+ std::cout << std::format(" {:{}}. {}\n", i, dgts, items[i].prompt);
}
while (true) {
@@ -40,20 +38,18 @@ int builtin_display(const char *title, const item_t itemv[], int size) {
return 1;
}
- std::cout << std::format("Choice: {}\n\n",
- items[choice].prompt);
+ std::cout << "Choice: " << items[choice].prompt << "\n\n";
const int res = items[choice].callback(choice);
- if (res > 1) return res - 1;
- else break;
+ if (res < 2) break;
+ return res - 1;
} else if (std::cin.eof()) {
std::cerr << "encountered end of input!\n";
return std::numeric_limits<int>::max();
- } else {
- std::cin.clear();
- std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
- '\n');
}
+
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid option, please choose again!\n";
}
std::cout << std::endl;