From 06cfdc4b6fdcbc8ffafb654d5c34e48353749533 Mon Sep 17 00:00:00 2001 From: angie Date: Fri, 29 Sep 2023 16:31:12 -0300 Subject: [PATCH] almost everything --- src/mapfile_parser/mapfile_parser.pyi | 35 +++++++++ src/rs/mapfile.rs | 103 +++++++++++++++++++------- 2 files changed, 112 insertions(+), 26 deletions(-) diff --git a/src/mapfile_parser/mapfile_parser.pyi b/src/mapfile_parser/mapfile_parser.pyi index 9206397..ed23abb 100644 --- a/src/mapfile_parser/mapfile_parser.pyi +++ b/src/mapfile_parser/mapfile_parser.pyi @@ -170,4 +170,39 @@ class MapFile: def readMapFile(self, mapPath: Path) -> None: ... + def filterBySectionType(self, sectionType: str) -> MapFile: ... + def getEveryFileExceptSectionType(self, sectionType: str) -> MapFile: ... + def findSymbolByName(self, symName: str) -> FoundSymbolInfo|None: ... + def findSymbolByVramOrVrom(self, address: int) -> FoundSymbolInfo|None: ... + + def findLowestDifferingSymbol(self, otherMapFile: MapFile) -> tuple[Symbol, File, Symbol|None]|None: ... + + def mixFolders(self) -> MapFile: ... + + # def getProgress(self, asmPath: Path, nonmatchings: Path, aliases: dict[str, str]=dict(), pathIndex: int=2) -> tuple[ProgressStats, dict[str, ProgressStats]]: ... + + # Useful for finding bss reorders + def compareFilesAndSymbols(self, otherMapFile: MapFile, *, checkOtherOnSelf: bool=True) -> MapsComparisonInfo: ... + + def toCsv(self, printVram: bool=True, skipWithoutSymbols: bool=True) -> str: ... + def toCsvSymbols(self) -> str: ... + + # def printAsCsv(self, printVram: bool=True, skipWithoutSymbols: bool=True): ... + # def printSymbolsCsv(self): ... + + # def toJson(self, humanReadable: bool=True) -> dict[str, Any]: ... + + def copySegmentList(self) -> list[Segment]: + """Returns a copy (not a reference) of the internal segment list""" + + def setSegmentList(self, newList: list[Segment]) -> None: + """Replaces the internal segment list with a copy of `newList`""" + + def appendSegment(self, segment: Segment) -> None: + """Appends a copy of `segment` into the internal segment list""" + + def __iter__(self) -> Generator[Segment, None, None]: ... + def __getitem__(self, index) -> Segment: ... + def __setitem__(self, index, segment: Segment): ... + def __len__(self) -> int: ... diff --git a/src/rs/mapfile.rs b/src/rs/mapfile.rs index dbd404f..a91102b 100644 --- a/src/rs/mapfile.rs +++ b/src/rs/mapfile.rs @@ -2,9 +2,10 @@ /* SPDX-License-Identifier: MIT */ use std::{fs::File, path::PathBuf, io::Read}; +use std::fmt::Write; use pyo3::prelude::*; -//use regex; +use regex::*; use crate::{utils, segment, file, symbol, found_symbol_info, maps_comparison_info, symbol_comparison_info}; @@ -36,12 +37,12 @@ impl MapFile { #[pyo3(name = "readMapFile")] pub fn read_map_file(&mut self, map_path: PathBuf) { // TODO: maybe move somewhere else? - let regex_file_data_entry = regex::Regex::new(r"^\s+(?P
\.[^\s]+)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); - let regex_function_entry = regex::Regex::new(r"^\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); + let regex_file_data_entry = Regex::new(r"^\s+(?P
\.[^\s]+)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); + let regex_function_entry = Regex::new(r"^\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); // regex_function_entry = re.compile(r"^\s+(?P0x[^\s]+)\s+(?P[^\s]+)((\s*=\s*(?P.+))?)$") - let regex_label = regex::Regex::new(r"^(?P\.?L[0-9A-F]{8})$").unwrap(); - let regex_fill = regex::Regex::new(r"^\s+(?P\*[^\s\*]+\*)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s*$").unwrap(); - let regex_segment_entry = regex::Regex::new(r"(?P([^\s]+)?)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s+(?P(load address)?)\s+(?P0x[^\s]+)$").unwrap(); + let regex_label = Regex::new(r"^(?P\.?L[0-9A-F]{8})$").unwrap(); + let regex_fill = Regex::new(r"^\s+(?P\*[^\s\*]+\*)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s*$").unwrap(); + let regex_segment_entry = Regex::new(r"(?P([^\s]+)?)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s+(?P(load address)?)\s+(?P0x[^\s]+)$").unwrap(); @@ -399,7 +400,7 @@ impl MapFile { */ - #[pyo3(name = "compareFilesAndSymbols", signature= (other_map_file, *, check_other_on_self=true))] + #[pyo3(name = "compareFilesAndSymbols", signature=(other_map_file, *, check_other_on_self=true))] /// Useful for finding bss reorders pub fn compare_files_and_symbols(&self, other_map_file: MapFile, check_other_on_self: bool) -> maps_comparison_info::MapsComparisonInfo { let mut comp_info = maps_comparison_info::MapsComparisonInfo::new(); @@ -442,21 +443,32 @@ impl MapFile { } - /* - def toCsv(self, printVram: bool=True, skipWithoutSymbols: bool=True) -> str: - ret = File.toCsvHeader(printVram=printVram) + "\n" - for segment in self._segmentsList: - ret += segment.toCsv(printVram=printVram, skipWithoutSymbols=skipWithoutSymbols) - return ret + #[pyo3(name = "toCsv", signature=(print_vram=true, skip_without_symbols=true))] + pub fn to_csv(&self, print_vram: bool, skip_without_symbols: bool) -> String { + let mut ret = file::File::to_csv_header(print_vram) + "\n"; - def toCsvSymbols(self) -> str: - ret = f"File," + Symbol.toCsvHeader() + "\n" + for segment in &self.segments_list { + ret += &segment.to_csv(print_vram, skip_without_symbols); + } - for segment in self._segmentsList: - ret += segment.toCsvSymbols() - return ret + ret + } + + #[pyo3(name = "toCsvSymbols")] + pub fn to_ssv_symbols(&self) -> String { + let mut ret = String::new(); + write!(ret, "File,{}\n", symbol::Symbol::to_csv_header()).unwrap(); + for segment in &self.segments_list { + ret += &segment.to_csv_symbols(); + } + + ret + } + + + /* def printAsCsv(self, printVram: bool=True, skipWithoutSymbols: bool=True): print(self.toCsv(printVram=printVram, skipWithoutSymbols=skipWithoutSymbols), end="") @@ -472,16 +484,55 @@ impl MapFile { "segments": segmentsList } return result + */ + + #[pyo3(name = "copySegmentList")] + fn copy_segment_list(&self) -> Vec { + self.segments_list.clone() + } + #[pyo3(name = "setSegmentList")] + fn set_segment_list(&mut self, new_list: Vec) { + self.segments_list = new_list; + } - def __iter__(self) -> Generator[Segment, None, None]: - for file in self._segmentsList: - yield file + #[pyo3(name = "appendSegment")] + fn append_segment(&mut self, segment: segment::Segment) { + self.segments_list.push(segment); + } - def __getitem__(self, index) -> Segment: - return self._segmentsList[index] + fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { + let iter = SegmentVecIter { + inner: slf.segments_list.clone().into_iter(), + }; + Py::new(slf.py(), iter) + } - def __len__(self) -> int: - return len(self._segmentsList) - */ + fn __getitem__(&self, index: usize) -> segment::Segment { + self.segments_list[index].clone() + } + + fn __setitem__(&mut self, index: usize, element: segment::Segment) { + self.segments_list[index] = element; + } + + fn __len__(&self) -> usize { + self.segments_list.len() + } +} + +#[pyclass] +struct SegmentVecIter { + inner: std::vec::IntoIter, +} + +#[pymethods] +impl SegmentVecIter { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { + slf + } + + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { + slf.inner.next() + } }