Am 07.06.2018 um 16:12 schrieb g...@jeffhostetler.com:
> From: Jeff Hostetler <jeffh...@microsoft.com>
> +/*
> + * Add comma if we have already seen a member at this level.
> + */
> +static inline void maybe_add_comma(struct json_writer *jw)
> +{
> +     if (!jw->open_stack.len)
> +             return;

This is impossible.  maybe_add_comma() is only called directly after
assert_in_object() and assert_in_object(), which abort if open_stack 
is empty.

> +     if (jw->first_stack.buf[jw->first_stack.len - 1] == '1')
> +             jw->first_stack.buf[jw->first_stack.len - 1] = '0';
> +     else
> +             strbuf_addch(&jw->json, ',');

You only need a binary flag to indicate if a comma is needed, not a
stack.  We need a comma at the current level if and only if we already
wrote a child item.  If we finish a level then we do need a comma at the
previous level because we just wrote a sub-object or sub-array there.
And that should cover all cases.  Am I missing something?

I get a sense of déjà vu, by the way. :)

Here's what I mean:
---
 json-writer.c | 17 ++++++-----------
 json-writer.h | 13 +++++--------
 2 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/json-writer.c b/json-writer.c
index f35ce1912a..14a4e89188 100644
--- a/json-writer.c
+++ b/json-writer.c
@@ -5,7 +5,7 @@ void jw_init(struct json_writer *jw)
 {
        strbuf_reset(&jw->json);
        strbuf_reset(&jw->open_stack);
-       strbuf_reset(&jw->first_stack);
+       jw->need_comma = 0;
        jw->pretty = 0;
 }
 
@@ -13,7 +13,6 @@ void jw_release(struct json_writer *jw)
 {
        strbuf_release(&jw->json);
        strbuf_release(&jw->open_stack);
-       strbuf_release(&jw->first_stack);
 }
 
 /*
@@ -69,7 +68,7 @@ static inline void begin(struct json_writer *jw, char 
ch_open, int pretty)
        strbuf_addch(&jw->json, ch_open);
 
        strbuf_addch(&jw->open_stack, ch_open);
-       strbuf_addch(&jw->first_stack, '1');
+       jw->need_comma = 0;
 }
 
 /*
@@ -99,12 +98,10 @@ static inline void assert_in_array(const struct json_writer 
*jw)
  */
 static inline void maybe_add_comma(struct json_writer *jw)
 {
-       if (!jw->open_stack.len)
-               return;
-       if (jw->first_stack.buf[jw->first_stack.len - 1] == '1')
-               jw->first_stack.buf[jw->first_stack.len - 1] = '0';
-       else
+       if (jw->need_comma)
                strbuf_addch(&jw->json, ',');
+       else
+               jw->need_comma = 1;
 }
 
 static inline void fmt_double(struct json_writer *jw, int precision,
@@ -397,8 +394,6 @@ void jw_end(struct json_writer *jw)
        char ch_open;
        int len;
 
-       if (jw->open_stack.len != jw->first_stack.len)
-               BUG("jwon-writer: open_ and first_ stacks out of sync");
        if (!jw->open_stack.len)
                BUG("json-writer: too many jw_end(): '%s'", jw->json.buf);
 
@@ -406,7 +401,7 @@ void jw_end(struct json_writer *jw)
        ch_open = jw->open_stack.buf[len];
 
        strbuf_setlen(&jw->open_stack, len);
-       strbuf_setlen(&jw->first_stack, len);
+       jw->need_comma = 1;
 
        if (jw->pretty)
                strbuf_addch(&jw->json, '\n');
diff --git a/json-writer.h b/json-writer.h
index af9c2612f8..c437462ba8 100644
--- a/json-writer.h
+++ b/json-writer.h
@@ -59,18 +59,15 @@ struct json_writer
        struct strbuf open_stack;
 
        /*
-        * Another simple stack of the currently open array and object
-        * forms.  This is used in parallel to "open_stack" (same length).
-        * It contains a string of '1' and '0' where '1' indicates that
-        * the next child-element seen will be the first child (and does
-        * not need a leading comma).
+        * Indicates if the next child item needs a leading comma.
+        * Only the first item of arrays and objects doesn't need one.
         */
-       struct strbuf first_stack;
+       unsigned int need_comma:1;
 
-       int pretty;
+       unsigned int pretty:1;
 };
 
-#define JSON_WRITER_INIT { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, 0 }
+#define JSON_WRITER_INIT { STRBUF_INIT, STRBUF_INIT, 0, 0 }
 
 void jw_init(struct json_writer *jw);
 void jw_release(struct json_writer *jw);
-- 
2.17.1

Reply via email to