добавить сортировщик для таблицы
This commit is contained in:
parent
dd57d5d64e
commit
8c652e8aa0
|
|
@ -34,6 +34,7 @@ if __name__ == "__main__":
|
|||
("kvs_pass3.py", [ast_file, csv_file], "3 проход"),
|
||||
("kvs_pass4.py", [csv_file], "4 проход"),
|
||||
("kvs_pass5.py", [csv_file], "5 проход"),
|
||||
("kvs_pass6.py", [csv_file], "6 проход"),
|
||||
("kvs_builder.py", [csv_file, elf_file], "Сборка ELF"),
|
||||
]
|
||||
|
||||
|
|
|
|||
131
kvs_pass6.py
Normal file
131
kvs_pass6.py
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Шестой проход КВС — сортировка CSV по адресам
|
||||
- Сортирует все записи по числовому значению адреса
|
||||
- Записи с адресом "BSS" помещает в конец (после всех реальных адресов)
|
||||
- Обеспечивает правильный порядок байтов в итоговом ELF-файле
|
||||
"""
|
||||
|
||||
import sys
|
||||
import csv
|
||||
|
||||
|
||||
def get_addr_value(addr_str):
|
||||
"""
|
||||
Преобразует адрес в число для сортировки
|
||||
BSS и пустые адреса отправляются в конец (большое число)
|
||||
"""
|
||||
if not addr_str or addr_str == '':
|
||||
return 999999999 # Пустые адреса в конец
|
||||
if addr_str == 'BSS':
|
||||
return 999999999 # BSS в самый конец (после всех реальных адресов)
|
||||
if addr_str.startswith('0x'):
|
||||
try:
|
||||
return int(addr_str, 16)
|
||||
except ValueError:
|
||||
return 999999999
|
||||
return 999999999
|
||||
|
||||
|
||||
def sort_csv_by_address(input_csv, output_csv):
|
||||
"""
|
||||
Сортирует CSV по адресам (числовым значениям)
|
||||
BSS и пустые адреса помещаются в конец
|
||||
|
||||
Args:
|
||||
input_csv: входной CSV файл
|
||||
output_csv: выходной CSV файл
|
||||
"""
|
||||
|
||||
print(f"\n=== ШЕСТОЙ ПРОХОД КВС: сортировка CSV ===")
|
||||
print(f"Чтение: {input_csv}")
|
||||
|
||||
# Читаем CSV
|
||||
with open(input_csv, 'r', encoding='utf-8') as f:
|
||||
reader = csv.DictReader(f, delimiter=';')
|
||||
fieldnames = reader.fieldnames
|
||||
rows = list(reader)
|
||||
|
||||
print(f"Найдено записей: {len(rows)}")
|
||||
|
||||
# Подсчёт статистики до сортировки
|
||||
bss_count = sum(1 for row in rows if row.get('адрес') == 'BSS')
|
||||
empty_count = sum(1 for row in rows if not row.get('адрес') or row.get('адрес') == '')
|
||||
normal_count = len(rows) - bss_count - empty_count
|
||||
|
||||
print(f" Обычных записей (с числовыми адресами): {normal_count}")
|
||||
print(f" BSS-записей: {bss_count}")
|
||||
print(f" Пустых адресов: {empty_count}")
|
||||
|
||||
# Сортировка
|
||||
def sort_key(row):
|
||||
addr = row.get('адрес', '')
|
||||
value = get_addr_value(addr)
|
||||
return (value, 0)
|
||||
|
||||
rows.sort(key=sort_key)
|
||||
|
||||
# Записываем отсортированный CSV
|
||||
with open(output_csv, 'w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=fieldnames, delimiter=';', restval='')
|
||||
writer.writeheader()
|
||||
writer.writerows(rows)
|
||||
|
||||
print(f"\n✅ CSV отсортирован и сохранён: {output_csv}")
|
||||
|
||||
# Показываем первые 10 адресов для проверки
|
||||
print("\n📊 Первые 10 адресов после сортировки:")
|
||||
for i, row in enumerate(rows[:10]):
|
||||
addr = row.get('адрес', '')
|
||||
seg = row.get('сегмент', '')
|
||||
source = row.get('исходная_команда', '')[:30]
|
||||
print(f" {i+1:2d}. {addr:12s} [{seg:10s}] {source}")
|
||||
|
||||
# Показываем последние 5 адресов (должны быть BSS)
|
||||
if bss_count > 0:
|
||||
print("\n📊 Последние 5 записей (BSS в конце):")
|
||||
for i, row in enumerate(rows[-5:]):
|
||||
addr = row.get('адрес', '')
|
||||
seg = row.get('сегмент', '')
|
||||
source = row.get('исходная_команда', '')[:30]
|
||||
print(f" {len(rows)-5+i+1:2d}. {addr:12s} [{seg:10s}] {source}")
|
||||
|
||||
# Проверка: убеждаемся, что после сортировки нет числовых адресов после BSS
|
||||
found_bss = False
|
||||
for row in rows:
|
||||
addr = row.get('адрес', '')
|
||||
if addr == 'BSS':
|
||||
found_bss = True
|
||||
elif found_bss and addr and addr != '' and addr.startswith('0x'):
|
||||
print(f"\n⚠️ ВНИМАНИЕ: Найден числовой адрес {addr} после BSS!")
|
||||
print(" Это может указывать на проблему в данных.")
|
||||
break
|
||||
else:
|
||||
if found_bss:
|
||||
print("\n✅ Проверка пройдена: все BSS-записи в конце, числовых адресов после них нет.")
|
||||
else:
|
||||
print("\n✅ BSS-записей не найдено.")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) not in (2, 3):
|
||||
print("Использование: python kvs_pass6.py <входной.csv> [выходной.csv]")
|
||||
print(" Если выходной не указан, перезаписывается входной файл")
|
||||
sys.exit(1)
|
||||
|
||||
input_csv = sys.argv[1]
|
||||
|
||||
# Определяем выходной файл
|
||||
if len(sys.argv) >= 3:
|
||||
output_csv = sys.argv[2]
|
||||
else:
|
||||
# По умолчанию: перезаписываем исходный файл
|
||||
output_csv = input_csv
|
||||
|
||||
sort_csv_by_address(input_csv, output_csv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue