--- 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 + 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)
+ 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": + 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: + elif field_iec_type in structures: - # collect all type dependencies
- basetypes=[] # use a list to keep them ordered
for iec_type,_instances in json_types.items():
- recurseJsonTypes(iec_type, basetypes)
+ 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: - 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:
- json_decl += " _P##_"+decl_type+"(" + field_C_type + ", " + field_C_name + ", " + field_name + ", _A)"
- json_decl += " _P##_separator \\"
+ 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_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(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_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 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(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 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;