From 798efe2048943a290ba778cf25ab1d20852a8b7c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 21 Jun 2021 12:47:03 +0200 Subject: [PATCH] made some more code generic --- events/event_parser.py | 42 +++++++++---- parserbase/parser.py | 57 +++++++++++++++++- returnvalues/returnvalues_parser.py | 93 ++++++++--------------------- 3 files changed, 113 insertions(+), 79 deletions(-) diff --git a/events/event_parser.py b/events/event_parser.py index fc06047..b1ca9a1 100644 --- a/events/event_parser.py +++ b/events/event_parser.py @@ -1,4 +1,5 @@ import re +from typing import List from fsfwgen.parserbase.parser import FileParser @@ -96,21 +97,28 @@ class EventParser(FileParser): file_name=file_name ) - def __handle_event_match(self, event_match, macro_api_match: bool, moving_window: list, file_name: str): - event_full_match = False + def __handle_event_match( + self, event_match, macro_api_match: bool, moving_window: list, file_name: str + ): if ";" in event_match.group(0): event_full_match = self.__handle_one_line_event_match( macro_api_match=macro_api_match, moving_window=moving_window ) + else: + event_full_match = self.__build_multi_line_event_string( + first_line=event_match.group(0), moving_window=moving_window + ) # Description will be parsed separately later description = " " if event_full_match: name = event_match.group(EVENT_NAME_IDX) if macro_api_match: - full_id = (self.my_id * 100) + self.return_number_from_string(event_full_match.group(2)) + full_id = (self.my_id * 100) + self.return_number_from_string( + event_full_match.group(2)) severity = event_full_match.group(3) else: - full_id = (self.my_id * 100) + self.return_number_from_string(event_full_match.group(3)) + full_id = (self.my_id * 100) + self.return_number_from_string( + event_full_match.group(3)) severity = event_full_match.group(4) self.mib_table.update({full_id: (name, severity, description, file_name)}) self.count = self.count + 1 @@ -128,6 +136,13 @@ class EventParser(FileParser): event_full_match = re.search(regex_string, moving_window[self.moving_window_center_idx]) return event_full_match + def __build_multi_line_event_string( + self, first_line: str, moving_window: List[str] + ) -> str: + return self._build_multi_line_string_generic( + first_line=first_line, moving_window=moving_window + ) + def _post_parsing_operation(self): pass @@ -208,14 +223,17 @@ def export_to_file(filename: str, event_list: list, file_separator: str): event_value = entry[1] file.write( str(event_id) + file_separator + event_value[EVENT_ENTRY_NAME_IDX] + file_separator + - event_value[EVENT_ENTRY_SEVERITY_IDX] + file_separator + event_value[EVENT_ENTRY_INFO_IDX] + - file_separator + event_value[EVENT_SOURCE_FILE_IDX] + '\n' + event_value[EVENT_ENTRY_SEVERITY_IDX] + file_separator + + event_value[EVENT_ENTRY_INFO_IDX] + file_separator + event_value[EVENT_SOURCE_FILE_IDX] + + '\n' ) file.close() return -def write_translation_source_file(event_list: list, date_string: str, filename: str = "translateEvents.cpp"): +def write_translation_source_file( + event_list: list, date_string: str, filename: str = "translateEvents.cpp" +): outputfile = open(filename, "w") definitions = "" @@ -224,11 +242,13 @@ def write_translation_source_file(event_list: list, date_string: str, filename: event_id = entry[0] event_value = entry[1] definitions += \ - f"const char *{event_value[EVENT_ENTRY_NAME_IDX]}_STRING = \"{event_value[EVENT_ENTRY_NAME_IDX]}\";\n" + f"const char *{event_value[EVENT_ENTRY_NAME_IDX]}_STRING " \ + f"= \"{event_value[EVENT_ENTRY_NAME_IDX]}\";\n" function += f"\tcase({event_id}):\n\t\treturn {event_value[EVENT_ENTRY_NAME_IDX]}_STRING;\n" function += '\tdefault:\n\t\treturn "UNKNOWN_EVENT";\n' outputfile.write( - f"/**\n * @brief Auto-generated event translation file. Contains {len(event_list)} translations.\n" + f"/**\n * @brief Auto-generated event translation file. " + f"Contains {len(event_list)} translations.\n" f" * @details\n" f" * Generated on: {date_string}\n */\n" ) @@ -258,8 +278,8 @@ def handle_csv_export(file_name: str, event_list: list, file_separator: str): def handle_cpp_export( - event_list: list, date_string: str, file_name: str = "translateEvents.cpp", generate_header: bool = True, - header_file_name: str = "translateEvents.h" + event_list: list, date_string: str, file_name: str = "translateEvents.cpp", + generate_header: bool = True, header_file_name: str = "translateEvents.h" ): print("EventParser: Generating translation cpp file.") write_translation_source_file(event_list=event_list, date_string=date_string, filename=file_name) diff --git a/parserbase/parser.py b/parserbase/parser.py index 4641a4b..35ae89a 100644 --- a/parserbase/parser.py +++ b/parserbase/parser.py @@ -12,8 +12,9 @@ Child classes fill out the MIB table (self.mib_table) @date 14.11.2019 """ import enum +import re from abc import abstractmethod -from typing import Dict +from typing import Dict, List class FileParserModes(enum.Enum): @@ -47,6 +48,7 @@ class FileParser: self.__debug_moving_window = False self.__debug_moving_window_filename = "" + self._moving_window_center_idx = 3 self._verbose_level = 1 @@ -195,3 +197,56 @@ class FileParser: file = open(file_name, 'r', encoding='cp1252') all_lines = file.readlines() return all_lines + + def _build_multi_line_string_generic( + self, first_line: str, moving_window: List[str] + ) -> str: + all_lines = first_line.rstrip() + end_found = False + current_idx = self._moving_window_center_idx + while not end_found and current_idx < len(moving_window) - 1: + current_idx += 1 + string_to_add = moving_window[current_idx].lstrip() + if ";" in moving_window[current_idx]: + all_lines += string_to_add + break + else: + string_to_add.rstrip() + all_lines += string_to_add + return all_lines + + def _search_for_descrip_string_generic( + self, moving_window: List[str], break_pattern: str + ) -> str: + current_idx = self._moving_window_center_idx - 1 + # Look at the line above first + descrip_match = re.search( + r"\[EXPORT][\s]*:[\s]*\[COMMENT]", moving_window[current_idx] + ) + if not descrip_match: + while current_idx > 0: + current_idx -= 1 + if re.search( + break_pattern, moving_window[current_idx] + ): + break + descrip_match = re.search( + r"\[EXPORT][\s]*:[\s]*\[COMMENT]", moving_window[current_idx] + ) + if descrip_match: + break + if descrip_match: + current_build_idx = current_idx + descrip_string = "" + while current_build_idx < self._moving_window_center_idx: + string_to_add = moving_window[current_build_idx].lstrip() + string_to_add = string_to_add.lstrip("//!<>") + string_to_add = string_to_add.rstrip() + descrip_string += string_to_add + current_build_idx += 1 + else: + return "" + resulting_description = re.search( + r"\[EXPORT][\s]*:[\s]*\[COMMENT](.*)", descrip_string + ) + return resulting_description.group(1) diff --git a/returnvalues/returnvalues_parser.py b/returnvalues/returnvalues_parser.py index 485b325..4a1eefe 100644 --- a/returnvalues/returnvalues_parser.py +++ b/returnvalues/returnvalues_parser.py @@ -141,7 +141,6 @@ class ReturnValueParser(FileParser): self.count = 0 # Stores last three lines self.last_lines = ["", "", ""] - self.moving_window_center_idx = 3 self.current_interface_id_entries = { "Name": "", "ID": 0, @@ -153,17 +152,8 @@ class ReturnValueParser(FileParser): 'RETURN_FAILED', 'HasReturnvaluesIF.h', 'HasReturnvaluesIF')}) - def set_moving_window_mode(self, moving_window_size: int): - """ - Set moving window parsing mode - :param moving_window_size: - :return: - """ - super().set_moving_window_mode(DEFAULT_MOVING_WINDOWS_SIZE) - def _handle_file_parsing(self, file_name: str, *args, **kwargs): - """ - Former way to parse returnvalues. Not recommended anymore. + """Former way to parse returnvalues. Not recommended anymore. :param file_name: :param args: :param kwargs: @@ -177,18 +167,22 @@ class ReturnValueParser(FileParser): for line in all_lines: self.__handle_line_reading(line, file_name, print_truncated_entries) - def _handle_file_parsing_moving_window(self, file_name: str, current_line: int, - moving_window_size: int, moving_window: list, *args, - **kwargs): + def _handle_file_parsing_moving_window( + self, file_name: str, current_line: int, moving_window_size: int, moving_window: list, + *args, **kwargs + ): + """Parse for returnvalues using a moving window""" interface_id_match = re.search( - rf"{CLASS_ID_NAMESPACE}::([a-zA-Z_0-9]*)", moving_window[self.moving_window_center_idx] + rf"{CLASS_ID_NAMESPACE}::([a-zA-Z_0-9]*)", moving_window[self._moving_window_center_idx] ) if interface_id_match: - self.__handle_interfaceid_match(interface_id_match=interface_id_match, file_name=file_name) + self.__handle_interfaceid_match( + interface_id_match=interface_id_match, file_name=file_name + ) returnvalue_match = re.search( r"^[\s]*static const(?:expr)?[\s]*ReturnValue_t[\s]*([\w]*)[\s]*=[\s]*((?!;).*$)", - moving_window[self.moving_window_center_idx], re.DOTALL + moving_window[self._moving_window_center_idx], re.DOTALL ) full_returnvalue_string = "" if returnvalue_match: @@ -196,10 +190,12 @@ class ReturnValueParser(FileParser): full_returnvalue_string = returnvalue_match.group(0) else: full_returnvalue_string = self.__build_multi_line_returnvalue_string( - moving_window=moving_window, first_line=moving_window[self.moving_window_center_idx] + moving_window=moving_window, + first_line=moving_window[self._moving_window_center_idx] ) returnvalue_match = re.search( - r"^[\s]*static const(?:expr)? ReturnValue_t[\s]*([\w] *)[\s]*=[\s]*.*::[\w]*\(([\w]*),[\s]*([\d]*)\)", + r"^[\s]*static const(?:expr)? ReturnValue_t[\s]*([\w] *)[\s]*" + r"=[\s]*.*::[\w]*\(([\w]*),[\s]*([\d]*)\)", full_returnvalue_string ) if not returnvalue_match: @@ -211,59 +207,21 @@ class ReturnValueParser(FileParser): if returnvalue_match: description = self.__search_for_descrip_string(moving_window=moving_window) self.__handle_returnvalue_match( - name_match=returnvalue_match.group(1), file_name=file_name, number_match=returnvalue_match.group(2), - description=description + name_match=returnvalue_match.group(1), file_name=file_name, + number_match=returnvalue_match.group(2), description=description ) - pass def __build_multi_line_returnvalue_string( self, first_line: str, moving_window: List[str] ) -> str: - all_lines = first_line.rstrip() - end_found = False - current_idx = self.moving_window_center_idx - while not end_found and current_idx < len(moving_window) - 1: - current_idx += 1 - string_to_add = moving_window[current_idx].lstrip() - if ";" in moving_window[current_idx]: - all_lines += string_to_add - break - else: - string_to_add.rstrip() - all_lines += string_to_add - return all_lines + return self._build_multi_line_string_generic( + first_line=first_line, moving_window=moving_window + ) def __search_for_descrip_string(self, moving_window: List[str]) -> str: - current_idx = self.moving_window_center_idx - 1 - # Look at the line above first - descrip_match = re.search( - r"\[EXPORT\][\s]*:[\s]*\[COMMENT\]", moving_window[current_idx] + return self._search_for_descrip_string_generic( + moving_window=moving_window, break_pattern=r"^[\s]*static const(?:expr)? ReturnValue_t" ) - if not descrip_match: - while current_idx > 0: - current_idx -= 1 - if re.search(r"^[\s]*static const(?:expr)? ReturnValue_t", moving_window[current_idx]): - break - descrip_match = re.search( - r"\[EXPORT\][\s]*:[\s]*\[COMMENT\]", moving_window[current_idx] - ) - if descrip_match: - break - if descrip_match: - current_build_idx = current_idx - descrip_string = "" - while current_build_idx < self.moving_window_center_idx: - string_to_add = moving_window[current_build_idx].lstrip() - string_to_add = string_to_add.lstrip("//!<>") - string_to_add = string_to_add.rstrip() - descrip_string += string_to_add - current_build_idx += 1 - else: - return "" - resulting_description = re.search( - r"\[EXPORT\][\s]*:[\s]*\[COMMENT\](.*)", descrip_string - ) - return resulting_description.group(1) def __handle_line_reading(self, line, file_name, print_truncated_entries: bool): newline = line @@ -327,9 +285,10 @@ class ReturnValueParser(FileParser): def export_to_file(filename: str, list_of_entries: dict, file_separator: str): file = open(filename, "w") for entry in list_of_entries.items(): - file.write(hex(entry[0]) + file_separator + entry[1][0] + file_separator + entry[1][1] + - file_separator + entry[1][2] + file_separator - + entry[1][3] + file_separator + entry[1][4] + '\n') + file.write( + hex(entry[0]) + file_separator + entry[1][0] + file_separator + entry[1][1] + + file_separator + entry[1][2] + file_separator + entry[1][3] + file_separator + entry[1][4] + '\n' + ) file.close() def build_checked_string(self, first_part, second_part, max_string_len: int,