diff options
author | David Robillard <d@drobilla.net> | 2007-10-22 03:46:46 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-10-22 03:46:46 +0000 |
commit | 282ad28ebe5217bec8039e6417bc518680f910e2 (patch) | |
tree | 90e8573758ebb197d3faa7ecc8391f5d446471e5 | |
parent | 58ceeae7457f03b60fdc5a491b36abb2aa6d9e8a (diff) | |
download | raul-282ad28ebe5217bec8039e6417bc518680f910e2.tar.gz raul-282ad28ebe5217bec8039e6417bc518680f910e2.tar.bz2 raul-282ad28ebe5217bec8039e6417bc518680f910e2.zip |
Stricter limitations for path symbols/names (C symbols, equivalent to lv2:symbol, subset of OSC addresses and URIs).
git-svn-id: http://svn.drobilla.net/lad/raul@897 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | src/Path.cpp | 79 | ||||
-rw-r--r-- | tests/path_test.cpp | 19 |
2 files changed, 75 insertions, 23 deletions
diff --git a/src/Path.cpp b/src/Path.cpp index 96dad69..284cf16 100644 --- a/src/Path.cpp +++ b/src/Path.cpp @@ -27,11 +27,11 @@ Path::is_valid(const std::basic_string<char>& path) return false; // Must start with a / - if (path.at(0) != '/') + if (path[0] != '/') return false; // Must not end with a slash unless "/" - if (path.length() > 1 && path.at(path.length()-1) == '/') + if (path.length() > 1 && path[path.length()-1] == '/') return false; assert(path.find_last_of("/") != string::npos); @@ -40,11 +40,17 @@ Path::is_valid(const std::basic_string<char>& path) if (path.find("//") != string::npos) return false; - // All characters must be printable ASCII + // All characters must be _, a-z, A-Z, 0-9 for (size_t i=0; i < path.length(); ++i) - if (path.at(i) < 32 || path.at(i) > 126) + if ( path[i] != '/' && path[i] != '_' + && (path[i] < 'a' || path[i] > 'z') + && (path[i] < 'A' || path[i] > 'Z') + && (path[i] < '0' || path[i] > '9') ) return false; + // FIXME: first character can't be number? + +#if 0 // Disallowed characters if ( path.find(" ") != string::npos || path.find("#") != string::npos @@ -56,6 +62,7 @@ Path::is_valid(const std::basic_string<char>& path) || path.find("{") != string::npos || path.find("}") != string::npos) return false; +#endif return true; } @@ -102,7 +109,7 @@ Path::nameify(const std::basic_string<char>& str) string name = str; if (name.length() == 0) - return "."; // this might not be wise + return "_"; // this might not be wise replace_invalid_chars(name, true); @@ -113,14 +120,11 @@ Path::nameify(const std::basic_string<char>& str) /** Replace any invalid characters in @a str with a suitable replacement. - * - * Makes a pretty name - underscores are a valid character, but this chops - * both spaces and underscores, uppercasing the next letter, to create - * uniform CamelCase names that look nice */ void Path::replace_invalid_chars(string& str, bool replace_slash) { +#if 0 for (size_t i=0; i < str.length(); ++i) { if (str[i] == ' ' || str[i] == '_') { str[i+1] = std::toupper(str[i+1]); // capitalize next char @@ -139,22 +143,55 @@ Path::replace_invalid_chars(string& str, bool replace_slash) str[i] = '.'; } } +#endif - // Chop brackets - // No, ruins uniqueness (LADSPA plugins) - /*while (true) { + size_t open_bracket = str.find_first_of('('); + if (open_bracket != string::npos) + str = str.substr(0, open_bracket-1); + + open_bracket = str.find_first_of('['); + if (open_bracket != string::npos) + str = str.substr(0, open_bracket-1); + + // dB = special case, need to avoid CamelCase killing below + while (true) { + size_t decibels = str.find("dB"); + if (decibels != string::npos) + str[decibels+1] = 'b'; + else + break; + } - const string::size_type open = str.find("("); - const string::size_type close = str.find(")"); - if (open != string::npos) { - if (close != string::npos) - str.erase(open, (close - open) + 1); - } else { - break; + // Kill CamelCase in favour of god_fearing_symbol_names + for (size_t i=1; i < str.length(); ++i) { + if (str[i] >= 'A' && str[i] <= 'Z' && str[i-1] >= 'a' && str[i-1] <= 'z') { + //str[i] = std::tolower(str[i]); + str = str.substr(0, i) + '_' + str.substr(i); } - - }*/ + } + + for (size_t i=0; i < str.length(); ++i) { + if (str[i] == '\'') { + str = str.substr(0, i) + str.substr(i+1); + } else if (str[i] >= 'A' && str[i] <= 'Z') { + str[i] = std::tolower(str[i]); + } else if ( str[i] != '_' && str[i] != '/' + && (str[i] < 'a' || str[i] > 'z') + && (str[i] < '0' || str[i] > '9') ) { + if (i > 0 && str[i-1] == '_') { + str = str.substr(0, i) + str.substr(i+1); + --i; + } else { + str[i] = '_'; + } + } else if (replace_slash && str[i] == '/') { + str[i] = '_'; + } + } + + if (str[str.length()-1] == '_') + str = str.substr(0, str.length()-1); } diff --git a/tests/path_test.cpp b/tests/path_test.cpp index c5c4415..8f33dee 100644 --- a/tests/path_test.cpp +++ b/tests/path_test.cpp @@ -1,4 +1,5 @@ #include <iostream> +#include <list> #include <raul/Path.hpp> using namespace std; @@ -7,14 +8,28 @@ using namespace Raul; int main() { + list<string> names; + names.push_back("foo+1bar(baz)"); + names.push_back("ThisCRAR"); + names.push_back("NAME"); + names.push_back("thing with a bunch of spaces"); + names.push_back("thing-with-a-bunch-of-dashes"); + names.push_back("CamelCaseABC"); + names.push_back("Signal Level [dB]"); + names.push_back("Gain dB"); + names.push_back("Dry/Wet Balance"); + names.push_back("Phaser1 - Similar to CSound's phaser1 by Sean Costello"); + + cerr << "Nameification:" << endl; + for (list<string>::iterator i = names.begin(); i != names.end(); ++i) + cerr << *i << " -> " << Path::nameify(*i) << endl; + cerr << "1's are good..." << endl << endl; cerr << (Path("/").is_parent_of(Path("/foo"))) << endl; cerr << (Path("/foo").is_parent_of(Path("/foo/bar"))) << endl; cerr << !(Path("/foo").is_parent_of(Path("/foo2"))) << endl; - cerr << Path::nameify("Signal Level [dB]") << endl; - cerr << endl << endl << "Descendants..." << endl; cerr << "/ /foo " << Path::descendant_comparator("/", "/foo") << endl; cerr << "/foo /foo/bar " << Path::descendant_comparator("/foo", "/foo/bar") << endl; |