diff options
author | Maxim Anisimov <maxim.anisimov.ua@gmail.com> | 2019-08-08 11:12:33 +0300 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-08-28 18:17:55 +0200 |
commit | d1ac5ca16bfbc2475eb379b48e981e035f908b50 (patch) | |
tree | f94a5b4fb4fa6bcf88834c41ced191a6f9a994c9 /cli/mmcli-output.c | |
parent | b0ec3030a3e5519d75c2268fa20062edd2dacf4e (diff) |
mmcli: add json output support
Signed-off-by: Maxim Anisimov <maxim.anisimov.ua@gmail.com>
Diffstat (limited to 'cli/mmcli-output.c')
-rw-r--r-- | cli/mmcli-output.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/cli/mmcli-output.c b/cli/mmcli-output.c index 7699f25e..5b2af008 100644 --- a/cli/mmcli-output.c +++ b/cli/mmcli-output.c @@ -1072,6 +1072,119 @@ dump_output_list_keyvalue (MmcF field) } /******************************************************************************/ +/* Json-friendly output */ + +static gint +list_sort_by_keys (const OutputItem *item_a, + const OutputItem *item_b) +{ + return g_strcmp0(field_infos[item_a->field].key, field_infos[item_b->field].key); +} + +static void +dump_output_json (void) +{ + GList *l; + MmcF current_field = MMC_F_UNKNOWN; + gchar **current_path = NULL; + guint cur_dlen = 0; + GRegex *escape_regex; + + output_items = g_list_sort (output_items, (GCompareFunc) list_sort_by_keys); + escape_regex = g_regex_new("'", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL); + + g_print("{"); + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l = (OutputItem *)(l->data); + + if (current_field != item_l->field) { + guint new_dlen; + guint iter = 0; + gchar **new_path; + + new_path = g_strsplit(field_infos[item_l->field].key, ".", -1); + new_dlen = g_strv_length(new_path) - 1; + if (current_path) { + guint min_dlen = MIN (cur_dlen, new_dlen); + while(iter < min_dlen && g_strcmp0(current_path[iter], new_path[iter]) == 0) + iter++; + + g_strfreev(current_path); + + if (iter < min_dlen || new_dlen < cur_dlen) + for(min_dlen = iter; min_dlen < cur_dlen; min_dlen++) + g_print("}"); + + g_print(","); + } + + while(iter < new_dlen) + g_print("\"%s\":{", new_path[iter++]); + + cur_dlen = new_dlen; + current_path = new_path; + current_field = item_l->field; + } else { + g_print(","); + } + if (item_l->type == VALUE_TYPE_SINGLE) { + OutputItemSingle *single = (OutputItemSingle *) item_l; + gchar *escaped = NULL; + + if (single->value) + escaped = g_regex_replace_literal(escape_regex, single->value, -1, 0, "\"", 0, NULL); + + g_print ("\"%s\":\"%s\"", current_path[cur_dlen], escaped ? escaped : "--"); + g_free (escaped); + } else if (item_l->type == VALUE_TYPE_MULTIPLE) { + OutputItemMultiple *multiple = (OutputItemMultiple *) item_l; + guint i, n = multiple->values ? g_strv_length (multiple->values) : 0; + + g_print ("\"%s\":[", current_path[cur_dlen]); + for(i = 0; i < n; i++) { + gchar *escaped = g_regex_replace_literal(escape_regex, multiple->values[i], -1, 0, "\"", 0, NULL); + g_print("\"%s\"", escaped); + if (i < n - 1) + g_print(","); + g_free (escaped); + } + g_print("]"); + } else { + g_assert_not_reached (); + } + } + while(cur_dlen--) + g_print("}"); + g_print("}\n"); + if (current_path) + g_strfreev(current_path); + g_regex_unref(escape_regex); +} + +static void +dump_output_list_json (MmcF field) +{ + GList *l; + g_assert (field != MMC_F_UNKNOWN); + g_print("{\"%s\":[", field_infos[field].key); + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l; + OutputItemListitem *listitem; + item_l = (OutputItem *)(l->data); + g_assert (item_l->type == VALUE_TYPE_LISTITEM); + listitem = (OutputItemListitem *)item_l; + g_assert (listitem->value); + + /* All items must be of same type */ + g_assert_cmpint (item_l->field, ==, field); + g_print("\"%s\"", listitem->value); + if (g_list_next(l)) + g_print(","); + } + g_print("]}\n"); +} + +/******************************************************************************/ /* Dump output */ void @@ -1086,6 +1199,9 @@ mmcli_output_dump (void) case MMC_OUTPUT_TYPE_KEYVALUE: dump_output_keyvalue (); break; + case MMC_OUTPUT_TYPE_JSON: + dump_output_json (); + break; } g_list_free_full (output_items, (GDestroyNotify) output_item_free); @@ -1106,6 +1222,9 @@ mmcli_output_list_dump (MmcF field) case MMC_OUTPUT_TYPE_KEYVALUE: dump_output_list_keyvalue (field); break; + case MMC_OUTPUT_TYPE_JSON: + dump_output_list_json (field); + break; } g_list_free_full (output_items, (GDestroyNotify) output_item_free); |