]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: use lib/jsonwrt.c for JSON
authorKarel Zak <kzak@redhat.com>
Thu, 12 Nov 2020 10:21:50 +0000 (11:21 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 12 Nov 2020 10:21:50 +0000 (11:21 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/src/Makemodule.am
libsmartcols/src/fput.c [deleted file]
libsmartcols/src/print-api.c
libsmartcols/src/print.c
libsmartcols/src/smartcolsP.h

index fff314c73e6b3b7c0d31707e4d23a9a9835e25f5..e3f4e7df17e10418830cc33a6ef21e4fdc9b360e 100644 (file)
@@ -16,7 +16,6 @@ libsmartcols_la_SOURCES= \
        libsmartcols/src/line.c \
        libsmartcols/src/table.c \
        libsmartcols/src/print.c \
-       libsmartcols/src/fput.c \
        libsmartcols/src/print-api.c \
        libsmartcols/src/version.c \
        libsmartcols/src/buffer.c \
diff --git a/libsmartcols/src/fput.c b/libsmartcols/src/fput.c
deleted file mode 100644 (file)
index b00c3d8..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "carefulputc.h"
-#include "smartcolsP.h"
-
-void fput_indent(struct libscols_table *tb)
-{
-       int i;
-
-       for (i = 0; i <= tb->indent; i++)
-               fputs("   ", tb->out);
-}
-
-void fput_table_open(struct libscols_table *tb)
-{
-       tb->indent = 0;
-
-       if (scols_table_is_json(tb)) {
-               fputc('{', tb->out);
-               fputs(linesep(tb), tb->out);
-
-               fput_indent(tb);
-               fputs_quoted(tb->name, tb->out);
-               fputs(": [", tb->out);
-               fputs(linesep(tb), tb->out);
-
-               tb->indent++;
-               tb->indent_last_sep = 1;
-       }
-}
-
-void fput_table_close(struct libscols_table *tb)
-{
-       tb->indent--;
-
-       if (scols_table_is_json(tb)) {
-               fput_indent(tb);
-               fputc(']', tb->out);
-               tb->indent--;
-               fputs(linesep(tb), tb->out);
-               fputc('}', tb->out);
-               tb->indent_last_sep = 1;
-       }
-}
-
-void fput_children_open(struct libscols_table *tb)
-{
-       if (scols_table_is_json(tb)) {
-               fputc(',', tb->out);
-               fputs(linesep(tb), tb->out);
-               fput_indent(tb);
-               fputs("\"children\": [", tb->out);
-       }
-       /* between parent and child is separator */
-       fputs(linesep(tb), tb->out);
-       tb->indent_last_sep = 1;
-       tb->indent++;
-       tb->termlines_used++;
-}
-
-void fput_children_close(struct libscols_table *tb)
-{
-       tb->indent--;
-
-       if (scols_table_is_json(tb)) {
-               fput_indent(tb);
-               fputc(']', tb->out);
-               fputs(linesep(tb), tb->out);
-               tb->indent_last_sep = 1;
-       }
-}
-
-void fput_line_open(struct libscols_table *tb)
-{
-       if (scols_table_is_json(tb)) {
-               fput_indent(tb);
-               fputc('{', tb->out);
-               tb->indent_last_sep = 0;
-       }
-       tb->indent++;
-}
-
-void fput_line_close(struct libscols_table *tb, int last, int last_in_table)
-{
-       tb->indent--;
-       if (scols_table_is_json(tb)) {
-               if (tb->indent_last_sep)
-                       fput_indent(tb);
-               fputs(last ? "}" : "},", tb->out);
-               if (!tb->no_linesep)
-                       fputs(linesep(tb), tb->out);
-
-       } else if (tb->no_linesep == 0 && last_in_table == 0) {
-               fputs(linesep(tb), tb->out);
-               tb->termlines_used++;
-       }
-
-       tb->indent_last_sep = 1;
-}
index 9a9f2df9420a0aec601bfc4b1c663847c1ac2889..89dd3bf9b0f7f4a0db0ecbda5285067e04a0f3d8 100644 (file)
@@ -117,8 +117,11 @@ static int do_print_table(struct libscols_table *tb, int *is_empty)
        if (list_empty(&tb->tb_lines)) {
                DBG(TAB, ul_debugobj(tb, "ignore -- no lines"));
                if (scols_table_is_json(tb)) {
-                       fput_table_open(tb);
-                       fput_table_close(tb);
+                       ul_jsonwrt_init(&tb->json, tb->out, 0);
+                       ul_jsonwrt_root_open(&tb->json);
+                       ul_jsonwrt_array_open(&tb->json, tb->name);
+                       ul_jsonwrt_array_close(&tb->json, 1);
+                       ul_jsonwrt_root_close(&tb->json);
                } else if (is_empty)
                        *is_empty = 1;
                return 0;
@@ -129,7 +132,10 @@ static int do_print_table(struct libscols_table *tb, int *is_empty)
        if (rc)
                return rc;
 
-       fput_table_open(tb);
+       if (scols_table_is_json(tb)) {
+               ul_jsonwrt_root_open(&tb->json);
+               ul_jsonwrt_array_open(&tb->json, tb->name);
+       }
 
        if (tb->format == SCOLS_FMT_HUMAN)
                __scols_print_title(tb);
@@ -143,7 +149,10 @@ static int do_print_table(struct libscols_table *tb, int *is_empty)
        else
                rc = __scols_print_table(tb, buf);
 
-       fput_table_close(tb);
+       if (scols_table_is_json(tb)) {
+               ul_jsonwrt_array_close(&tb->json, 1);
+               ul_jsonwrt_root_close(&tb->json);
+       }
 done:
        __scols_cleanup_printing(tb, buf);
        return rc;
@@ -162,7 +171,7 @@ int scols_print_table(struct libscols_table *tb)
        int empty = 0;
        int rc = do_print_table(tb, &empty);
 
-       if (rc == 0 && !empty)
+       if (rc == 0 && !empty && !scols_table_is_json(tb))
                fputc('\n', tb->out);
        return rc;
 }
index 1172533604f3e1bdd260a2740241f752e434f7c3..9d78c90b3ef0c078a7262d51f3ae02324e6c71d0 100644 (file)
@@ -444,6 +444,7 @@ static int print_data(struct libscols_table *tb,
        size_t len = 0, i, width, bytes;
        const char *color = NULL;
        char *data, *nextchunk;
+       const char *name = NULL;
        int is_last;
 
        assert(tb);
@@ -453,8 +454,16 @@ static int print_data(struct libscols_table *tb,
        if (!data)
                data = "";
 
+       if (tb->format != SCOLS_FMT_HUMAN)
+               name = scols_cell_get_data(&cl->header);
+
        is_last = is_last_column(cl);
 
+       if (is_last && scols_table_is_json(tb) &&
+           scols_table_is_tree(tb) && has_children(ln))
+               /* "children": [] is the real last value */
+               is_last = 0;
+
        switch (tb->format) {
        case SCOLS_FMT_RAW:
                fputs_nonblank(data, tb->out);
@@ -463,37 +472,28 @@ static int print_data(struct libscols_table *tb,
                return 0;
 
        case SCOLS_FMT_EXPORT:
-               fprintf(tb->out, "%s=", scols_cell_get_data(&cl->header));
+               fprintf(tb->out, "%s=", name);
                fputs_quoted(data, tb->out);
                if (!is_last)
                        fputs(colsep(tb), tb->out);
                return 0;
 
        case SCOLS_FMT_JSON:
-               fputs_quoted_json_lower(scols_cell_get_data(&cl->header), tb->out);
-               fputs(":", tb->out);
                switch (cl->json_type) {
-                       case SCOLS_JSON_STRING:
-                               if (!*data)
-                                       fputs("null", tb->out);
-                               else
-                                       fputs_quoted_json(data, tb->out);
-                               break;
-                       case SCOLS_JSON_NUMBER:
-                               if (!*data)
-                                       fputs("null", tb->out);
-                               else
-                                       fputs(data, tb->out);
-                               break;
-                       case SCOLS_JSON_BOOLEAN:
-                               fputs(!*data ? "false" :
-                                     *data == '0' ? "false" :
-                                     *data == 'N' || *data == 'n' ? "false" : "true",
-                                     tb->out);
-                               break;
+               case SCOLS_JSON_STRING:
+                       ul_jsonwrt_value_s(&tb->json, name, data, is_last);
+                       break;
+               case SCOLS_JSON_NUMBER:
+                       ul_jsonwrt_value_raw(&tb->json, name, data, is_last);
+                       break;
+               case SCOLS_JSON_BOOLEAN:
+                       ul_jsonwrt_value_boolean(&tb->json, name,
+                               !*data ? 0 :
+                               *data == '0' ? 0 :
+                               *data == 'N' || *data == 'n' ? 0 : 1,
+                               is_last);
+                       break;
                }
-               if (!is_last)
-                       fputs(", ", tb->out);
                return 0;
 
        case SCOLS_FMT_HUMAN:
@@ -871,9 +871,17 @@ int __scols_print_range(struct libscols_table *tb,
 
                int last = scols_iter_is_last(itr);
 
-               fput_line_open(tb);
+               if (scols_table_is_json(tb))
+                       ul_jsonwrt_object_open(&tb->json, NULL);
+
                rc = print_line(tb, ln, buf);
-               fput_line_close(tb, last, last);
+
+               if (scols_table_is_json(tb))
+                       ul_jsonwrt_object_close(&tb->json, last);
+               else if (last == 0 && tb->no_linesep == 0) {
+                       fputs(linesep(tb), tb->out);
+                       tb->termlines_used++;
+               }
 
                if (end && ln == end)
                        break;
@@ -905,16 +913,22 @@ static int print_tree_line(struct libscols_table *tb,
 
        DBG(LINE, ul_debugobj(ln, "   printing tree line"));
 
-       fput_line_open(tb);
+       if (scols_table_is_json(tb))
+               ul_jsonwrt_object_open(&tb->json, NULL);
+
        rc = print_line(tb, ln, buf);
        if (rc)
                return rc;
 
-       if (has_children(ln))
-               fput_children_open(tb);
-
-       else {
-               int last_in_tree = scols_walk_is_last(tb, ln);
+       if (has_children(ln)) {
+               if (scols_table_is_json(tb))
+                       ul_jsonwrt_array_open(&tb->json, "children");
+               else {
+                       /* between parent and child is separator */
+                       fputs(linesep(tb), tb->out);
+                       tb->termlines_used++;
+               }
+       } else {
                int last;
 
                /* terminate all open last children for JSON */
@@ -923,20 +937,20 @@ static int print_tree_line(struct libscols_table *tb,
                                last = (is_child(ln) && is_last_child(ln)) ||
                                       (is_tree_root(ln) && is_last_tree_root(tb, ln));
 
-                               fput_line_close(tb, last, last_in_tree);
+                               ul_jsonwrt_object_close(&tb->json, last);
                                if (last && is_child(ln))
-                                       fput_children_close(tb);
-
-                               last_in_tree = 0;
+                                       ul_jsonwrt_array_close(&tb->json, last);
                                ln = ln->parent;
                        } while(ln && last);
 
-               } else {
-                       /* standard output */
-                       last = (is_child(ln) && is_last_child(ln)) ||
-                              (is_group_child(ln) && is_last_group_child(ln));
+               } else if (tb->no_linesep == 0) {
+                       int last_in_tree = scols_walk_is_last(tb, ln);
 
-                       fput_line_close(tb, last, last_in_tree);
+                       if (last_in_tree == 0) {
+                               /* standard output */
+                               fputs(linesep(tb), tb->out);
+                               tb->termlines_used++;
+                       }
                }
        }
 
@@ -1029,8 +1043,8 @@ int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffe
                extra_bufsz += tb->ncols;                       /* separator between columns */
                break;
        case SCOLS_FMT_JSON:
-               if (tb->format == SCOLS_FMT_JSON)
-                       extra_bufsz += tb->nlines * 3;          /* indentation */
+               ul_jsonwrt_init(&tb->json, tb->out, 0);
+               extra_bufsz += tb->nlines * 3;          /* indentation */
                /* fallthrough */
        case SCOLS_FMT_EXPORT:
        {
index e36bb5171b0d0691553262127b642d7252be9958..5e9b9ec5619de9123477c52adb8711160249781c 100644 (file)
@@ -15,6 +15,7 @@
 #include "list.h"
 #include "strutils.h"
 #include "color-names.h"
+#include "jsonwrt.h"
 #include "debug.h"
 
 #include "libsmartcols.h"
@@ -224,8 +225,8 @@ struct libscols_table {
        struct libscols_symbols *symbols;
        struct libscols_cell    title;          /* optional table title (for humans) */
 
-       int     indent;         /* indentation counter */
-       int     indent_last_sep;/* last printed has been line separator */
+       struct ul_jsonwrt       json;           /* JSON formatting */
+
        int     format;         /* SCOLS_FMT_* */
 
        size_t  termlines_used; /* printed line counter */
@@ -357,17 +358,6 @@ int __scols_print_range(struct libscols_table *tb,
                         struct libscols_iter *itr,
                         struct libscols_line *end);
 
-/*
- * fput.c
- */
-extern void fput_indent(struct libscols_table *tb);
-extern void fput_table_open(struct libscols_table *tb);
-extern void fput_table_close(struct libscols_table *tb);
-extern void fput_children_open(struct libscols_table *tb);
-extern void fput_children_close(struct libscols_table *tb);
-extern void fput_line_open(struct libscols_table *tb);
-extern void fput_line_close(struct libscols_table *tb, int last, int last_in_table);
-
 static inline int is_tree_root(struct libscols_line *ln)
 {
        return ln && !ln->parent && !ln->parent_group;