From 8fda36120aaf7975cfa7e202d574ee5f4ddd475c Mon Sep 17 00:00:00 2001 From: richardyu-ms Date: Thu, 23 Feb 2023 14:05:05 +0000 Subject: [PATCH] [SAI-PTF] Convert generated enum code from ctypesgen into pythoon enum class why When ctypesgen generated the python code for c++ enum, the python cannot be logged by it enum name, we need to change it to enum class. the code like ```C++ /** * @brief SAI common API type */ typedef enum _sai_common_api_t { SAI_COMMON_API_CREATE = 0, SAI_COMMON_API_REMOVE = 1, SAI_COMMON_API_SET = 2, SAI_COMMON_API_GET = 3, SAI_COMMON_API_BULK_CREATE = 4, SAI_COMMON_API_BULK_REMOVE = 5, SAI_COMMON_API_BULK_SET = 6, SAI_COMMON_API_BULK_GET = 7, SAI_COMMON_API_MAX = 8, } sai_common_api_t; ``` original converted by ctypesgen ``` enum__sai_common_api_t = c_int# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_SET = 2# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_GET = 3# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_CREATE = 4# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_REMOVE = 5# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_SET = 6# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_GET = 7# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_MAX = 8# /usr/include/sai/saitypes.h: 183 sai_common_api_t = enum__sai_common_api_t# /usr/include/sai/saitypes.h: 183 enum__sai_object_type_t = c_int# /usr/include/sai/saitypes.h: 294 ``` new code ``` class sai_common_api(SAIEnum): SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_SET = 2# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_GET = 3# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_CREATE = 4# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_REMOVE = 5# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_SET = 6# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_BULK_GET = 7# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_MAX = 8# /usr/include/sai/saitypes.h: 183 SAI_COMMON_API_CREATE = sai_common_api.SAI_COMMON_API_CREATE SAI_COMMON_API_REMOVE = sai_common_api.SAI_COMMON_API_REMOVE SAI_COMMON_API_SET = sai_common_api.SAI_COMMON_API_SET SAI_COMMON_API_GET = sai_common_api.SAI_COMMON_API_GET SAI_COMMON_API_BULK_CREATE = sai_common_api.SAI_COMMON_API_BULK_CREATE SAI_COMMON_API_BULK_REMOVE = sai_common_api.SAI_COMMON_API_BULK_REMOVE SAI_COMMON_API_BULK_SET = sai_common_api.SAI_COMMON_API_BULK_SET SAI_COMMON_API_BULK_GET = sai_common_api.SAI_COMMON_API_BULK_GET SAI_COMMON_API_MAX = sai_common_api.SAI_COMMON_API_MAX ``` how Convert the python code after generated from ctypesgen verify pipeline local testing Signed-off-by: richardyu-ms --- meta/templates/sai_adapter_utils.tt | 3 +- test/saithriftv2/Makefile | 3 + test/saithriftv2/convert_header.py | 144 ++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 test/saithriftv2/convert_header.py diff --git a/meta/templates/sai_adapter_utils.tt b/meta/templates/sai_adapter_utils.tt index 119d92bff3..1589929d6f 100644 --- a/meta/templates/sai_adapter_utils.tt +++ b/meta/templates/sai_adapter_utils.tt @@ -10,6 +10,7 @@ from functools import wraps [%- BLOCK invocation_logger_imports %] import inspect import logging +from functools import wraps [% END -%] [%- ######################################################################## -%] @@ -180,7 +181,7 @@ def invocation_logger(func): SAI interface invocation logger. Use it to log all the invocated method in this sai_adapater. """ - + @wraps(func) def inner_logger(*args, **kwargs): args_name = inspect.getargspec(func)[0] diff --git a/test/saithriftv2/Makefile b/test/saithriftv2/Makefile index 358d0aadf6..0026426f34 100644 --- a/test/saithriftv2/Makefile +++ b/test/saithriftv2/Makefile @@ -83,6 +83,9 @@ $(PY_SOURCES): $(METADIR)sai.thrift $(SAI_PY_HEADERS): $(SAI_HEADERS) $(CTYPESGEN) --output-language=py32 -I/usr/include -I$(SAI_HEADER_DIR) -I../../experimental --include /usr/include/linux/limits.h $^ -o $@ + python3 convert_header.py -i $(SAI_PY_HEADERS) -o ./new_header.py + mv $(SAI_PY_HEADERS) ./sai_headers.py.bk + mv ./new_header.py $(SAI_PY_HEADERS) $(ODIR)/%.o: gen-cpp/%.cpp meta $(CXX) $(CPPFLAGS) -c $< -o $@ -I../../meta diff --git a/test/saithriftv2/convert_header.py b/test/saithriftv2/convert_header.py new file mode 100644 index 0000000000..b03bde8d3b --- /dev/null +++ b/test/saithriftv2/convert_header.py @@ -0,0 +1,144 @@ +import logging +import argparse + +""" +Convert the generated code in sai_header.py. +For the generated code from c++ enum, convert it to python enum class. + +the code like + ```C++ + /** + * @brief SAI common API type + */ + typedef enum _sai_common_api_t + { + SAI_COMMON_API_CREATE = 0, + SAI_COMMON_API_REMOVE = 1, + ... + } sai_common_api_t; + ``` + original converted by ctypesgen + ``` + enum__sai_common_api_t = c_int# /usr/include/sai/saitypes.h: 183 + + SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183 + + SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183 + ... + ``` + new code + ``` + class sai_common_api(SAIEnum): + + SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183 + + SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183 + ... + + SAI_COMMON_API_CREATE = sai_common_api.SAI_COMMON_API_CREATE + SAI_COMMON_API_REMOVE = sai_common_api.SAI_COMMON_API_REMOVE + ... + ``` + +""" + +def parse_param(): + ''' + Parse param. + ''' + parser = argparse.ArgumentParser( + description=""" + Convert python file after ctypesgen convert. + """ + ) + + parser.add_argument( + "-i", type=str, dest="input_file", + help="input file name", required=True) + parser.add_argument( + "-o", type=str, dest="output_file", + help="output file name", required=True) + return parser.parse_args() + +def import_and_enum_define(): + """ + import and add the enum class definitation. + """ + def_str = "import enum\r\nclass SAIEnum(enum.IntEnum):\r\n def __str__(self):\r\n return super().__str__().split(\".\")[1]\r\n" + return def_str + +def convert_enum_start_to_class(line): + """ + Convert the enum to class. + args: + line: input + """ + class_name = line.strip("enum__").split("_t = c_int", 1)[0] + return class_name + +def convert_file(input_file_name, output_file_name): + """ + Convert the input file to a output file. + + """ + input_file = open(input_file_name, 'r') + output_file = open(output_file_name, 'w') + enum_times = 0 + enum_items = [] + enum_start = False + class_name = None + + Lines = input_file.readlines() + for line in Lines: + if not enum_start and enum_times == 0 and "enum__sai_" in line and "= c_int" in line: + # first time hit a enum + # add import + output_file.write(import_and_enum_define()) + enum_times= enum_times + 1 + enum_start = True + enum_items = [] + output_file.write("\n") + class_name = convert_enum_start_to_class(line) + output_file.writelines("class {}(SAIEnum):\n".format(class_name)) + output_file.flush() + continue + elif not enum_start and enum_times > 0 and "enum__sai_" in line and "= c_int" in line: + enum_times= enum_times + 1 + enum_start = True + enum_items = [] + output_file.write("\n") + class_name = convert_enum_start_to_class(line) + output_file.writelines("class {}(SAIEnum):\n".format(class_name)) + output_file.flush() + continue + elif enum_start and " = enum__sai_" not in line and "SAI" in line: + line = line.split("\n", 1)[0] + enum_name = line.split(" =", 1)[0] + enum_items.append(enum_name) + output_file.write(" {}\n".format(line)) + output_file.flush() + continue + elif " = enum__sai_" in line: + enum_start = False + output_file.write("\n") + for item in enum_items: + output_file.write("{} = {}.{}".format(item, class_name, item)) + output_file.write("\n") + output_file.write("\n") + output_file.flush() + continue + else: + output_file.writelines(line) + + + output_file.flush() + input_file.close() + output_file.close() + + +if __name__ == "__main__": + ''' + For the generated code from c++ enum, convert it to python enum class. + ''' + args = parse_param() + convert_file(args.input_file, args.output_file)