aboutsummaryrefslogtreecommitdiff
path: root/gcc/json.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/json.cc')
-rw-r--r--gcc/json.cc122
1 files changed, 121 insertions, 1 deletions
diff --git a/gcc/json.cc b/gcc/json.cc
index f3f3645..7153f08 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -289,6 +289,30 @@ object::print (pretty_printer *pp, bool formatted) const
pp_character (pp, '}');
}
+std::unique_ptr<value>
+object::clone () const
+{
+ return clone_as_object ();
+}
+
+std::unique_ptr<object>
+object::clone_as_object () const
+{
+ auto result = std::make_unique<object> ();
+
+ /* Iterate in the order that the keys were inserted. */
+ unsigned i;
+ const char *key;
+ FOR_EACH_VEC_ELT (m_keys, i, key)
+ {
+ map_t &mut_map = const_cast<map_t &> (m_map);
+ value *value = *mut_map.get (key);
+ result->set (key, value->clone ());
+ }
+
+ return result;
+}
+
/* Set the json::value * for KEY, taking ownership of V
(and taking a copy of KEY if necessary). */
@@ -443,6 +467,17 @@ array::print (pretty_printer *pp, bool formatted) const
pp_character (pp, ']');
}
+std::unique_ptr<value>
+array::clone () const
+{
+ auto result = std::make_unique<array> ();
+ unsigned i;
+ value *v;
+ FOR_EACH_VEC_ELT (m_elements, i, v)
+ result->append (v->clone ());
+ return result;
+}
+
/* Append non-NULL value V to a json::array, taking ownership of V. */
void
@@ -473,6 +508,12 @@ float_number::print (pretty_printer *pp,
pp_string (pp, tmp);
}
+std::unique_ptr<value>
+float_number::clone () const
+{
+ return std::make_unique<float_number> (m_value);
+}
+
/* class json::integer_number, a subclass of json::value, wrapping a long. */
/* Implementation of json::value::print for json::integer_number. */
@@ -486,6 +527,11 @@ integer_number::print (pretty_printer *pp,
pp_string (pp, tmp);
}
+std::unique_ptr<value>
+integer_number::clone () const
+{
+ return std::make_unique<integer_number> (m_value);
+}
/* class json::string, a subclass of json::value. */
@@ -501,9 +547,10 @@ string::string (const char *utf8)
string::string (const char *utf8, size_t len)
{
gcc_assert (utf8);
- m_utf8 = XNEWVEC (char, len);
+ m_utf8 = XNEWVEC (char, len + 1);
m_len = len;
memcpy (m_utf8, utf8, len);
+ m_utf8[len] = '\0';
}
/* Implementation of json::value::print for json::string. */
@@ -515,6 +562,12 @@ string::print (pretty_printer *pp,
print_escaped_json_string (pp, m_utf8, m_len);
}
+std::unique_ptr<value>
+string::clone () const
+{
+ return std::make_unique<string> (m_utf8, m_len);
+}
+
/* class json::literal, a subclass of json::value. */
/* Implementation of json::value::print for json::literal. */
@@ -539,6 +592,12 @@ literal::print (pretty_printer *pp,
}
}
+std::unique_ptr<value>
+literal::clone () const
+{
+ return std::make_unique<literal> (m_kind);
+}
+
#if CHECKING_P
@@ -914,6 +973,65 @@ test_comparisons ()
ASSERT_JSON_NE (arr_1, arr_2);
}
+/* Ensure that json::string's get_string is usable as a C-style string. */
+
+static void
+test_strcmp ()
+{
+ string str ("foobar", 3);
+ ASSERT_EQ (strcmp (str.get_string (), "foo"), 0);
+}
+
+static void
+test_cloning ()
+{
+ // Objects
+ {
+ object obj;
+ obj.set_string ("foo", "bar");
+
+ auto obj_clone = obj.clone ();
+ ASSERT_JSON_EQ (obj, *obj_clone);
+ }
+
+ // Arrays
+ {
+ array arr;
+ arr.append (std::make_unique<string> ("foo"));
+
+ auto arr_clone = arr.clone ();
+ ASSERT_JSON_EQ (arr, *arr_clone);
+ }
+
+ // float_number
+ {
+ float_number f_one (1.0);
+ auto f_clone = f_one.clone ();
+ ASSERT_JSON_EQ (f_one, *f_clone);
+ }
+
+ // integer_number
+ {
+ integer_number num (42);
+ auto num_clone = num.clone ();
+ ASSERT_JSON_EQ (num, *num_clone);
+ }
+
+ // string
+ {
+ string str ("foo");
+ auto str_clone = str.clone ();
+ ASSERT_JSON_EQ (str, *str_clone);
+ }
+
+ // literal
+ {
+ literal lit (JSON_TRUE);
+ auto lit_clone = lit.clone ();
+ ASSERT_JSON_EQ (lit, *lit_clone);
+ }
+}
+
/* Run all of the selftests within this file. */
void
@@ -928,6 +1046,8 @@ json_cc_tests ()
test_writing_literals ();
test_formatting ();
test_comparisons ();
+ test_strcmp ();
+ test_cloning ();
}
} // namespace selftest