ONE-15: Fix duplicate locator, refactoring locator
[vpp.git] / vppapigen / node.c
index b82816e..2fb65c2 100644 (file)
@@ -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 @@ void primtype_recursive_generate(node_t *this, enum passid which, FILE *ofp,
         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;
@@ -172,6 +179,20 @@ void primtype_recursive_generate(node_t *this, enum passid which, FILE *ofp,
     }
 }
 
+static int hidden_from_java(const node_t * deeper)
+{
+    if (current_java_parameter_number++ < 3) {
+        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
+            return 1;
+        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
+            return 1;
+        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
+            return 1;
+    }
+
+    return 0;
+}
+
 void primtype_java_method (node_t * this, enum passid which, FILE *ofp, 
                            char *java_type_name)
 {
@@ -180,13 +201,8 @@ void primtype_java_method (node_t * this, enum passid which, FILE *ofp,
     deeper = this->deeper;
 
     /* We'll take care of _msg_id, client_index, and context ourselves */
-    if (current_java_parameter_number++ < 3) {
-        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
-            return;
+    if (hidden_from_java(deeper)) {
+        return;
     }
 
     if (deeper->type == NODE_SCALAR)
@@ -207,13 +223,8 @@ void primtype_java_parameter (node_t * this, enum passid which, FILE *ofp,
     deeper = this->deeper;
 
     /* We'll take care of _msg_id, client_index, and context ourselves */
-    if (current_java_parameter_number++ < 3) {
-        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
-            return;
+    if (hidden_from_java(deeper)) {
+        return;
     }
     if (current_java_parameter_need_comma_space) {
         current_java_parameter_need_comma_space = 0;
@@ -236,13 +247,8 @@ void primtype_java_setup (node_t * this, enum passid which, FILE *ofp,
     deeper = this->deeper;
 
     /* We'll take care of _msg_id, client_index, and context ourselves */
-    if (current_java_parameter_number++ < 3) {
-        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
-            return;
+    if (hidden_from_java(deeper)) {
+        return;
     }
 
     if (deeper->type == NODE_VECTOR) {
@@ -265,13 +271,8 @@ void primtype_java_code (node_t * this, enum passid which, FILE *ofp,
     deeper = this->deeper;
 
     /* We'll take care of _msg_id, client_index, and context ourselves */
-    if (current_java_parameter_number++ < 3) {
-        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
-            return;
+    if (hidden_from_java(deeper)) {
+        return;
     }
 
     indent_me(ofp);
@@ -291,8 +292,8 @@ void primtype_java_code (node_t * this, enum passid which, FILE *ofp,
             indent_me(ofp);
             fprintf(ofp, "int _i;\n");
             indent_me(ofp);
-            fprintf(ofp, "for (_i = 0; _i < %d; _i++) {\n", 
-                    (int)(u64)(deeper->data[1]));
+            fprintf(ofp, "for (_i = 0; _i < %lu; _i++) {\n",
+                    (u64)(deeper->data[1]));
             indent += 4;
             indent_me(ofp);
             fprintf(ofp, "mp->%s[_i] = %s(%sP[_i]);\n",
@@ -319,13 +320,8 @@ void primtype_java_teardown (node_t * this, enum passid which, FILE *ofp,
     deeper = this->deeper;
 
     /* We'll take care of _msg_id, client_index, and context ourselves */
-    if (current_java_parameter_number++ < 3) {
-        if (!strncmp ((char *)(deeper->data[0]), "client_index", 12))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "context", 7))
-            return;
-        else if (!strncmp ((char *)(deeper->data[0]), "_vl_msg_id", 10))
-            return;
+    if (hidden_from_java(deeper)) {
+        return;
     }
 
     if (deeper->type == NODE_VECTOR) {
@@ -720,6 +716,18 @@ void node_define_print (node_t *this)
     fprintf(stdout, "};\n");
 }
 
+static void emit_java_arg_declaration(node_t *child, FILE *fp) {
+    current_java_parameter_number = 0;
+    while (child) {
+        node_vft_t *vftp = the_vft[child->type];
+        current_java_emitted_parameter = 0;
+        vftp->java_method_function(child, JAVA_METHOD_PASS, fp);
+        child = child->peer;
+        if (child && current_java_emitted_parameter)
+            fputs (", ", fp);
+    }
+}
+
 void node_define_generate (node_t *this, enum passid which, FILE *fp)
 {
     node_t *child, *save_child;
@@ -752,27 +760,49 @@ void node_define_generate (node_t *this, enum passid which, FILE *fp)
     case JAVA_METHOD_PASS:
         indent += 4;
         indent_me(fp);
-        fprintf (fp, "public native int %s (", 
-                 java_name_mangle(CDATA0));
+
+        /* Generate private native declaration */
+        fprintf (fp, "private static native int %s0(", java_name_mangle(CDATA0));
+        emit_java_arg_declaration(this->deeper, fp);
+        fputs (");\n", fp);
+
+        /* Generate public Java method */
+        indent_me(fp);
+        fprintf (fp, "public final int %s(", java_name_mangle(CDATA0));
+        emit_java_arg_declaration(this->deeper, fp);
+        fputs (") {\n", fp);
+
+        indent += 4;
+        indent_me(fp);
+        fputs ("checkConnected();\n", fp);
+        indent_me(fp);
+        fprintf (fp, "return %s.%s0(", java_class, java_name_mangle(CDATA0));
+
         child = this->deeper;
+        current_java_parameter_number = 0;
+        while (child && hidden_from_java(child->deeper)) {
+            child = child->peer;
+        }
         while (child) {
-            node_vft_t *vftp = the_vft[child->type];
-            current_java_emitted_parameter = 0;
-            vftp->java_method_function(child, which, fp);
+            fputs(java_name_mangle((char *)(child->deeper->data[0])), fp);
             child = child->peer;
-            if (child && current_java_emitted_parameter)
+            if (child)
                 fputs (", ", fp);
         }
-        fprintf (fp, ");\n");
+
+        fputs (");\n", fp);
+        indent -= 4;
+        indent_me(fp);
+        fputs ("}\n\n", fp);
         indent -= 4;
         break;
 
     case JAVA_JNI_PASS:
         /* Generate function prototype */
-        fprintf (fp, "JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_%s_%s\n", 
+        fprintf (fp, "JNIEXPORT jint JNICALL Java_org_openvpp_vppjapi_%s_%s0\n", 
                  java_class, java_name_mangle(CDATA0));
 
-        fprintf (fp, "(JNIEnv * env, jobject obj");
+        fprintf (fp, "(JNIEnv * env, jclass clazz");
         current_java_parameter_need_comma_space = 1;
         child = this->deeper;
         save_child = child;
@@ -853,6 +883,20 @@ void node_define_generate (node_t *this, enum passid which, FILE *fp)
         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;
@@ -1009,6 +1053,9 @@ void node_scalar_generate (node_t *this, enum passid which, FILE *fp)
             }
         }
         break;
+    case PYTHON_PASS:
+        fprintf(fp, "'%s'),\n", CDATA0);
+        break;
 
     default:
         fprintf(stderr, "node_scalar_generate: unimp pass %d\n", which);
@@ -1113,6 +1160,9 @@ void node_vector_generate (node_t *this, enum passid which, FILE *fp)
         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);
@@ -1193,6 +1243,14 @@ void node_complex_generate (node_t *this, enum passid which, FILE *fp)
         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);
@@ -1744,14 +1802,14 @@ void add_msg_ids(YYSTYPE a1)
     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;
     }
@@ -1773,9 +1831,12 @@ void generate_java_top_boilerplate(FILE *fp)
     fprintf (fp, " */\n\n");
 
     fprintf (fp, "package org.openvpp.vppjapi;\n\n");
-    fprintf (fp, "import org.openvpp.vppjapi.vppConn;\n\n");
-    fprintf (fp, "public class %s extends vppConn {\n\n",
+    fprintf (fp, "import java.io.IOException;\n\n");
+    fprintf (fp, "public class %s extends vppConn {\n",
              java_class);
+    fprintf (fp, "    public %s(String clientName) throws IOException {\n", java_class);
+    fprintf (fp, "        super(clientName);\n");
+    fprintf (fp, "    }\n\n");
 }
 
 void generate_java_bottom_boilerplate(FILE *fp)
@@ -1962,6 +2023,23 @@ void generate_jni_bottom_boilerplate(FILE *fp)
     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) {
@@ -1994,4 +2072,7 @@ void generate(YYSTYPE a1)
         generate_jni_code(a1, jnifp);
         generate_jni_bottom_boilerplate(jnifp);
     }
+    if (pythonfp) {
+      generate_python(a1, pythonfp);
+    }
 }