From 284471c236f3edce4e2ccab6e77ad0e4893e5d6c Mon Sep 17 00:00:00 2001 From: Mateusz Starzyk Date: Thu, 27 May 2021 12:42:32 +0200 Subject: [PATCH] Clarify python script's comments Signed-off-by: Mateusz Starzyk --- apply_MBEDTLS_PRIVATE.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/apply_MBEDTLS_PRIVATE.py b/apply_MBEDTLS_PRIVATE.py index 4160287f22..4d87384ff5 100644 --- a/apply_MBEDTLS_PRIVATE.py +++ b/apply_MBEDTLS_PRIVATE.py @@ -6,32 +6,41 @@ import os import xml.etree.ElementTree as ET +# Create dictionary with following structre +# files_to_visit = { +# "filepath1" : { "variable_name1": (1, 2, 40, 61), # line numbers +# "variable_name2": (60, 64), +# }, +# "filepath2" : { "variable_name1": (1, 2, 40, 61), # line numbers +# "variable_name2": (60, 64), +# }, ... +# } files_to_visit = {} +# find xml models for structs parsed by doxygen struct_files = glob.glob("apidoc/xml/structmbedtls*.xml") + glob.glob("apidoc/xml/structpsa*.xml") for struct_file in struct_files: + # get all variables from currently processed struct struct_file_tree = ET.parse(struct_file) all_struct_members_definitions = struct_file_tree.getroot().findall(".//memberdef[@kind='variable']") - # Create dictionary with following structre - # "filepath" : { "variable_name1": (1, 2, 40, 61), # line numbers - # "variable_name2": (60, 64), - # } for struct_member_def in all_struct_members_definitions: - # find file path for this variable + # get unique id by which this variable is referenced member_id = struct_member_def.attrib["id"] + # find file path for this variable's definition location = struct_member_def.find("location") file_path = location.attrib["file"] + # get variable name variable_name = struct_member_def.find("name").text - # if path not yet in dictionary, create empty record to initialize + # if file path is not yet in dictionary, create empty sub-dictionary to initialize if file_path not in files_to_visit: files_to_visit[file_path] = {} # if variable is not yet in this file's dictionary, create empty set to initialize if variable_name not in files_to_visit[file_path]: files_to_visit[file_path][variable_name] = set() - # add variable definition + # add variable's definition line number files_to_visit[file_path][variable_name].add(int(location.attrib["line"])) # check where the variable was referenced @@ -39,13 +48,13 @@ for struct_file in struct_files: for reference in references: refid = reference.attrib["refid"] # assuming that compound name is related to header's xml file - header_file = "apidoc/xml/" + reference.attrib["compoundref"] + ".xml" - header_file_tree = ET.parse(header_file) + header_file_xml = "apidoc/xml/" + reference.attrib["compoundref"] + ".xml" + header_file_tree = ET.parse(header_file_xml) # check if this reference is created by static inline function static_inline_function_definition = header_file_tree.getroot().find(f".//memberdef[@id='{refid}'][@kind='function'][@static='yes'][@inline='yes']") if static_inline_function_definition: static_inline_function_file_path = static_inline_function_definition.find("location").attrib["file"] - # if path not yet in dictionary, create empty record to initialize. + # if file path not yet in dictionary, create empty sub-dictionary to initialize. # This could happen if reference is inside header file which was not yet processed in search for variable definitions if static_inline_function_file_path not in files_to_visit: files_to_visit[static_inline_function_file_path] = {} @@ -55,26 +64,30 @@ for struct_file in struct_files: # function block scope function_lines_from = int(reference.attrib["startline"]) function_lines_to = int(reference.attrib["endline"]) - # find codelines referencing struct's variable + # find codelines referencing currently processed variable. This is using the code listing inside header's xml model. codelines_xml = header_file_tree.getroot().findall(f".//ref[@refid='{member_id}']/../..") # filter by function's scope codelines = [int(line.attrib["lineno"]) for line in codelines_xml if int(line.attrib["lineno"]) >= function_lines_from and int(line.attrib["lineno"]) <= function_lines_to] - # add variable reference + # add lines referencing currently processed variable files_to_visit[static_inline_function_file_path][variable_name].update(codelines) pp = pprint.PrettyPrinter(indent=4) pp.pprint(files_to_visit) for file_path, variables in files_to_visit.items(): + # FileInput redirects stdout to to 'file', so every print in this block will be put inside 'file' with fileinput.FileInput(file_path, inplace=True) as file: output_line_number = 1 + # compile regex matching the header's include guard. re_include_guard = re.compile(r"^#define.*{name}$".format(name=os.path.basename(file_path).replace('.','_').upper())) for line in file: insert_allow_private_include = False if re_include_guard.match(line): insert_allow_private_include = True + # every line in file is checked against variables and lines in which they occur for variable, var_lines in variables.items(): for var_line in var_lines: + # wrap variable with MBEDTLS_PRIVATE(...) macro if output_line_number == var_line: line = re.sub(r"(^.*?\W+)({var})(\W+.*$)".format(var=variable), r"\1MBEDTLS_PRIVATE(\2)\3", line) output_line_number += 1