]> git.tdb.fi Git - libs/datafile.git/commitdiff
Prefer exact type match when looking for Loader actions
authorMikko Rasa <tdb@tdb.fi>
Mon, 3 Jun 2019 08:16:18 +0000 (11:16 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 3 Jun 2019 08:16:18 +0000 (11:16 +0300)
Previosuly the first matching action in alphabetical signature order was
taken, which causes a float overload to be chosen for an int value even
if an int overload was also available.

source/loader.cpp

index 997e7c9eec27f7f480c711291f6a47f997c7039e..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;
 }
 
 }
@@ -191,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