Coverage for src/pyTRLCConverter/item_walker.py: 84%

64 statements  

« prev     ^ index     » next       coverage.py v7.10.3, created at 2025-08-14 10:59 +0000

1""" 

2This module implements a TRLC items walker over the loaded model. 

3 

4Author: Norbert Schulz (norbert.schulz@newtec.de) 

5""" 

6 

7# pyTRLCConverter - A tool to convert TRLC files to specific formats. 

8# Copyright (c) 2024 - 2025 NewTec GmbH 

9# 

10# This file is part of pyTRLCConverter program. 

11# 

12# The pyTRLCConverter program is free software: you can redistribute it and/or modify it under 

13# the terms of the GNU General Public License as published by the Free Software Foundation, 

14# either version 3 of the License, or (at your option) any later version. 

15# 

16# The pyTRLCConverter program is distributed in the hope that it will be useful, but 

17# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

18# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 

19# 

20# You should have received a copy of the GNU General Public License along with pyTRLCConverter. 

21# If not, see <https://www.gnu.org/licenses/>. 

22 

23# Imports ********************************************************************** 

24import os 

25import traceback 

26from trlc.ast import Symbol_Table 

27 

28from pyTRLCConverter.abstract_converter import AbstractConverter 

29from pyTRLCConverter.logger import log_verbose, log_error 

30from pyTRLCConverter.trlc_helper import get_file_dict_from_symbols, is_item_record, is_item_section 

31from pyTRLCConverter.ret import Ret 

32 

33# Variables ******************************************************************** 

34 

35# Classes ********************************************************************** 

36 

37 

38class ItemWalker: # pylint: disable=too-few-public-methods 

39 # lobster-trace: SwRequirements.sw_req_process_trlc_symbols 

40 """ 

41 A walker that traverses through the TRLC items in the given symbol table. 

42 

43 Attributes: 

44 _converter (AbstractConverter): The converter used for processing items. 

45 _exclude_files (list): List of file paths to exclude from processing. 

46 """ 

47 

48 def __init__(self, args: any, converter: AbstractConverter) -> None: 

49 """ 

50 Initializes the TrlcWalker with the given arguments and converter. 

51 

52 Args: 

53 args (any): Arguments containing the exclude file paths. 

54 converter (AbstractConverter): The converter used for processing items. 

55 """ 

56 self._converter = converter 

57 self._exclude_files = args.exclude 

58 

59 def walk_symbols(self, symbol_table: Symbol_Table) -> Ret: 

60 """ 

61 Walks through the items in the given symbol table and processes them. 

62 

63 Args: 

64 symbol_table (Symbol_Table): The symbol table containing items to be walked through. 

65 

66 Returns: 

67 Ret: Status of the walk operation. 

68 """ 

69 result = self._converter.begin() 

70 

71 if result == Ret.OK: 

72 files_dict = get_file_dict_from_symbols(symbol_table) 

73 for file_name, item_list in files_dict.items(): 

74 skip_it = False 

75 

76 # Normalize the file name to make it comparable. 

77 file_name = os.path.normpath(file_name) 

78 

79 if self._exclude_files is not None: 

80 for excluded_path in self._exclude_files: 

81 

82 # Normalize the excluded path to make it comparable. 

83 excluded_path = os.path.normpath(excluded_path) 

84 

85 if os.path.commonpath([excluded_path, file_name]) == excluded_path: 

86 skip_it = True 

87 break 

88 

89 if skip_it is True: 

90 log_verbose(f"Skipping file {file_name}.") 

91 

92 else: 

93 log_verbose(f"Processing file {file_name}.") 

94 result = self._walk_file(file_name, item_list) 

95 

96 if result != Ret.OK: 

97 break 

98 

99 if result == Ret.OK: 

100 result = self._converter.finish() 

101 

102 return result 

103 

104 def _walk_file(self, file_name: str, item_list: any) -> Ret: 

105 """ 

106 Walks through the items in the given file. 

107 

108 Args: 

109 file_name (str): The name of the file. 

110 item_list (any): The list of trlc items in the file. 

111 

112 Returns: 

113 Ret: The result of the walk operation. 

114 """ 

115 result = Ret.ERROR 

116 

117 try: 

118 if Ret.OK == self._converter.enter_file(file_name): 

119 if Ret.OK == self._walk_items(item_list): 

120 if Ret.OK == self._converter.leave_file(file_name): 

121 result = Ret.OK 

122 

123 except Exception as e: # pylint: disable=broad-except 

124 log_error(f"Error processing file {file_name}: {e}") 

125 

126 return result 

127 

128 def _walk_items(self, item_list: list) -> Ret: 

129 """ 

130 Walks through the given list of items. 

131 

132 Args: 

133 item_list (list): The list of items to walk through. 

134 

135 Returns: 

136 Ret: The result of the walk operation. 

137 """ 

138 

139 result = Ret.OK 

140 

141 try: 

142 for item in item_list: 

143 result = self._visit_item(item) 

144 

145 if result != Ret.OK: 

146 break 

147 except Exception as e: # pylint: disable=broad-except 

148 log_error(f"Error processing item {item}: {e}") 

149 traceback.print_exc() 

150 result = Ret.ERROR 

151 

152 return result 

153 

154 def _visit_item(self, item: any) -> Ret: 

155 """ 

156 Visits the given item and processes it based on its type. 

157 

158 Args: 

159 item (any): The item to visit. 

160 

161 Returns: 

162 Ret: The result of the visit. 

163 """ 

164 result = Ret.OK 

165 

166 if is_item_section(item): 

167 result = self._converter.convert_section(item[0], item[1]) 

168 elif is_item_record(item): 

169 result = self._converter.convert_record_object(item[0], item[1]) 

170 else: 

171 log_error(f"Unrecognized item type {item}") 

172 result = Ret.ERROR 

173 

174 return result 

175 

176# Functions ******************************************************************** 

177 

178 

179# Main *************************************************************************