tests: upgrade python packages
[vpp.git] / src / vpp-api / vapi / vapi_c_gen.py
index 2978ebd..9d1efb5 100755 (executable)
@@ -23,7 +23,7 @@ class CField(Field):
         return "vapi_type_%s" % self.name
 
     def get_c_def(self):
-        if self.type.get_c_name() == "vl_api_string_t":
+        if self.type.get_c_name() == "string":
             if self.len:
                 return "u8 %s[%d];" % (self.name, self.len)
             else:
@@ -85,12 +85,15 @@ class CField(Field):
     def needs_byte_swap(self):
         return self.type.needs_byte_swap()
 
-    def get_vla_field_length_name(self, path):
+    def get_vla_parameter_name(self, path):
         return "%s_%s_array_size" % ("_".join(path), self.name)
 
+    def get_vla_field_name(self, path):
+        return ".".join(path + [self.nelem_field.name])
+
     def get_alloc_vla_param_names(self, path):
         if self.is_vla():
-            result = [self.get_vla_field_length_name(path)]
+            result = [self.get_vla_parameter_name(path)]
         else:
             result = []
         if self.type.has_vla():
@@ -98,20 +101,24 @@ class CField(Field):
             result.extend(t)
         return result
 
-    def get_vla_calc_size_code(self, prefix, path):
+    def get_vla_calc_size_code(self, prefix, path, is_alloc):
         if self.is_vla():
             result = [
                 "sizeof(%s.%s[0]) * %s"
                 % (
                     ".".join([prefix] + path),
                     self.name,
-                    self.get_vla_field_length_name(path),
+                    (
+                        self.get_vla_parameter_name(path)
+                        if is_alloc
+                        else "%s.%s" % (prefix, self.get_vla_field_name(path))
+                    ),
                 )
             ]
         else:
             result = []
         if self.type.has_vla():
-            t = self.type.get_vla_calc_size_code(prefix, path + [self.name])
+            t = self.type.get_vla_calc_size_code(prefix, path + [self.name], is_alloc)
             result.extend(t)
         return result
 
@@ -123,7 +130,7 @@ class CField(Field):
                 % (
                     ".".join([prefix] + path),
                     self.nelem_field.name,
-                    self.get_vla_field_length_name(path),
+                    self.get_vla_parameter_name(path),
                 )
             )
         if self.type.has_vla():
@@ -173,17 +180,16 @@ class CStruct(Struct):
             for x in f.get_alloc_vla_param_names(path)
         ]
 
-    def get_vla_calc_size_code(self, prefix, path):
+    def get_vla_calc_size_code(self, prefix, path, is_alloc):
         return [
             x
             for f in self.fields
             if f.has_vla()
-            for x in f.get_vla_calc_size_code(prefix, path)
+            for x in f.get_vla_calc_size_code(prefix, path, is_alloc)
         ]
 
 
 class CSimpleType(SimpleType):
-
     swap_to_be_dict = {
         "i16": "htobe16",
         "u16": "htobe16",
@@ -289,6 +295,8 @@ class CUnion(Union):
 
 class CStructType(StructType, CStruct):
     def get_c_name(self):
+        if self.name == "vl_api_string_t":
+            return "vl_api_string_t"
         return "vapi_type_%s" % self.name
 
     def get_swap_to_be_func_name(self):
@@ -399,7 +407,9 @@ class CMessage(Message):
                             " + %s" % x
                             for f in self.fields
                             if f.has_vla()
-                            for x in f.get_vla_calc_size_code("msg->payload", [])
+                            for x in f.get_vla_calc_size_code(
+                                "msg->payload", [], is_alloc=True
+                            )
                         ]
                     ),
                 ),
@@ -443,10 +453,12 @@ class CMessage(Message):
                 "  return sizeof(*msg)%s;"
                 % "".join(
                     [
-                        "+ msg->payload.%s * sizeof(msg->payload.%s[0])"
-                        % (f.nelem_field.name, f.name)
+                        " + %s" % x
                         for f in self.fields
-                        if f.nelem_field is not None
+                        if f.has_vla()
+                        for x in f.get_vla_calc_size_code(
+                            "msg->payload", [], is_alloc=False
+                        )
                     ]
                 ),
                 "}",
@@ -478,7 +490,7 @@ class CMessage(Message):
                 {{
                   VAPI_ERR("Truncated '{self.name}' msg received, received %lu"
                     "bytes, expected %lu bytes.", buf_size,
-                    sizeof({self.get_calc_msg_size_func_name()}));
+                    {self.get_calc_msg_size_func_name()}(msg));
                   return -1;
                 }}
               return 0;
@@ -583,12 +595,16 @@ class CMessage(Message):
                     '  VAPI_DBG("Swapping `%s\'@%%p to big endian", msg);'
                     % self.get_c_name()
                 ),
-                "  %s(&msg->header);" % self.header.get_swap_to_be_func_name()
-                if self.header is not None
-                else "",
-                "  %s(&msg->payload);" % self.get_swap_payload_to_be_func_name()
-                if self.has_payload()
-                else "",
+                (
+                    "  %s(&msg->header);" % self.header.get_swap_to_be_func_name()
+                    if self.header is not None
+                    else ""
+                ),
+                (
+                    "  %s(&msg->payload);" % self.get_swap_payload_to_be_func_name()
+                    if self.has_payload()
+                    else ""
+                ),
                 "}",
             ]
         )
@@ -602,12 +618,16 @@ class CMessage(Message):
                     '  VAPI_DBG("Swapping `%s\'@%%p to host byte order", msg);'
                     % self.get_c_name()
                 ),
-                "  %s(&msg->header);" % self.header.get_swap_to_host_func_name()
-                if self.header is not None
-                else "",
-                "  %s(&msg->payload);" % self.get_swap_payload_to_host_func_name()
-                if self.has_payload()
-                else "",
+                (
+                    "  %s(&msg->header);" % self.header.get_swap_to_host_func_name()
+                    if self.header is not None
+                    else ""
+                ),
+                (
+                    "  %s(&msg->payload);" % self.get_swap_payload_to_host_func_name()
+                    if self.has_payload()
+                    else ""
+                ),
                 "}",
             ]
         )
@@ -616,45 +636,66 @@ class CMessage(Message):
         return "vapi_%s" % self.name
 
     def get_op_func_decl(self):
-        if self.reply.has_payload():
-            return "vapi_error_e %s(%s)" % (
-                self.get_op_func_name(),
-                ",\n  ".join(
-                    [
-                        "struct vapi_ctx_s *ctx",
-                        "%s *msg" % self.get_c_name(),
-                        "vapi_error_e (*callback)(struct vapi_ctx_s *ctx",
-                        "                         void *callback_ctx",
-                        "                         vapi_error_e rv",
-                        "                         bool is_last",
-                        "                         %s *reply)"
-                        % self.reply.get_payload_struct_name(),
-                        "void *callback_ctx",
-                    ]
-                ),
-            )
-        else:
-            return "vapi_error_e %s(%s)" % (
-                self.get_op_func_name(),
-                ",\n  ".join(
-                    [
-                        "struct vapi_ctx_s *ctx",
-                        "%s *msg" % self.get_c_name(),
-                        "vapi_error_e (*callback)(struct vapi_ctx_s *ctx",
-                        "                         void *callback_ctx",
-                        "                         vapi_error_e rv",
-                        "                         bool is_last)",
-                        "void *callback_ctx",
-                    ]
-                ),
-            )
+        stream_param_lines = []
+        if self.has_stream_msg:
+            stream_param_lines = [
+                "vapi_error_e (*details_callback)(struct vapi_ctx_s *ctx",
+                "                                 void *callback_ctx",
+                "                                 vapi_error_e rv",
+                "                                 bool is_last",
+                "                                 %s *details)"
+                % self.stream_msg.get_payload_struct_name(),
+                "void *details_callback_ctx",
+            ]
+
+        return "vapi_error_e %s(%s)" % (
+            self.get_op_func_name(),
+            ",\n  ".join(
+                [
+                    "struct vapi_ctx_s *ctx",
+                    "%s *msg" % self.get_c_name(),
+                    "vapi_error_e (*reply_callback)(struct vapi_ctx_s *ctx",
+                    "                               void *callback_ctx",
+                    "                               vapi_error_e rv",
+                    "                               bool is_last",
+                    "                               %s *reply)"
+                    % self.reply.get_payload_struct_name(),
+                ]
+                + [
+                    "void *reply_callback_ctx",
+                ]
+                + stream_param_lines
+            ),
+        )
 
     def get_op_func_def(self):
+        param_check_lines = ["  if (!msg || !reply_callback) {"]
+        store_request_lines = [
+            "    vapi_store_request(ctx, req_context, %s, %s, "
+            % (
+                self.reply.get_msg_id_name(),
+                "VAPI_REQUEST_DUMP" if self.reply_is_stream else "VAPI_REQUEST_REG",
+            ),
+            "                       (vapi_cb_t)reply_callback, reply_callback_ctx);",
+        ]
+        if self.has_stream_msg:
+            param_check_lines = [
+                "  if (!msg || !reply_callback || !details_callback) {"
+            ]
+            store_request_lines = [
+                f"    vapi_store_request(ctx, req_context, {self.stream_msg.get_msg_id_name()}, VAPI_REQUEST_STREAM, ",
+                "                       (vapi_cb_t)details_callback, details_callback_ctx);",
+                f"    vapi_store_request(ctx, req_context, {self.reply.get_msg_id_name()}, VAPI_REQUEST_REG, ",
+                "                       (vapi_cb_t)reply_callback, reply_callback_ctx);",
+            ]
+
         return "\n".join(
             [
                 "%s" % self.get_op_func_decl(),
                 "{",
-                "  if (!msg || !callback) {",
+            ]
+            + param_check_lines
+            + [
                 "    return VAPI_EINVAL;",
                 "  }",
                 "  if (vapi_is_nonblocking(ctx) && vapi_requests_full(ctx)) {",
@@ -670,14 +711,12 @@ class CMessage(Message):
                 (
                     "  if (VAPI_OK == (rv = vapi_send_with_control_ping "
                     "(ctx, msg, req_context))) {"
-                    if self.reply_is_stream
+                    if (self.reply_is_stream and not self.has_stream_msg)
                     else "  if (VAPI_OK == (rv = vapi_send (ctx, msg))) {"
                 ),
-                (
-                    "    vapi_store_request(ctx, req_context, %s, "
-                    "(vapi_cb_t)callback, callback_ctx);"
-                    % ("true" if self.reply_is_stream else "false")
-                ),
+            ]
+            + store_request_lines
+            + [
                 "    if (VAPI_OK != vapi_producer_unlock (ctx)) {",
                 "      abort (); /* this really shouldn't happen */",
                 "    }",
@@ -762,12 +801,16 @@ class CMessage(Message):
                 "    name_with_crc,",
                 "    sizeof(name_with_crc) - 1,",
                 "    true," if has_context else "    false,",
-                "    offsetof(%s, context)," % self.header.get_c_name()
-                if has_context
-                else "    0,",
-                ("    offsetof(%s, payload)," % self.get_c_name())
-                if self.has_payload()
-                else "    VAPI_INVALID_MSG_ID,",
+                (
+                    "    offsetof(%s, context)," % self.header.get_c_name()
+                    if has_context
+                    else "    0,"
+                ),
+                (
+                    ("    offsetof(%s, payload)," % self.get_c_name())
+                    if self.has_payload()
+                    else "    VAPI_INVALID_MSG_ID,"
+                ),
                 "    (verify_msg_size_fn_t)%s," % self.get_verify_msg_size_func_name(),
                 "    (generic_swap_fn_t)%s," % self.get_swap_to_be_func_name(),
                 "    (generic_swap_fn_t)%s," % self.get_swap_to_host_func_name(),
@@ -793,6 +836,8 @@ def emit_definition(parser, json_file, emitted, o):
             emit_definition(parser, json_file, emitted, x)
     if hasattr(o, "reply"):
         emit_definition(parser, json_file, emitted, o.reply)
+    if hasattr(o, "stream_msg"):
+        emit_definition(parser, json_file, emitted, o.stream_msg)
     if hasattr(o, "get_c_def"):
         if (
             o not in parser.enums_by_json[json_file]
@@ -821,14 +866,14 @@ def emit_definition(parser, json_file, emitted, o):
             print("%s%s" % (function_attrs, o.get_calc_msg_size_func_def()))
             print("")
             print("%s%s" % (function_attrs, o.get_verify_msg_size_func_def()))
-            if not o.is_reply and not o.is_event:
+            if not o.is_reply and not o.is_event and not o.is_stream:
                 print("")
                 print("%s%s" % (function_attrs, o.get_alloc_func_def()))
                 print("")
                 print("%s%s" % (function_attrs, o.get_op_func_def()))
             print("")
             print("%s" % o.get_c_constructor())
-            if o.is_reply or o.is_event:
+            if (o.is_reply or o.is_event) and not o.is_stream:
                 print("")
                 print("%s%s;" % (function_attrs, o.get_event_cb_func_def()))
         elif hasattr(o, "get_swap_to_be_func_def"):
@@ -865,6 +910,20 @@ def gen_json_unified_header(parser, logger, j, io, name):
     print("#ifdef __cplusplus")
     print('extern "C" {')
     print("#endif")
+
+    print("#ifndef __vl_api_string_swap_fns_defined__")
+    print("#define __vl_api_string_swap_fns_defined__")
+    print("")
+    print("#include <vlibapi/api_types.h>")
+    print("")
+    function_attrs = "static inline "
+    o = parser.types["vl_api_string_t"]
+    print("%s%s" % (function_attrs, o.get_swap_to_be_func_def()))
+    print("")
+    print("%s%s" % (function_attrs, o.get_swap_to_host_func_def()))
+    print("")
+    print("#endif //__vl_api_string_swap_fns_defined__")
+
     if name == "memclnt.api.vapi.h":
         print("")
         print(