several bugfixes and improvements
This commit is contained in:
parent
8e805d2408
commit
16280cc1df
@ -1,37 +1,37 @@
|
||||
"""
|
||||
@file file_list_parser.py
|
||||
@brief Generic File Parser class
|
||||
@details
|
||||
"""Generic File Parser class
|
||||
Used by parse header files. Implemented as class in case header parser becomes more complex
|
||||
@author R. Mueller
|
||||
@date 22.11.2019
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
from typing import Union
|
||||
|
||||
from fsfwgen.core import get_console_logger
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class FileListParser:
|
||||
"""
|
||||
Generic header parser which takes a directory name or directory name list
|
||||
"""Generic header parser which takes a directory name or directory name list
|
||||
and parses all included header files recursively.
|
||||
TODO: Filter functionality for each directory to filter out files or folders
|
||||
"""
|
||||
def __init__(self, directory_list_or_name: Union[str, list]):
|
||||
self.directory_list = []
|
||||
if isinstance(directory_list_or_name, str):
|
||||
self.directory_list = [directory_list_or_name]
|
||||
self.directory_list.append(directory_list_or_name)
|
||||
elif isinstance(directory_list_or_name, list):
|
||||
self.directory_list = directory_list_or_name
|
||||
self.directory_list.extend(directory_list_or_name)
|
||||
else:
|
||||
print("Header Parser: Passed directory list is not a header name or list of "
|
||||
"header names")
|
||||
LOGGER.warning(
|
||||
"Header Parser: Passed directory list is not a header name or list of header names"
|
||||
)
|
||||
self.header_files = []
|
||||
|
||||
def parse_header_files(self, search_recursively: bool = False,
|
||||
printout_string: str = "Parsing header files: ",
|
||||
print_current_dir: bool = False):
|
||||
"""
|
||||
This function is called to get a list of header files
|
||||
"""This function is called to get a list of header files
|
||||
:param search_recursively:
|
||||
:param printout_string:
|
||||
:param print_current_dir:
|
||||
|
@ -17,6 +17,12 @@ from abc import abstractmethod
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class VerbosityLevels(enum.Enum):
|
||||
REDUCED = 0,
|
||||
REGULAR = 1,
|
||||
DEBUG = 2
|
||||
|
||||
|
||||
class FileParserModes(enum.Enum):
|
||||
REGULAR = enum.auto(),
|
||||
MOVING_WINDOW = enum.auto()
|
||||
@ -72,6 +78,9 @@ class FileParser:
|
||||
def set_verbosity(self, verbose_level: int):
|
||||
self._verbose_level = verbose_level
|
||||
|
||||
def get_verbosity(self):
|
||||
return self._verbose_level
|
||||
|
||||
def enable_moving_window_debugging(self, file_name: str):
|
||||
self.__debug_moving_window = True
|
||||
self.__debug_moving_window_filename = file_name
|
||||
@ -201,6 +210,8 @@ class FileParser:
|
||||
def _build_multi_line_string_generic(
|
||||
self, first_line: str, moving_window: List[str]
|
||||
) -> str:
|
||||
"""This function transforms a multi line match into a one line match by searching for the
|
||||
semicolon at the string end"""
|
||||
all_lines = first_line.rstrip()
|
||||
end_found = False
|
||||
current_idx = self._moving_window_center_idx
|
||||
|
@ -2,19 +2,21 @@ import re
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
|
||||
from fsfwgen.parserbase.parser import FileParser
|
||||
from fsfwgen.parserbase.parser import FileParser, VerbosityLevels
|
||||
from fsfwgen.utility.printer import PrettyPrinter
|
||||
from fsfwgen.core import get_console_logger
|
||||
|
||||
LOGGER = get_console_logger()
|
||||
|
||||
# Intermediate solution
|
||||
MAX_STRING_LEN = 80
|
||||
|
||||
PRINT_TRUNCATED_ENTRIES = False
|
||||
DEBUG_INTERFACE_ID_COMPARISON = False
|
||||
DEBUG_FOR_FILE_NAME = False
|
||||
|
||||
DEBUG_FILE_NAME = "RingBufferAnalyzer"
|
||||
CLASS_ID_NAMESPACE = "CLASS_ID"
|
||||
DEFAULT_MOVING_WINDOWS_SIZE = 7
|
||||
INVALID_IF_ID = -1
|
||||
|
||||
|
||||
class InterfaceParser(FileParser):
|
||||
@ -26,6 +28,10 @@ class InterfaceParser(FileParser):
|
||||
self.file_name_table = []
|
||||
self.start_name_list = []
|
||||
self.end_name_list = []
|
||||
self._debug_mode = False
|
||||
|
||||
def enable_debug_mode(self, enable: bool):
|
||||
self._debug_mode = enable
|
||||
|
||||
def _handle_file_parsing_moving_window(
|
||||
self, file_name: str, current_line: int, moving_window_size: int, moving_window: list,
|
||||
@ -182,7 +188,7 @@ class ReturnValueParser(FileParser):
|
||||
):
|
||||
"""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:
|
||||
@ -202,22 +208,36 @@ class ReturnValueParser(FileParser):
|
||||
moving_window=moving_window,
|
||||
first_line=moving_window[self._moving_window_center_idx]
|
||||
)
|
||||
number_match = INVALID_IF_ID
|
||||
# Try to match for a string using the new API first. Example:
|
||||
# static const ReturnValue_t PACKET_TOO_LONG =
|
||||
# HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0);
|
||||
returnvalue_match = re.search(
|
||||
r"^[\s]*static const(?:expr)? ReturnValue_t[\s]*([\w] *)[\s]*"
|
||||
r"^[\s]*static const(?:expr)? ReturnValue_t[\s]*([\w]*)[\s]*"
|
||||
r"=[\s]*.*::[\w]*\(([\w]*),[\s]*([\d]*)\)",
|
||||
full_returnvalue_string
|
||||
)
|
||||
if not returnvalue_match:
|
||||
# Try to match for old API using MAE_RETURN_CODE macro
|
||||
returnvalue_match = re.search(
|
||||
r'^[\s]*static const(?:expr)? ReturnValue_t[\s]*([a-zA-Z_0-9]*)[\s]*=[\s]*'
|
||||
r'MAKE_RETURN_CODE[\s]*\([\s]*([\w]*)[\s]*\)',
|
||||
full_returnvalue_string
|
||||
)
|
||||
if returnvalue_match:
|
||||
number_match = returnvalue_match.group(2)
|
||||
else:
|
||||
number_match = returnvalue_match.group(3)
|
||||
if returnvalue_match:
|
||||
description = self.__search_for_descrip_string(moving_window=moving_window)
|
||||
if number_match == INVALID_IF_ID:
|
||||
LOGGER.warning(f'Invalid number match detected for file {file_name}')
|
||||
LOGGER.warning(f'Match groups:')
|
||||
for group in returnvalue_match.groups():
|
||||
LOGGER.info(group)
|
||||
self.__handle_returnvalue_match(
|
||||
name_match=returnvalue_match.group(1), file_name=file_name,
|
||||
number_match=returnvalue_match.group(2), description=description
|
||||
number_match=number_match, description=description
|
||||
)
|
||||
|
||||
def __build_multi_line_returnvalue_string(
|
||||
@ -256,17 +276,27 @@ class ReturnValueParser(FileParser):
|
||||
self.last_lines[1] = self.last_lines[0]
|
||||
self.last_lines[0] = newline
|
||||
|
||||
def __handle_interfaceid_match(self, interface_id_match, file_name: str):
|
||||
if DEBUG_INTERFACE_ID_COMPARISON:
|
||||
print(f"Interface ID {interface_id_match.group(1)} found in {file_name}")
|
||||
self.current_interface_id_entries["ID"] = \
|
||||
self.interfaces[interface_id_match.group(1)][0]
|
||||
def __handle_interfaceid_match(self, interface_id_match, file_name: str) -> bool:
|
||||
"""Handle a match of an interface ID definition in the code.
|
||||
Returns whether the interface ID was found successfully in the IF ID header files
|
||||
"""
|
||||
if self.get_verbosity() == VerbosityLevels.DEBUG:
|
||||
LOGGER.info(f'Interface ID {interface_id_match.group(1)} found in {file_name}')
|
||||
if_id_entry = self.interfaces.get(interface_id_match.group(1))
|
||||
if if_id_entry is not None:
|
||||
self.current_interface_id_entries["ID"] = if_id_entry[0]
|
||||
else:
|
||||
LOGGER.warning(
|
||||
f'Interface ID {interface_id_match.group(1)} not found in IF ID dictionary'
|
||||
)
|
||||
return False
|
||||
self.current_interface_id_entries["Name"] = \
|
||||
self.interfaces[interface_id_match.group(1)][1]
|
||||
self.current_interface_id_entries["FullName"] = interface_id_match.group(1)
|
||||
if DEBUG_INTERFACE_ID_COMPARISON:
|
||||
if self.get_verbosity() == VerbosityLevels.DEBUG:
|
||||
current_id = self.current_interface_id_entries["ID"]
|
||||
print(f"Current ID: {current_id}")
|
||||
LOGGER.info(f'Current ID: {current_id}')
|
||||
return True
|
||||
|
||||
def __handle_returnvalue_match(
|
||||
self, name_match: str, number_match: str, file_name: str, description: str
|
||||
@ -312,7 +342,7 @@ class ReturnValueParser(FileParser):
|
||||
my_str = first_part + '_' + self.convert(second_part)
|
||||
if len(my_str) > max_string_len:
|
||||
if print_truncated_entries:
|
||||
print("Warning: Entry " + my_str + " too long. Will truncate.")
|
||||
LOGGER.warning(f'Entry {my_str} too long. Will truncate.')
|
||||
my_str = my_str[0:max_string_len]
|
||||
else:
|
||||
# print("Entry: " + myStr + " is all right.")
|
||||
@ -342,6 +372,6 @@ def return_number_from_string(a_string):
|
||||
return int(a_string, 16)
|
||||
if a_string.isdigit():
|
||||
return int(a_string)
|
||||
print('Error: Illegal number representation: ' + a_string)
|
||||
LOGGER.warning(f'Illegal number representation: {a_string}')
|
||||
return 0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user