cplus_demangle-0.1.2/.cargo_vcs_info.json0000644000000001120000000000100140100ustar { "git": { "sha1": "89b152bd1658bfa1ede8c54c2ae904000ff1fd59" } } cplus_demangle-0.1.2/.gitignore000064400000000000000000000000100072674642500146150ustar 00000000000000/target cplus_demangle-0.1.2/Cargo.toml0000644000000016540000000000100120220ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "cplus_demangle" version = "0.1.2" authors = ["Vivek Jain "] build = "build.rs" description = "Rust wrapper for GNU libiberty's cplus_demangle to demangle C++ symbols" readme = "README.md" keywords = ["demangle", "symbolicate", "c-plus-plus", "cpp"] license = "MIT OR Apache-2.0" repository = "https://github.com/viveksjain/rust_cplus_demangle" [dependencies.libc] version = "0.2" [build-dependencies.cc] version = "1.0" cplus_demangle-0.1.2/Cargo.toml.orig000064400000000000000000000010550072674642500155260ustar 00000000000000[package] name = "cplus_demangle" description = "Rust wrapper for GNU libiberty's cplus_demangle to demangle C++ symbols" version = "0.1.2" authors = ["Vivek Jain "] license = "MIT OR Apache-2.0" repository = "https://github.com/viveksjain/rust_cplus_demangle" keywords = ["demangle", "symbolicate", "c-plus-plus", "cpp"] readme = "README.md" edition = "2018" build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] libc = "0.2" [build-dependencies] cc = "1.0" cplus_demangle-0.1.2/README.md000064400000000000000000000015030072674642500141140ustar 00000000000000# cplus_demangle ## cplus_demangle [![crates.io](https://img.shields.io/crates/v/cplus_demangle)](https://crates.io/crates/cplus_demangle) [![docs.rs](https://docs.rs/cplus_demangle/badge.svg)](https://docs.rs/cplus_demangle/latest/cplus_demangle/) This library converts C++ mangled symbol names to human-readable strings. It is a safe Rust wrapper to GNU libiberty's C function `cplus_demangle`. I found it much faster and more robust than other Rust-native implementations that I found. ### Example Suppose you compile the following C++ program: ```cpp namespace test { void myfn(int x) { } } ``` In the resulting binary, the symbol that gets generated for `myfn` is `_ZN4test4myfnEi`. We can convert it back with this Rust code: ```rust assert_eq!(cplus_demangle::demangle("_ZN4test4myfnEi").unwrap(), "test::myfn(int)"); ``` cplus_demangle-0.1.2/build.rs000064400000000000000000000012170072674642500143040ustar 00000000000000fn main() { // docs.rs build env does not seem to have libiberty if let Ok(_) = std::env::var("DOCS_RS") { return; } cc::Build::new() .file("src/demangle.c") // Some distros (e.g. Ubuntu) have `demangle.h` under this folder, // others have it directly inside `/usr/include` which is in default // include path. This approach works across both. .include("/usr/include/libiberty") .compile("libdemangle.a"); // Cannot use #[link] macro in lib.rs because it adds -liberty before linking // with our libdemangle.a which will fail. println!("cargo:rustc-link-lib=iberty"); } cplus_demangle-0.1.2/src/demangle.c000064400000000000000000000006160072674642500153500ustar 00000000000000#include char* cplus_demangle_wrapper(const char* mangled_name, int show_params, int show_ansi) { // This is a simple wrapper solely to allow using the demangle macros // DMGL_PARAMS and DMGL_ANSI. int options = DMGL_NO_OPTS; if (show_params) { options |= DMGL_PARAMS; } if (show_ansi) { options |= DMGL_ANSI; } return cplus_demangle(mangled_name, options); } cplus_demangle-0.1.2/src/lib.rs000064400000000000000000000062360072674642500145500ustar 00000000000000//! # cplus_demangle //! [![crates.io](https://img.shields.io/crates/v/cplus_demangle)](https://crates.io/crates/cplus_demangle) [![docs.rs](https://docs.rs/cplus_demangle/badge.svg)](https://docs.rs/cplus_demangle/latest/cplus_demangle/) //! //! This library converts C++ mangled symbol names to human-readable strings. It is a safe Rust wrapper to GNU libiberty's C function `cplus_demangle`. //! //! ## Example //! Suppose you compile the following C++ program: //! ```cpp //! namespace test { //! void myfn(int x) { } //! } //! ``` //! //! In the resulting binary, the symbol that gets generated for `myfn` is `_ZN4test4myfnEi`. We can convert it back with this Rust code: //! ```rust //! assert_eq!(cplus_demangle::demangle("_ZN4test4myfnEi").unwrap(), "test::myfn(int)"); //! ``` use libc::{c_char, c_int}; use std::ffi::{CStr, CString}; extern "C" { fn cplus_demangle_wrapper( mangled_name: *const c_char, show_params: c_int, show_ansi: c_int, ) -> *mut c_char; } #[derive(Debug)] pub struct Error(&'static str); /// Description of options from demangle.h: /// ``` /// #define DMGL_PARAMS (1 << 0) /* Include function args */ /// #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ /// ``` pub struct Options { pub show_params: bool, pub show_ansi: bool, } impl Options { pub fn default() -> Options { Options { show_params: true, show_ansi: true, } } } /// Demangle the given name, with default options. pub fn demangle(mangled_name: &str) -> Result { demangle_with_options(mangled_name, Options::default()) } /// Demangle the given name with the specified options. /// /// Fails if: the name contains a null character, or demangling fails. pub fn demangle_with_options(mangled_name: &str, options: Options) -> Result { let mangled_name = match CString::new(mangled_name) { Ok(mangled_name) => mangled_name, Err(std::ffi::NulError { .. }) => return Err(Error("mangled_name contains null")), }; let result: *mut c_char = unsafe { cplus_demangle_wrapper( mangled_name.as_ptr(), options.show_params as i32, options.show_ansi as i32, ) }; if result.is_null() { // Unfortunately cplus_demangle appears to give us precisely 0 helpful // error info, we have to go with a generic message. return Err(Error("Failed to demangle")); } let demangled = unsafe { CStr::from_ptr(result) }; Ok(demangled.to_str().unwrap().to_owned()) } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!( crate::demangle("_ZNK5boost16cpp_regex_traitsIcE7isctypeEcj").unwrap(), "boost::cpp_regex_traits::isctype(char, unsigned int) const" ); assert_eq!( crate::demangle_with_options( "_ZNK5boost16cpp_regex_traitsIcE7isctypeEcj", crate::Options { show_params: false, show_ansi: true, } ) .unwrap(), "boost::cpp_regex_traits::isctype" ); } }