Browse Source

string(JSON): Add GET_RAW mode

Kyle Edwards 2 months ago
parent
commit
15973ff247

+ 11 - 1
Help/command/string.rst

@@ -46,7 +46,7 @@ Synopsis
 
 
   `JSON`_
   `JSON`_
     string(JSON <out-var> [ERROR_VARIABLE <error-var>]
     string(JSON <out-var> [ERROR_VARIABLE <error-var>]
-           {`GET <JSON-GET_>`__ | `TYPE <JSON-TYPE_>`__ | `LENGTH <JSON-LENGTH_>`__ | `REMOVE <JSON-REMOVE_>`__}
+           {`GET <JSON-GET_>`__ | `GET_RAW <JSON-GET-RAW_>`__ | `TYPE <JSON-TYPE_>`__ | `LENGTH <JSON-LENGTH_>`__ | `REMOVE <JSON-REMOVE_>`__}
            <json-string> <member|index> [<member|index> ...])
            <json-string> <member|index> [<member|index> ...])
     string(JSON <out-var> [ERROR_VARIABLE <error-var>]
     string(JSON <out-var> [ERROR_VARIABLE <error-var>]
            `MEMBER <JSON-MEMBER_>`__ <json-string>
            `MEMBER <JSON-MEMBER_>`__ <json-string>
@@ -559,6 +559,16 @@ string is passed as a single argument even if it contains semicolons.
   Null elements will be returned as an empty string.
   Null elements will be returned as an empty string.
   Number and string types will be returned as strings.
   Number and string types will be returned as strings.
 
 
+.. signature::
+  string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
+         GET_RAW <json-string> <member|index> [<member|index> ...])
+  :target: JSON-GET-RAW
+
+  Get an element from ``<json-string>`` at the location given
+  by the list of ``<member|index>`` arguments. Similar to
+  `GET <JSON-GET_>`__, but does not convert number, string,
+  boolean, or null elements.
+
 .. signature::
 .. signature::
   string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
   string(JSON <out-var> [ERROR_VARIABLE <error-variable>]
          TYPE <json-string> <member|index> [<member|index> ...])
          TYPE <json-string> <member|index> [<member|index> ...])

+ 4 - 0
Help/release/dev/string-json-improvements.rst

@@ -0,0 +1,4 @@
+string-json-improvements
+------------------------
+
+* The :command:`string(JSON)` command gained a new ``GET_RAW`` mode.

+ 11 - 7
Source/cmStringCommand.cxx

@@ -952,13 +952,13 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
     }
     }
 
 
     auto const& mode = args.PopFront("missing mode argument"_s);
     auto const& mode = args.PopFront("missing mode argument"_s);
-    if (mode != "GET"_s && mode != "TYPE"_s && mode != "MEMBER"_s &&
-        mode != "LENGTH"_s && mode != "REMOVE"_s && mode != "SET"_s &&
-        mode != "EQUAL"_s) {
-      throw json_error(
-        cmStrCat("got an invalid mode '"_s, mode,
-                 "', expected one of GET, TYPE, MEMBER, LENGTH, REMOVE, SET, "
-                 " EQUAL"_s));
+    if (mode != "GET"_s && mode != "GET_RAW"_s && mode != "TYPE"_s &&
+        mode != "MEMBER"_s && mode != "LENGTH"_s && mode != "REMOVE"_s &&
+        mode != "SET"_s && mode != "EQUAL"_s) {
+      throw json_error(cmStrCat(
+        "got an invalid mode '"_s, mode,
+        "', expected one of GET, GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, "
+        " EQUAL"_s));
     }
     }
 
 
     auto const& jsonstr = args.PopFront("missing json string argument"_s);
     auto const& jsonstr = args.PopFront("missing json string argument"_s);
@@ -974,6 +974,10 @@ bool HandleJSONCommand(std::vector<std::string> const& arguments,
         makefile.AddDefinition(*outputVariable, value.asString());
         makefile.AddDefinition(*outputVariable, value.asString());
       }
       }
 
 
+    } else if (mode == "GET_RAW"_s) {
+      auto const& value = ResolvePath(json, args);
+      makefile.AddDefinition(*outputVariable, WriteJson(value));
+
     } else if (mode == "TYPE"_s) {
     } else if (mode == "TYPE"_s) {
       auto const& value = ResolvePath(json, args);
       auto const& value = ResolvePath(json, args);
       makefile.AddDefinition(*outputVariable, JsonTypeToString(value.type()));
       makefile.AddDefinition(*outputVariable, JsonTypeToString(value.type()));

+ 21 - 1
Tests/RunCMake/string/JSON.cmake

@@ -65,6 +65,9 @@ set(json1 [=[
     "false" : false,
     "false" : false,
     "true" : true
     "true" : true
   },
   },
+  "object": {
+    "foo": "bar"
+  },
   "special" : {
   "special" : {
     "foo;bar" : "value1",
     "foo;bar" : "value1",
     ";" : "value2",
     ";" : "value2",
@@ -90,6 +93,7 @@ set(json1 [=[
 }
 }
 ]=])
 ]=])
 
 
+# test GET
 string(JSON result GET "${json1}" foo)
 string(JSON result GET "${json1}" foo)
 assert_strequal("${result}" bar)
 assert_strequal("${result}" bar)
 string(JSON result GET "${json1}" array 0)
 string(JSON result GET "${json1}" array 0)
@@ -200,6 +204,22 @@ string(JSON char ERROR_VARIABLE error GET "${unicode}" datalinkescape)
 string(JSON result ERROR_VARIABLE error GET "${unicode}" "${char}")
 string(JSON result ERROR_VARIABLE error GET "${unicode}" "${char}")
 assert_strequal_error("${result}" "datalinkescape" "${error}")
 assert_strequal_error("${result}" "datalinkescape" "${error}")
 
 
+# Test GET_RAW
+string(JSON result GET_RAW "${json1}" values null)
+assert_strequal("${result}" null)
+string(JSON result GET_RAW "${json1}" values number)
+assert_strequal("${result}" 5)
+string(JSON result GET_RAW "${json1}" values string)
+assert_strequal("${result}" "\"foo\"")
+string(JSON result GET_RAW "${json1}" values false)
+assert_strequal("${result}" false)
+string(JSON result GET_RAW "${json1}" values true)
+assert_strequal("${result}" true)
+string(JSON result ERROR_VARIABLE error GET_RAW "${json1}" array)
+assert_json_equal("${error}" "${result}" [=[ [5, "val", {"some": "other"}, null] ]=])
+string(JSON result ERROR_VARIABLE error GET_RAW "${json1}" object)
+assert_json_equal("${error}" "${result}" [=[ { "foo": "bar" } ]=])
+
 # Test TYPE
 # Test TYPE
 string(JSON result TYPE "${json1}" types null)
 string(JSON result TYPE "${json1}" types null)
 assert_strequal("${result}" NULL)
 assert_strequal("${result}" NULL)
@@ -216,7 +236,7 @@ assert_strequal("${result}" OBJECT)
 
 
 # Test LENGTH
 # Test LENGTH
 string(JSON result ERROR_VARIABLE error LENGTH "${json1}")
 string(JSON result ERROR_VARIABLE error LENGTH "${json1}")
-assert_strequal("${result}" 5)
+assert_strequal("${result}" 6)
 if(error)
 if(error)
   message(SEND_ERROR "Unexpected error: ${error}")
   message(SEND_ERROR "Unexpected error: ${error}")
 endif()
 endif()

+ 1 - 1
Tests/RunCMake/string/JSONWrongMode-stderr.txt

@@ -1,5 +1,5 @@
 CMake Error at JSONWrongMode\.cmake:1 \(string\):
 CMake Error at JSONWrongMode\.cmake:1 \(string\):
   string sub-command JSON got an invalid mode 'FOO', expected one of GET,
   string sub-command JSON got an invalid mode 'FOO', expected one of GET,
-  TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL\.
+  GET_RAW, TYPE, MEMBER, LENGTH, REMOVE, SET, EQUAL\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:[0-9]+ \(include\)
   CMakeLists\.txt:[0-9]+ \(include\)