--- a/mqtt/mqtt_client_gen.py Fri Sep 20 15:30:22 2024 +0200
+++ b/mqtt/mqtt_client_gen.py Wed Sep 25 11:10:33 2024 +0200
@@ -430,56 +430,84 @@
formatdict["retrieve"] += """
READ_VALUE({c_loc_name}, {C_type})""".format(**locals())
- def recurseJsonTypes(datatype, basetypes):
+ # collect all used type with their dependencies
+ basetypes=[]
+ arrays=set()
+ structures=set()
+ already_generated_types = set()
+
+ def recurseJsonTypes(datatype):
+ # append derivated type first so we can expect the list
+ # to be sorted with base types in last position
basetypes.append(datatype)
- # add derivated type first fo we can expect the list to be sorted
- # with base types in last position
infos = datatype_info_getter(datatype)
- for element in infos["elements"]:
- field_datatype = element["Type"]
- if field_datatype not in MQTT_IEC_types:
- recurseJsonTypes(field_datatype, basetypes)
-
- print(json_types)
-
- # collect all type dependencies
- basetypes=[] # use a list to keep them ordered
+ print(infos)
+ element_type = infos["type"]
+ if element_type == "Structure":
+ structures.add(datatype)
+ for element in infos["elements"]:
+ field_datatype = element["Type"]
+ if field_datatype not in MQTT_IEC_types:
+ recurseJsonTypes(field_datatype)
+ elif element_type == "Array":
+ arrays.add(datatype)
+ item_datatype = infos["base_type"]
+ if item_datatype not in MQTT_IEC_types:
+ recurseJsonTypes(item_datatype)
+ def typeCategory(iec_type):
+ if field_iec_type in arrays:
+ return "ARRAY"
+ elif field_iec_type in structures:
+ return "OBJECT"
+ return "SIMPLE"
+
for iec_type,_instances in json_types.items():
- recurseJsonTypes(iec_type, basetypes)
-
- done_types = set()
+ recurseJsonTypes(iec_type)
+
# go backard to get most derivated type definition last
# so that CPP can always find base type deinition before
for iec_type in reversed(basetypes):
# avoid repeating type definition
- if iec_type in done_types:
+ if iec_type in already_generated_types:
continue
- done_types.add(iec_type)
+ already_generated_types.add(iec_type)
C_type = iec_type.upper()
json_decl = "#define TYPE_" + C_type + "(_P, _A) \\\n"
infos = datatype_info_getter(iec_type)
- elements = infos["elements"]
- last = len(elements) - 1
- for idx, element in enumerate(elements):
- field_iec_type = element["Type"]
+ element_type = infos["type"]
+ if element_type == "Structure":
+ elements = infos["elements"]
+ last = len(elements) - 1
+ for idx, element in enumerate(elements):
+ field_iec_type = element["Type"]
+ if type(field_iec_type) == tuple and field_iec_type[0] == "array":
+ raise Exception("Inline arrays in structure are not supported. Please use a separate data type for array.")
+
+ field_C_type = field_iec_type.upper()
+ field_name = element["Name"]
+ field_C_name = field_name.upper()
+ decl_type = typeCategory(field_iec_type)
+
+ json_decl += (" _P##_" + decl_type + "(" +
+ field_C_type + ", " + field_C_name + ", " + field_name + ", _A)" +
+ ("\n\n" if idx == last else " _P##_separator \\\n"))
+
+ elif element_type == "Array":
+ dimensions = infos["dimensions"]
+ if len(dimensions) > 1:
+ raise Exception("Only 1 dimension arrays are supported")
+ count = int(dimensions[0][1]) - int(dimensions[0][0]) + 1
+ field_iec_type = infos["base_type"]
+ decl_type = typeCategory(field_iec_type)
field_C_type = field_iec_type.upper()
- field_name = element["Name"]
- field_C_name = field_name.upper()
- if field_iec_type in MQTT_IEC_types:
- decl_type = "SIMPLE"
- else:
- decl_type = "OBJECT"
-
- json_decl += " _P##_"+decl_type+"(" + field_C_type + ", " + field_C_name + ", " + field_name + ", _A)"
- if idx != last:
- json_decl += " _P##_separator \\"
- else:
- json_decl += "\n"
- json_decl += "\n"
-
+ last = count - 1
+ for idx in range(count):
+ json_decl += (" _P##_ARRAY_" + decl_type + "(" +
+ field_C_type + ", " + repr(idx) + " , _A)" +
+ ("\n\n" if idx == last else " _P##_separator \\\n"))
formatdict["json_decl"] += json_decl
--- a/mqtt/mqtt_template.c Fri Sep 20 15:30:22 2024 +0200
+++ b/mqtt/mqtt_template.c Wed Sep 25 11:10:33 2024 +0200
@@ -71,6 +71,9 @@
#define printf_fmt_SIMPLE(C_type, C_name, name, _A) #name " : " printf_fmt_##C_type
#define printf_fmt_OBJECT(C_type, C_name, name, _A) #name " : {{ " TYPE_##C_type(printf_fmt, _A) " }}"
+#define printf_fmt_ARRAY(C_type, C_name, name, _A) #name " : [ " TYPE_##C_type(printf_fmt, _A) " ]"
+#define printf_fmt_ARRAY_SIMPLE(C_type, index, _A) printf_fmt_##C_type
+#define printf_fmt_ARRAY_OBJECT(C_type, index, _A) "{{ " TYPE_##C_type(printf_fmt, _A) " }}"
#define scanf_fmt_BOOL "%B"
#define scanf_fmt_SINT "%hhd"
@@ -89,42 +92,51 @@
#define scanf_fmt_SIMPLE(C_type, C_name, name, _A) #name " : " scanf_fmt_##C_type
#define scanf_fmt_OBJECT(C_type, C_name, name, _A) #name " : {{ " TYPE_##C_type(scanf_fmt, _A) " }}"
-
-#define scanf_arg_BOOL(name, data_ptr) &data_ptr->name
-#define scanf_arg_SINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_USINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_INT(name, data_ptr) &data_ptr->name
-#define scanf_arg_UINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_DINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_UDINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_LINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_ULINT(name, data_ptr) &data_ptr->name
-#define scanf_arg_REAL(name, data_ptr) &data_ptr->name
-#define scanf_arg_LREAL(name, data_ptr) &data_ptr->name
-#define scanf_arg_STRING(name, data_ptr) scan_string, &data_ptr->name
+#define scanf_fmt_ARRAY(C_type, C_name, name, _A) #name " : [ " TYPE_##C_type(scanf_fmt, _A) " ]"
+#define scanf_fmt_ARRAY_SIMPLE(C_type, index, _A) scanf_fmt_##C_type
+#define scanf_fmt_ARRAY_OBJECT(C_type, index, _A) "{{ " TYPE_##C_type(scanf_fmt, _A) " }}"
+
+#define scanf_arg_BOOL(arg) arg
+#define scanf_arg_SINT(arg) arg
+#define scanf_arg_USINT(arg) arg
+#define scanf_arg_INT(arg) arg
+#define scanf_arg_UINT(arg) arg
+#define scanf_arg_DINT(arg) arg
+#define scanf_arg_UDINT(arg) arg
+#define scanf_arg_LINT(arg) arg
+#define scanf_arg_ULINT(arg) arg
+#define scanf_arg_REAL(arg) arg
+#define scanf_arg_LREAL(arg) arg
+#define scanf_arg_STRING(arg) scan_string, arg
#define scanf_args_separator ,
-#define scanf_args_SIMPLE(C_type, C_name, name, data_ptr) scanf_arg_##C_type(C_name, data_ptr)
+#define scanf_args_SIMPLE(C_type, C_name, name, data_ptr) scanf_arg_##C_type(&data_ptr->C_name)
#define scanf_args_OBJECT(C_type, C_name, name, data_ptr) TYPE_##C_type(scanf_args, (&data_ptr->C_name))
-
-#define printf_arg_BOOL(name, data_ptr) data_ptr->name
-#define printf_arg_SINT(name, data_ptr) data_ptr->name
-#define printf_arg_USINT(name, data_ptr) data_ptr->name
-#define printf_arg_INT(name, data_ptr) data_ptr->name
-#define printf_arg_UINT(name, data_ptr) data_ptr->name
-#define printf_arg_DINT(name, data_ptr) data_ptr->name
-#define printf_arg_UDINT(name, data_ptr) data_ptr->name
-#define printf_arg_LINT(name, data_ptr) data_ptr->name
-#define printf_arg_ULINT(name, data_ptr) data_ptr->name
-#define printf_arg_REAL(name, data_ptr) data_ptr->name
-#define printf_arg_LREAL(name, data_ptr) data_ptr->name
-#define printf_arg_STRING(name, data_ptr) data_ptr->name.len, data_ptr->name.body
+#define scanf_args_ARRAY(C_type, C_name, name, data_ptr) TYPE_##C_type(scanf_args, data_ptr->C_name.table)
+#define scanf_args_ARRAY_SIMPLE(C_type, index, data_ptr) scanf_arg_##C_type(&data_ptr[index])
+#define scanf_args_ARRAY_OBJECT(C_type, index, data_ptr) TYPE_##C_type(scanf_args, (&data_ptr[index]))
+
+#define printf_arg_BOOL(arg) arg
+#define printf_arg_SINT(arg) arg
+#define printf_arg_USINT(arg) arg
+#define printf_arg_INT(arg) arg
+#define printf_arg_UINT(arg) arg
+#define printf_arg_DINT(arg) arg
+#define printf_arg_UDINT(arg) arg
+#define printf_arg_LINT(arg) arg
+#define printf_arg_ULINT(arg) arg
+#define printf_arg_REAL(arg) arg
+#define printf_arg_LREAL(arg) arg
+#define printf_arg_STRING(arg) arg.len, arg.body
#define printf_args_separator ,
-#define printf_args_SIMPLE(C_type, C_name, name, data_ptr) printf_arg_##C_type(C_name, data_ptr)
+#define printf_args_SIMPLE(C_type, C_name, name, data_ptr) printf_arg_##C_type(data_ptr->C_name)
#define printf_args_OBJECT(C_type, C_name, name, data_ptr) TYPE_##C_type(printf_args, (&data_ptr->C_name))
+#define printf_args_ARRAY(C_type, C_name, name, data_ptr) TYPE_##C_type(printf_args, (&data_ptr->C_name.table))
+#define printf_args_ARRAY_SIMPLE(C_type, index, data_ptr) printf_arg_##C_type(data_ptr[index])
+#define printf_args_ARRAY_OBJECT(C_type, index, data_ptr) TYPE_##C_type(printf_args, (data_ptr[index]))
static void scan_string(const char *str, int len, void *user_data) {{
IEC_STRING *iecstr = (IEC_STRING*)user_data;