X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vppapigen%2Fnode.c;h=abb909a17033ff8f073326fe3bcd5d4804a39b4f;hb=refs%2Fchanges%2F49%2F4149%2F1;hp=ef812787c8a9b283fa52efc478cfa438df1b510c;hpb=948b95a9a08d38e7f74a160c11193f73a90e98c9;p=vpp.git diff --git a/vppapigen/node.c b/vppapigen/node.c index ef812787c8a..abb909a1703 100644 --- a/vppapigen/node.c +++ b/vppapigen/node.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -33,6 +34,7 @@ FILE *ofp; FILE *pythonfp; +FILE *jsonfp; time_t starttime; char *vlib_app_name; char *input_filename; @@ -130,6 +132,12 @@ void primtype_recursive_generate(node_t *this, enum passid which, FILE *ofp, fputs("', ", pythonfp); break; + case JSON_PASS: + fputs("[\"", jsonfp); + fputs((char *)type_name, jsonfp); + fputs("\", ", jsonfp); + break; + default: fprintf(stderr, "primtype_recursive_generate: unimp pass %d\n", which); break; @@ -172,7 +180,7 @@ void node_u8_generate (node_t *this, enum passid which, FILE *ofp) node_vft_t node_u8_vft = { node_u8_print, node_u8_generate, - "" + NULL }; void node_u16_print (node_t *this) @@ -377,6 +385,24 @@ void node_define_generate (node_t *this, enum passid which, FILE *fp) fprintf(fp, "),\n\n"); break; + case JSON_PASS: + fprintf(fp, "[\"%s\",\n", CDATA0); + child = this->deeper; + indent += 4; + while (child) { + node_vft_t *vftp = the_vft[child->type]; + indent_me(fp); + vftp->generate(child, which, fp); + child = child->peer; + fprintf(fp, ",\n"); + } + indent_me(fp); + fprintf (fp, "{\"crc\" : \"0x%08x\"}\n", (u32)(u64)CDATA3); + indent -= 4; + indent_me(fp); + fprintf(fp, "]"); + break; + default: fprintf(stderr, "node_define_generate: unimp pass %d\n", which); break; @@ -527,7 +553,7 @@ void node_scalar_generate (node_t *this, enum passid which, FILE *fp) CDATA0, current_endianfun, union_prefix, CDATA0); } else { - fprintf(fp, "/* a->%s%s = a->%s%s */\n", + fprintf(fp, "/* a->%s%s = a->%s%s (no-op) */\n", union_prefix, CDATA0, union_prefix, CDATA0); } @@ -537,6 +563,10 @@ void node_scalar_generate (node_t *this, enum passid which, FILE *fp) fprintf(fp, "'%s'),\n", CDATA0); break; + case JSON_PASS: + fprintf(fp, "\"%s\"]", CDATA0); + break; + default: fprintf(stderr, "node_scalar_generate: unimp pass %d\n", which); } @@ -611,6 +641,16 @@ void node_vector_generate (node_t *this, enum passid which, FILE *fp) /* Don't bother about "u8 data [0];" et al. */ if (IDATA1 == 0) break; + /* If this is a simple endian swap, but the endian swap method is a no-op, + * then indicate this is a no-op in a comment. + */ + if (!current_is_complex && current_endianfun == NULL) { + indent_me(fp); + fprintf(fp, "/* a->%s%s[0..%d] = a->%s%s[0..%d] (no-op) */\n", + union_prefix, CDATA0, IDATA1 - 1, + union_prefix, CDATA0, IDATA1 - 1); + break; + } indent_me(fp); fprintf(fp, "{\n"); @@ -648,6 +688,14 @@ void node_vector_generate (node_t *this, enum passid which, FILE *fp) } break; + case JSON_PASS: + if (CDATA2 != 0) { /* variable length vector */ + fprintf(fp, "\"%s\", %d, \"%s\"]", CDATA0, IDATA1, CDATA2); + } else { + fprintf(fp, "\"%s\", %d]", CDATA0, IDATA1); + } + break; + default: fprintf(stderr, "node_vector_generate: unimp pass %d\n", which); } @@ -736,6 +784,15 @@ void node_complex_generate (node_t *this, enum passid which, FILE *fp) } break; + case JSON_PASS: + fprintf(fp, "[\"%s\", ", CDATA0); + deeper = this->deeper; + if (deeper) { + vftp = the_vft[deeper->type]; + vftp->generate(deeper, which, fp); + } + break; + default: fprintf(stderr, "node_complex_generate unimp pass %d...\n", which); break; @@ -869,6 +926,7 @@ YYSTYPE add_define (YYSTYPE a1, YYSTYPE a2) np = make_node(NODE_DEFINE); np->data[0] = a1; + np->data[3] = (void *) message_crc; deeper((YYSTYPE)np, a2); return ((YYSTYPE) np); } @@ -1024,7 +1082,7 @@ char *fixup_input_filename(void) if (*cp == '/') cp++; - strcpy (tmpbuf, cp); + strncpy (tmpbuf, cp, sizeof(tmpbuf)-1); cp = tmpbuf; @@ -1055,15 +1113,11 @@ void generate_top_boilerplate(FILE *fp) fprintf (fp, " * Input file: %s\n", input_filename); fprintf (fp, " * Automatically generated: please edit the input file "); fprintf (fp, "NOT this file!\n"); - - /* Moron Acme trigger workaround */ - fprintf (fp, " * %syright (c) %s by Cisco Systems, Inc.\n", "Cop", - &datestring[20]); fprintf (fp, " */\n\n"); fprintf (fp, "#if defined(vl_msg_id)||defined(vl_union_id)||"); fprintf (fp, "defined(vl_printfun) \\\n ||defined(vl_endianfun)||"); fprintf (fp, " defined(vl_api_version)||defined(vl_typedefs) \\\n"); - fprintf (fp, " ||defined(vl_msg_name)\n"); + fprintf (fp, " ||defined(vl_msg_name)||defined(vl_msg_name_crc_list)\n"); fprintf (fp, "/* ok, something was selected */\n"); fprintf (fp, "#else\n"); fprintf (fp, "#warning no content included from %s\n", input_filename); @@ -1131,6 +1185,38 @@ void generate_msg_names(YYSTYPE a1, FILE *fp) fprintf (fp, "#endif\n\n"); } +void generate_msg_name_crc_list (YYSTYPE a1, FILE *fp) +{ + node_t *np = (node_t *)a1; + char *unique_suffix, *cp; + + unique_suffix = sxerox(fixed_name); + + cp = unique_suffix; + while (*cp && (*cp != '.')) + cp++; + if (*cp == '.') + *cp = 0; + + fprintf (fp, "\n/****** Message name, crc list ******/\n\n"); + + fprintf (fp, "#ifdef vl_msg_name_crc_list\n"); + fprintf (fp, "#define foreach_vl_msg_name_crc_%s ", unique_suffix); + + while (np) { + if (np->type == NODE_DEFINE) { + if (!(np->flags & NODE_FLAG_TYPEONLY)) { + fprintf (fp, "\\\n_(VL_API_%s, %s, %08x) ", + uppercase (np->data[0]), (i8 *) np->data[0], + (u32)(u64)np->data[3]); + } + } + np = np->peer; + } + fprintf (fp, "\n#endif\n\n"); + free (unique_suffix); +} + void generate_typedefs(YYSTYPE a1, FILE *fp) { node_t *np = (node_t *)a1; @@ -1314,21 +1400,105 @@ void add_msg_ids(YYSTYPE a1) } } -void generate_python (YYSTYPE a1, FILE *fp) +void generate_python_msg_definitions(YYSTYPE a1, FILE *fp) { - node_t *np = (node_t *)a1; - node_vft_t *vftp; - fprintf (fp, "vppapidef = [\n"); - /* Walk the top-level node-list */ - while (np) { - if (np->type == NODE_DEFINE && !(np->flags & NODE_FLAG_TYPEONLY)) { - /* Yeah, this is pedantic */ - vftp = the_vft[np->type]; - vftp->generate(np, PYTHON_PASS, fp); + node_t *np = (node_t *)a1; + node_vft_t *vftp; + fprintf (fp, "messages = [\n"); + /* Walk the top-level node-list */ + while (np) { + if (np->type == NODE_DEFINE && !(np->flags & NODE_FLAG_TYPEONLY)) { + /* Yeah, this is pedantic */ + vftp = the_vft[np->type]; + vftp->generate(np, PYTHON_PASS, fp); + } + np = np->peer; } - np = np->peer; - } - fprintf (fp, "\n]\n"); + fprintf (fp, "\n]\n"); +} + +static bool +is_typeonly_check(node_t *np, bool typeonly) +{ + bool is_typeonly = (np->flags & NODE_FLAG_TYPEONLY); + return (is_typeonly == typeonly); +} + +static void +generate_json_definitions(YYSTYPE a1, FILE *fp, bool typeonly) +{ + node_t *np = (node_t *)a1; + node_vft_t *vftp; + indent_me(fp); + if (typeonly) + fprintf (fp, "\"types\" : [\n"); + else + fprintf (fp, "\"messages\" : [\n"); + + /* Walk the top-level node-list */ + bool comma = false; + indent += 4; + while (np) { + if (np->type == NODE_DEFINE && is_typeonly_check(np, typeonly)) { + /* Yeah, this is pedantic */ + vftp = the_vft[np->type]; + indent_me(fp); + vftp->generate(np, JSON_PASS, fp); + comma = true; + } + np = np->peer; + if (comma && np && + np->type == NODE_DEFINE && is_typeonly_check(np, typeonly)) + fprintf (fp, ",\n"); + + } + indent -= 4; + fprintf (fp, "\n"); + indent_me(fp); + fprintf(fp, "]"); +} + +void generate_python_typeonly_definitions(YYSTYPE a1, FILE *fp) +{ + node_t *np = (node_t *)a1; + node_vft_t *vftp; + fprintf (fp, "types = [\n"); + /* Walk the top-level node-list */ + while (np) { + if (np->type == NODE_DEFINE && (np->flags & NODE_FLAG_TYPEONLY)) { + vftp = the_vft[np->type]; + vftp->generate(np, PYTHON_PASS, fp); + } + np = np->peer; + } + fprintf (fp, "\n]\n"); +} + +void generate_python(YYSTYPE a1, FILE *fp) +{ + generate_python_typeonly_definitions(a1, fp); + generate_python_msg_definitions(a1, fp); + + /* + * API CRC signature + */ + fprintf (fp, "vl_api_version = 0x%08x\n\n", (unsigned int)input_crc); +} + +void generate_json(YYSTYPE a1, FILE *fp) +{ + fprintf (fp, "{\n"); + indent += 4; + generate_json_definitions(a1, fp, true); + fprintf (fp, ",\n"); + generate_json_definitions(a1, fp, false); + + /* + * API CRC signature + */ + fprintf (fp, ",\n\"vl_api_version\" :\"0x%08x\"\n", + (unsigned int)input_crc); + fprintf (fp, "}\n"); } void generate(YYSTYPE a1) @@ -1344,6 +1514,7 @@ void generate(YYSTYPE a1) generate_msg_ids(a1, ofp); generate_msg_names(a1, ofp); + generate_msg_name_crc_list(a1, ofp); generate_typedefs(a1, ofp); generate_uniondefs(a1, ofp); generate_printfun(a1, ofp); @@ -1354,4 +1525,7 @@ void generate(YYSTYPE a1) if (pythonfp) { generate_python(a1, pythonfp); } + if (jsonfp) { + generate_json(a1, jsonfp); + } }