LCOV - code coverage report
Current view: top level - gcc - json.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.9 % 256 248
Test Date: 2025-03-22 13:13:03 Functions: 97.0 % 33 32
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* JSON trees
       2                 :             :    Copyright (C) 2017-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       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
      10                 :             : version.
      11                 :             : 
      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
      15                 :             : for more details.
      16                 :             : 
      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/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "json.h"
      25                 :             : #include "pretty-print.h"
      26                 :             : #include "math.h"
      27                 :             : #include "make-unique.h"
      28                 :             : #include "selftest.h"
      29                 :             : 
      30                 :             : using namespace json;
      31                 :             : 
      32                 :             : /* Print a JSON string to PP, escaping '"', control characters,
      33                 :             :    and embedded null bytes.
      34                 :             :    The string is required to be UTF-8 encoded.  */
      35                 :             : 
      36                 :             : static void
      37                 :     1366208 : print_escaped_json_string (pretty_printer *pp,
      38                 :             :                            const char *utf8_str,
      39                 :             :                            size_t len)
      40                 :             : {
      41                 :     1366208 :   pp_character (pp, '"');
      42                 :    18452560 :   for (size_t i = 0; i != len; ++i)
      43                 :             :     {
      44                 :    17086352 :       char ch = utf8_str[i];
      45                 :    17086352 :       switch (ch)
      46                 :             :         {
      47                 :        2534 :         case '"':
      48                 :        2534 :           pp_string (pp, "\\\"");
      49                 :        2534 :           break;
      50                 :        1439 :         case '\\':
      51                 :        1439 :           pp_string (pp, "\\\\");
      52                 :        1439 :           break;
      53                 :           8 :         case '\b':
      54                 :           8 :           pp_string (pp, "\\b");
      55                 :           8 :           break;
      56                 :           8 :         case '\f':
      57                 :           8 :           pp_string (pp, "\\f");
      58                 :           8 :           break;
      59                 :       54099 :         case '\n':
      60                 :       54099 :           pp_string (pp, "\\n");
      61                 :       54099 :           break;
      62                 :           8 :         case '\r':
      63                 :           8 :           pp_string (pp, "\\r");
      64                 :           8 :           break;
      65                 :        3558 :         case '\t':
      66                 :        3558 :           pp_string (pp, "\\t");
      67                 :        3558 :           break;
      68                 :           4 :         case '\0':
      69                 :           4 :           pp_string (pp, "\\0");
      70                 :           4 :           break;
      71                 :    17024694 :         default:
      72                 :    17024694 :           pp_character (pp, ch);
      73                 :             :         }
      74                 :             :     }
      75                 :     1366208 :   pp_character (pp, '"');
      76                 :     1366208 : }
      77                 :             : 
      78                 :             : /* class json::value.  */
      79                 :             : 
      80                 :             : /* Dump this json::value tree to OUTF.
      81                 :             : 
      82                 :             :    The key/value pairs of json::objects are printed in the order
      83                 :             :    in which the keys were originally inserted.  */
      84                 :             : 
      85                 :             : void
      86                 :         136 : value::dump (FILE *outf, bool formatted) const
      87                 :             : {
      88                 :         136 :   pretty_printer pp;
      89                 :         136 :   pp_buffer (&pp)->m_stream = outf;
      90                 :         136 :   print (&pp, formatted);
      91                 :         136 :   pp_flush (&pp);
      92                 :         136 : }
      93                 :             : 
      94                 :             : /* A convenience function for debugging.
      95                 :             :    Dump to stderr with formatting, and a trailing newline. */
      96                 :             : 
      97                 :             : void
      98                 :           0 : value::dump () const
      99                 :             : {
     100                 :           0 :   dump (stderr, true);
     101                 :           0 :   fprintf (stderr, "\n");
     102                 :           0 : }
     103                 :             : 
     104                 :             : /* class json::object, a subclass of json::value, representing
     105                 :             :    an ordered collection of key/value pairs.  */
     106                 :             : 
     107                 :             : /* json:object's dtor.  */
     108                 :             : 
     109                 :     1508714 : object::~object ()
     110                 :             : {
     111                 :     7428240 :   for (map_t::iterator it = m_map.begin (); it != m_map.end (); ++it)
     112                 :             :     {
     113                 :     3334540 :       free (const_cast <char *>((*it).first));
     114                 :     3334540 :       delete ((*it).second);
     115                 :             :     }
     116                 :     1508714 : }
     117                 :             : 
     118                 :             : /* Implementation of json::value::print for json::object.  */
     119                 :             : 
     120                 :             : void
     121                 :      257977 : object::print (pretty_printer *pp, bool formatted) const
     122                 :             : {
     123                 :      257977 :   pp_character (pp, '{');
     124                 :      257977 :   if (formatted)
     125                 :        3953 :     pp_indentation (pp) += 1;
     126                 :             : 
     127                 :             :   /* Iterate in the order that the keys were inserted.  */
     128                 :             :   unsigned i;
     129                 :             :   const char *key;
     130                 :     1099358 :   FOR_EACH_VEC_ELT (m_keys, i, key)
     131                 :             :     {
     132                 :      841381 :       if (i > 0)
     133                 :             :         {
     134                 :      583412 :           pp_string (pp, ",");
     135                 :      583412 :           if (formatted)
     136                 :             :             {
     137                 :        5590 :               pp_newline (pp);
     138                 :        5590 :               pp_indent (pp);
     139                 :             :             }
     140                 :             :           else
     141                 :      577822 :             pp_space (pp);
     142                 :             :         }
     143                 :      841381 :       map_t &mut_map = const_cast<map_t &> (m_map);
     144                 :      841381 :       value *value = *mut_map.get (key);
     145                 :      841381 :       print_escaped_json_string (pp, key, strlen (key));
     146                 :      841381 :       pp_string (pp, ": ");
     147                 :      841381 :       const int indent = strlen (key) + 4;
     148                 :      841381 :       if (formatted)
     149                 :        9535 :         pp_indentation (pp) += indent;
     150                 :      841381 :       value->print (pp, formatted);
     151                 :      841381 :       if (formatted)
     152                 :        9535 :         pp_indentation (pp) -= indent;
     153                 :             :     }
     154                 :      257977 :   if (formatted)
     155                 :        3953 :     pp_indentation (pp) -= 1;
     156                 :      257977 :   pp_character (pp, '}');
     157                 :      257977 : }
     158                 :             : 
     159                 :             : /* Set the json::value * for KEY, taking ownership of V
     160                 :             :    (and taking a copy of KEY if necessary).  */
     161                 :             : 
     162                 :             : void
     163                 :     3335597 : object::set (const char *key, value *v)
     164                 :             : {
     165                 :     3335597 :   gcc_assert (key);
     166                 :     3335597 :   gcc_assert (v);
     167                 :             : 
     168                 :     3335597 :   value **ptr = m_map.get (key);
     169                 :     3335597 :   if (ptr)
     170                 :             :     {
     171                 :             :       /* If the key is already present, delete the existing value
     172                 :             :          and overwrite it.  */
     173                 :           0 :       delete *ptr;
     174                 :           0 :       *ptr = v;
     175                 :             :     }
     176                 :             :   else
     177                 :             :     {
     178                 :             :       /* If the key wasn't already present, take a copy of the key,
     179                 :             :          and store the value.  */
     180                 :     3335597 :       char *owned_key = xstrdup (key);
     181                 :     3335597 :       m_map.put (owned_key, v);
     182                 :     3335597 :       m_keys.safe_push (owned_key);
     183                 :             :     }
     184                 :     3335597 : }
     185                 :             : 
     186                 :             : /* Get the json::value * for KEY.
     187                 :             : 
     188                 :             :    The object retains ownership of the value.  */
     189                 :             : 
     190                 :             : value *
     191                 :        6270 : object::get (const char *key) const
     192                 :             : {
     193                 :        6270 :   gcc_assert (key);
     194                 :             : 
     195                 :        6270 :   value **ptr = const_cast <map_t &> (m_map).get (key);
     196                 :        6270 :   if (ptr)
     197                 :        5892 :     return *ptr;
     198                 :             :   else
     199                 :             :     return NULL;
     200                 :             : }
     201                 :             : 
     202                 :             : /* Set value of KEY within this object to a JSON
     203                 :             :    string value based on UTF8_VALUE.  */
     204                 :             : 
     205                 :             : void
     206                 :     1356821 : object::set_string (const char *key, const char *utf8_value)
     207                 :             : {
     208                 :     1356821 :   set (key, new json::string (utf8_value));
     209                 :     1356821 : }
     210                 :             : 
     211                 :             : /* Set value of KEY within this object to a JSON
     212                 :             :    integer value based on V.  */
     213                 :             : 
     214                 :             : void
     215                 :      675127 : object::set_integer (const char *key, long v)
     216                 :             : {
     217                 :      675127 :   set (key, new json::integer_number (v));
     218                 :      675127 : }
     219                 :             : 
     220                 :             : /* Set value of KEY within this object to a JSON
     221                 :             :    floating point value based on V.  */
     222                 :             : 
     223                 :             : void
     224                 :          16 : object::set_float (const char *key, double v)
     225                 :             : {
     226                 :          16 :   set (key, new json::float_number (v));
     227                 :          16 : }
     228                 :             : 
     229                 :             : /* Set value of KEY within this object to the JSON
     230                 :             :    literal true or false, based on V.  */
     231                 :             : 
     232                 :             : void
     233                 :         531 : object::set_bool (const char *key, bool v)
     234                 :             : {
     235                 :         836 :   set (key, new json::literal (v));
     236                 :         531 : }
     237                 :             : 
     238                 :             : /* class json::array, a subclass of json::value, representing
     239                 :             :    an ordered collection of values.  */
     240                 :             : 
     241                 :             : /* json::array's dtor.  */
     242                 :             : 
     243                 :     1231320 : array::~array ()
     244                 :             : {
     245                 :      615662 :   unsigned i;
     246                 :      615662 :   value *v;
     247                 :     1415306 :   FOR_EACH_VEC_ELT (m_elements, i, v)
     248                 :      799644 :     delete v;
     249                 :     1231320 : }
     250                 :             : 
     251                 :             : /* Implementation of json::value::print for json::array.  */
     252                 :             : 
     253                 :             : void
     254                 :       96720 : array::print (pretty_printer *pp, bool formatted) const
     255                 :             : {
     256                 :       96720 :   pp_character (pp, '[');
     257                 :       96720 :   if (formatted)
     258                 :        1391 :     pp_indentation (pp) += 1;
     259                 :             :   unsigned i;
     260                 :             :   value *v;
     261                 :      314806 :   FOR_EACH_VEC_ELT (m_elements, i, v)
     262                 :             :     {
     263                 :      218086 :       if (i)
     264                 :             :         {
     265                 :      135882 :           pp_string (pp, ",");
     266                 :      135882 :           if (formatted)
     267                 :             :             {
     268                 :        3212 :               pp_newline (pp);
     269                 :        3212 :               pp_indent (pp);
     270                 :             :             }
     271                 :             :           else
     272                 :      132670 :             pp_space (pp);
     273                 :             :         }
     274                 :      218086 :       v->print (pp, formatted);
     275                 :             :     }
     276                 :       96720 :   if (formatted)
     277                 :        1391 :     pp_indentation (pp) -= 1;
     278                 :       96720 :   pp_character (pp, ']');
     279                 :       96720 : }
     280                 :             : 
     281                 :             : /* Append non-NULL value V to a json::array, taking ownership of V.  */
     282                 :             : 
     283                 :             : void
     284                 :      799723 : array::append (value *v)
     285                 :             : {
     286                 :      799723 :   gcc_assert (v);
     287                 :      799723 :   m_elements.safe_push (v);
     288                 :      799723 : }
     289                 :             : 
     290                 :             : void
     291                 :      182943 : array::append_string (const char *utf8_value)
     292                 :             : {
     293                 :      182943 :   gcc_assert (utf8_value);
     294                 :      182943 :   append (new json::string (utf8_value));
     295                 :      182943 : }
     296                 :             : 
     297                 :             : /* class json::float_number, a subclass of json::value, wrapping a double.  */
     298                 :             : 
     299                 :             : /* Implementation of json::value::print for json::float_number.  */
     300                 :             : 
     301                 :             : void
     302                 :          32 : float_number::print (pretty_printer *pp,
     303                 :             :                      bool formatted ATTRIBUTE_UNUSED) const
     304                 :             : {
     305                 :          32 :   char tmp[1024];
     306                 :          32 :   snprintf (tmp, sizeof (tmp), "%g", m_value);
     307                 :          32 :   pp_string (pp, tmp);
     308                 :          32 : }
     309                 :             : 
     310                 :             : /* class json::integer_number, a subclass of json::value, wrapping a long.  */
     311                 :             : 
     312                 :             : /* Implementation of json::value::print for json::integer_number.  */
     313                 :             : 
     314                 :             : void
     315                 :      179984 : integer_number::print (pretty_printer *pp,
     316                 :             :                        bool formatted ATTRIBUTE_UNUSED) const
     317                 :             : {
     318                 :      179984 :   char tmp[1024];
     319                 :      179984 :   snprintf (tmp, sizeof (tmp), "%ld", m_value);
     320                 :      179984 :   pp_string (pp, tmp);
     321                 :      179984 : }
     322                 :             : 
     323                 :             : 
     324                 :             : /* class json::string, a subclass of json::value.  */
     325                 :             : 
     326                 :             : /* json::string's ctor.  */
     327                 :             : 
     328                 :     2087014 : string::string (const char *utf8)
     329                 :             : {
     330                 :     2087014 :   gcc_assert (utf8);
     331                 :     2087014 :   m_utf8 = xstrdup (utf8);
     332                 :     2087014 :   m_len = strlen (utf8);
     333                 :     2087014 : }
     334                 :             : 
     335                 :         212 : string::string (const char *utf8, size_t len)
     336                 :             : {
     337                 :         212 :   gcc_assert (utf8);
     338                 :         212 :   m_utf8 = XNEWVEC (char, len);
     339                 :         212 :   m_len = len;
     340                 :         212 :   memcpy (m_utf8, utf8, len);
     341                 :         212 : }
     342                 :             : 
     343                 :             : /* Implementation of json::value::print for json::string.  */
     344                 :             : 
     345                 :             : void
     346                 :      524827 : string::print (pretty_printer *pp,
     347                 :             :                bool formatted ATTRIBUTE_UNUSED) const
     348                 :             : {
     349                 :      524827 :   print_escaped_json_string (pp, m_utf8, m_len);
     350                 :      524827 : }
     351                 :             : 
     352                 :             : /* class json::literal, a subclass of json::value.  */
     353                 :             : 
     354                 :             : /* Implementation of json::value::print for json::literal.  */
     355                 :             : 
     356                 :             : void
     357                 :         262 : literal::print (pretty_printer *pp,
     358                 :             :                 bool formatted ATTRIBUTE_UNUSED) const
     359                 :             : {
     360                 :         262 :   switch (m_kind)
     361                 :             :     {
     362                 :         110 :     case JSON_TRUE:
     363                 :         110 :       pp_string (pp, "true");
     364                 :         110 :       break;
     365                 :         144 :     case JSON_FALSE:
     366                 :         144 :       pp_string (pp, "false");
     367                 :         144 :       break;
     368                 :           8 :     case JSON_NULL:
     369                 :           8 :       pp_string (pp, "null");
     370                 :           8 :       break;
     371                 :           0 :     default:
     372                 :           0 :       gcc_unreachable ();
     373                 :             :     }
     374                 :         262 : }
     375                 :             : 
     376                 :             : 
     377                 :             : #if CHECKING_P
     378                 :             : 
     379                 :             : namespace selftest {
     380                 :             : 
     381                 :             : /* Selftests.  */
     382                 :             : 
     383                 :             : /* Verify that JV->print () prints EXPECTED_JSON.  */
     384                 :             : 
     385                 :             : void
     386                 :         152 : assert_print_eq (const location &loc,
     387                 :             :                  const json::value &jv,
     388                 :             :                  bool formatted,
     389                 :             :                  const char *expected_json)
     390                 :             : {
     391                 :         152 :   pretty_printer pp;
     392                 :         152 :   jv.print (&pp, formatted);
     393                 :         152 :   ASSERT_STREQ_AT (loc, expected_json, pp_formatted_text (&pp));
     394                 :         152 : }
     395                 :             : 
     396                 :             : #define ASSERT_PRINT_EQ(JV, FORMATTED, EXPECTED_JSON)   \
     397                 :             :   assert_print_eq (SELFTEST_LOCATION, JV, FORMATTED, EXPECTED_JSON)
     398                 :             : 
     399                 :             : /* Verify that object::get works as expected.  */
     400                 :             : 
     401                 :             : static void
     402                 :           4 : test_object_get ()
     403                 :             : {
     404                 :           4 :   object obj;
     405                 :           4 :   value *val = new json::string ("value");
     406                 :           4 :   obj.set ("foo", val);
     407                 :           4 :   ASSERT_EQ (obj.get ("foo"), val);
     408                 :           4 :   ASSERT_EQ (obj.get ("not-present"), NULL);
     409                 :           4 : }
     410                 :             : 
     411                 :             : /* Verify that JSON objects are written correctly.  */
     412                 :             : 
     413                 :             : static void
     414                 :           4 : test_writing_objects ()
     415                 :             : {
     416                 :           4 :   object obj;
     417                 :           4 :   obj.set_string ("foo", "bar");
     418                 :           4 :   obj.set_string ("baz", "quux");
     419                 :           4 :   obj.set_string ("\"\\\b\f\n\r\t", "value for awkward key");
     420                 :             : 
     421                 :             :   /* This test relies on json::object writing out key/value pairs
     422                 :             :      in key-insertion order.  */
     423                 :           4 :   ASSERT_PRINT_EQ (obj, true,
     424                 :             :                    "{\"foo\": \"bar\",\n"
     425                 :             :                    " \"baz\": \"quux\",\n"
     426                 :             :                    " \"\\\"\\\\\\b\\f\\n\\r\\t\": \"value for awkward key\"}");
     427                 :           4 :   ASSERT_PRINT_EQ (obj, false,
     428                 :             :                    "{\"foo\": \"bar\", \"baz\": \"quux\""
     429                 :             :                    ", \"\\\"\\\\\\b\\f\\n\\r\\t\": \"value for awkward key\"}");
     430                 :           4 : }
     431                 :             : 
     432                 :             : /* Verify that JSON arrays are written correctly.  */
     433                 :             : 
     434                 :             : static void
     435                 :           4 : test_writing_arrays ()
     436                 :             : {
     437                 :           4 :   array arr;
     438                 :           4 :   ASSERT_PRINT_EQ (arr, true, "[]");
     439                 :             : 
     440                 :           4 :   arr.append (new json::string ("foo"));
     441                 :           4 :   ASSERT_PRINT_EQ (arr, true, "[\"foo\"]");
     442                 :             : 
     443                 :           4 :   arr.append_string ("bar");
     444                 :           4 :   ASSERT_PRINT_EQ (arr, true,
     445                 :             :                    "[\"foo\",\n"
     446                 :             :                    " \"bar\"]");
     447                 :           4 :   ASSERT_PRINT_EQ (arr, false,
     448                 :             :                    "[\"foo\", \"bar\"]");
     449                 :           4 : }
     450                 :             : 
     451                 :             : /* Verify that JSON numbers are written correctly.  */
     452                 :             : 
     453                 :             : static void
     454                 :           4 : test_writing_float_numbers ()
     455                 :             : {
     456                 :           4 :   ASSERT_PRINT_EQ (float_number (0), true, "0");
     457                 :           4 :   ASSERT_PRINT_EQ (float_number (42), true, "42");
     458                 :           4 :   ASSERT_PRINT_EQ (float_number (-100), true, "-100");
     459                 :           4 :   ASSERT_PRINT_EQ (float_number (123456789), true, "1.23457e+08");
     460                 :           4 : }
     461                 :             : 
     462                 :             : static void
     463                 :           4 : test_writing_integer_numbers ()
     464                 :             : {
     465                 :           4 :   ASSERT_PRINT_EQ (integer_number (0), true, "0");
     466                 :           4 :   ASSERT_PRINT_EQ (integer_number (42), true, "42");
     467                 :           4 :   ASSERT_PRINT_EQ (integer_number (-100), true, "-100");
     468                 :           4 :   ASSERT_PRINT_EQ (integer_number (123456789), true, "123456789");
     469                 :           4 :   ASSERT_PRINT_EQ (integer_number (-123456789), true, "-123456789");
     470                 :           4 : }
     471                 :             : 
     472                 :             : /* Verify that JSON strings are written correctly.  */
     473                 :             : 
     474                 :             : static void
     475                 :           4 : test_writing_strings ()
     476                 :             : {
     477                 :           4 :   string foo ("foo");
     478                 :           4 :   ASSERT_PRINT_EQ (foo, true, "\"foo\"");
     479                 :             : 
     480                 :           4 :   string contains_quotes ("before \"quoted\" after");
     481                 :           4 :   ASSERT_PRINT_EQ (contains_quotes, true, "\"before \\\"quoted\\\" after\"");
     482                 :             : 
     483                 :           4 :   const char data[] = {'a', 'b', 'c', 'd', '\0', 'e', 'f'};
     484                 :           4 :   string not_terminated (data, 3);
     485                 :           4 :   ASSERT_PRINT_EQ (not_terminated, true, "\"abc\"");
     486                 :           4 :   string embedded_null (data, sizeof data);
     487                 :           4 :   ASSERT_PRINT_EQ (embedded_null, true, "\"abcd\\0ef\"");
     488                 :           4 : }
     489                 :             : 
     490                 :             : /* Verify that JSON literals are written correctly.  */
     491                 :             : 
     492                 :             : static void
     493                 :           4 : test_writing_literals ()
     494                 :             : {
     495                 :           4 :   ASSERT_PRINT_EQ (literal (JSON_TRUE), true, "true");
     496                 :           4 :   ASSERT_PRINT_EQ (literal (JSON_FALSE), true, "false");
     497                 :           4 :   ASSERT_PRINT_EQ (literal (JSON_NULL), true, "null");
     498                 :             : 
     499                 :           4 :   ASSERT_PRINT_EQ (literal (true), true, "true");
     500                 :           4 :   ASSERT_PRINT_EQ (literal (false), true, "false");
     501                 :           4 : }
     502                 :             : 
     503                 :             : /* Verify that nested values are formatted correctly when written.
     504                 :             : 
     505                 :             :    Also, make use of array::append(std::unique_ptr<value>) and
     506                 :             :    object::set (const char *key, std::unique_ptr<value> v).*/
     507                 :             : 
     508                 :             : static void
     509                 :           4 : test_formatting ()
     510                 :             : {
     511                 :           4 :   object obj;
     512                 :           4 :   object *child = new object;
     513                 :           4 :   std::unique_ptr<object> grandchild = ::make_unique<object> ();
     514                 :             : 
     515                 :           4 :   obj.set_string ("str", "bar");
     516                 :           4 :   obj.set ("child", child);
     517                 :           4 :   obj.set_integer ("int", 42);
     518                 :             : 
     519                 :           4 :   array *arr = new array;
     520                 :          16 :   for (int i = 0; i < 3; i++)
     521                 :          12 :     arr->append (::make_unique<integer_number> (i));
     522                 :           4 :   grandchild->set ("arr", arr);
     523                 :           4 :   grandchild->set_integer ("int", 1066);
     524                 :             : 
     525                 :           4 :   child->set ("grandchild", std::move (grandchild));
     526                 :           4 :   child->set_integer ("int", 1776);
     527                 :             : 
     528                 :             :   /* This test relies on json::object writing out key/value pairs
     529                 :             :      in key-insertion order.  */
     530                 :           4 :   ASSERT_PRINT_EQ (obj, true,
     531                 :             :                    ("{\"str\": \"bar\",\n"
     532                 :             :                     " \"child\": {\"grandchild\": {\"arr\": [0,\n"
     533                 :             :                     "                                  1,\n"
     534                 :             :                     "                                  2],\n"
     535                 :             :                     "                          \"int\": 1066},\n"
     536                 :             :                     "           \"int\": 1776},\n"
     537                 :             :                     " \"int\": 42}"));
     538                 :           4 :   ASSERT_PRINT_EQ (obj, false,
     539                 :             :                    ("{\"str\": \"bar\", \"child\": {\"grandchild\":"
     540                 :             :                     " {\"arr\": [0, 1, 2], \"int\": 1066},"
     541                 :             :                     " \"int\": 1776}, \"int\": 42}"));
     542                 :           4 : }
     543                 :             : 
     544                 :             : /* Run all of the selftests within this file.  */
     545                 :             : 
     546                 :             : void
     547                 :           4 : json_cc_tests ()
     548                 :             : {
     549                 :           4 :   test_object_get ();
     550                 :           4 :   test_writing_objects ();
     551                 :           4 :   test_writing_arrays ();
     552                 :           4 :   test_writing_float_numbers ();
     553                 :           4 :   test_writing_integer_numbers ();
     554                 :           4 :   test_writing_strings ();
     555                 :           4 :   test_writing_literals ();
     556                 :           4 :   test_formatting ();
     557                 :           4 : }
     558                 :             : 
     559                 :             : } // namespace selftest
     560                 :             : 
     561                 :             : #endif /* #if CHECKING_P */
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.