Add an extra argument compact to json_do_object() to instruct the parser
authorclaudio <claudio@openbsd.org>
Mon, 5 Jun 2023 14:19:13 +0000 (14:19 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 5 Jun 2023 14:19:13 +0000 (14:19 +0000)
to dump this object on a single line.

While one can select on an object to object basis for arrays the compact
setting is inherited from the surrounding object.

Requested by job@, OK job@ tb@

usr.sbin/rpki-client/json.c
usr.sbin/rpki-client/json.h
usr.sbin/rpki-client/output-json.c
usr.sbin/rpki-client/output-ometric.c
usr.sbin/rpki-client/print.c

index 5d86072..970439b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: json.c,v 1.2 2023/05/03 07:56:05 claudio Exp $ */
+/*     $OpenBSD: json.c,v 1.3 2023/06/05 14:19:13 claudio Exp $ */
 
 /*
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@@ -38,6 +38,7 @@ enum json_type {
 static struct json_stack {
        const char      *name;
        unsigned int    count;
+       int             compact;
        enum json_type  type;
 } stack[JSON_MAX_STACK];
 
@@ -49,9 +50,18 @@ static FILE *jsonfh;
 static void
 do_comma_indent(void)
 {
-       if (stack[level].count++ > 0)
+       char sp = '\n';
+
+       if (stack[level].compact)
+               sp = ' ';
+
+       if (stack[level].count++ > 0) {
                if (!eb)
-                       eb = fprintf(jsonfh, ",\n") < 0;
+                       eb = fprintf(jsonfh, ",%c", sp) < 0;
+       }
+
+       if (stack[level].compact)
+               return;
        if (!eb)
                eb = fprintf(jsonfh, "\t%.*s", level, indent) < 0;
 }
@@ -107,6 +117,7 @@ void
 json_do_array(const char *name)
 {
        int i, l;
+       char sp = '\n';
 
        if ((l = do_find(ARRAY, name)) > 0) {
                /* array already in use, close element and move on */
@@ -118,10 +129,12 @@ json_do_array(const char *name)
        if (stack[level].type == ARRAY)
                json_do_end();
 
+       if (stack[level].compact)
+               sp = ' ';
        do_comma_indent();
        do_name(name);
        if (!eb)
-               eb = fprintf(jsonfh, "[\n") < 0;
+               eb = fprintf(jsonfh, "[%c", sp) < 0;
 
        if (++level >= JSON_MAX_STACK)
                errx(1, "json stack too deep");
@@ -129,12 +142,15 @@ json_do_array(const char *name)
        stack[level].name = name;
        stack[level].type = ARRAY;
        stack[level].count = 0;
+       /* inherit compact setting from above level */
+       stack[level].compact = stack[level - 1].compact;
 }
 
 void
-json_do_object(const char *name)
+json_do_object(const char *name, int compact)
 {
        int i, l;
+       char sp = '\n';
 
        if ((l = do_find(OBJECT, name)) > 0) {
                /* roll back to that object and close it */
@@ -142,10 +158,12 @@ json_do_object(const char *name)
                        json_do_end();
        }
 
+       if (compact)
+               sp = ' ';
        do_comma_indent();
        do_name(name);
        if (!eb)
-               eb = fprintf(jsonfh, "{\n") < 0;
+               eb = fprintf(jsonfh, "{%c", sp) < 0;
 
        if (++level >= JSON_MAX_STACK)
                errx(1, "json stack too deep");
@@ -153,23 +171,33 @@ json_do_object(const char *name)
        stack[level].name = name;
        stack[level].type = OBJECT;
        stack[level].count = 0;
+       stack[level].compact = compact;
 }
 
 void
 json_do_end(void)
 {
-       if (stack[level].type == ARRAY) {
-               if (!eb)
-                       eb = fprintf(jsonfh, "\n%.*s]", level, indent) < 0;
-       } else if (stack[level].type == OBJECT) {
+       char c;
+
+       if (stack[level].type == ARRAY)
+               c = ']';
+       else if (stack[level].type == OBJECT)
+               c = '}';
+       else
+               errx(1, "json bad stack state");
+
+       if (!stack[level].compact) {
                if (!eb)
-                       eb = fprintf(jsonfh, "\n%.*s}", level, indent) < 0;
+                       eb = fprintf(jsonfh, "\n%.*s%c", level, indent, c) < 0;
        } else {
-               errx(1, "json bad stack state");
+               if (!eb)
+                       eb = fprintf(jsonfh, " %c", c) < 0;
        }
+
        stack[level].name = NULL;
        stack[level].type = NONE;
        stack[level].count = 0;
+       stack[level].compact = 0;
 
        if (level-- <= 0)
                errx(1, "json stack underflow");
index 5eb8bab..011d38f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: json.h,v 1.2 2023/05/03 07:56:05 claudio Exp $ */
+/*     $OpenBSD: json.h,v 1.3 2023/06/05 14:19:13 claudio Exp $ */
 
 /*
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@@ -22,7 +22,7 @@
 void   json_do_start(FILE *);
 int    json_do_finish(void);
 void   json_do_array(const char *);
-void   json_do_object(const char *);
+void   json_do_object(const char *, int);
 void   json_do_end(void);
 void   json_do_printf(const char *, const char *, ...)
            __attribute__((__format__ (printf, 2, 3)));
index f68872e..dce33e6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output-json.c,v 1.38 2023/05/26 14:57:38 claudio Exp $ */
+/*     $OpenBSD: output-json.c,v 1.39 2023/06/05 14:19:13 claudio Exp $ */
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
  *
@@ -37,7 +37,7 @@ outputheader_json(struct stats *st)
 
        gethostname(hn, sizeof hn);
 
-       json_do_object("metadata");
+       json_do_object("metadata", 0);
 
        json_do_string("buildmachine", hn);
        json_do_string("buildtime", tbuf);
@@ -87,7 +87,7 @@ print_vap(struct vap *v, enum afi afi)
        size_t i;
        int found = 0;
 
-       json_do_object("aspa");
+       json_do_object("aspa", 1);
        json_do_int("customer_asid", v->custasid);
        json_do_int("expires", v->expires);
 
@@ -108,7 +108,7 @@ output_aspa(struct vap_tree *vaps)
 {
        struct vap      *v;
 
-       json_do_object("provider_authorizations");
+       json_do_object("provider_authorizations", 0);
 
        json_do_array("ipv4");
        RB_FOREACH(v, vap_tree, vaps) {
@@ -138,7 +138,7 @@ output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
        RB_FOREACH(v, vrp_tree, vrps) {
                ip_addr_print(&v->addr, v->afi, buf, sizeof(buf));
 
-               json_do_object("roa");
+               json_do_object("roa", 1);
                json_do_int("asn", v->asid);
                json_do_string("prefix", buf);
                json_do_int("maxLength", v->maxlength);
@@ -150,7 +150,7 @@ output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
 
        json_do_array("bgpsec_keys");
        RB_FOREACH(b, brk_tree, brks) {
-               json_do_object("brks");
+               json_do_object("brks", 0);
                json_do_int("asn", b->asid);
                json_do_string("ski", b->ski);
                json_do_string("pubkey", b->pubkey);
index 9ddd896..53ab900 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output-ometric.c,v 1.3 2023/04/26 16:32:41 claudio Exp $ */
+/*     $OpenBSD: output-ometric.c,v 1.4 2023/06/05 14:19:13 claudio Exp $ */
 /*
  * Copyright (c) 2022 Claudio Jeker <claudio@openbsd.org>
  *
@@ -216,7 +216,6 @@ output_ometric(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
        repo_stats_collect(repo_stats, NULL);
        set_common_stats(&st->repo_tal_stats, rpki_obj, NULL);
 
-       ometric_set_int(rpki_repo, st->repos, NULL);
        ometric_set_int_with_labels(rpki_repo, st->rsync_repos,
            OKV("type", "state"), OKV("rsync", "synced"), NULL);
        ometric_set_int_with_labels(rpki_repo, st->rsync_fails,
index fbd0e02..1b58bf2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: print.c,v 1.39 2023/05/30 12:02:22 claudio Exp $ */
+/*     $OpenBSD: print.c,v 1.40 2023/06/05 14:19:13 claudio Exp $ */
 /*
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -161,7 +161,7 @@ as_resources_print(struct cert_as *as, size_t asz)
 
        for (i = 0; i < asz; i++) {
                if (outformats & FORMAT_JSON)
-                       json_do_object("resource");
+                       json_do_object("resource", 1);
                switch (as[i].type) {
                case CERT_AS_ID:
                        if (outformats & FORMAT_JSON) {
@@ -183,7 +183,7 @@ as_resources_print(struct cert_as *as, size_t asz)
                        break;
                case CERT_AS_RANGE:
                        if (outformats & FORMAT_JSON) {
-                               json_do_object("asrange");
+                               json_do_object("asrange", 1);
                                json_do_uint("min", as[i].range.min);
                                json_do_uint("max", as[i].range.max);
                                json_do_end();
@@ -212,7 +212,7 @@ ip_resources_print(struct cert_ip *ips, size_t ipsz, size_t asz)
 
        for (i = 0; i < ipsz; i++) {
                if (outformats & FORMAT_JSON)
-                       json_do_object("resource");
+                       json_do_object("resource", 1);
                switch (ips[i].type) {
                case CERT_IP_INHERIT:
                        if (outformats & FORMAT_JSON) {
@@ -240,7 +240,7 @@ ip_resources_print(struct cert_ip *ips, size_t ipsz, size_t asz)
                        inet_ntop(sockt, ips[i].min, buf1, sizeof(buf1));
                        inet_ntop(sockt, ips[i].max, buf2, sizeof(buf2));
                        if (outformats & FORMAT_JSON) {
-                               json_do_object("ip_range");
+                               json_do_object("ip_range", 1);
                                json_do_string("min", buf1);
                                json_do_string("max", buf2);
                                json_do_end();
@@ -376,7 +376,7 @@ crl_print(const struct crl *p)
                x509_get_time(X509_REVOKED_get0_revocationDate(rev), &t);
                if (serial != NULL) {
                        if (outformats & FORMAT_JSON) {
-                               json_do_object("cert");
+                               json_do_object("cert", 1);
                                json_do_string("serial", serial);
                                json_do_string("date", time2str(t));
                                json_do_end();
@@ -436,7 +436,7 @@ mft_print(const X509 *x, const struct mft *p)
                        errx(1, "base64_encode failure");
 
                if (outformats & FORMAT_JSON) {
-                       json_do_object("filehash");
+                       json_do_object("filehash", 1);
                        json_do_string("filename", p->files[i].file);
                        json_do_string("hash", hash);
                        json_do_end();
@@ -495,7 +495,7 @@ roa_print(const X509 *x, const struct roa *p)
                    p->ips[i].afi, buf, sizeof(buf));
 
                if (outformats & FORMAT_JSON) {
-                       json_do_object("vrp");
+                       json_do_object("vrp", 1);
                        json_do_string("prefix", buf);
                        json_do_uint("asid", p->asid);
                        json_do_uint("maxlen", p->ips[i].maxlength);
@@ -591,7 +591,7 @@ rsc_print(const X509 *x, const struct rsc *p)
                        errx(1, "base64_encode failure");
 
                if (outformats & FORMAT_JSON) {
-                       json_do_object("filehash");
+                       json_do_object("filehash", 1);
                        if (p->files[i].filename)
                                json_do_string("filename",
                                    p->files[i].filename);
@@ -616,7 +616,7 @@ static void
 aspa_provider(uint32_t as, enum afi afi)
 {
        if (outformats & FORMAT_JSON) {
-               json_do_object("aspa");
+               json_do_object("aspa", 1);
                json_do_uint("asid", as);
                if (afi == AFI_IPV4)
                        json_do_string("afi_limit", "ipv4");
@@ -713,7 +713,7 @@ takey_print(char *name, const struct takey *t)
                errx(1, "base64_encode failed in %s", __func__);
 
        if (outformats & FORMAT_JSON) {
-               json_do_object("takey");
+               json_do_object("takey", 0);
                json_do_string("name", name);
                json_do_array("comments");
                for (i = 0; i < t->commentsz; i++)
@@ -824,7 +824,7 @@ geofeed_print(const X509 *x, const struct geofeed *p)
                ip_addr_print(&p->geoips[i].ip->ip, p->geoips[i].ip->afi, buf,
                    sizeof(buf));
                if (outformats & FORMAT_JSON) {
-                       json_do_object("geoip");
+                       json_do_object("geoip", 1);
                        json_do_string("prefix", buf);
                        json_do_string("location", p->geoips[i].loc);
                        json_do_end();