Require quotes around string values in set

This change makes it more consistent with string key values: these also
have to be quoted. It will also help me reuse the leaf_data parser for
the key values.

Change-Id: I5647403648830614d308073be6fb4f1f5469dcb2
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 9f50634..2574019 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -254,7 +254,8 @@
 auto const leaf_data_uint64_def =
     uint64;
 auto const leaf_data_string_def =
-    *char_;
+    '\'' >> *(char_-'\'') >> '\'' |
+    '\"' >> *(char_-'\"') >> '\"';
 
 // This intermediate rule is neccessary for coercing to std::string.
 auto const leaf_data_binary_data_def =
diff --git a/src/utils.cpp b/src/utils.cpp
index cd0858f..d0e8639 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -67,6 +67,8 @@
         return "an identity";
     case yang::LeafDataTypes::LeafRef:
         return "a leafref";
+    case yang::LeafDataTypes::Binary:
+        return "a base64-encoded binary value";
     default:
         throw std::runtime_error("leafDataTypeToString: unsupported leaf data type");
     }
diff --git a/tests/leaf_editing.cpp b/tests/leaf_editing.cpp
index ab5e6bd..d7703c0 100644
--- a/tests/leaf_editing.cpp
+++ b/tests/leaf_editing.cpp
@@ -58,32 +58,48 @@
     {
         set_ expected;
 
-        SECTION("set mod:leafString some_data")
+        SECTION("set mod:leafString \"some_data\"")
         {
-            input = "set mod:leafString some_data";
+            input = "set mod:leafString \'some_data\'";
             expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
             expected.m_data = std::string("some_data");
         }
 
-        SECTION("set mod:contA/leafInCont more_data")
+        SECTION("set mod:contA/leafInCont 'more_data'")
         {
-            input = "set mod:contA/leafInCont more_data";
+            input = "set mod:contA/leafInCont 'more_data'";
             expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
             expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
             expected.m_data = std::string("more_data");
         }
 
-        SECTION("set mod:contA/leafInCont   more   d\tata") // spaces in string
+        SECTION("set mod:contA/leafInCont \"data with' a quote\"")
         {
-            input = "set mod:contA/leafInCont more   d\tata";
+            input = "set mod:contA/leafInCont \"data with' a quote\"";
+            expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
+            expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
+            expected.m_data = std::string("data with' a quote");
+        }
+
+        SECTION("set mod:contA/leafInCont 'data with\" a quote'")
+        {
+            input = "set mod:contA/leafInCont 'data with\" a quote'";
+            expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
+            expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
+            expected.m_data = std::string("data with\" a quote");
+        }
+
+        SECTION("set mod:contA/leafInCont   'more   d\tata'") // spaces in string
+        {
+            input = "set mod:contA/leafInCont 'more   d\tata'";
             expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
             expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
             expected.m_data = std::string("more   d\tata");
         }
 
-        SECTION("set mod:list[number=1]/leafInList another_data")
+        SECTION("set mod:list[number=1]/leafInList \"another_data\"")
         {
-            input = "set mod:list[number=1]/leafInList another_data";
+            input = "set mod:list[number=1]/leafInList \"another_data\"";
             auto keys = std::map<std::string, std::string>{
                 {"number", "1"}};
             expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
@@ -95,7 +111,7 @@
         {
             SECTION("string")
             {
-                input = "set mod:leafString somedata";
+                input = "set mod:leafString \"somedata\"";
                 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
                 expected.m_data = std::string("somedata");
             }
@@ -285,7 +301,7 @@
             {
                 SECTION("refToString")
                 {
-                    input = "set mod:refToString blabal";
+                    input = "set mod:refToString \"blabal\"";
                     expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("refToString")});
                     expected.m_data = std::string("blabal");
                 }
@@ -311,85 +327,85 @@
         {
             SECTION("setmod:leafString some_data")
             {
-                input = "setmod:leafString some_data";
+                input = "setmod:leafString 'some_data'";
             }
         }
 
         SECTION("missing space between arguments")
         {
-            SECTION("set mod:leafStringlol")
+            SECTION("set mod:leafString'lol'")
             {
-                input = "set mod:leafStringlol";
+                input = "set mod:leafString'lol'";
             }
         }
 
         SECTION("non-leaf identifiers")
         {
-            SECTION("set mod:nonexistent blabla")
+            SECTION("set mod:nonexistent 'blabla'")
             {
-                input = "set mod:nonexistent blabla";
+                input = "set mod:nonexistent 'blabla'";
             }
 
-            SECTION("set mod:contA abde")
+            SECTION("set mod:contA 'abde'")
             {
-                input = "set mod:contA abde";
+                input = "set mod:contA 'abde'";
             }
         }
 
         SECTION("wrong types")
         {
             expectedError = "leaf data type mismatch";
-            SECTION("set mod:leafBool blabla")
+            SECTION("set mod:leafBool 'blabla'")
             {
-                input = "set mod:leafBool blabla";
+                input = "set mod:leafBool 'blabla'";
             }
-            SECTION("set mod:leafUint8 blabla")
+            SECTION("set mod:leafUint8 'blabla'")
             {
-                input = "set mod:leafUint8 blabla";
+                input = "set mod:leafUint8 'blabla'";
             }
             SECTION("set mod:leafUint8 -5")
             {
                 input = "set mod:leafUint8 -5";
             }
-            SECTION("set mod:leafInt8 blabla")
+            SECTION("set mod:leafInt8 'blabla'")
             {
-                input = "set mod:leafInt8 blabla";
+                input = "set mod:leafInt8 'blabla'";
             }
             SECTION("set mod:leafInt8 130")
             {
                 input = "set mod:leafInt8 130";
             }
-            SECTION("set mod:leafUint16 blabla")
+            SECTION("set mod:leafUint16 'blabla'")
             {
-                input = "set mod:leafUint16 blabla";
+                input = "set mod:leafUint16 'blabla'";
             }
-            SECTION("set mod:leafInt16 blabla")
+            SECTION("set mod:leafInt16 'blabla'")
             {
-                input = "set mod:leafInt16 blabla";
+                input = "set mod:leafInt16 'blabla'";
             }
-            SECTION("set mod:leafUint32 blabla")
+            SECTION("set mod:leafUint32 'blabla'")
             {
-                input = "set mod:leafUint32 blabla";
+                input = "set mod:leafUint32 'blabla'";
             }
-            SECTION("set mod:leafInt32 blabla")
+            SECTION("set mod:leafInt32 'blabla'")
             {
-                input = "set mod:leafInt32 blabla";
+                input = "set mod:leafInt32 'blabla'";
             }
-            SECTION("set mod:leafUint64 blabla")
+            SECTION("set mod:leafUint64 'blabla'")
             {
-                input = "set mod:leafUint64 blabla";
+                input = "set mod:leafUint64 'blabla'";
             }
-            SECTION("set mod:leafInt64 blabla")
+            SECTION("set mod:leafInt64 'blabla'")
             {
-                input = "set mod:leafInt64 blabla";
+                input = "set mod:leafInt64 'blabla'";
             }
-            SECTION("set mod:leafEnum blabla")
+            SECTION("set mod:leafEnum 'blabla'")
             {
-                input = "set mod:leafEnum blabla";
+                input = "set mod:leafEnum 'blabla'";
             }
-            SECTION("set mod:refToInt8 blabla")
+            SECTION("set mod:refToInt8 'blabla'")
             {
-                input = "set mod:refToInt8 blabla";
+                input = "set mod:refToInt8 'blabla'";
             }
         }
 
@@ -399,6 +415,8 @@
                 input = "set mod:leafBinary dbahj-";
             SECTION("equal sign in the middle")
                 input = "set mod:leafBinary db=ahj";
+            SECTION("enclosing in quotes")
+                input = "set mod:leafBinary 'dbahj'";
         }
 
         SECTION("non-existing identity")