api: API trace improvements

Type: improvement

 * add support for JSON format in API trace
 * add ability to replay JSON API trace in both VPP and VAT2
 * use CRC for backward compatibility check during JSON API replay
 * fix API trace CLI (and remove duplicits)
 * remove custom dump
 * remove vppapitrace.py
 * update docs accordingly

Change-Id: I5294f68bebe6cbe738630f457f3a87720e06486b
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
Filip Tehlar
2021-07-23 08:51:10 +00:00
parent 3459ece6da
commit 36217e3ca8
34 changed files with 1164 additions and 1061 deletions
+2 -2
View File
@@ -4,6 +4,6 @@
About
=====
**VPP Version:** 21.06-rc0~304-ga73e7568c
**VPP Version:** 21.10-rc0~204-g13e841847
**Built on:** Fri Feb 19 23:40:45 GMT 2021
**Built on:** Thu Jul 22 23:44:06 GMT 2021
@@ -206,11 +206,10 @@ out the set of plugins:
.. code-block:: console
DBGvpp# api trace custom-dump /tmp/api_trace
vl_api_trace_plugin_msg_ids: abf_54307ba2 first 846 last 855
vl_api_trace_plugin_msg_ids: acl_0d7265b0 first 856 last 893
vl_api_trace_plugin_msg_ids: cdp_8f707b96 first 894 last 895
vl_api_trace_plugin_msg_ids: flowprobe_f2f0286c first 898 last 901
DBGvpp# api trace dump /tmp/api_trace
vl_api_trace_plugin_msg_ids: arp_cfdf7292 first 49 last 56
vl_api_trace_plugin_msg_ids: ip6_nd_ac628462 first 57 last 69
vl_api_trace_plugin_msg_ids: rd_cp_8a996e86 first 70 last 71
<etc>
Here, we see the "abf," "acl," "cdp," and "flowprobe" plugins. Use the
@@ -239,7 +238,7 @@ __________________________
Along the same lines, it may be necessary to manufacture [simulated]
physical interfaces so that an API trace will replay correctly. "show
interface" on the trace origin system can help. An API trace
"custom-dump" as shown above may make it obvious how many loopback
dump as shown above may make it obvious how many loopback
interfaces to create. If you see vhost interfaces being created and
then configured, the first such configuration message in the trace
will tell you how many physical interfaces were involved.
+59 -58
View File
@@ -1,58 +1,59 @@
.. _interface:
.. toctree::
.. note:: For a complete list of CLI Debug commands refer to the Debug CLI section of the `Source Code Documents <https://docs.fd.io/vpp/18.07/clicmd.html>`_ .
API Trace
===========
Summary/Usage
--------------
api trace [on|off][first <*n*>][last <*n*>][status][free][post-mortem-on][dump|custom-dump|save|replay <*file*>]
Description
------------
Display, replay, or save a binary API trace.
Declaration and Implementation
-------------------------------
**Declaration:** api_trace_command (src/vlibmemory/vlib_api_cli.c line 783)
**Implementation:** api_trace_command_fn
Clear Trace
=============
Summary/Usage
--------------
Clear trace buffer and free memory.
Declaration and implementation
**Declaration:** clear_trace_cli (src/vlib/trace.c line 519)
**Implementation:** cli_clear_trace_buffer
Show Trace
===========
`Show Trace <../show/show.html#show-trace>`_
Trace Add
===========
Summary/Usage
--------------
Trace given number of packets.
Declaration and Implementation
-------------------------------
**Declaration:** add_trace_cli (src/vlib/trace.c line 405)
**Implementation:** cli_add_trace_buffer
.. _interface:
.. toctree::
.. note:: For a complete list of CLI Debug commands refer to the Debug CLI section of the `Source Code Documents <https://docs.fd.io/vpp/18.07/clicmd.html>`_ .
API Trace
===========
Summary/Usage
--------------
api trace [tx][on|off][first <n>][last <n>][status][free]
[post-mortem-on][dump|dump-file|dump-json|save|tojson|save-json|replay <file>][nitems <n>][initializers <file>]
Description
------------
Display, replay, or save a binary API trace.
Declaration and Implementation
-------------------------------
**Declaration:** api_trace_command (src/vlibmemory/vlib_api_cli.c line 783)
**Implementation:** api_trace_command_fn
Clear Trace
=============
Summary/Usage
--------------
Clear trace buffer and free memory.
Declaration and implementation
**Declaration:** clear_trace_cli (src/vlib/trace.c line 519)
**Implementation:** cli_clear_trace_buffer
Show Trace
===========
`Show Trace <../show/show.html#show-trace>`_
Trace Add
===========
Summary/Usage
--------------
Trace given number of packets.
Declaration and Implementation
-------------------------------
**Declaration:** add_trace_cli (src/vlib/trace.c line 405)
**Implementation:** cli_add_trace_buffer
+5 -4
View File
@@ -569,10 +569,11 @@ echo_api_hookup (echo_main_t * em)
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_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);
foreach_quic_echo_msg;
#undef _
}
+6 -8
View File
@@ -143,14 +143,12 @@ connect_to_vpp (char *name)
if (mm->msg_id_base == (u16) ~ 0)
return -1;
#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);
#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);
foreach_mactime_api_msg;
#undef _
+6 -6
View File
@@ -246,12 +246,12 @@ api_trace_clear_capture (vat_main_t * vam)
void
manual_setup_message_id_table (vat_main_t * vam)
{
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_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_tojson, vl_api_trace_details_t_fromjson);
}
#define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE manual_setup_message_id_table
+53 -18
View File
@@ -66,7 +66,10 @@ class ToJSON():
write('#ifndef included_{}_api_tojson_h\n'.format(self.module))
write('#define included_{}_api_tojson_h\n'.format(self.module))
write('#include <vppinfra/cJSON.h>\n\n')
write('#include <vat2/jsonconvert.h>\n\n')
write('#include <vppinfra/jsonformat.h>\n\n')
if self.module == 'interface_types':
write('#define vl_printfun\n')
write('#include <vnet/interface_types.api.h>\n\n')
def footer(self):
'''Output the bottom boilerplate.'''
@@ -231,6 +234,8 @@ class ToJSON():
write(' cJSON *o = cJSON_CreateObject();\n')
write(' cJSON_AddStringToObject(o, "_msgname", "{}");\n'
.format(o.name))
write(' cJSON_AddStringToObject(o, "_crc", "{crc:08x}");\n'
.format(crc=o.crc))
for t in o.block:
self._dispatch[t.type](self, t)
@@ -312,7 +317,7 @@ class FromJSON():
write('#ifndef included_{}_api_fromjson_h\n'.format(self.module))
write('#define included_{}_api_fromjson_h\n'.format(self.module))
write('#include <vppinfra/cJSON.h>\n\n')
write('#include <vat2/jsonconvert.h>\n\n')
write('#include <vppinfra/jsonformat.h>\n\n')
write('#pragma GCC diagnostic ignored "-Wunused-label"\n')
def is_base_type(self, t):
@@ -338,7 +343,7 @@ class FromJSON():
if o.modern_vla:
write(' char *p = cJSON_GetStringValue(item);\n')
write(' size_t plen = strlen(p);\n')
write(' {msgvar} = realloc({msgvar}, {msgsize} + plen);\n'
write(' {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n'
.format(msgvar=msgvar, msgsize=msgsize))
write(' if ({msgvar} == 0) goto error;\n'.format(msgvar=msgvar))
write(' vl_api_c_string_to_api_string(p, (void *){msgvar} + '
@@ -393,7 +398,7 @@ class FromJSON():
cJSON *array = cJSON_GetObjectItem(o, "{n}");
int size = cJSON_GetArraySize(array);
{lfield} = size;
{realloc} = realloc({realloc}, {msgsize} + sizeof({t}) * size);
{realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize});
{t} *d = (void *){realloc} + {msgsize};
{msgsize} += sizeof({t}) * size;
for (i = 0; i < size; i++) {{
@@ -419,8 +424,8 @@ class FromJSON():
write(' if (!s) goto error;\n')
write(' {} = vec_len(s);\n'.format(lfield))
write(' {realloc} = realloc({realloc}, {msgsize} + '
'vec_len(s));\n'.format(msgvar=msgvar, msgsize=msgsize, realloc=realloc))
write(' {realloc} = cJSON_realloc({realloc}, {msgsize} + '
'vec_len(s), {msgsize});\n'.format(msgvar=msgvar, msgsize=msgsize, realloc=realloc))
write(' memcpy((void *){realloc} + {msgsize}, s, '
'vec_len(s));\n'.format(realloc=realloc, msgsize=msgsize))
write(' {msgsize} += vec_len(s);\n'.format(msgsize=msgsize))
@@ -553,7 +558,7 @@ class FromJSON():
write(' cJSON *item __attribute__ ((unused));\n')
write(' u8 *s __attribute__ ((unused));\n')
write(' int l = sizeof(vl_api_{}_t);\n'.format(o.name))
write(' vl_api_{}_t *a = malloc(l);\n'.format(o.name))
write(' vl_api_{}_t *a = cJSON_malloc(l);\n'.format(o.name))
write('\n')
for t in o.block:
@@ -573,7 +578,7 @@ class FromJSON():
if error:
write('\n error:\n')
write(' free(a);\n')
write(' cJSON_free(a);\n')
write(' return 0;\n')
write('}\n')
@@ -928,10 +933,13 @@ def printfun(objs, stream, modulename):
#define _uword_cast long
#endif
#include "{module}.api_tojson.h"
#include "{module}.api_fromjson.h"
'''
signature = '''\
static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
static inline void *vl_api_{name}_t_print{suffix} (vl_api_{name}_t *a, void *handle)
{{
u8 *s = 0;
u32 indent __attribute__((unused)) = 2;
@@ -946,7 +954,7 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
if t.manual_print:
write("/***** manual: vl_api_%s_t_print *****/\n\n" % t.name)
continue
write(signature.format(name=t.name))
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:
@@ -957,6 +965,16 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
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('}\n\n');
write("\n#endif")
write("\n#endif /* vl_printfun */\n")
@@ -1346,6 +1364,9 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
' .print = vl_api_{n}_t_print,\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'
' .is_autoendian = {auto}}};\n'
.format(n=s.caller, ID=s.caller.upper(),
auto=d.autoendian))
@@ -1359,6 +1380,11 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
' .cleanup = vl_noop_handler,\n'
' .endian = vl_api_{n}_t_endian,\n'
' .print = vl_api_{n}_t_print,\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'
' .is_autoendian = {auto}}};\n'
.format(n=s.reply, ID=s.reply.upper(),
auto=d.autoendian))
@@ -1455,7 +1481,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
' vl_noop_handler,\n'
' vl_api_{n}_t_endian, '
' vl_api_{n}_t_print,\n'
' sizeof(vl_api_{n}_t), 1);\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'
.format(n=s.reply, ID=s.reply.upper()))
write(' hash_set_mem (vam->function_by_name, "{n}", api_{n});\n'
.format(n=s.caller))
@@ -1474,7 +1503,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
' vl_noop_handler,\n'
' vl_api_{n}_t_endian, '
' vl_api_{n}_t_print,\n'
' sizeof(vl_api_{n}_t), 1);\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'
.format(n=e, ID=e.upper()))
write('}\n')
@@ -1526,7 +1558,7 @@ api_{n} (cJSON *o)
mp->_vl_msg_id = vac_get_msg_index(VL_API_{N}_CRC);
vl_api_{n}_t_endian(mp);
vac_write((char *)mp, len);
free(mp);
cJSON_free(mp);
/* Read reply */
char *p;
@@ -1559,7 +1591,7 @@ api_{n} (cJSON *o)
mp->_vl_msg_id = msg_id;
vl_api_{n}_t_endian(mp);
vac_write((char *)mp, len);
free(mp);
cJSON_free(mp);
vat2_control_ping(123); // FIX CONTEXT
cJSON *reply = cJSON_CreateArray();
@@ -1615,7 +1647,7 @@ api_{n} (cJSON *o)
vl_api_{n}_t_endian(mp);
vac_write((char *)mp, len);
free(mp);
cJSON_free(mp);
cJSON *reply = cJSON_CreateArray();
@@ -1713,13 +1745,16 @@ def generate_c_test2_boilerplate(services, defines, module, stream):
continue
c_test_api_service(s, s.stream, stream)
write('void vat2_register_function(char *, cJSON * (*)(cJSON *), cJSON * (*)(void *));\n')
write('void vat2_register_function(char *, cJSON * (*)(cJSON *), cJSON * (*)(void *), u32);\n')
# write('__attribute__((constructor))')
write('clib_error_t *\n')
write('vat2_register_plugin (void) {\n')
for s in services:
write(' vat2_register_function("{n}", api_{n}, (cJSON * (*)(void *))vl_api_{n}_t_tojson);\n'
.format(n=s.caller))
if s.reply not in define_hash:
continue
crc = define_hash[s.caller].crc
write(' vat2_register_function("{n}", api_{n}, (cJSON * (*)(void *))vl_api_{n}_t_tojson, 0x{crc:08x});\n'
.format(n=s.caller, crc=crc))
write(' return 0;\n')
write('}\n')
-1
View File
@@ -1 +0,0 @@
vppapitrace.py
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -2627,7 +2627,9 @@ vat_api_hookup (vat_main_t * vam)
#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, sizeof (vl_api_##n##_t), 1, \
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson);
foreach_vpe_api_reply_msg;
#if VPP_API_TEST_BUILTIN == 0
foreach_standalone_reply_msg;
-4
View File
@@ -18,7 +18,6 @@ add_vpp_executable(vat2 ENABLE_EXPORTS
SOURCES
main.c
plugin.c
jsonconvert.c
DEPENDS api_headers
@@ -41,7 +40,6 @@ vpp_generate_api_c_header (test/vat2_test.api)
add_vpp_executable(test_vat2 ENABLE_EXPORTS NO_INSTALL
SOURCES
test/vat2_test.c
jsonconvert.c
DEPENDS api_headers
@@ -57,7 +55,6 @@ add_vpp_executable(test_vat2 ENABLE_EXPORTS NO_INSTALL
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13" AND "${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
set(TARGET_NAME test_vat2)
set(COV_SOURCES ${CMAKE_SOURCE_DIR}/vat2/jsonconvert.c)
message("Building with llvm Code Coverage Tools ${TARGET_NAME}")
target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping)
@@ -96,7 +93,6 @@ endif()
##############################################################################
install(
FILES
jsonconvert.h
vat2_helpers.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vat2
COMPONENT vpp-dev
-105
View File
@@ -1,105 +0,0 @@
/*
* Copyright (c) 2020 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef included_json_convert_h
#define included_json_convert_h
#include <stdbool.h>
#include <vppinfra/cJSON.h>
#include <vnet/ethernet/mac_address.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/ip/ip_types.api_types.h>
#include <vnet/ethernet/ethernet_types.api_types.h>
#define foreach_vat2_fromjson \
_(i8) \
_(u8) \
_(i16) \
_(u16) \
_(i32) \
_(u32) \
_(u64) \
_(f64)
#define _(T) \
int vl_api_ ##T## _fromjson(cJSON *o, T *d);
foreach_vat2_fromjson
#undef _
/* Prototypes */
int
vl_api_bool_fromjson (cJSON *o, bool *d);
int vl_api_ip4_address_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip4_address_t *a);
int vl_api_ip4_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip4_prefix_t *a);
int vl_api_ip4_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip4_prefix_t *a);
int vl_api_ip6_address_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip6_address_t *a);
int vl_api_ip6_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip6_prefix_t *a);
int vl_api_ip6_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_ip6_prefix_t *a);
int vl_api_address_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_address_t *a);
int vl_api_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_prefix_t *a);
int vl_api_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_prefix_t *a);
int vl_api_mac_address_t_fromjson (void **mp, int *len, cJSON *o,
vl_api_mac_address_t *a);
uword unformat_ip4_address (unformat_input_t *input, va_list *args);
uword unformat_ip6_address (unformat_input_t *input, va_list *args);
u8 *format_ip6_address (u8 *s, va_list *args);
uword unformat_mac_address (unformat_input_t *input, va_list *args);
u8 *format_ip4_address (u8 *s, va_list *args);
u8 *format_vl_api_interface_index_t (u8 *s, va_list *args);
u8 *format_vl_api_timestamp_t (u8 *s, va_list *args);
u8 *format_vl_api_timedelta_t (u8 *s, va_list *args);
uword unformat_vl_api_timedelta_t (unformat_input_t *input, va_list *args);
uword unformat_vl_api_timestamp_t (unformat_input_t *input, va_list *args);
u8 *format_vl_api_gbp_scope_t (u8 *s, va_list *args);
uword unformat_vl_api_gbp_scope_t (unformat_input_t *input, va_list *args);
int vl_api_c_string_to_api_string (const char *buf, vl_api_string_t *str);
void vl_api_string_cJSON_AddToObject (cJSON *const object,
const char *const name,
vl_api_string_t *astr);
u8 *u8string_fromjson (cJSON *o, char *fieldname);
int u8string_fromjson2 (cJSON *o, char *fieldname, u8 *data);
int vl_api_u8_string_fromjson (cJSON *o, u8 *s, int len);
#define foreach_vat2_tojson \
_(ip4_address) \
_(ip4_prefix) \
_(ip6_address) \
_(ip6_prefix) \
_(address) \
_(prefix) \
_(mac_address)
#define _(T) \
cJSON *vl_api_ ##T## _t_tojson(vl_api_ ##T## _t *);
foreach_vat2_tojson
#undef _
cJSON *vl_api_ip4_address_with_prefix_t_tojson (vl_api_ip4_prefix_t *a);
cJSON *vl_api_ip6_address_with_prefix_t_tojson (vl_api_ip6_prefix_t *a);
cJSON *vl_api_address_with_prefix_t_tojson (vl_api_prefix_t *a);
#endif
+60 -8
View File
@@ -18,7 +18,7 @@
#include <stdbool.h>
#include <ctype.h>
#include <getopt.h>
#include <assert.h>
#include <string.h>
#include <vlib/vlib.h>
#include <vlibapi/api_types.h>
#include <vppinfra/hash.h>
@@ -30,6 +30,33 @@
#include <limits.h>
#include "vat2.h"
/*
* Filter these messages as they are used to manage the API connection to VPP
*/
char *filter_messages_strings[] = { "memclnt_create",
"memclnt_delete",
"sockclnt_create",
"sockclnt_delete",
"memclnt_rx_thread_suspend",
"memclnt_read_timeout",
"rx_thread_exit",
"trace_plugin_msg_ids",
0 };
static bool
filter_message (char *msgname)
{
char **p = filter_messages_strings;
while (*p)
{
if (strcmp (*p, msgname) == 0)
return true;
p++;
}
return false;
}
uword *function_by_name;
bool debug = false;
@@ -89,15 +116,16 @@ struct apifuncs_s
{
cJSON (*f) (cJSON *);
cJSON (*tojson) (void *);
u32 crc;
};
struct apifuncs_s *apifuncs = 0;
void
vat2_register_function (char *name, cJSON (*f) (cJSON *),
cJSON (*tojson) (void *))
cJSON (*tojson) (void *), u32 crc)
{
struct apifuncs_s funcs = { .f = f, .tojson = tojson };
struct apifuncs_s funcs = { .f = f, .tojson = tojson, .crc = crc };
vec_add1 (apifuncs, funcs);
hash_set_mem (function_by_name, name, vec_len (apifuncs) - 1);
}
@@ -105,12 +133,28 @@ vat2_register_function (char *name, cJSON (*f) (cJSON *),
static int
vat2_exec_command_by_name (char *msgname, cJSON *o)
{
if (filter_message (msgname))
return 0;
cJSON *crc_obj = cJSON_GetObjectItem (o, "_crc");
if (!crc_obj)
{
fprintf (stderr, "Missing '_crc' element!\n");
return -1;
}
char *crc_str = cJSON_GetStringValue (crc_obj);
u32 crc = (u32) strtol (crc_str, NULL, 16);
uword *p = hash_get_mem (function_by_name, msgname);
if (!p)
{
fprintf (stderr, "No such command %s", msgname);
fprintf (stderr, "No such command %s\n", msgname);
return -1;
}
if (crc != apifuncs[p[0]].crc)
{
fprintf (stderr, "API CRC does not match: %s!\n", msgname);
}
cJSON *(*fp) (cJSON *);
fp = (void *) apifuncs[p[0]].f;
@@ -143,9 +187,10 @@ vat2_exec_command (cJSON *o)
}
char *name = cJSON_GetStringValue (msg_id_obj);
assert (name);
return vat2_exec_command_by_name (name, o);
}
static void
print_template (char *msgname)
{
@@ -307,6 +352,12 @@ int main (int argc, char **argv)
}
}
if (!msgname && !filename)
{
print_help ();
exit (-1);
}
/* Read message from file */
if (filename) {
if (argc > index)
@@ -325,6 +376,7 @@ int main (int argc, char **argv)
fprintf(stderr, "%s: can't open file: %s\n", argv[0], filename);
exit(-1);
}
chunksize = bufsize = 1024;
char *buf = malloc(bufsize);
while ((n = fread (buf + n_read, 1, chunksize, f)))
@@ -339,17 +391,17 @@ int main (int argc, char **argv)
fclose(f);
if (n_read) {
o = cJSON_Parse(buf);
free(buf);
if (!o) {
fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
exit(-1);
}
}
free (buf);
}
if (!msgname && !filename)
if (!o)
{
print_help ();
fprintf (stderr, "%s: Failed parsing JSON input\n", argv[0]);
exit (-1);
}
+1
View File
@@ -196,6 +196,7 @@ struct tests tests[] = {
"[\"2001:db8::23\", \"2001:db8::23\"] }" },
{ .s = "{\"_msgname\": \"test_empty\"}" },
{ .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 100 }" },
{ .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 4294967295 }" },
};
int main (int argc, char **argv)
+5 -4
View File
@@ -299,10 +299,11 @@ vcl_bapi_hookup (void)
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_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);
foreach_sock_msg;
#undef _
}
+7 -2
View File
@@ -36,8 +36,8 @@ typedef CLIB_PACKED ( struct {
}) vl_api_trace_file_header_t;
/* *INDENT-ON* */
int vl_msg_api_trace_save (api_main_t * am,
vl_api_trace_which_t which, FILE * fp);
int vl_msg_api_trace_save (api_main_t *am, vl_api_trace_which_t which,
FILE *fp, u8 is_json);
#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)
@@ -123,6 +123,11 @@ vlib_node_t ***vlib_node_unserialize (u8 * vector);
u32 vl_msg_api_get_msg_length (void *msg_arg);
typedef int (*vl_msg_traverse_trace_fn) (u8 *, void *);
int vl_msg_traverse_trace (vl_api_trace_t *tp, vl_msg_traverse_trace_fn fn,
void *ctx);
#endif /* included_api_h */
/*
* fd.io coding-style-patch-verification: ON
+20 -5
View File
@@ -27,6 +27,7 @@
#include <vppinfra/clib_error.h>
#include <vppinfra/elog.h>
#include <vppinfra/cJSON.h>
#include <vlibapi/api_types.h>
#include <svm/svm_common.h>
#include <svm/queue.h>
@@ -128,6 +129,9 @@ typedef struct
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 *tojson; /**< binary to JSON convert function */
void *fromjson; /**< JSON to binary convert function */
int size; /**< message size */
int traced; /**< is this message to be traced? */
int replay; /**< is this message to be replayed? */
@@ -173,11 +177,10 @@ void vl_msg_api_trace_only (void *the_msg);
void vl_msg_api_cleanup_handler (void *the_msg);
void vl_msg_api_replay_handler (void *the_msg);
void vl_msg_api_socket_handler (void *the_msg);
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 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 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);
@@ -241,9 +244,21 @@ typedef struct api_main_t
/** Message print function vector */
void (**msg_print_handlers) (void *, void *);
/** Message print function vector in JSON */
void (**msg_print_json_handlers) (void *, void *);
/** Message convert function vector */
cJSON *(**msg_tojson_handlers) (void *);
/** Message convert function vector */
void *(**msg_fromjson_handlers) (cJSON *, int *);
/** Message name vector */
const char **msg_names;
/** API message ID by name hash table */
uword *msg_id_by_name;
/** Don't automatically free message buffer vetor */
u8 *message_bounce;
+182 -101
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -57,3 +57,9 @@ add_dependencies(vlibmemoryclient vlibmemory_api_headers)
add_vat_test_library(vlib
vlibapi_test.c
)
##############################################################################
# VAT2 plugins
##############################################################################
add_vpp_test_library(vlibmemoryclient
memclnt.api
)
+1 -3
View File
@@ -29,7 +29,6 @@ service {
/*
* Create a client registration
*/
manual_print
define memclnt_create {
u32 context; /* opaque value to be returned in the reply */
i32 ctx_quota; /* requested punt context quota */
@@ -49,7 +48,6 @@ define memclnt_create_reply {
/*
* Delete a client registration
*/
manual_print
define memclnt_delete {
u32 index; /* index, used e.g. by API trace replay */
u64 handle; /* handle by which vlib knows this client */
@@ -137,7 +135,7 @@ define api_versions_reply {
* at api trace replay time
*/
manual_print define trace_plugin_msg_ids
define trace_plugin_msg_ids
{
u32 client_index;
u32 context;
+18 -16
View File
@@ -52,16 +52,6 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_printfun
static inline void *
vl_api_trace_plugin_msg_ids_t_print (vl_api_trace_plugin_msg_ids_t *a,
void *handle)
{
vl_print (handle, "vl_api_trace_plugin_msg_ids: %s first %u last %u\n",
a->plugin_name, clib_host_to_net_u16 (a->first_msg_id),
clib_host_to_net_u16 (a->last_msg_id));
return handle;
}
/* instantiate all the endian swap functions we know about */
#define vl_endianfun
#include <vlibmemory/vl_memory_api_h.h>
@@ -154,6 +144,12 @@ vlib_api_init (void)
vl_msg_api_msg_config_t cfg;
vl_msg_api_msg_config_t *c = &cfg;
cJSON_Hooks cjson_hooks = {
.malloc_fn = clib_mem_alloc,
.free_fn = clib_mem_free,
};
cJSON_InitHooks (&cjson_hooks);
clib_memset (c, 0, sizeof (*c));
#define _(N, n) \
@@ -689,19 +685,25 @@ rpc_api_hookup (vlib_main_t *vm)
{
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_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##_t_fromjson);
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_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##_t_fromjson);
foreach_plugin_trace_msg;
#undef _
am->api_trace_cfg[VL_API_TRACE_PLUGIN_MSG_IDS].replay_enable = 0;
/* No reason to halt the parade to create a trace record... */
am->is_mp_safe[VL_API_TRACE_PLUGIN_MSG_IDS] = 1;
rpc_call_main_thread_cb_fn = vl_api_rpc_call_main_thread;
+5 -25
View File
@@ -38,26 +38,6 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
static inline void *
vl_api_memclnt_create_t_print (vl_api_memclnt_create_t * a, void *handle)
{
vl_print (handle, "vl_api_memclnt_create_t:\n");
vl_print (handle, "name: %s\n", a->name);
vl_print (handle, "input_queue: 0x%wx\n", a->input_queue);
vl_print (handle, "context: %u\n", (unsigned) a->context);
vl_print (handle, "ctx_quota: %ld\n", (long) a->ctx_quota);
return handle;
}
static inline void *
vl_api_memclnt_delete_t_print (vl_api_memclnt_delete_t * a, void *handle)
{
vl_print (handle, "vl_api_memclnt_delete_t:\n");
vl_print (handle, "index: %u\n", (unsigned) a->index);
vl_print (handle, "handle: 0x%wx\n", a->handle);
return handle;
}
volatile int **vl_api_queue_cursizes;
static void
@@ -417,11 +397,11 @@ vl_api_memclnt_keepalive_t_handler (vl_api_memclnt_keepalive_t * mp)
* don't trace memclnt_keepalive[_reply] msgs
*/
#define foreach_vlib_api_msg \
_(MEMCLNT_CREATE, memclnt_create, 1) \
_(MEMCLNT_DELETE, memclnt_delete, 1) \
_(MEMCLNT_KEEPALIVE, memclnt_keepalive, 0) \
_(MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply, 0)
#define foreach_vlib_api_msg \
_ (MEMCLNT_CREATE, memclnt_create, 0) \
_ (MEMCLNT_DELETE, memclnt_delete, 0) \
_ (MEMCLNT_KEEPALIVE, memclnt_keepalive, 0) \
_ (MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply, 0)
/*
* memory_api_init
+8 -8
View File
@@ -362,14 +362,14 @@ _(MEMCLNT_KEEPALIVE, memclnt_keepalive)
void
vl_client_install_client_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), 1);
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##_t_fromjson); \
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
foreach_api_msg;
#undef _
}
+19 -12
View File
@@ -495,7 +495,13 @@ vl_api_sockclnt_create_t_handler (vl_api_sockclnt_create_t * mp)
regp = socket_main.current_rp;
ASSERT (regp->registration_type == REGISTRATION_TYPE_SOCKET_SERVER);
/* client already connected through shared memory? */
if (!regp || regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER)
{
clib_warning (
"unsupported API call: already connected though shared memory?");
return;
}
regp->name = format (0, "%s%c", mp->name, 0);
@@ -765,14 +771,15 @@ reply:
vl_sock_api_send_fd_msg (cf->file_descriptor, &memfd->fd, 1);
}
#define foreach_vlib_api_msg \
_(SOCKCLNT_CREATE, sockclnt_create, 1) \
_(SOCKCLNT_DELETE, sockclnt_delete, 1) \
_(SOCK_INIT_SHM, sock_init_shm, 1)
#define foreach_vlib_api_msg \
_ (SOCKCLNT_CREATE, sockclnt_create, 0) \
_ (SOCKCLNT_DELETE, sockclnt_delete, 0) \
_ (SOCK_INIT_SHM, sock_init_shm, 0)
clib_error_t *
vl_sock_api_init (vlib_main_t * vm)
{
api_main_t *am = vlibapi_get_main ();
clib_file_main_t *fm = &file_main;
clib_file_t template = { 0 };
vl_api_registration_t *rp;
@@ -784,13 +791,13 @@ vl_sock_api_init (vlib_main_t * vm)
if (sm->socket_name == 0)
return 0;
#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);
#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##_t_fromjson); \
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
foreach_vlib_api_msg;
#undef _
+6 -7
View File
@@ -432,13 +432,12 @@ 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), 1);
#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##_t_fromjson);
foreach_sock_client_api_msg;
#undef _
}
File diff suppressed because it is too large Load Diff
+17 -14
View File
@@ -190,10 +190,11 @@ sr_mpls_api_hookup (vlib_main_t * vm)
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_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);
foreach_vpe_api_msg;
#undef _
@@ -201,21 +202,23 @@ sr_mpls_api_hookup (vlib_main_t * vm)
* Manually register the sr policy add msg, so we trace enough bytes
* to capture a typical segment list
*/
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_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_mod_t_tojson, vl_api_sr_mpls_policy_mod_t_fromjson);
/*
* Manually register the sr policy mod msg, so we trace enough bytes
* to capture a typical segment list
*/
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_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_tojson, vl_api_sr_mpls_policy_mod_t_fromjson);
/*
* Set up the (msg_name, crc, message-id) table
-8
View File
@@ -101,14 +101,6 @@ cleanup (void)
clib_memset(pm, 0, sizeof(*pm));
}
/*
* Satisfy external references when -lvlib is not available.
*/
void vlib_cli_output (struct vlib_main_t * vm, char * fmt, ...)
{
clib_warning ("vlib_cli_output called...");
}
void
vac_free (void * msg)
{
+3 -1
View File
@@ -39,7 +39,7 @@ install(
add_definitions(-fvisibility=hidden)
# Ensure symbols from cJSON are exported
set_source_files_properties( cJSON.c PROPERTIES
set_source_files_properties( cJSON.c jsonformat.c PROPERTIES
COMPILE_DEFINITIONS " CJSON_API_VISIBILITY " )
@@ -62,6 +62,7 @@ set(VPPINFRA_SRCS
hash.c
heap.c
interrupt.c
jsonformat.c
longjmp.S
macros.c
maplog.c
@@ -140,6 +141,7 @@ set(VPPINFRA_HEADERS
hash.h
heap.h
interrupt.h
jsonformat.h
lb_hash_hash.h
llist.h
lock.h
+49 -36
View File
@@ -157,7 +157,7 @@ typedef struct internal_hooks
{
void *(CJSON_CDECL *allocate)(size_t size);
void (CJSON_CDECL *deallocate)(void *pointer);
void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
void *(CJSON_CDECL *reallocate)(void *pointer, size_t new_size, size_t old_size);
} internal_hooks;
#if defined(_MSC_VER)
@@ -170,16 +170,20 @@ static void CJSON_CDECL internal_free(void *pointer)
{
free(pointer);
}
static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
{
return realloc(pointer, size);
}
#else
#define internal_malloc malloc
#define internal_free free
#define internal_realloc realloc
#endif
static void * CJSON_CDECL internal_realloc(void *pointer, size_t new_size,
size_t old_size)
{
return realloc(pointer, new_size);
}
static void *
cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size);
/* strlen of character literals resolved at compile time */
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
@@ -213,7 +217,7 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
/* Reset hooks */
global_hooks.allocate = malloc;
global_hooks.deallocate = free;
global_hooks.reallocate = realloc;
global_hooks.reallocate = internal_realloc;
return;
}
@@ -233,7 +237,11 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
global_hooks.reallocate = NULL;
if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
{
global_hooks.reallocate = realloc;
global_hooks.reallocate = internal_realloc;
}
else
{
global_hooks.reallocate = cjson_realloc_internal;
}
}
@@ -435,6 +443,27 @@ typedef struct
internal_hooks hooks;
} printbuffer;
static void *
cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size)
{
size_t copy_size;
if (old_size < new_size)
copy_size = old_size;
else
copy_size = new_size;
unsigned char *newbuffer = global_hooks.allocate(new_size);
if (!newbuffer)
{
global_hooks.deallocate(ptr);
return NULL;
}
memcpy (newbuffer, ptr, copy_size);
global_hooks.deallocate (ptr);
return newbuffer;
}
/* realloc printbuffer if necessary to have at least "needed" bytes more */
static unsigned char* ensure(printbuffer * const p, size_t needed)
{
@@ -486,34 +515,13 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
newsize = needed * 2;
}
if (p->hooks.reallocate != NULL)
newbuffer = p->hooks.reallocate (p->buffer, newsize, p->length);
if (newbuffer == NULL)
{
/* reallocate with realloc if available */
newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
if (newbuffer == NULL)
{
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
}
else
{
/* otherwise reallocate manually */
newbuffer = (unsigned char*)p->hooks.allocate(newsize);
if (!newbuffer)
{
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
memcpy (newbuffer, p->buffer, p->offset + 1);
p->hooks.deallocate (p->buffer);
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
p->length = newsize;
p->buffer = newbuffer;
@@ -1208,7 +1216,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
/* check if reallocate is available */
if (hooks->reallocate != NULL)
{
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1, default_buffer_size);
if (printed == NULL) {
goto fail;
}
@@ -3112,3 +3120,8 @@ CJSON_PUBLIC(void) cJSON_free(void *object)
{
global_hooks.deallocate(object);
}
CJSON_PUBLIC(void *) cJSON_realloc(void *object, size_t new_size, size_t old_size)
{
return global_hooks.reallocate(object, new_size, old_size);
}

Some files were not shown because too many files have changed in this diff Show More