Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "py_cpp_demangle"
version = "0.1.2"
authors = ["Ben Frederickson <[email protected]>"]
version = "0.1.3"
authors = ["Ben Frederickson <[email protected]>", "Andrew V. Teylu <[email protected]>"]
edition = "2021"

[lib]
Expand All @@ -10,6 +10,7 @@ crate-type = ["cdylib"]

[dependencies]
cpp_demangle = "0.4.0"
msvc-demangler = "0.9.0"

[dependencies.pyo3]
version = "0.17.3"
Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -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
Expand Down
23 changes: 16 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <http://github.com/gimli-rs/cpp_demangle>`_ by building
This package provides Python bindings for the Rust crate `cpp_demangle
<http://github.com/gimli-rs/cpp_demangle>`_ and for the Rust crate
`msvc_demangler <https://github.com/mstange/msvc-demangler-rust>`_ by building
a native Python extension using `PyO3 <https://github.com/pyO3/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.
<https://www.benfrederickson.com/writing-python-extensions-in-rust-using-pyo3/>`_

Expand All @@ -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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
34 changes: 27 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<String> {
fn demangle_itanium(mangled: String) -> PyResult<String> {
let symbol = ::cpp_demangle::Symbol::new(&mangled[..]).map_err(|error| {
exceptions::PyValueError::new_err(("Could not demangle symbol", error.to_string()))
})?;
Expand All @@ -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<String> {
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(())
}