mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-18 19:36:00 +01:00
provide enumeration value validation during loading of configuration variables (and other) - if the loaded value isn't a legal enum value, the first registered legal value will be used instead
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@7824 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
13f05dc115
commit
d1771add39
3 changed files with 105 additions and 13 deletions
|
|
@ -24,6 +24,7 @@
|
|||
#include <ostream>
|
||||
|
||||
#include <pbd/xml++.h>
|
||||
#include <pbd/enumwriter.h>
|
||||
|
||||
#include "ardour/utils.h"
|
||||
|
||||
|
|
@ -113,9 +114,9 @@ class ConfigVariable : public ConfigVariableBase
|
|||
if ((prop = child->property ("name")) != 0) {
|
||||
if (prop->value() == _name) {
|
||||
if ((prop = child->property ("value")) != 0) {
|
||||
std::stringstream ss;
|
||||
ss << prop->value();
|
||||
ss >> value;
|
||||
std::stringstream ss;
|
||||
ss << enum_validate (value, prop->value());
|
||||
ss >> value;
|
||||
_owner = (ConfigVariableBase::Owner)(_owner |owner);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -138,12 +139,12 @@ class ConfigVariable : public ConfigVariableBase
|
|||
for (oiter = olist.begin(); oiter != olist.end(); ++oiter) {
|
||||
|
||||
option = *oiter;
|
||||
|
||||
|
||||
if (option->name() == _name) {
|
||||
if ((opt_prop = option->property ("val")) != 0) {
|
||||
std::stringstream ss;
|
||||
ss << opt_prop->value();
|
||||
ss >> value;
|
||||
std::stringstream ss;
|
||||
ss << enum_validate (value, opt_prop->value());
|
||||
ss >> value;
|
||||
_owner = (ConfigVariableBase::Owner)(_owner |owner);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,6 +174,83 @@ EnumWriter::write_distinct (EnumRegistration& er, int value)
|
|||
return string();
|
||||
}
|
||||
|
||||
string
|
||||
EnumWriter::validate_string (EnumRegistration& er, const string& str)
|
||||
{
|
||||
if (er.values.empty()) {
|
||||
return str;
|
||||
}
|
||||
|
||||
vector<int>::iterator i;
|
||||
int val = atoi (str.c_str());
|
||||
|
||||
for (i = er.values.begin(); i != er.values.end(); ++i) {
|
||||
if (*i == val) {
|
||||
return str; /* string is a legal representation of a enumerated value */
|
||||
}
|
||||
}
|
||||
|
||||
string enum_name = _("unknown enumeration");
|
||||
|
||||
for (Registry::iterator x = registry.begin(); x != registry.end(); ++x) {
|
||||
if (&er == &(*x).second) {
|
||||
enum_name = (*x).first;
|
||||
}
|
||||
}
|
||||
|
||||
warning << string_compose (_("Illegal value loaded for %1 (%2) - %3 used instead"),
|
||||
enum_name, val, er.names.front())
|
||||
<< endmsg;
|
||||
|
||||
stringstream ss;
|
||||
ss << er.values.front();
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string
|
||||
EnumWriter::typed_validate (const string& type, const string& value_str)
|
||||
{
|
||||
for (Registry::iterator x = registry.begin(); x != registry.end(); ++x) {
|
||||
if (x->first == type) {
|
||||
return validate_string (x->second, value_str);
|
||||
}
|
||||
}
|
||||
|
||||
/* not a known enum */
|
||||
|
||||
return value_str;
|
||||
}
|
||||
|
||||
int
|
||||
EnumWriter::validate (EnumRegistration& er, int val)
|
||||
{
|
||||
if (er.values.empty()) {
|
||||
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 +263,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 {
|
||||
|
||||
|
|
@ -231,14 +310,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) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __pbd_enumwriter_h__
|
||||
#define __pbd_enumwriter_h__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -45,6 +48,7 @@ class EnumWriter {
|
|||
int read (std::string type, std::string value);
|
||||
|
||||
void add_to_hack_table (std::string str, std::string hacked_str);
|
||||
std::string typed_validate (const std::string& type, const std::string&);
|
||||
|
||||
private:
|
||||
struct EnumRegistration {
|
||||
|
|
@ -68,10 +72,16 @@ class EnumWriter {
|
|||
|
||||
static EnumWriter* _instance;
|
||||
static std::map<std::string,std::string> hack_table;
|
||||
|
||||
int validate (EnumRegistration& er, int value);
|
||||
|
||||
std::string validate_string (EnumRegistration& er, const std::string&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define enum_validate(v,str) PBD::EnumWriter::instance().typed_validate (typeid(v).name(),str)
|
||||
#define enum_2_string(e) (PBD::EnumWriter::instance().write (typeid(e).name(), e))
|
||||
#define string_2_enum(str,e) (PBD::EnumWriter::instance().read (typeid(e).name(), (str)))
|
||||
|
||||
#endif /* __pbd_enumwriter_h__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue