diff --git a/.travis.yml b/.travis.yml index a6a565c..a7f0fb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,3 +49,6 @@ matrix: # Benching should only happen on nightly with --release. - rust: nightly env: GIMLI_JOB="bench" GIMLI_PROFILE="--release" + # alloc requires nightly. + - rust: nightly + env: GIMLI_JOB="build" GIMLI_PROFILE="--no-default-features" GIMLI_FEATURES="alloc" diff --git a/Cargo.toml b/Cargo.toml index 73dc627..a42bfbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,20 +15,20 @@ exclude = ["/benches/*", "/fixtures/*"] travis-ci = { repository = "gimli-rs/addr2line" } [dependencies] -gimli = "0.16" -fallible-iterator = "0.1" -object = "0.9" -intervaltree = "0.2" -smallvec = "0.6" +gimli = { version = "0.16", default-features = false } +fallible-iterator = { version = "0.1", default-features = false } +object = { version = "0.9", default-features = false } +intervaltree = { version = "0.2", default-features = false } +smallvec = { version = "0.6", default-features = false } lazycell = "1.0" rustc-demangle = { version = "0.1", optional = true } -cpp_demangle = { version = "0.2", optional = true } +cpp_demangle = { version = "0.2", default-features = false, optional = true } [dev-dependencies] memmap = "0.6" clap = "2" backtrace = "0.3" -findshlibs = "0.3" +findshlibs = "0.4" rustc-test = "0.3" [profile.release] @@ -37,7 +37,9 @@ debug = true debug = true [features] -default = ["rustc-demangle", "cpp_demangle"] +default = ["rustc-demangle", "cpp_demangle", "std"] +std = ["gimli/std", "intervaltree/std", "object/std", "smallvec/std"] +alloc = ["gimli/alloc"] [[test]] name = "output_equivalence" diff --git a/examples/addr2line.rs b/examples/addr2line.rs index d250103..53d2f93 100644 --- a/examples/addr2line.rs +++ b/examples/addr2line.rs @@ -47,9 +47,9 @@ fn print_loc(loc: &Option, basenames: bool, llvm: bool) { if let Some(ref loc) = *loc { let file = loc.file.as_ref().unwrap(); let path = if basenames { - Path::new(file.file_name().unwrap()) + Path::new(Path::new(file).file_name().unwrap()) } else { - file + Path::new(file) }; print!("{}:", path.display()); if llvm { diff --git a/src/lib.rs b/src/lib.rs index 84581ce..01f2bba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,17 @@ //! which is parsed using [`gimli`](https://github.com/gimli-rs/gimli). The example CLI //! wrapper also uses symbol table information provided by the `object` crate. #![deny(missing_docs)] +#![no_std] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +#[cfg(feature = "std")] +#[macro_use] +extern crate std; + +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(not(feature = "std"))] +extern crate core as std; #[cfg(feature = "cpp_demangle")] extern crate cpp_demangle; @@ -34,11 +45,18 @@ extern crate object; extern crate rustc_demangle; extern crate smallvec; -use std::path::PathBuf; +#[cfg(feature = "std")] +mod alloc { + pub use std::{borrow, rc, string, vec}; +} + +use alloc::borrow::Cow; +use alloc::rc::Rc; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; + use std::cmp::Ordering; -use std::borrow::Cow; use std::u64; -use std::rc::Rc; use fallible_iterator::FallibleIterator; use intervaltree::{Element, IntervalTree}; @@ -438,7 +456,7 @@ impl FallibleIterator for WrapRangeIter { /// A source location. pub struct Location { /// The file name. - pub file: Option, + pub file: Option, /// The line number. pub line: Option, /// The column number. @@ -562,23 +580,34 @@ where &self, file: &gimli::FileEntry, lines: &Lines, - ) -> Result { + ) -> Result { let mut path = if let Some(ref comp_dir) = self.comp_dir { - PathBuf::from(comp_dir.to_string_lossy()?.as_ref()) + String::from(comp_dir.to_string_lossy()?.as_ref()) } else { - PathBuf::new() + String::new() }; if let Some(directory) = file.directory(lines.lnp.header()) { - path.push(directory.to_string_lossy()?.as_ref()); + path_push(&mut path, directory.to_string_lossy()?.as_ref()); } - path.push(file.path_name().to_string_lossy()?.as_ref()); + path_push(&mut path, file.path_name().to_string_lossy()?.as_ref()); Ok(path) } } +fn path_push(path: &mut String, p: &str) { + if p.starts_with("/") { + *path = p.to_string(); + } else { + if !path.ends_with("/") { + *path += "/"; + } + *path += p; + } +} + type Error = gimli::Error; fn name_attr<'abbrev, 'unit, R>(