From 92141b2344a594c2d8f162d493783d0e46f4194b Mon Sep 17 00:00:00 2001 From: angie Date: Sat, 16 Sep 2023 13:23:01 -0300 Subject: [PATCH] start bindings --- .github/workflows/CI.yml.txt | 120 +++++++++++++++++++++++++++++++++++ Cargo.toml | 3 + pyproject.toml | 10 +++ src/rs/file.rs | 18 +++++- src/rs/lib.rs | 8 ++- src/rs/mapfile.rs | 25 ++++++-- src/rs/segment.rs | 14 +++- src/rs/symbol.rs | 8 +++ 8 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/CI.yml.txt diff --git a/.github/workflows/CI.yml.txt b/.github/workflows/CI.yml.txt new file mode 100644 index 0000000..f5796a5 --- /dev/null +++ b/.github/workflows/CI.yml.txt @@ -0,0 +1,120 @@ +# This file is autogenerated by maturin v1.2.3 +# To update, run +# +# maturin generate-ci github +# +name: CI + +on: + push: + branches: + - main + - master + tags: + - '*' + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + linux: + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + manylinux: auto + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + windows: + runs-on: windows-latest + strategy: + matrix: + target: [x64, x86] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + architecture: ${{ matrix.target }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + macos: + runs-on: macos-latest + strategy: + matrix: + target: [x86_64, aarch64] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist + - name: Upload sdist + uses: actions/upload-artifact@v3 + with: + name: wheels + path: dist + + release: + name: Release + runs-on: ubuntu-latest + if: "startsWith(github.ref, 'refs/tags/')" + needs: [linux, windows, macos, sdist] + steps: + - uses: actions/download-artifact@v3 + with: + name: wheels + - name: Publish to PyPI + uses: PyO3/maturin-action@v1 + env: + MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + with: + command: upload + args: --non-interactive --skip-existing * diff --git a/Cargo.toml b/Cargo.toml index 9f84416..b11baf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] +name = "mapfile_parser" path = "src/rs/lib.rs" +crate-type = ["cdylib"] [dependencies] regex = "1.9.5" +pyo3 = "0.19.0" diff --git a/pyproject.toml b/pyproject.toml index 4879fca..9203d92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,11 @@ description = "Map file parser library focusing decompilation projects" readme = "README.md" requires-python = ">=3.7" dynamic = ["dependencies"] +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] [project.urls] "Homepage" = "https://github.com/Decompollaborate/mapfile_parser" @@ -16,9 +21,14 @@ dynamic = ["dependencies"] [build-system] requires = ["hatchling", "hatch-requirements-txt"] build-backend = "hatchling.build" +# requires = ["maturin>=1.2,<2.0"] +# build-backend = "maturin" [tool.hatch.metadata.hooks.requirements_txt] files = ["requirements.txt"] [tool.cibuildwheel] skip = ["cp36-*"] + +[tool.maturin] +features = ["pyo3/extension-module"] diff --git a/src/rs/file.rs b/src/rs/file.rs index 9a3fee1..776ea96 100644 --- a/src/rs/file.rs +++ b/src/rs/file.rs @@ -4,19 +4,33 @@ use crate::{utils, symbol}; #[derive(Debug, Clone)] +#[pyo3::prelude::pyclass(module = "mapfile_parser", unsendable)] pub struct File { + #[pyo3(get, set)] pub filepath: std::path::PathBuf, + + #[pyo3(get, set)] pub vram: u64, + + #[pyo3(get, set)] pub size: u64, + + #[pyo3(get, set)] pub section_type: String, + + #[pyo3(get, set)] pub vrom: Option, + + //#[pyo3(get, set)] pub symbols: Vec, } +#[pyo3::prelude::pymethods] impl File { - pub fn new(filepath: &std::path::PathBuf, vram: u64, size: u64, section_type: &String) -> Self { + #[new] + pub fn new(filepath: std::path::PathBuf, vram: u64, size: u64, section_type: &str) -> Self { File { - filepath: filepath.into(), + filepath: filepath, vram: vram, size: size, section_type: section_type.into(), diff --git a/src/rs/lib.rs b/src/rs/lib.rs index 4bafbe4..a54a0a0 100644 --- a/src/rs/lib.rs +++ b/src/rs/lib.rs @@ -7,6 +7,12 @@ pub mod file; pub mod symbol; pub mod utils; +#[pyo3::prelude::pymodule] +fn mapfile_parser(_py: pyo3::prelude::Python<'_>, m: &pyo3::prelude::PyModule) -> pyo3::prelude::PyResult<()> { + m.add_class::()?; + Ok(()) +} + pub fn add(left: usize, right: usize) -> usize { left + right } @@ -26,6 +32,6 @@ mod tests { #[test] fn w0_000_map() { let mut map = MapFile::new(); - map.read_map_file(&"tests/maps/w0_000.map".to_string()); + map.read_map_file("tests/maps/w0_000.map"); } } diff --git a/src/rs/mapfile.rs b/src/rs/mapfile.rs index 08ab086..85b1f61 100644 --- a/src/rs/mapfile.rs +++ b/src/rs/mapfile.rs @@ -3,17 +3,25 @@ use std::{vec, fs::File, io::{BufReader, Read}, path::PathBuf}; -use regex; +//use regex; use crate::{utils, segment, file, symbol}; #[derive(Debug, Clone)] +// TODO: sequence? +// TODO: maybe not use unsendable? +#[pyo3::prelude::pyclass(module = "mapfile_parser", unsendable)] pub struct MapFile { + #[pyo3(get)] segments_list: Vec, + + #[pyo3(get, set)] pub debugging: bool, } +#[pyo3::prelude::pymethods] impl MapFile { + #[new] pub fn new() -> Self { MapFile { segments_list: Vec::new(), @@ -21,8 +29,11 @@ impl MapFile { } } + //#[getter] + //fn segments_list(&self) -> + // TODO: look for equivalent to pathlib.Path - pub fn read_map_file(&mut self, map_path: &String) { + pub fn read_map_file(&mut self, map_path: &str) { // TODO: maybe move somewhere else? let regex_fileDataEntry = regex::Regex::new(r"^\s+(?P
\.[^\s]+)\s+(?P0x[^\s]+)\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); let regex_functionEntry = regex::Regex::new(r"^\s+(?P0x[^\s]+)\s+(?P[^\s]+)$").unwrap(); @@ -42,11 +53,11 @@ impl MapFile { // TODO: "Linker script and memory map" stuff let mut temp_segment_list: Vec = Vec::new(); - temp_segment_list.push(segment::Segment::new(&"$nosegment".into(), 0, 0, 0)); + temp_segment_list.push(segment::Segment::new("$nosegment".into(), 0, 0, 0)); { let current_segment = temp_segment_list.last_mut().unwrap(); - current_segment.files_list.push(file::File::new(&"".into(), 0, 0, &"".into())); + current_segment.files_list.push(file::File::new("".into(), 0, 0, "".into())); } let mut in_file = false; @@ -95,7 +106,7 @@ impl MapFile { in_file = true; let current_segment = temp_segment_list.last_mut().unwrap(); - current_segment.files_list.push(file::File::new(&filepath, vram, size, §ion_type.into())); + current_segment.files_list.push(file::File::new(filepath, vram, size, section_type.into())); } } else if let Some(segment_entry_match) = regex_segmentEntry.captures(line) { let mut name = &segment_entry_match["name"]; @@ -113,7 +124,7 @@ impl MapFile { println!(" vram: {vram:X}"); println!(" size: {size:X}"); println!(" vrom: {vrom:X}"); - temp_segment_list.push(segment::Segment::new(&name.into(), vram, size, vrom)); + temp_segment_list.push(segment::Segment::new(name.into(), vram, size, vrom)); //current_segment = temp_segment_list.last_mut().unwrap(); } else if let Some(fill_match) = regex_fill.captures(line) { // Make a dummy file to handle *fill* @@ -137,7 +148,7 @@ impl MapFile { println!("fill info:"); println!(" {size:X}"); - current_segment.files_list.push(file::File::new(&filepath, vram, size, §ion_type)); + current_segment.files_list.push(file::File::new(filepath, vram, size, §ion_type)); } } diff --git a/src/rs/segment.rs b/src/rs/segment.rs index b18070f..ff65350 100644 --- a/src/rs/segment.rs +++ b/src/rs/segment.rs @@ -4,16 +4,28 @@ use crate::{utils, file}; #[derive(Debug, Clone)] +#[pyo3::prelude::pyclass(module = "mapfile_parser", unsendable)] pub struct Segment { + #[pyo3(get, set)] pub name: String, + + #[pyo3(get, set)] pub vram: u64, + + #[pyo3(get, set)] pub size: u64, + + #[pyo3(get, set)] pub vrom: u64, + + #[pyo3(get, set)] pub files_list: Vec, } +#[pyo3::prelude::pymethods] impl Segment { - pub fn new(name: &String, vram: u64, size: u64, vrom: u64) -> Self { + #[new] + pub fn new(name: String, vram: u64, size: u64, vrom: u64) -> Self { Segment { name: name.into(), vram: vram, diff --git a/src/rs/symbol.rs b/src/rs/symbol.rs index 27d43ad..1be2064 100644 --- a/src/rs/symbol.rs +++ b/src/rs/symbol.rs @@ -4,10 +4,18 @@ use crate::{utils, file}; #[derive(Debug, Clone)] +#[pyo3::prelude::pyclass(module = "mapfile_parser", unsendable)] pub struct Symbol { + #[pyo3(get, set)] pub name: String, + + #[pyo3(get, set)] pub vram: u64, + + #[pyo3(get, set)] pub size: Option, + + #[pyo3(get, set)] pub vrom: Option, }