diff --git a/src/cmd/flux-kvs.c b/src/cmd/flux-kvs.c index 040ff0157819..829018eaf374 100644 --- a/src/cmd/flux-kvs.c +++ b/src/cmd/flux-kvs.c @@ -304,37 +304,73 @@ int main (int argc, char *argv[]) return (exitval); } -static void output_key_json_object (const char *key, json_t *o) +static void kv_printf (const char *key, int maxcol, const char *fmt, ...) +{ + va_list ap; + int rc; + char *val, *kv, *p; + bool overflow = false; + + assert (maxcol == 0 || maxcol > 3); + + va_start (ap, fmt); + rc = vasprintf (&val, fmt, ap); + va_end (ap); + + if (rc < 0) + log_err_exit ("%s", __FUNCTION__); + + if (asprintf (&kv, "%s%s%s", key ? key : "", + key ? " = " : "", + val) < 0) + log_err_exit ("%s", __FUNCTION__); + + if (maxcol != 0) { // perform truncation + if ((p = strchr (kv, '\n'))) { + *p = '\0'; + overflow = true; + } + if (strlen (kv) > maxcol - 3) { + kv[maxcol - 3] = '\0'; + overflow = true; + } + } + printf ("%s%s\n", kv, + overflow ? "..." : ""); + + free (val); + free (kv); +} + +static void output_key_json_object (const char *key, json_t *o, int maxcol) { char *s; - if (key) - printf ("%s = ", key); switch (json_typeof (o)) { case JSON_NULL: - printf ("nil\n"); + kv_printf (key, maxcol, "nil"); break; case JSON_TRUE: - printf ("true\n"); + kv_printf (key, maxcol, "true"); break; case JSON_FALSE: - printf ("false\n"); + kv_printf (key, maxcol, "false"); break; case JSON_REAL: - printf ("%f\n", json_real_value (o)); + kv_printf (key, maxcol, "%f", json_real_value (o)); break; case JSON_INTEGER: - printf ("%lld\n", (long long)json_integer_value (o)); + kv_printf (key, maxcol, "%lld", (long long)json_integer_value (o)); break; case JSON_STRING: - printf ("%s\n", json_string_value (o)); + kv_printf (key, maxcol, "%s", json_string_value (o)); break; case JSON_ARRAY: case JSON_OBJECT: default: if (!(s = json_dumps (o, JSON_SORT_KEYS))) log_msg_exit ("json_dumps failed"); - printf ("%s\n", s); + kv_printf (key, maxcol, "%s", s); free (s); break; } @@ -352,7 +388,7 @@ static void output_key_json_str (const char *key, if (!(o = json_loads (json_str, JSON_DECODE_ANY, &error))) log_msg_exit ("%s: %s (line %d column %d)", arg, error.text, error.line, error.column); - output_key_json_object (key, o); + output_key_json_object (key, o, 0); json_decref (o); } @@ -802,20 +838,20 @@ int cmd_dropcache (optparse_t *p, int argc, char **argv) return (0); } -static void dump_kvs_val (const char *key, const char *json_str) +static void dump_kvs_val (const char *key, int maxcol, const char *value) { json_t *o; - json_error_t error; - if (!json_str) - json_str = "null"; - if (!(o = json_loads (json_str, JSON_DECODE_ANY, &error))) { - printf ("%s: %s (line %d column %d)\n", - key, error.text, error.line, error.column); - return; + if (!value) { + kv_printf (key, maxcol, "NULL"); + } + else if ((o = json_loads (value, JSON_DECODE_ANY, NULL))) { + output_key_json_object (key, o, maxcol); + json_decref (o); + } + else { + kv_printf (key, maxcol, value); } - output_key_json_object (key, o); - json_decref (o); } static void dump_kvs_dir (const flux_kvsdir_t *dir, bool Ropt, bool dopt) @@ -826,6 +862,7 @@ static void dump_kvs_dir (const flux_kvsdir_t *dir, bool Ropt, bool dopt) flux_kvsitr_t *itr; const char *name; char *key; + const int maxcol = 79; itr = flux_kvsitr_create (dir); while ((name = flux_kvsitr_next (itr))) { @@ -850,11 +887,17 @@ static void dump_kvs_dir (const flux_kvsdir_t *dir, bool Ropt, bool dopt) printf ("%s.\n", key); } else { if (!dopt) { - const char *json_str; - if (!(f = flux_kvs_lookupat (h, 0, key, rootref)) - || flux_kvs_lookup_get (f, &json_str) < 0) + const char *value; + const void *buf; + int len; + if (!(f = flux_kvs_lookupat (h, 0, key, rootref))) + log_err_exit ("%s", key); + if (flux_kvs_lookup_get (f, &value) == 0) // null terminated + dump_kvs_val (key, maxcol, value); + else if (flux_kvs_lookup_get_raw (f, &buf, &len) == 0) + kv_printf (key, maxcol, "%.*s", len, buf); + else log_err_exit ("%s", key); - dump_kvs_val (key, json_str); flux_future_destroy (f); } else