diff --git a/test/saithriftv2/Makefile b/test/saithriftv2/Makefile index 358d0aadf6..0409da0b16 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 + rm $(SAI_PY_HEADERS) + 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)