api: replace print functions wth format

Type: improvement
Change-Id: I7f7050c19453a69a7fb6c5e62f8f57db847d9144
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/plugins/acl/acl.c b/src/plugins/acl/acl.c
index a7b8104..eb38150 100644
--- a/src/plugins/acl/acl.c
+++ b/src/plugins/acl/acl.c
@@ -36,7 +36,6 @@
 #include <acl/acl.api_enum.h>
 #include <acl/acl.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #include "fa_node.h"
 #include "public_inlines.h"
diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c
index 7514a8e..0c21868 100644
--- a/src/plugins/acl/acl_test.c
+++ b/src/plugins/acl/acl_test.c
@@ -36,8 +36,6 @@
 /* Declare message IDs */
 #include <acl/acl.api_enum.h>
 #include <acl/acl.api_types.h>
-#define vl_print(handle, ...)
-#undef vl_print
 #define vl_endianfun            /* define message structures */
 #include <acl/acl.api.h>
 #undef vl_endianfun
diff --git a/src/plugins/adl/adl_api.c b/src/plugins/adl/adl_api.c
index dba3b0c..8bd805d 100644
--- a/src/plugins/adl/adl_api.c
+++ b/src/plugins/adl/adl_api.c
@@ -30,7 +30,6 @@
 #include <adl/adl.api_enum.h>
 #include <adl/adl.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define REPLY_MSG_ID_BASE am->msg_id_base
 #include <vlibapi/api_helper_macros.h>
diff --git a/src/plugins/dhcp/dhcp_test.c b/src/plugins/dhcp/dhcp_test.c
index c1894ec..d8288e6 100644
--- a/src/plugins/dhcp/dhcp_test.c
+++ b/src/plugins/dhcp/dhcp_test.c
@@ -39,13 +39,11 @@
 #define __plugin_msg_base dhcp_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static int
 api_dhcp_proxy_config (vat_main_t * vam)
diff --git a/src/plugins/dns/dns.c b/src/plugins/dns/dns.c
index 1839379..4a283bf 100644
--- a/src/plugins/dns/dns.c
+++ b/src/plugins/dns/dns.c
@@ -30,13 +30,11 @@
 #define REPLY_MSG_ID_BASE dm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 dns_main_t dns_main;
 
diff --git a/src/plugins/flowprobe/flowprobe.c b/src/plugins/flowprobe/flowprobe.c
index df0e5ff..058a642 100644
--- a/src/plugins/flowprobe/flowprobe.c
+++ b/src/plugins/flowprobe/flowprobe.c
@@ -90,13 +90,11 @@
 };
 /* *INDENT-ON* */
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static inline ipfix_field_specifier_t *
 flowprobe_template_ip4_fields (ipfix_field_specifier_t * f)
diff --git a/src/plugins/geneve/geneve_test.c b/src/plugins/geneve/geneve_test.c
index 2eb3821..e777e9b 100644
--- a/src/plugins/geneve/geneve_test.c
+++ b/src/plugins/geneve/geneve_test.c
@@ -41,13 +41,11 @@
 #define __plugin_msg_base geneve_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static void vl_api_geneve_add_del_tunnel_reply_t_handler
   (vl_api_geneve_add_del_tunnel_reply_t * mp)
diff --git a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
index e38559c..0652b86 100644
--- a/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
+++ b/src/plugins/hs_apps/sapi/vpp_echo_bapi.c
@@ -556,7 +556,6 @@
 _(APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply)      \
 _(APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)
 
-#define vl_print(handle, ...) fformat (handle, __VA_ARGS__)
 #define vl_endianfun
 #include <vnet/session/session.api.h>
 #undef vl_endianfun
@@ -586,12 +585,11 @@
     return;
 
 #define _(N, n)                                                               \
-  vl_msg_api_set_handlers (                                                   \
-    REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler,               \
-    vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print,             \
-    sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json,                    \
-    vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,                           \
-    vl_api_##n##_t_calc_size);
+  vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n,                \
+			   vl_api_##n##_t_handler, vl_api_##n##_t_endian,     \
+			   vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 1, \
+			   vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,    \
+			   vl_api_##n##_t_calc_size);
   foreach_quic_echo_msg;
 #undef _
 }
diff --git a/src/plugins/http_static/http_static.c b/src/plugins/http_static/http_static.c
index 005eefc..8f8fe37 100644
--- a/src/plugins/http_static/http_static.c
+++ b/src/plugins/http_static/http_static.c
@@ -27,7 +27,6 @@
 
 #include <vpp/api/types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define REPLY_MSG_ID_BASE hsm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
diff --git a/src/plugins/l2tp/l2tp_test.c b/src/plugins/l2tp/l2tp_test.c
index fef6121..3369131 100644
--- a/src/plugins/l2tp/l2tp_test.c
+++ b/src/plugins/l2tp/l2tp_test.c
@@ -41,13 +41,11 @@
 #define __plugin_msg_base l2tp_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
diff --git a/src/plugins/lacp/lacp_api.c b/src/plugins/lacp/lacp_api.c
index fab28cb..cdf05aa 100644
--- a/src/plugins/lacp/lacp_api.c
+++ b/src/plugins/lacp/lacp_api.c
@@ -31,14 +31,11 @@
 #include <lacp/lacp.api_enum.h>
 #include <lacp/lacp.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-
-/* Macro to finish up custom dump fns */
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 #define REPLY_MSG_ID_BASE lm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
diff --git a/src/plugins/lb/api.c b/src/plugins/lb/api.c
index e44f815..3aa745c 100644
--- a/src/plugins/lb/api.c
+++ b/src/plugins/lb/api.c
@@ -30,17 +30,15 @@
 #include <lb/lb.api_enum.h>
 #include <lb/lb.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define REPLY_MSG_ID_BASE lbm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static void
 vl_api_lb_conf_t_handler
diff --git a/src/plugins/lisp/lisp-cp/lisp_cp_test.c b/src/plugins/lisp/lisp-cp/lisp_cp_test.c
index 0ab4180..8657aae 100644
--- a/src/plugins/lisp/lisp-cp/lisp_cp_test.c
+++ b/src/plugins/lisp/lisp-cp/lisp_cp_test.c
@@ -41,13 +41,11 @@
 #define __plugin_msg_base lisp_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 typedef struct
 {
diff --git a/src/plugins/lisp/lisp-cp/one_test.c b/src/plugins/lisp/lisp-cp/one_test.c
index 7ca1f31..ad308b7 100644
--- a/src/plugins/lisp/lisp-cp/one_test.c
+++ b/src/plugins/lisp/lisp-cp/one_test.c
@@ -41,13 +41,11 @@
 #define __plugin_msg_base one_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 #define LISP_PING(_lm, mp_ping)                                         \
   if (!(_lm)->ping_id)                                                  \
diff --git a/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c b/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c
index 6f40e64..2f1a418 100644
--- a/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c
+++ b/src/plugins/lisp/lisp-gpe/lisp_gpe_test.c
@@ -41,13 +41,11 @@
 #define __plugin_msg_base lisp_gpe_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 #define LISP_PING(_lm, mp_ping)                                         \
   if (!(_lm)->ping_id)                                                  \
diff --git a/src/plugins/lldp/lldp_test.c b/src/plugins/lldp/lldp_test.c
index 661487c..6eb3e0f 100644
--- a/src/plugins/lldp/lldp_test.c
+++ b/src/plugins/lldp/lldp_test.c
@@ -38,13 +38,11 @@
 #define __plugin_msg_base lldp_test_main.msg_id_base
 #include <vlibapi/vat_helper_macros.h>
 
-/* Macro to finish up custom dump fns */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static int
 api_lldp_config (vat_main_t * vam)
diff --git a/src/plugins/mactime/mactime.c b/src/plugins/mactime/mactime.c
index f878ffe..ffb41c2 100644
--- a/src/plugins/mactime/mactime.c
+++ b/src/plugins/mactime/mactime.c
@@ -28,7 +28,6 @@
 #include <mactime/mactime.api_enum.h>
 #include <mactime/mactime.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define REPLY_MSG_ID_BASE mm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
diff --git a/src/plugins/mactime/mactime_top.c b/src/plugins/mactime/mactime_top.c
index d7223f4..60c3e5c 100644
--- a/src/plugins/mactime/mactime_top.c
+++ b/src/plugins/mactime/mactime_top.c
@@ -106,7 +106,6 @@
     }
 }
 
-#define vl_print(handle, ...) fformat(handle, __VA_ARGS__)
 #define vl_endianfun		/* define message structures */
 #include <mactime/mactime.api.h>
 #undef vl_endianfun
@@ -145,10 +144,9 @@
 
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers ((VL_API_##N + mm->msg_id_base), #n,                \
-			   vl_api_##n##_t_handler, vl_noop_handler,           \
-			   vl_api_##n##_t_endian, vl_api_##n##_t_print,       \
-			   sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_tojson, \
-			   vl_api_##n##_t_fromjson);
+			   vl_api_##n##_t_handler, vl_api_##n##_t_endian,     \
+			   vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 1, \
+			   vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
   foreach_mactime_api_msg;
 #undef _
 
diff --git a/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_api.c b/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_api.c
index 9ed835b..36c2216 100644
--- a/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_api.c
+++ b/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_api.c
@@ -38,7 +38,6 @@
 #undef vl_endianfun
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include <nsh/nsh.api.h>
 #undef vl_printfun
diff --git a/src/plugins/stn/stn_api.c b/src/plugins/stn/stn_api.c
index e868593..8d96014 100644
--- a/src/plugins/stn/stn_api.c
+++ b/src/plugins/stn/stn_api.c
@@ -29,13 +29,11 @@
 #define REPLY_MSG_ID_BASE stn_main.msg_id_base
 #include <vlibapi/api_helper_macros.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-/* Macro to finish up custom dump fns */
-#define FINISH                                  \
-    vec_add1 (s, 0);                            \
-    vl_print (handle, (char *)s);               \
-    vec_free (s);                               \
-    return handle;
+#define FINISH                                                                \
+  vec_add1 (s, 0);                                                            \
+  vlib_cli_output (handle, (char *) s);                                       \
+  vec_free (s);                                                               \
+  return handle;
 
 static void
 vl_api_stn_add_del_rule_t_handler (vl_api_stn_add_del_rule_t * mp)
diff --git a/src/plugins/tlsopenssl/tls_openssl_api.c b/src/plugins/tlsopenssl/tls_openssl_api.c
index c34829f..0b17271 100644
--- a/src/plugins/tlsopenssl/tls_openssl_api.c
+++ b/src/plugins/tlsopenssl/tls_openssl_api.c
@@ -23,7 +23,6 @@
 #include <tlsopenssl/tls_openssl.api_enum.h>
 #include <tlsopenssl/tls_openssl.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define REPLY_MSG_ID_BASE om->msg_id_base
 #include <vlibapi/api_helper_macros.h>
diff --git a/src/plugins/tracedump/tracedump_test.c b/src/plugins/tracedump/tracedump_test.c
index abb8105..f2bb63e 100644
--- a/src/plugins/tracedump/tracedump_test.c
+++ b/src/plugins/tracedump/tracedump_test.c
@@ -235,7 +235,6 @@
 
 
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_endianfun
 #include <tracedump/tracedump.api.h>
 #undef vl_endianfun
@@ -251,9 +250,8 @@
 {
   vl_msg_api_set_handlers (
     VL_API_TRACE_DETAILS + tracedump_test_main.msg_id_base, "trace_details",
-    vl_api_trace_details_t_handler, vl_noop_handler,
-    vl_api_trace_details_t_endian, vl_api_trace_details_t_print,
-    sizeof (vl_api_trace_details_t), 1, vl_api_trace_details_t_print_json,
+    vl_api_trace_details_t_handler, vl_api_trace_details_t_endian,
+    vl_api_trace_details_t_format, sizeof (vl_api_trace_details_t), 1,
     vl_api_trace_details_t_tojson, vl_api_trace_details_t_fromjson,
     vl_api_trace_details_t_calc_size);
 }
diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py
index a065653..b9f9e07 100644
--- a/src/tools/vppapigen/vppapigen_c.py
+++ b/src/tools/vppapigen/vppapigen_c.py
@@ -1028,9 +1028,9 @@
 """
 
     signature = """\
-static inline void *vl_api_{name}_t_print{suffix} (vl_api_{name}_t *a, void *handle)
+static inline u8 *vl_api_{name}_t_format (u8 *s,  va_list *args)
 {{
-    u8 *s = 0;
+    __attribute__((unused)) vl_api_{name}_t *a = va_arg (*args, vl_api_{name}_t *);
     u32 indent __attribute__((unused)) = 2;
     int i __attribute__((unused));
 """
@@ -1041,27 +1041,14 @@
     pp = Printfun(stream)
     for t in objs:
         if t.manual_print:
-            write("/***** manual: vl_api_%s_t_print  *****/\n\n" % t.name)
+            write("/***** manual: vl_api_%s_t_format *****/\n\n" % t.name)
             continue
         write(signature.format(name=t.name, suffix=""))
         write("    /* Message definition: vl_api_{}_t: */\n".format(t.name))
         write('    s = format(s, "vl_api_%s_t:");\n' % t.name)
         for o in t.block:
             pp.print_obj(o, stream)
-        write("    vec_add1(s, 0);\n")
-        write("    vl_print (handle, (char *)s);\n")
-        write("    vec_free (s);\n")
-        write("    return handle;\n")
-        write("}\n\n")
-
-        write(signature.format(name=t.name, suffix="_json"))
-        write("    cJSON * o = vl_api_{}_t_tojson(a);\n".format(t.name))
-        write("    (void)s;\n")
-        write("    char *out = cJSON_Print(o);\n")
-        write("    vl_print(handle, out);\n")
-        write("    cJSON_Delete(o);\n")
-        write("    cJSON_free(out);\n")
-        write("    return handle;\n")
+        write("    return s;\n")
         write("}\n\n")
 
     write("\n#endif")
@@ -1103,7 +1090,7 @@
             continue
 
         if t.manual_print:
-            write("/***** manual: vl_api_%s_t_print  *****/\n\n" % t.name)
+            write("/***** manual: vl_api_%s_t_format *****/\n\n" % t.name)
             continue
 
         if t.__class__.__name__ == "Using":
@@ -1525,7 +1512,6 @@
 #undef vl_calsizefun
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include "{module}.api.h"
 #undef vl_printfun
@@ -1556,12 +1542,10 @@
             " {{.id = VL_API_{ID} + msg_id_base,\n"
             '   .name = "{n}",\n'
             "   .handler = vl_api_{n}_t_handler,\n"
-            "   .cleanup = vl_noop_handler,\n"
             "   .endian = vl_api_{n}_t_endian,\n"
-            "   .print = vl_api_{n}_t_print,\n"
+            "   .format_fn = vl_api_{n}_t_format,\n"
             "   .traced = 1,\n"
             "   .replay = 1,\n"
-            "   .print_json = vl_api_{n}_t_print_json,\n"
             "   .tojson = vl_api_{n}_t_tojson,\n"
             "   .fromjson = vl_api_{n}_t_fromjson,\n"
             "   .calc_size = vl_api_{n}_t_calc_size,\n"
@@ -1577,12 +1561,10 @@
                 "{{.id = VL_API_{ID} + msg_id_base,\n"
                 '  .name = "{n}",\n'
                 "  .handler = 0,\n"
-                "  .cleanup = vl_noop_handler,\n"
                 "  .endian = vl_api_{n}_t_endian,\n"
-                "  .print = vl_api_{n}_t_print,\n"
+                "  .format_fn = vl_api_{n}_t_format,\n"
                 "  .traced = 1,\n"
                 "  .replay = 1,\n"
-                "  .print_json = vl_api_{n}_t_print_json,\n"
                 "  .tojson = vl_api_{n}_t_tojson,\n"
                 "  .fromjson = vl_api_{n}_t_fromjson,\n"
                 "  .calc_size = vl_api_{n}_t_calc_size,\n"
@@ -1631,7 +1613,6 @@
 #undef vl_calsizefun
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include "{module}.api.h"
 #undef vl_printfun
@@ -1678,8 +1659,10 @@
                 continue
             write("static void\n")
             write("vl_api_{n}_t_handler (vl_api_{n}_t * mp) {{\n".format(n=e))
-            write('    vl_print(0, "{n} event called:");\n'.format(n=e))
-            write("    vl_api_{n}_t_print(mp, 0);\n".format(n=e))
+            write('    vlib_cli_output(0, "{n} event called:");\n'.format(n=e))
+            write(
+                '    vlib_cli_output(0, "%U", vl_api_{n}_t_format, mp);\n'.format(n=e)
+            )
             write("}\n")
 
     write("static void\n")
@@ -1689,11 +1672,9 @@
             "   vl_msg_api_set_handlers(VL_API_{ID} + msg_id_base, "
             '                           "{n}",\n'
             "                           vl_api_{n}_t_handler, "
-            "                           vl_noop_handler,\n"
             "                           vl_api_{n}_t_endian, "
-            "                           vl_api_{n}_t_print,\n"
+            "                           vl_api_{n}_t_format,\n"
             "                           sizeof(vl_api_{n}_t), 1,\n"
-            "                           vl_api_{n}_t_print_json,\n"
             "                           vl_api_{n}_t_tojson,\n"
             "                           vl_api_{n}_t_fromjson,\n"
             "                           vl_api_{n}_t_calc_size);\n".format(
@@ -1720,11 +1701,9 @@
                 "   vl_msg_api_set_handlers(VL_API_{ID} + msg_id_base, "
                 '                          "{n}",\n'
                 "                           vl_api_{n}_t_handler, "
-                "                           vl_noop_handler,\n"
                 "                           vl_api_{n}_t_endian, "
-                "                           vl_api_{n}_t_print,\n"
+                "                           vl_api_{n}_t_format,\n"
                 "                           sizeof(vl_api_{n}_t), 1,\n"
-                "                           vl_api_{n}_t_print_json,\n"
                 "                           vl_api_{n}_t_tojson,\n"
                 "                           vl_api_{n}_t_fromjson,\n"
                 "                           vl_api_{n}_t_calc_size);\n".format(
@@ -1968,7 +1947,6 @@
 #include "{module}.api.h"
 #undef vl_calsizefun
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include "{module}.api.h"
 #undef vl_printfun
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 14546b5..72ce34f 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -69,11 +69,6 @@
 #undef vl_calcsizefun
 
 /* instantiate all the print functions we know about */
-#if VPP_API_TEST_BUILTIN == 0
-#define vl_print(handle, ...)
-#else
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#endif
 #define vl_printfun
 #include <vlibmemory/memclnt.api.h>
 #undef vl_printfun
@@ -564,9 +559,6 @@
 }
 
 
-#define vl_api_bridge_domain_details_t_endian vl_noop_handler
-#define vl_api_bridge_domain_details_t_print vl_noop_handler
-
 static void vl_api_get_first_msg_id_reply_t_handler
   (vl_api_get_first_msg_id_reply_t * mp)
 {
@@ -2742,9 +2734,8 @@
 {
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N + 1, #n, vl_api_##n##_t_handler_uni, vl_noop_handler,          \
-    vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1,  \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N + 1, #n, vl_api_##n##_t_handler_uni, vl_api_##n##_t_endian,    \
+    vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_tojson, \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
   foreach_vpe_api_reply_msg;
 #if VPP_API_TEST_BUILTIN == 0
diff --git a/src/vcl/vcl_bapi.c b/src/vcl/vcl_bapi.c
index bbb0420..7e5203d 100644
--- a/src/vcl/vcl_bapi.c
+++ b/src/vcl/vcl_bapi.c
@@ -271,7 +271,6 @@
   _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)                \
   _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)
 
-#define vl_print(handle, ...) fformat (handle, __VA_ARGS__)
 #define vl_endianfun	      /* define message structures */
 #include <vnet/session/session.api.h>
 #undef vl_endianfun
@@ -303,12 +302,11 @@
     return;
 
 #define _(N, n)                                                               \
-  vl_msg_api_set_handlers (                                                   \
-    REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler,               \
-    vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print,             \
-    sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json,                    \
-    vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,                           \
-    vl_api_##n##_t_calc_size);
+  vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n,                \
+			   vl_api_##n##_t_handler, vl_api_##n##_t_endian,     \
+			   vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 1, \
+			   vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,    \
+			   vl_api_##n##_t_calc_size);
   foreach_sock_msg;
 #undef _
 }
diff --git a/src/vlibapi/CMakeLists.txt b/src/vlibapi/CMakeLists.txt
index 95bb4cf..6476b5a 100644
--- a/src/vlibapi/CMakeLists.txt
+++ b/src/vlibapi/CMakeLists.txt
@@ -14,6 +14,7 @@
 add_vpp_library (vlibapi
   SOURCES
   api_shared.c
+  api_format.c
   node_serialize.c
   memory_shared.c
 
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index f838a80..705678b 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -148,6 +148,9 @@
   am->msg_data[msg_id].replay_allowed = v != 0;
 }
 
+format_function_t format_vl_api_msg_text;
+format_function_t format_vl_api_msg_json;
+
 #endif /* included_api_h */
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h
index 66a547f..37ffb58 100644
--- a/src/vlibapi/api_common.h
+++ b/src/vlibapi/api_common.h
@@ -122,8 +122,7 @@
   void *handler;		/**< the message handler  */
   void *cleanup;		/**< non-default message cleanup handler */
   void *endian;			/**< message endian function  */
-  void *print;			/**< message print function  */
-  void *print_json;		/**< message print function (JSON format)  */
+  void *format_fn;		/**< message format function  */
   void *tojson;			/**< binary to JSON convert function */
   void *fromjson;		/**< JSON to binary convert function */
   void *calc_size;		/**< message size calculation */
@@ -173,10 +172,9 @@
 void vl_msg_api_replay_handler (void *the_msg);
 void vl_msg_api_socket_handler (void *the_msg, uword msg_len);
 void vl_msg_api_set_handlers (int msg_id, char *msg_name, void *handler,
-			      void *cleanup, void *endian, void *print,
-			      int msg_size, int traced, void *print_json,
-			      void *tojson, void *fromjson,
-			      void *validate_size);
+			      void *endian, format_function_t *format,
+			      int msg_size, int traced, void *tojson,
+			      void *fromjson, void *validate_size);
 void vl_msg_api_clean_handlers (int msg_id);
 void vl_msg_api_config (vl_msg_api_msg_config_t *);
 void vl_msg_api_set_cleanup_handler (int msg_id, void *fp);
@@ -191,7 +189,6 @@
 #define vl_msg_api_barrier_trace_context(X)
 #endif
 void vl_msg_api_free (void *);
-void vl_noop_handler (void *mp);
 void vl_msg_api_increment_missing_client_counter (void);
 void vl_msg_api_post_mortem_dump (void);
 void vl_msg_api_post_mortem_dump_enable_disable (int enable);
@@ -234,6 +231,9 @@
   /** Message name vector */
   const char *name;
 
+  /** Message format function */
+  format_function_t *format_fn;
+
   /** Message convert function vector */
   cJSON *(*tojson_handler) (void *);
 
@@ -243,12 +243,6 @@
   /** Message endian handler vector */
   void (*endian_handler) (void *);
 
-  /** Message print function vector */
-  void (*print_handler) (void *, void *);
-
-  /** Message print function vector in JSON */
-  void (*print_json_handler) (void *, void *);
-
   /** Message calc size function vector */
   uword (*calc_size_func) (void *);
 
diff --git a/src/vlibapi/api_doc.rst b/src/vlibapi/api_doc.rst
index 7d2b80a..2131cc1 100644
--- a/src/vlibapi/api_doc.rst
+++ b/src/vlibapi/api_doc.rst
@@ -300,7 +300,6 @@
        #undef vl_endianfun
 
        /* instantiate all the print functions we know about */
-       #define vl_print(handle, ...)
        #define vl_printfun
        #include <vpp/api/vpe_all_api_h.h>
        #undef vl_printfun
diff --git a/src/vlibapi/api_format.c b/src/vlibapi/api_format.c
new file mode 100644
index 0000000..f7bb9d3
--- /dev/null
+++ b/src/vlibapi/api_format.c
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2022 Cisco Systems, Inc.
+ */
+
+#include <vppinfra/format.h>
+#include <vlibapi/api.h>
+
+u8 *
+format_vl_api_msg_text (u8 *s, va_list *args)
+{
+  api_main_t *am = va_arg (*args, api_main_t *);
+  u32 msg_id = va_arg (*args, u32);
+  void *msg = va_arg (*args, void *);
+  vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
+
+  if (m->format_fn)
+    s = format (s, "%U", m->format_fn, msg);
+  else
+    s = format (s, "[format handler missing for `%s`]", m->name);
+  return s;
+}
+
+u8 *
+format_vl_api_msg_json (u8 *s, va_list *args)
+{
+  api_main_t *am = va_arg (*args, api_main_t *);
+  u32 msg_id = va_arg (*args, u32);
+  void *msg = va_arg (*args, void *);
+  vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
+
+  cJSON *o = m->tojson_handler (msg);
+  char *out = cJSON_Print (o);
+
+  s = format (s, "%s", out);
+
+  cJSON_Delete (o);
+  cJSON_free (out);
+  return s;
+}
diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c
index 73ef3ce..0a98348 100644
--- a/src/vlibapi/api_shared.c
+++ b/src/vlibapi/api_shared.c
@@ -531,10 +531,7 @@
       if (am->msg_print_flag)
 	{
 	  fformat (stdout, "[%d]: %s\n", id, m->name);
-	  if (m->print_handler)
-	    m->print_handler (the_msg, stdout);
-	  else
-	    fformat (stdout, "  [no registered print fn]\n");
+	  fformat (stdout, "%U", format_vl_api_msg_text, am, id, the_msg);
 	}
 
       uword calc_size = 0;
@@ -769,8 +766,7 @@
   m->handler = c->handler;
   m->cleanup_handler = c->cleanup;
   m->endian_handler = c->endian;
-  m->print_handler = c->print;
-  m->print_json_handler = c->print_json;
+  m->format_fn = c->format_fn;
   m->tojson_handler = c->tojson;
   m->fromjson_handler = c->fromjson;
   m->calc_size_func = c->calc_size;
@@ -793,10 +789,9 @@
  * preserve the old API for a while
  */
 void
-vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
-			 void *endian, void *print, int size, int traced,
-			 void *print_json, void *tojson, void *fromjson,
-			 void *calc_size)
+vl_msg_api_set_handlers (int id, char *name, void *handler, void *endian,
+			 format_function_t *format, int size, int traced,
+			 void *tojson, void *fromjson, void *calc_size)
 {
   vl_msg_api_msg_config_t cfg;
   vl_msg_api_msg_config_t *c = &cfg;
@@ -806,9 +801,8 @@
   c->id = id;
   c->name = name;
   c->handler = handler;
-  c->cleanup = cleanup;
   c->endian = endian;
-  c->print = print;
+  c->format_fn = format;
   c->traced = traced;
   c->replay = 1;
   c->message_bounce = 0;
@@ -816,7 +810,6 @@
   c->is_autoendian = 0;
   c->tojson = tojson;
   c->fromjson = fromjson;
-  c->print_json = print_json;
   c->calc_size = calc_size;
   vl_msg_api_config (c);
 }
@@ -884,12 +877,6 @@
     }
 }
 
-void
-vl_noop_handler (void *mp)
-{
-}
-
-
 static u8 post_mortem_dump_enabled;
 
 void
diff --git a/src/vlibmemory/memclnt_api.c b/src/vlibmemory/memclnt_api.c
index 9e2971a..0717d81 100644
--- a/src/vlibmemory/memclnt_api.c
+++ b/src/vlibmemory/memclnt_api.c
@@ -48,7 +48,6 @@
 #undef vl_typedefs
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_printfun
@@ -175,10 +174,8 @@
       c->id = VL_API_##N;                                                     \
       c->name = #n;                                                           \
       c->handler = vl_api_##n##_t_handler;                                    \
-      c->cleanup = vl_noop_handler;                                           \
       c->endian = vl_api_##n##_t_endian;                                      \
-      c->print = vl_api_##n##_t_print;                                        \
-      c->print_json = vl_api_##n##_t_print_json;                              \
+      c->format_fn = vl_api_##n##_t_format;                                   \
       c->tojson = vl_api_##n##_t_tojson;                                      \
       c->fromjson = vl_api_##n##_t_fromjson;                                  \
       c->calc_size = vl_api_##n##_t_calc_size;                                \
@@ -711,18 +708,16 @@
   api_main_t *am = vlibapi_get_main ();
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \
-    vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0 /* do not trace */,      \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N, #n, vl_api_##n##_t_handler, 0, vl_api_##n##_t_format,         \
+    sizeof (vl_api_##n##_t), 0 /* do not trace */, vl_api_##n##_t_tojson,     \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
   foreach_rpc_api_msg;
 #undef _
 
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \
-    vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1 /* do trace */,          \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N, #n, vl_api_##n##_t_handler, 0, vl_api_##n##_t_format,         \
+    sizeof (vl_api_##n##_t), 1 /* do trace */, vl_api_##n##_t_tojson,         \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
   foreach_plugin_trace_msg;
 #undef _
diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c
index 80d8628..01fe49b 100644
--- a/src/vlibmemory/memory_api.c
+++ b/src/vlibmemory/memory_api.c
@@ -28,7 +28,6 @@
 #undef vl_typedefs
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_printfun
@@ -504,18 +503,21 @@
   if ((rv = vl_map_shmem (region_name, 1 /* is_vlib */ )) < 0)
     return rv;
 
-#define _(N,n,t) do {                                            \
-    c->id = VL_API_##N;                                         \
-    c->name = #n;                                               \
-    c->handler = vl_api_##n##_t_handler;                        \
-    c->cleanup = vl_noop_handler;                               \
-    c->endian = vl_api_##n##_t_endian;                          \
-    c->print = vl_api_##n##_t_print;                            \
-    c->size = sizeof(vl_api_##n##_t);                           \
-    c->traced = t; /* trace, so these msgs print */             \
-    c->replay = 0; /* don't replay client create/delete msgs */ \
-    c->message_bounce = 0; /* don't bounce this message */	\
-    vl_msg_api_config(c);} while (0);
+#define _(N, n, t)                                                            \
+  do                                                                          \
+    {                                                                         \
+      c->id = VL_API_##N;                                                     \
+      c->name = #n;                                                           \
+      c->handler = vl_api_##n##_t_handler;                                    \
+      c->endian = vl_api_##n##_t_endian;                                      \
+      c->format_fn = vl_api_##n##_t_format;                                   \
+      c->size = sizeof (vl_api_##n##_t);                                      \
+      c->traced = t;	     /* trace, so these msgs print */                 \
+      c->replay = 0;	     /* don't replay client create/delete msgs */     \
+      c->message_bounce = 0; /* don't bounce this message */                  \
+      vl_msg_api_config (c);                                                  \
+    }                                                                         \
+  while (0);
 
   foreach_vlib_api_msg;
 #undef _
@@ -770,7 +772,6 @@
   u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
   vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
   u8 *(*handler) (void *, void *, void *);
-  u8 *(*print_fp) (void *, void *);
   svm_region_t *old_vlib_rp;
   void *save_shmem_hdr;
   int is_mp_safe = 1;
@@ -802,15 +803,7 @@
       if (PREDICT_FALSE (am->msg_print_flag))
 	{
 	  fformat (stdout, "[%d]: %s\n", id, m->name);
-	  print_fp = (void *) am->msg_data[id].print_handler;
-	  if (print_fp == 0)
-	    {
-	      fformat (stdout, "  [no registered print fn for msg %d]\n", id);
-	    }
-	  else
-	    {
-	      (*print_fp) (the_msg, vm);
-	    }
+	  fformat (stdout, "%U", format_vl_api_msg_text, am, id, the_msg);
 	}
       is_mp_safe = am->msg_data[id].is_mp_safe;
 
diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c
index 330390e..738c4e5 100644
--- a/src/vlibmemory/memory_client.c
+++ b/src/vlibmemory/memory_client.c
@@ -44,7 +44,6 @@
 #undef vl_calcsizefun
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) clib_warning (__VA_ARGS__)
 #define vl_printfun
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_printfun
@@ -155,11 +154,6 @@
     }
 }
 
-static void
-noop_handler (void *notused)
-{
-}
-
 void vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem);
 int
 vl_client_connect (const char *name, int ctx_quota, int input_queue_size)
@@ -373,9 +367,8 @@
   api_main_t *am = vlibapi_get_main ();
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler,                     \
-    vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0,  \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N, #n, vl_api_##n##_t_handler, vl_api_##n##_t_endian,            \
+    vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 0, vl_api_##n##_t_tojson, \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);                       \
   am->msg_data[VL_API_##N].replay_allowed = 0;
   foreach_api_msg;
diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c
index e451d62..106fcb2 100644
--- a/src/vlibmemory/socket_api.c
+++ b/src/vlibmemory/socket_api.c
@@ -35,7 +35,6 @@
 #undef vl_typedefs
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 #define vl_printfun
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_printfun
@@ -798,9 +797,8 @@
 
 #define _(N, n, t)                                                            \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler,                  \
-    vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t,  \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N, #n, vl_api_##n##_t_handler, vl_api_##n##_t_endian,            \
+    vl_api_##n##_t_format, sizeof (vl_api_##n##_t), t, vl_api_##n##_t_tojson, \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);                       \
   am->msg_data[VL_API_##N].replay_allowed = 0;
   foreach_vlib_api_msg;
diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c
index 237d222..1eccb73 100644
--- a/src/vlibmemory/socket_client.c
+++ b/src/vlibmemory/socket_client.c
@@ -41,7 +41,6 @@
 #undef vl_calcsizefun
 
 /* instantiate all the print functions we know about */
-#define vl_print(handle, ...) clib_warning (__VA_ARGS__)
 #define vl_printfun
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_printfun
@@ -427,20 +426,14 @@
 _(SOCKCLNT_CREATE_REPLY, sockclnt_create_reply)			\
 _(SOCK_INIT_SHM_REPLY, sock_init_shm_reply)     		\
 
-static void
-noop_handler (void *notused)
-{
-}
-
 void
 vl_sock_client_install_message_handlers (void)
 {
 
 #define _(N, n)                                                               \
   vl_msg_api_set_handlers (                                                   \
-    VL_API_##N, #n, vl_api_##n##_t_handler, noop_handler,                     \
-    vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0,  \
-    vl_api_##n##_t_print_json, vl_api_##n##_t_tojson,                         \
+    VL_API_##N, #n, vl_api_##n##_t_handler, vl_api_##n##_t_endian,            \
+    vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 0, vl_api_##n##_t_tojson, \
     vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
   foreach_sock_client_api_msg;
 #undef _
diff --git a/src/vlibmemory/vlib_api_cli.c b/src/vlibmemory/vlib_api_cli.c
index e53ea95..5b62e61 100644
--- a/src/vlibmemory/vlib_api_cli.c
+++ b/src/vlibmemory/vlib_api_cli.c
@@ -584,40 +584,24 @@
       switch (which)
 	{
 	case DUMP_JSON:
-	  if (m && m->print_json_handler)
-	    {
-	      m->print_json_handler (tmpbuf + sizeof (uword), vm);
-	    }
-	  else
-	    {
-	      vlib_cli_output (vm, "Skipping msg id %d: no JSON print fcn\n",
-			       msg_id);
-	      break;
-	    }
+	  vlib_cli_output (vm, "%U", format_vl_api_msg_json, am, msg_id,
+			   tmpbuf + sizeof (uword));
 	  break;
 
 	case DUMP:
-	  if (m && m->print_handler)
-	    {
-	      m->print_handler (tmpbuf + sizeof (uword), vm);
-	    }
-	  else
-	    {
-	      vlib_cli_output (vm, "Skipping msg id %d: no print fcn\n",
-			       msg_id);
-	      break;
-	    }
+	  vlib_cli_output (vm, "%U", format_vl_api_msg_text, am, msg_id,
+			   tmpbuf + sizeof (uword));
 	  break;
 
 	case INITIALIZERS:
-	  if (m && m->print_handler)
+	  if (m)
 	    {
 	      u8 *s;
 	      int j;
 
-	      vlib_cli_output (vm, "/*");
+	      vlib_cli_output (vm, "/*%U*/", format_vl_api_msg_text, am,
+			       msg_id, tmpbuf + sizeof (uword));
 
-	      m->print_handler (tmpbuf + sizeof (uword), vm);
 	      vlib_cli_output (vm, "*/\n");
 
 	      s = format (0, "static u8 * vl_api_%s_%d[%d] = {", m->name, i,
@@ -636,7 +620,7 @@
 	  break;
 
 	case REPLAY:
-	  if (m && m->print_handler && m->replay_allowed)
+	  if (m && m->handler && m->replay_allowed)
 	    {
 	      if (!m->is_mp_safe)
 		vl_msg_api_barrier_sync ();
@@ -690,7 +674,6 @@
   api_main_t *am = vlibapi_get_main ();
   u16 msg_id = ntohs (*((u16 *) msg));
   vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
-  void (*handler) (void *, void *) = 0;
   u8 is_json = a->is_json;
   u8 *tmpbuf = 0;
 
@@ -710,12 +693,9 @@
       m->endian_handler (tmpbuf);
     }
 
-  handler = is_json ? m->print_json_handler : m->print_handler;
-
-  if (handler)
-    handler (msg, a->vm);
-  else
-    vlib_cli_output (a->vm, "Skipping msg id %d: no print fcn\n", msg_id);
+  vlib_cli_output (a->vm, "%U\n",
+		   is_json ? format_vl_api_msg_json : format_vl_api_msg_text,
+		   am, msg_id, msg);
 
   vec_free (tmpbuf);
   return 0;
@@ -868,11 +848,14 @@
 	  goto end;
 	}
 
-      if (!m->is_mp_safe)
-	vl_msg_api_barrier_sync ();
-      m->handler (msg);
-      if (!m->is_mp_safe)
-	vl_msg_api_barrier_release ();
+      if (m->handler)
+	{
+	  if (!m->is_mp_safe)
+	    vl_msg_api_barrier_sync ();
+	  m->handler (msg);
+	  if (!m->is_mp_safe)
+	    vl_msg_api_barrier_release ();
+	}
     }
 
   rv = 0;
diff --git a/src/vnet/ip6-nd/rd_cp.c b/src/vnet/ip6-nd/rd_cp.c
index 13fd90d..1840233 100644
--- a/src/vnet/ip6-nd/rd_cp.c
+++ b/src/vnet/ip6-nd/rd_cp.c
@@ -72,8 +72,6 @@
   RD_CP_EVENT_INTERRUPT,
 };
 
-#define vl_api_ip6_nd_address_autoconfig_t_print vl_noop_handler
-
 static void
 router_solicitation_start_stop (u32 sw_if_index, u8 start)
 {
diff --git a/src/vnet/srmpls/sr_mpls_api.c b/src/vnet/srmpls/sr_mpls_api.c
index 45107f0..8642db9 100644
--- a/src/vnet/srmpls/sr_mpls_api.c
+++ b/src/vnet/srmpls/sr_mpls_api.c
@@ -29,7 +29,6 @@
 #include <vnet/srmpls/sr_mpls.api_enum.h>
 #include <vnet/srmpls/sr_mpls.api_types.h>
 
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
 
 #define vl_api_version(n, v) static u32 api_version = v;
 #include <vnet/srmpls/sr_mpls.api.h>
@@ -194,12 +193,11 @@
   vec_free (name);
 
 #define _(N, n)                                                               \
-  vl_msg_api_set_handlers (                                                   \
-    REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler,               \
-    vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print,             \
-    sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json,                    \
-    vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,                           \
-    vl_api_##n##_t_calc_size);
+  vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n,                \
+			   vl_api_##n##_t_handler, vl_api_##n##_t_endian,     \
+			   vl_api_##n##_t_format, sizeof (vl_api_##n##_t), 1, \
+			   vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson,    \
+			   vl_api_##n##_t_calc_size);
   foreach_vpe_api_msg;
 #undef _
 
@@ -209,9 +207,8 @@
    */
   vl_msg_api_set_handlers (
     REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_ADD, "sr_mpls_policy_add",
-    vl_api_sr_mpls_policy_add_t_handler, vl_noop_handler,
-    vl_api_sr_mpls_policy_add_t_endian, vl_api_sr_mpls_policy_add_t_print, 256,
-    1, vl_api_sr_mpls_policy_add_t_print_json,
+    vl_api_sr_mpls_policy_add_t_handler, vl_api_sr_mpls_policy_add_t_endian,
+    vl_api_sr_mpls_policy_add_t_format, 256, 1,
     vl_api_sr_mpls_policy_add_t_tojson, vl_api_sr_mpls_policy_add_t_fromjson,
     vl_api_sr_mpls_policy_add_t_calc_size);
 
@@ -221,9 +218,8 @@
    */
   vl_msg_api_set_handlers (
     REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_MOD, "sr_mpls_policy_mod",
-    vl_api_sr_mpls_policy_mod_t_handler, vl_noop_handler,
-    vl_api_sr_mpls_policy_mod_t_endian, vl_api_sr_mpls_policy_mod_t_print, 256,
-    1, vl_api_sr_mpls_policy_mod_t_print_json,
+    vl_api_sr_mpls_policy_mod_t_handler, vl_api_sr_mpls_policy_mod_t_endian,
+    vl_api_sr_mpls_policy_mod_t_format, 256, 1,
     vl_api_sr_mpls_policy_mod_t_tojson, vl_api_sr_mpls_policy_mod_t_fromjson,
     vl_api_sr_mpls_policy_mod_t_calc_size);