2 Copyright (C) 2017-2018 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "pretty-print.h"
31 /* class json::value. */
33 /* Dump this json::value tree to OUTF.
34 No formatting is done. There are no guarantees about the order
35 in which the key/value pairs of json::objects are printed. */
38 value::dump (FILE *outf) const
41 pp_buffer (&pp)->stream = outf;
46 /* class json::object, a subclass of json::value, representing
47 an unordered collection of key/value pairs. */
49 /* json:object's dtor. */
53 for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it)
55 free (const_cast <char *>((*it).first));
56 delete ((*it).second);
60 /* Implementation of json::value::print for json::object. */
63 object::print (pretty_printer *pp) const
65 /* Note that the order is not guaranteed. */
66 pp_character (pp, '{');
67 for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it)
69 if (it != m_map.begin ())
71 const char *key = const_cast <char *>((*it).first);
72 value *value = (*it).second;
73 pp_printf (pp, "\"%s\": ", key); // FIXME: escaping?
76 pp_character (pp, '}');
79 /* Set the json::value * for KEY, taking ownership of V
80 (and taking a copy of KEY if necessary). */
83 object::set (const char *key, value *v)
88 value **ptr = m_map.get (key);
91 /* If the key is already present, delete the existing value
97 /* If the key wasn't already present, take a copy of the key,
98 and store the value. */
99 m_map.put (xstrdup (key), v);
102 /* class json::array, a subclass of json::value, representing
103 an ordered collection of values. */
105 /* json::array's dtor. */
111 FOR_EACH_VEC_ELT (m_elements, i, v)
115 /* Implementation of json::value::print for json::array. */
118 array::print (pretty_printer *pp) const
120 pp_character (pp, '[');
123 FOR_EACH_VEC_ELT (m_elements, i, v)
126 pp_string (pp, ", ");
129 pp_character (pp, ']');
132 /* Append non-NULL value V to a json::array, taking ownership of V. */
135 array::append (value *v)
138 m_elements.safe_push (v);
141 /* class json::number, a subclass of json::value, wrapping a double. */
143 /* Implementation of json::value::print for json::number. */
146 number::print (pretty_printer *pp) const
149 snprintf (tmp, sizeof (tmp), "%g", m_value);
153 /* class json::string, a subclass of json::value. */
155 /* json::string's ctor. */
157 string::string (const char *utf8)
160 m_utf8 = xstrdup (utf8);
163 /* Implementation of json::value::print for json::string. */
166 string::print (pretty_printer *pp) const
168 pp_character (pp, '"');
169 for (const char *ptr = m_utf8; *ptr; ptr++)
175 pp_string (pp, "\\\"");
178 pp_string (pp, "\\n");
181 pp_string (pp, "\\b");
184 pp_string (pp, "\\f");
187 pp_string (pp, "\\n");
190 pp_string (pp, "\\r");
193 pp_string (pp, "\\t");
197 pp_character (pp, ch);
200 pp_character (pp, '"');
203 /* class json::literal, a subclass of json::value. */
205 /* Implementation of json::value::print for json::literal. */
208 literal::print (pretty_printer *pp) const
213 pp_string (pp, "true");
216 pp_string (pp, "false");
219 pp_string (pp, "null");
233 /* Verify that JV->print () prints EXPECTED_JSON. */
236 assert_print_eq (const json::value &jv, const char *expected_json)
240 ASSERT_STREQ (expected_json, pp_formatted_text (&pp));
243 /* Verify that JSON objects are written correctly. We can't test more than
244 one key/value pair, as we don't impose a guaranteed ordering. */
247 test_writing_objects ()
250 obj.set ("foo", new json::string ("bar"));
251 assert_print_eq (obj, "{\"foo\": \"bar\"}");
254 /* Verify that JSON arrays are written correctly. */
257 test_writing_arrays ()
260 assert_print_eq (arr, "[]");
262 arr.append (new json::string ("foo"));
263 assert_print_eq (arr, "[\"foo\"]");
265 arr.append (new json::string ("bar"));
266 assert_print_eq (arr, "[\"foo\", \"bar\"]");
269 /* Verify that JSON numbers are written correctly. */
272 test_writing_numbers ()
274 assert_print_eq (number (0), "0");
275 assert_print_eq (number (42), "42");
276 assert_print_eq (number (-100), "-100");
279 /* Verify that JSON strings are written correctly. */
282 test_writing_strings ()
285 assert_print_eq (foo, "\"foo\"");
287 string contains_quotes ("before \"quoted\" after");
288 assert_print_eq (contains_quotes, "\"before \\\"quoted\\\" after\"");
291 /* Verify that JSON strings are written correctly. */
294 test_writing_literals ()
296 assert_print_eq (literal (JSON_TRUE), "true");
297 assert_print_eq (literal (JSON_FALSE), "false");
298 assert_print_eq (literal (JSON_NULL), "null");
300 assert_print_eq (literal (true), "true");
301 assert_print_eq (literal (false), "false");
304 /* Run all of the selftests within this file. */
309 test_writing_objects ();
310 test_writing_arrays ();
311 test_writing_numbers ();
312 test_writing_strings ();
313 test_writing_literals ();
316 } // namespace selftest
318 #endif /* #if CHECKING_P */