diff options
author | Donatas Abraitis <donatas.abraitis@gmail.com> | 2021-11-18 09:33:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-18 09:33:52 +0100 |
commit | d86cf7aa6584265419733b6c7419b9864df08dc2 (patch) | |
tree | 87d931e6b55067d788bbe3687bfab7352fcdeb6e /lib | |
parent | Merge pull request #10089 from donaldsharp/really_remove (diff) | |
parent | lib: use json-printf in filter code (diff) | |
download | frr-d86cf7aa6584265419733b6c7419b9864df08dc2.tar.xz frr-d86cf7aa6584265419733b6c7419b9864df08dc2.zip |
Merge pull request #10084 from opensourcerouting/json-sugar
lib: make JSON output less painful/boilerplate-y
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ferr.c | 8 | ||||
-rw-r--r-- | lib/filter.c | 56 | ||||
-rw-r--r-- | lib/json.c | 24 | ||||
-rw-r--r-- | lib/json.h | 48 | ||||
-rw-r--r-- | lib/plist.c | 9 | ||||
-rw-r--r-- | lib/routemap.c | 9 | ||||
-rw-r--r-- | lib/vty.c | 16 | ||||
-rw-r--r-- | lib/vty.h | 8 |
8 files changed, 115 insertions, 63 deletions
diff --git a/lib/ferr.c b/lib/ferr.c index 513ef5ebe..e5b6d7552 100644 --- a/lib/ferr.c +++ b/lib/ferr.c @@ -157,13 +157,7 @@ void log_ref_display(struct vty *vty, uint32_t code, bool json) } } - if (json) { - const char *str = json_object_to_json_string_ext( - top, JSON_C_TO_STRING_PRETTY); - vty_out(vty, "%s\n", str); - json_object_free(top); - } - + vty_json(vty, top); list_delete(&errlist); } diff --git a/lib/filter.c b/lib/filter.c index 9c80808fe..fc4b578e7 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -558,18 +558,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi, json_rule); else { if (json) { - char buf[BUFSIZ]; - - json_object_string_add( - json_rule, "address", - inet_ntop(AF_INET, - &filter->addr, buf, - sizeof(buf))); - json_object_string_add( - json_rule, "mask", - inet_ntop(AF_INET, - &filter->addr_mask, - buf, sizeof(buf))); + json_object_string_addf( + json_rule, "address", "%pI4", + &filter->addr); + json_object_string_addf( + json_rule, "mask", "%pI4", + &filter->addr_mask); } else { if (filter->addr_mask.s_addr == 0xffffffff) @@ -589,14 +583,7 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi, } } - if (json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - - return CMD_SUCCESS; + return vty_json(vty, json); } /* show MAC access list - this only has MAC filters for now*/ @@ -681,21 +668,15 @@ static void config_write_access_cisco(struct vty *vty, struct filter *mfilter, filter = &mfilter->u.cfilter; if (json) { - char buf[BUFSIZ]; - json_object_boolean_add(json, "extended", !!filter->extended); - json_object_string_add( - json, "sourceAddress", - inet_ntop(AF_INET, &filter->addr, buf, sizeof(buf))); - json_object_string_add(json, "sourceMask", - inet_ntop(AF_INET, &filter->addr_mask, - buf, sizeof(buf))); - json_object_string_add( - json, "destinationAddress", - inet_ntop(AF_INET, &filter->mask, buf, sizeof(buf))); - json_object_string_add(json, "destinationMask", - inet_ntop(AF_INET, &filter->mask_mask, - buf, sizeof(buf))); + json_object_string_addf(json, "sourceAddress", "%pI4", + &filter->addr); + json_object_string_addf(json, "sourceMask", "%pI4", + &filter->addr_mask); + json_object_string_addf(json, "destinationAddress", "%pI4", + &filter->mask); + json_object_string_addf(json, "destinationMask", "%pI4", + &filter->mask_mask); } else { vty_out(vty, " ip"); if (filter->addr_mask.s_addr == 0xffffffff) @@ -730,16 +711,13 @@ static void config_write_access_zebra(struct vty *vty, struct filter *mfilter, p = &filter->prefix; if (json) { - json_object_string_add(json, "prefix", - prefix2str(p, buf, sizeof(buf))); + json_object_string_addf(json, "prefix", "%pFX", p); json_object_boolean_add(json, "exact-match", !!filter->exact); } else { if (p->prefixlen == 0 && !filter->exact) vty_out(vty, " any"); else if (p->family == AF_INET6 || p->family == AF_INET) - vty_out(vty, " %s/%d%s", - inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), - p->prefixlen, + vty_out(vty, " %pFX%s", p, filter->exact ? " exact-match" : ""); else if (p->family == AF_ETHERNET) { if (p->prefixlen == 0) diff --git a/lib/json.c b/lib/json.c index cfba6ea3b..854a3d59d 100644 --- a/lib/json.c +++ b/lib/json.c @@ -39,17 +39,41 @@ bool use_json(const int argc, struct cmd_token *argv[]) return false; } +struct json_object *json_object_new_stringv(const char *fmt, va_list args) +{ + struct json_object *ret; + char *text, buf[256]; + + text = vasnprintfrr(MTYPE_TMP, buf, sizeof(buf), fmt, args); + ret = json_object_new_string(text); + + if (text != buf) + XFREE(MTYPE_TMP, text); + return ret; +} + void json_array_string_add(json_object *json, const char *str) { json_object_array_add(json, json_object_new_string(str)); } +void json_array_string_addv(json_object *json, const char *fmt, va_list args) +{ + json_object_array_add(json, json_object_new_stringv(fmt, args)); +} + void json_object_string_add(struct json_object *obj, const char *key, const char *s) { json_object_object_add(obj, key, json_object_new_string(s)); } +void json_object_string_addv(struct json_object *obj, const char *key, + const char *fmt, va_list args) +{ + json_object_object_add(obj, key, json_object_new_stringv(fmt, args)); +} + void json_object_int_add(struct json_object *obj, const char *key, int64_t i) { json_object_object_add(obj, key, json_object_new_int64(i)); diff --git a/lib/json.h b/lib/json.h index fe208f4fa..9d33ac7ae 100644 --- a/lib/json.h +++ b/lib/json.h @@ -26,6 +26,7 @@ extern "C" { #endif #include "command.h" +#include "printfrr.h" #include <json-c/json.h> /* @@ -59,6 +60,53 @@ extern struct json_object *json_object_lock(struct json_object *obj); extern void json_object_free(struct json_object *obj); extern void json_array_string_add(json_object *json, const char *str); +/* printfrr => json helpers */ + +PRINTFRR(3, 0) +extern void json_object_string_addv(struct json_object *obj, const char *key, + const char *fmt, va_list args); +PRINTFRR(3, 4) +static inline void json_object_string_addf(struct json_object *obj, + const char *key, const char *fmt, + ...) +{ + va_list args; + + va_start(args, fmt); + json_object_string_addv(obj, key, fmt, args); + va_end(args); +} + +PRINTFRR(2, 0) +extern void json_array_string_addv(json_object *json, const char *fmt, + va_list args); +PRINTFRR(2, 3) +static inline void json_array_string_addf(struct json_object *obj, + const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + json_array_string_addv(obj, fmt, args); + va_end(args); +} + +PRINTFRR(1, 0) +extern struct json_object *json_object_new_stringv(const char *fmt, + va_list args); +PRINTFRR(1, 2) +static inline struct json_object *json_object_new_stringf(const char *fmt, ...) +{ + struct json_object *ret; + va_list args; + + va_start(args, fmt); + ret = json_object_new_stringv(fmt, args); + va_end(args); + + return ret; +} + #define JSON_STR "JavaScript Object Notation\n" /* NOTE: json-c lib has following commit 316da85 which diff --git a/lib/plist.c b/lib/plist.c index a53b087a4..0b3de88d9 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1127,14 +1127,7 @@ static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name, master, dtype, seqnum); } - if (uj) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - - return CMD_SUCCESS; + return vty_json(vty, json); } static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi, diff --git a/lib/routemap.c b/lib/routemap.c index 6227ebf15..a004e23b8 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -1026,14 +1026,7 @@ static int vty_show_route_map(struct vty *vty, const char *name, bool use_json) list_delete(&maplist); } - if (use_json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } - - return CMD_SUCCESS; + return vty_json(vty, json); } /* Unused route map details */ @@ -48,6 +48,7 @@ #include "lib_errors.h" #include "northbound_cli.h" #include "printfrr.h" +#include "json.h" #include <arpa/telnet.h> #include <termios.h> @@ -280,6 +281,21 @@ done: return len; } +int vty_json(struct vty *vty, struct json_object *json) +{ + const char *text; + + if (!json) + return CMD_SUCCESS; + + text = json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_NOSLASHESCAPE); + vty_out(vty, "%s\n", text); + json_object_free(json); + + return CMD_SUCCESS; +} + /* Output current time to the vty. */ void vty_time_print(struct vty *vty, int cr) { @@ -39,6 +39,8 @@ extern "C" { #endif +struct json_object; + #define VTY_BUFSIZ 4096 #define VTY_MAXHIST 20 #define VTY_MAXDEPTH 8 @@ -321,7 +323,11 @@ extern struct vty *vty_stdio(void (*atclose)(int isexit)); extern int vty_out(struct vty *, const char *, ...) PRINTFRR(2, 3); extern void vty_frame(struct vty *, const char *, ...) PRINTFRR(2, 3); extern void vty_endframe(struct vty *, const char *); -bool vty_set_include(struct vty *vty, const char *regexp); +extern bool vty_set_include(struct vty *vty, const char *regexp); +/* returns CMD_SUCCESS so you can do a one-line "return vty_json(...)" + * NULL check and json_object_free() is included. + */ +extern int vty_json(struct vty *vty, struct json_object *json); extern bool vty_read_config(struct nb_config *config, const char *config_file, char *config_default_dir); |