]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/loader.cpp
Prefer exact type match when looking for Loader actions
[libs/datafile.git] / source / loader.cpp
index 4bc715aff01597c4164f19b206f5a31ae8db87fb..a05e5f0dfe187b0060cd307f21146d7f199dbb55 100644 (file)
@@ -8,37 +8,37 @@ using namespace std;
 
 namespace {
 
-bool signature_match(char s, char a)
+int signature_match(char s, char a)
 {
        if(s==a)
-               return true;
+               return 3;
        if(s==Msp::DataFile::IntType::signature && a==Msp::DataFile::FloatType::signature)
-               return true;
-       return false;
+               return 1;
+       return 0;
 }
 
-bool signature_match(const string &st_sig, const string &act_sig)
+int signature_match(const string &st_sig, const string &act_sig)
 {
        if(act_sig=="*")
-               return true;
+               return 1;
        else if(act_sig.size()==2 && act_sig[1]=='*')
        {
-               for(string::const_iterator i=st_sig.begin(); i!=st_sig.end(); ++i)
-                       if(!signature_match(*i, act_sig[0]))
-                               return false;
+               int match = 3;
+               for(string::const_iterator i=st_sig.begin(); (i!=st_sig.end() && match); ++i)
+                       match = min(match, signature_match(*i, act_sig[0]));
 
-               return true;
+               return match;
        }
        else if(st_sig.size()==act_sig.size())
        {
-               for(unsigned i=0; i<st_sig.size(); ++i)
-                       if(!signature_match(st_sig[i], act_sig[i]))
-                               return false;
+               int match = 3;
+               for(unsigned i=0; (i<st_sig.size() && match); ++i)
+                       match = min(match, signature_match(st_sig[i], act_sig[i]));
 
-               return true;
+               return match ? match+1 : 0;
        }
        else
-               return false;
+               return 0;
 }
 
 }
@@ -47,28 +47,6 @@ bool signature_match(const string &st_sig, const string &act_sig)
 namespace Msp {
 namespace DataFile {
 
-class unknown_keyword: public runtime_error
-{
-public:
-       unknown_keyword(const std::string &k):
-               runtime_error(k)
-       { }
-
-       virtual ~unknown_keyword() throw() { }
-};
-
-
-class invalid_signature: public runtime_error
-{
-public:
-       invalid_signature(const std::string &k, const std::string &s):
-               runtime_error(format("%s %s", k, s))
-       { }
-
-       virtual ~invalid_signature() throw() { }
-};
-
-
 Loader::Loader():
        cur_st(0),
        direct(false),
@@ -213,11 +191,22 @@ LoaderAction *Loader::find_action(const StatementKey &key) const
        if(begin==end)
                throw unknown_keyword(key.keyword);
 
+       LoaderAction *act = 0;
+       int match = 0;
        for(ActionMap::const_iterator i=begin; i!=end; ++i)
-               if(signature_match(key.signature, i->first.signature))
-                       return i->second;
+       {
+               int m = signature_match(key.signature, i->first.signature);
+               if(m>match)
+               {
+                       act = i->second;
+                       match = m;
+               }
+       }
+
+       if(!act)
+               throw invalid_signature(key.keyword, key.signature);
 
-       throw invalid_signature(key.keyword, key.signature);
+       return act;
 }
 
 const string &Loader::get_source() const
@@ -227,5 +216,12 @@ const string &Loader::get_source() const
        return cur_st->source;
 }
 
+const string &Loader::get_keyword() const
+{
+       if(!cur_st)
+               throw logic_error("no current statement");
+       return cur_st->keyword;
+}
+
 } // namespace DataFile
 } // namespace Msp