[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