работа с таблицей перенесена в отдельный файл

сделано автозаполнение при поиске переменых
сделано правильное формирование структур, через . или ->

пофиксены мелкие фиксы
This commit is contained in:
Razvalyaev 2025-07-09 15:40:16 +03:00
parent 0b50c31aa8
commit 4962276760
15 changed files with 594 additions and 293 deletions

Binary file not shown.

View File

@ -1,9 +1,10 @@
import re import re
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton, QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
QLineEdit, QLabel, QHeaderView QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout
) )
from PySide6.QtCore import Qt from PySide6.QtGui import QKeySequence, QKeyEvent
from PySide6.QtCore import Qt, QStringListModel, QSettings
from setupVars import * from setupVars import *
from scanVars import * from scanVars import *
@ -25,9 +26,21 @@ class VariableSelectorDialog(QDialog):
self.xml_path = xml_path # сохраняем путь к xml self.xml_path = xml_path # сохраняем путь к xml
# --- Добавляем чекбокс для автодополнения ---
self.autocomplete_checkbox = QCheckBox("Включить автодополнение")
self.autocomplete_checkbox.setChecked(True)
# Инициализируем QSettings с именем организации и приложения
self.settings = QSettings("SET", "DebugVarEdit_VarsSelector")
# Восстанавливаем сохранённое состояние чекбокса, если есть
checked = self.settings.value("autocomplete_enabled", True, type=bool)
self.autocomplete_checkbox.setChecked(checked)
# При изменении состояния чекбокса сохраняем его
self.autocomplete_checkbox.stateChanged.connect(self.save_checkbox_state)
self.search_input = QLineEdit() self.search_input = QLineEdit()
self.search_input.setPlaceholderText("Поиск по имени переменной...") self.search_input.setPlaceholderText("Поиск по имени переменной...")
self.search_input.textChanged.connect(self.filter_tree) self.search_input.textChanged.connect(self.on_search_text_changed)
self.tree = QTreeWidget() self.tree = QTreeWidget()
self.tree.setHeaderLabels(["Имя переменной", "Тип"]) self.tree.setHeaderLabels(["Имя переменной", "Тип"])
@ -51,17 +64,33 @@ class VariableSelectorDialog(QDialog):
self.btn_delete = QPushButton("Удалить выбранные") self.btn_delete = QPushButton("Удалить выбранные")
self.btn_delete.clicked.connect(self.on_delete_clicked) self.btn_delete.clicked.connect(self.on_delete_clicked)
self.completer = QCompleter()
self.completer.setCompletionMode(QCompleter.PopupCompletion) # важно!
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setFilterMode(Qt.MatchContains)
self.completer.setWidget(self.search_input)
self.search_input.installEventFilter(self)
# Создаем горизонтальный layout для "Поиск:" и чекбокса справа
search_layout = QHBoxLayout()
label_search = QLabel("Поиск:")
search_layout.addWidget(label_search, alignment=Qt.AlignLeft)
search_layout.addStretch() # чтобы чекбокс прижался вправо
search_layout.addWidget(self.autocomplete_checkbox, alignment=Qt.AlignRight)
self.completer.activated[str].connect(self.insert_completion)
layout = QVBoxLayout() layout = QVBoxLayout()
layout.addWidget(QLabel("Поиск:")) layout.addLayout(search_layout) # заменили label и чекбокс
layout.addWidget(self.search_input) layout.addWidget(self.search_input)
layout.addWidget(self.tree) layout.addWidget(self.tree)
layout.addWidget(self.btn_add) layout.addWidget(self.btn_add)
layout.addWidget(self.btn_delete) # Кнопка удаления layout.addWidget(self.btn_delete)
self.setLayout(layout) self.setLayout(layout)
self.populate_tree() self.populate_tree()
def add_tree_item_recursively(self, parent, var): def add_tree_item_recursively(self, parent, var):
""" """
Рекурсивно добавляет переменную и её дочерние поля в дерево. Рекурсивно добавляет переменную и её дочерние поля в дерево.
@ -113,7 +142,7 @@ class VariableSelectorDialog(QDialog):
def filter_tree(self): def filter_tree(self):
text = self.search_input.text().strip().lower() text = self.search_input.text().strip().lower()
path_parts = text.split('.') if text else [] path_parts = self.split_path(text) if text else []
def hide_all(item): def hide_all(item):
item.setHidden(True) item.setHidden(True)
@ -121,7 +150,7 @@ class VariableSelectorDialog(QDialog):
hide_all(item.child(i)) hide_all(item.child(i))
def path_matches_search(name, search_parts): def path_matches_search(name, search_parts):
name_parts = name.lower().split('.') name_parts = self.split_path(name.lower())
if len(name_parts) < len(search_parts): if len(name_parts) < len(search_parts):
return False return False
for sp, np in zip(search_parts, name_parts): for sp, np in zip(search_parts, name_parts):
@ -156,11 +185,189 @@ class VariableSelectorDialog(QDialog):
return matched or matched_any_child return matched or matched_any_child
for i in range(self.tree.topLevelItemCount()): # Если в поиске нет точки — особая логика для первого уровня
item = self.tree.topLevelItem(i) if '.' not in text and '->' not in text and text != '':
hide_all(item) for i in range(self.tree.topLevelItemCount()):
show_matching_path(item, 0) item = self.tree.topLevelItem(i)
name = item.text(0).lower()
if text in name:
item.setHidden(False)
item.setExpanded(False) # НЕ раскрываем потомков
else:
hide_all(item)
item.setHidden(True)
else:
# Обычная логика с поиском по пути
for i in range(self.tree.topLevelItemCount()):
item = self.tree.topLevelItem(i)
hide_all(item)
show_matching_path(item, 0)
def update_completions(self, text = None):
if text is None:
text = self.search_input.text().strip()
else:
text = text.strip()
parts = self.split_path(text)
path_parts = parts[:-1]
prefix = parts[-1].lower() if not text.endswith(('.', '>')) else ''
# Если путь есть (например: project.adc или project.adc.), ищем внутри него
search_deep = len(path_parts) > 0
def find_path_items(path_parts):
items = [self.tree.topLevelItem(i) for i in range(self.tree.topLevelItemCount())]
for part in path_parts:
part_lower = part.lower()
matched = []
for item in items:
# Берём последний фрагмент имени item, разделённого точками
item_name_part = self.split_path(item.text(0))[-1].lower()
if item_name_part == part_lower:
matched.append(item)
if not matched:
return []
items = []
# Собираем детей для следующего уровня поиска
for node in matched:
for i in range(node.childCount()):
items.append(node.child(i))
return matched
if not search_deep:
# Без точки — ищем только в топ-уровне, фильтруя по prefix
items = []
for i in range(self.tree.topLevelItemCount()):
item = self.tree.topLevelItem(i)
name_part = self.split_path(item.text(0))[-1].lower()
if name_part.startswith(prefix):
items.append(item)
completions = [item.text(0) for item in items]
else:
# С точкой — углубляемся по пути и показываем имена детей
if len(path_parts) == 0:
items = [self.tree.topLevelItem(i) for i in range(self.tree.topLevelItemCount())]
else:
items = find_path_items(path_parts)
completions = []
for item in items:
for i in range(item.childCount()):
child = item.child(i)
name_part = self.split_path(child.text(0))[-1].lower()
if prefix == '' or name_part.startswith(prefix):
completions.append(child.text(0))
self.completer.setModel(QStringListModel(completions))
return completions
def eventFilter(self, obj, event):
if obj == self.search_input and isinstance(event, QKeyEvent):
if event.key() == Qt.Key_Space and event.modifiers() & Qt.ControlModifier:
completions = self.update_completions()
self.completer.complete()
text = self.search_input.text().strip()
if len(completions) == 1 and completions[0].lower() == text.lower():
# Найдем узел с таким именем
def find_exact_item(name):
stack = [self.tree.topLevelItem(i) for i in range(self.tree.topLevelItemCount())]
while stack:
node = stack.pop()
if node.text(0).lower() == name.lower():
return node
for i in range(node.childCount()):
stack.append(node.child(i))
return None
node = find_exact_item(completions[0])
if node and node.childCount() > 0:
# Используем первую подсказку, чтобы определить нужный разделитель
completions = self.update_completions(text + '.')
suggestion = completions[0]
# Ищем, какой символ идёт после текущего текста
separator = '.'
if suggestion.startswith(text):
rest = suggestion[len(text):]
if rest.startswith('->'):
separator = '->'
elif rest.startswith('.'):
separator = '.'
self.search_input.setText(text + separator)
completions = self.update_completions()
self.completer.setModel(QStringListModel(completions))
self.completer.complete()
return True
# Иначе просто показываем подсказки
self.completer.setModel(QStringListModel(completions))
if completions:
self.completer.complete()
return True
return super().eventFilter(obj, event)
# Функция для поиска узла с полным именем
def find_node_by_fullname(self, name):
stack = [self.tree.topLevelItem(i) for i in range(self.tree.topLevelItemCount())]
while stack:
node = stack.pop()
if node.text(0).lower() == name.lower():
return node
for i in range(node.childCount()):
stack.append(node.child(i))
return None
def insert_completion(self, text):
node = self.find_node_by_fullname(text)
if node and node.childCount() > 0 and not (text.endswith('.') or text.endswith('->')):
# Определяем разделитель по имени первого ребёнка
child_name = node.child(0).text(0)
if child_name.startswith(text + '->'):
text += '->'
else:
text += '.'
self.search_input.setText(text)
self.search_input.setCursorPosition(len(text))
self.update_completions()
self.completer.complete()
else:
self.search_input.setText(text)
self.search_input.setCursorPosition(len(text))
def on_search_text_changed(self, text):
if self.autocomplete_checkbox.isChecked():
completions = self.update_completions(text)
node = self.find_node_by_fullname(text)
should_show = False
if completions:
if len(completions) > 1:
should_show = True
elif len(completions) == 1:
single_node = self.find_node_by_fullname(completions[0])
if single_node and single_node.childCount() > 0:
should_show = True
elif node and node.childCount() > 0 and not (text.endswith('.') or text.endswith('->')):
should_show = True
if should_show:
self.completer.setModel(QStringListModel(completions))
self.completer.complete()
self.filter_tree()
def on_add_clicked(self): def on_add_clicked(self):
self.selected_names = [] self.selected_names = []
@ -206,16 +413,55 @@ class VariableSelectorDialog(QDialog):
self.accept() self.accept()
def on_delete_clicked(self): def on_delete_clicked(self):
# Деактивируем (удаляем из видимых) выбранные переменные selected_names = self._get_selected_var_names()
for item in self.tree.selectedItems(): if not selected_names:
name = item.text(0) return
if not name:
continue # Обновляем var_map и all_vars
for name in selected_names:
if name in self.var_map: if name in self.var_map:
var = self.var_map[name] self.var_map[name]['show_var'] = 'false'
var['show_var'] = 'false' self.var_map[name]['enable'] = 'false'
var['enable'] = 'false'
for v in self.all_vars:
if v['name'] == name:
v['show_var'] = 'false'
v['enable'] = 'false'
break
# Проверка пути к XML
if not hasattr(self, 'xml_path') or not self.xml_path:
from PySide6.QtWidgets import QMessageBox
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
return
import xml.etree.ElementTree as ET
tree = ET.parse(self.xml_path)
root = tree.getroot()
if root is None:
return
vars_section = root.find('variables')
if vars_section is None:
return
for var_elem in vars_section.findall('var'):
name = var_elem.attrib.get('name')
if name in selected_names:
def set_text(tag, value):
el = var_elem.find(tag)
if el is None:
el = ET.SubElement(var_elem, tag)
el.text = value
set_text('show_var', 'false')
set_text('enable', 'false')
ET.indent(tree, space=" ", level=0)
tree.write(self.xml_path, encoding='utf-8', xml_declaration=True)
self.populate_tree()
self.accept() self.accept()
@ -231,16 +477,11 @@ class VariableSelectorDialog(QDialog):
super().keyPressEvent(event) super().keyPressEvent(event)
def delete_selected_vars(self): def delete_selected_vars(self):
# Деактивируем (удаляем из видимых) выбранные переменные selected_names = self._get_selected_var_names()
for item in self.tree.selectedItems(): if not selected_names:
name = item.text(0) return
if not name:
continue
if name in self.var_map:
var = self.var_map[name]
var['show_var'] = 'false'
var['enable'] = 'false'
# Проверка пути к XML
if not hasattr(self, 'xml_path') or not self.xml_path: if not hasattr(self, 'xml_path') or not self.xml_path:
from PySide6.QtWidgets import QMessageBox from PySide6.QtWidgets import QMessageBox
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.") QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.")
@ -249,31 +490,39 @@ class VariableSelectorDialog(QDialog):
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
tree = ET.parse(self.xml_path) tree = ET.parse(self.xml_path)
root = tree.getroot() root = tree.getroot()
if root is None: if root is None:
return return
vars_section = root.find('variables') vars_section = root.find('variables')
if vars_section is None: if vars_section is None:
return # Нет секции variables — ничего удалять return
selected_names = [item.text(0) for item in self.tree.selectedItems() if item.text(0)]
removed_any = False removed_any = False
for var_elem in vars_section.findall('var'): for var_elem in list(vars_section.findall('var')):
name = var_elem.attrib.get('name') name = var_elem.attrib.get('name')
if name in selected_names: if name in selected_names:
vars_section.remove(var_elem) vars_section.remove(var_elem)
removed_any = True removed_any = True
if name in self.var_map: self.var_map.pop(name, None)
del self.var_map[name]
# Удаляем элементы из списка на месте
self.all_vars[:] = [v for v in self.all_vars if v['name'] != name]
# Удаляем из all_vars (глобально)
self.all_vars[:] = [v for v in self.all_vars if v['name'] not in selected_names]
if removed_any: if removed_any:
ET.indent(tree, space=" ", level=0) ET.indent(tree, space=" ", level=0)
tree.write(self.xml_path, encoding='utf-8', xml_declaration=True) tree.write(self.xml_path, encoding='utf-8', xml_declaration=True)
self.populate_tree() self.populate_tree()
self.filter_tree()
def _get_selected_var_names(self):
return [item.text(0) for item in self.tree.selectedItems() if item.text(0)]
def save_checkbox_state(self):
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
def split_path(self, path):
# Разбиваем по точке или по -> (учитываем, что -> длиной 2 символа)
return re.split(r'\.|->', path)

184
Src/VariableTable.py Normal file
View File

@ -0,0 +1,184 @@
from PySide6.QtWidgets import (
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
QAbstractItemView, QHeaderView
)
from PySide6.QtCore import Qt
from enum import IntEnum
from generateVars import type_map
class rows(IntEnum):
No = 0
include = 1
name = 2
type = 3
pt_type = 4
iq_type = 5
ret_type = 6
short_name = 7
class VariableTableWidget(QTableWidget):
def __init__(self, parent=None):
super().__init__(0, 8, parent)
# Таблица переменных
self.setHorizontalHeaderLabels([
'', # новый столбец
'En',
'Name',
'Origin Type',
'Pointer Type',
'IQ Type',
'Return Type',
'Short Name'
])
self.setEditTriggers(QAbstractItemView.AllEditTriggers)
self.type_options = list(dict.fromkeys(type_map.values()))
self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
self.iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
header = self.horizontalHeader()
# Для остальных колонок — растяжение (Stretch), чтобы они заняли всю оставшуюся ширину
for col in range(self.columnCount()):
if col == self.columnCount() - 1:
header.setSectionResizeMode(col, QHeaderView.Stretch)
else:
header.setSectionResizeMode(col, QHeaderView.Interactive)
parent_widget = self.parentWidget()
# Сделаем колонки с номерами фиксированной ширины
self.setColumnWidth(rows.No, 30)
self.setColumnWidth(rows.include, 30)
self.setColumnWidth(rows.pt_type, 85)
self.setColumnWidth(rows.iq_type, 85)
self.setColumnWidth(rows.ret_type, 85)
self.setColumnWidth(rows.name, 300)
self.setColumnWidth(rows.type, 100)
self._resizing = False
self.horizontalHeader().sectionResized.connect(self.on_section_resized)
def populate(self, vars_list, structs, on_change_callback):
self.type_options = list(dict.fromkeys(type_map.values()))
self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
filtered_vars = [v for v in vars_list if v.get('show_var', 'false') == 'true']
self.setRowCount(len(filtered_vars))
self.verticalHeader().setVisible(False)
for row, var in enumerate(filtered_vars):
# №
no_item = QTableWidgetItem(str(row))
no_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
self.setItem(row, rows.No, no_item)
# Enable
cb = QCheckBox()
cb.setChecked(var.get('enable', 'false') == 'true')
cb.stateChanged.connect(on_change_callback)
self.setCellWidget(row, rows.include, cb)
# Name
name_edit = QLineEdit(var['name'])
if var['type'] in structs:
completer = QCompleter(structs[var['type']].keys())
completer.setCaseSensitivity(Qt.CaseInsensitive)
name_edit.setCompleter(completer)
name_edit.textChanged.connect(on_change_callback)
self.setCellWidget(row, rows.name, name_edit)
# Origin Type (readonly)
origin_item = QTableWidgetItem(var.get('type', ''))
origin_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
self.setItem(row, rows.type, origin_item)
# pt_type
pt_combo = QComboBox()
pt_combo.addItems(self.display_type_options)
value = var['pt_type'].replace('pt_', '')
if value not in self.display_type_options:
pt_combo.addItem(value)
pt_combo.setCurrentText(value)
pt_combo.currentTextChanged.connect(on_change_callback)
self.setCellWidget(row, rows.pt_type, pt_combo)
# iq_type
iq_combo = QComboBox()
iq_combo.addItems(self.iq_types)
value = var['iq_type'].replace('t_', '')
if value not in self.iq_types:
iq_combo.addItem(value)
iq_combo.setCurrentText(value)
iq_combo.currentTextChanged.connect(on_change_callback)
self.setCellWidget(row, rows.iq_type, iq_combo)
# return_type
ret_combo = QComboBox()
ret_combo.addItems(self.iq_types)
ret_combo.setCurrentText(var.get('return_type', ''))
ret_combo.currentTextChanged.connect(on_change_callback)
self.setCellWidget(row, rows.ret_type, ret_combo)
# short_name
short_name_edit = QLineEdit(var.get('shortname', var['name']))
short_name_edit.textChanged.connect(on_change_callback)
self.setCellWidget(row, rows.short_name, short_name_edit)
def read_data(self):
result = []
for row in range(self.rowCount()):
cb = self.cellWidget(row, rows.include)
name = self.cellWidget(row, rows.name).text()
pt = self.cellWidget(row, rows.pt_type).currentText()
iq = self.cellWidget(row, rows.iq_type).currentText()
ret = self.cellWidget(row, rows.ret_type).currentText()
shortname = self.cellWidget(row, rows.short_name).text()
origin_type = self.item(row, rows.type).text()
result.append({
'show_var': True,
'enable': cb.isChecked(),
'name': name,
'pt_type': f'pt_{pt}',
'iq_type': iq,
'return_type': ret,
'shortname': shortname,
'type': origin_type,
})
return result
def on_section_resized(self, logicalIndex, oldSize, newSize):
if self._resizing:
return # предотвращаем рекурсию
min_width = 50
delta = newSize - oldSize
right_index = logicalIndex + 1
if right_index >= self.columnCount():
# Если правая колока - нет соседа, ограничиваем минимальную ширину
if newSize < min_width:
self._resizing = True
self.setColumnWidth(logicalIndex, min_width)
self._resizing = False
return
self._resizing = True
try:
right_width = self.columnWidth(right_index)
new_right_width = right_width - delta
# Если соседняя колонка станет уже минимальной - подкорректируем левую
if new_right_width < min_width:
new_right_width = min_width
newSize = oldSize + (right_width - min_width)
self.setColumnWidth(logicalIndex, newSize)
self.setColumnWidth(right_index, new_right_width)
finally:
self._resizing = False

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -330,12 +330,13 @@ def generate_vars_file(proj_path, xml_path, output_dir):
# Дополнительные поля, например комментарий # Дополнительные поля, например комментарий
comment = info.get("comment", "") comment = info.get("comment", "")
short_name = info.get("shortname", f'"{vname}"')
if pt_type not in ('pt_struct', 'pt_union'): if pt_type not in ('pt_struct', 'pt_union'):
formated_name = f'"{vname}"' formated_name = f'"{vname}"'
# Добавим комментарий после записи, если он есть # Добавим комментарий после записи, если он есть
comment_str = f' // {comment}' if comment else '' comment_str = f' // {comment}' if comment else ''
line = f'{{(char *)&{vname:<41} , {pt_type:<21} , {iq_type:<21} , {formated_name:<42}}}, \\{comment_str}' line = f'{{(char *)&{vname:<41} , {pt_type:<21} , {iq_type:<21} , {short_name:<42}}}, \\{comment_str}'
new_debug_vars[vname] = line new_debug_vars[vname] = line
else: else:

View File

@ -7,11 +7,14 @@ def strip_single_line_comments(code):
return re.sub(r'//.*?$', '', code, flags=re.MULTILINE) return re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
def read_file_try_encodings(filepath): def read_file_try_encodings(filepath):
if not os.path.isfile(filepath):
# Файл не существует — просто вернуть пустую строку или None
return "", None
for enc in ['utf-8', 'cp1251']: for enc in ['utf-8', 'cp1251']:
try: try:
with open(filepath, 'r', encoding=enc) as f: with open(filepath, 'r', encoding=enc) as f:
content = f.read() content = f.read()
content = strip_single_line_comments(content) # <=== ВАЖНО content = strip_single_line_comments(content)
return content, enc return content, enc
except UnicodeDecodeError: except UnicodeDecodeError:
continue continue
@ -38,6 +41,8 @@ def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
processed_files.add(norm_path) processed_files.add(norm_path)
content, _ = read_file_try_encodings(cfile) content, _ = read_file_try_encodings(cfile)
if content is None:
continue
includes = include_pattern.findall(content) includes = include_pattern.findall(content)
for inc in includes: for inc in includes:
# Ищем полный путь к include-файлу в include_dirs # Ищем полный путь к include-файлу в include_dirs
@ -61,9 +66,9 @@ def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
return include_files return include_files
def parse_makefile(makefile_path): def parse_makefile(makefile_path, proj_path):
makefile_dir = os.path.dirname(makefile_path) makefile_dir = os.path.dirname(makefile_path)
project_root = os.path.dirname(makefile_dir) # поднялись из Debug project_root = proj_path
with open(makefile_path, 'r', encoding='utf-8') as f: with open(makefile_path, 'r', encoding='utf-8') as f:
lines = f.readlines() lines = f.readlines()
@ -115,6 +120,8 @@ def parse_makefile(makefile_path):
continue continue
if "v120" in obj_path: if "v120" in obj_path:
continue continue
if "v100" in obj_path:
continue
if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"): if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"):
rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/") rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/")
@ -129,6 +136,10 @@ def parse_makefile(makefile_path):
else: else:
c_path = abs_path c_path = abs_path
# Проверяем существование файла, если нет — пропускаем
if not os.path.isfile(c_path):
continue
# Сохраняем только .c файлы # Сохраняем только .c файлы
if c_path.lower().endswith(".c"): if c_path.lower().endswith(".c"):
c_files.append(c_path) c_files.append(c_path)

View File

@ -812,7 +812,7 @@ Usage example:
print(f"Error: Makefile path '{makefile_path}' does not exist.") print(f"Error: Makefile path '{makefile_path}' does not exist.")
sys.exit(1) sys.exit(1)
c_files, h_files, include_dirs = parse_makefile(makefile_path) c_files, h_files, include_dirs = parse_makefile(makefile_path, proj_path)
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs) vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs)
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs) typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs)
@ -855,7 +855,7 @@ def run_scan(proj_path, makefile_path, output_xml, verbose=2):
if not os.path.isfile(makefile_path): if not os.path.isfile(makefile_path):
raise FileNotFoundError(f"Makefile path '{makefile_path}' does not exist.") raise FileNotFoundError(f"Makefile path '{makefile_path}' does not exist.")
c_files, h_files, include_dirs = parse_makefile(makefile_path) c_files, h_files, include_dirs = parse_makefile(makefile_path, proj_path)
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs) vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs)
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs) typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs)

View File

@ -63,6 +63,21 @@ def parse_vars(filename, typedef_map=None):
iq_type = var.findtext('iq_type') iq_type = var.findtext('iq_type')
if not iq_type: if not iq_type:
iq_type = get_iq_define(var_type) iq_type = get_iq_define(var_type)
# Записываем iq_type в XML
iq_type_elem = var.find('iq_type')
if iq_type_elem is None:
iq_type_elem = ET.SubElement(var, 'iq_type')
iq_type_elem.text = iq_type
# Вычисляем pt_type и iq_type
pt_type = var.findtext('pt_type')
if not pt_type:
pt_type = map_type_to_pt(var_type, name, typedef_map)
# Записываем pt_type в XML
pt_type_elem = var.find('pt_type')
if pt_type_elem is None:
pt_type_elem = ET.SubElement(var, 'pt_type')
pt_type_elem.text = pt_type
vars_list.append({ vars_list.append({
'name': name, 'name': name,
@ -78,6 +93,10 @@ def parse_vars(filename, typedef_map=None):
'static': var.findtext('static', 'false') == 'true', 'static': var.findtext('static', 'false') == 'true',
}) })
ET.indent(tree, space=" ", level=0)
# Сохраняем изменения в XML-файл
tree.write(filename, encoding='utf-8', xml_declaration=True)
return vars_list return vars_list
@ -159,6 +178,9 @@ def safe_parse_xml(xml_path):
except Exception as e: except Exception as e:
print(f"Неожиданная ошибка при чтении XML файла '{xml_path}': {e}") print(f"Неожиданная ошибка при чтении XML файла '{xml_path}': {e}")
return None, None return None, None
def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, depth=0): def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, depth=0):
if depth > 10: if depth > 10:
return [] return []
@ -178,7 +200,15 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
if field_name == 'type': if field_name == 'type':
continue continue
full_name = f"{prefix}.{field_name}" # Определяем разделитель между prefix и полем
if prefix.endswith('*'):
separator = '->'
# Для красоты можно убрать пробелы у указателя
# например, если prefix="ptr*" -> "ptr->field"
full_name = f"{prefix[:-1]}{separator}{field_name}"
else:
separator = '.'
full_name = f"{prefix}{separator}{field_name}"
if isinstance(field_value, dict): if isinstance(field_value, dict):
# Если вложенная структура — берем её имя типа из поля 'type' или пустую строку # Если вложенная структура — берем её имя типа из поля 'type' или пустую строку
@ -187,10 +217,14 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
'name': full_name, 'name': full_name,
'type': type_name, 'type': type_name,
'pt_type': '', 'pt_type': '',
'iq_type': '',
'return_type': '',
'file': var_attrs.get('file'), 'file': var_attrs.get('file'),
'extern': var_attrs.get('extern'), 'extern': var_attrs.get('extern'),
'static': var_attrs.get('static'), 'static': var_attrs.get('static'),
} }
if '*' in type_name and not full_name.endswith('*'):
full_name += '*'
# Рекурсивно раскрываем вложенные поля # Рекурсивно раскрываем вложенные поля
subchildren = expand_struct_recursively(full_name, field_value, structs, typedefs, var_attrs, depth + 1) subchildren = expand_struct_recursively(full_name, field_value, structs, typedefs, var_attrs, depth + 1)
if subchildren: if subchildren:
@ -205,6 +239,8 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
'name': full_name, 'name': full_name,
'type': field_value, 'type': field_value,
'pt_type': '', 'pt_type': '',
'iq_type': '',
'return_type': '',
'file': var_attrs.get('file'), 'file': var_attrs.get('file'),
'extern': var_attrs.get('extern'), 'extern': var_attrs.get('extern'),
'static': var_attrs.get('static'), 'static': var_attrs.get('static'),
@ -215,6 +251,7 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
return children return children
def expand_vars(vars_list, structs, typedefs): def expand_vars(vars_list, structs, typedefs):
""" """
Раскрывает структуры и массивы структур в деревья. Раскрывает структуры и массивы структур в деревья.
@ -228,6 +265,11 @@ def expand_vars(vars_list, structs, typedefs):
fields = structs.get(base_type) fields = structs.get(base_type)
if pt_type.startswith('pt_ptr_') and isinstance(fields, dict):
new_var = var.copy()
new_var['children'] = expand_struct_recursively(var['name']+'*', raw_type, structs, typedefs, var)
expanded.append(new_var)
if pt_type.startswith('pt_arr_') and isinstance(fields, dict): if pt_type.startswith('pt_arr_') and isinstance(fields, dict):
new_var = var.copy() new_var = var.copy()
new_var['children'] = expand_struct_recursively(var['name'], raw_type, structs, typedefs, var) new_var['children'] = expand_struct_recursively(var['name'], raw_type, structs, typedefs, var)

View File

@ -12,6 +12,7 @@ from scanVars import run_scan
from generateVars import run_generate from generateVars import run_generate
from setupVars import * from setupVars import *
from VariableSelector import * from VariableSelector import *
from VariableTable import VariableTableWidget, rows
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QApplication, QWidget, QTableWidget, QTableWidgetItem, QApplication, QWidget, QTableWidget, QTableWidgetItem,
@ -20,19 +21,9 @@ from PySide6.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QSizePolicy QDialog, QTreeWidget, QTreeWidgetItem, QSizePolicy
) )
from PySide6.QtGui import QTextCursor, QKeyEvent from PySide6.QtGui import QTextCursor, QKeyEvent
from PySide6.QtCore import Qt, QProcess, QObject, Signal, QTimer from PySide6.QtCore import Qt, QProcess, QObject, Signal, QSettings
class rows(IntEnum):
No = 0
include = 1
name = 2
type = 3
pt_type = 4
iq_type = 5
ret_type = 6
short_name = 7
class EmittingStream(QObject): class EmittingStream(QObject):
text_written = Signal(str) text_written = Signal(str)
@ -54,11 +45,12 @@ class EmittingStream(QObject):
self._buffer = "" self._buffer = ""
class ProcessOutputWindowDummy(QWidget): class ProcessOutputWindowDummy(QDialog):
def __init__(self, on_done_callback): def __init__(self, on_done_callback):
super().__init__() super().__init__()
self.setWindowTitle("Поиск переменных...") self.setWindowTitle("Поиск переменных...")
self.resize(600, 400) self.resize(600, 400)
self.setModal(True) # сделаем окно модальным
self.layout = QVBoxLayout(self) self.layout = QVBoxLayout(self)
self.output_edit = QTextEdit() self.output_edit = QTextEdit()
@ -75,7 +67,7 @@ class ProcessOutputWindowDummy(QWidget):
def __handle_done(self): def __handle_done(self):
if self._on_done_callback: if self._on_done_callback:
self._on_done_callback() self._on_done_callback()
self.close() self.accept() # закрыть диалог
def append_text(self, text): def append_text(self, text):
cursor = self.output_edit.textCursor() cursor = self.output_edit.textCursor()
@ -161,20 +153,6 @@ class VarEditor(QWidget):
self.btn_update_vars = QPushButton("Обновить данные о переменных") self.btn_update_vars = QPushButton("Обновить данные о переменных")
self.btn_update_vars.clicked.connect(self.update_vars_data) self.btn_update_vars.clicked.connect(self.update_vars_data)
# Таблица переменных
self.table = QTableWidget(len(self.vars_list), 8)
self.table.setHorizontalHeaderLabels([
'', # новый столбец
'En',
'Name',
'Origin Type',
'Pointer Type',
'IQ Type',
'Return Type',
'Short Name'
])
self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
# Кнопка сохранения # Кнопка сохранения
btn_save = QPushButton("Build") btn_save = QPushButton("Build")
btn_save.clicked.connect(self.save_build) btn_save.clicked.connect(self.save_build)
@ -183,7 +161,8 @@ class VarEditor(QWidget):
self.btn_add_vars = QPushButton("Add Variables") self.btn_add_vars = QPushButton("Add Variables")
self.btn_add_vars.clicked.connect(self.__open_variable_selector) self.btn_add_vars.clicked.connect(self.__open_variable_selector)
# Таблица
self.table = VariableTableWidget()
# Основной layout # Основной layout
layout = QVBoxLayout() layout = QVBoxLayout()
layout.addLayout(xml_layout) layout.addLayout(xml_layout)
@ -195,68 +174,9 @@ class VarEditor(QWidget):
layout.addLayout(source_output_layout) layout.addLayout(source_output_layout)
layout.addWidget(btn_save) layout.addWidget(btn_save)
header = self.table.horizontalHeader()
# Для остальных колонок — растяжение (Stretch), чтобы они заняли всю оставшуюся ширину
for col in range(self.table.columnCount()):
if col == self.table.columnCount() - 1:
header.setSectionResizeMode(col, QHeaderView.Stretch)
else:
header.setSectionResizeMode(col, QHeaderView.Interactive)
parent_widget = self.table.parentWidget()
if parent_widget:
w = parent_widget.width()
h = parent_widget.height()
viewport_width = self.table.viewport().width()
# Сделаем колонки с номерами фиксированной ширины
self.table.setColumnWidth(rows.No, 30)
self.table.setColumnWidth(rows.include, 30)
self.table.setColumnWidth(rows.pt_type, 85)
self.table.setColumnWidth(rows.iq_type, 85)
self.table.setColumnWidth(rows.ret_type, 85)
self.table.setColumnWidth(rows.name, 300)
self.table.setColumnWidth(rows.type, 100)
self.table.horizontalHeader().sectionResized.connect(self.on_section_resized)
self.setLayout(layout) self.setLayout(layout)
def on_section_resized(self, logicalIndex, oldSize, newSize):
if self._resizing:
return # предотвращаем рекурсию
min_width = 50
delta = newSize - oldSize
right_index = logicalIndex + 1
if right_index >= self.table.columnCount():
# Если правая колока - нет соседа, ограничиваем минимальную ширину
if newSize < min_width:
self._resizing = True
self.table.setColumnWidth(logicalIndex, min_width)
self._resizing = False
return
self._resizing = True
try:
right_width = self.table.columnWidth(right_index)
new_right_width = right_width - delta
# Если соседняя колонка станет уже минимальной - подкорректируем левую
if new_right_width < min_width:
new_right_width = min_width
newSize = oldSize + (right_width - min_width)
self.table.setColumnWidth(logicalIndex, newSize)
self.table.setColumnWidth(right_index, new_right_width)
finally:
self._resizing = False
def get_xml_path(self): def get_xml_path(self):
xml_path = self.xml_output_edit.text().strip() xml_path = self.xml_output_edit.text().strip()
@ -416,18 +336,17 @@ class VarEditor(QWidget):
else: else:
self.makefile_path = None self.makefile_path = None
if not self.structs_path: # --- structs_path из атрибута ---
# --- structs_path из атрибута --- structs_path = root.attrib.get('structs_path', '').strip()
structs_path = root.attrib.get('structs_path', '').strip() structs_path_full = make_absolute_path(structs_path, self.proj_path)
structs_path_full = make_absolute_path(structs_path, self.proj_path) if structs_path_full and os.path.isfile(structs_path_full):
if structs_path_full and os.path.isfile(structs_path_full): self.structs_path = structs_path_full
self.structs_path = structs_path_full self.structs, self.typedef_map = parse_structs(structs_path_full)
self.structs, self.typedef_map = parse_structs(structs_path_full) else:
else: self.structs_path = None
self.structs_path = None
self.vars_list = parse_vars(self.xml_path, self.typedef_map) self.vars_list = parse_vars(self.xml_path, self.typedef_map)
self.update_table() self.table.populate(self.vars_list, self.structs, self.write_to_xml)
except Exception as e: except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Ошибка при чтении XML:\n{e}") QMessageBox.warning(self, "Ошибка", f"Ошибка при чтении XML:\n{e}")
@ -528,7 +447,7 @@ class VarEditor(QWidget):
v['show_var'] = 'false' v['show_var'] = 'false'
break break
self.update_table() self.table.populate(self.vars_list, self.structs, self.write_to_xml)
def __open_variable_selector(self): def __open_variable_selector(self):
@ -542,102 +461,6 @@ class VarEditor(QWidget):
self.update() self.update()
def update_table(self):
self.type_options = list(dict.fromkeys(type_map.values()))
self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
filtered_vars = [v for v in self.vars_list if v.get('show_var', 'false') == 'true']
self.table.setRowCount(len(filtered_vars))
self.table.verticalHeader().setVisible(False)
for row, var in enumerate(filtered_vars):
# Добавляем номер строки в колонку No (0)
no_item = QTableWidgetItem(str(row))
no_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) # readonly
self.table.setItem(row, rows.No, no_item)
cb = QCheckBox()
enable_str = var.get('enable', 'false')
cb.setChecked(enable_str.lower() == 'true')
self.table.setCellWidget(row, rows.include, cb)
name_edit = QLineEdit(var['name'])
if var['type'] in self.structs:
completer = QCompleter(self.structs[var['type']].keys())
completer.setCaseSensitivity(Qt.CaseInsensitive)
name_edit.setCompleter(completer)
self.table.setCellWidget(row, rows.name, name_edit)
# Type (origin)
origin_type = var.get('type', '').strip()
origin_item = QTableWidgetItem(origin_type)
origin_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) # read-only
self.table.setItem(row, rows.type, origin_item)
pt_type_combo = QComboBox()
pt_type_combo.addItems(self.display_type_options)
internal_type = var['pt_type'].replace('pt_', '')
if internal_type in self.display_type_options:
pt_type_combo.setCurrentText(internal_type)
else:
pt_type_combo.addItem(internal_type)
pt_type_combo.setCurrentText(internal_type)
self.table.setCellWidget(row, rows.pt_type, pt_type_combo)
iq_combo = QComboBox()
iq_combo.addItems(iq_types)
iq_type = var['iq_type'].replace('t_', '')
if iq_type in iq_types:
iq_combo.setCurrentText(iq_type)
else:
iq_combo.addItem(iq_type)
iq_combo.setCurrentText(iq_type)
self.table.setCellWidget(row, rows.iq_type, iq_combo)
ret_combo = QComboBox()
ret_combo.addItems(iq_types)
self.table.setCellWidget(row, rows.ret_type, ret_combo)
short_name_edit = QLineEdit(var['name'])
self.table.setCellWidget(row, rows.short_name, short_name_edit)
cb.stateChanged.connect(self.write_to_xml)
name_edit.textChanged.connect(self.write_to_xml)
pt_type_combo.currentTextChanged.connect(self.write_to_xml)
iq_combo.currentTextChanged.connect(self.write_to_xml)
ret_combo.currentTextChanged.connect(self.write_to_xml)
short_name_edit.textChanged.connect(self.write_to_xml)
self.write_to_xml()
def read_table(self):
vars_data = []
for row in range(self.table.rowCount()):
cb = self.table.cellWidget(row, rows.include)
name_edit = self.table.cellWidget(row, rows.name)
pt_type_combo = self.table.cellWidget(row, rows.pt_type)
iq_combo = self.table.cellWidget(row, rows.iq_type)
ret_combo = self.table.cellWidget(row, rows.ret_type)
short_name_edit = self.table.cellWidget(row, rows.short_name)
origin_item = self.table.item(row, rows.type)
vars_data.append({
'show_var': True,
'enable': cb.isChecked() if cb else False,
'name': name_edit.text() if name_edit else '',
'pt_type': 'pt_' + pt_type_combo.currentText() if pt_type_combo else '',
'iq_type': iq_combo.currentText() if iq_combo else '',
'return_type': ret_combo.currentText() if ret_combo else '',
'shortname': short_name_edit.text() if short_name_edit else '',
'type': origin_item.text() if origin_item else '',
})
return vars_data
def write_to_xml(self): def write_to_xml(self):
self.update_all_paths() self.update_all_paths()
@ -682,7 +505,7 @@ class VarEditor(QWidget):
} }
# Читаем переменные из таблицы (активные/изменённые) # Читаем переменные из таблицы (активные/изменённые)
table_vars = {v['name']: v for v in self.read_table()} table_vars = {v['name']: v for v in self.table.read_data()}
# Все переменные (в том числе новые, которых нет в таблице) # Все переменные (в том числе новые, которых нет в таблице)
all_vars_by_name = {v['name']: v for v in self.vars_list} all_vars_by_name = {v['name']: v for v in self.vars_list}
@ -707,8 +530,11 @@ class VarEditor(QWidget):
el = ET.SubElement(parent, tag) el = ET.SubElement(parent, tag)
el.text = str(text) el.text = str(text)
set_sub_elem_text(var_elem, 'show_var', v.get('show_var', 'false')) show_var_val = str(v.get('show_var', 'false')).lower()
set_sub_elem_text(var_elem, 'enable', v.get('enable', 'false')) enable_val = str(v_table['enable'] if v_table and 'enable' in v_table else v.get('enable', 'false')).lower()
set_sub_elem_text(var_elem, 'show_var', show_var_val)
set_sub_elem_text(var_elem, 'enable', enable_val)
# Тут подтягиваем из таблицы, если есть, иначе из v # Тут подтягиваем из таблицы, если есть, иначе из v
shortname_val = v_table['shortname'] if v_table and 'shortname' in v_table else v.get('shortname', '') shortname_val = v_table['shortname'] if v_table and 'shortname' in v_table else v.get('shortname', '')

View File

@ -1,5 +1,5 @@
<?xml version="1.0" ?> <?xml version='1.0' encoding='utf-8'?>
<analysis proj_path="E:\.WORK\TMS\TMS_new_bus" makefile_path="E:\.WORK\TMS\TMS_new_bus\Debug\makefile" structs_path="E:\.WORK\TMS\TMS_new_bus\Src\DebugTools\structs.xml"> <analysis proj_path="F:/Work/Projects/TMS/TMS_new_bus" makefile_path="Debug/makefile" structs_path="Src/DebugTools/structs.xml">
<variables> <variables>
<var name="ADC0finishAddr"> <var name="ADC0finishAddr">
<show_var>false</show_var> <show_var>false</show_var>
@ -14,7 +14,7 @@
<static>false</static> <static>false</static>
</var> </var>
<var name="ADC0startAddr"> <var name="ADC0startAddr">
<show_var>false</show_var> <show_var>true</show_var>
<enable>true</enable> <enable>true</enable>
<shortname>ADC0startAddr</shortname> <shortname>ADC0startAddr</shortname>
<pt_type>pt_int16</pt_type> <pt_type>pt_int16</pt_type>
@ -407,7 +407,7 @@
<type>char[8][16]</type> <type>char[8][16]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="IN0finishAddr"> <var name="IN0finishAddr">
<show_var>false</show_var> <show_var>false</show_var>
@ -863,7 +863,7 @@
<type>int[12]</type> <type>int[12]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="biTemperatureWarnings"> <var name="biTemperatureWarnings">
<show_var>false</show_var> <show_var>false</show_var>
@ -875,7 +875,7 @@
<type>int[12]</type> <type>int[12]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="block_size_counter_fast"> <var name="block_size_counter_fast">
<show_var>false</show_var> <show_var>false</show_var>
@ -959,7 +959,7 @@
<type>int[12]</type> <type>int[12]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="bvTemperatureWarnings"> <var name="bvTemperatureWarnings">
<show_var>false</show_var> <show_var>false</show_var>
@ -971,7 +971,7 @@
<type>int[12]</type> <type>int[12]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="byte"> <var name="byte">
<show_var>false</show_var> <show_var>false</show_var>
@ -1151,7 +1151,7 @@
<type>char[4]</type> <type>char[4]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cmd_finish1"> <var name="cmd_finish1">
<show_var>false</show_var> <show_var>false</show_var>
@ -1163,7 +1163,7 @@
<type>char</type> <type>char</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cmd_finish2"> <var name="cmd_finish2">
<show_var>false</show_var> <show_var>false</show_var>
@ -1175,7 +1175,7 @@
<type>char</type> <type>char</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cmd_start"> <var name="cmd_start">
<show_var>false</show_var> <show_var>false</show_var>
@ -1187,7 +1187,7 @@
<type>char[5]</type> <type>char[5]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cmd_txt"> <var name="cmd_txt">
<show_var>false</show_var> <show_var>false</show_var>
@ -1199,7 +1199,7 @@
<type>char[4][8]</type> <type>char[4][8]</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="compress_size"> <var name="compress_size">
<show_var>false</show_var> <show_var>false</show_var>
@ -1283,7 +1283,7 @@
<type>unsigned int</type> <type>unsigned int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myXilinx/x_serial_bus.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myXilinx/x_serial_bus.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="crc_16_tab"> <var name="crc_16_tab">
<show_var>false</show_var> <show_var>false</show_var>
@ -1319,7 +1319,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/message_modbus.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/message_modbus.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cur_position_buf_modbus16_can"> <var name="cur_position_buf_modbus16_can">
<show_var>false</show_var> <show_var>false</show_var>
@ -1343,7 +1343,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/message_modbus.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/message_modbus.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="cycle"> <var name="cycle">
<show_var>false</show_var> <show_var>false</show_var>
@ -1367,7 +1367,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="data_to_umu1_8"> <var name="data_to_umu1_8">
<show_var>false</show_var> <show_var>false</show_var>
@ -1379,7 +1379,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="data_to_umu2_7f"> <var name="data_to_umu2_7f">
<show_var>false</show_var> <show_var>false</show_var>
@ -1391,7 +1391,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="data_to_umu2_8"> <var name="data_to_umu2_8">
<show_var>false</show_var> <show_var>false</show_var>
@ -1403,7 +1403,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/init_protect_levels.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="delta_capnum"> <var name="delta_capnum">
<show_var>false</show_var> <show_var>false</show_var>
@ -1451,7 +1451,7 @@
<type>DQ_TO_ALPHABETA</type> <type>DQ_TO_ALPHABETA</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/v_pwm24.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/v_pwm24.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="enable_can"> <var name="enable_can">
<show_var>false</show_var> <show_var>false</show_var>
@ -2039,7 +2039,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="koef_Base_stop_run"> <var name="koef_Base_stop_run">
<show_var>false</show_var> <show_var>false</show_var>
@ -2279,7 +2279,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="length"> <var name="length">
<show_var>false</show_var> <show_var>false</show_var>
@ -2375,7 +2375,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/PWMTMSHandle.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/PWMTMSHandle.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mPWM_b"> <var name="mPWM_b">
<show_var>false</show_var> <show_var>false</show_var>
@ -2387,7 +2387,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/PWMTMSHandle.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/PWMTMSHandle.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="m_PWM"> <var name="m_PWM">
<show_var>false</show_var> <show_var>false</show_var>
@ -2531,7 +2531,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_1000"> <var name="mzz_limit_1000">
<show_var>false</show_var> <show_var>false</show_var>
@ -2543,7 +2543,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_1100"> <var name="mzz_limit_1100">
<show_var>false</show_var> <show_var>false</show_var>
@ -2555,7 +2555,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_1200"> <var name="mzz_limit_1200">
<show_var>false</show_var> <show_var>false</show_var>
@ -2567,7 +2567,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_1400"> <var name="mzz_limit_1400">
<show_var>false</show_var> <show_var>false</show_var>
@ -2579,7 +2579,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_1500"> <var name="mzz_limit_1500">
<show_var>false</show_var> <show_var>false</show_var>
@ -2591,7 +2591,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_2000"> <var name="mzz_limit_2000">
<show_var>false</show_var> <show_var>false</show_var>
@ -2603,7 +2603,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="mzz_limit_500"> <var name="mzz_limit_500">
<show_var>false</show_var> <show_var>false</show_var>
@ -2615,7 +2615,7 @@
<type>int</type> <type>int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/modbus_read_table.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="new_cycle_fifo"> <var name="new_cycle_fifo">
<show_var>false</show_var> <show_var>false</show_var>
@ -3311,7 +3311,7 @@
<type>unsigned int</type> <type>unsigned int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/main22220.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/main22220.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="timePauseCAN_Messages"> <var name="timePauseCAN_Messages">
<show_var>false</show_var> <show_var>false</show_var>
@ -3323,7 +3323,7 @@
<type>unsigned int</type> <type>unsigned int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/main22220.c</file> <file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/main/main22220.c</file>
<extern>false</extern> <extern>false</extern>
<static>true</static> <static>True</static>
</var> </var>
<var name="time_alg"> <var name="time_alg">
<show_var>false</show_var> <show_var>false</show_var>
@ -3577,18 +3577,6 @@
<extern>false</extern> <extern>false</extern>
<static>false</static> <static>false</static>
</var> </var>
<var name="Bender.KOhms">
<show_var>true</show_var>
<enable>true</enable>
<shortname>Bender.KOhms</shortname>
<pt_type>pt_uint16</pt_type>
<iq_type>iq_none</iq_type>
<return_type>iq_none</return_type>
<type>unsigned int</type>
<file>Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/DebugTools/Src/myLibs/bender.c</file>
<extern>false</extern>
<static>false</static>
</var>
</variables> </variables>
<includes> <includes>
<file>Src/main/vector.h</file> <file>Src/main/vector.h</file>