Python-API: Inital commit of Python bindings for the VPP API.
See: https://wiki.fd.io/view/VPP/Python_API
Change-Id: If135fc32208c7031787e1935b399d930e0e1ea1f
Signed-off-by: Ole Troan <ot@cisco.com>
diff --git a/vppapigen/lex.c b/vppapigen/lex.c
index b41eb5e..f1d49a8 100644
--- a/vppapigen/lex.c
+++ b/vppapigen/lex.c
@@ -28,7 +28,7 @@
#include "node.h"
#include "gram.h"
-FILE *ifp, *ofp, *javafp, *jnifp;
+FILE *ifp, *ofp, *javafp, *jnifp, *pythonfp;
char *java_class = "vppApi";
char *vlib_app_name = "vpp";
int dump_tree;
@@ -260,6 +260,7 @@
char *ofile=0;
char *jofile=0;
char *jnifile=0;
+ char *pythonfile=0;
char *show_name=0;
while (curarg < argc) {
@@ -364,6 +365,23 @@
}
continue;
}
+ if (!strncmp (argv [curarg], "--python", 8)) {
+ curarg++;
+ if (curarg < argc) {
+ pythonfp = fopen (argv[curarg], "w");
+ if (pythonfp == NULL) {
+ fprintf (stderr, "Couldn't open python output file %s\n",
+ argv[curarg]);
+ exit (1);
+ }
+ pythonfile = argv[curarg];
+ curarg++;
+ } else {
+ fprintf(stderr, "Missing filename after --python\n");
+ exit(1);
+ }
+ continue;
+ }
if (!strncmp (argv [curarg], "--app", 4)) {
curarg++;
if (curarg < argc) {
@@ -399,6 +417,9 @@
if (jnifp == NULL) {
jnifile = 0;
}
+ if (pythonfp == NULL) {
+ pythonfile = 0;
+ }
if (ifp == NULL) {
fprintf(stderr, "No input file specified...\n");
exit(1);
@@ -424,6 +445,10 @@
printf ("Java native bindings written to %s\n", jnifile);
fclose (jnifp);
}
+ if (pythonfile) {
+ printf ("Python bindings written to %s\n", pythonfile);
+ fclose (pythonfp);
+ }
}
else {
fclose (ifp);
@@ -441,6 +466,10 @@
printf ("Removing %s\n", jnifile);
unlink (jnifile);
}
+ if (pythonfile) {
+ printf ("Removing %s\n", pythonfile);
+ unlink (pythonfile);
+ }
exit (1);
}
exit (0);
@@ -452,7 +481,7 @@
static void usage (char *progname)
{
fprintf (stderr,
- "usage: %s --input <filename> [--output <filename>]\n%s",
+ "usage: %s --input <filename> [--output <filename>] [--python <filename>]\n%s",
progname,
" [--yydebug] [--dump-tree]\n");
exit (1);
diff --git a/vppapigen/node.c b/vppapigen/node.c
index 3a32abe..ffe5d77 100644
--- a/vppapigen/node.c
+++ b/vppapigen/node.c
@@ -34,6 +34,7 @@
FILE *ofp;
FILE *javafp;
FILE *jnifp;
+FILE *pythonfp;
char *java_class;
time_t starttime;
char *vlib_app_name;
@@ -161,6 +162,12 @@
current_java_methodfun = vftp->java_method_function;
break;
+ case PYTHON_PASS:
+ fputs("('", pythonfp);
+ fputs((char *)type_name, pythonfp);
+ fputs("', ", pythonfp);
+ break;
+
default:
fprintf(stderr, "primtype_recursive_generate: unimp pass %d\n", which);
break;
@@ -876,6 +883,20 @@
fprintf (fp, "}\n\n");
break;
+ case PYTHON_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;
+ }
+ indent -= 4;
+ fprintf(fp, "),\n\n");
+ break;
+
default:
fprintf(stderr, "node_define_generate: unimp pass %d\n", which);
break;
@@ -1032,6 +1053,9 @@
}
}
break;
+ case PYTHON_PASS:
+ fprintf(fp, "'%s'),\n", CDATA0);
+ break;
default:
fprintf(stderr, "node_scalar_generate: unimp pass %d\n", which);
@@ -1136,6 +1160,9 @@
indent_me(fp);
fprintf(fp, "}\n");
break;
+ case PYTHON_PASS:
+ fprintf(fp, "'%s', '%d'),\n", CDATA0, IDATA1);
+ break;
default:
fprintf(stderr, "node_vector_generate: unimp pass %d\n", which);
@@ -1216,6 +1243,14 @@
fprintf(fp, "%s_endian(&a->%s%s);\n",
CDATA0, union_prefix, member_name);
break;
+ case PYTHON_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);
@@ -1767,14 +1802,14 @@
while (np) {
if (np->type == NODE_DEFINE) {
if (!(np->flags & NODE_FLAG_TYPEONLY)) {
- /* add the parse tree for "u16 _vl_msg_id" */
+ /* add the parse tree for "u16 _vl_msg_id" */
new_u16 = make_node(NODE_U16);
new_u16->peer = np->deeper;
np->deeper = new_u16;
new_vbl = make_node(NODE_SCALAR);
new_vbl->data[0] = sxerox("_vl_msg_id");
new_u16->deeper = new_vbl;
- }
+ }
}
np = np->peer;
}
@@ -1988,6 +2023,23 @@
fputs (hookup_boilerplate, fp);
}
+void generate_python (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);
+ }
+ np = np->peer;
+ }
+ fprintf (fp, "\n]\n");
+}
+
void generate(YYSTYPE a1)
{
if (dump_tree) {
@@ -2020,4 +2072,7 @@
generate_jni_code(a1, jnifp);
generate_jni_bottom_boilerplate(jnifp);
}
+ if (pythonfp) {
+ generate_python(a1, pythonfp);
+ }
}
diff --git a/vppapigen/node.h b/vppapigen/node.h
index 670b5af..1f5a153 100644
--- a/vppapigen/node.h
+++ b/vppapigen/node.h
@@ -63,6 +63,7 @@
PRINTFUN_PASS,
JAVA_METHOD_PASS,
JAVA_JNI_PASS,
+ PYTHON_PASS,
};
extern void *make_node (enum node_subclass type);