From: Karel Zak Date: Thu, 12 Nov 2020 10:21:50 +0000 (+0100) Subject: libsmartcols: use lib/jsonwrt.c for JSON X-Git-Tag: v2.37-rc1~384 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=618a6ccbfd41d4ad3864eecab3d7d5091314d53e;p=thirdparty%2Futil-linux.git libsmartcols: use lib/jsonwrt.c for JSON Signed-off-by: Karel Zak --- diff --git a/libsmartcols/src/Makemodule.am b/libsmartcols/src/Makemodule.am index fff314c73e..e3f4e7df17 100644 --- a/libsmartcols/src/Makemodule.am +++ b/libsmartcols/src/Makemodule.am @@ -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 index b00c3d8b89..0000000000 --- a/libsmartcols/src/fput.c +++ /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; -} diff --git a/libsmartcols/src/print-api.c b/libsmartcols/src/print-api.c index 9a9f2df942..89dd3bf9b0 100644 --- a/libsmartcols/src/print-api.c +++ b/libsmartcols/src/print-api.c @@ -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; } diff --git a/libsmartcols/src/print.c b/libsmartcols/src/print.c index 1172533604..9d78c90b3e 100644 --- a/libsmartcols/src/print.c +++ b/libsmartcols/src/print.c @@ -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: { diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h index e36bb5171b..5e9b9ec561 100644 --- a/libsmartcols/src/smartcolsP.h +++ b/libsmartcols/src/smartcolsP.h @@ -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;