+#include <msp/core/algorithm.h>
#include <msp/core/raii.h>
#include <msp/strings/format.h>
#include "except.h"
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);
}
}
{
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)
{
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())
{
auto end = actions->upper_bound(StatementKey(key.keyword, "~"));
if(begin==end)
- throw unknown_keyword(key.keyword);
+ return nullptr;
LoaderAction *act = nullptr;
int match = 0;
}
}
- 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
/** 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 *);
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