From b402085e85c371db4235aa94a41719d5926ae247 Mon Sep 17 00:00:00 2001 From: "Andrew V. Teylu" Date: Wed, 3 Apr 2024 14:59:40 +0100 Subject: [PATCH] Add support for the 'msvc-demangler' crate Signed-off-by: Andrew V. Teylu --- Cargo.toml | 5 +++-- LICENSE | 1 + README.rst | 23 ++++++++++++++++------- setup.py | 2 +- src/lib.rs | 34 +++++++++++++++++++++++++++------- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6401b55..8f42f29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "py_cpp_demangle" -version = "0.1.2" -authors = ["Ben Frederickson "] +version = "0.1.3" +authors = ["Ben Frederickson ", "Andrew V. Teylu "] edition = "2021" [lib] @@ -10,6 +10,7 @@ crate-type = ["cdylib"] [dependencies] cpp_demangle = "0.4.0" +msvc-demangler = "0.9.0" [dependencies.pyo3] version = "0.17.3" diff --git a/LICENSE b/LICENSE index 415b7b7..0688d34 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2016 Ben Frederickson +Copyright (c) 2023 Andrew V. Teylu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.rst b/README.rst index c7b85e5..a791e2b 100644 --- a/README.rst +++ b/README.rst @@ -6,11 +6,12 @@ py-cpp-demangle: Demangles C++ linker symbols A package for demangling C++ linker symbol strings -This package provides python bindings for the rust crate -`cpp_demangle `_ by building +This package provides Python bindings for the Rust crate `cpp_demangle +`_ and for the Rust crate +`msvc_demangler `_ by building a native Python extension using `PyO3 `_. -This is mainly an experiment in creating python extensions in Rust. +This is mainly an experiment in creating Python extensions in Rust. `A blog post about this is here. `_ @@ -24,16 +25,24 @@ To install pip install cpp-demangle -Building from source requires the nightly version of the rust compiler. +Building from source requires the nightly version of the Rust compiler. -This module exposes a single function that transforms C++ linker symbols to a human readable -representation. +This module exposes a two functions (one for Itanium and one for MSVC) which +transform C++ linker symbols to a human readable representation. .. code-block:: python - from cpp_demangle import demangle + from cpp_demangle import demangle_itanium print(demangle('_ZN7mangled3fooEd')) # prints 'mangled::foo(double)' + +.. code-block:: python + + from cpp_demangle import demangle_msvc + + print(demangle_msvc('??_0klass@@QEAAHH@Z')) + # prints 'public: int __cdecl klass::operator/=(int)' + Released under the MIT License diff --git a/setup.py b/setup.py index 10da346..165eff5 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ url='http://github.com/benfred/py-cpp-demangle/', description="A package for demangling C++ linker symbols", long_description=open("README.rst").read(), - version="0.1.2", + version="0.1.3", rust_extensions=[RustExtension('cpp_demangle', 'Cargo.toml', binding=Binding.PyO3)], test_suite="tests", license="MIT", diff --git a/src/lib.rs b/src/lib.rs index 6a38222..8a76096 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,5 @@ -use pyo3::prelude::*; use pyo3::exceptions; - - +use pyo3::prelude::*; // This defines a python module. pyo3 will copy the rust doc comment // below into a python docstring @@ -14,21 +12,29 @@ use pyo3::exceptions; /// /// Basic usage: /// -/// >>> demangle('_ZN7mangled3fooEd') +/// >>> demangle_itanium('_ZN7mangled3fooEd') /// 'mangled::foo(double)' /// +/// >>> demangle_msvc('??_0klass@@QEAAHH@Z') +/// 'public: int __cdecl klass::operator/=(int)' +/// /// Passing an invalid identifier will throw a ValueError: /// -/// >>> demangle('invalid c++ symbol') +/// >>> demangle_itanium('invalid c++ symbol') /// Traceback (most recent call last): /// ... /// ValueError: ('Could not demangle symbol', 'mangled symbol is not well-formed') +/// +/// >>> demangle_msvc('invalid C++ symbol') +/// Traceback (most recent call last): +/// ... +/// ValueError: ('Could not format demangled name as string', 'does not start with b\'?\' (offset: 0, remaining: "invalid C++ symbol")') #[pymodule] fn cpp_demangle(_py: Python, m: &PyModule) -> PyResult<()> { // This adds a function to the python module: - /// Demangles a mangled c++ linker symbol name and returns it as a string + /// Demangles a mangled Itanium ABI C++ linker symbol name and returns it as a string #[pyfn(m)] - fn demangle(mangled: String) -> PyResult { + fn demangle_itanium(mangled: String) -> PyResult { let symbol = ::cpp_demangle::Symbol::new(&mangled[..]).map_err(|error| { exceptions::PyValueError::new_err(("Could not demangle symbol", error.to_string())) })?; @@ -42,5 +48,19 @@ fn cpp_demangle(_py: Python, m: &PyModule) -> PyResult<()> { Ok(demangled) } + /// Demangles a mangled MSVC C++ linker symbol name and returns it as a string + #[pyfn(m)] + fn demangle_msvc(mangled: String) -> PyResult { + let flags = ::msvc_demangler::DemangleFlags::llvm(); + let demangled = ::msvc_demangler::demangle(&mangled[..], flags).map_err(|error| { + exceptions::PyValueError::new_err(( + "Could not format demangled name as string", + error.to_string(), + )) + })?; + + Ok(demangled) + } + Ok(()) }