From 92f48f40015dfca11e24f2be166613bf243641fe Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 18 May 2017 19:54:56 -0400 Subject: [PATCH 10/31] FIXME: implement json::value::to_str --- gcc/json.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++---------------- gcc/json.h | 15 ++++++++------ 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/gcc/json.c b/gcc/json.c index 542b936..44044ee 100644 --- a/gcc/json.c +++ b/gcc/json.c @@ -21,12 +21,30 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "json.h" +#include "pretty-print.h" #include "selftest.h" using namespace json; /* Implemenation. */ +char * +value::to_str () const +{ + pretty_printer pp; + print (&pp); + return xstrdup (pp_formatted_text (&pp)); +} + +void +value::dump (FILE *outf) const +{ + pretty_printer pp; + pp_buffer (&pp)->stream = outf; + print (&pp); + pp_flush (&pp); +} + const object * value::as_object () const { @@ -69,20 +87,20 @@ object::~object () } void -object::dump (FILE *outf) const +object::print (pretty_printer *pp) const { /* Note that the order is not guaranteed. */ - fprintf (outf, "{"); + pp_character (pp, '{'); for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it) { if (it != m_map.begin ()) - fprintf (outf, ", "); + pp_string (pp, ", "); const char *key = const_cast ((*it).first); value *value = (*it).second; - fprintf (outf, "\"%s\": ", key); - value->dump (outf); + pp_printf (pp, "\"%s\": ", key); // FIXME: escaping? + value->print (pp); } - fprintf (outf, "}"); + pp_character (pp, '}'); } value * @@ -117,18 +135,18 @@ array::~array () } void -array::dump (FILE *outf) const +array::print (pretty_printer *pp) const { - fprintf (outf, "["); + pp_character (pp, '['); unsigned i; value *v; FOR_EACH_VEC_ELT (m_elements, i, v) { if (i) - fprintf (outf, ", "); - v->dump (outf); + pp_string (pp, ", "); + v->print (pp); } - fprintf (outf, "]"); + pp_character (pp, ']'); } value * @@ -138,9 +156,9 @@ array::clone () const } void -number::dump (FILE *outf) const +number::print (pretty_printer *pp) const { - fprintf (outf, "%g", m_value); + pp_printf (pp, "%i", (int)m_value); // FIXME } value * @@ -150,9 +168,9 @@ number::clone () const } void -string::dump (FILE *outf) const +string::print (pretty_printer *pp) const { - fprintf (outf, "\"%s\"", m_utf8); // FIXME: escaping + pp_printf (pp, "\"%s\"", m_utf8); // FIXME: escaping } value * @@ -162,9 +180,9 @@ string::clone () const } void -literal::dump (FILE *outf) const +literal::print (pretty_printer *pp) const { - fprintf (outf, "FIXME"); // FIXME + pp_string (pp, "FIXME"); // FIXME } value * @@ -754,6 +772,16 @@ namespace selftest { /* Selftests. */ +/* Verify that JV->to_str () equals EXPECTED_JSON. */ + +static void +assert_to_str_eq (const char *expected_json, json::value *jv) +{ + char *json = jv->to_str (); + ASSERT_STREQ (expected_json, json); + free (json); +} + static void test_parse_string () { @@ -762,6 +790,7 @@ test_parse_string () ASSERT_EQ (NULL, err); ASSERT_EQ (JSON_STRING, jv->get_kind ()); ASSERT_STREQ ("foo", ((json::string *)jv)->get_string ()); + assert_to_str_eq ("\"foo\"", jv); delete jv; } @@ -773,6 +802,7 @@ test_parse_number () ASSERT_EQ (NULL, err); ASSERT_EQ (JSON_NUMBER, jv->get_kind ()); ASSERT_EQ (42.0, ((json::number *)jv)->get ()); + assert_to_str_eq ("42", jv); delete jv; } @@ -791,6 +821,7 @@ test_parse_array () ASSERT_EQ (JSON_NUMBER, element->get_kind ()); ASSERT_EQ (i, ((json::number *)element)->get ()); } + assert_to_str_eq ("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", jv); delete jv; } @@ -823,6 +854,8 @@ test_parse_object () // TODO: error-handling // TODO: partial document + /* We can't use assert_to_str_eq since ordering is not guaranteed. */ + delete jv; } @@ -847,6 +880,7 @@ test_parse_empty_object () ASSERT_EQ (NULL, err); ASSERT_TRUE (jv != NULL); ASSERT_EQ (JSON_OBJECT, jv->get_kind ()); + assert_to_str_eq ("{}", jv); delete jv; } diff --git a/gcc/json.h b/gcc/json.h index f50e14f..ddce444 100644 --- a/gcc/json.h +++ b/gcc/json.h @@ -48,9 +48,12 @@ class value public: virtual ~value () {} virtual enum kind get_kind () const = 0; - virtual void dump (FILE *outf) const = 0; + virtual void print (pretty_printer *pp) const = 0; virtual value *clone () const = 0; + char *to_str () const; + void dump (FILE *) const; + const object *as_object () const; const array *as_array () const; const number *as_number () const; @@ -65,7 +68,7 @@ class object : public value ~object (); enum kind get_kind () const FINAL OVERRIDE { return JSON_OBJECT; } - void dump (FILE *outf) const FINAL OVERRIDE; + void print (pretty_printer *pp) const FINAL OVERRIDE; value *clone () const FINAL OVERRIDE; value *get (const char *key) const; @@ -85,7 +88,7 @@ class array : public value ~array (); enum kind get_kind () const FINAL OVERRIDE { return JSON_ARRAY; } - void dump (FILE *outf) const FINAL OVERRIDE; + void print (pretty_printer *pp) const FINAL OVERRIDE; value *clone () const FINAL OVERRIDE; unsigned get_length () const { return m_elements.length (); } @@ -104,7 +107,7 @@ class number : public value number (double value) : m_value (value) {} enum kind get_kind () const FINAL OVERRIDE { return JSON_NUMBER; } - void dump (FILE *outf) const FINAL OVERRIDE; + void print (pretty_printer *pp) const FINAL OVERRIDE; value *clone () const FINAL OVERRIDE; double get () const { return m_value; } @@ -122,7 +125,7 @@ class string : public value ~string () { free (m_utf8); } enum kind get_kind () const FINAL OVERRIDE { return JSON_STRING; } - void dump (FILE *outf) const FINAL OVERRIDE; + void print (pretty_printer *pp) const FINAL OVERRIDE; value *clone () const FINAL OVERRIDE; const char *get_string () const { return m_utf8; } @@ -139,7 +142,7 @@ class literal : public value literal (enum kind kind) : m_kind (kind) {} enum kind get_kind () const FINAL OVERRIDE { return m_kind; } - void dump (FILE *outf) const FINAL OVERRIDE; + void print (pretty_printer *pp) const FINAL OVERRIDE; value *clone () const FINAL OVERRIDE; private: -- 1.8.5.3