├── .github └── workflows │ └── tools.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyleSettings.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler-explorer-tools.iml ├── copyright │ └── profiles_settings.xml ├── deployment.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLinters │ └── jshint.xml ├── libraries │ └── .gitignore ├── misc.xml ├── modules.xml ├── vcs.xml ├── watcherTasks.xml └── webResources.xml ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── Makefile ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── d ├── .gitignore ├── Makefile └── demangle.d ├── get_compilers.sh ├── haskell ├── .gitignore ├── Makefile └── demangle.hs └── rust ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── rustfilt.iml └── src └── main.rs /.github/workflows/tools.yml: -------------------------------------------------------------------------------- 1 | name: Tools CI 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | build-and-deploy: 7 | runs-on: ubuntu-20.04 8 | steps: 9 | - uses: actions/checkout@v1 10 | - uses: actions/cache@v2 11 | with: 12 | path: .compilers 13 | key: ${{ runner.os }}-compilers-${{ hashFiles('get_compilers.sh') }} 14 | restore-keys: | 15 | ${{ runner.os }}-compilers- 16 | - name: Install compilers 17 | run: make compilers 18 | - name: Build 19 | id: gh_dist 20 | run: make gh-dist 21 | - name: Deploy 22 | if: github.repository_owner == 'compiler-explorer' 23 | uses: jakejarvis/s3-sync-action@master 24 | with: 25 | args: --acl public-read --follow-symlinks 26 | env: 27 | AWS_S3_BUCKET: compiler-explorer 28 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 29 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 30 | SOURCE_DIR: out/dist-bin 31 | DEST_DIR: dist/tools/${{ steps.gh_dist.outputs.branch }} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | /node_modules 3 | newrelic_agent.log 4 | /.npm-updated 5 | /.node-bin 6 | *.vscode 7 | /out 8 | *.heapsnapshot 9 | etc/config/*.local.properties 10 | .compilers 11 | /nbproject 12 | *.bundle*.js 13 | *.map 14 | static/dist 15 | static/vs 16 | lib/storage/data 17 | f.out 18 | /.nyc_output 19 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | /.name 2 | /workspace.xml 3 | /xtextAutoBuilderState.xml 4 | -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler-explorer-tools.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | -------------------------------------------------------------------------------- /.idea/jsLinters/jshint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 85 | -------------------------------------------------------------------------------- /.idea/libraries/.gitignore: -------------------------------------------------------------------------------- 1 | Cargo__rustfilt_.xml 2 | Rust__rustfilt_.xml 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/webResources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in the repo. 5 | * @mattgodbolt 6 | 7 | # tartanllama 8 | haskell @TartanLlama 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | **Compiler Explorer** contributor covenant Code of Conduct. 4 | 5 | ## Our Pledge 6 | 7 | In the interest of fostering an open and welcoming environment, we as 8 | contributors and maintainers pledge to making participation in our project 9 | and our community a harassment-free experience for everyone, regardless of age, 10 | body size, disability, ethnicity, gender identity and expression, 11 | level of experience, nationality, personal appearance, race, religion, 12 | or sexual identity and orientation. 13 | 14 | ## Our Standards 15 | 16 | Examples of behavior that contributes to creating a positive environment include: 17 | 18 | * Using welcoming and inclusive language. 19 | * Being respectful of differing viewpoints and experiences. 20 | * Gracefully accepting constructive criticism. 21 | * Focusing on what is best for the community. 22 | * Showing empathy towards other community members. 23 | 24 | Examples of **unacceptable** behavior by participants include: 25 | 26 | * The use of sexualized language or imagery and unwelcome sexual attention or 27 | advances. 28 | * Trolling, insulting/derogatory comments, and personal or political attacks. 29 | * Public or private harassment. 30 | * Publishing others' private information, such as a physical or electronic 31 | address, without explicit permission. 32 | * Other conduct which could reasonably be considered inappropriate in a 33 | professional setting. 34 | 35 | ## Our Responsibilities 36 | 37 | Project maintainers are responsible for clarifying the standards of acceptable 38 | behavior and are expected to take appropriate and fair corrective action in 39 | response to any instances of unacceptable behavior. 40 | 41 | Project maintainers have the right and responsibility to remove, edit, or 42 | reject comments, commits, code, wiki edits, issues, and other contributions 43 | that are not aligned to this Code of Conduct, or to ban 44 | temporarily or permanently any contributor for other behaviors that they deem 45 | inappropriate, threatening, offensive, or harmful. 46 | 47 | ## Scope 48 | 49 | This Code of Conduct applies both within project spaces and in public spaces 50 | when an individual is representing the project or its community. Examples of 51 | representing a project or community include using an official project e-mail 52 | address, posting via an official social media account, or acting as 53 | an appointed representative at an online or offline event. 54 | Representation of a project may be further defined and clarified by project 55 | maintainers. 56 | 57 | ## Enforcement 58 | 59 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 60 | reported by contacting the project owner at 61 | [matt@godbolt.org](mailto:matt@godbolt.org). The project team will review 62 | and investigate all complaints, and will respond in a way that it deems 63 | appropriate to the circumstances. The project team is obligated to maintain 64 | confidentiality with regard to the reporter of an incident. Further details of 65 | specific enforcement policies may be posted separately. 66 | 67 | Project maintainers who do not follow or enforce the Code of Conduct in good 68 | faith may face temporary or permanent repercussions as determined by other 69 | members of the project's leadership. 70 | 71 | ## Attribution 72 | 73 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 74 | version 1.4, available at [contributor-covenant.org/version/1/4][version] 75 | 76 | [homepage]: https://www.contributor-covenant.org/ 77 | [version]: https://www.contributor-covenant.org/version/1/4/ 78 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Compiler Explorer 2 | 3 | First of, if you're reading this: thank you! Even considering contributing to 4 | **Compiler Explorer** is very much appreciated! 5 | Before we go too far, an apology: **Compiler Explorer** grew out of a bit of 6 | hacky JavaScript into a pretty large and well-used project pretty quickly. 7 | Not all the code was originally well-written or well-tested. 8 | Please be forgiving of that, and be ready to help in improving that. 9 | 10 | **Compiler Explorer** follows a [Code of Conduct](CODE_OF_CONDUCT.md) which 11 | aims to foster an open and welcoming environment. 12 | 13 | This is a set of tools mainly for demangling code. Most of the interesting stuff is in 14 | the [main repository](https://github.com/mattgodbolt/compiler-explorer). 15 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | - [Matt Godbolt](https://xania.org) 2 | - [Rubén Rincón](https://github.com/RabsRincon) 3 | - [Patrick Quist](https://github.com/partouf) 4 | - [Simon Brand](https://blog.tartanllama.xyz/) 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: dist 2 | COMPILERS:=$(shell pwd)/.compilers 3 | PATH:=$(COMPILERS)/rust/bin/:$(PATH) 4 | 5 | help: # with thanks to Ben Rady 6 | @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' 7 | 8 | export XZ_OPT=-1 -T 0 9 | 10 | .PHONY: clean run haskell-support d-support rust-support compilers 11 | .PHONY: dist demanglers gh-dist 12 | demanglers: haskell-support d-support rust-support 13 | d-support: compilers 14 | $(MAKE) -C d GDC=$(COMPILERS)/gdc/x86_64-pc-linux-gnu/bin/gdc 15 | 16 | compilers: 17 | ./get_compilers.sh 18 | 19 | haskell-support: compilers 20 | $(MAKE) -C haskell GHC=$(COMPILERS)/ghc/bin/ghc 21 | 22 | CARGO=$(COMPILERS)/rust/bin/cargo 23 | rust/bin/rustfilt: rust/src/main.rs rust/Cargo.lock rust/Cargo.toml compilers 24 | cd rust && $(CARGO) build --release 25 | rust-support: rust/bin/rustfilt 26 | 27 | clean: ## Cleans up everything 28 | rm -rf out 29 | [ -x $(CARGO) ] && cd rust && $(CARGO) clean 30 | $(MAKE) -C d clean 31 | $(MAKE) -C haskell clean 32 | 33 | HASH := $(shell git rev-parse HEAD) 34 | dist: demanglers ## Creates a distribution 35 | rm -rf out/demanglers 36 | mkdir -p out/demanglers 37 | mkdir -p out/demanglers/d 38 | cp d/demangle out/demanglers/d/ 39 | mkdir -p out/demanglers/haskell 40 | cp haskell/demangle out/demanglers/haskell 41 | ldd out/demanglers/haskell/demangle \ 42 | | sed -n -e 's/.*=> \([^ ]*\) .*/\1/p' \ 43 | | egrep -v '^/lib' \ 44 | | xargs cp -t out/demanglers/haskell/ 45 | cd rust && $(CARGO) install --path . --root $(shell pwd)/out/demanglers/rust --force 46 | echo ${HASH} > out/demanglers/git_hash 47 | 48 | gh-dist: dist ## Creates a distribution as if we were running on github CI 49 | echo "branch=$${GITHUB_REF#refs/heads/}" >> "${GITHUB_OUTPUT}" 50 | tar -Jcf /tmp/ce-build.tar.xz -C out demanglers 51 | rm -rf out/dist-bin 52 | mkdir -p out/dist-bin 53 | mv /tmp/ce-build.tar.xz out/dist-bin/gh-${GITHUB_RUN_NUMBER}.tar.xz 54 | echo ${HASH} > out/dist-bin/gh-${GITHUB_RUN_NUMBER}.txt 55 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Tools CI](https://github.com/compiler-explorer/tools/actions/workflows/tools.yml/badge.svg)](https://github.com/compiler-explorer/tools/actions/workflows/tools.yml) 2 | 3 | Compiler Explorer Tools 4 | ------------ 5 | 6 | These are tools (mainly demanglers) for the [Compiler Explorer](https://github.com/mattgodbolt/compiler-explorer) project. 7 | -------------------------------------------------------------------------------- /d/.gitignore: -------------------------------------------------------------------------------- 1 | demangle 2 | demangle.o 3 | -------------------------------------------------------------------------------- /d/Makefile: -------------------------------------------------------------------------------- 1 | GDC:=gdc 2 | demangle: demangle.d 3 | $(GDC) -O2 $< -o $@ 4 | 5 | clean: 6 | rm -f demangle.o demangle 7 | -------------------------------------------------------------------------------- /d/demangle.d: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2017, Matt Godbolt 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are met: 6 | // 7 | // * Redistributions of source code must retain the above copyright notice, 8 | // this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 17 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | // POSSIBILITY OF SUCH DAMAGE. 24 | 25 | import std.stdio; 26 | static import std.demangle; 27 | import std.regex; 28 | 29 | auto idRegex = ctRegex!("\\b_?_D[0-9a-zA-Z_]+\\b", "g"); 30 | 31 | void main() { 32 | string dem(Captures!(string) m) { 33 | if (m.hit[1] == '_') { 34 | // Could be a symbolname with double leading underscore 35 | auto result = std.demangle.demangle(m.hit[1..$]); 36 | if (result == m.hit[1..$]) 37 | { 38 | return m.hit; 39 | } 40 | else 41 | { 42 | return result; 43 | } 44 | } 45 | else 46 | { 47 | return std.demangle.demangle(m.hit); 48 | } 49 | } 50 | 51 | foreach (line; stdin.byLine()) { 52 | string s2 = cast(string)line; 53 | auto s = replaceAll!(dem)(s2, idRegex); 54 | writeln(s); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /get_compilers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eux 4 | 5 | OPT=$(pwd)/.compilers 6 | mkdir -p "${OPT}" 7 | mkdir -p "${OPT}/tmp" 8 | 9 | fetch() { 10 | # shellcheck disable=SC2154 11 | curl "${http_proxy:+--proxy "${http_proxy}"}" -sL "$*" 12 | } 13 | 14 | get_ghc() { 15 | local VER=$1 16 | local DIR=ghc-$VER 17 | 18 | pushd "${OPT}/tmp" 19 | fetch "https://downloads.haskell.org/~ghc/${VER}/ghc-${VER}-x86_64-deb10-linux.tar.xz" | tar Jxf - 20 | cd "${OPT}/tmp/ghc-${VER}" 21 | ./configure --prefix="${OPT}/ghc" 22 | make install 23 | rm -rf "${OPT}/ghc/lib/ghc-${VER}"/Cabal* 24 | rm -rf "${OPT}/ghc/share" 25 | popd 26 | rm -rf "${OPT}/tmp/ghc-${VER}" 27 | } 28 | 29 | get_gdc() { 30 | vers=$1 31 | build=$2 32 | mkdir "${OPT}/gdc" 33 | pushd "${OPT}/gdc" 34 | fetch "https://gdcproject.org/downloads/binaries/${vers}/x86_64-linux-gnu/gdc-${vers}+${build}.tar.xz" | tar Jxf - 35 | popd 36 | } 37 | 38 | do_rust_install() { 39 | local DIR=$1 40 | pushd "${OPT}/tmp" 41 | fetch "http://static.rust-lang.org/dist/${DIR}.tar.gz" | tar zxf - 42 | cd "${DIR}" 43 | ./install.sh --prefix="${OPT}/rust" --without=rust-docs 44 | popd 45 | rm -rf "${OPT}/tmp/${DIR}" 46 | } 47 | 48 | install_new_rust() { 49 | local NAME=$1 50 | do_rust_install "rust-${NAME}-x86_64-unknown-linux-gnu" 51 | } 52 | 53 | CE_GHC_VER=9.0.1 54 | if ! ("${OPT}/ghc/bin/ghc" --version | grep -q -F "${CE_GHC_VER}"); then 55 | get_ghc "${CE_GHC_VER}" 56 | fi 57 | 58 | CE_GDC_VER=5.2.0 59 | if ! ("${OPT}/gdc/x86_64-pc-linux-gnu/bin/gdc" --version | grep -q -F "${CE_GDC_VER}"); then 60 | get_gdc "${CE_GDC_VER}" 2.066.1 61 | fi 62 | 63 | CE_RUST_VERSION=1.55.0 64 | if ! ("${OPT}"/rust/bin/rustc -V | grep -q -F "${CE_RUST_VERSION}"); then 65 | install_new_rust "${CE_RUST_VERSION}" 66 | fi 67 | -------------------------------------------------------------------------------- /haskell/.gitignore: -------------------------------------------------------------------------------- 1 | *.hi 2 | *.o 3 | *.so* 4 | demangle 5 | -------------------------------------------------------------------------------- /haskell/Makefile: -------------------------------------------------------------------------------- 1 | GHC:=ghc 2 | demangle: demangle.hs 3 | $(GHC) -package ghc -dynamic demangle.hs -optl-Wl,-rpath,'$$ORIGIN' 4 | 5 | clean: 6 | rm -f demangle.o demangle demangle.hi *.so* 7 | -------------------------------------------------------------------------------- /haskell/demangle.hs: -------------------------------------------------------------------------------- 1 | import GHC.Utils.Encoding as Encoding 2 | import Data.Char 3 | 4 | main :: IO () 5 | main = do 6 | inp <- getContents 7 | let encoded = lines inp 8 | decoded = map Encoding.zDecodeString encoded in 9 | mapM_ putStrLn decoded 10 | -------------------------------------------------------------------------------- /rust/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | bin 3 | .crates.toml 4 | -------------------------------------------------------------------------------- /rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "0.7.18" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "lazy_static" 16 | version = "1.4.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 19 | 20 | [[package]] 21 | name = "memchr" 22 | version = "2.4.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" 25 | 26 | [[package]] 27 | name = "regex" 28 | version = "1.5.5" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 31 | dependencies = [ 32 | "aho-corasick", 33 | "memchr", 34 | "regex-syntax", 35 | ] 36 | 37 | [[package]] 38 | name = "regex-syntax" 39 | version = "0.6.25" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 42 | 43 | [[package]] 44 | name = "rustc-demangle" 45 | version = "0.1.20" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" 48 | 49 | [[package]] 50 | name = "rustfilt" 51 | version = "0.1.2" 52 | dependencies = [ 53 | "lazy_static", 54 | "regex", 55 | "rustc-demangle", 56 | ] 57 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustfilt" 3 | version = "0.1.2" 4 | authors = ["Matt Godbolt "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | lazy_static = "1.4.0" 9 | regex = "1.5.5" 10 | rustc-demangle = "0.1.20" 11 | -------------------------------------------------------------------------------- /rust/rustfilt.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /rust/src/main.rs: -------------------------------------------------------------------------------- 1 | #![deny(rust_2018_idioms)] 2 | 3 | use lazy_static::lazy_static; 4 | 5 | use regex::Captures; 6 | use regex::Regex; 7 | use rustc_demangle::demangle; 8 | use std::io; 9 | use std::io::prelude::*; 10 | 11 | fn demangle_line(line: &str) -> String { 12 | lazy_static! { 13 | static ref RE: Regex = Regex::new(r"[_a-zA-Z$][_a-zA-Z$0-9.]*").unwrap(); 14 | } 15 | 16 | RE.replace_all(line, |caps: &Captures<'_>| { 17 | format!("{:#}", demangle(caps.get(0).unwrap().as_str())) 18 | }) 19 | .to_string() 20 | } 21 | 22 | #[cfg(test)] 23 | mod tests { 24 | use super::demangle_line; 25 | 26 | #[test] 27 | fn passes_text() { 28 | assert_eq!( 29 | demangle_line("mo fo\tboom hello "), 30 | "mo fo\tboom hello " 31 | ); 32 | } 33 | 34 | #[test] 35 | fn demangles() { 36 | assert_eq!( 37 | demangle_line("_ZN7example4main17h0db00b8b32acffd5E:"), 38 | "example::main:" 39 | ); 40 | } 41 | 42 | #[test] 43 | fn handles_mid_demangling() { 44 | assert_eq!( 45 | demangle_line(" lea rax, [rip + _ZN55_$LT$$RF$$u27$a$u20$T$u20$as$u20$core..fmt..Display$GT$3fmt17h510ed05e72307174E]"), 46 | " lea rax, [rip + <&\'a T as core::fmt::Display>::fmt]", 47 | ); 48 | } 49 | 50 | #[test] 51 | fn handles_call_plt() { 52 | assert_eq!( 53 | demangle_line(" call _ZN3std2io5stdio6_print17he48522be5b0a80d9E@PLT"), 54 | " call std::io::stdio::_print@PLT" 55 | ); 56 | } 57 | } 58 | 59 | fn main() { 60 | let stdin = io::stdin(); 61 | 62 | for line in stdin.lock().lines() { 63 | println!("{}", demangle_line(&line.unwrap())); 64 | } 65 | } 66 | --------------------------------------------------------------------------------