Add client-side msg_name_and_crc -> msg_index table
vppapigen now generates per-message crcs. Verified that whitespace
and real changes in message A don't change the crc for message B, etc.
Fixed the sample and flowperpkt plugins to participate. Others need
the same treatment. They don't build due to python/java language binding
build issues.
To use the scheme:
Client connects as usual.
Then call: u32 vl_api_get_msg_index(char * name_and_crc)
name_and_crc is a string like: "flowperpkt_tx_interface_add_del_753301f3",
aka the message name with _%08x <expected crc> appended.
Try these vpp-api-test commands to play with it:
vat# dump_msg_api_table
<snip>
[366]: punt_reply_cca27fbe
[367]: ipsec_spd_dump_5e9ae88e
[368]: ipsec_spd_details_6f7821b0
[369]: sample_macswap_enable_disable_0f2813e2
[370]: sample_macswap_enable_disable_reply_476738e5
[371]: flowperpkt_tx_interface_add_del_753301f3
[372]: flowperpkt_tx_interface_add_del_reply_d47e6e0b
vat# get_msg_id sample_macswap_enable_disable_reply_476738e5
'sample_macswap_enable_disable_reply_476738e5' has message index 370
vat# get_msg_id sample_macswap_enable_disable_reply_476738e3
'sample_macswap_enable_disable_reply_476738e3' not found
CRCs may vary, etc.
vppapigen is used to build a set of JSON representations
of each API file from vpp-api/Makefile.am and that is in
turn used by each language binding (Java, Python, Lua).
Change-Id: I3d64582e779dac5f20cddec79c562c288d8fd9c6
Signed-off-by: Dave Barach <dave@barachs.net>
Signed-off-by: Ole Troan <ot@cisco.com>
diff --git a/vppapigen/lex.c b/vppapigen/lex.c
index b011044..e807d46 100644
--- a/vppapigen/lex.c
+++ b/vppapigen/lex.c
@@ -28,7 +28,7 @@
#include "node.h"
#include "gram.h"
-FILE *ifp, *ofp, *pythonfp;
+FILE *ifp, *ofp, *pythonfp, *jsonfp;
char *vlib_app_name = "vpp";
int dump_tree;
time_t starttime;
@@ -36,6 +36,7 @@
char *current_filename;
int current_filename_allocated;
unsigned long input_crc;
+unsigned long message_crc;
int yydebug;
/*
@@ -258,6 +259,7 @@
int curarg = 1;
char *ofile=0;
char *pythonfile=0;
+ char *jsonfile=0;
char *show_name=0;
while (curarg < argc) {
@@ -349,6 +351,27 @@
}
continue;
}
+ if (!strncmp (argv [curarg], "--json", 6)) {
+ curarg++;
+ if (curarg < argc) {
+ if (!strcmp(argv[curarg], "-")) {
+ jsonfp = stdout;
+ } else {
+ jsonfp = fopen(argv[curarg], "w");
+ jsonfile = argv[curarg];
+ }
+ if (jsonfp == NULL) {
+ fprintf (stderr, "Couldn't open JSON output file %s\n",
+ argv[curarg]);
+ exit (1);
+ }
+ curarg++;
+ } else {
+ fprintf(stderr, "Missing filename after --json\n");
+ exit(1);
+ }
+ continue;
+ }
if (!strncmp (argv [curarg], "--app", 4)) {
curarg++;
if (curarg < argc) {
@@ -370,6 +393,9 @@
if (pythonfp == NULL) {
pythonfile = 0;
}
+ if (jsonfp == NULL) {
+ jsonfile = 0;
+ }
if (ifp == NULL) {
fprintf(stderr, "No input file specified...\n");
exit(1);
@@ -391,6 +417,10 @@
printf ("Python bindings written to %s\n", pythonfile);
fclose (pythonfp);
}
+ if (jsonfile) {
+ printf ("JSON bindings written to %s\n", jsonfile);
+ fclose (jsonfp);
+ }
}
else {
fclose (ifp);
@@ -404,6 +434,10 @@
printf ("Removing %s\n", pythonfile);
unlink (pythonfile);
}
+ if (jsonfile) {
+ printf ("Removing %s\n", jsonfile);
+ unlink (jsonfile);
+ }
exit (1);
}
exit (0);
@@ -415,7 +449,8 @@
static void usage (char *progname)
{
fprintf (stderr,
- "usage: %s --input <filename> [--output <filename>] [--python <filename>]\n%s",
+ "usage: %s --input <filename> [--output <filename>] "
+ "[--json <filename>] [--python <filename>]\n%s",
progname,
" [--yydebug] [--dump-tree]\n");
exit (1);
@@ -818,18 +853,18 @@
*/
unsigned long crc = input_crc;
int node_type = yylex_1 ();
+ unsigned long crc2 = message_crc;
+ int use_helper_string = 0;
+ unsigned short code;
switch (node_type) {
case PRIMTYPE:
case NAME:
case NUMBER:
case STRING:
- case HELPER_STRING: {
- /* We know these types accumulated token text into namebuf */
- /* HELPER_STRING may still contain C comments. Argh. */
- crc = crc_eliding_c_comments (namebuf, crc);
+ case HELPER_STRING:
+ use_helper_string = 1;
break;
- }
/* Other node types have no "substate" */
/* This code is written in this curious fashion because we
@@ -837,30 +872,25 @@
* values a particular version of lex/bison assigned to various states.
*/
- /* case NAME: crc = CRC16 (crc, 257); break; */
- case RPAR: crc = CRC16 (crc, 258); break;
- case LPAR: crc = CRC16 (crc, 259); break;
- case SEMI: crc = CRC16 (crc, 260); break;
- case LBRACK: crc = CRC16 (crc, 261); break;
- case RBRACK: crc = CRC16 (crc, 262); break;
- /* case NUMBER: crc = CRC16 (crc, 263); break; */
- /* case PRIMTYPE: crc = CRC16 (crc, 264); break; */
- case BARF: crc = CRC16 (crc, 265); break;
- case TPACKED: crc = CRC16 (crc, 266); break;
- case DEFINE: crc = CRC16 (crc, 267); break;
- case LCURLY: crc = CRC16 (crc, 268); break;
- case RCURLY: crc = CRC16 (crc, 269); break;
- /* case STRING: crc = CRC16 (crc, 270); break; */
- case UNION: crc = CRC16 (crc, 271); break;
- /* case HELPER_STRING: crc = CRC16 (crc, 272); break; */
- case COMMA: crc = CRC16 (crc, 273); break;
- case NOVERSION: crc = CRC16 (crc, 274); break;
- case MANUAL_PRINT: crc = CRC16 (crc, 275); break;
- case MANUAL_ENDIAN: crc = CRC16 (crc, 276); break;
- case TYPEONLY: crc = CRC16 (crc, 278); break;
- case DONT_TRACE: crc = CRC16 (crc, 279); break;
+ case RPAR: code = 258; break;
+ case LPAR: code = 259; break;
+ case SEMI: code = 260; break;
+ case LBRACK: code = 261; break;
+ case RBRACK: code = 262; break;
+ case BARF: code = 265; break;
+ case TPACKED: code = 266; break;
+ case DEFINE: code = 267; break;
+ case LCURLY: code = 268; break;
+ case RCURLY: code = 269; break;
+ case UNION: code = 271; break;
+ case COMMA: code = 273; break;
+ case NOVERSION: code = 274; break;
+ case MANUAL_PRINT: code = 275; break;
+ case MANUAL_ENDIAN: code = 276; break;
+ case TYPEONLY: code = 278; break;
+ case DONT_TRACE: code = 279; break;
- case EOF: crc = CRC16 (crc, ~0); break; /* hysterical compatibility */
+ case EOF: code = ~0; break; /* hysterical compatibility */
default:
fprintf(stderr, "yylex: node_type %d missing state CRC cookie\n",
@@ -868,11 +898,23 @@
exit(1);
}
+ if (use_helper_string)
+ {
+ /* We know these types accumulated token text into namebuf */
+ /* HELPER_STRING may still contain C comments. Argh. */
+ crc = crc_eliding_c_comments (namebuf, crc);
+ crc2 = crc_eliding_c_comments (namebuf, crc2);
+ } else
+ {
+ crc = CRC16 (crc, code);
+ crc2 = CRC16 (crc2, code);
+ }
+
input_crc = crc;
+ message_crc = crc2;
return (node_type);
}
-
/*
* name_check -- see if the name we just ate
* matches a known keyword. If so, set yylval
@@ -943,6 +985,7 @@
return (TPACKED);
case NODE_DEFINE:
+ message_crc = 0;
*token_value = make_node(subclass_id);
return(DEFINE);