]> git.tdb.fi Git - libs/datafile.git/commitdiff
Refactor handling of actions in Loader
authorMikko Rasa <tdb@tdb.fi>
Wed, 6 Sep 2023 12:05:42 +0000 (15:05 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 6 Sep 2023 12:05:42 +0000 (15:05 +0300)
Auxiliary loaders now work with the binary format and the flow control
structures are more clear in general.

source/loader.cpp
source/loader.h
source/loaderaction.h

index 7e910b8a73c5d79adc63b161a2e01248edf50211..8f443c3ce038c978643b4e753e40417aaddb41b8 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/core/algorithm.h>
 #include <msp/core/raii.h>
 #include <msp/strings/format.h>
 #include "except.h"
@@ -92,15 +93,16 @@ void Loader::load_direct(Parser &p, unsigned l)
                if(!key)
                        break;
 
-               LoaderAction *act = find_action(*key);
-               if(act)
+               if(LoaderAction *act = find_action(*key))
                {
                        SetFlag set_direct(direct);
                        if(!p.parse_and_load(l, *this, *act))
                                throw logic_error("direct load failed");
                }
+               else if(Loader *ldr = find_auxiliary_loader(*key))
+                       ldr->load_direct(p, l);
                else
-                       load_statement(p.parse());
+                       unrecognized(*key);
        }
 }
 
@@ -112,21 +114,17 @@ void Loader::load_statement(const Statement &st)
        {
                StatementKey key(st.keyword, st.get_signature());
 
-               if(!aux_loaders.empty() && !has_action(key))
-               {
-                       for(Loader *l: aux_loaders)
-                               if(l->has_action(key))
-                                       return l->load_statement(st);
-               }
-
-               LoaderAction *act = find_action(key);
-               if(act)
+               if(LoaderAction *act = find_action(key))
                {
                        sub_loaded = false;
                        act->execute(*this, st);
                        if(check_sub_loads && !st.sub.empty() && !sub_loaded)
                                throw logic_error("substatements ignored");
                }
+               else if(Loader *ldr = find_auxiliary_loader(key))
+                       ldr->load_statement(st);
+               else
+                       unrecognized(key);
        }
        catch(const data_error &e)
        {
@@ -174,7 +172,7 @@ void Loader::add(const string &kwd, LoaderAction *act)
        if(!actions)
                actions = &local_actions;
 
-       StatementKey key(kwd, (act ? act->get_signature() : "*"));
+       StatementKey key(kwd, act->get_signature());
        ActionMap::iterator i = actions->find(key);
        if(i!=actions->end())
        {
@@ -211,7 +209,7 @@ LoaderAction *Loader::find_action(const StatementKey &key) const
        auto end = actions->upper_bound(StatementKey(key.keyword, "~"));
 
        if(begin==end)
-               throw unknown_keyword(key.keyword);
+               return nullptr;
 
        LoaderAction *act = nullptr;
        int match = 0;
@@ -225,10 +223,25 @@ LoaderAction *Loader::find_action(const StatementKey &key) const
                }
        }
 
-       if(!match)
+       return act;
+}
+
+Loader *Loader::find_auxiliary_loader(const StatementKey &key) const
+{
+       auto i = find_if(aux_loaders, [&key](Loader *l){ return l->has_action(key); });
+       return (i!=aux_loaders.end() ? *i : nullptr);
+}
+
+void Loader::unrecognized(const StatementKey &key) const
+{
+       if(!actions)
+               throw logic_error("no actions");
+
+       auto i = actions->lower_bound(StatementKey(key.keyword, string()));
+       if(i!=actions->end() && i->first.keyword==key.keyword)
                throw invalid_signature(key.keyword, key.signature);
 
-       return act;
+       throw unknown_keyword(key.keyword);
 }
 
 const string &Loader::get_source() const
index 5b96cb0954812f2f17ec1d01e4b1260f8c0cf2a4..59ebc2304c96cce8bb32f01c2199457b1b107278 100644 (file)
@@ -135,7 +135,7 @@ protected:
 
        /** Adds a keyword that is recognized but ignored. */
        void add(const std::string &k)
-       { add(k, nullptr); }
+       { add(k, new LoaderDiscard); }
 
 private:
        void add(const std::string &, LoaderAction *);
@@ -146,6 +146,8 @@ protected:
 private:
        bool has_action(const StatementKey &) const;
        LoaderAction *find_action(const StatementKey &) const;
+       Loader *find_auxiliary_loader(const StatementKey &) const;
+       void unrecognized(const StatementKey &) const;
 
 protected:
        /** Returns the source of the statement being processed.  This can be used
index 9e08dac59edea834323c158e4807dba3ff3e61f2..0c56eab0292e3201d36503e7b30cad332532c424 100644 (file)
@@ -37,6 +37,15 @@ public:
 };
 
 
+class LoaderDiscard: public LoaderAction
+{
+public:
+       void execute(Loader &, const Statement &) const override { }
+       void execute(Loader &, const ArgumentStore &) const override { }
+       std::string get_signature() const override { return "*"; };
+};
+
+
 /**
 Loads a statement by calling a function that takes no arguments.
 */