[Swift-commit] cog r3994
swift at ci.uchicago.edu
swift at ci.uchicago.edu
Thu Jul 3 12:10:03 CDT 2014
------------------------------------------------------------------------
r3994 | timgarmstrong | 2014-07-03 12:09:45 -0500 (Thu, 03 Jul 2014) | 1 line
Basic parsing for coaster settings with escapes and quotes
------------------------------------------------------------------------
Index: modules/provider-coaster-c-client/src/Settings.h
===================================================================
--- modules/provider-coaster-c-client/src/Settings.h (revision 3993)
+++ modules/provider-coaster-c-client/src/Settings.h (working copy)
@@ -34,7 +34,16 @@
void set(const char* key, size_t key_len,
const char* value, size_t value_len);
void remove(const std::string& key);
+
+ bool contains(const std::string& key);
+ /*
+ * Get key from map
+ * returns true if key exists, false if doesn't
+ * value: set to value if key exists
+ */
+ bool get(const std::string& key, std::string &value);
+
std::map<std::string, std::string>& getSettings();
template<typename cls> friend cls& operator<< (cls& os, Settings& s);
Index: modules/provider-coaster-c-client/src/coasters.cpp
===================================================================
--- modules/provider-coaster-c-client/src/coasters.cpp (revision 3993)
+++ modules/provider-coaster-c-client/src/coasters.cpp (working copy)
@@ -127,14 +127,96 @@
}
}
-coaster_rc coaster_settings_parse(coaster_settings *settings,
- const char *str, size_t str_len)
+static void
+settings_emit(coaster_settings *settings, string &key, string &value);
+
+coaster_rc
+coaster_settings_parse(coaster_settings *settings,
+ const char *str, size_t str_len, char separator)
COASTER_THROWS_NOTHING {
+ COASTER_CONDITION(settings != NULL, COASTER_ERROR_INVALID,
+ "Null Coaster settings object");
+ COASTER_CONDITION(str != NULL, COASTER_ERROR_INVALID,
+ "Null Coaster settings string");
+ string key, value; // Storage for current key and value
+
+ bool in_key = true; // Either in key or value
+ bool in_quotes = false;
+ bool in_escape = false;
- // TODO: parsing using code currently in CoasterSwig
- return COASTER_ERROR_UNKNOWN;
+ for (size_t pos = 0; pos < str_len; pos++) {
+ char c = str[pos];
+ string &curr = in_key ? key : value;
+
+ if (in_escape) {
+ // Current character is escaped
+ curr.push_back(c);
+ in_escape = false;
+
+ } else if (in_quotes) {
+ if (c == '\\') {
+ in_escape = true;
+ } else if (c == '"') {
+ in_quotes = false;
+ } else {
+ curr.push_back(c);
+ }
+ } else {
+ // Not in escape or quotes
+ if (c == '\\') {
+ in_escape = true;
+ } else if (c == '"') {
+ in_quotes = true;
+ } else if (c == '=') {
+ COASTER_CONDITION(in_key, COASTER_ERROR_INVALID,
+ "'=' not allowed in unquoted Coaster settings value");
+ in_key = false;
+ } else if (c == separator) {
+ COASTER_CONDITION(!in_key, COASTER_ERROR_INVALID,
+ "',' not allowed in unquoted Coaster settings key");
+
+ settings_emit(settings, key, value);
+
+ in_key = true;
+ } else {
+ curr.push_back(c);
+ }
+ }
+ }
+
+ // Check for invalid state
+ COASTER_CONDITION(!in_escape, COASTER_ERROR_INVALID,
+ "Trailing '\\' escape at end of Coaster settings");
+ COASTER_CONDITION(!in_quotes, COASTER_ERROR_INVALID,
+ "Unclosed '\"' quote at end of Coaster settings");
+ COASTER_CONDITION(!in_key, COASTER_ERROR_INVALID,
+ "Key without value at end of Coaster settings");
+
+ settings_emit(settings, key, value);
+
+ return COASTER_SUCCESS;
}
+
+/*
+ * Helper function to emit completed key/value setting
+ */
+static void
+settings_emit(coaster_settings *settings, string &key, string &value) {
+ if (settings->contains(key)) {
+ string old_value;
+ settings->get(key, old_value);
+ LogWarn << "Overwrote previous Coaster settings value for "
+ "key: \"" << key << "\". Old value: \"" <<
+ old_value << "\", New value: \"" <<
+ value << "\"." << endl;
+ }
+
+ settings->set(key, value);
+ key.clear();
+ value.clear();
+}
+
coaster_rc
coaster_settings_set(coaster_settings *settings,
const char *key, size_t key_len,
Index: modules/provider-coaster-c-client/src/Settings.cpp
===================================================================
--- modules/provider-coaster-c-client/src/Settings.cpp (revision 3993)
+++ modules/provider-coaster-c-client/src/Settings.cpp (working copy)
@@ -60,6 +60,20 @@
settings.erase(key);
}
+bool Settings::contains(const string& key) {
+ return settings.find(key) != settings.end();
+}
+
+bool Settings::get(const string& key, string& value) {
+ map<string, string>::iterator it = settings.find(key);
+ if (settings.find(key) == settings.end()) {
+ return false;
+ } else {
+ value = it->second;
+ return true;
+ }
+}
+
map<string, string>& Settings::getSettings() {
return settings;
}
Index: modules/provider-coaster-c-client/src/coasters.h
===================================================================
--- modules/provider-coaster-c-client/src/coasters.h (revision 3993)
+++ modules/provider-coaster-c-client/src/coasters.h (working copy)
@@ -134,12 +134,14 @@
* Parse settings from string.
*
* str[_len]: String with key/value settings and length of string.
- Settings separated by commas, key/values separated by equals sign.
- If NULL, will create empty settings object.
+ Settings separated by separator char, key/values separated by equals sign.
+ Backslash escapes the next character.
+ Keys and values can be quoted with ".
+ separator: character to separate keys/values
*/
coaster_rc
coaster_settings_parse(coaster_settings *settings, const char *str,
- size_t str_len) COASTER_THROWS_NOTHING;
+ size_t str_len, char separator) COASTER_THROWS_NOTHING;
/*
* Set settings individually.
*/
More information about the Swift-commit
mailing list