for windows build, add fallback_folders.cc to libpbd source list
[ardour.git] / libs / pbd / enumwriter.cc
index 134a00a20746cb2057c0a60a3329b10d38633a4e..6d911b2dea7c540198bf559ed603ed3f524b06ff 100644 (file)
@@ -63,11 +63,25 @@ nocase_cmp(const string & s1, const string& s2)
        return (size1 < size2) ? -1 : 1;
 }
 
-EnumWriter::EnumWriter ()
+EnumWriter&
+EnumWriter::instance() 
 {
        if (_instance == 0) {
-               _instance = this;
-       }
+               _instance = new EnumWriter;
+       } 
+
+       return *_instance;
+}
+
+void
+EnumWriter::destroy ()
+{
+       delete _instance;
+       _instance = 0;
+}
+
+EnumWriter::EnumWriter ()
+{
 }
 
 EnumWriter::~EnumWriter ()
@@ -113,7 +127,7 @@ EnumWriter::write (string type, int value)
 
        if (x == registry.end()) {
                error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg;
-               throw unknown_enumeration();
+               throw unknown_enumeration (type);
        }
 
        if (x->second.bitwise) {
@@ -130,7 +144,7 @@ EnumWriter::read (string type, string value)
 
        if (x == registry.end()) {
                error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg;
-               throw unknown_enumeration();
+               throw unknown_enumeration (type);
        }
 
        if (x->second.bitwise) {
@@ -174,6 +188,41 @@ EnumWriter::write_distinct (EnumRegistration& er, int value)
        return string();
 }
 
+int
+EnumWriter::validate (EnumRegistration& er, int val)
+{
+        if (er.values.empty()) {
+                return val;
+        }
+
+        if (val == 0) {
+                /* zero is always a legal value for our enumerations, just about
+                 */
+                return val;
+        }
+
+        vector<int>::iterator i;
+        string enum_name = _("unknown enumeration");
+        
+        for (Registry::iterator x = registry.begin(); x != registry.end(); ++x) {
+                if (&er == &(*x).second) {
+                        enum_name = (*x).first;
+                }
+        }
+        
+
+        for (i = er.values.begin(); i != er.values.end(); ++i) {
+                if (*i == val) {
+                        return val;
+                }
+        }
+        
+        warning << string_compose (_("Illegal value loaded for %1 (%2) - %3 used instead"),
+                                   enum_name, val, er.names.front()) 
+                << endmsg;
+        return er.values.front();
+}
+
 int
 EnumWriter::read_bits (EnumRegistration& er, string str)
 {
@@ -186,14 +235,16 @@ EnumWriter::read_bits (EnumRegistration& er, string str)
        /* catch old-style hex numerics */
 
        if (str.length() > 2 && str[0] == '0' && str[1] == 'x') {
-               return strtol (str.c_str(), (char **) 0, 16);
+               int val = strtol (str.c_str(), (char **) 0, 16);
+                return validate (er, val);
        }
 
        /* catch old style dec numerics */
 
        if (strspn (str.c_str(), "0123456789") == str.length()) {
-               return strtol (str.c_str(), (char **) 0, 10);
-       }
+               int val = strtol (str.c_str(), (char **) 0, 10);
+                return validate (er, val);
+        }
 
        do {
                
@@ -216,7 +267,7 @@ EnumWriter::read_bits (EnumRegistration& er, string str)
        } while (true);
 
        if (!found) {
-               throw unknown_enumeration();
+               throw unknown_enumeration (str);
        }
 
        return result;
@@ -231,14 +282,16 @@ EnumWriter::read_distinct (EnumRegistration& er, string str)
        /* catch old-style hex numerics */
 
        if (str.length() > 2 && str[0] == '0' && str[1] == 'x') {
-               return strtol (str.c_str(), (char **) 0, 16);
+               int val = strtol (str.c_str(), (char **) 0, 16);
+                return validate (er, val);
        }
 
        /* catch old style dec numerics */
 
        if (strspn (str.c_str(), "0123456789") == str.length()) {
-               return strtol (str.c_str(), (char **) 0, 10);
-       }
+               int val = strtol (str.c_str(), (char **) 0, 10);
+                return validate (er, val);
+        }
 
        for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) {
                if (str == (*s) || nocase_cmp (str, *s) == 0) {
@@ -263,7 +316,7 @@ EnumWriter::read_distinct (EnumRegistration& er, string str)
                }
        }
 
-       throw unknown_enumeration();
+       throw unknown_enumeration(str);
 }
 
 void