stamenStatic Menu Generator | 
          
| git clone git://git.dimitrijedobrota.com/stamen.git | 
| Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
stamen.cpp (2524B)
    0 #include <cstddef>
              1 #include <iostream>
              2 #include <sstream>
              3 #include <string>
              4 #include <unordered_set>
              5 #include <utility>
          
              7 #include "stamen/stamen.hpp"
          
              9 namespace {
          
             11 void warning(const std::string& message, const std::string& addition)
             12 {
             13   std::cerr << "Stamen: " << message;
             14   if (!addition.empty())
             15   {
             16     std::cerr << ":  " + addition;
             17   }
             18   std::cerr << '\n' << std::flush;
             19 }
          
             21 }  // namespace
          
             23 namespace stamen {
          
             25 Stamen::Stamen(std::istream& ist)
             26 {
             27   using namespace std::placeholders;  // NOLINT
          
             29   std::unordered_set<std::string> refd;
             30   std::string line;
             31   std::string delim;
             32   std::string code;
             33   std::string prompt;
          
             35   auto last = m_menu_lookup.end();
             36   while (std::getline(ist, line))
             37   {
             38     if (line.empty()) continue;
          
             40     std::istringstream iss(line);
             41     iss >> delim >> code >> std::ws;
             42     std::getline(iss, prompt);
          
             44     if (delim != "+")
             45     {
             46       last->second.insert(code,
             47                           prompt,
             48                           [&](std::size_t idx)
             49                           { return this->display_stub(idx); });
             50       refd.insert(code);
             51     }
             52     else
             53     {
             54       const auto [iter, succ] =
             55           m_menu_lookup.emplace(code, Menu(code, prompt));
             56       last = iter;
             57     }
             58   }
          
             60   for (const auto& ref : refd)
             61   {
             62     if (!m_menu_lookup.contains(ref))
             63     {
             64       m_free_lookup.emplace(ref, nullptr);
             65     }
             66   }
             67 }
          
             69 void Stamen::insert(const std::string& code, const callback_f& callback)
             70 {
             71   auto itr = m_free_lookup.find(code);
             72   if (itr == m_free_lookup.end())
             73   {
             74     warning("unknown callback registration", code);
             75     return;
             76   }
             77   itr->second = callback;
             78 }
          
             80 int Stamen::dynamic(const std::string& code, const display_f& disp)
             81 {
             82   m_stub_default = code;
             83   m_stub_display = disp;
             84   return display_stub(0);
             85 }
          
             87 int Stamen::display_stub(std::size_t idx)
             88 {
             89   const std::string& code = !m_stub_stack.empty()
             90       ? m_stub_stack.top()->item(idx).code
             91       : m_stub_default;
          
             93   const auto mit = m_menu_lookup.find(code);
             94   if (mit != m_menu_lookup.end())
             95   {
             96     m_stub_stack.push(&mit->second);
             97     const int ret = m_stub_display(mit->second);
             98     m_stub_stack.pop();
          
            100     return ret;
            101   }
          
            103   const auto fit = m_free_lookup.find(code);
            104   if (fit != m_free_lookup.end() && fit->second != nullptr)
            105   {
            106     return fit->second(0);
            107   }
          
            109   warning("no callback for", code);
          
            111   return 1;
            112 }
          
            114 void Menu::insert(const std::string& code,
            115                     const std::string& prompt,
            116                     const callback_f& callback)
            117 {
            118   m_items.emplace_back(code, prompt, callback);
            119 }
          
            121 }  // namespace stamen