Coverage for src/pyTRLCConverter/item_walker.py: 85%
65 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 12:41 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 12:41 +0000
1"""
2This module implements a TRLC items walker over the loaded model.
4Author: Norbert Schulz (norbert.schulz@newtec.de)
5"""
7# pyTRLCConverter - A tool to convert TRLC files to specific formats.
8# Copyright (c) 2024 - 2026 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/>.
23# Imports **********************************************************************
24import os
25import traceback
26from typing import Any
27from trlc.ast import Symbol_Table
29from pyTRLCConverter.abstract_converter import AbstractConverter
30from pyTRLCConverter.logger import log_verbose, log_error
31from pyTRLCConverter.trlc_helper import get_file_dict_from_symbols, is_item_record, is_item_section
32from pyTRLCConverter.ret import Ret
34# Variables ********************************************************************
36# Classes **********************************************************************
39# pylint: disable-next=too-few-public-methods
40class ItemWalker:
41 # lobster-trace: SwRequirements.sw_req_process_trlc_symbols
42 """A walker that traverses through the TRLC items in the given symbol table."""
44 def __init__(self, args: Any, converter: AbstractConverter) -> None:
45 """
46 Initializes the TrlcWalker with the given arguments and converter.
48 Args:
49 args (Any): Arguments containing the exclude file paths.
50 converter (AbstractConverter): The converter used for processing items.
51 """
52 self._converter = converter
53 self._exclude_files = args.exclude
55 def walk_symbols(self, symbol_table: Symbol_Table) -> Ret:
56 """
57 Walks through the items in the given symbol table and processes them.
59 Args:
60 symbol_table (Symbol_Table): The symbol table containing items to be walked through.
62 Returns:
63 Ret: Status of the walk operation.
64 """
65 result = self._converter.begin()
67 if result == Ret.OK:
68 files_dict = get_file_dict_from_symbols(symbol_table)
69 for file_name, item_list in files_dict.items():
70 skip_it = False
72 # Normalize the file name to make it comparable.
73 file_name = os.path.normpath(file_name)
75 if self._exclude_files is not None:
76 for excluded_path in self._exclude_files:
78 # Normalize the excluded path to make it comparable.
79 excluded_path = os.path.normpath(excluded_path)
81 if os.path.commonpath([excluded_path, file_name]) == excluded_path:
82 skip_it = True
83 break
85 if skip_it is True:
86 log_verbose(f"Skipping file {file_name}.")
88 else:
89 log_verbose(f"Processing file {file_name}.")
90 result = self._walk_file(file_name, item_list)
92 if result != Ret.OK:
93 break
95 if result == Ret.OK:
96 result = self._converter.finish()
98 return result
100 def _walk_file(self, file_name: str, item_list: Any) -> Ret:
101 """
102 Walks through the items in the given file.
104 Args:
105 file_name (str): The name of the file.
106 item_list (Any): The list of trlc items in the file.
108 Returns:
109 Ret: The result of the walk operation.
110 """
111 result = Ret.ERROR
113 try:
114 if Ret.OK == self._converter.enter_file(file_name):
115 if Ret.OK == self._walk_items(item_list):
116 if Ret.OK == self._converter.leave_file(file_name):
117 result = Ret.OK
119 except Exception as e: # pylint: disable=broad-except
120 log_error(f"Error processing file {file_name}: {e}")
122 return result
124 def _walk_items(self, item_list: list) -> Ret:
125 """
126 Walks through the given list of items.
128 Args:
129 item_list (list): The list of items to walk through.
131 Returns:
132 Ret: The result of the walk operation.
133 """
135 result = Ret.OK
137 try:
138 for item in item_list:
139 result = self._visit_item(item)
141 if result != Ret.OK:
142 break
143 except Exception as e: # pylint: disable=broad-except
144 log_error(f"Error processing item {item}: {e}")
145 traceback.print_exc()
146 result = Ret.ERROR
148 return result
150 def _visit_item(self, item: Any) -> Ret:
151 """
152 Visits the given item and processes it based on its type.
154 Args:
155 item (Any): The item to visit.
157 Returns:
158 Ret: The result of the visit.
159 """
160 result = Ret.OK
162 if is_item_section(item):
163 result = self._converter.convert_section(item[0], item[1])
164 elif is_item_record(item):
165 result = self._converter.convert_record_object(item[0], item[1])
166 else:
167 log_error(f"Unrecognized item type {item}")
168 result = Ret.ERROR
170 return result
172# Functions ********************************************************************
175# Main *************************************************************************