mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
std: Deprecate std::old_io::fs
This commit deprecates the majority of std::old_io::fs in favor of std::fs and its new functionality. Some functions remain non-deprecated but are now behind a feature gate called `old_fs`. These functions will be deprecated once suitable replacements have been implemented. The compiler has been migrated to new `std::fs` and `std::path` APIs where appropriate as part of this change.
This commit is contained in:
parent
3b3bb0e682
commit
95d904625b
@ -273,11 +273,13 @@ compiler-docs: $(COMPILER_DOC_TARGETS)
|
|||||||
trpl: doc/book/index.html
|
trpl: doc/book/index.html
|
||||||
|
|
||||||
doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
|
doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
|
||||||
|
@$(call E, rustbook: $@)
|
||||||
$(Q)rm -rf doc/book
|
$(Q)rm -rf doc/book
|
||||||
$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
|
$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
|
||||||
|
|
||||||
style: doc/style/index.html
|
style: doc/style/index.html
|
||||||
|
|
||||||
doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
|
doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
|
||||||
|
@$(call E, rustbook: $@)
|
||||||
$(Q)rm -rf doc/style
|
$(Q)rm -rf doc/style
|
||||||
$(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
|
$(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
|
||||||
|
@ -11,6 +11,7 @@ pub use self::Mode::*;
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
@ -68,13 +69,13 @@ pub struct Config {
|
|||||||
pub run_lib_path: String,
|
pub run_lib_path: String,
|
||||||
|
|
||||||
// The rustc executable
|
// The rustc executable
|
||||||
pub rustc_path: Path,
|
pub rustc_path: PathBuf,
|
||||||
|
|
||||||
// The clang executable
|
// The clang executable
|
||||||
pub clang_path: Option<Path>,
|
pub clang_path: Option<PathBuf>,
|
||||||
|
|
||||||
// The llvm binaries path
|
// The llvm binaries path
|
||||||
pub llvm_bin_path: Option<Path>,
|
pub llvm_bin_path: Option<PathBuf>,
|
||||||
|
|
||||||
// The valgrind path
|
// The valgrind path
|
||||||
pub valgrind_path: Option<String>,
|
pub valgrind_path: Option<String>,
|
||||||
@ -84,13 +85,13 @@ pub struct Config {
|
|||||||
pub force_valgrind: bool,
|
pub force_valgrind: bool,
|
||||||
|
|
||||||
// The directory containing the tests to run
|
// The directory containing the tests to run
|
||||||
pub src_base: Path,
|
pub src_base: PathBuf,
|
||||||
|
|
||||||
// The directory where programs should be built
|
// The directory where programs should be built
|
||||||
pub build_base: Path,
|
pub build_base: PathBuf,
|
||||||
|
|
||||||
// Directory for auxiliary libraries
|
// Directory for auxiliary libraries
|
||||||
pub aux_base: Path,
|
pub aux_base: PathBuf,
|
||||||
|
|
||||||
// The name of the stage being built (stage1, etc)
|
// The name of the stage being built (stage1, etc)
|
||||||
pub stage_id: String,
|
pub stage_id: String,
|
||||||
@ -105,7 +106,7 @@ pub struct Config {
|
|||||||
pub filter: Option<String>,
|
pub filter: Option<String>,
|
||||||
|
|
||||||
// Write out a parseable log of tests that were run
|
// Write out a parseable log of tests that were run
|
||||||
pub logfile: Option<Path>,
|
pub logfile: Option<PathBuf>,
|
||||||
|
|
||||||
// A command line to prefix program execution with,
|
// A command line to prefix program execution with,
|
||||||
// for running under valgrind
|
// for running under valgrind
|
||||||
@ -133,7 +134,7 @@ pub struct Config {
|
|||||||
pub lldb_version: Option<String>,
|
pub lldb_version: Option<String>,
|
||||||
|
|
||||||
// Path to the android tools
|
// Path to the android tools
|
||||||
pub android_cross_path: Path,
|
pub android_cross_path: PathBuf,
|
||||||
|
|
||||||
// Extra parameter to run adb on arm-linux-androideabi
|
// Extra parameter to run adb on arm-linux-androideabi
|
||||||
pub adb_path: String,
|
pub adb_path: String,
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(os)]
|
||||||
|
#![feature(io)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(net)]
|
||||||
|
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
@ -31,8 +36,9 @@ extern crate getopts;
|
|||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
use std::old_io;
|
use std::old_io;
|
||||||
use std::old_io::fs;
|
use std::path::{Path, PathBuf};
|
||||||
use std::thunk::Thunk;
|
use std::thunk::Thunk;
|
||||||
use getopts::{optopt, optflag, reqopt};
|
use getopts::{optopt, optflag, reqopt};
|
||||||
use common::Config;
|
use common::Config;
|
||||||
@ -114,9 +120,9 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
|||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
|
fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf {
|
||||||
match m.opt_str(nm) {
|
match m.opt_str(nm) {
|
||||||
Some(s) => Path::new(s),
|
Some(s) => PathBuf::new(&s),
|
||||||
None => panic!("no option (=path) found for {}", nm),
|
None => panic!("no option (=path) found for {}", nm),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,10 +137,10 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
|||||||
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
|
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
|
||||||
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
|
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
|
||||||
rustc_path: opt_path(matches, "rustc-path"),
|
rustc_path: opt_path(matches, "rustc-path"),
|
||||||
clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)),
|
clang_path: matches.opt_str("clang-path").map(|s| PathBuf::new(&s)),
|
||||||
valgrind_path: matches.opt_str("valgrind-path"),
|
valgrind_path: matches.opt_str("valgrind-path"),
|
||||||
force_valgrind: matches.opt_present("force-valgrind"),
|
force_valgrind: matches.opt_present("force-valgrind"),
|
||||||
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)),
|
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::new(&s)),
|
||||||
src_base: opt_path(matches, "src-base"),
|
src_base: opt_path(matches, "src-base"),
|
||||||
build_base: opt_path(matches, "build-base"),
|
build_base: opt_path(matches, "build-base"),
|
||||||
aux_base: opt_path(matches, "aux-base"),
|
aux_base: opt_path(matches, "aux-base"),
|
||||||
@ -142,7 +148,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
|
|||||||
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
|
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
|
||||||
run_ignored: matches.opt_present("ignored"),
|
run_ignored: matches.opt_present("ignored"),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
|
logfile: matches.opt_str("logfile").map(|s| PathBuf::new(&s)),
|
||||||
runtool: matches.opt_str("runtool"),
|
runtool: matches.opt_str("runtool"),
|
||||||
host_rustcflags: matches.opt_str("host-rustcflags"),
|
host_rustcflags: matches.opt_str("host-rustcflags"),
|
||||||
target_rustcflags: matches.opt_str("target-rustcflags"),
|
target_rustcflags: matches.opt_str("target-rustcflags"),
|
||||||
@ -276,9 +282,9 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
|
|||||||
debug!("making tests from {:?}",
|
debug!("making tests from {:?}",
|
||||||
config.src_base.display());
|
config.src_base.display());
|
||||||
let mut tests = Vec::new();
|
let mut tests = Vec::new();
|
||||||
let dirs = fs::readdir(&config.src_base).unwrap();
|
let dirs = fs::read_dir(&config.src_base).unwrap();
|
||||||
for file in &dirs {
|
for file in dirs {
|
||||||
let file = file.clone();
|
let file = file.unwrap().path();
|
||||||
debug!("inspecting file {:?}", file.display());
|
debug!("inspecting file {:?}", file.display());
|
||||||
if is_test(config, &file) {
|
if is_test(config, &file) {
|
||||||
let t = make_test(config, &file, || {
|
let t = make_test(config, &file, || {
|
||||||
@ -301,7 +307,7 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool {
|
|||||||
_ => vec!(".rc".to_string(), ".rs".to_string())
|
_ => vec!(".rc".to_string(), ".rs".to_string())
|
||||||
};
|
};
|
||||||
let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string());
|
let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string());
|
||||||
let name = testfile.filename_str().unwrap();
|
let name = testfile.file_name().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
let mut valid = false;
|
let mut valid = false;
|
||||||
|
|
||||||
@ -337,9 +343,9 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
|
|||||||
|
|
||||||
// Try to elide redundant long paths
|
// Try to elide redundant long paths
|
||||||
fn shorten(path: &Path) -> String {
|
fn shorten(path: &Path) -> String {
|
||||||
let filename = path.filename_str();
|
let filename = path.file_name().unwrap().to_str();
|
||||||
let p = path.dir_path();
|
let p = path.parent().unwrap();
|
||||||
let dir = p.filename_str();
|
let dir = p.file_name().unwrap().to_str();
|
||||||
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
|
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,19 +354,17 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
|
|||||||
|
|
||||||
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
||||||
let config = (*config).clone();
|
let config = (*config).clone();
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
let testfile = testfile.to_path_buf();
|
||||||
let testfile = testfile.as_str().unwrap().to_string();
|
|
||||||
test::DynTestFn(Thunk::new(move || {
|
test::DynTestFn(Thunk::new(move || {
|
||||||
runtest::run(config, testfile)
|
runtest::run(config, &testfile)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
||||||
let config = (*config).clone();
|
let config = (*config).clone();
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
let testfile = testfile.to_path_buf();
|
||||||
let testfile = testfile.as_str().unwrap().to_string();
|
|
||||||
test::DynMetricFn(box move |mm: &mut test::MetricMap| {
|
test::DynMetricFn(box move |mm: &mut test::MetricMap| {
|
||||||
runtest::run_metrics(config, testfile, mm)
|
runtest::run_metrics(config, &testfile, mm)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
use self::WhichLine::*;
|
use self::WhichLine::*;
|
||||||
|
|
||||||
use std::old_io::{BufferedReader, File};
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
pub struct ExpectedError {
|
pub struct ExpectedError {
|
||||||
pub line: uint,
|
pub line: uint,
|
||||||
@ -29,7 +32,7 @@ enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) }
|
|||||||
/// //~| ERROR message two for that same line.
|
/// //~| ERROR message two for that same line.
|
||||||
// Load any test directives embedded in the file
|
// Load any test directives embedded in the file
|
||||||
pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
|
pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
|
||||||
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
|
let rdr = BufReader::new(File::open(testfile).unwrap());
|
||||||
|
|
||||||
// `last_nonfollow_error` tracks the most recently seen
|
// `last_nonfollow_error` tracks the most recently seen
|
||||||
// line with an error template that did not use the
|
// line with an error template that did not use the
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use common::Config;
|
use common::Config;
|
||||||
use common;
|
use common;
|
||||||
@ -23,7 +27,7 @@ pub struct TestProps {
|
|||||||
pub run_flags: Option<String>,
|
pub run_flags: Option<String>,
|
||||||
// If present, the name of a file that this test should match when
|
// If present, the name of a file that this test should match when
|
||||||
// pretty-printed
|
// pretty-printed
|
||||||
pub pp_exact: Option<Path>,
|
pub pp_exact: Option<PathBuf>,
|
||||||
// Modules from aux directory that should be compiled
|
// Modules from aux directory that should be compiled
|
||||||
pub aux_builds: Vec<String> ,
|
pub aux_builds: Vec<String> ,
|
||||||
// Environment settings to use during execution
|
// Environment settings to use during execution
|
||||||
@ -62,7 +66,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
|
|||||||
let mut pretty_mode = None;
|
let mut pretty_mode = None;
|
||||||
let mut pretty_compare_only = false;
|
let mut pretty_compare_only = false;
|
||||||
let mut forbid_output = Vec::new();
|
let mut forbid_output = Vec::new();
|
||||||
iter_header(testfile, |ln| {
|
iter_header(testfile, &mut |ln| {
|
||||||
match parse_error_pattern(ln) {
|
match parse_error_pattern(ln) {
|
||||||
Some(ep) => error_patterns.push(ep),
|
Some(ep) => error_patterns.push(ep),
|
||||||
None => ()
|
None => ()
|
||||||
@ -219,7 +223,7 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let val = iter_header(testfile, |ln| {
|
let val = iter_header(testfile, &mut |ln| {
|
||||||
!parse_name_directive(ln, "ignore-test") &&
|
!parse_name_directive(ln, "ignore-test") &&
|
||||||
!parse_name_directive(ln, &ignore_target(config)) &&
|
!parse_name_directive(ln, &ignore_target(config)) &&
|
||||||
!parse_name_directive(ln, &ignore_stage(config)) &&
|
!parse_name_directive(ln, &ignore_stage(config)) &&
|
||||||
@ -232,12 +236,8 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
|
|||||||
!val
|
!val
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_header<F>(testfile: &Path, mut it: F) -> bool where
|
fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool {
|
||||||
F: FnMut(&str) -> bool,
|
let rdr = BufReader::new(File::open(testfile).unwrap());
|
||||||
{
|
|
||||||
use std::old_io::{BufferedReader, File};
|
|
||||||
|
|
||||||
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
|
|
||||||
for ln in rdr.lines() {
|
for ln in rdr.lines() {
|
||||||
// Assume that any directives will be found before the first
|
// Assume that any directives will be found before the first
|
||||||
// module or function. This doesn't seem to be an optimization
|
// module or function. This doesn't seem to be an optimization
|
||||||
@ -322,12 +322,12 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> {
|
fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> {
|
||||||
match parse_name_value_directive(line, "pp-exact") {
|
match parse_name_value_directive(line, "pp-exact") {
|
||||||
Some(s) => Some(Path::new(s)),
|
Some(s) => Some(PathBuf::new(&s)),
|
||||||
None => {
|
None => {
|
||||||
if parse_name_directive(line, "pp-exact") {
|
if parse_name_directive(line, "pp-exact") {
|
||||||
testfile.filename().map(|s| Path::new(s))
|
testfile.file_name().map(|s| PathBuf::new(s))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::old_io::process::{ProcessExit, Command, Process, ProcessOutput};
|
use std::process::{ExitStatus, Command, Child, Output, Stdio};
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::dynamic_lib::DynamicLibrary;
|
use std::dynamic_lib::DynamicLibrary;
|
||||||
|
|
||||||
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
|
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
|
||||||
@ -25,10 +26,10 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
|
|||||||
let var = DynamicLibrary::envvar();
|
let var = DynamicLibrary::envvar();
|
||||||
let newpath = DynamicLibrary::create_path(&path);
|
let newpath = DynamicLibrary::create_path(&path);
|
||||||
let newpath = String::from_utf8(newpath).unwrap();
|
let newpath = String::from_utf8(newpath).unwrap();
|
||||||
cmd.env(var.to_string(), newpath);
|
cmd.env(var, &newpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
|
pub struct Result {pub status: ExitStatus, pub out: String, pub err: String}
|
||||||
|
|
||||||
pub fn run(lib_path: &str,
|
pub fn run(lib_path: &str,
|
||||||
prog: &str,
|
prog: &str,
|
||||||
@ -38,10 +39,13 @@ pub fn run(lib_path: &str,
|
|||||||
input: Option<String>) -> Option<Result> {
|
input: Option<String>) -> Option<Result> {
|
||||||
|
|
||||||
let mut cmd = Command::new(prog);
|
let mut cmd = Command::new(prog);
|
||||||
cmd.args(args);
|
cmd.args(args)
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped());
|
||||||
add_target_env(&mut cmd, lib_path, aux_path);
|
add_target_env(&mut cmd, lib_path, aux_path);
|
||||||
for (key, val) in env {
|
for (key, val) in env {
|
||||||
cmd.env(key, val);
|
cmd.env(&key, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
match cmd.spawn() {
|
match cmd.spawn() {
|
||||||
@ -49,13 +53,13 @@ pub fn run(lib_path: &str,
|
|||||||
if let Some(input) = input {
|
if let Some(input) = input {
|
||||||
process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
|
process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
let ProcessOutput { status, output, error } =
|
let Output { status, stdout, stderr } =
|
||||||
process.wait_with_output().unwrap();
|
process.wait_with_output().unwrap();
|
||||||
|
|
||||||
Some(Result {
|
Some(Result {
|
||||||
status: status,
|
status: status,
|
||||||
out: String::from_utf8(output).unwrap(),
|
out: String::from_utf8(stdout).unwrap(),
|
||||||
err: String::from_utf8(error).unwrap()
|
err: String::from_utf8(stderr).unwrap()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
Err(..) => None
|
Err(..) => None
|
||||||
@ -67,13 +71,16 @@ pub fn run_background(lib_path: &str,
|
|||||||
aux_path: Option<&str>,
|
aux_path: Option<&str>,
|
||||||
args: &[String],
|
args: &[String],
|
||||||
env: Vec<(String, String)> ,
|
env: Vec<(String, String)> ,
|
||||||
input: Option<String>) -> Option<Process> {
|
input: Option<String>) -> Option<Child> {
|
||||||
|
|
||||||
let mut cmd = Command::new(prog);
|
let mut cmd = Command::new(prog);
|
||||||
cmd.args(args);
|
cmd.args(args)
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped());
|
||||||
add_target_env(&mut cmd, lib_path, aux_path);
|
add_target_env(&mut cmd, lib_path, aux_path);
|
||||||
for (key, val) in env {
|
for (key, val) in env {
|
||||||
cmd.env(key, val);
|
cmd.env(&key, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
match cmd.spawn() {
|
match cmd.spawn() {
|
||||||
|
@ -11,35 +11,30 @@
|
|||||||
use self::TargetLocation::*;
|
use self::TargetLocation::*;
|
||||||
|
|
||||||
use common::Config;
|
use common::Config;
|
||||||
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
|
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
|
||||||
use common::{Codegen, DebugInfoLldb};
|
use common::{Codegen, DebugInfoLldb, DebugInfoGdb};
|
||||||
use errors;
|
use errors;
|
||||||
use header::TestProps;
|
use header::TestProps;
|
||||||
use header;
|
use header;
|
||||||
use procsrv;
|
use procsrv;
|
||||||
use util::logv;
|
use util::logv;
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use util;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
use std::old_io::File;
|
|
||||||
use std::old_io::fs::PathExtensions;
|
|
||||||
use std::old_io::fs;
|
|
||||||
use std::old_io::net::tcp;
|
|
||||||
use std::old_io::process::ProcessExit;
|
|
||||||
use std::old_io::process;
|
|
||||||
use std::old_io::timer;
|
|
||||||
use std::old_io;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::fmt;
|
||||||
|
use std::fs::{self, File};
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
use std::net::TcpStream;
|
||||||
|
use std::old_io::timer;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Command, Output, ExitStatus};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::string::String;
|
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use test::MetricMap;
|
use test::MetricMap;
|
||||||
|
|
||||||
pub fn run(config: Config, testfile: String) {
|
pub fn run(config: Config, testfile: &Path) {
|
||||||
match &*config.target {
|
match &*config.target {
|
||||||
|
|
||||||
"arm-linux-androideabi" | "aarch64-linux-android" => {
|
"arm-linux-androideabi" | "aarch64-linux-android" => {
|
||||||
@ -55,12 +50,11 @@ pub fn run(config: Config, testfile: String) {
|
|||||||
run_metrics(config, testfile, &mut _mm);
|
run_metrics(config, testfile, &mut _mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
|
pub fn run_metrics(config: Config, testfile: &Path, mm: &mut MetricMap) {
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
// We're going to be dumping a lot of info. Start on a new line.
|
// We're going to be dumping a lot of info. Start on a new line.
|
||||||
print!("\n\n");
|
print!("\n\n");
|
||||||
}
|
}
|
||||||
let testfile = Path::new(testfile);
|
|
||||||
debug!("running {:?}", testfile.display());
|
debug!("running {:?}", testfile.display());
|
||||||
let props = header::load_props(&testfile);
|
let props = header::load_props(&testfile);
|
||||||
debug!("loaded props");
|
debug!("loaded props");
|
||||||
@ -127,8 +121,8 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The value our Makefile configures valgrind to return on failure
|
// The value our Makefile configures valgrind to return on failure
|
||||||
const VALGRIND_ERR: int = 100;
|
const VALGRIND_ERR: i32 = 100;
|
||||||
if proc_res.status.matches_exit_status(VALGRIND_ERR) {
|
if proc_res.status.code() == Some(VALGRIND_ERR) {
|
||||||
fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
|
fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,10 +133,10 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
|
|
||||||
fn check_correct_failure_status(proc_res: &ProcRes) {
|
fn check_correct_failure_status(proc_res: &ProcRes) {
|
||||||
// The value the rust runtime returns on failure
|
// The value the rust runtime returns on failure
|
||||||
const RUST_ERR: int = 101;
|
const RUST_ERR: i32 = 101;
|
||||||
if !proc_res.status.matches_exit_status(RUST_ERR) {
|
if proc_res.status.code() != Some(RUST_ERR) {
|
||||||
fatal_proc_rec(
|
fatal_proc_rec(
|
||||||
&format!("failure produced the wrong error: {:?}",
|
&format!("failure produced the wrong error: {}",
|
||||||
proc_res.status),
|
proc_res.status),
|
||||||
proc_res);
|
proc_res);
|
||||||
}
|
}
|
||||||
@ -201,8 +195,8 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
let rounds =
|
let rounds =
|
||||||
match props.pp_exact { Some(_) => 1, None => 2 };
|
match props.pp_exact { Some(_) => 1, None => 2 };
|
||||||
|
|
||||||
let src = File::open(testfile).read_to_end().unwrap();
|
let mut src = String::new();
|
||||||
let src = String::from_utf8(src.clone()).unwrap();
|
File::open(testfile).unwrap().read_to_string(&mut src).unwrap();
|
||||||
let mut srcs = vec!(src);
|
let mut srcs = vec!(src);
|
||||||
|
|
||||||
let mut round = 0;
|
let mut round = 0;
|
||||||
@ -226,9 +220,10 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
|
|
||||||
let mut expected = match props.pp_exact {
|
let mut expected = match props.pp_exact {
|
||||||
Some(ref file) => {
|
Some(ref file) => {
|
||||||
let filepath = testfile.dir_path().join(file);
|
let filepath = testfile.parent().unwrap().join(file);
|
||||||
let s = File::open(&filepath).read_to_end().unwrap();
|
let mut s = String::new();
|
||||||
String::from_utf8(s).unwrap()
|
File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
|
||||||
|
s
|
||||||
}
|
}
|
||||||
None => { srcs[srcs.len() - 2].clone() }
|
None => { srcs[srcs.len() - 2].clone() }
|
||||||
};
|
};
|
||||||
@ -283,7 +278,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
pretty_type.to_string()),
|
pretty_type.to_string()),
|
||||||
props.exec_env.clone(),
|
props.exec_env.clone(),
|
||||||
&config.compile_lib_path,
|
&config.compile_lib_path,
|
||||||
Some(aux_dir.as_str().unwrap()),
|
Some(aux_dir.to_str().unwrap()),
|
||||||
Some(src))
|
Some(src))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,11 +294,11 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
pretty_type,
|
pretty_type,
|
||||||
format!("--target={}", config.target),
|
format!("--target={}", config.target),
|
||||||
"-L".to_string(),
|
"-L".to_string(),
|
||||||
aux_dir.as_str().unwrap().to_string());
|
aux_dir.to_str().unwrap().to_string());
|
||||||
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
|
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
|
||||||
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
||||||
return ProcArgs {
|
return ProcArgs {
|
||||||
prog: config.rustc_path.as_str().unwrap().to_string(),
|
prog: config.rustc_path.to_str().unwrap().to_string(),
|
||||||
args: args,
|
args: args,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -345,14 +340,14 @@ actual:\n\
|
|||||||
"--crate-type=lib".to_string(),
|
"--crate-type=lib".to_string(),
|
||||||
format!("--target={}", target),
|
format!("--target={}", target),
|
||||||
"-L".to_string(),
|
"-L".to_string(),
|
||||||
config.build_base.as_str().unwrap().to_string(),
|
config.build_base.to_str().unwrap().to_string(),
|
||||||
"-L".to_string(),
|
"-L".to_string(),
|
||||||
aux_dir.as_str().unwrap().to_string());
|
aux_dir.to_str().unwrap().to_string());
|
||||||
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
|
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
|
||||||
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
return ProcArgs {
|
return ProcArgs {
|
||||||
prog: config.rustc_path.as_str().unwrap().to_string(),
|
prog: config.rustc_path.to_str().unwrap().to_string(),
|
||||||
args: args,
|
args: args,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -390,18 +385,19 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
// write debugger script
|
// write debugger script
|
||||||
let mut script_str = String::with_capacity(2048);
|
let mut script_str = String::with_capacity(2048);
|
||||||
script_str.push_str("set charset UTF-8\n");
|
script_str.push_str("set charset UTF-8\n");
|
||||||
script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap()));
|
script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
|
||||||
script_str.push_str("target remote :5039\n");
|
script_str.push_str("target remote :5039\n");
|
||||||
script_str.push_str(&format!("set solib-search-path \
|
script_str.push_str(&format!("set solib-search-path \
|
||||||
./{}/stage2/lib/rustlib/{}/lib/\n",
|
./{}/stage2/lib/rustlib/{}/lib/\n",
|
||||||
config.host, config.target));
|
config.host, config.target));
|
||||||
for line in breakpoint_lines.iter() {
|
for line in breakpoint_lines.iter() {
|
||||||
script_str.push_str(&format!("break {:?}:{}\n",
|
script_str.push_str(&format!("break {:?}:{}\n",
|
||||||
testfile.filename_display(),
|
testfile.file_name().unwrap()
|
||||||
|
.to_string_lossy(),
|
||||||
*line)[..]);
|
*line)[..]);
|
||||||
}
|
}
|
||||||
script_str.push_str(&cmds);
|
script_str.push_str(&cmds);
|
||||||
script_str.push_str("quit\n");
|
script_str.push_str("\nquit\n");
|
||||||
|
|
||||||
debug!("script_str = {}", script_str);
|
debug!("script_str = {}", script_str);
|
||||||
dump_output_file(config,
|
dump_output_file(config,
|
||||||
@ -415,7 +411,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
None,
|
None,
|
||||||
&[
|
&[
|
||||||
"push".to_string(),
|
"push".to_string(),
|
||||||
exe_file.as_str().unwrap().to_string(),
|
exe_file.to_str().unwrap().to_string(),
|
||||||
config.adb_test_dir.clone()
|
config.adb_test_dir.clone()
|
||||||
],
|
],
|
||||||
vec!(("".to_string(), "".to_string())),
|
vec!(("".to_string(), "".to_string())),
|
||||||
@ -440,9 +436,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
if config.target.contains("aarch64")
|
if config.target.contains("aarch64")
|
||||||
{"64"} else {""},
|
{"64"} else {""},
|
||||||
config.adb_test_dir.clone(),
|
config.adb_test_dir.clone(),
|
||||||
str::from_utf8(
|
exe_file.file_name().unwrap().to_str()
|
||||||
exe_file.filename()
|
.unwrap());
|
||||||
.unwrap()).unwrap());
|
|
||||||
|
|
||||||
let mut process = procsrv::run_background("",
|
let mut process = procsrv::run_background("",
|
||||||
&config.adb_path
|
&config.adb_path
|
||||||
@ -459,16 +454,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
loop {
|
loop {
|
||||||
//waiting 1 second for gdbserver start
|
//waiting 1 second for gdbserver start
|
||||||
timer::sleep(Duration::milliseconds(1000));
|
timer::sleep(Duration::milliseconds(1000));
|
||||||
let result = thread::spawn(move || {
|
if TcpStream::connect("127.0.0.1:5039").is_ok() {
|
||||||
tcp::TcpStream::connect("127.0.0.1:5039").unwrap();
|
break
|
||||||
}).join();
|
|
||||||
if result.is_err() {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let tool_path = match config.android_cross_path.as_str() {
|
let tool_path = match config.android_cross_path.to_str() {
|
||||||
Some(x) => x.to_string(),
|
Some(x) => x.to_string(),
|
||||||
None => fatal("cannot find android cross path")
|
None => fatal("cannot find android cross path")
|
||||||
};
|
};
|
||||||
@ -479,7 +470,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
vec!("-quiet".to_string(),
|
vec!("-quiet".to_string(),
|
||||||
"-batch".to_string(),
|
"-batch".to_string(),
|
||||||
"-nx".to_string(),
|
"-nx".to_string(),
|
||||||
format!("-command={}", debugger_script.as_str().unwrap()));
|
format!("-command={}", debugger_script.to_str().unwrap()));
|
||||||
|
|
||||||
let mut gdb_path = tool_path;
|
let mut gdb_path = tool_path;
|
||||||
gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
|
gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
|
||||||
@ -503,12 +494,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
debugger_run_result = ProcRes {
|
debugger_run_result = ProcRes {
|
||||||
status: status,
|
status: Status::Normal(status),
|
||||||
stdout: out,
|
stdout: out,
|
||||||
stderr: err,
|
stderr: err,
|
||||||
cmdline: cmdline
|
cmdline: cmdline
|
||||||
};
|
};
|
||||||
if process.signal_kill().is_err() {
|
if process.kill().is_err() {
|
||||||
println!("Adb process is already finished.");
|
println!("Adb process is already finished.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,7 +509,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
.expect("Could not find Rust source root");
|
.expect("Could not find Rust source root");
|
||||||
let rust_pp_module_rel_path = Path::new("./src/etc");
|
let rust_pp_module_rel_path = Path::new("./src/etc");
|
||||||
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
|
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
|
||||||
.as_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
// write debugger script
|
// write debugger script
|
||||||
@ -538,7 +529,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
// GDB's script auto loading safe path
|
// GDB's script auto loading safe path
|
||||||
script_str.push_str(
|
script_str.push_str(
|
||||||
&format!("add-auto-load-safe-path {}\n",
|
&format!("add-auto-load-safe-path {}\n",
|
||||||
rust_pp_module_abs_path.replace("\\", "\\\\"))
|
rust_pp_module_abs_path.replace(r"\", r"\\"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,21 +544,24 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
script_str.push_str("set print pretty off\n");
|
script_str.push_str("set print pretty off\n");
|
||||||
|
|
||||||
// Add the pretty printer directory to GDB's source-file search path
|
// Add the pretty printer directory to GDB's source-file search path
|
||||||
script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)[..]);
|
script_str.push_str(&format!("directory {}\n",
|
||||||
|
rust_pp_module_abs_path));
|
||||||
|
|
||||||
// Load the target executable
|
// Load the target executable
|
||||||
script_str.push_str(&format!("file {}\n",
|
script_str.push_str(&format!("file {}\n",
|
||||||
exe_file.as_str().unwrap().replace("\\", "\\\\"))[..]);
|
exe_file.to_str().unwrap()
|
||||||
|
.replace(r"\", r"\\")));
|
||||||
|
|
||||||
// Add line breakpoints
|
// Add line breakpoints
|
||||||
for line in &breakpoint_lines {
|
for line in &breakpoint_lines {
|
||||||
script_str.push_str(&format!("break '{}':{}\n",
|
script_str.push_str(&format!("break '{}':{}\n",
|
||||||
testfile.filename_display(),
|
testfile.file_name().unwrap()
|
||||||
*line)[..]);
|
.to_string_lossy(),
|
||||||
|
*line));
|
||||||
}
|
}
|
||||||
|
|
||||||
script_str.push_str(&cmds);
|
script_str.push_str(&cmds);
|
||||||
script_str.push_str("quit\n");
|
script_str.push_str("\nquit\n");
|
||||||
|
|
||||||
debug!("script_str = {}", script_str);
|
debug!("script_str = {}", script_str);
|
||||||
dump_output_file(config,
|
dump_output_file(config,
|
||||||
@ -576,13 +570,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
"debugger.script");
|
"debugger.script");
|
||||||
|
|
||||||
// run debugger script with gdb
|
// run debugger script with gdb
|
||||||
#[cfg(windows)]
|
fn debugger() -> &'static str {
|
||||||
fn debugger() -> String {
|
if cfg!(windows) {"gdb.exe"} else {"gdb"}
|
||||||
"gdb.exe".to_string()
|
|
||||||
}
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn debugger() -> String {
|
|
||||||
"gdb".to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let debugger_script = make_out_name(config, testfile, "debugger.script");
|
let debugger_script = make_out_name(config, testfile, "debugger.script");
|
||||||
@ -592,10 +581,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
vec!("-quiet".to_string(),
|
vec!("-quiet".to_string(),
|
||||||
"-batch".to_string(),
|
"-batch".to_string(),
|
||||||
"-nx".to_string(),
|
"-nx".to_string(),
|
||||||
format!("-command={}", debugger_script.as_str().unwrap()));
|
format!("-command={}", debugger_script.to_str().unwrap()));
|
||||||
|
|
||||||
let proc_args = ProcArgs {
|
let proc_args = ProcArgs {
|
||||||
prog: debugger(),
|
prog: debugger().to_string(),
|
||||||
args: debugger_opts,
|
args: debugger_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -618,7 +607,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
|||||||
check_debugger_output(&debugger_run_result, &check_lines);
|
check_debugger_output(&debugger_run_result, &check_lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_rust_src_root(config: &Config) -> Option<Path> {
|
fn find_rust_src_root(config: &Config) -> Option<PathBuf> {
|
||||||
let mut path = config.src_base.clone();
|
let mut path = config.src_base.clone();
|
||||||
let path_postfix = Path::new("src/etc/lldb_batchmode.py");
|
let path_postfix = Path::new("src/etc/lldb_batchmode.py");
|
||||||
|
|
||||||
@ -632,8 +621,6 @@ fn find_rust_src_root(config: &Config) -> Option<Path> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||||
use std::old_io::process::{Command, ProcessOutput};
|
|
||||||
|
|
||||||
if config.lldb_python_dir.is_none() {
|
if config.lldb_python_dir.is_none() {
|
||||||
fatal("Can't run LLDB test because LLDB's python path is not set.");
|
fatal("Can't run LLDB test because LLDB's python path is not set.");
|
||||||
}
|
}
|
||||||
@ -685,11 +672,12 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
|||||||
.expect("Could not find Rust source root");
|
.expect("Could not find Rust source root");
|
||||||
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
|
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
|
||||||
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
|
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
|
||||||
.as_str()
|
.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]);
|
script_str.push_str(&format!("command script import {}\n",
|
||||||
|
&rust_pp_module_abs_path[..])[..]);
|
||||||
script_str.push_str("type summary add --no-value ");
|
script_str.push_str("type summary add --no-value ");
|
||||||
script_str.push_str("--python-function lldb_rust_formatters.print_val ");
|
script_str.push_str("--python-function lldb_rust_formatters.print_val ");
|
||||||
script_str.push_str("-x \".*\" --category Rust\n");
|
script_str.push_str("-x \".*\" --category Rust\n");
|
||||||
@ -707,7 +695,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally, quit the debugger
|
// Finally, quit the debugger
|
||||||
script_str.push_str("quit\n");
|
script_str.push_str("\nquit\n");
|
||||||
|
|
||||||
// Write the script into a file
|
// Write the script into a file
|
||||||
debug!("script_str = {}", script_str);
|
debug!("script_str = {}", script_str);
|
||||||
@ -735,22 +723,19 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
|||||||
rust_src_root: &Path)
|
rust_src_root: &Path)
|
||||||
-> ProcRes {
|
-> ProcRes {
|
||||||
// Prepare the lldb_batchmode which executes the debugger script
|
// Prepare the lldb_batchmode which executes the debugger script
|
||||||
let lldb_script_path = rust_src_root.join(Path::new("./src/etc/lldb_batchmode.py"));
|
let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
|
||||||
|
|
||||||
let mut cmd = Command::new("python");
|
let mut cmd = Command::new("python");
|
||||||
cmd.arg(lldb_script_path)
|
cmd.arg(&lldb_script_path)
|
||||||
.arg(test_executable)
|
.arg(test_executable)
|
||||||
.arg(debugger_script)
|
.arg(debugger_script)
|
||||||
.env_set_all(&[("PYTHONPATH", config.lldb_python_dir.clone().unwrap())]);
|
.env("PYTHONPATH", config.lldb_python_dir.as_ref().unwrap());
|
||||||
|
|
||||||
let (status, out, err) = match cmd.spawn() {
|
|
||||||
Ok(process) => {
|
|
||||||
let ProcessOutput { status, output, error } =
|
|
||||||
process.wait_with_output().unwrap();
|
|
||||||
|
|
||||||
|
let (status, out, err) = match cmd.output() {
|
||||||
|
Ok(Output { status, stdout, stderr }) => {
|
||||||
(status,
|
(status,
|
||||||
String::from_utf8(output).unwrap(),
|
String::from_utf8(stdout).unwrap(),
|
||||||
String::from_utf8(error).unwrap())
|
String::from_utf8(stderr).unwrap())
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
fatal(&format!("Failed to setup Python process for \
|
fatal(&format!("Failed to setup Python process for \
|
||||||
@ -760,7 +745,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
|||||||
|
|
||||||
dump_output(config, test_executable, &out, &err);
|
dump_output(config, test_executable, &out, &err);
|
||||||
return ProcRes {
|
return ProcRes {
|
||||||
status: status,
|
status: Status::Normal(status),
|
||||||
stdout: out,
|
stdout: out,
|
||||||
stderr: err,
|
stderr: err,
|
||||||
cmdline: format!("{:?}", cmd)
|
cmdline: format!("{:?}", cmd)
|
||||||
@ -776,8 +761,6 @@ struct DebuggerCommands {
|
|||||||
|
|
||||||
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
||||||
-> DebuggerCommands {
|
-> DebuggerCommands {
|
||||||
use std::old_io::{BufferedReader, File};
|
|
||||||
|
|
||||||
let command_directive = format!("{}-command", debugger_prefix);
|
let command_directive = format!("{}-command", debugger_prefix);
|
||||||
let check_directive = format!("{}-check", debugger_prefix);
|
let check_directive = format!("{}-check", debugger_prefix);
|
||||||
|
|
||||||
@ -785,7 +768,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
|||||||
let mut commands = vec!();
|
let mut commands = vec!();
|
||||||
let mut check_lines = vec!();
|
let mut check_lines = vec!();
|
||||||
let mut counter = 1;
|
let mut counter = 1;
|
||||||
let mut reader = BufferedReader::new(File::open(file_path).unwrap());
|
let reader = BufReader::new(File::open(file_path).unwrap());
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
match line {
|
match line {
|
||||||
Ok(line) => {
|
Ok(line) => {
|
||||||
@ -963,16 +946,17 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
|
|||||||
|
|
||||||
let prefixes = expected_errors.iter().map(|ee| {
|
let prefixes = expected_errors.iter().map(|ee| {
|
||||||
format!("{}:{}:", testfile.display(), ee.line)
|
format!("{}:{}:", testfile.display(), ee.line)
|
||||||
}).collect::<Vec<String> >();
|
}).collect::<Vec<String>>();
|
||||||
|
|
||||||
#[cfg(windows)]
|
fn prefix_matches(line: &str, prefix: &str) -> bool {
|
||||||
fn prefix_matches( line : &str, prefix : &str ) -> bool {
|
use std::ascii::AsciiExt;
|
||||||
line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
|
// On windows just translate all '\' path separators to '/'
|
||||||
}
|
let line = line.replace(r"\", "/");
|
||||||
|
if cfg!(windows) {
|
||||||
#[cfg(unix)]
|
line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
|
||||||
fn prefix_matches( line : &str, prefix : &str ) -> bool {
|
} else {
|
||||||
line.starts_with( prefix )
|
line.starts_with(prefix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A multi-line error will have followup lines which will always
|
// A multi-line error will have followup lines which will always
|
||||||
@ -1113,12 +1097,42 @@ struct ProcArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ProcRes {
|
struct ProcRes {
|
||||||
status: ProcessExit,
|
status: Status,
|
||||||
stdout: String,
|
stdout: String,
|
||||||
stderr: String,
|
stderr: String,
|
||||||
cmdline: String,
|
cmdline: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Status {
|
||||||
|
Parsed(i32),
|
||||||
|
Normal(ExitStatus),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Status {
|
||||||
|
fn code(&self) -> Option<i32> {
|
||||||
|
match *self {
|
||||||
|
Status::Parsed(i) => Some(i),
|
||||||
|
Status::Normal(ref e) => e.code(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn success(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Status::Parsed(i) => i == 0,
|
||||||
|
Status::Normal(ref e) => e.success(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Status {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
Status::Parsed(i) => write!(f, "exit code: {}", i),
|
||||||
|
Status::Normal(ref e) => e.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_test(config: &Config, props: &TestProps,
|
fn compile_test(config: &Config, props: &TestProps,
|
||||||
testfile: &Path) -> ProcRes {
|
testfile: &Path) -> ProcRes {
|
||||||
compile_test_(config, props, testfile, &[])
|
compile_test_(config, props, testfile, &[])
|
||||||
@ -1133,7 +1147,7 @@ fn compile_test_(config: &Config, props: &TestProps,
|
|||||||
let aux_dir = aux_output_dir_name(config, testfile);
|
let aux_dir = aux_output_dir_name(config, testfile);
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let mut link_args = vec!("-L".to_string(),
|
let mut link_args = vec!("-L".to_string(),
|
||||||
aux_dir.as_str().unwrap().to_string());
|
aux_dir.to_str().unwrap().to_string());
|
||||||
link_args.extend(extra_args.iter().cloned());
|
link_args.extend(extra_args.iter().cloned());
|
||||||
let args = make_compile_args(config,
|
let args = make_compile_args(config,
|
||||||
props,
|
props,
|
||||||
@ -1160,7 +1174,7 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
|
|||||||
make_run_args(config, props, testfile),
|
make_run_args(config, props, testfile),
|
||||||
env,
|
env,
|
||||||
&config.run_lib_path,
|
&config.run_lib_path,
|
||||||
Some(aux_dir.as_str().unwrap()),
|
Some(aux_dir.to_str().unwrap()),
|
||||||
None)
|
None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1179,7 +1193,7 @@ fn compose_and_run_compiler(
|
|||||||
|
|
||||||
let aux_dir = aux_output_dir_name(config, testfile);
|
let aux_dir = aux_output_dir_name(config, testfile);
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let extra_link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string());
|
let extra_link_args = vec!("-L".to_string(), aux_dir.to_str().unwrap().to_string());
|
||||||
|
|
||||||
for rel_ab in &props.aux_builds {
|
for rel_ab in &props.aux_builds {
|
||||||
let abs_ab = config.aux_base.join(rel_ab);
|
let abs_ab = config.aux_base.join(rel_ab);
|
||||||
@ -1196,7 +1210,8 @@ fn compose_and_run_compiler(
|
|||||||
crate_type,
|
crate_type,
|
||||||
|a,b| {
|
|a,b| {
|
||||||
let f = make_lib_name(a, b, testfile);
|
let f = make_lib_name(a, b, testfile);
|
||||||
TargetLocation::ThisDirectory(f.dir_path())
|
let parent = f.parent().unwrap();
|
||||||
|
TargetLocation::ThisDirectory(parent.to_path_buf())
|
||||||
},
|
},
|
||||||
&abs_ab);
|
&abs_ab);
|
||||||
let auxres = compose_and_run(config,
|
let auxres = compose_and_run(config,
|
||||||
@ -1204,7 +1219,7 @@ fn compose_and_run_compiler(
|
|||||||
aux_args,
|
aux_args,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
&config.compile_lib_path,
|
&config.compile_lib_path,
|
||||||
Some(aux_dir.as_str().unwrap()),
|
Some(aux_dir.to_str().unwrap()),
|
||||||
None);
|
None);
|
||||||
if !auxres.status.success() {
|
if !auxres.status.success() {
|
||||||
fatal_proc_rec(
|
fatal_proc_rec(
|
||||||
@ -1226,13 +1241,13 @@ fn compose_and_run_compiler(
|
|||||||
args,
|
args,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
&config.compile_lib_path,
|
&config.compile_lib_path,
|
||||||
Some(aux_dir.as_str().unwrap()),
|
Some(aux_dir.to_str().unwrap()),
|
||||||
input)
|
input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_dir(path: &Path) {
|
fn ensure_dir(path: &Path) {
|
||||||
if path.is_dir() { return; }
|
if path.is_dir() { return; }
|
||||||
fs::mkdir(path, old_io::USER_RWX).unwrap();
|
fs::create_dir(path).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compose_and_run(config: &Config, testfile: &Path,
|
fn compose_and_run(config: &Config, testfile: &Path,
|
||||||
@ -1246,8 +1261,8 @@ fn compose_and_run(config: &Config, testfile: &Path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum TargetLocation {
|
enum TargetLocation {
|
||||||
ThisFile(Path),
|
ThisFile(PathBuf),
|
||||||
ThisDirectory(Path),
|
ThisDirectory(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_compile_args<F>(config: &Config,
|
fn make_compile_args<F>(config: &Config,
|
||||||
@ -1265,9 +1280,9 @@ fn make_compile_args<F>(config: &Config,
|
|||||||
&*config.target
|
&*config.target
|
||||||
};
|
};
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let mut args = vec!(testfile.as_str().unwrap().to_string(),
|
let mut args = vec!(testfile.to_str().unwrap().to_string(),
|
||||||
"-L".to_string(),
|
"-L".to_string(),
|
||||||
config.build_base.as_str().unwrap().to_string(),
|
config.build_base.to_str().unwrap().to_string(),
|
||||||
format!("--target={}", target));
|
format!("--target={}", target));
|
||||||
args.push_all(&extras);
|
args.push_all(&extras);
|
||||||
if !props.no_prefer_dynamic {
|
if !props.no_prefer_dynamic {
|
||||||
@ -1284,7 +1299,7 @@ fn make_compile_args<F>(config: &Config,
|
|||||||
path
|
path
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
args.push(path.as_str().unwrap().to_string());
|
args.push(path.to_str().unwrap().to_string());
|
||||||
if props.force_host {
|
if props.force_host {
|
||||||
args.extend(split_maybe_args(&config.host_rustcflags).into_iter());
|
args.extend(split_maybe_args(&config.host_rustcflags).into_iter());
|
||||||
} else {
|
} else {
|
||||||
@ -1292,24 +1307,24 @@ fn make_compile_args<F>(config: &Config,
|
|||||||
}
|
}
|
||||||
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
args.extend(split_maybe_args(&props.compile_flags).into_iter());
|
||||||
return ProcArgs {
|
return ProcArgs {
|
||||||
prog: config.rustc_path.as_str().unwrap().to_string(),
|
prog: config.rustc_path.to_str().unwrap().to_string(),
|
||||||
args: args,
|
args: args,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path {
|
fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf {
|
||||||
// what we return here is not particularly important, as it
|
// what we return here is not particularly important, as it
|
||||||
// happens; rustc ignores everything except for the directory.
|
// happens; rustc ignores everything except for the directory.
|
||||||
let auxname = output_testname(auxfile);
|
let auxname = output_testname(auxfile);
|
||||||
aux_output_dir_name(config, testfile).join(&auxname)
|
aux_output_dir_name(config, testfile).join(&auxname)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_exe_name(config: &Config, testfile: &Path) -> Path {
|
fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||||
let mut f = output_base_name(config, testfile);
|
let mut f = output_base_name(config, testfile);
|
||||||
if !env::consts::EXE_SUFFIX.is_empty() {
|
if !env::consts::EXE_SUFFIX.is_empty() {
|
||||||
let mut fname = f.filename().unwrap().to_vec();
|
let mut fname = f.file_name().unwrap().to_os_string();
|
||||||
fname.extend(env::consts::EXE_SUFFIX.bytes());
|
fname.push_os_str(OsStr::from_str(env::consts::EXE_SUFFIX));
|
||||||
f.set_filename(fname);
|
f.set_file_name(&fname);
|
||||||
}
|
}
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
@ -1322,7 +1337,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) ->
|
|||||||
let exe_file = make_exe_name(config, testfile);
|
let exe_file = make_exe_name(config, testfile);
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
args.push(exe_file.as_str().unwrap().to_string());
|
args.push(exe_file.to_str().unwrap().to_string());
|
||||||
|
|
||||||
// Add the arguments in the run_flags directive
|
// Add the arguments in the run_flags directive
|
||||||
args.extend(split_maybe_args(&props.run_flags).into_iter());
|
args.extend(split_maybe_args(&props.run_flags).into_iter());
|
||||||
@ -1375,29 +1390,28 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
|
|||||||
input).expect(&format!("failed to exec `{}`", prog));
|
input).expect(&format!("failed to exec `{}`", prog));
|
||||||
dump_output(config, testfile, &out, &err);
|
dump_output(config, testfile, &out, &err);
|
||||||
return ProcRes {
|
return ProcRes {
|
||||||
status: status,
|
status: Status::Normal(status),
|
||||||
stdout: out,
|
stdout: out,
|
||||||
stderr: err,
|
stderr: err,
|
||||||
cmdline: cmdline,
|
cmdline: cmdline,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linux and mac don't require adjusting the library search path
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String {
|
|
||||||
format!("{} {}", prog, args.connect(" "))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
|
fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
|
||||||
|
use util;
|
||||||
|
|
||||||
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
|
// Linux and mac don't require adjusting the library search path
|
||||||
// for diagnostic purposes
|
if cfg!(unix) {
|
||||||
fn lib_path_cmd_prefix(path: &str) -> String {
|
format!("{} {}", prog, args.connect(" "))
|
||||||
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
|
} else {
|
||||||
|
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
|
||||||
|
// for diagnostic purposes
|
||||||
|
fn lib_path_cmd_prefix(path: &str) -> String {
|
||||||
|
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
|
||||||
}
|
}
|
||||||
|
|
||||||
format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
|
fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
|
||||||
@ -1409,25 +1423,25 @@ fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
|
|||||||
fn dump_output_file(config: &Config, testfile: &Path,
|
fn dump_output_file(config: &Config, testfile: &Path,
|
||||||
out: &str, extension: &str) {
|
out: &str, extension: &str) {
|
||||||
let outfile = make_out_name(config, testfile, extension);
|
let outfile = make_out_name(config, testfile, extension);
|
||||||
File::create(&outfile).write_all(out.as_bytes()).unwrap();
|
File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path {
|
fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
|
||||||
output_base_name(config, testfile).with_extension(extension)
|
output_base_name(config, testfile).with_extension(extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path {
|
fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||||
let f = output_base_name(config, testfile);
|
let f = output_base_name(config, testfile);
|
||||||
let mut fname = f.filename().unwrap().to_vec();
|
let mut fname = f.file_name().unwrap().to_os_string();
|
||||||
fname.extend("libaux".bytes());
|
fname.push_os_str(OsStr::from_str("libaux"));
|
||||||
f.with_filename(fname)
|
f.with_file_name(&fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_testname(testfile: &Path) -> Path {
|
fn output_testname(testfile: &Path) -> PathBuf {
|
||||||
Path::new(testfile.filestem().unwrap())
|
PathBuf::new(testfile.file_stem().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_base_name(config: &Config, testfile: &Path) -> Path {
|
fn output_base_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||||
config.build_base
|
config.build_base
|
||||||
.join(&output_testname(testfile))
|
.join(&output_testname(testfile))
|
||||||
.with_extension(&config.stage_id)
|
.with_extension(&config.stage_id)
|
||||||
@ -1542,11 +1556,11 @@ fn _arm_exec_compiled_test(config: &Config,
|
|||||||
Some("".to_string()))
|
Some("".to_string()))
|
||||||
.expect(&format!("failed to exec `{}`", config.adb_path));
|
.expect(&format!("failed to exec `{}`", config.adb_path));
|
||||||
|
|
||||||
let mut exitcode: int = 0;
|
let mut exitcode: i32 = 0;
|
||||||
for c in exitcode_out.chars() {
|
for c in exitcode_out.chars() {
|
||||||
if !c.is_numeric() { break; }
|
if !c.is_numeric() { break; }
|
||||||
exitcode = exitcode * 10 + match c {
|
exitcode = exitcode * 10 + match c {
|
||||||
'0' ... '9' => c as int - ('0' as int),
|
'0' ... '9' => c as i32 - ('0' as i32),
|
||||||
_ => 101,
|
_ => 101,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1587,7 +1601,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
|||||||
&stderr_out);
|
&stderr_out);
|
||||||
|
|
||||||
ProcRes {
|
ProcRes {
|
||||||
status: process::ProcessExit::ExitStatus(exitcode),
|
status: Status::Parsed(exitcode),
|
||||||
stdout: stdout_out,
|
stdout: stdout_out,
|
||||||
stderr: stderr_out,
|
stderr: stderr_out,
|
||||||
cmdline: cmdline
|
cmdline: cmdline
|
||||||
@ -1597,16 +1611,17 @@ fn _arm_exec_compiled_test(config: &Config,
|
|||||||
fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
|
fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
|
||||||
let tdir = aux_output_dir_name(config, testfile);
|
let tdir = aux_output_dir_name(config, testfile);
|
||||||
|
|
||||||
let dirs = fs::readdir(&tdir).unwrap();
|
let dirs = fs::read_dir(&tdir).unwrap();
|
||||||
for file in &dirs {
|
for file in dirs {
|
||||||
if file.extension_str() == Some("so") {
|
let file = file.unwrap().path();
|
||||||
|
if file.extension().and_then(|s| s.to_str()) == Some("so") {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let copy_result = procsrv::run("",
|
let copy_result = procsrv::run("",
|
||||||
&config.adb_path,
|
&config.adb_path,
|
||||||
None,
|
None,
|
||||||
&[
|
&[
|
||||||
"push".to_string(),
|
"push".to_string(),
|
||||||
file.as_str()
|
file.to_str()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
config.adb_test_dir.to_string(),
|
config.adb_test_dir.to_string(),
|
||||||
@ -1627,14 +1642,14 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
|
|||||||
|
|
||||||
// codegen tests (vs. clang)
|
// codegen tests (vs. clang)
|
||||||
|
|
||||||
fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
|
fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf {
|
||||||
if suffix.len() == 0 {
|
if suffix.len() == 0 {
|
||||||
(*p).clone()
|
p.to_path_buf()
|
||||||
} else {
|
} else {
|
||||||
let mut stem = p.filestem().unwrap().to_vec();
|
let mut stem = p.file_stem().unwrap().to_os_string();
|
||||||
stem.extend("-".bytes());
|
stem.push_os_str(OsStr::from_str("-"));
|
||||||
stem.extend(suffix.bytes());
|
stem.push_os_str(OsStr::from_str(suffix));
|
||||||
p.with_filename(stem)
|
p.with_file_name(&stem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1643,7 +1658,7 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
|
|||||||
let aux_dir = aux_output_dir_name(config, testfile);
|
let aux_dir = aux_output_dir_name(config, testfile);
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let mut link_args = vec!("-L".to_string(),
|
let mut link_args = vec!("-L".to_string(),
|
||||||
aux_dir.as_str().unwrap().to_string());
|
aux_dir.to_str().unwrap().to_string());
|
||||||
let llvm_args = vec!("--emit=llvm-bc,obj".to_string(),
|
let llvm_args = vec!("--emit=llvm-bc,obj".to_string(),
|
||||||
"--crate-type=lib".to_string());
|
"--crate-type=lib".to_string());
|
||||||
link_args.extend(llvm_args.into_iter());
|
link_args.extend(llvm_args.into_iter());
|
||||||
@ -1651,7 +1666,8 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
|
|||||||
props,
|
props,
|
||||||
link_args,
|
link_args,
|
||||||
|a, b| TargetLocation::ThisDirectory(
|
|a, b| TargetLocation::ThisDirectory(
|
||||||
output_base_name(a, b).dir_path()),
|
output_base_name(a, b).parent()
|
||||||
|
.unwrap().to_path_buf()),
|
||||||
testfile);
|
testfile);
|
||||||
compose_and_run_compiler(config, props, testfile, args, None)
|
compose_and_run_compiler(config, props, testfile, args, None)
|
||||||
}
|
}
|
||||||
@ -1663,12 +1679,12 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps,
|
|||||||
let testcc = testfile.with_extension("cc");
|
let testcc = testfile.with_extension("cc");
|
||||||
let proc_args = ProcArgs {
|
let proc_args = ProcArgs {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
prog: config.clang_path.as_ref().unwrap().as_str().unwrap().to_string(),
|
prog: config.clang_path.as_ref().unwrap().to_str().unwrap().to_string(),
|
||||||
args: vec!("-c".to_string(),
|
args: vec!("-c".to_string(),
|
||||||
"-emit-llvm".to_string(),
|
"-emit-llvm".to_string(),
|
||||||
"-o".to_string(),
|
"-o".to_string(),
|
||||||
bitcodefile.as_str().unwrap().to_string(),
|
bitcodefile.to_str().unwrap().to_string(),
|
||||||
testcc.as_str().unwrap().to_string())
|
testcc.to_str().unwrap().to_string())
|
||||||
};
|
};
|
||||||
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
||||||
}
|
}
|
||||||
@ -1682,10 +1698,10 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
|
|||||||
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract");
|
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract");
|
||||||
let proc_args = ProcArgs {
|
let proc_args = ProcArgs {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
prog: prog.as_str().unwrap().to_string(),
|
prog: prog.to_str().unwrap().to_string(),
|
||||||
args: vec!(format!("-func={}", fname),
|
args: vec!(format!("-func={}", fname),
|
||||||
format!("-o={}", extracted_bc.as_str().unwrap()),
|
format!("-o={}", extracted_bc.to_str().unwrap()),
|
||||||
bitcodefile.as_str().unwrap().to_string())
|
bitcodefile.to_str().unwrap().to_string())
|
||||||
};
|
};
|
||||||
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
||||||
}
|
}
|
||||||
@ -1699,16 +1715,17 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
|
|||||||
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis");
|
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis");
|
||||||
let proc_args = ProcArgs {
|
let proc_args = ProcArgs {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
prog: prog.as_str().unwrap().to_string(),
|
prog: prog.to_str().unwrap().to_string(),
|
||||||
args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
|
args: vec!(format!("-o={}", extracted_ll.to_str().unwrap()),
|
||||||
extracted_bc.as_str().unwrap().to_string())
|
extracted_bc.to_str().unwrap().to_string())
|
||||||
};
|
};
|
||||||
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn count_extracted_lines(p: &Path) -> uint {
|
fn count_extracted_lines(p: &Path) -> uint {
|
||||||
let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
|
let mut x = Vec::new();
|
||||||
|
File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap();
|
||||||
let x = str::from_utf8(&x).unwrap();
|
let x = str::from_utf8(&x).unwrap();
|
||||||
x.lines().count()
|
x.lines().count()
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use common::Config;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use common::Config;
|
||||||
|
|
||||||
/// Conversion table from triple OS name to Rust SYSNAME
|
/// Conversion table from triple OS name to Rust SYSNAME
|
||||||
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
|
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
|
||||||
@ -36,24 +34,20 @@ pub fn get_os(triple: &str) -> &'static str {
|
|||||||
panic!("Cannot determine OS from triple");
|
panic!("Cannot determine OS from triple");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn make_new_path(path: &str) -> String {
|
pub fn make_new_path(path: &str) -> String {
|
||||||
|
assert!(cfg!(windows));
|
||||||
// Windows just uses PATH as the library search path, so we have to
|
// Windows just uses PATH as the library search path, so we have to
|
||||||
// maintain the current value while adding our own
|
// maintain the current value while adding our own
|
||||||
match env::var(lib_path_env_var()) {
|
match env::var(lib_path_env_var()) {
|
||||||
Ok(curr) => {
|
Ok(curr) => {
|
||||||
format!("{}{}{}", path, path_div(), curr)
|
format!("{}{}{}", path, path_div(), curr)
|
||||||
}
|
}
|
||||||
Err(..) => path.to_string()
|
Err(..) => path.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn lib_path_env_var() -> &'static str { "PATH" }
|
pub fn lib_path_env_var() -> &'static str { "PATH" }
|
||||||
|
fn path_div() -> &'static str { ";" }
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn path_div() -> &'static str { ";" }
|
|
||||||
|
|
||||||
pub fn logv(config: &Config, s: String) {
|
pub fn logv(config: &Config, s: String) {
|
||||||
debug!("{}", s);
|
debug!("{}", s);
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(unsafe_no_drop_flag)]
|
#![feature(unsafe_no_drop_flag)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
|
#![feature(unique)]
|
||||||
#![cfg_attr(test, feature(test, alloc, rustc_private))]
|
#![cfg_attr(test, feature(test, alloc, rustc_private))]
|
||||||
#![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
|
#![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
|
||||||
feature(libc))]
|
feature(libc))]
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(str_words)]
|
#![feature(str_words)]
|
||||||
|
#![feature(core)]
|
||||||
#![cfg_attr(test, feature(rustc_private))]
|
#![cfg_attr(test, feature(rustc_private))]
|
||||||
|
|
||||||
#[cfg(test)] #[macro_use] extern crate log;
|
#[cfg(test)] #[macro_use] extern crate log;
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
#![feature(os)]
|
#![feature(os)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(io)]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|
||||||
extern crate arena;
|
extern crate arena;
|
||||||
|
@ -21,6 +21,7 @@ use metadata::decoder;
|
|||||||
use metadata::loader;
|
use metadata::loader;
|
||||||
use metadata::loader::CratePaths;
|
use metadata::loader::CratePaths;
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
@ -126,7 +127,7 @@ fn register_native_lib(sess: &Session,
|
|||||||
// Extra info about a crate loaded for plugins or exported macros.
|
// Extra info about a crate loaded for plugins or exported macros.
|
||||||
struct ExtensionCrate {
|
struct ExtensionCrate {
|
||||||
metadata: PMDSource,
|
metadata: PMDSource,
|
||||||
dylib: Option<Path>,
|
dylib: Option<PathBuf>,
|
||||||
target_only: bool,
|
target_only: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +552,8 @@ impl<'a> CrateReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Look for a plugin registrar. Returns library path and symbol name.
|
/// Look for a plugin registrar. Returns library path and symbol name.
|
||||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> {
|
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
|
||||||
|
-> Option<(PathBuf, String)> {
|
||||||
let ekrate = self.read_extension_crate(span, &CrateInfo {
|
let ekrate = self.read_extension_crate(span, &CrateInfo {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
ident: name.to_string(),
|
ident: name.to_string(),
|
||||||
@ -574,7 +576,7 @@ impl<'a> CrateReader<'a> {
|
|||||||
.map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
|
.map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
|
||||||
|
|
||||||
match (ekrate.dylib.as_ref(), registrar) {
|
match (ekrate.dylib.as_ref(), registrar) {
|
||||||
(Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
|
(Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
|
||||||
(None, Some(_)) => {
|
(None, Some(_)) => {
|
||||||
let message = format!("plugin `{}` only found in rlib format, \
|
let message = format!("plugin `{}` only found in rlib format, \
|
||||||
but must be available in dylib format",
|
but must be available in dylib format",
|
||||||
|
@ -25,6 +25,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
|
|||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::path::PathBuf;
|
||||||
use flate::Bytes;
|
use flate::Bytes;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
@ -78,8 +79,8 @@ pub enum NativeLibraryKind {
|
|||||||
// must be non-None.
|
// must be non-None.
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
pub struct CrateSource {
|
pub struct CrateSource {
|
||||||
pub dylib: Option<(Path, PathKind)>,
|
pub dylib: Option<(PathBuf, PathKind)>,
|
||||||
pub rlib: Option<(Path, PathKind)>,
|
pub rlib: Option<(PathBuf, PathKind)>,
|
||||||
pub cnum: ast::CrateNum,
|
pub cnum: ast::CrateNum,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ impl CStore {
|
|||||||
// topological sort of all crates putting the leaves at the right-most
|
// topological sort of all crates putting the leaves at the right-most
|
||||||
// positions.
|
// positions.
|
||||||
pub fn get_used_crates(&self, prefer: LinkagePreference)
|
pub fn get_used_crates(&self, prefer: LinkagePreference)
|
||||||
-> Vec<(ast::CrateNum, Option<Path>)> {
|
-> Vec<(ast::CrateNum, Option<PathBuf>)> {
|
||||||
let mut ordering = Vec::new();
|
let mut ordering = Vec::new();
|
||||||
fn visit(cstore: &CStore, cnum: ast::CrateNum,
|
fn visit(cstore: &CStore, cnum: ast::CrateNum,
|
||||||
ordering: &mut Vec<ast::CrateNum>) {
|
ordering: &mut Vec<ast::CrateNum>) {
|
||||||
|
@ -34,9 +34,9 @@ use middle::astencode::vtable_decoder_helpers;
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::{self, Hash, SipHasher};
|
use std::hash::{self, Hash, SipHasher};
|
||||||
use std::num::FromPrimitive;
|
use std::io::prelude::*;
|
||||||
use std::num::Int;
|
use std::io;
|
||||||
use std::old_io;
|
use std::num::{FromPrimitive, Int};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::slice::bytes;
|
use std::slice::bytes;
|
||||||
use std::str;
|
use std::str;
|
||||||
@ -1191,7 +1191,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
|
fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
|
||||||
out: &mut old_io::Writer) -> old_io::IoResult<()> {
|
out: &mut io::Write) -> io::Result<()> {
|
||||||
try!(write!(out, "=Crate Attributes ({})=\n", *hash));
|
try!(write!(out, "=Crate Attributes ({})=\n", *hash));
|
||||||
|
|
||||||
let r = get_attributes(md);
|
let r = get_attributes(md);
|
||||||
@ -1236,7 +1236,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
|
|||||||
return deps;
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_crate_deps(data: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
|
fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
|
||||||
try!(write!(out, "=External Dependencies=\n"));
|
try!(write!(out, "=External Dependencies=\n"));
|
||||||
for dep in &get_crate_deps(data) {
|
for dep in &get_crate_deps(data) {
|
||||||
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
|
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
|
||||||
@ -1275,7 +1275,7 @@ pub fn get_crate_name(data: &[u8]) -> String {
|
|||||||
maybe_get_crate_name(data).expect("no crate name in crate")
|
maybe_get_crate_name(data).expect("no crate name in crate")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_crate_metadata(bytes: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
|
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
|
||||||
let hash = get_crate_hash(bytes);
|
let hash = get_crate_hash(bytes);
|
||||||
let md = rbml::Doc::new(bytes);
|
let md = rbml::Doc::new(bytes);
|
||||||
try!(list_crate_attributes(md, &hash, out));
|
try!(list_crate_attributes(md, &hash, out));
|
||||||
|
@ -14,9 +14,9 @@ pub use self::FileMatch::*;
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::os;
|
use std::fs;
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::io::prelude::*;
|
||||||
use std::old_io::fs;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use util::fs as myfs;
|
use util::fs as myfs;
|
||||||
use session::search_paths::{SearchPaths, PathKind};
|
use session::search_paths::{SearchPaths, PathKind};
|
||||||
@ -50,20 +50,20 @@ impl<'a> FileSearch<'a> {
|
|||||||
FileMatches => found = true,
|
FileMatches => found = true,
|
||||||
FileDoesntMatch => ()
|
FileDoesntMatch => ()
|
||||||
}
|
}
|
||||||
visited_dirs.insert(path.as_vec().to_vec());
|
visited_dirs.insert(path.to_path_buf());
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("filesearch: searching lib path");
|
debug!("filesearch: searching lib path");
|
||||||
let tlib_path = make_target_lib_path(self.sysroot,
|
let tlib_path = make_target_lib_path(self.sysroot,
|
||||||
self.triple);
|
self.triple);
|
||||||
if !visited_dirs.contains(tlib_path.as_vec()) {
|
if !visited_dirs.contains(&tlib_path) {
|
||||||
match f(&tlib_path, PathKind::All) {
|
match f(&tlib_path, PathKind::All) {
|
||||||
FileMatches => found = true,
|
FileMatches => found = true,
|
||||||
FileDoesntMatch => ()
|
FileDoesntMatch => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visited_dirs.insert(tlib_path.as_vec().to_vec());
|
visited_dirs.insert(tlib_path);
|
||||||
// Try RUST_PATH
|
// Try RUST_PATH
|
||||||
if !found {
|
if !found {
|
||||||
let rustpath = rust_path();
|
let rustpath = rust_path();
|
||||||
@ -71,10 +71,10 @@ impl<'a> FileSearch<'a> {
|
|||||||
let tlib_path = make_rustpkg_lib_path(
|
let tlib_path = make_rustpkg_lib_path(
|
||||||
self.sysroot, path, self.triple);
|
self.sysroot, path, self.triple);
|
||||||
debug!("is {} in visited_dirs? {}", tlib_path.display(),
|
debug!("is {} in visited_dirs? {}", tlib_path.display(),
|
||||||
visited_dirs.contains(&tlib_path.as_vec().to_vec()));
|
visited_dirs.contains(&tlib_path));
|
||||||
|
|
||||||
if !visited_dirs.contains(tlib_path.as_vec()) {
|
if !visited_dirs.contains(&tlib_path) {
|
||||||
visited_dirs.insert(tlib_path.as_vec().to_vec());
|
visited_dirs.insert(tlib_path.clone());
|
||||||
// Don't keep searching the RUST_PATH if one match turns up --
|
// Don't keep searching the RUST_PATH if one match turns up --
|
||||||
// if we did, we'd get a "multiple matching crates" error
|
// if we did, we'd get a "multiple matching crates" error
|
||||||
match f(&tlib_path, PathKind::All) {
|
match f(&tlib_path, PathKind::All) {
|
||||||
@ -88,7 +88,7 @@ impl<'a> FileSearch<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lib_path(&self) -> Path {
|
pub fn get_lib_path(&self) -> PathBuf {
|
||||||
make_target_lib_path(self.sysroot, self.triple)
|
make_target_lib_path(self.sysroot, self.triple)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,11 +97,13 @@ impl<'a> FileSearch<'a> {
|
|||||||
{
|
{
|
||||||
self.for_each_lib_search_path(|lib_search_path, kind| {
|
self.for_each_lib_search_path(|lib_search_path, kind| {
|
||||||
debug!("searching {}", lib_search_path.display());
|
debug!("searching {}", lib_search_path.display());
|
||||||
match fs::readdir(lib_search_path) {
|
match fs::read_dir(lib_search_path) {
|
||||||
Ok(files) => {
|
Ok(files) => {
|
||||||
|
let files = files.filter_map(|p| p.ok().map(|s| s.path()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let mut rslt = FileDoesntMatch;
|
let mut rslt = FileDoesntMatch;
|
||||||
fn is_rlib(p: & &Path) -> bool {
|
fn is_rlib(p: &Path) -> bool {
|
||||||
p.extension_str() == Some("rlib")
|
p.extension().and_then(|s| s.to_str()) == Some("rlib")
|
||||||
}
|
}
|
||||||
// Reading metadata out of rlibs is faster, and if we find both
|
// Reading metadata out of rlibs is faster, and if we find both
|
||||||
// an rlib and a dylib we only read one of the files of
|
// an rlib and a dylib we only read one of the files of
|
||||||
@ -143,59 +145,60 @@ impl<'a> FileSearch<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of directories where target-specific dylibs might be located.
|
// Returns a list of directories where target-specific dylibs might be located.
|
||||||
pub fn get_dylib_search_paths(&self) -> Vec<Path> {
|
pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
self.for_each_lib_search_path(|lib_search_path, _| {
|
self.for_each_lib_search_path(|lib_search_path, _| {
|
||||||
paths.push(lib_search_path.clone());
|
paths.push(lib_search_path.to_path_buf());
|
||||||
FileDoesntMatch
|
FileDoesntMatch
|
||||||
});
|
});
|
||||||
paths
|
paths
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of directories where target-specific tool binaries are located.
|
// Returns a list of directories where target-specific tool binaries are located.
|
||||||
pub fn get_tools_search_paths(&self) -> Vec<Path> {
|
pub fn get_tools_search_paths(&self) -> Vec<PathBuf> {
|
||||||
let mut p = Path::new(self.sysroot);
|
let mut p = PathBuf::new(self.sysroot);
|
||||||
p.push(find_libdir(self.sysroot));
|
p.push(&find_libdir(self.sysroot));
|
||||||
p.push(rustlibdir());
|
p.push(&rustlibdir());
|
||||||
p.push(self.triple);
|
p.push(&self.triple);
|
||||||
p.push("bin");
|
p.push("bin");
|
||||||
vec![p]
|
vec![p]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path {
|
pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||||
let mut p = Path::new(find_libdir(sysroot));
|
let mut p = PathBuf::new(&find_libdir(sysroot));
|
||||||
assert!(p.is_relative());
|
assert!(p.is_relative());
|
||||||
p.push(rustlibdir());
|
p.push(&rustlibdir());
|
||||||
p.push(target_triple);
|
p.push(target_triple);
|
||||||
p.push("lib");
|
p.push("lib");
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_target_lib_path(sysroot: &Path,
|
fn make_target_lib_path(sysroot: &Path,
|
||||||
target_triple: &str) -> Path {
|
target_triple: &str) -> PathBuf {
|
||||||
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
|
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_rustpkg_lib_path(sysroot: &Path,
|
fn make_rustpkg_lib_path(sysroot: &Path,
|
||||||
dir: &Path,
|
dir: &Path,
|
||||||
triple: &str) -> Path {
|
triple: &str) -> PathBuf {
|
||||||
let mut p = dir.join(find_libdir(sysroot));
|
let mut p = dir.join(&find_libdir(sysroot));
|
||||||
p.push(triple);
|
p.push(triple);
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_or_default_sysroot() -> Path {
|
pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||||
fn canonicalize(path: Option<Path>) -> Option<Path> {
|
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
|
||||||
path.and_then(|path|
|
path.and_then(|path| {
|
||||||
match myfs::realpath(&path) {
|
match myfs::realpath(&path) {
|
||||||
Ok(canon) => Some(canon),
|
Ok(canon) => Some(canon),
|
||||||
Err(e) => panic!("failed to get realpath: {}", e),
|
Err(e) => panic!("failed to get realpath: {}", e),
|
||||||
})
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
match canonicalize(os::self_exe_name()) {
|
match canonicalize(env::current_exe().ok()) {
|
||||||
Some(mut p) => { p.pop(); p.pop(); p }
|
Some(mut p) => { p.pop(); p.pop(); p }
|
||||||
None => panic!("can't determine value for sysroot")
|
None => panic!("can't determine value for sysroot")
|
||||||
}
|
}
|
||||||
@ -216,16 +219,16 @@ pub fn get_rust_path() -> Option<String> {
|
|||||||
/// $HOME/.rust
|
/// $HOME/.rust
|
||||||
/// DIR/.rust for any DIR that's the current working directory
|
/// DIR/.rust for any DIR that's the current working directory
|
||||||
/// or an ancestor of it
|
/// or an ancestor of it
|
||||||
pub fn rust_path() -> Vec<Path> {
|
pub fn rust_path() -> Vec<PathBuf> {
|
||||||
let mut env_rust_path: Vec<Path> = match get_rust_path() {
|
let mut env_rust_path: Vec<PathBuf> = match get_rust_path() {
|
||||||
Some(env_path) => {
|
Some(env_path) => {
|
||||||
let env_path_components =
|
let env_path_components =
|
||||||
env_path.split(PATH_ENTRY_SEPARATOR);
|
env_path.split(PATH_ENTRY_SEPARATOR);
|
||||||
env_path_components.map(|s| Path::new(s)).collect()
|
env_path_components.map(|s| PathBuf::new(s)).collect()
|
||||||
}
|
}
|
||||||
None => Vec::new()
|
None => Vec::new()
|
||||||
};
|
};
|
||||||
let mut cwd = os::getcwd().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
// now add in default entries
|
// now add in default entries
|
||||||
let cwd_dot_rust = cwd.join(".rust");
|
let cwd_dot_rust = cwd.join(".rust");
|
||||||
if !env_rust_path.contains(&cwd_dot_rust) {
|
if !env_rust_path.contains(&cwd_dot_rust) {
|
||||||
@ -234,17 +237,15 @@ pub fn rust_path() -> Vec<Path> {
|
|||||||
if !env_rust_path.contains(&cwd) {
|
if !env_rust_path.contains(&cwd) {
|
||||||
env_rust_path.push(cwd.clone());
|
env_rust_path.push(cwd.clone());
|
||||||
}
|
}
|
||||||
loop {
|
let mut cur = &*cwd;
|
||||||
if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } {
|
while let Some(parent) = cur.parent() {
|
||||||
break
|
let candidate = parent.join(".rust");
|
||||||
|
if !env_rust_path.contains(&candidate) && candidate.exists() {
|
||||||
|
env_rust_path.push(candidate.clone());
|
||||||
}
|
}
|
||||||
cwd.set_filename(".rust");
|
cur = parent;
|
||||||
if !env_rust_path.contains(&cwd) && cwd.exists() {
|
|
||||||
env_rust_path.push(cwd.clone());
|
|
||||||
}
|
|
||||||
cwd.pop();
|
|
||||||
}
|
}
|
||||||
if let Some(h) = os::homedir() {
|
if let Some(h) = env::home_dir() {
|
||||||
let p = h.join(".rust");
|
let p = h.join(".rust");
|
||||||
if !env_rust_path.contains(&p) && p.exists() {
|
if !env_rust_path.contains(&p) && p.exists() {
|
||||||
env_rust_path.push(p);
|
env_rust_path.push(p);
|
||||||
@ -267,7 +268,7 @@ fn find_libdir(sysroot: &Path) -> String {
|
|||||||
|
|
||||||
match option_env!("CFG_LIBDIR_RELATIVE") {
|
match option_env!("CFG_LIBDIR_RELATIVE") {
|
||||||
Some(libdir) if libdir != "lib" => return libdir.to_string(),
|
Some(libdir) if libdir != "lib" => return libdir.to_string(),
|
||||||
_ => if sysroot.join(primary_libdir_name()).join(rustlibdir()).exists() {
|
_ => if sysroot.join(&primary_libdir_name()).join(&rustlibdir()).exists() {
|
||||||
return primary_libdir_name();
|
return primary_libdir_name();
|
||||||
} else {
|
} else {
|
||||||
return secondary_libdir_name();
|
return secondary_libdir_name();
|
||||||
|
@ -226,13 +226,14 @@ use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
|||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::diagnostic::SpanHandler;
|
use syntax::diagnostic::SpanHandler;
|
||||||
use util::fs;
|
use util::fs;
|
||||||
|
use util::common;
|
||||||
use rustc_back::target::Target;
|
use rustc_back::target::Target;
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::io::prelude::*;
|
||||||
use std::old_io;
|
use std::io;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -240,7 +241,7 @@ use std::time::Duration;
|
|||||||
use flate;
|
use flate;
|
||||||
|
|
||||||
pub struct CrateMismatch {
|
pub struct CrateMismatch {
|
||||||
path: Path,
|
path: PathBuf,
|
||||||
got: String,
|
got: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,8 +263,8 @@ pub struct Context<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Library {
|
pub struct Library {
|
||||||
pub dylib: Option<(Path, PathKind)>,
|
pub dylib: Option<(PathBuf, PathKind)>,
|
||||||
pub rlib: Option<(Path, PathKind)>,
|
pub rlib: Option<(PathBuf, PathKind)>,
|
||||||
pub metadata: MetadataBlob,
|
pub metadata: MetadataBlob,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,12 +276,12 @@ pub struct ArchiveMetadata {
|
|||||||
|
|
||||||
pub struct CratePaths {
|
pub struct CratePaths {
|
||||||
pub ident: String,
|
pub ident: String,
|
||||||
pub dylib: Option<Path>,
|
pub dylib: Option<PathBuf>,
|
||||||
pub rlib: Option<Path>
|
pub rlib: Option<PathBuf>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CratePaths {
|
impl CratePaths {
|
||||||
fn paths(&self) -> Vec<Path> {
|
fn paths(&self) -> Vec<PathBuf> {
|
||||||
match (&self.dylib, &self.rlib) {
|
match (&self.dylib, &self.rlib) {
|
||||||
(&None, &None) => vec!(),
|
(&None, &None) => vec!(),
|
||||||
(&Some(ref p), &None) |
|
(&Some(ref p), &None) |
|
||||||
@ -400,7 +401,7 @@ impl<'a> Context<'a> {
|
|||||||
//
|
//
|
||||||
// The goal of this step is to look at as little metadata as possible.
|
// The goal of this step is to look at as little metadata as possible.
|
||||||
self.filesearch.search(|path, kind| {
|
self.filesearch.search(|path, kind| {
|
||||||
let file = match path.filename_str() {
|
let file = match path.file_name().and_then(|s| s.to_str()) {
|
||||||
None => return FileDoesntMatch,
|
None => return FileDoesntMatch,
|
||||||
Some(file) => file,
|
Some(file) => file,
|
||||||
};
|
};
|
||||||
@ -416,7 +417,7 @@ impl<'a> Context<'a> {
|
|||||||
if file.starts_with(&staticlib_prefix[..]) &&
|
if file.starts_with(&staticlib_prefix[..]) &&
|
||||||
file.ends_with(".a") {
|
file.ends_with(".a") {
|
||||||
staticlibs.push(CrateMismatch {
|
staticlibs.push(CrateMismatch {
|
||||||
path: path.clone(),
|
path: path.to_path_buf(),
|
||||||
got: "static".to_string()
|
got: "static".to_string()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -506,9 +507,9 @@ impl<'a> Context<'a> {
|
|||||||
// read the metadata from it if `*slot` is `None`. If the metadata couldn't
|
// read the metadata from it if `*slot` is `None`. If the metadata couldn't
|
||||||
// be read, it is assumed that the file isn't a valid rust library (no
|
// be read, it is assumed that the file isn't a valid rust library (no
|
||||||
// errors are emitted).
|
// errors are emitted).
|
||||||
fn extract_one(&mut self, m: HashMap<Path, PathKind>, flavor: &str,
|
fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str,
|
||||||
slot: &mut Option<MetadataBlob>) -> Option<(Path, PathKind)> {
|
slot: &mut Option<MetadataBlob>) -> Option<(PathBuf, PathKind)> {
|
||||||
let mut ret = None::<(Path, PathKind)>;
|
let mut ret = None::<(PathBuf, PathKind)>;
|
||||||
let mut error = 0;
|
let mut error = 0;
|
||||||
|
|
||||||
if slot.is_some() {
|
if slot.is_some() {
|
||||||
@ -587,7 +588,7 @@ impl<'a> Context<'a> {
|
|||||||
if triple != self.triple {
|
if triple != self.triple {
|
||||||
info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
|
info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
|
||||||
self.rejected_via_triple.push(CrateMismatch {
|
self.rejected_via_triple.push(CrateMismatch {
|
||||||
path: libpath.clone(),
|
path: libpath.to_path_buf(),
|
||||||
got: triple.to_string()
|
got: triple.to_string()
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
@ -599,7 +600,7 @@ impl<'a> Context<'a> {
|
|||||||
if *myhash != hash {
|
if *myhash != hash {
|
||||||
info!("Rejecting via hash: expected {} got {}", *myhash, hash);
|
info!("Rejecting via hash: expected {} got {}", *myhash, hash);
|
||||||
self.rejected_via_hash.push(CrateMismatch {
|
self.rejected_via_hash.push(CrateMismatch {
|
||||||
path: libpath.clone(),
|
path: libpath.to_path_buf(),
|
||||||
got: myhash.as_str().to_string()
|
got: myhash.as_str().to_string()
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
@ -627,13 +628,13 @@ impl<'a> Context<'a> {
|
|||||||
let mut rlibs = HashMap::new();
|
let mut rlibs = HashMap::new();
|
||||||
let mut dylibs = HashMap::new();
|
let mut dylibs = HashMap::new();
|
||||||
{
|
{
|
||||||
let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| {
|
let locs = locs.iter().map(|l| PathBuf::new(&l[..])).filter(|loc| {
|
||||||
if !loc.exists() {
|
if !loc.exists() {
|
||||||
sess.err(&format!("extern location for {} does not exist: {}",
|
sess.err(&format!("extern location for {} does not exist: {}",
|
||||||
self.crate_name, loc.display()));
|
self.crate_name, loc.display()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let file = match loc.filename_str() {
|
let file = match loc.file_name().and_then(|s| s.to_str()) {
|
||||||
Some(file) => file,
|
Some(file) => file,
|
||||||
None => {
|
None => {
|
||||||
sess.err(&format!("extern location for {} is not a file: {}",
|
sess.err(&format!("extern location for {} is not a file: {}",
|
||||||
@ -658,7 +659,7 @@ impl<'a> Context<'a> {
|
|||||||
// Now that we have an iterator of good candidates, make sure
|
// Now that we have an iterator of good candidates, make sure
|
||||||
// there's at most one rlib and at most one dylib.
|
// there's at most one rlib and at most one dylib.
|
||||||
for loc in locs {
|
for loc in locs {
|
||||||
if loc.filename_str().unwrap().ends_with(".rlib") {
|
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
||||||
rlibs.insert(fs::realpath(&loc).unwrap(),
|
rlibs.insert(fs::realpath(&loc).unwrap(),
|
||||||
PathKind::ExternFlag);
|
PathKind::ExternFlag);
|
||||||
} else {
|
} else {
|
||||||
@ -714,7 +715,7 @@ fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, S
|
|||||||
let dur = Duration::span(|| {
|
let dur = Duration::span(|| {
|
||||||
ret = Some(get_metadata_section_imp(is_osx, filename));
|
ret = Some(get_metadata_section_imp(is_osx, filename));
|
||||||
});
|
});
|
||||||
info!("reading {} => {}ms", filename.filename_display(),
|
info!("reading {:?} => {}ms", filename.file_name().unwrap(),
|
||||||
dur.num_milliseconds());
|
dur.num_milliseconds());
|
||||||
return ret.unwrap();;
|
return ret.unwrap();;
|
||||||
}
|
}
|
||||||
@ -723,7 +724,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
|
|||||||
if !filename.exists() {
|
if !filename.exists() {
|
||||||
return Err(format!("no such file: '{}'", filename.display()));
|
return Err(format!("no such file: '{}'", filename.display()));
|
||||||
}
|
}
|
||||||
if filename.filename_str().unwrap().ends_with(".rlib") {
|
if filename.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
|
||||||
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
|
||||||
// internally to read the file. We also avoid even using a memcpy by
|
// internally to read the file. We also avoid even using a memcpy by
|
||||||
// just keeping the archive along while the metadata is in use.
|
// just keeping the archive along while the metadata is in use.
|
||||||
@ -742,7 +743,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
let buf = CString::new(filename.as_vec()).unwrap();
|
let buf = common::path2cstr(filename);
|
||||||
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
|
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
|
||||||
if mb as int == 0 {
|
if mb as int == 0 {
|
||||||
return Err(format!("error reading library: '{}'",
|
return Err(format!("error reading library: '{}'",
|
||||||
@ -811,7 +812,7 @@ pub fn read_meta_section_name(is_osx: bool) -> &'static str {
|
|||||||
|
|
||||||
// A diagnostic function for dumping crate metadata to an output stream
|
// A diagnostic function for dumping crate metadata to an output stream
|
||||||
pub fn list_file_metadata(is_osx: bool, path: &Path,
|
pub fn list_file_metadata(is_osx: bool, path: &Path,
|
||||||
out: &mut old_io::Writer) -> old_io::IoResult<()> {
|
out: &mut io::Write) -> io::Result<()> {
|
||||||
match get_metadata_section(is_osx, path) {
|
match get_metadata_section(is_osx, path) {
|
||||||
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
|
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
|
@ -19,7 +19,7 @@ pub use self::EntryOrExit::*;
|
|||||||
use middle::cfg;
|
use middle::cfg;
|
||||||
use middle::cfg::CFGIndex;
|
use middle::cfg::CFGIndex;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use std::old_io;
|
use std::io;
|
||||||
use std::usize;
|
use std::usize;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@ -103,7 +103,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
|
|||||||
impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
|
impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
|
||||||
fn pre(&self,
|
fn pre(&self,
|
||||||
ps: &mut pprust::State,
|
ps: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
let id = match node {
|
let id = match node {
|
||||||
pprust::NodeIdent(_) | pprust::NodeName(_) => 0,
|
pprust::NodeIdent(_) | pprust::NodeName(_) => 0,
|
||||||
pprust::NodeExpr(expr) => expr.id,
|
pprust::NodeExpr(expr) => expr.id,
|
||||||
@ -485,13 +485,15 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
|
|||||||
|
|
||||||
debug!("Dataflow result for {}:", self.analysis_name);
|
debug!("Dataflow result for {}:", self.analysis_name);
|
||||||
debug!("{}", {
|
debug!("{}", {
|
||||||
self.pretty_print_to(box old_io::stderr(), blk).unwrap();
|
let mut v = Vec::new();
|
||||||
|
self.pretty_print_to(box &mut v, blk).unwrap();
|
||||||
|
println!("{}", String::from_utf8(v).unwrap());
|
||||||
""
|
""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pretty_print_to(&self, wr: Box<old_io::Writer+'static>,
|
fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
|
||||||
blk: &ast::Block) -> old_io::IoResult<()> {
|
blk: &ast::Block) -> io::Result<()> {
|
||||||
let mut ps = pprust::rust_printer_annotated(wr, self);
|
let mut ps = pprust::rust_printer_annotated(wr, self);
|
||||||
try!(ps.cbox(pprust::indent_unit));
|
try!(ps.cbox(pprust::indent_unit));
|
||||||
try!(ps.ibox(0));
|
try!(ps.ibox(0));
|
||||||
|
@ -28,8 +28,10 @@ use util::ppaux::Repr;
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::hash_map::Entry::Vacant;
|
use std::collections::hash_map::Entry::Vacant;
|
||||||
use std::old_io::{self, File};
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
|
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
@ -256,10 +258,11 @@ pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>;
|
|||||||
|
|
||||||
fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>,
|
fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>,
|
||||||
map: &ConstraintMap<'tcx>,
|
map: &ConstraintMap<'tcx>,
|
||||||
path: &str) -> old_io::IoResult<()> {
|
path: &str) -> io::Result<()> {
|
||||||
debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path);
|
debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path);
|
||||||
let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
|
let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
|
||||||
let mut f = File::create(&Path::new(path));
|
|
||||||
debug!("dump_region_constraints calling render");
|
debug!("dump_region_constraints calling render");
|
||||||
dot::render(&g, &mut f)
|
let mut v = Vec::new();
|
||||||
|
dot::render(&g, &mut v).unwrap();
|
||||||
|
File::create(path).and_then(|mut f| f.write_all(&v))
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,12 @@ use session::Session;
|
|||||||
use metadata::creader::CrateReader;
|
use metadata::creader::CrateReader;
|
||||||
use plugin::registry::Registry;
|
use plugin::registry::Registry;
|
||||||
|
|
||||||
use std::mem;
|
|
||||||
use std::os;
|
|
||||||
use std::dynamic_lib::DynamicLibrary;
|
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
use std::dynamic_lib::DynamicLibrary;
|
||||||
|
use std::env;
|
||||||
|
use std::mem;
|
||||||
|
use std::old_path;
|
||||||
|
use std::path::PathBuf;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::{Span, COMMAND_LINE_SP};
|
use syntax::codemap::{Span, COMMAND_LINE_SP};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
@ -100,10 +102,11 @@ impl<'a> PluginLoader<'a> {
|
|||||||
// Dynamically link a registrar function into the compiler process.
|
// Dynamically link a registrar function into the compiler process.
|
||||||
fn dylink_registrar(&mut self,
|
fn dylink_registrar(&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
path: Path,
|
path: PathBuf,
|
||||||
symbol: String) -> PluginRegistrarFun {
|
symbol: String) -> PluginRegistrarFun {
|
||||||
// Make sure the path contains a / or the linker will search for it.
|
// Make sure the path contains a / or the linker will search for it.
|
||||||
let path = os::getcwd().unwrap().join(&path);
|
let path = env::current_dir().unwrap().join(&path);
|
||||||
|
let path = old_path::Path::new(path.to_str().unwrap());
|
||||||
|
|
||||||
let lib = match DynamicLibrary::open(Some(&path)) {
|
let lib = match DynamicLibrary::open(Some(&path)) {
|
||||||
Ok(lib) => lib,
|
Ok(lib) => lib,
|
||||||
|
@ -38,6 +38,7 @@ use std::collections::HashMap;
|
|||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ pub struct Options {
|
|||||||
// this.
|
// this.
|
||||||
pub search_paths: SearchPaths,
|
pub search_paths: SearchPaths,
|
||||||
pub libs: Vec<(String, cstore::NativeLibraryKind)>,
|
pub libs: Vec<(String, cstore::NativeLibraryKind)>,
|
||||||
pub maybe_sysroot: Option<Path>,
|
pub maybe_sysroot: Option<PathBuf>,
|
||||||
pub target_triple: String,
|
pub target_triple: String,
|
||||||
// User-specified cfg meta items. The compiler itself will add additional
|
// User-specified cfg meta items. The compiler itself will add additional
|
||||||
// items to the crate config, and during parsing the entire crate config
|
// items to the crate config, and during parsing the entire crate config
|
||||||
@ -103,7 +104,7 @@ pub struct Options {
|
|||||||
pub no_analysis: bool,
|
pub no_analysis: bool,
|
||||||
pub debugging_opts: DebuggingOptions,
|
pub debugging_opts: DebuggingOptions,
|
||||||
/// Whether to write dependency files. It's (enabled, optional filename).
|
/// Whether to write dependency files. It's (enabled, optional filename).
|
||||||
pub write_dependency_info: (bool, Option<Path>),
|
pub write_dependency_info: (bool, Option<PathBuf>),
|
||||||
pub prints: Vec<PrintRequest>,
|
pub prints: Vec<PrintRequest>,
|
||||||
pub cg: CodegenOptions,
|
pub cg: CodegenOptions,
|
||||||
pub color: ColorConfig,
|
pub color: ColorConfig,
|
||||||
@ -142,7 +143,7 @@ pub enum PrintRequest {
|
|||||||
|
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
/// Load source from file
|
/// Load source from file
|
||||||
File(Path),
|
File(PathBuf),
|
||||||
/// The string is the source
|
/// The string is the source
|
||||||
Str(String)
|
Str(String)
|
||||||
}
|
}
|
||||||
@ -150,7 +151,8 @@ pub enum Input {
|
|||||||
impl Input {
|
impl Input {
|
||||||
pub fn filestem(&self) -> String {
|
pub fn filestem(&self) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(),
|
Input::File(ref ifile) => ifile.file_stem().unwrap()
|
||||||
|
.to_str().unwrap().to_string(),
|
||||||
Input::Str(_) => "rust_out".to_string(),
|
Input::Str(_) => "rust_out".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,14 +160,14 @@ impl Input {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct OutputFilenames {
|
pub struct OutputFilenames {
|
||||||
pub out_directory: Path,
|
pub out_directory: PathBuf,
|
||||||
pub out_filestem: String,
|
pub out_filestem: String,
|
||||||
pub single_output_file: Option<Path>,
|
pub single_output_file: Option<PathBuf>,
|
||||||
pub extra: String,
|
pub extra: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputFilenames {
|
impl OutputFilenames {
|
||||||
pub fn path(&self, flavor: OutputType) -> Path {
|
pub fn path(&self, flavor: OutputType) -> PathBuf {
|
||||||
match self.single_output_file {
|
match self.single_output_file {
|
||||||
Some(ref path) => return path.clone(),
|
Some(ref path) => return path.clone(),
|
||||||
None => {}
|
None => {}
|
||||||
@ -173,8 +175,8 @@ impl OutputFilenames {
|
|||||||
self.temp_path(flavor)
|
self.temp_path(flavor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn temp_path(&self, flavor: OutputType) -> Path {
|
pub fn temp_path(&self, flavor: OutputType) -> PathBuf {
|
||||||
let base = self.out_directory.join(self.filestem());
|
let base = self.out_directory.join(&self.filestem());
|
||||||
match flavor {
|
match flavor {
|
||||||
OutputTypeBitcode => base.with_extension("bc"),
|
OutputTypeBitcode => base.with_extension("bc"),
|
||||||
OutputTypeAssembly => base.with_extension("s"),
|
OutputTypeAssembly => base.with_extension("s"),
|
||||||
@ -185,8 +187,8 @@ impl OutputFilenames {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_extension(&self, extension: &str) -> Path {
|
pub fn with_extension(&self, extension: &str) -> PathBuf {
|
||||||
self.out_directory.join(self.filestem()).with_extension(extension)
|
self.out_directory.join(&self.filestem()).with_extension(extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filestem(&self) -> String {
|
pub fn filestem(&self) -> String {
|
||||||
@ -897,7 +899,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||||||
|
|
||||||
let cg = build_codegen_options(matches);
|
let cg = build_codegen_options(matches);
|
||||||
|
|
||||||
let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m));
|
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::new(&m));
|
||||||
let target = matches.opt_str("target").unwrap_or(
|
let target = matches.opt_str("target").unwrap_or(
|
||||||
host_triple().to_string());
|
host_triple().to_string());
|
||||||
let opt_level = {
|
let opt_level = {
|
||||||
|
@ -26,8 +26,9 @@ use syntax::{ast, codemap};
|
|||||||
|
|
||||||
use rustc_back::target::Target;
|
use rustc_back::target::Target;
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::os;
|
use std::env;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod search_paths;
|
pub mod search_paths;
|
||||||
@ -44,11 +45,11 @@ pub struct Session {
|
|||||||
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
|
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
|
||||||
pub entry_type: Cell<Option<config::EntryFnType>>,
|
pub entry_type: Cell<Option<config::EntryFnType>>,
|
||||||
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
|
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
|
||||||
pub default_sysroot: Option<Path>,
|
pub default_sysroot: Option<PathBuf>,
|
||||||
// The name of the root source file of the crate, in the local file system. The path is always
|
// The name of the root source file of the crate, in the local file system. The path is always
|
||||||
// expected to be absolute. `None` means that there is no source file.
|
// expected to be absolute. `None` means that there is no source file.
|
||||||
pub local_crate_source_file: Option<Path>,
|
pub local_crate_source_file: Option<PathBuf>,
|
||||||
pub working_dir: Path,
|
pub working_dir: PathBuf,
|
||||||
pub lint_store: RefCell<lint::LintStore>,
|
pub lint_store: RefCell<lint::LintStore>,
|
||||||
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
|
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
|
||||||
pub crate_types: RefCell<Vec<config::CrateType>>,
|
pub crate_types: RefCell<Vec<config::CrateType>>,
|
||||||
@ -310,7 +311,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_session(sopts: config::Options,
|
pub fn build_session(sopts: config::Options,
|
||||||
local_crate_source_file: Option<Path>,
|
local_crate_source_file: Option<PathBuf>,
|
||||||
registry: diagnostics::registry::Registry)
|
registry: diagnostics::registry::Registry)
|
||||||
-> Session {
|
-> Session {
|
||||||
// FIXME: This is not general enough to make the warning lint completely override
|
// FIXME: This is not general enough to make the warning lint completely override
|
||||||
@ -333,7 +334,7 @@ pub fn build_session(sopts: config::Options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_session_(sopts: config::Options,
|
pub fn build_session_(sopts: config::Options,
|
||||||
local_crate_source_file: Option<Path>,
|
local_crate_source_file: Option<PathBuf>,
|
||||||
span_diagnostic: diagnostic::SpanHandler)
|
span_diagnostic: diagnostic::SpanHandler)
|
||||||
-> Session {
|
-> Session {
|
||||||
let host = match Target::search(config::host_triple()) {
|
let host = match Target::search(config::host_triple()) {
|
||||||
@ -355,7 +356,7 @@ pub fn build_session_(sopts: config::Options,
|
|||||||
if path.is_absolute() {
|
if path.is_absolute() {
|
||||||
path.clone()
|
path.clone()
|
||||||
} else {
|
} else {
|
||||||
os::getcwd().unwrap().join(&path)
|
env::current_dir().unwrap().join(&path)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -378,7 +379,7 @@ pub fn build_session_(sopts: config::Options,
|
|||||||
plugin_registrar_fn: Cell::new(None),
|
plugin_registrar_fn: Cell::new(None),
|
||||||
default_sysroot: default_sysroot,
|
default_sysroot: default_sysroot,
|
||||||
local_crate_source_file: local_crate_source_file,
|
local_crate_source_file: local_crate_source_file,
|
||||||
working_dir: os::getcwd().unwrap(),
|
working_dir: env::current_dir().unwrap(),
|
||||||
lint_store: RefCell::new(lint::LintStore::new()),
|
lint_store: RefCell::new(lint::LintStore::new()),
|
||||||
lints: RefCell::new(NodeMap()),
|
lints: RefCell::new(NodeMap()),
|
||||||
crate_types: RefCell::new(Vec::new()),
|
crate_types: RefCell::new(Vec::new()),
|
||||||
|
@ -9,15 +9,16 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SearchPaths {
|
pub struct SearchPaths {
|
||||||
paths: Vec<(PathKind, Path)>,
|
paths: Vec<(PathKind, PathBuf)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Iter<'a> {
|
pub struct Iter<'a> {
|
||||||
kind: PathKind,
|
kind: PathKind,
|
||||||
iter: slice::Iter<'a, (PathKind, Path)>,
|
iter: slice::Iter<'a, (PathKind, PathBuf)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
||||||
@ -49,7 +50,7 @@ impl SearchPaths {
|
|||||||
} else {
|
} else {
|
||||||
(PathKind::All, path)
|
(PathKind::All, path)
|
||||||
};
|
};
|
||||||
self.paths.push((kind, Path::new(path)));
|
self.paths.push((kind, PathBuf::new(path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self, kind: PathKind) -> Iter {
|
pub fn iter(&self, kind: PathKind) -> Iter {
|
||||||
|
@ -12,11 +12,13 @@
|
|||||||
|
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::collections::hash_state::HashState;
|
||||||
|
use std::ffi::CString;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
use std::path::Path;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::collections::hash_state::HashState;
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::visit;
|
use syntax::visit;
|
||||||
@ -222,3 +224,14 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub fn path2cstr(p: &Path) -> CString {
|
||||||
|
use std::os::unix::prelude::*;
|
||||||
|
use std::ffi::AsOsStr;
|
||||||
|
CString::new(p.as_os_str().as_bytes()).unwrap()
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub fn path2cstr(p: &Path) -> CString {
|
||||||
|
CString::new(p.to_str().unwrap()).unwrap()
|
||||||
|
}
|
||||||
|
@ -10,11 +10,12 @@
|
|||||||
|
|
||||||
//! A helper class for dealing with static archives
|
//! A helper class for dealing with static archives
|
||||||
|
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::env;
|
||||||
use std::old_io::process::{Command, ProcessOutput};
|
use std::fs::{self, TempDir};
|
||||||
use std::old_io::{fs, TempDir};
|
use std::io::prelude::*;
|
||||||
use std::old_io;
|
use std::io;
|
||||||
use std::os;
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Command, Output, Stdio};
|
||||||
use std::str;
|
use std::str;
|
||||||
use syntax::diagnostic::Handler as ErrorHandler;
|
use syntax::diagnostic::Handler as ErrorHandler;
|
||||||
|
|
||||||
@ -22,8 +23,8 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
|
|||||||
|
|
||||||
pub struct ArchiveConfig<'a> {
|
pub struct ArchiveConfig<'a> {
|
||||||
pub handler: &'a ErrorHandler,
|
pub handler: &'a ErrorHandler,
|
||||||
pub dst: Path,
|
pub dst: PathBuf,
|
||||||
pub lib_search_paths: Vec<Path>,
|
pub lib_search_paths: Vec<PathBuf>,
|
||||||
pub slib_prefix: String,
|
pub slib_prefix: String,
|
||||||
pub slib_suffix: String,
|
pub slib_suffix: String,
|
||||||
pub maybe_ar_prog: Option<String>
|
pub maybe_ar_prog: Option<String>
|
||||||
@ -31,8 +32,8 @@ pub struct ArchiveConfig<'a> {
|
|||||||
|
|
||||||
pub struct Archive<'a> {
|
pub struct Archive<'a> {
|
||||||
handler: &'a ErrorHandler,
|
handler: &'a ErrorHandler,
|
||||||
dst: Path,
|
dst: PathBuf,
|
||||||
lib_search_paths: Vec<Path>,
|
lib_search_paths: Vec<PathBuf>,
|
||||||
slib_prefix: String,
|
slib_prefix: String,
|
||||||
slib_suffix: String,
|
slib_suffix: String,
|
||||||
maybe_ar_prog: Option<String>
|
maybe_ar_prog: Option<String>
|
||||||
@ -45,25 +46,25 @@ pub struct ArchiveBuilder<'a> {
|
|||||||
archive: Archive<'a>,
|
archive: Archive<'a>,
|
||||||
work_dir: TempDir,
|
work_dir: TempDir,
|
||||||
/// Filename of each member that should be added to the archive.
|
/// Filename of each member that should be added to the archive.
|
||||||
members: Vec<Path>,
|
members: Vec<PathBuf>,
|
||||||
should_update_symbols: bool,
|
should_update_symbols: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
|
fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
|
||||||
args: &str, cwd: Option<&Path>,
|
args: &str, cwd: Option<&Path>,
|
||||||
paths: &[&Path]) -> ProcessOutput {
|
paths: &[&Path]) -> Output {
|
||||||
let ar = match *maybe_ar_prog {
|
let ar = match *maybe_ar_prog {
|
||||||
Some(ref ar) => &ar[..],
|
Some(ref ar) => &ar[..],
|
||||||
None => "ar"
|
None => "ar"
|
||||||
};
|
};
|
||||||
let mut cmd = Command::new(ar);
|
let mut cmd = Command::new(ar);
|
||||||
|
|
||||||
cmd.arg(args).args(paths);
|
cmd.arg(args).args(paths).stdout(Stdio::piped()).stderr(Stdio::piped());
|
||||||
debug!("{:?}", cmd);
|
debug!("{:?}", cmd);
|
||||||
|
|
||||||
match cwd {
|
match cwd {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
cmd.cwd(p);
|
cmd.current_dir(p);
|
||||||
debug!("inside {:?}", p.display());
|
debug!("inside {:?}", p.display());
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@ -75,9 +76,9 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
|
|||||||
if !o.status.success() {
|
if !o.status.success() {
|
||||||
handler.err(&format!("{:?} failed with: {}", cmd, o.status));
|
handler.err(&format!("{:?} failed with: {}", cmd, o.status));
|
||||||
handler.note(&format!("stdout ---\n{}",
|
handler.note(&format!("stdout ---\n{}",
|
||||||
str::from_utf8(&o.output).unwrap()));
|
str::from_utf8(&o.stdout).unwrap()));
|
||||||
handler.note(&format!("stderr ---\n{}",
|
handler.note(&format!("stderr ---\n{}",
|
||||||
str::from_utf8(&o.error).unwrap())
|
str::from_utf8(&o.stderr).unwrap())
|
||||||
);
|
);
|
||||||
handler.abort_if_errors();
|
handler.abort_if_errors();
|
||||||
}
|
}
|
||||||
@ -93,14 +94,15 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
|
pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
|
||||||
search_paths: &[Path], handler: &ErrorHandler) -> Path {
|
search_paths: &[PathBuf],
|
||||||
|
handler: &ErrorHandler) -> PathBuf {
|
||||||
// On Windows, static libraries sometimes show up as libfoo.a and other
|
// On Windows, static libraries sometimes show up as libfoo.a and other
|
||||||
// times show up as foo.lib
|
// times show up as foo.lib
|
||||||
let oslibname = format!("{}{}{}", osprefix, name, ossuffix);
|
let oslibname = format!("{}{}{}", osprefix, name, ossuffix);
|
||||||
let unixlibname = format!("lib{}.a", name);
|
let unixlibname = format!("lib{}.a", name);
|
||||||
|
|
||||||
for path in search_paths {
|
for path in search_paths {
|
||||||
debug!("looking for {} inside {:?}", name, path.display());
|
debug!("looking for {} inside {:?}", name, path);
|
||||||
let test = path.join(&oslibname[..]);
|
let test = path.join(&oslibname[..]);
|
||||||
if test.exists() { return test }
|
if test.exists() { return test }
|
||||||
if oslibname != unixlibname {
|
if oslibname != unixlibname {
|
||||||
@ -142,7 +144,7 @@ impl<'a> Archive<'a> {
|
|||||||
/// Lists all files in an archive
|
/// Lists all files in an archive
|
||||||
pub fn files(&self) -> Vec<String> {
|
pub fn files(&self) -> Vec<String> {
|
||||||
let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]);
|
let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]);
|
||||||
let output = str::from_utf8(&output.output).unwrap();
|
let output = str::from_utf8(&output.stdout).unwrap();
|
||||||
// use lines_any because windows delimits output with `\r\n` instead of
|
// use lines_any because windows delimits output with `\r\n` instead of
|
||||||
// just `\n`
|
// just `\n`
|
||||||
output.lines_any().map(|s| s.to_string()).collect()
|
output.lines_any().map(|s| s.to_string()).collect()
|
||||||
@ -172,7 +174,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
|
|
||||||
/// Adds all of the contents of a native library to this archive. This will
|
/// Adds all of the contents of a native library to this archive. This will
|
||||||
/// search in the relevant locations for a library named `name`.
|
/// search in the relevant locations for a library named `name`.
|
||||||
pub fn add_native_library(&mut self, name: &str) -> old_io::IoResult<()> {
|
pub fn add_native_library(&mut self, name: &str) -> io::Result<()> {
|
||||||
let location = find_library(name,
|
let location = find_library(name,
|
||||||
&self.archive.slib_prefix,
|
&self.archive.slib_prefix,
|
||||||
&self.archive.slib_suffix,
|
&self.archive.slib_suffix,
|
||||||
@ -187,7 +189,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
|
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
|
||||||
/// then the object file also isn't added.
|
/// then the object file also isn't added.
|
||||||
pub fn add_rlib(&mut self, rlib: &Path, name: &str,
|
pub fn add_rlib(&mut self, rlib: &Path, name: &str,
|
||||||
lto: bool) -> old_io::IoResult<()> {
|
lto: bool) -> io::Result<()> {
|
||||||
// Ignoring obj file starting with the crate name
|
// Ignoring obj file starting with the crate name
|
||||||
// as simple comparison is not enough - there
|
// as simple comparison is not enough - there
|
||||||
// might be also an extra name suffix
|
// might be also an extra name suffix
|
||||||
@ -205,11 +207,11 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an arbitrary file to this archive
|
/// Adds an arbitrary file to this archive
|
||||||
pub fn add_file(&mut self, file: &Path) -> old_io::IoResult<()> {
|
pub fn add_file(&mut self, file: &Path) -> io::Result<()> {
|
||||||
let filename = Path::new(file.filename().unwrap());
|
let filename = Path::new(file.file_name().unwrap());
|
||||||
let new_file = self.work_dir.path().join(&filename);
|
let new_file = self.work_dir.path().join(&filename);
|
||||||
try!(fs::copy(file, &new_file));
|
try!(fs::copy(file, &new_file));
|
||||||
self.members.push(filename);
|
self.members.push(filename.to_path_buf());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,10 +226,10 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
pub fn build(self) -> Archive<'a> {
|
pub fn build(self) -> Archive<'a> {
|
||||||
// Get an absolute path to the destination, so `ar` will work even
|
// Get an absolute path to the destination, so `ar` will work even
|
||||||
// though we run it from `self.work_dir`.
|
// though we run it from `self.work_dir`.
|
||||||
let abs_dst = os::getcwd().unwrap().join(&self.archive.dst);
|
let abs_dst = env::current_dir().unwrap().join(&self.archive.dst);
|
||||||
assert!(!abs_dst.is_relative());
|
assert!(!abs_dst.is_relative());
|
||||||
let mut args = vec![&abs_dst];
|
let mut args = vec![&*abs_dst];
|
||||||
let mut total_len = abs_dst.as_vec().len();
|
let mut total_len = abs_dst.to_string_lossy().len();
|
||||||
|
|
||||||
if self.members.is_empty() {
|
if self.members.is_empty() {
|
||||||
// OSX `ar` does not allow using `r` with no members, but it does
|
// OSX `ar` does not allow using `r` with no members, but it does
|
||||||
@ -245,7 +247,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
const ARG_LENGTH_LIMIT: uint = 32_000;
|
const ARG_LENGTH_LIMIT: uint = 32_000;
|
||||||
|
|
||||||
for member_name in &self.members {
|
for member_name in &self.members {
|
||||||
let len = member_name.as_vec().len();
|
let len = member_name.to_string_lossy().len();
|
||||||
|
|
||||||
// `len + 1` to account for the space that's inserted before each
|
// `len + 1` to account for the space that's inserted before each
|
||||||
// argument. (Windows passes command-line arguments as a single
|
// argument. (Windows passes command-line arguments as a single
|
||||||
@ -258,7 +260,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
|
|
||||||
args.clear();
|
args.clear();
|
||||||
args.push(&abs_dst);
|
args.push(&abs_dst);
|
||||||
total_len = abs_dst.as_vec().len();
|
total_len = abs_dst.to_string_lossy().len();
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push(member_name);
|
args.push(member_name);
|
||||||
@ -275,7 +277,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_archive<F>(&mut self, archive: &Path, name: &str,
|
fn add_archive<F>(&mut self, archive: &Path, name: &str,
|
||||||
mut skip: F) -> old_io::IoResult<()>
|
mut skip: F) -> io::Result<()>
|
||||||
where F: FnMut(&str) -> bool,
|
where F: FnMut(&str) -> bool,
|
||||||
{
|
{
|
||||||
let loc = TempDir::new("rsar").unwrap();
|
let loc = TempDir::new("rsar").unwrap();
|
||||||
@ -283,7 +285,7 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
// First, extract the contents of the archive to a temporary directory.
|
// First, extract the contents of the archive to a temporary directory.
|
||||||
// We don't unpack directly into `self.work_dir` due to the possibility
|
// We don't unpack directly into `self.work_dir` due to the possibility
|
||||||
// of filename collisions.
|
// of filename collisions.
|
||||||
let archive = os::getcwd().unwrap().join(archive);
|
let archive = env::current_dir().unwrap().join(archive);
|
||||||
run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
|
run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
|
||||||
"x", Some(loc.path()), &[&archive]);
|
"x", Some(loc.path()), &[&archive]);
|
||||||
|
|
||||||
@ -296,9 +298,10 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
// We skip any files explicitly desired for skipping, and we also skip
|
// We skip any files explicitly desired for skipping, and we also skip
|
||||||
// all SYMDEF files as these are just magical placeholders which get
|
// all SYMDEF files as these are just magical placeholders which get
|
||||||
// re-created when we make a new archive anyway.
|
// re-created when we make a new archive anyway.
|
||||||
let files = try!(fs::readdir(loc.path()));
|
let files = try!(fs::read_dir(loc.path()));
|
||||||
for file in &files {
|
for file in files {
|
||||||
let filename = file.filename_str().unwrap();
|
let file = try!(file).path();
|
||||||
|
let filename = file.file_name().unwrap().to_str().unwrap();
|
||||||
if skip(filename) { continue }
|
if skip(filename) { continue }
|
||||||
if filename.contains(".SYMDEF") { continue }
|
if filename.contains(".SYMDEF") { continue }
|
||||||
|
|
||||||
@ -313,8 +316,8 @@ impl<'a> ArchiveBuilder<'a> {
|
|||||||
filename
|
filename
|
||||||
};
|
};
|
||||||
let new_filename = self.work_dir.path().join(&filename[..]);
|
let new_filename = self.work_dir.path().join(&filename[..]);
|
||||||
try!(fs::rename(file, &new_filename));
|
try!(fs::rename(&file, &new_filename));
|
||||||
self.members.push(Path::new(filename));
|
self.members.push(PathBuf::new(&filename));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,29 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::old_io;
|
use std::io;
|
||||||
use std::old_io::fs;
|
use std::old_io::fs;
|
||||||
|
use std::old_io;
|
||||||
|
use std::old_path;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// Returns an absolute path in the filesystem that `path` points to. The
|
/// Returns an absolute path in the filesystem that `path` points to. The
|
||||||
/// returned path does not contain any symlinks in its hierarchy.
|
/// returned path does not contain any symlinks in its hierarchy.
|
||||||
pub fn realpath(original: &Path) -> old_io::IoResult<Path> {
|
#[allow(deprecated)] // readlink is deprecated
|
||||||
const MAX_LINKS_FOLLOWED: uint = 256;
|
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
||||||
|
let old = old_path::Path::new(original.to_str().unwrap());
|
||||||
|
match old_realpath(&old) {
|
||||||
|
Ok(p) => Ok(PathBuf::new(p.as_str().unwrap())),
|
||||||
|
Err(e) => Err(io::Error::new(io::ErrorKind::Other,
|
||||||
|
"realpath error",
|
||||||
|
Some(e.to_string())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
|
||||||
|
const MAX_LINKS_FOLLOWED: usize = 256;
|
||||||
let original = try!(os::getcwd()).join(original);
|
let original = try!(os::getcwd()).join(original);
|
||||||
|
|
||||||
// Right now lstat on windows doesn't work quite well
|
// Right now lstat on windows doesn't work quite well
|
||||||
@ -55,7 +70,7 @@ pub fn realpath(original: &Path) -> old_io::IoResult<Path> {
|
|||||||
mod test {
|
mod test {
|
||||||
use std::old_io;
|
use std::old_io;
|
||||||
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
|
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
|
||||||
use super::realpath;
|
use super::old_realpath as realpath;
|
||||||
use std::old_io::TempDir;
|
use std::old_io::TempDir;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -33,14 +33,18 @@
|
|||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(collections)]
|
#![feature(collections)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
|
#![feature(old_fs)]
|
||||||
|
#![feature(fs)]
|
||||||
#![feature(hash)]
|
#![feature(hash)]
|
||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
|
#![feature(io)]
|
||||||
#![feature(old_io)]
|
#![feature(old_io)]
|
||||||
#![feature(os)]
|
|
||||||
#![feature(old_path)]
|
#![feature(old_path)]
|
||||||
|
#![feature(os)]
|
||||||
|
#![feature(path)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(path)]
|
#![feature(tempdir)]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
|
@ -10,26 +10,20 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::old_io::IoError;
|
use std::io;
|
||||||
use std::os;
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
pub struct RPathConfig<F, G> where
|
pub struct RPathConfig<'a> {
|
||||||
F: FnOnce() -> Path,
|
pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>,
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
pub out_filename: PathBuf,
|
||||||
{
|
|
||||||
pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
|
|
||||||
pub out_filename: Path,
|
|
||||||
pub is_like_osx: bool,
|
pub is_like_osx: bool,
|
||||||
pub has_rpath: bool,
|
pub has_rpath: bool,
|
||||||
pub get_install_prefix_lib_path: F,
|
pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
|
||||||
pub realpath: G,
|
pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
|
pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
|
||||||
F: FnOnce() -> Path,
|
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
|
||||||
{
|
|
||||||
// No rpath on windows
|
// No rpath on windows
|
||||||
if !config.has_rpath {
|
if !config.has_rpath {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
@ -54,10 +48,7 @@ fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where
|
fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
|
||||||
F: FnOnce() -> Path,
|
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
|
||||||
{
|
|
||||||
debug!("output: {:?}", config.out_filename.display());
|
debug!("output: {:?}", config.out_filename.display());
|
||||||
debug!("libs:");
|
debug!("libs:");
|
||||||
for libpath in libs {
|
for libpath in libs {
|
||||||
@ -67,7 +58,7 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String>
|
|||||||
// Use relative paths to the libraries. Binaries can be moved
|
// Use relative paths to the libraries. Binaries can be moved
|
||||||
// as long as they maintain the relative relationship to the
|
// as long as they maintain the relative relationship to the
|
||||||
// crates they depend on.
|
// crates they depend on.
|
||||||
let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
|
let rel_rpaths = get_rpaths_relative_to_output(config, libs);
|
||||||
|
|
||||||
// And a final backup rpath to the global library location.
|
// And a final backup rpath to the global library location.
|
||||||
let fallback_rpaths = vec!(get_install_prefix_rpath(config));
|
let fallback_rpaths = vec!(get_install_prefix_rpath(config));
|
||||||
@ -90,18 +81,12 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String>
|
|||||||
return rpaths;
|
return rpaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>,
|
fn get_rpaths_relative_to_output(config: &mut RPathConfig,
|
||||||
libs: &[Path]) -> Vec<String> where
|
libs: &[PathBuf]) -> Vec<String> {
|
||||||
F: FnOnce() -> Path,
|
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
|
||||||
{
|
|
||||||
libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
|
libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where
|
fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String {
|
||||||
F: FnOnce() -> Path,
|
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
|
||||||
{
|
|
||||||
// Mac doesn't appear to support $ORIGIN
|
// Mac doesn't appear to support $ORIGIN
|
||||||
let prefix = if config.is_like_osx {
|
let prefix = if config.is_like_osx {
|
||||||
"@loader_path"
|
"@loader_path"
|
||||||
@ -109,23 +94,36 @@ fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path
|
|||||||
"$ORIGIN"
|
"$ORIGIN"
|
||||||
};
|
};
|
||||||
|
|
||||||
let cwd = os::getcwd().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
|
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
|
||||||
lib.pop();
|
lib.pop();
|
||||||
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
|
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
|
||||||
output.pop();
|
output.pop();
|
||||||
let relative = lib.path_relative_from(&output);
|
let relative = relativize(&lib, &output);
|
||||||
let relative = relative.expect("could not create rpath relative to output");
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
format!("{}/{}",
|
format!("{}/{}", prefix,
|
||||||
prefix,
|
relative.to_str().expect("non-utf8 component in path"))
|
||||||
relative.as_str().expect("non-utf8 component in path"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where
|
fn relativize(path: &Path, rel: &Path) -> PathBuf {
|
||||||
F: FnOnce() -> Path,
|
let mut res = PathBuf::new("");
|
||||||
G: FnMut(&Path) -> Result<Path, IoError>,
|
let mut cur = rel;
|
||||||
{
|
while !path.starts_with(cur) {
|
||||||
|
res.push("..");
|
||||||
|
match cur.parent() {
|
||||||
|
Some(p) => cur = p,
|
||||||
|
None => panic!("can't create relative paths across filesystems"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match path.relative_from(cur) {
|
||||||
|
Some(s) => { res.push(s); res }
|
||||||
|
None => panic!("couldn't create relative path from {:?} to {:?}",
|
||||||
|
rel, path),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
|
||||||
let path = (config.get_install_prefix_lib_path)();
|
let path = (config.get_install_prefix_lib_path)();
|
||||||
let path = env::current_dir().unwrap().join(&path);
|
let path = env::current_dir().unwrap().join(&path);
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
@ -147,6 +145,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::{RPathConfig};
|
use super::{RPathConfig};
|
||||||
use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
|
use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rpaths_to_flags() {
|
fn test_rpaths_to_flags() {
|
||||||
@ -195,50 +194,31 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
||||||
fn test_rpath_relative() {
|
fn test_rpath_relative() {
|
||||||
let config = &mut RPathConfig {
|
if cfg!(target_os = "macos") {
|
||||||
used_crates: Vec::new(),
|
let config = &mut RPathConfig {
|
||||||
out_filename: Path::new("bin/rustc"),
|
used_crates: Vec::new(),
|
||||||
get_install_prefix_lib_path: || panic!(),
|
has_rpath: true,
|
||||||
has_rpath: true,
|
is_like_osx: true,
|
||||||
is_like_osx: false,
|
out_filename: PathBuf::new("bin/rustc"),
|
||||||
realpath: |p| Ok(p.clone())
|
get_install_prefix_lib_path: &mut || panic!(),
|
||||||
};
|
realpath: &mut |p| Ok(p.to_path_buf()),
|
||||||
let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
|
};
|
||||||
assert_eq!(res, "$ORIGIN/../lib");
|
let res = get_rpath_relative_to_output(config,
|
||||||
}
|
Path::new("lib/libstd.so"));
|
||||||
|
assert_eq!(res, "@loader_path/../lib");
|
||||||
#[test]
|
} else {
|
||||||
#[cfg(any(target_os = "freebsd",
|
let config = &mut RPathConfig {
|
||||||
target_os = "dragonfly",
|
used_crates: Vec::new(),
|
||||||
target_os = "bitrig",
|
out_filename: PathBuf::new("bin/rustc"),
|
||||||
target_os = "openbsd"))]
|
get_install_prefix_lib_path: &mut || panic!(),
|
||||||
fn test_rpath_relative() {
|
has_rpath: true,
|
||||||
let config = &mut RPathConfig {
|
is_like_osx: false,
|
||||||
used_crates: Vec::new(),
|
realpath: &mut |p| Ok(p.to_path_buf()),
|
||||||
has_rpath: true,
|
};
|
||||||
is_like_osx: false,
|
let res = get_rpath_relative_to_output(config,
|
||||||
out_filename: Path::new("bin/rustc"),
|
Path::new("lib/libstd.so"));
|
||||||
get_install_prefix_lib_path: || panic!(),
|
assert_eq!(res, "$ORIGIN/../lib");
|
||||||
realpath: |p| Ok(p.clone())
|
}
|
||||||
};
|
|
||||||
let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
|
|
||||||
assert_eq!(res, "$ORIGIN/../lib");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn test_rpath_relative() {
|
|
||||||
let config = &mut RPathConfig {
|
|
||||||
used_crates: Vec::new(),
|
|
||||||
has_rpath: true,
|
|
||||||
is_like_osx: true,
|
|
||||||
out_filename: Path::new("bin/rustc"),
|
|
||||||
get_install_prefix_lib_path: || panic!(),
|
|
||||||
realpath: |p| Ok(p.clone())
|
|
||||||
};
|
|
||||||
let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
|
|
||||||
assert_eq!(res, "@loader_path/../lib");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
use serialize::json::Json;
|
use serialize::json::Json;
|
||||||
use syntax::{diagnostic, abi};
|
use syntax::{diagnostic, abi};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::io::prelude::*;
|
||||||
|
|
||||||
mod windows_base;
|
mod windows_base;
|
||||||
mod linux_base;
|
mod linux_base;
|
||||||
@ -302,23 +302,26 @@ impl Target {
|
|||||||
base
|
base
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
|
/// Search RUST_TARGET_PATH for a JSON file specifying the given target
|
||||||
/// could also just be a bare filename already, so also check for that. If one of the hardcoded
|
/// triple. Note that it could also just be a bare filename already, so also
|
||||||
/// targets we know about, just return it directly.
|
/// check for that. If one of the hardcoded targets we know about, just
|
||||||
|
/// return it directly.
|
||||||
///
|
///
|
||||||
/// The error string could come from any of the APIs called, including filesystem access and
|
/// The error string could come from any of the APIs called, including
|
||||||
/// JSON decoding.
|
/// filesystem access and JSON decoding.
|
||||||
pub fn search(target: &str) -> Result<Target, String> {
|
pub fn search(target: &str) -> Result<Target, String> {
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::os;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::old_io::File;
|
use std::fs::File;
|
||||||
use std::old_path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use serialize::json;
|
use serialize::json;
|
||||||
|
|
||||||
fn load_file(path: &Path) -> Result<Target, String> {
|
fn load_file(path: &Path) -> Result<Target, String> {
|
||||||
let mut f = try!(File::open(path).map_err(|e| format!("{:?}", e)));
|
let mut f = try!(File::open(path).map_err(|e| e.to_string()));
|
||||||
let obj = try!(json::from_reader(&mut f).map_err(|e| format!("{:?}", e)));
|
let mut contents = Vec::new();
|
||||||
|
try!(f.read_to_end(&mut contents).map_err(|e| e.to_string()));
|
||||||
|
let obj = try!(json::from_reader(&mut &contents[..])
|
||||||
|
.map_err(|e| e.to_string()));
|
||||||
Ok(Target::from_json(obj))
|
Ok(Target::from_json(obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,15 +393,16 @@ impl Target {
|
|||||||
let path = {
|
let path = {
|
||||||
let mut target = target.to_string();
|
let mut target = target.to_string();
|
||||||
target.push_str(".json");
|
target.push_str(".json");
|
||||||
Path::new(target)
|
PathBuf::new(&target)
|
||||||
};
|
};
|
||||||
|
|
||||||
let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or(OsString::from_str(""));
|
let target_path = env::var_os("RUST_TARGET_PATH")
|
||||||
|
.unwrap_or(OsString::from_str(""));
|
||||||
|
|
||||||
// FIXME 16351: add a sane default search path?
|
// FIXME 16351: add a sane default search path?
|
||||||
|
|
||||||
for dir in os::split_paths(target_path.to_str().unwrap()).iter() {
|
for dir in env::split_paths(&target_path) {
|
||||||
let p = dir.join(path.clone());
|
let p = dir.join(&path);
|
||||||
if p.is_file() {
|
if p.is_file() {
|
||||||
return load_file(&p);
|
return load_file(&p);
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,10 @@ use super::Compilation;
|
|||||||
use serialize::json;
|
use serialize::json;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::os;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::old_io::fs;
|
use std::fs;
|
||||||
use std::old_io;
|
use std::io::{self, Write};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_map;
|
use syntax::ast_map;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
@ -48,8 +48,8 @@ use syntax;
|
|||||||
pub fn compile_input(sess: Session,
|
pub fn compile_input(sess: Session,
|
||||||
cfg: ast::CrateConfig,
|
cfg: ast::CrateConfig,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
outdir: &Option<Path>,
|
outdir: &Option<PathBuf>,
|
||||||
output: &Option<Path>,
|
output: &Option<PathBuf>,
|
||||||
addl_plugins: Option<Vec<String>>,
|
addl_plugins: Option<Vec<String>>,
|
||||||
control: CompileController) {
|
control: CompileController) {
|
||||||
macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
|
macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
|
||||||
@ -166,7 +166,7 @@ pub fn anon_src() -> String {
|
|||||||
pub fn source_name(input: &Input) -> String {
|
pub fn source_name(input: &Input) -> String {
|
||||||
match *input {
|
match *input {
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
Input::File(ref ifile) => ifile.as_str().unwrap().to_string(),
|
Input::File(ref ifile) => ifile.to_str().unwrap().to_string(),
|
||||||
Input::Str(_) => anon_src()
|
Input::Str(_) => anon_src()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,12 +243,12 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
|
|||||||
impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||||
fn empty(input: &'a Input,
|
fn empty(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>)
|
out_dir: &'a Option<PathBuf>)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
input: input,
|
input: input,
|
||||||
session: session,
|
session: session,
|
||||||
out_dir: out_dir.as_ref(),
|
out_dir: out_dir.as_ref().map(|s| &**s),
|
||||||
cfg: None,
|
cfg: None,
|
||||||
krate: None,
|
krate: None,
|
||||||
crate_name: None,
|
crate_name: None,
|
||||||
@ -263,7 +263,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
|||||||
|
|
||||||
fn state_after_parse(input: &'a Input,
|
fn state_after_parse(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>,
|
out_dir: &'a Option<PathBuf>,
|
||||||
krate: &'a ast::Crate)
|
krate: &'a ast::Crate)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
@ -274,7 +274,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
|||||||
|
|
||||||
fn state_after_expand(input: &'a Input,
|
fn state_after_expand(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>,
|
out_dir: &'a Option<PathBuf>,
|
||||||
expanded_crate: &'a ast::Crate,
|
expanded_crate: &'a ast::Crate,
|
||||||
crate_name: &'a str)
|
crate_name: &'a str)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
@ -287,7 +287,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
|||||||
|
|
||||||
fn state_after_write_deps(input: &'a Input,
|
fn state_after_write_deps(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>,
|
out_dir: &'a Option<PathBuf>,
|
||||||
ast_map: &'a ast_map::Map<'ast>,
|
ast_map: &'a ast_map::Map<'ast>,
|
||||||
expanded_crate: &'a ast::Crate,
|
expanded_crate: &'a ast::Crate,
|
||||||
crate_name: &'a str)
|
crate_name: &'a str)
|
||||||
@ -302,7 +302,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
|||||||
|
|
||||||
fn state_after_analysis(input: &'a Input,
|
fn state_after_analysis(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>,
|
out_dir: &'a Option<PathBuf>,
|
||||||
expanded_crate: &'a ast::Crate,
|
expanded_crate: &'a ast::Crate,
|
||||||
analysis: &'a ty::CrateAnalysis<'tcx>,
|
analysis: &'a ty::CrateAnalysis<'tcx>,
|
||||||
tcx: &'a ty::ctxt<'tcx>)
|
tcx: &'a ty::ctxt<'tcx>)
|
||||||
@ -318,7 +318,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
|||||||
|
|
||||||
fn state_after_llvm(input: &'a Input,
|
fn state_after_llvm(input: &'a Input,
|
||||||
session: &'a Session,
|
session: &'a Session,
|
||||||
out_dir: &'a Option<Path>,
|
out_dir: &'a Option<PathBuf>,
|
||||||
trans: &'a trans::CrateTranslation)
|
trans: &'a trans::CrateTranslation)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
@ -472,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
|||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
_old_path = env::var_os("PATH").unwrap_or(_old_path);
|
_old_path = env::var_os("PATH").unwrap_or(_old_path);
|
||||||
let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
|
let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
|
||||||
new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter());
|
new_path.extend(env::split_paths(&_old_path));
|
||||||
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
|
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
|
||||||
}
|
}
|
||||||
let features = sess.features.borrow();
|
let features = sess.features.borrow();
|
||||||
@ -717,7 +717,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
|
|||||||
|
|
||||||
// Remove assembly source, unless --save-temps was specified
|
// Remove assembly source, unless --save-temps was specified
|
||||||
if !sess.opts.cg.save_temps {
|
if !sess.opts.cg.save_temps {
|
||||||
fs::unlink(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
|
fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
time(sess.time_passes(), "LLVM passes", (), |_|
|
time(sess.time_passes(), "LLVM passes", (), |_|
|
||||||
@ -737,7 +737,7 @@ pub fn phase_6_link_output(sess: &Session,
|
|||||||
outputs: &OutputFilenames) {
|
outputs: &OutputFilenames) {
|
||||||
let old_path = env::var_os("PATH").unwrap_or(OsString::from_str(""));
|
let old_path = env::var_os("PATH").unwrap_or(OsString::from_str(""));
|
||||||
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
|
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
|
||||||
new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter());
|
new_path.extend(env::split_paths(&old_path));
|
||||||
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
|
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
|
||||||
|
|
||||||
time(sess.time_passes(), "linking", (), |_|
|
time(sess.time_passes(), "linking", (), |_|
|
||||||
@ -793,17 +793,17 @@ fn write_out_deps(sess: &Session,
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = (|| -> old_io::IoResult<()> {
|
let result = (|| -> io::Result<()> {
|
||||||
// Build a list of files used to compile the output and
|
// Build a list of files used to compile the output and
|
||||||
// write Makefile-compatible dependency rules
|
// write Makefile-compatible dependency rules
|
||||||
let files: Vec<String> = sess.codemap().files.borrow()
|
let files: Vec<String> = sess.codemap().files.borrow()
|
||||||
.iter().filter(|fmap| fmap.is_real_file())
|
.iter().filter(|fmap| fmap.is_real_file())
|
||||||
.map(|fmap| escape_dep_filename(&fmap.name))
|
.map(|fmap| escape_dep_filename(&fmap.name))
|
||||||
.collect();
|
.collect();
|
||||||
let mut file = try!(old_io::File::create(&deps_filename));
|
let mut file = try!(fs::File::create(&deps_filename));
|
||||||
for path in &out_filenames {
|
for path in &out_filenames {
|
||||||
try!(write!(&mut file as &mut Writer,
|
try!(write!(&mut file,
|
||||||
"{}: {}\n\n", path.display(), files.connect(" ")));
|
"{}: {}\n\n", path.display(), files.connect(" ")));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})();
|
})();
|
||||||
@ -896,8 +896,8 @@ pub fn collect_crate_metadata(session: &Session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_output_filenames(input: &Input,
|
pub fn build_output_filenames(input: &Input,
|
||||||
odir: &Option<Path>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<Path>,
|
ofile: &Option<PathBuf>,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
sess: &Session)
|
sess: &Session)
|
||||||
-> OutputFilenames {
|
-> OutputFilenames {
|
||||||
@ -908,7 +908,7 @@ pub fn build_output_filenames(input: &Input,
|
|||||||
// We want to toss everything after the final '.'
|
// We want to toss everything after the final '.'
|
||||||
let dirpath = match *odir {
|
let dirpath = match *odir {
|
||||||
Some(ref d) => d.clone(),
|
Some(ref d) => d.clone(),
|
||||||
None => Path::new(".")
|
None => PathBuf::new(".")
|
||||||
};
|
};
|
||||||
|
|
||||||
// If a crate name is present, we use it as the link name
|
// If a crate name is present, we use it as the link name
|
||||||
@ -936,8 +936,9 @@ pub fn build_output_filenames(input: &Input,
|
|||||||
sess.warn("ignoring --out-dir flag due to -o flag.");
|
sess.warn("ignoring --out-dir flag due to -o flag.");
|
||||||
}
|
}
|
||||||
OutputFilenames {
|
OutputFilenames {
|
||||||
out_directory: out_file.dir_path(),
|
out_directory: out_file.parent().unwrap().to_path_buf(),
|
||||||
out_filestem: out_file.filestem_str().unwrap().to_string(),
|
out_filestem: out_file.file_stem().unwrap()
|
||||||
|
.to_str().unwrap().to_string(),
|
||||||
single_output_file: ofile,
|
single_output_file: ofile,
|
||||||
extra: sess.opts.cg.extra_filename.clone(),
|
extra: sess.opts.cg.extra_filename.clone(),
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#![feature(old_io)]
|
#![feature(old_io)]
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
#![feature(os)]
|
#![feature(os)]
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(quote)]
|
#![feature(quote)]
|
||||||
#![feature(rustc_diagnostic_macros)]
|
#![feature(rustc_diagnostic_macros)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
@ -38,6 +37,9 @@
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(exit_status)]
|
#![feature(exit_status)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(io)]
|
||||||
|
#![feature(fs)]
|
||||||
|
|
||||||
extern crate arena;
|
extern crate arena;
|
||||||
extern crate flate;
|
extern crate flate;
|
||||||
@ -73,9 +75,10 @@ use rustc::metadata;
|
|||||||
use rustc::util::common::time;
|
use rustc::util::common::time;
|
||||||
|
|
||||||
use std::cmp::Ordering::Equal;
|
use std::cmp::Ordering::Equal;
|
||||||
use std::old_io::{self, stdio};
|
|
||||||
use std::iter::repeat;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::iter::repeat;
|
||||||
|
use std::old_io::{self, stdio};
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
@ -159,14 +162,14 @@ pub fn run_compiler<'a>(args: &[String],
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract output directory and file from matches.
|
// Extract output directory and file from matches.
|
||||||
fn make_output(matches: &getopts::Matches) -> (Option<Path>, Option<Path>) {
|
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
|
||||||
let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
|
let odir = matches.opt_str("out-dir").map(|o| PathBuf::new(&o));
|
||||||
let ofile = matches.opt_str("o").map(|o| Path::new(o));
|
let ofile = matches.opt_str("o").map(|o| PathBuf::new(&o));
|
||||||
(odir, ofile)
|
(odir, ofile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract input (string or file and optional path) from matches.
|
// Extract input (string or file and optional path) from matches.
|
||||||
fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> {
|
fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
|
||||||
if free_matches.len() == 1 {
|
if free_matches.len() == 1 {
|
||||||
let ifile = &free_matches[0][..];
|
let ifile = &free_matches[0][..];
|
||||||
if ifile == "-" {
|
if ifile == "-" {
|
||||||
@ -174,7 +177,7 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> {
|
|||||||
let src = String::from_utf8(contents).unwrap();
|
let src = String::from_utf8(contents).unwrap();
|
||||||
Some((Input::Str(src), None))
|
Some((Input::Str(src), None))
|
||||||
} else {
|
} else {
|
||||||
Some((Input::File(Path::new(ifile)), Some(Path::new(ifile))))
|
Some((Input::File(PathBuf::new(ifile)), Some(PathBuf::new(ifile))))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -215,14 +218,15 @@ pub trait CompilerCalls<'a> {
|
|||||||
&getopts::Matches,
|
&getopts::Matches,
|
||||||
&Session,
|
&Session,
|
||||||
&Input,
|
&Input,
|
||||||
&Option<Path>,
|
&Option<PathBuf>,
|
||||||
&Option<Path>)
|
&Option<PathBuf>)
|
||||||
-> Compilation;
|
-> Compilation;
|
||||||
|
|
||||||
// Called after we extract the input from the arguments. Gives the implementer
|
// Called after we extract the input from the arguments. Gives the implementer
|
||||||
// an opportunity to change the inputs or to add some custom input handling.
|
// an opportunity to change the inputs or to add some custom input handling.
|
||||||
// The default behaviour is to simply pass through the inputs.
|
// The default behaviour is to simply pass through the inputs.
|
||||||
fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
|
fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
|
||||||
|
-> (Input, Option<PathBuf>) {
|
||||||
(input, input_path)
|
(input, input_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,10 +238,10 @@ pub trait CompilerCalls<'a> {
|
|||||||
fn no_input(&mut self,
|
fn no_input(&mut self,
|
||||||
&getopts::Matches,
|
&getopts::Matches,
|
||||||
&config::Options,
|
&config::Options,
|
||||||
&Option<Path>,
|
&Option<PathBuf>,
|
||||||
&Option<Path>,
|
&Option<PathBuf>,
|
||||||
&diagnostics::registry::Registry)
|
&diagnostics::registry::Registry)
|
||||||
-> Option<(Input, Option<Path>)>;
|
-> Option<(Input, Option<PathBuf>)>;
|
||||||
|
|
||||||
// Parse pretty printing information from the arguments. The implementer can
|
// Parse pretty printing information from the arguments. The implementer can
|
||||||
// choose to ignore this (the default will return None) which will skip pretty
|
// choose to ignore this (the default will return None) which will skip pretty
|
||||||
@ -293,10 +297,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||||||
fn no_input(&mut self,
|
fn no_input(&mut self,
|
||||||
matches: &getopts::Matches,
|
matches: &getopts::Matches,
|
||||||
sopts: &config::Options,
|
sopts: &config::Options,
|
||||||
odir: &Option<Path>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<Path>,
|
ofile: &Option<PathBuf>,
|
||||||
descriptions: &diagnostics::registry::Registry)
|
descriptions: &diagnostics::registry::Registry)
|
||||||
-> Option<(Input, Option<Path>)> {
|
-> Option<(Input, Option<PathBuf>)> {
|
||||||
match matches.free.len() {
|
match matches.free.len() {
|
||||||
0 => {
|
0 => {
|
||||||
if sopts.describe_lints {
|
if sopts.describe_lints {
|
||||||
@ -346,8 +350,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||||||
matches: &getopts::Matches,
|
matches: &getopts::Matches,
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
odir: &Option<Path>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<Path>)
|
ofile: &Option<PathBuf>)
|
||||||
-> Compilation {
|
-> Compilation {
|
||||||
RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then(
|
RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then(
|
||||||
|| RustcDefaultCalls::list_metadata(sess, matches, input))
|
|| RustcDefaultCalls::list_metadata(sess, matches, input))
|
||||||
@ -400,11 +404,12 @@ impl RustcDefaultCalls {
|
|||||||
if r.contains(&("ls".to_string())) {
|
if r.contains(&("ls".to_string())) {
|
||||||
match input {
|
match input {
|
||||||
&Input::File(ref ifile) => {
|
&Input::File(ref ifile) => {
|
||||||
let mut stdout = old_io::stdout();
|
|
||||||
let path = &(*ifile);
|
let path = &(*ifile);
|
||||||
|
let mut v = Vec::new();
|
||||||
metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx,
|
metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx,
|
||||||
path,
|
path,
|
||||||
&mut stdout).unwrap();
|
&mut v).unwrap();
|
||||||
|
println!("{}", String::from_utf8(v).unwrap());
|
||||||
}
|
}
|
||||||
&Input::Str(_) => {
|
&Input::Str(_) => {
|
||||||
early_error("cannot list metadata for stdin");
|
early_error("cannot list metadata for stdin");
|
||||||
@ -419,8 +424,8 @@ impl RustcDefaultCalls {
|
|||||||
|
|
||||||
fn print_crate_info(sess: &Session,
|
fn print_crate_info(sess: &Session,
|
||||||
input: Option<&Input>,
|
input: Option<&Input>,
|
||||||
odir: &Option<Path>,
|
odir: &Option<PathBuf>,
|
||||||
ofile: &Option<Path>)
|
ofile: &Option<PathBuf>)
|
||||||
-> Compilation {
|
-> Compilation {
|
||||||
if sess.opts.prints.len() == 0 {
|
if sess.opts.prints.len() == 0 {
|
||||||
return Compilation::Continue;
|
return Compilation::Continue;
|
||||||
@ -457,7 +462,8 @@ impl RustcDefaultCalls {
|
|||||||
style,
|
style,
|
||||||
&id,
|
&id,
|
||||||
&t_outputs.with_extension(""));
|
&t_outputs.with_extension(""));
|
||||||
println!("{}", fname.filename_display());
|
println!("{}", fname.file_name().unwrap()
|
||||||
|
.to_string_lossy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,11 @@ use syntax::ptr::P;
|
|||||||
|
|
||||||
use graphviz as dot;
|
use graphviz as dot;
|
||||||
|
|
||||||
use std::old_io::{self, MemReader};
|
use std::fs::File;
|
||||||
|
use std::io::{self, Write};
|
||||||
|
use std::old_io;
|
||||||
use std::option;
|
use std::option;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Copy, PartialEq, Debug)]
|
#[derive(Copy, PartialEq, Debug)]
|
||||||
@ -208,7 +211,7 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
|||||||
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
||||||
fn pre(&self,
|
fn pre(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
match node {
|
match node {
|
||||||
pprust::NodeExpr(_) => s.popen(),
|
pprust::NodeExpr(_) => s.popen(),
|
||||||
_ => Ok(())
|
_ => Ok(())
|
||||||
@ -216,7 +219,7 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
|||||||
}
|
}
|
||||||
fn post(&self,
|
fn post(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
match node {
|
match node {
|
||||||
pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()),
|
pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()),
|
||||||
|
|
||||||
@ -259,7 +262,7 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
|
|||||||
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
|
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
|
||||||
fn post(&self,
|
fn post(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
match node {
|
match node {
|
||||||
pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => {
|
pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => {
|
||||||
try!(pp::space(&mut s.s));
|
try!(pp::space(&mut s.s));
|
||||||
@ -294,7 +297,7 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
|
|||||||
impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
|
impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
|
||||||
fn pre(&self,
|
fn pre(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
match node {
|
match node {
|
||||||
pprust::NodeExpr(_) => s.popen(),
|
pprust::NodeExpr(_) => s.popen(),
|
||||||
_ => Ok(())
|
_ => Ok(())
|
||||||
@ -302,7 +305,7 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
|
|||||||
}
|
}
|
||||||
fn post(&self,
|
fn post(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> old_io::IoResult<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
let tcx = &self.analysis.ty_cx;
|
let tcx = &self.analysis.ty_cx;
|
||||||
match node {
|
match node {
|
||||||
pprust::NodeExpr(expr) => {
|
pprust::NodeExpr(expr) => {
|
||||||
@ -507,7 +510,7 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
input: &Input,
|
input: &Input,
|
||||||
ppm: PpMode,
|
ppm: PpMode,
|
||||||
opt_uii: Option<UserIdentifiedItem>,
|
opt_uii: Option<UserIdentifiedItem>,
|
||||||
ofile: Option<Path>) {
|
ofile: Option<PathBuf>) {
|
||||||
let krate = driver::phase_1_parse_input(&sess, cfg, input);
|
let krate = driver::phase_1_parse_input(&sess, cfg, input);
|
||||||
|
|
||||||
let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
|
let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
|
||||||
@ -547,24 +550,15 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.to_vec();
|
.to_vec();
|
||||||
let mut rdr = MemReader::new(src);
|
let mut rdr = &src[..];
|
||||||
|
|
||||||
let out = match ofile {
|
let mut out = Vec::new();
|
||||||
None => box old_io::stdout() as Box<Writer+'static>,
|
|
||||||
Some(p) => {
|
|
||||||
let r = old_io::File::create(&p);
|
|
||||||
match r {
|
|
||||||
Ok(w) => box w as Box<Writer+'static>,
|
|
||||||
Err(e) => panic!("print-print failed to open {} due to {}",
|
|
||||||
p.display(), e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match (ppm, opt_uii) {
|
match (ppm, opt_uii) {
|
||||||
(PpmSource(s), None) =>
|
(PpmSource(s), None) => {
|
||||||
|
let out: &mut Write = &mut out;
|
||||||
s.call_with_pp_support(
|
s.call_with_pp_support(
|
||||||
sess, ast_map, &arenas, id, out, |annotation, out| {
|
sess, ast_map, &arenas, id, box out, |annotation, out| {
|
||||||
debug!("pretty printing source code {:?}", s);
|
debug!("pretty printing source code {:?}", s);
|
||||||
let sess = annotation.sess();
|
let sess = annotation.sess();
|
||||||
pprust::print_crate(sess.codemap(),
|
pprust::print_crate(sess.codemap(),
|
||||||
@ -575,9 +569,11 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
out,
|
out,
|
||||||
annotation.pp_ann(),
|
annotation.pp_ann(),
|
||||||
is_expanded)
|
is_expanded)
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
|
||||||
(PpmSource(s), Some(uii)) =>
|
(PpmSource(s), Some(uii)) => {
|
||||||
|
let out: &mut Write = &mut out;
|
||||||
s.call_with_pp_support(
|
s.call_with_pp_support(
|
||||||
sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
|
sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
|
||||||
debug!("pretty printing source code {:?}", s);
|
debug!("pretty printing source code {:?}", s);
|
||||||
@ -589,7 +585,7 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
sess.diagnostic(),
|
sess.diagnostic(),
|
||||||
src_name.to_string(),
|
src_name.to_string(),
|
||||||
&mut rdr,
|
&mut rdr,
|
||||||
out,
|
box out,
|
||||||
annotation.pp_ann(),
|
annotation.pp_ann(),
|
||||||
is_expanded);
|
is_expanded);
|
||||||
for node_id in uii.all_matching_node_ids(ast_map) {
|
for node_id in uii.all_matching_node_ids(ast_map) {
|
||||||
@ -600,7 +596,8 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
try!(pp::hardbreak(&mut pp_state.s));
|
try!(pp::hardbreak(&mut pp_state.s));
|
||||||
}
|
}
|
||||||
pp::eof(&mut pp_state.s)
|
pp::eof(&mut pp_state.s)
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
|
||||||
(PpmFlowGraph(mode), opt_uii) => {
|
(PpmFlowGraph(mode), opt_uii) => {
|
||||||
debug!("pretty printing flow graph for {:?}", opt_uii);
|
debug!("pretty printing flow graph for {:?}", opt_uii);
|
||||||
@ -618,6 +615,7 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
});
|
});
|
||||||
|
|
||||||
let code = blocks::Code::from_node(node);
|
let code = blocks::Code::from_node(node);
|
||||||
|
let out: &mut Writer = &mut out;
|
||||||
match code {
|
match code {
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
let variants = gather_flowgraph_variants(&sess);
|
let variants = gather_flowgraph_variants(&sess);
|
||||||
@ -642,14 +640,25 @@ pub fn pretty_print_input(sess: Session,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.unwrap()
|
}.unwrap();
|
||||||
|
|
||||||
|
match ofile {
|
||||||
|
None => print!("{}", String::from_utf8(out).unwrap()),
|
||||||
|
Some(p) => {
|
||||||
|
match File::create(&p) {
|
||||||
|
Ok(mut w) => w.write_all(&out).unwrap(),
|
||||||
|
Err(e) => panic!("print-print failed to open {} due to {}",
|
||||||
|
p.display(), e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
|
fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
|
||||||
analysis: ty::CrateAnalysis,
|
analysis: ty::CrateAnalysis,
|
||||||
code: blocks::Code,
|
code: blocks::Code,
|
||||||
mode: PpFlowGraphMode,
|
mode: PpFlowGraphMode,
|
||||||
mut out: W) -> old_io::IoResult<()> {
|
mut out: W) -> io::Result<()> {
|
||||||
let ty_cx = &analysis.ty_cx;
|
let ty_cx = &analysis.ty_cx;
|
||||||
let cfg = match code {
|
let cfg = match code {
|
||||||
blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
|
blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
|
||||||
@ -689,17 +698,10 @@ fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_err_details(r: old_io::IoResult<()>) -> old_io::IoResult<()> {
|
fn expand_err_details(r: old_io::IoResult<()>) -> io::Result<()> {
|
||||||
r.map_err(|ioerr| {
|
r.map_err(|ioerr| {
|
||||||
let orig_detail = ioerr.detail.clone();
|
io::Error::new(io::ErrorKind::Other, "graphviz::render failed",
|
||||||
let m = "graphviz::render failed";
|
Some(ioerr.to_string()))
|
||||||
old_io::IoError {
|
|
||||||
detail: Some(match orig_detail {
|
|
||||||
None => m.to_string(),
|
|
||||||
Some(d) => format!("{}: {}", m, d)
|
|
||||||
}),
|
|
||||||
..ioerr
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use ArchiveRef;
|
|||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::raw;
|
use std::raw;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
pub struct ArchiveRO {
|
pub struct ArchiveRO {
|
||||||
ptr: ArchiveRef,
|
ptr: ArchiveRef,
|
||||||
@ -29,14 +30,25 @@ impl ArchiveRO {
|
|||||||
/// If this archive is used with a mutable method, then an error will be
|
/// If this archive is used with a mutable method, then an error will be
|
||||||
/// raised.
|
/// raised.
|
||||||
pub fn open(dst: &Path) -> Option<ArchiveRO> {
|
pub fn open(dst: &Path) -> Option<ArchiveRO> {
|
||||||
unsafe {
|
return unsafe {
|
||||||
let s = CString::new(dst.as_vec()).unwrap();
|
let s = path2cstr(dst);
|
||||||
let ar = ::LLVMRustOpenArchive(s.as_ptr());
|
let ar = ::LLVMRustOpenArchive(s.as_ptr());
|
||||||
if ar.is_null() {
|
if ar.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(ArchiveRO { ptr: ar })
|
Some(ArchiveRO { ptr: ar })
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn path2cstr(p: &Path) -> CString {
|
||||||
|
use std::os::unix::prelude::*;
|
||||||
|
use std::ffi::AsOsStr;
|
||||||
|
CString::new(p.as_os_str().as_bytes()).unwrap()
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn path2cstr(p: &Path) -> CString {
|
||||||
|
CString::new(p.to_str().unwrap()).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@
|
|||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
#![feature(link_args)]
|
#![feature(link_args)]
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
|
#![feature(path)]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
||||||
|
@ -27,12 +27,13 @@ use util::common::time;
|
|||||||
use util::ppaux;
|
use util::ppaux;
|
||||||
use util::sha2::{Digest, Sha256};
|
use util::sha2::{Digest, Sha256};
|
||||||
|
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::ffi::{AsOsStr, OsString};
|
||||||
use std::old_io::{fs, TempDir, Command};
|
use std::fs::{self, TempDir, PathExt};
|
||||||
use std::old_io;
|
use std::io::{self, Read, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::string::String;
|
|
||||||
use flate;
|
use flate;
|
||||||
use serialize::hex::ToHex;
|
use serialize::hex::ToHex;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@ -156,7 +157,7 @@ pub fn find_crate_name(sess: Option<&Session>,
|
|||||||
return validate(s.to_string(), Some(attr.span));
|
return validate(s.to_string(), Some(attr.span));
|
||||||
}
|
}
|
||||||
if let Input::File(ref path) = *input {
|
if let Input::File(ref path) = *input {
|
||||||
if let Some(s) = path.filestem_str() {
|
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
|
||||||
return validate(s.to_string(), None);
|
return validate(s.to_string(), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -356,7 +357,7 @@ pub fn get_cc_prog(sess: &Session) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(sess: &Session, path: &Path) {
|
pub fn remove(sess: &Session, path: &Path) {
|
||||||
match fs::unlink(path) {
|
match fs::remove_file(path) {
|
||||||
Ok(..) => {}
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.err(&format!("failed to remove {}: {}",
|
sess.err(&format!("failed to remove {}: {}",
|
||||||
@ -371,7 +372,7 @@ pub fn remove(sess: &Session, path: &Path) {
|
|||||||
pub fn link_binary(sess: &Session,
|
pub fn link_binary(sess: &Session,
|
||||||
trans: &CrateTranslation,
|
trans: &CrateTranslation,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
crate_name: &str) -> Vec<Path> {
|
crate_name: &str) -> Vec<PathBuf> {
|
||||||
let mut out_filenames = Vec::new();
|
let mut out_filenames = Vec::new();
|
||||||
for &crate_type in &*sess.crate_types.borrow() {
|
for &crate_type in &*sess.crate_types.borrow() {
|
||||||
if invalid_output_for_target(sess, crate_type) {
|
if invalid_output_for_target(sess, crate_type) {
|
||||||
@ -425,35 +426,35 @@ pub fn invalid_output_for_target(sess: &Session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_writeable(p: &Path) -> bool {
|
fn is_writeable(p: &Path) -> bool {
|
||||||
match p.stat() {
|
match p.metadata() {
|
||||||
Err(..) => true,
|
Err(..) => true,
|
||||||
Ok(m) => m.perm & old_io::USER_WRITE == old_io::USER_WRITE
|
Ok(m) => !m.permissions().readonly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filename_for_input(sess: &Session,
|
pub fn filename_for_input(sess: &Session,
|
||||||
crate_type: config::CrateType,
|
crate_type: config::CrateType,
|
||||||
name: &str,
|
name: &str,
|
||||||
out_filename: &Path) -> Path {
|
out_filename: &Path) -> PathBuf {
|
||||||
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
|
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
|
||||||
match crate_type {
|
match crate_type {
|
||||||
config::CrateTypeRlib => {
|
config::CrateTypeRlib => {
|
||||||
out_filename.with_filename(format!("lib{}.rlib", libname))
|
out_filename.with_file_name(&format!("lib{}.rlib", libname))
|
||||||
}
|
}
|
||||||
config::CrateTypeDylib => {
|
config::CrateTypeDylib => {
|
||||||
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
|
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
|
||||||
&sess.target.target.options.dll_suffix);
|
&sess.target.target.options.dll_suffix);
|
||||||
out_filename.with_filename(format!("{}{}{}",
|
out_filename.with_file_name(&format!("{}{}{}",
|
||||||
prefix,
|
prefix,
|
||||||
libname,
|
libname,
|
||||||
suffix))
|
suffix))
|
||||||
}
|
}
|
||||||
config::CrateTypeStaticlib => {
|
config::CrateTypeStaticlib => {
|
||||||
out_filename.with_filename(format!("lib{}.a", libname))
|
out_filename.with_file_name(&format!("lib{}.a", libname))
|
||||||
}
|
}
|
||||||
config::CrateTypeExecutable => {
|
config::CrateTypeExecutable => {
|
||||||
let suffix = &sess.target.target.options.exe_suffix;
|
let suffix = &sess.target.target.options.exe_suffix;
|
||||||
out_filename.with_filename(format!("{}{}", libname, suffix))
|
out_filename.with_file_name(&format!("{}{}", libname, suffix))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,7 +463,7 @@ fn link_binary_output(sess: &Session,
|
|||||||
trans: &CrateTranslation,
|
trans: &CrateTranslation,
|
||||||
crate_type: config::CrateType,
|
crate_type: config::CrateType,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
crate_name: &str) -> Path {
|
crate_name: &str) -> PathBuf {
|
||||||
let obj_filename = outputs.temp_path(OutputTypeObject);
|
let obj_filename = outputs.temp_path(OutputTypeObject);
|
||||||
let out_filename = match outputs.single_output_file {
|
let out_filename = match outputs.single_output_file {
|
||||||
Some(ref file) => file.clone(),
|
Some(ref file) => file.clone(),
|
||||||
@ -507,10 +508,10 @@ fn link_binary_output(sess: &Session,
|
|||||||
out_filename
|
out_filename
|
||||||
}
|
}
|
||||||
|
|
||||||
fn archive_search_paths(sess: &Session) -> Vec<Path> {
|
fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
|
||||||
let mut search = Vec::new();
|
let mut search = Vec::new();
|
||||||
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
|
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
|
||||||
search.push(path.clone());
|
search.push(path.to_path_buf());
|
||||||
FileDoesntMatch
|
FileDoesntMatch
|
||||||
});
|
});
|
||||||
return search;
|
return search;
|
||||||
@ -529,7 +530,7 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
let handler = &sess.diagnostic().handler;
|
let handler = &sess.diagnostic().handler;
|
||||||
let config = ArchiveConfig {
|
let config = ArchiveConfig {
|
||||||
handler: handler,
|
handler: handler,
|
||||||
dst: out_filename.clone(),
|
dst: out_filename.to_path_buf(),
|
||||||
lib_search_paths: archive_search_paths(sess),
|
lib_search_paths: archive_search_paths(sess),
|
||||||
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
|
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
|
||||||
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
|
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
|
||||||
@ -588,7 +589,9 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
// the same filename for metadata (stomping over one another)
|
// the same filename for metadata (stomping over one another)
|
||||||
let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
|
let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
|
||||||
let metadata = tmpdir.path().join(METADATA_FILENAME);
|
let metadata = tmpdir.path().join(METADATA_FILENAME);
|
||||||
match fs::File::create(&metadata).write_all(&trans.metadata) {
|
match fs::File::create(&metadata).and_then(|mut f| {
|
||||||
|
f.write_all(&trans.metadata)
|
||||||
|
}) {
|
||||||
Ok(..) => {}
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.err(&format!("failed to write {}: {}",
|
sess.err(&format!("failed to write {}: {}",
|
||||||
@ -613,28 +616,32 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
let bc_deflated_filename = obj_filename.with_extension(
|
let bc_deflated_filename = obj_filename.with_extension(
|
||||||
&format!("{}.bytecode.deflate", i));
|
&format!("{}.bytecode.deflate", i));
|
||||||
|
|
||||||
let bc_data = match fs::File::open(&bc_filename).read_to_end() {
|
let mut bc_data = Vec::new();
|
||||||
Ok(buffer) => buffer,
|
match fs::File::open(&bc_filename).and_then(|mut f| {
|
||||||
|
f.read_to_end(&mut bc_data)
|
||||||
|
}) {
|
||||||
|
Ok(..) => {}
|
||||||
Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
|
Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
|
||||||
e))
|
e))
|
||||||
};
|
}
|
||||||
|
|
||||||
let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
|
let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
|
||||||
Some(compressed) => compressed,
|
Some(compressed) => compressed,
|
||||||
None => sess.fatal(&format!("failed to compress bytecode from {}",
|
None => sess.fatal(&format!("failed to compress bytecode \
|
||||||
bc_filename.display()))
|
from {}",
|
||||||
|
bc_filename.display()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
|
let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.fatal(&format!("failed to create compressed bytecode \
|
sess.fatal(&format!("failed to create compressed \
|
||||||
file: {}", e))
|
bytecode file: {}", e))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
|
match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
|
||||||
bc_data_deflated.as_slice()) {
|
&bc_data_deflated) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.err(&format!("failed to write compressed bytecode: \
|
sess.err(&format!("failed to write compressed bytecode: \
|
||||||
@ -670,15 +677,23 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||||||
ab
|
ab
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
|
fn write_rlib_bytecode_object_v1(writer: &mut Write,
|
||||||
bc_data_deflated: &[u8])
|
bc_data_deflated: &[u8]) -> io::Result<()> {
|
||||||
-> ::std::old_io::IoResult<()> {
|
|
||||||
let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
|
let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
|
||||||
|
|
||||||
try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) };
|
try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC));
|
||||||
try! { writer.write_le_u32(1) };
|
try!(writer.write_all(&[1, 0, 0, 0]));
|
||||||
try! { writer.write_le_u64(bc_data_deflated_size) };
|
try!(writer.write_all(&[
|
||||||
try! { writer.write_all(&bc_data_deflated[..]) };
|
(bc_data_deflated_size >> 0) as u8,
|
||||||
|
(bc_data_deflated_size >> 8) as u8,
|
||||||
|
(bc_data_deflated_size >> 16) as u8,
|
||||||
|
(bc_data_deflated_size >> 24) as u8,
|
||||||
|
(bc_data_deflated_size >> 32) as u8,
|
||||||
|
(bc_data_deflated_size >> 40) as u8,
|
||||||
|
(bc_data_deflated_size >> 48) as u8,
|
||||||
|
(bc_data_deflated_size >> 56) as u8,
|
||||||
|
]));
|
||||||
|
try!(writer.write_all(&bc_data_deflated));
|
||||||
|
|
||||||
let number_of_bytes_written_so_far =
|
let number_of_bytes_written_so_far =
|
||||||
RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id
|
RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id
|
||||||
@ -690,7 +705,7 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
|
|||||||
// padding byte to make it even. This works around a crash bug in LLDB
|
// padding byte to make it even. This works around a crash bug in LLDB
|
||||||
// (see issue #15950)
|
// (see issue #15950)
|
||||||
if number_of_bytes_written_so_far % 2 == 1 {
|
if number_of_bytes_written_so_far % 2 == 1 {
|
||||||
try! { writer.write_u8(0) };
|
try!(writer.write_all(&[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -796,13 +811,13 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
|
|||||||
pname,
|
pname,
|
||||||
prog.status));
|
prog.status));
|
||||||
sess.note(&format!("{:?}", &cmd));
|
sess.note(&format!("{:?}", &cmd));
|
||||||
let mut output = prog.error.clone();
|
let mut output = prog.stderr.clone();
|
||||||
output.push_all(&prog.output);
|
output.push_all(&prog.stdout);
|
||||||
sess.note(str::from_utf8(&output[..]).unwrap());
|
sess.note(str::from_utf8(&output[..]).unwrap());
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
}
|
}
|
||||||
debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap());
|
debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap());
|
||||||
debug!("linker stdout:\n{}", String::from_utf8(prog.output).unwrap());
|
debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap());
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.err(&format!("could not exec the linker `{}`: {}",
|
sess.err(&format!("could not exec the linker `{}`: {}",
|
||||||
@ -866,9 +881,9 @@ fn link_args(cmd: &mut Command,
|
|||||||
if t.options.is_like_osx {
|
if t.options.is_like_osx {
|
||||||
let morestack = lib_path.join("libmorestack.a");
|
let morestack = lib_path.join("libmorestack.a");
|
||||||
|
|
||||||
let mut v = b"-Wl,-force_load,".to_vec();
|
let mut v = OsString::from_str("-Wl,-force_load,");
|
||||||
v.push_all(morestack.as_vec());
|
v.push_os_str(morestack.as_os_str());
|
||||||
cmd.arg(&v[..]);
|
cmd.arg(&v);
|
||||||
} else {
|
} else {
|
||||||
cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
|
cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
|
||||||
}
|
}
|
||||||
@ -878,7 +893,7 @@ fn link_args(cmd: &mut Command,
|
|||||||
// executable. This metadata is in a separate object file from the main
|
// executable. This metadata is in a separate object file from the main
|
||||||
// object file, so we link that in here.
|
// object file, so we link that in here.
|
||||||
if dylib {
|
if dylib {
|
||||||
cmd.arg(obj_filename.with_extension("metadata.o"));
|
cmd.arg(&obj_filename.with_extension("metadata.o"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.options.is_like_osx {
|
if t.options.is_like_osx {
|
||||||
@ -991,9 +1006,9 @@ fn link_args(cmd: &mut Command,
|
|||||||
cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
|
cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
|
||||||
|
|
||||||
if sess.opts.cg.rpath {
|
if sess.opts.cg.rpath {
|
||||||
let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec();
|
let mut v = OsString::from_str("-Wl,-install_name,@rpath/");
|
||||||
v.push_all(out_filename.filename().unwrap());
|
v.push_os_str(out_filename.file_name().unwrap());
|
||||||
cmd.arg(&v[..]);
|
cmd.arg(&v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd.arg("-shared");
|
cmd.arg("-shared");
|
||||||
@ -1006,23 +1021,23 @@ fn link_args(cmd: &mut Command,
|
|||||||
if sess.opts.cg.rpath {
|
if sess.opts.cg.rpath {
|
||||||
let sysroot = sess.sysroot();
|
let sysroot = sess.sysroot();
|
||||||
let target_triple = &sess.opts.target_triple;
|
let target_triple = &sess.opts.target_triple;
|
||||||
let get_install_prefix_lib_path = || {
|
let mut get_install_prefix_lib_path = || {
|
||||||
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
|
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
|
||||||
let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
|
let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
|
||||||
let mut path = Path::new(install_prefix);
|
let mut path = PathBuf::new(install_prefix);
|
||||||
path.push(&tlib);
|
path.push(&tlib);
|
||||||
|
|
||||||
path
|
path
|
||||||
};
|
};
|
||||||
let rpath_config = RPathConfig {
|
let mut rpath_config = RPathConfig {
|
||||||
used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
|
used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
|
||||||
out_filename: out_filename.clone(),
|
out_filename: out_filename.to_path_buf(),
|
||||||
has_rpath: sess.target.target.options.has_rpath,
|
has_rpath: sess.target.target.options.has_rpath,
|
||||||
is_like_osx: sess.target.target.options.is_like_osx,
|
is_like_osx: sess.target.target.options.is_like_osx,
|
||||||
get_install_prefix_lib_path: get_install_prefix_lib_path,
|
get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
|
||||||
realpath: ::util::fs::realpath
|
realpath: &mut ::util::fs::realpath
|
||||||
};
|
};
|
||||||
cmd.args(&rpath::get_rpath_flags(rpath_config));
|
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally add all the linker arguments provided on the command line along
|
// Finally add all the linker arguments provided on the command line along
|
||||||
@ -1082,7 +1097,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||||||
let search_path = archive_search_paths(sess);
|
let search_path = archive_search_paths(sess);
|
||||||
for l in staticlibs {
|
for l in staticlibs {
|
||||||
if takes_hints {
|
if takes_hints {
|
||||||
cmd.arg(format!("-l{}", l));
|
cmd.arg(&format!("-l{}", l));
|
||||||
} else {
|
} else {
|
||||||
// -force_load is the OSX equivalent of --whole-archive, but it
|
// -force_load is the OSX equivalent of --whole-archive, but it
|
||||||
// involves passing the full path to the library to link.
|
// involves passing the full path to the library to link.
|
||||||
@ -1091,9 +1106,9 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||||||
&sess.target.target.options.staticlib_suffix,
|
&sess.target.target.options.staticlib_suffix,
|
||||||
&search_path[..],
|
&search_path[..],
|
||||||
&sess.diagnostic().handler);
|
&sess.diagnostic().handler);
|
||||||
let mut v = b"-Wl,-force_load,".to_vec();
|
let mut v = OsString::from_str("-Wl,-force_load,");
|
||||||
v.push_all(lib.as_vec());
|
v.push_os_str(lib.as_os_str());
|
||||||
cmd.arg(&v[..]);
|
cmd.arg(&v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if takes_hints {
|
if takes_hints {
|
||||||
@ -1103,7 +1118,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||||||
for &(ref l, kind) in others {
|
for &(ref l, kind) in others {
|
||||||
match kind {
|
match kind {
|
||||||
cstore::NativeUnknown => {
|
cstore::NativeUnknown => {
|
||||||
cmd.arg(format!("-l{}", l));
|
cmd.arg(&format!("-l{}", l));
|
||||||
}
|
}
|
||||||
cstore::NativeFramework => {
|
cstore::NativeFramework => {
|
||||||
cmd.arg("-framework").arg(&l[..]);
|
cmd.arg("-framework").arg(&l[..]);
|
||||||
@ -1150,18 +1165,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
let src = sess.cstore.get_used_crate_source(cnum).unwrap();
|
let src = sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||||
match kind {
|
match kind {
|
||||||
cstore::RequireDynamic => {
|
cstore::RequireDynamic => {
|
||||||
add_dynamic_crate(cmd, sess, src.dylib.unwrap().0)
|
add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
|
||||||
}
|
}
|
||||||
cstore::RequireStatic => {
|
cstore::RequireStatic => {
|
||||||
add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap().0)
|
add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a library file-stem into a cc -l argument
|
// Converts a library file-stem into a cc -l argument
|
||||||
fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] {
|
fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
|
||||||
if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows {
|
if stem.starts_with("lib") && !config.target.options.is_like_windows {
|
||||||
&stem[3..]
|
&stem[3..]
|
||||||
} else {
|
} else {
|
||||||
stem
|
stem
|
||||||
@ -1170,7 +1185,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
|
|
||||||
// Adds the static "rlib" versions of all crates to the command line.
|
// Adds the static "rlib" versions of all crates to the command line.
|
||||||
fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
|
fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
|
||||||
cratepath: Path) {
|
cratepath: &Path) {
|
||||||
// When performing LTO on an executable output, all of the
|
// When performing LTO on an executable output, all of the
|
||||||
// bytecode from the upstream libraries has already been
|
// bytecode from the upstream libraries has already been
|
||||||
// included in our object file output. We need to modify all of
|
// included in our object file output. We need to modify all of
|
||||||
@ -1186,12 +1201,12 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
// If we're not doing LTO, then our job is simply to just link
|
// If we're not doing LTO, then our job is simply to just link
|
||||||
// against the archive.
|
// against the archive.
|
||||||
if sess.lto() {
|
if sess.lto() {
|
||||||
let name = cratepath.filename_str().unwrap();
|
let name = cratepath.file_name().unwrap().to_str().unwrap();
|
||||||
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
|
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
|
||||||
time(sess.time_passes(),
|
time(sess.time_passes(),
|
||||||
&format!("altering {}.rlib", name),
|
&format!("altering {}.rlib", name),
|
||||||
(), |()| {
|
(), |()| {
|
||||||
let dst = tmpdir.join(cratepath.filename().unwrap());
|
let dst = tmpdir.join(cratepath.file_name().unwrap());
|
||||||
match fs::copy(&cratepath, &dst) {
|
match fs::copy(&cratepath, &dst) {
|
||||||
Ok(..) => {}
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -1205,7 +1220,11 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
// Fix up permissions of the copy, as fs::copy() preserves
|
// Fix up permissions of the copy, as fs::copy() preserves
|
||||||
// permissions, but the original file may have been installed
|
// permissions, but the original file may have been installed
|
||||||
// by a package manager and may be read-only.
|
// by a package manager and may be read-only.
|
||||||
match fs::chmod(&dst, old_io::USER_READ | old_io::USER_WRITE) {
|
match fs::metadata(&dst).and_then(|m| {
|
||||||
|
let mut perms = m.permissions();
|
||||||
|
perms.set_readonly(false);
|
||||||
|
fs::set_permissions(&dst, perms)
|
||||||
|
}) {
|
||||||
Ok(..) => {}
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
sess.err(&format!("failed to chmod {} when preparing \
|
sess.err(&format!("failed to chmod {} when preparing \
|
||||||
@ -1227,7 +1246,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
archive.remove_file(&format!("{}.o", name));
|
archive.remove_file(&format!("{}.o", name));
|
||||||
let files = archive.files();
|
let files = archive.files();
|
||||||
if files.iter().any(|s| s.ends_with(".o")) {
|
if files.iter().any(|s| s.ends_with(".o")) {
|
||||||
cmd.arg(dst);
|
cmd.arg(&dst);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -1236,19 +1255,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Same thing as above, but for dynamic crates instead of static crates.
|
// Same thing as above, but for dynamic crates instead of static crates.
|
||||||
fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) {
|
fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) {
|
||||||
// If we're performing LTO, then it should have been previously required
|
// If we're performing LTO, then it should have been previously required
|
||||||
// that all upstream rust dependencies were available in an rlib format.
|
// that all upstream rust dependencies were available in an rlib format.
|
||||||
assert!(!sess.lto());
|
assert!(!sess.lto());
|
||||||
|
|
||||||
// Just need to tell the linker about where the library lives and
|
// Just need to tell the linker about where the library lives and
|
||||||
// what its name is
|
// what its name is
|
||||||
let dir = cratepath.dirname();
|
if let Some(dir) = cratepath.parent() {
|
||||||
if !dir.is_empty() { cmd.arg("-L").arg(dir); }
|
cmd.arg("-L").arg(dir);
|
||||||
|
}
|
||||||
let mut v = "-l".as_bytes().to_vec();
|
let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
|
||||||
v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
|
cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
|
||||||
cmd.arg(&v[..]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,7 +1304,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||||||
for &(kind, ref lib) in &libs {
|
for &(kind, ref lib) in &libs {
|
||||||
match kind {
|
match kind {
|
||||||
cstore::NativeUnknown => {
|
cstore::NativeUnknown => {
|
||||||
cmd.arg(format!("-l{}", *lib));
|
cmd.arg(&format!("-l{}", *lib));
|
||||||
}
|
}
|
||||||
cstore::NativeFramework => {
|
cstore::NativeFramework => {
|
||||||
cmd.arg("-framework");
|
cmd.arg("-framework");
|
||||||
|
@ -59,7 +59,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
|
|||||||
};
|
};
|
||||||
|
|
||||||
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
|
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
|
||||||
let file = path.filename_str().unwrap();
|
let file = path.file_name().unwrap().to_str().unwrap();
|
||||||
let file = &file[3..file.len() - 5]; // chop off lib/.rlib
|
let file = &file[3..file.len() - 5]; // chop off lib/.rlib
|
||||||
debug!("reading {}", file);
|
debug!("reading {}", file);
|
||||||
for i in iter::count(0, 1) {
|
for i in iter::count(0, 1) {
|
||||||
|
@ -18,17 +18,19 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, Conte
|
|||||||
use llvm::SMDiagnosticRef;
|
use llvm::SMDiagnosticRef;
|
||||||
use trans::{CrateTranslation, ModuleTranslation};
|
use trans::{CrateTranslation, ModuleTranslation};
|
||||||
use util::common::time;
|
use util::common::time;
|
||||||
|
use util::common::path2cstr;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::diagnostic;
|
use syntax::diagnostic;
|
||||||
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
|
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::old_io::Command;
|
use std::fs;
|
||||||
use std::old_io::fs;
|
|
||||||
use std::iter::Unfold;
|
use std::iter::Unfold;
|
||||||
|
use std::mem;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::mem;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@ -67,7 +69,7 @@ pub fn write_output_file(
|
|||||||
output: &Path,
|
output: &Path,
|
||||||
file_type: llvm::FileType) {
|
file_type: llvm::FileType) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let output_c = CString::new(output.as_vec()).unwrap();
|
let output_c = path2cstr(output);
|
||||||
let result = llvm::LLVMRustWriteOutputFile(
|
let result = llvm::LLVMRustWriteOutputFile(
|
||||||
target, pm, m, output_c.as_ptr(), file_type);
|
target, pm, m, output_c.as_ptr(), file_type);
|
||||||
if !result {
|
if !result {
|
||||||
@ -424,7 +426,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|||||||
if config.emit_no_opt_bc {
|
if config.emit_no_opt_bc {
|
||||||
let ext = format!("{}.no-opt.bc", name_extra);
|
let ext = format!("{}.no-opt.bc", name_extra);
|
||||||
let out = output_names.with_extension(&ext);
|
let out = output_names.with_extension(&ext);
|
||||||
let out = CString::new(out.as_vec()).unwrap();
|
let out = path2cstr(&out);
|
||||||
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +479,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|||||||
if config.emit_lto_bc {
|
if config.emit_lto_bc {
|
||||||
let name = format!("{}.lto.bc", name_extra);
|
let name = format!("{}.lto.bc", name_extra);
|
||||||
let out = output_names.with_extension(&name);
|
let out = output_names.with_extension(&name);
|
||||||
let out = CString::new(out.as_vec()).unwrap();
|
let out = path2cstr(&out);
|
||||||
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -511,7 +513,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|||||||
if config.emit_bc {
|
if config.emit_bc {
|
||||||
let ext = format!("{}.bc", name_extra);
|
let ext = format!("{}.bc", name_extra);
|
||||||
let out = output_names.with_extension(&ext);
|
let out = output_names.with_extension(&ext);
|
||||||
let out = CString::new(out.as_vec()).unwrap();
|
let out = path2cstr(&out);
|
||||||
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,7 +521,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
|||||||
if config.emit_ir {
|
if config.emit_ir {
|
||||||
let ext = format!("{}.ll", name_extra);
|
let ext = format!("{}.ll", name_extra);
|
||||||
let out = output_names.with_extension(&ext);
|
let out = output_names.with_extension(&ext);
|
||||||
let out = CString::new(out.as_vec()).unwrap();
|
let out = path2cstr(&out);
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||||
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
|
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
|
||||||
})
|
})
|
||||||
@ -717,12 +719,11 @@ pub fn run_passes(sess: &Session,
|
|||||||
cmd.arg("-nostdlib");
|
cmd.arg("-nostdlib");
|
||||||
|
|
||||||
for index in 0..trans.modules.len() {
|
for index in 0..trans.modules.len() {
|
||||||
cmd.arg(crate_output.with_extension(&format!("{}.o", index)));
|
cmd.arg(&crate_output.with_extension(&format!("{}.o", index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.arg("-r")
|
cmd.arg("-r").arg("-o")
|
||||||
.arg("-o")
|
.arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path));
|
||||||
.arg(windows_output_path.as_ref().unwrap_or(output_path));
|
|
||||||
|
|
||||||
cmd.args(&sess.target.target.options.post_link_args);
|
cmd.args(&sess.target.target.options.post_link_args);
|
||||||
|
|
||||||
@ -730,9 +731,7 @@ pub fn run_passes(sess: &Session,
|
|||||||
println!("{:?}", &cmd);
|
println!("{:?}", &cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.stdin(::std::old_io::process::Ignored)
|
cmd.stdin(Stdio::null());
|
||||||
.stdout(::std::old_io::process::InheritFd(1))
|
|
||||||
.stderr(::std::old_io::process::InheritFd(2));
|
|
||||||
match cmd.status() {
|
match cmd.status() {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
@ -964,9 +963,9 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
|
|||||||
let pname = get_cc_prog(sess);
|
let pname = get_cc_prog(sess);
|
||||||
let mut cmd = Command::new(&pname[..]);
|
let mut cmd = Command::new(&pname[..]);
|
||||||
|
|
||||||
cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
|
cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject))
|
||||||
.arg(outputs.temp_path(config::OutputTypeAssembly));
|
.arg(&outputs.temp_path(config::OutputTypeAssembly));
|
||||||
debug!("{:?}", &cmd);
|
debug!("{:?}", cmd);
|
||||||
|
|
||||||
match cmd.output() {
|
match cmd.output() {
|
||||||
Ok(prog) => {
|
Ok(prog) => {
|
||||||
@ -975,8 +974,8 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
|
|||||||
pname,
|
pname,
|
||||||
prog.status));
|
prog.status));
|
||||||
sess.note(&format!("{:?}", &cmd));
|
sess.note(&format!("{:?}", &cmd));
|
||||||
let mut note = prog.error.clone();
|
let mut note = prog.stderr.clone();
|
||||||
note.push_all(&prog.output);
|
note.push_all(&prog.stdout);
|
||||||
sess.note(str::from_utf8(¬e[..]).unwrap());
|
sess.note(str::from_utf8(¬e[..]).unwrap());
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,7 @@
|
|||||||
#![feature(collections)]
|
#![feature(collections)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
#![feature(old_io)]
|
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(quote)]
|
#![feature(quote)]
|
||||||
#![feature(rustc_diagnostic_macros)]
|
#![feature(rustc_diagnostic_macros)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
@ -39,6 +37,11 @@
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
|
#![feature(io)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(os)]
|
||||||
|
#![feature(tempdir)]
|
||||||
|
|
||||||
extern crate arena;
|
extern crate arena;
|
||||||
extern crate flate;
|
extern crate flate;
|
||||||
|
@ -33,8 +33,9 @@ use middle::def;
|
|||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::old_io::{self, File, fs};
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::{self, File};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use syntax::ast_util::{self, PostExpansionMethod};
|
use syntax::ast_util::{self, PostExpansionMethod};
|
||||||
use syntax::ast::{self, NodeId, DefId};
|
use syntax::ast::{self, NodeId, DefId};
|
||||||
@ -1537,6 +1538,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn process_crate(sess: &Session,
|
pub fn process_crate(sess: &Session,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
analysis: &ty::CrateAnalysis,
|
analysis: &ty::CrateAnalysis,
|
||||||
@ -1557,15 +1559,15 @@ pub fn process_crate(sess: &Session,
|
|||||||
info!("Dumping crate {}", cratename);
|
info!("Dumping crate {}", cratename);
|
||||||
|
|
||||||
// find a path to dump our data to
|
// find a path to dump our data to
|
||||||
let mut root_path = match env::var("DXR_RUST_TEMP_FOLDER") {
|
let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") {
|
||||||
Ok(val) => Path::new(val),
|
Some(val) => PathBuf::new(&val),
|
||||||
Err(..) => match odir {
|
None => match odir {
|
||||||
Some(val) => val.join("dxr"),
|
Some(val) => val.join("dxr"),
|
||||||
None => Path::new("dxr-temp"),
|
None => PathBuf::new("dxr-temp"),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
match fs::mkdir_recursive(&root_path, old_io::USER_RWX) {
|
match fs::create_dir_all(&root_path) {
|
||||||
Err(e) => sess.err(&format!("Could not create directory {}: {}",
|
Err(e) => sess.err(&format!("Could not create directory {}: {}",
|
||||||
root_path.display(), e)),
|
root_path.display(), e)),
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -1579,7 +1581,7 @@ pub fn process_crate(sess: &Session,
|
|||||||
// Create output file.
|
// Create output file.
|
||||||
let mut out_name = cratename.clone();
|
let mut out_name = cratename.clone();
|
||||||
out_name.push_str(".csv");
|
out_name.push_str(".csv");
|
||||||
root_path.push(out_name);
|
root_path.push(&out_name);
|
||||||
let output_file = match File::create(&root_path) {
|
let output_file = match File::create(&root_path) {
|
||||||
Ok(f) => box f,
|
Ok(f) => box f,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -1595,7 +1597,7 @@ pub fn process_crate(sess: &Session,
|
|||||||
collected_paths: vec!(),
|
collected_paths: vec!(),
|
||||||
collecting: false,
|
collecting: false,
|
||||||
fmt: FmtStrs::new(box Recorder {
|
fmt: FmtStrs::new(box Recorder {
|
||||||
out: output_file as Box<Writer+'static>,
|
out: output_file,
|
||||||
dump_spans: false,
|
dump_spans: false,
|
||||||
},
|
},
|
||||||
SpanUtils {
|
SpanUtils {
|
||||||
|
@ -13,7 +13,7 @@ pub use self::Row::*;
|
|||||||
use super::escape;
|
use super::escape;
|
||||||
use super::span_utils::SpanUtils;
|
use super::span_utils::SpanUtils;
|
||||||
|
|
||||||
use std::vec::Vec;
|
use std::io::Write;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::{NodeId,DefId};
|
use syntax::ast::{NodeId,DefId};
|
||||||
@ -23,7 +23,7 @@ const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 };
|
|||||||
|
|
||||||
pub struct Recorder {
|
pub struct Recorder {
|
||||||
// output file
|
// output file
|
||||||
pub out: Box<Writer+'static>,
|
pub out: Box<Write+'static>,
|
||||||
pub dump_spans: bool,
|
pub dump_spans: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,10 +206,12 @@ use middle::pat_util;
|
|||||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||||
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
||||||
use util::ppaux;
|
use util::ppaux;
|
||||||
|
use util::common::path2cstr;
|
||||||
|
|
||||||
use libc::{c_uint, c_longlong};
|
use libc::{c_uint, c_longlong};
|
||||||
use std::ffi::CString;
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use syntax::util::interner::Interner;
|
use syntax::util::interner::Interner;
|
||||||
@ -1588,20 +1590,13 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
|
|||||||
cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
|
cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
|
||||||
fallback_path(cx)
|
fallback_path(cx)
|
||||||
} else {
|
} else {
|
||||||
match abs_path.path_relative_from(work_dir) {
|
match abs_path.relative_from(work_dir) {
|
||||||
Some(ref p) if p.is_relative() => {
|
Some(ref p) if p.is_relative() => {
|
||||||
// prepend "./" if necessary
|
if p.starts_with(Path::new("./")) {
|
||||||
let dotdot = b"..";
|
path2cstr(p)
|
||||||
let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE];
|
} else {
|
||||||
let mut path_bytes = p.as_vec().to_vec();
|
path2cstr(&Path::new(".").join(p))
|
||||||
|
|
||||||
if &path_bytes[..2] != prefix &&
|
|
||||||
&path_bytes[..2] != dotdot {
|
|
||||||
path_bytes.insert(0, prefix[0]);
|
|
||||||
path_bytes.insert(1, prefix[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CString::new(path_bytes).unwrap()
|
|
||||||
}
|
}
|
||||||
_ => fallback_path(cx)
|
_ => fallback_path(cx)
|
||||||
}
|
}
|
||||||
@ -1614,7 +1609,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
|
|||||||
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
|
||||||
|
|
||||||
let compile_unit_name = compile_unit_name.as_ptr();
|
let compile_unit_name = compile_unit_name.as_ptr();
|
||||||
let work_dir = CString::new(work_dir.as_vec()).unwrap();
|
let work_dir = path2cstr(&work_dir);
|
||||||
let producer = CString::new(producer).unwrap();
|
let producer = CString::new(producer).unwrap();
|
||||||
let flags = "\0";
|
let flags = "\0";
|
||||||
let split_name = "\0";
|
let split_name = "\0";
|
||||||
@ -1716,7 +1711,7 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
|
|||||||
debug!("file_metadata: {}", full_path);
|
debug!("file_metadata: {}", full_path);
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
let work_dir = cx.sess().working_dir.as_str().unwrap();
|
let work_dir = cx.sess().working_dir.to_str().unwrap();
|
||||||
let file_name =
|
let file_name =
|
||||||
if full_path.starts_with(work_dir) {
|
if full_path.starts_with(work_dir) {
|
||||||
&full_path[work_dir.len() + 1..full_path.len()]
|
&full_path[work_dir.len() + 1..full_path.len()]
|
||||||
|
@ -49,7 +49,7 @@ use rustc::middle::stability;
|
|||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use std::old_path::Path as FsPath; // Conflicts with Path struct
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use core::DocContext;
|
use core::DocContext;
|
||||||
use doctree;
|
use doctree;
|
||||||
@ -118,7 +118,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
|
|||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Crate {
|
pub struct Crate {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub src: FsPath,
|
pub src: PathBuf,
|
||||||
pub module: Option<Item>,
|
pub module: Option<Item>,
|
||||||
pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
|
pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
|
||||||
pub primitives: Vec<PrimitiveType>,
|
pub primitives: Vec<PrimitiveType>,
|
||||||
@ -191,7 +191,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
let src = match cx.input {
|
let src = match cx.input {
|
||||||
Input::File(ref path) => path.clone(),
|
Input::File(ref path) => path.clone(),
|
||||||
Input::Str(_) => FsPath::new("") // FIXME: this is wrong
|
Input::Str(_) => PathBuf::new("") // FIXME: this is wrong
|
||||||
};
|
};
|
||||||
|
|
||||||
Crate {
|
Crate {
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::{old_io, str};
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::io;
|
||||||
|
use std::old_io;
|
||||||
|
use std::path::{PathBuf, Path};
|
||||||
|
use std::str;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ExternalHtml{
|
pub struct ExternalHtml{
|
||||||
@ -33,16 +38,17 @@ impl ExternalHtml {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_string(input: &Path) -> old_io::IoResult<Option<String>> {
|
pub fn load_string(input: &Path) -> io::Result<Option<String>> {
|
||||||
let mut f = try!(old_io::File::open(input));
|
let mut f = try!(File::open(input));
|
||||||
let d = try!(f.read_to_end());
|
let mut d = Vec::new();
|
||||||
|
try!(f.read_to_end(&mut d));
|
||||||
Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
|
Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! load_or_return {
|
macro_rules! load_or_return {
|
||||||
($input: expr, $cant_read: expr, $not_utf8: expr) => {
|
($input: expr, $cant_read: expr, $not_utf8: expr) => {
|
||||||
{
|
{
|
||||||
let input = Path::new($input);
|
let input = PathBuf::new($input);
|
||||||
match ::externalfiles::load_string(&input) {
|
match ::externalfiles::load_string(&input) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = writeln!(&mut old_io::stderr(),
|
let _ = writeln!(&mut old_io::stderr(),
|
||||||
|
@ -20,7 +20,9 @@ pub use self::imp::Lock;
|
|||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
mod imp {
|
mod imp {
|
||||||
use std::ffi::CString;
|
use std::ffi::{AsOsStr, CString};
|
||||||
|
use std::os::unix::prelude::*;
|
||||||
|
use std::path::Path;
|
||||||
use libc;
|
use libc;
|
||||||
use std::os as stdos;
|
use std::os as stdos;
|
||||||
|
|
||||||
@ -114,7 +116,7 @@ mod imp {
|
|||||||
|
|
||||||
impl Lock {
|
impl Lock {
|
||||||
pub fn new(p: &Path) -> Lock {
|
pub fn new(p: &Path) -> Lock {
|
||||||
let buf = CString::new(p.as_vec()).unwrap();
|
let buf = CString::new(p.as_os_str().as_bytes()).unwrap();
|
||||||
let fd = unsafe {
|
let fd = unsafe {
|
||||||
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
|
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
|
||||||
libc::S_IRWXU)
|
libc::S_IRWXU)
|
||||||
@ -163,8 +165,11 @@ mod imp {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod imp {
|
mod imp {
|
||||||
use libc;
|
use libc;
|
||||||
|
use std::ffi::AsOsStr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::os::windows::prelude::*;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
use std::path::Path;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
|
const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
|
||||||
@ -190,7 +195,7 @@ mod imp {
|
|||||||
|
|
||||||
impl Lock {
|
impl Lock {
|
||||||
pub fn new(p: &Path) -> Lock {
|
pub fn new(p: &Path) -> Lock {
|
||||||
let mut p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect();
|
let mut p_16: Vec<_> = p.as_os_str().encode_wide().collect();
|
||||||
p_16.push(0);
|
p_16.push(0);
|
||||||
let handle = unsafe {
|
let handle = unsafe {
|
||||||
libc::CreateFileW(p_16.as_ptr(),
|
libc::CreateFileW(p_16.as_ptr(),
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::old_io;
|
use std::io::prelude::*;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
use externalfiles::ExternalHtml;
|
use externalfiles::ExternalHtml;
|
||||||
|
|
||||||
@ -31,8 +32,8 @@ pub struct Page<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<T: fmt::Display, S: fmt::Display>(
|
pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||||
dst: &mut old_io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
|
dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
|
||||||
-> old_io::IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
write!(dst,
|
write!(dst,
|
||||||
r##"<!DOCTYPE html>
|
r##"<!DOCTYPE html>
|
||||||
@ -159,7 +160,7 @@ r##"<!DOCTYPE html>
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> {
|
pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
|
||||||
// <script> triggers a redirect before refresh, so this is fine.
|
// <script> triggers a redirect before refresh, so this is fine.
|
||||||
write!(dst,
|
write!(dst,
|
||||||
r##"<!DOCTYPE html>
|
r##"<!DOCTYPE html>
|
||||||
|
@ -38,11 +38,13 @@ use std::cell::RefCell;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::ffi::OsStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::fs::{self, File};
|
||||||
use std::old_io::{fs, File, BufferedWriter, BufferedReader};
|
use std::io::prelude::*;
|
||||||
use std::old_io;
|
use std::io::{self, BufWriter, BufReader};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
use std::path::{PathBuf, Path};
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -89,10 +91,10 @@ pub struct Context {
|
|||||||
pub root_path: String,
|
pub root_path: String,
|
||||||
/// The path to the crate root source minus the file name.
|
/// The path to the crate root source minus the file name.
|
||||||
/// Used for simplifying paths to the highlighted source code files.
|
/// Used for simplifying paths to the highlighted source code files.
|
||||||
pub src_root: Path,
|
pub src_root: PathBuf,
|
||||||
/// The current destination folder of where HTML artifacts should be placed.
|
/// The current destination folder of where HTML artifacts should be placed.
|
||||||
/// This changes as the context descends into the module hierarchy.
|
/// This changes as the context descends into the module hierarchy.
|
||||||
pub dst: Path,
|
pub dst: PathBuf,
|
||||||
/// This describes the layout of each page, and is not modified after
|
/// This describes the layout of each page, and is not modified after
|
||||||
/// creation of the context (contains info like the favicon and added html).
|
/// creation of the context (contains info like the favicon and added html).
|
||||||
pub layout: layout::Layout,
|
pub layout: layout::Layout,
|
||||||
@ -220,7 +222,7 @@ struct SourceCollector<'a> {
|
|||||||
/// Processed source-file paths
|
/// Processed source-file paths
|
||||||
seen: HashSet<String>,
|
seen: HashSet<String>,
|
||||||
/// Root destination to place all HTML output into
|
/// Root destination to place all HTML output into
|
||||||
dst: Path,
|
dst: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper struct to render the source code of a file. This will do things like
|
/// Wrapper struct to render the source code of a file. This will do things like
|
||||||
@ -257,11 +259,15 @@ thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
|
|||||||
/// Generates the documentation for `crate` into the directory `dst`
|
/// Generates the documentation for `crate` into the directory `dst`
|
||||||
pub fn run(mut krate: clean::Crate,
|
pub fn run(mut krate: clean::Crate,
|
||||||
external_html: &ExternalHtml,
|
external_html: &ExternalHtml,
|
||||||
dst: Path,
|
dst: PathBuf,
|
||||||
passes: HashSet<String>) -> old_io::IoResult<()> {
|
passes: HashSet<String>) -> io::Result<()> {
|
||||||
|
let src_root = match krate.src.parent() {
|
||||||
|
Some(p) => p.to_path_buf(),
|
||||||
|
None => PathBuf::new(""),
|
||||||
|
};
|
||||||
let mut cx = Context {
|
let mut cx = Context {
|
||||||
dst: dst,
|
dst: dst,
|
||||||
src_root: krate.src.dir_path(),
|
src_root: src_root,
|
||||||
passes: passes,
|
passes: passes,
|
||||||
current: Vec::new(),
|
current: Vec::new(),
|
||||||
root_path: String::new(),
|
root_path: String::new(),
|
||||||
@ -392,7 +398,7 @@ pub fn run(mut krate: clean::Crate,
|
|||||||
cx.krate(krate, summary)
|
cx.krate(krate, summary)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<String> {
|
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
|
||||||
// Build the search index from the collected metadata
|
// Build the search index from the collected metadata
|
||||||
let mut nodeid_to_pathid = HashMap::new();
|
let mut nodeid_to_pathid = HashMap::new();
|
||||||
let mut pathid_to_nodeid = Vec::new();
|
let mut pathid_to_nodeid = Vec::new();
|
||||||
@ -437,7 +443,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Collect the index into a string
|
// Collect the index into a string
|
||||||
let mut w = Vec::new();
|
let mut w = io::Cursor::new(Vec::new());
|
||||||
try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name));
|
try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name));
|
||||||
|
|
||||||
let mut lastpath = "".to_string();
|
let mut lastpath = "".to_string();
|
||||||
@ -480,13 +486,13 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
|
|||||||
|
|
||||||
try!(write!(&mut w, "]}};"));
|
try!(write!(&mut w, "]}};"));
|
||||||
|
|
||||||
Ok(String::from_utf8(w).unwrap())
|
Ok(String::from_utf8(w.into_inner()).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_shared(cx: &Context,
|
fn write_shared(cx: &Context,
|
||||||
krate: &clean::Crate,
|
krate: &clean::Crate,
|
||||||
cache: &Cache,
|
cache: &Cache,
|
||||||
search_index: String) -> old_io::IoResult<()> {
|
search_index: String) -> io::Result<()> {
|
||||||
// Write out the shared files. Note that these are shared among all rustdoc
|
// Write out the shared files. Note that these are shared among all rustdoc
|
||||||
// docs placed in the output directory, so this needs to be a synchronized
|
// docs placed in the output directory, so this needs to be a synchronized
|
||||||
// operation with respect to all other rustdocs running around.
|
// operation with respect to all other rustdocs running around.
|
||||||
@ -518,10 +524,10 @@ fn write_shared(cx: &Context,
|
|||||||
include_bytes!("static/SourceCodePro-Semibold.woff")));
|
include_bytes!("static/SourceCodePro-Semibold.woff")));
|
||||||
|
|
||||||
fn collect(path: &Path, krate: &str,
|
fn collect(path: &Path, krate: &str,
|
||||||
key: &str) -> old_io::IoResult<Vec<String>> {
|
key: &str) -> io::Result<Vec<String>> {
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
for line in BufferedReader::new(File::open(path)).lines() {
|
for line in BufReader::new(try!(File::open(path))).lines() {
|
||||||
let line = try!(line);
|
let line = try!(line);
|
||||||
if !line.starts_with(key) {
|
if !line.starts_with(key) {
|
||||||
continue
|
continue
|
||||||
@ -567,14 +573,14 @@ fn write_shared(cx: &Context,
|
|||||||
mydst.push(part);
|
mydst.push(part);
|
||||||
try!(mkdir(&mydst));
|
try!(mkdir(&mydst));
|
||||||
}
|
}
|
||||||
mydst.push(format!("{}.{}.js",
|
mydst.push(&format!("{}.{}.js",
|
||||||
remote_item_type.to_static_str(),
|
remote_item_type.to_static_str(),
|
||||||
remote_path[remote_path.len() - 1]));
|
remote_path[remote_path.len() - 1]));
|
||||||
let all_implementors = try!(collect(&mydst, &krate.name,
|
let all_implementors = try!(collect(&mydst, &krate.name,
|
||||||
"implementors"));
|
"implementors"));
|
||||||
|
|
||||||
try!(mkdir(&mydst.dir_path()));
|
try!(mkdir(mydst.parent().unwrap()));
|
||||||
let mut f = BufferedWriter::new(try!(File::create(&mydst)));
|
let mut f = BufWriter::new(try!(File::create(&mydst)));
|
||||||
try!(writeln!(&mut f, "(function() {{var implementors = {{}};"));
|
try!(writeln!(&mut f, "(function() {{var implementors = {{}};"));
|
||||||
|
|
||||||
for implementor in &all_implementors {
|
for implementor in &all_implementors {
|
||||||
@ -606,7 +612,7 @@ fn write_shared(cx: &Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_sources(cx: &mut Context,
|
fn render_sources(cx: &mut Context,
|
||||||
krate: clean::Crate) -> old_io::IoResult<clean::Crate> {
|
krate: clean::Crate) -> io::Result<clean::Crate> {
|
||||||
info!("emitting source files");
|
info!("emitting source files");
|
||||||
let dst = cx.dst.join("src");
|
let dst = cx.dst.join("src");
|
||||||
try!(mkdir(&dst));
|
try!(mkdir(&dst));
|
||||||
@ -624,15 +630,15 @@ fn render_sources(cx: &mut Context,
|
|||||||
|
|
||||||
/// Writes the entire contents of a string to a destination, not attempting to
|
/// Writes the entire contents of a string to a destination, not attempting to
|
||||||
/// catch any errors.
|
/// catch any errors.
|
||||||
fn write(dst: Path, contents: &[u8]) -> old_io::IoResult<()> {
|
fn write(dst: PathBuf, contents: &[u8]) -> io::Result<()> {
|
||||||
File::create(&dst).write_all(contents)
|
try!(File::create(&dst)).write_all(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a directory on the filesystem, failing the task if an error occurs and
|
/// Makes a directory on the filesystem, failing the task if an error occurs and
|
||||||
/// skipping if the directory already exists.
|
/// skipping if the directory already exists.
|
||||||
fn mkdir(path: &Path) -> old_io::IoResult<()> {
|
fn mkdir(path: &Path) -> io::Result<()> {
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
fs::mkdir(path, old_io::USER_RWX)
|
fs::create_dir(path)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -648,21 +654,17 @@ fn shortty(item: &clean::Item) -> ItemType {
|
|||||||
/// static HTML tree.
|
/// static HTML tree.
|
||||||
// FIXME (#9639): The closure should deal with &[u8] instead of &str
|
// FIXME (#9639): The closure should deal with &[u8] instead of &str
|
||||||
// FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
|
// FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
|
||||||
fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where
|
fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where
|
||||||
F: FnMut(&str),
|
F: FnMut(&str),
|
||||||
{
|
{
|
||||||
let p = Path::new(src);
|
|
||||||
|
|
||||||
// make it relative, if possible
|
// make it relative, if possible
|
||||||
let p = p.path_relative_from(src_root).unwrap_or(p);
|
let p = p.relative_from(src_root).unwrap_or(p);
|
||||||
|
|
||||||
if p.as_vec() != b"." {
|
for c in p.iter().map(|x| x.to_str().unwrap()) {
|
||||||
for c in p.str_components().map(|x|x.unwrap()) {
|
if ".." == c {
|
||||||
if ".." == c {
|
f("up");
|
||||||
f("up");
|
} else {
|
||||||
} else {
|
f(c)
|
||||||
f(c)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,13 +735,14 @@ impl<'a> DocFolder for SourceCollector<'a> {
|
|||||||
|
|
||||||
impl<'a> SourceCollector<'a> {
|
impl<'a> SourceCollector<'a> {
|
||||||
/// Renders the given filename into its corresponding HTML source file.
|
/// Renders the given filename into its corresponding HTML source file.
|
||||||
fn emit_source(&mut self, filename: &str) -> old_io::IoResult<()> {
|
fn emit_source(&mut self, filename: &str) -> io::Result<()> {
|
||||||
let p = Path::new(filename);
|
let p = PathBuf::new(filename);
|
||||||
|
|
||||||
// If we couldn't open this file, then just returns because it
|
// If we couldn't open this file, then just returns because it
|
||||||
// probably means that it's some standard library macro thing and we
|
// probably means that it's some standard library macro thing and we
|
||||||
// can't have the source to it anyway.
|
// can't have the source to it anyway.
|
||||||
let contents = match File::open(&p).read_to_end() {
|
let mut contents = Vec::new();
|
||||||
|
match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
// macros from other libraries get special filenames which we can
|
// macros from other libraries get special filenames which we can
|
||||||
// safely ignore
|
// safely ignore
|
||||||
@ -759,18 +762,20 @@ impl<'a> SourceCollector<'a> {
|
|||||||
// Create the intermediate directories
|
// Create the intermediate directories
|
||||||
let mut cur = self.dst.clone();
|
let mut cur = self.dst.clone();
|
||||||
let mut root_path = String::from_str("../../");
|
let mut root_path = String::from_str("../../");
|
||||||
clean_srcpath(&self.cx.src_root, p.dirname(), |component| {
|
clean_srcpath(&self.cx.src_root, &p, |component| {
|
||||||
cur.push(component);
|
cur.push(component);
|
||||||
mkdir(&cur).unwrap();
|
mkdir(&cur).unwrap();
|
||||||
root_path.push_str("../");
|
root_path.push_str("../");
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut fname = p.filename().expect("source has no filename").to_vec();
|
let mut fname = p.file_name().expect("source has no filename")
|
||||||
fname.extend(".html".bytes());
|
.to_os_string();
|
||||||
cur.push(fname);
|
fname.push_os_str(OsStr::from_str(".html"));
|
||||||
let mut w = BufferedWriter::new(try!(File::create(&cur)));
|
cur.push(&fname);
|
||||||
|
let mut w = BufWriter::new(try!(File::create(&cur)));
|
||||||
|
|
||||||
let title = format!("{} -- source", cur.filename_display());
|
let title = format!("{} -- source", cur.file_name().unwrap()
|
||||||
|
.to_string_lossy());
|
||||||
let desc = format!("Source to the Rust file `{}`.", filename);
|
let desc = format!("Source to the Rust file `{}`.", filename);
|
||||||
let page = layout::Page {
|
let page = layout::Page {
|
||||||
title: &title,
|
title: &title,
|
||||||
@ -779,7 +784,7 @@ impl<'a> SourceCollector<'a> {
|
|||||||
description: &desc,
|
description: &desc,
|
||||||
keywords: get_basic_keywords(),
|
keywords: get_basic_keywords(),
|
||||||
};
|
};
|
||||||
try!(layout::render(&mut w as &mut Writer, &self.cx.layout,
|
try!(layout::render(&mut w, &self.cx.layout,
|
||||||
&page, &(""), &Source(contents)));
|
&page, &(""), &Source(contents)));
|
||||||
try!(w.flush());
|
try!(w.flush());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -1081,7 +1086,7 @@ impl Context {
|
|||||||
/// This currently isn't parallelized, but it'd be pretty easy to add
|
/// This currently isn't parallelized, but it'd be pretty easy to add
|
||||||
/// parallelization to this function.
|
/// parallelization to this function.
|
||||||
fn krate(mut self, mut krate: clean::Crate,
|
fn krate(mut self, mut krate: clean::Crate,
|
||||||
stability: stability_summary::ModuleSummary) -> old_io::IoResult<()> {
|
stability: stability_summary::ModuleSummary) -> io::Result<()> {
|
||||||
let mut item = match krate.module.take() {
|
let mut item = match krate.module.take() {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
None => return Ok(())
|
None => return Ok(())
|
||||||
@ -1091,7 +1096,7 @@ impl Context {
|
|||||||
// render stability dashboard
|
// render stability dashboard
|
||||||
try!(self.recurse(stability.name.clone(), |this| {
|
try!(self.recurse(stability.name.clone(), |this| {
|
||||||
let json_dst = &this.dst.join("stability.json");
|
let json_dst = &this.dst.join("stability.json");
|
||||||
let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
|
let mut json_out = BufWriter::new(try!(File::create(json_dst)));
|
||||||
try!(write!(&mut json_out, "{}", json::as_json(&stability)));
|
try!(write!(&mut json_out, "{}", json::as_json(&stability)));
|
||||||
|
|
||||||
let mut title = stability.name.clone();
|
let mut title = stability.name.clone();
|
||||||
@ -1106,7 +1111,7 @@ impl Context {
|
|||||||
keywords: get_basic_keywords(),
|
keywords: get_basic_keywords(),
|
||||||
};
|
};
|
||||||
let html_dst = &this.dst.join("stability.html");
|
let html_dst = &this.dst.join("stability.html");
|
||||||
let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
|
let mut html_out = BufWriter::new(try!(File::create(html_dst)));
|
||||||
layout::render(&mut html_out, &this.layout, &page,
|
layout::render(&mut html_out, &this.layout, &page,
|
||||||
&Sidebar{ cx: this, item: &item },
|
&Sidebar{ cx: this, item: &item },
|
||||||
&stability)
|
&stability)
|
||||||
@ -1131,12 +1136,12 @@ impl Context {
|
|||||||
/// all sub-items which need to be rendered.
|
/// all sub-items which need to be rendered.
|
||||||
///
|
///
|
||||||
/// The rendering driver uses this closure to queue up more work.
|
/// The rendering driver uses this closure to queue up more work.
|
||||||
fn item<F>(&mut self, item: clean::Item, mut f: F) -> old_io::IoResult<()> where
|
fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::Result<()> where
|
||||||
F: FnMut(&mut Context, clean::Item),
|
F: FnMut(&mut Context, clean::Item),
|
||||||
{
|
{
|
||||||
fn render(w: old_io::File, cx: &Context, it: &clean::Item,
|
fn render(w: File, cx: &Context, it: &clean::Item,
|
||||||
pushname: bool) -> old_io::IoResult<()> {
|
pushname: bool) -> io::Result<()> {
|
||||||
info!("Rendering an item to {}", w.path().display());
|
info!("Rendering an item to {}", w.path().unwrap().display());
|
||||||
// A little unfortunate that this is done like this, but it sure
|
// A little unfortunate that this is done like this, but it sure
|
||||||
// does make formatting *a lot* nicer.
|
// does make formatting *a lot* nicer.
|
||||||
CURRENT_LOCATION_KEY.with(|slot| {
|
CURRENT_LOCATION_KEY.with(|slot| {
|
||||||
@ -1177,7 +1182,7 @@ impl Context {
|
|||||||
// We have a huge number of calls to write, so try to alleviate some
|
// We have a huge number of calls to write, so try to alleviate some
|
||||||
// of the pain by using a buffered writer instead of invoking the
|
// of the pain by using a buffered writer instead of invoking the
|
||||||
// write syscall all the time.
|
// write syscall all the time.
|
||||||
let mut writer = BufferedWriter::new(w);
|
let mut writer = BufWriter::new(w);
|
||||||
if !cx.render_redirect_pages {
|
if !cx.render_redirect_pages {
|
||||||
try!(layout::render(&mut writer, &cx.layout, &page,
|
try!(layout::render(&mut writer, &cx.layout, &page,
|
||||||
&Sidebar{ cx: cx, item: it },
|
&Sidebar{ cx: cx, item: it },
|
||||||
@ -1238,7 +1243,7 @@ impl Context {
|
|||||||
// Things which don't have names (like impls) don't get special
|
// Things which don't have names (like impls) don't get special
|
||||||
// pages dedicated to them.
|
// pages dedicated to them.
|
||||||
_ if item.name.is_some() => {
|
_ if item.name.is_some() => {
|
||||||
let dst = self.dst.join(item_path(&item));
|
let dst = self.dst.join(&item_path(&item));
|
||||||
let dst = try!(File::create(&dst));
|
let dst = try!(File::create(&dst));
|
||||||
render(dst, self, &item, true)
|
render(dst, self, &item, true)
|
||||||
}
|
}
|
||||||
@ -1307,7 +1312,7 @@ impl<'a> Item<'a> {
|
|||||||
// has anchors for the line numbers that we're linking to.
|
// has anchors for the line numbers that we're linking to.
|
||||||
if ast_util::is_local(self.item.def_id) {
|
if ast_util::is_local(self.item.def_id) {
|
||||||
let mut path = Vec::new();
|
let mut path = Vec::new();
|
||||||
clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(),
|
clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
|
||||||
|component| {
|
|component| {
|
||||||
path.push(component.to_string());
|
path.push(component.to_string());
|
||||||
});
|
});
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(str_words)]
|
#![feature(str_words)]
|
||||||
|
#![feature(io)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(tempdir)]
|
||||||
|
|
||||||
extern crate arena;
|
extern crate arena;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
@ -53,10 +57,12 @@ extern crate "serialize" as rustc_serialize; // used by deriving
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::old_io::File;
|
use std::fs::File;
|
||||||
use std::old_io;
|
use std::io::{self, Read, Write};
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
use externalfiles::ExternalHtml;
|
use externalfiles::ExternalHtml;
|
||||||
use serialize::Decodable;
|
use serialize::Decodable;
|
||||||
use serialize::json::{self, Json};
|
use serialize::json::{self, Json};
|
||||||
@ -242,7 +248,7 @@ pub fn main_args(args: &[String]) -> int {
|
|||||||
let should_test = matches.opt_present("test");
|
let should_test = matches.opt_present("test");
|
||||||
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
|
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
|
||||||
|
|
||||||
let output = matches.opt_str("o").map(|s| Path::new(s));
|
let output = matches.opt_str("o").map(|s| PathBuf::new(&s));
|
||||||
let cfgs = matches.opt_strs("cfg");
|
let cfgs = matches.opt_strs("cfg");
|
||||||
|
|
||||||
let external_html = match ExternalHtml::load(
|
let external_html = match ExternalHtml::load(
|
||||||
@ -261,7 +267,8 @@ pub fn main_args(args: &[String]) -> int {
|
|||||||
(true, false) => {
|
(true, false) => {
|
||||||
return test::run(input, cfgs, libs, externs, test_args, crate_name)
|
return test::run(input, cfgs, libs, externs, test_args, crate_name)
|
||||||
}
|
}
|
||||||
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
|
(false, true) => return markdown::render(input,
|
||||||
|
output.unwrap_or(PathBuf::new("doc")),
|
||||||
&matches, &external_html,
|
&matches, &external_html,
|
||||||
!matches.opt_present("markdown-no-toc")),
|
!matches.opt_present("markdown-no-toc")),
|
||||||
(false, false) => {}
|
(false, false) => {}
|
||||||
@ -278,7 +285,8 @@ pub fn main_args(args: &[String]) -> int {
|
|||||||
info!("going to format");
|
info!("going to format");
|
||||||
match matches.opt_str("w").as_ref().map(|s| &**s) {
|
match matches.opt_str("w").as_ref().map(|s| &**s) {
|
||||||
Some("html") | None => {
|
Some("html") | None => {
|
||||||
match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")),
|
match html::render::run(krate, &external_html,
|
||||||
|
output.unwrap_or(PathBuf::new("doc")),
|
||||||
passes.into_iter().collect()) {
|
passes.into_iter().collect()) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => panic!("failed to generate documentation: {}", e),
|
Err(e) => panic!("failed to generate documentation: {}", e),
|
||||||
@ -286,7 +294,7 @@ pub fn main_args(args: &[String]) -> int {
|
|||||||
}
|
}
|
||||||
Some("json") => {
|
Some("json") => {
|
||||||
match json_output(krate, json_plugins,
|
match json_output(krate, json_plugins,
|
||||||
output.unwrap_or(Path::new("doc.json"))) {
|
output.unwrap_or(PathBuf::new("doc.json"))) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => panic!("failed to write json: {}", e),
|
Err(e) => panic!("failed to write json: {}", e),
|
||||||
}
|
}
|
||||||
@ -364,15 +372,15 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
|
|||||||
let cfgs = matches.opt_strs("cfg");
|
let cfgs = matches.opt_strs("cfg");
|
||||||
let triple = matches.opt_str("target");
|
let triple = matches.opt_str("target");
|
||||||
|
|
||||||
let cr = Path::new(cratefile);
|
let cr = PathBuf::new(cratefile);
|
||||||
info!("starting to run rustc");
|
info!("starting to run rustc");
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
use rustc::session::config::Input;
|
use rustc::session::config::Input;
|
||||||
|
|
||||||
let cr = cr;
|
tx.send(core::run_core(paths, cfgs, externs, Input::File(cr),
|
||||||
tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap();
|
triple)).unwrap();
|
||||||
}).join().map_err(|_| "rustc failed").unwrap();
|
}).join().map_err(|_| "rustc failed").unwrap();
|
||||||
let (mut krate, analysis) = rx.recv().unwrap();
|
let (mut krate, analysis) = rx.recv().unwrap();
|
||||||
info!("finished with rustc");
|
info!("finished with rustc");
|
||||||
@ -451,13 +459,12 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
|
|||||||
/// This input format purely deserializes the json output file. No passes are
|
/// This input format purely deserializes the json output file. No passes are
|
||||||
/// run over the deserialized output.
|
/// run over the deserialized output.
|
||||||
fn json_input(input: &str) -> Result<Output, String> {
|
fn json_input(input: &str) -> Result<Output, String> {
|
||||||
let mut input = match File::open(&Path::new(input)) {
|
let mut bytes = Vec::new();
|
||||||
Ok(f) => f,
|
match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
|
||||||
Err(e) => {
|
Ok(()) => {}
|
||||||
return Err(format!("couldn't open {}: {}", input, e))
|
Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
match json::from_reader(&mut input) {
|
match json::from_reader(&mut &bytes[..]) {
|
||||||
Err(s) => Err(format!("{:?}", s)),
|
Err(s) => Err(format!("{:?}", s)),
|
||||||
Ok(Json::Object(obj)) => {
|
Ok(Json::Object(obj)) => {
|
||||||
let mut obj = obj;
|
let mut obj = obj;
|
||||||
@ -495,7 +502,7 @@ fn json_input(input: &str) -> Result<Output, String> {
|
|||||||
/// Outputs the crate/plugin json as a giant json blob at the specified
|
/// Outputs the crate/plugin json as a giant json blob at the specified
|
||||||
/// destination.
|
/// destination.
|
||||||
fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
||||||
dst: Path) -> old_io::IoResult<()> {
|
dst: PathBuf) -> io::Result<()> {
|
||||||
// {
|
// {
|
||||||
// "schema": version,
|
// "schema": version,
|
||||||
// "crate": { parsed crate ... },
|
// "crate": { parsed crate ... },
|
||||||
|
@ -8,7 +8,10 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
use std::old_io;
|
use std::old_io;
|
||||||
|
use std::path::{PathBuf, Path};
|
||||||
|
|
||||||
use core;
|
use core;
|
||||||
use getopts;
|
use getopts;
|
||||||
@ -40,10 +43,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
|||||||
|
|
||||||
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
|
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
|
||||||
/// (e.g. output = "bar" => "bar/foo.html").
|
/// (e.g. output = "bar" => "bar/foo.html").
|
||||||
pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
|
pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
|
||||||
external_html: &ExternalHtml, include_toc: bool) -> int {
|
external_html: &ExternalHtml, include_toc: bool) -> int {
|
||||||
let input_p = Path::new(input);
|
let input_p = Path::new(input);
|
||||||
output.push(input_p.filestem().unwrap());
|
output.push(input_p.file_stem().unwrap());
|
||||||
output.set_extension("html");
|
output.set_extension("html");
|
||||||
|
|
||||||
let mut css = String::new();
|
let mut css = String::new();
|
||||||
@ -59,7 +62,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
|
|||||||
}
|
}
|
||||||
let playground = playground.unwrap_or("".to_string());
|
let playground = playground.unwrap_or("".to_string());
|
||||||
|
|
||||||
let mut out = match old_io::File::create(&output) {
|
let mut out = match File::create(&output) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = writeln!(&mut old_io::stderr(),
|
let _ = writeln!(&mut old_io::stderr(),
|
||||||
"error opening `{}` for writing: {}",
|
"error opening `{}` for writing: {}",
|
||||||
|
@ -9,16 +9,20 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::sync::mpsc::channel;
|
use std::collections::{HashSet, HashMap};
|
||||||
use std::dynamic_lib::DynamicLibrary;
|
use std::dynamic_lib::DynamicLibrary;
|
||||||
use std::old_io::{Command, TempDir};
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::fs::TempDir;
|
||||||
use std::old_io;
|
use std::old_io;
|
||||||
use std::os;
|
use std::io;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thunk::Thunk;
|
use std::thunk::Thunk;
|
||||||
|
|
||||||
use std::collections::{HashSet, HashMap};
|
|
||||||
use testing;
|
use testing;
|
||||||
use rustc_lint;
|
use rustc_lint;
|
||||||
use rustc::session::{self, config};
|
use rustc::session::{self, config};
|
||||||
@ -43,11 +47,12 @@ pub fn run(input: &str,
|
|||||||
mut test_args: Vec<String>,
|
mut test_args: Vec<String>,
|
||||||
crate_name: Option<String>)
|
crate_name: Option<String>)
|
||||||
-> int {
|
-> int {
|
||||||
let input_path = Path::new(input);
|
let input_path = PathBuf::new(input);
|
||||||
let input = config::Input::File(input_path.clone());
|
let input = config::Input::File(input_path.clone());
|
||||||
|
|
||||||
let sessopts = config::Options {
|
let sessopts = config::Options {
|
||||||
maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
|
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
|
||||||
|
.parent().unwrap().to_path_buf()),
|
||||||
search_paths: libs.clone(),
|
search_paths: libs.clone(),
|
||||||
crate_types: vec!(config::CrateTypeDylib),
|
crate_types: vec!(config::CrateTypeDylib),
|
||||||
externs: externs.clone(),
|
externs: externs.clone(),
|
||||||
@ -115,7 +120,8 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
|
|||||||
let input = config::Input::Str(test.to_string());
|
let input = config::Input::Str(test.to_string());
|
||||||
|
|
||||||
let sessopts = config::Options {
|
let sessopts = config::Options {
|
||||||
maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
|
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
|
||||||
|
.parent().unwrap().to_path_buf()),
|
||||||
search_paths: libs,
|
search_paths: libs,
|
||||||
crate_types: vec!(config::CrateTypeExecutable),
|
crate_types: vec!(config::CrateTypeExecutable),
|
||||||
output_types: vec!(config::OutputTypeExe),
|
output_types: vec!(config::OutputTypeExe),
|
||||||
@ -170,7 +176,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
|
|||||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||||
|
|
||||||
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
|
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
|
||||||
let out = Some(outdir.path().clone());
|
let out = Some(outdir.path().to_path_buf());
|
||||||
let cfg = config::build_configuration(&sess);
|
let cfg = config::build_configuration(&sess);
|
||||||
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
|
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
|
||||||
let mut control = driver::CompileController::basic();
|
let mut control = driver::CompileController::basic();
|
||||||
@ -187,17 +193,19 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
|
|||||||
// environment to ensure that the target loads the right libraries at
|
// environment to ensure that the target loads the right libraries at
|
||||||
// runtime. It would be a sad day if the *host* libraries were loaded as a
|
// runtime. It would be a sad day if the *host* libraries were loaded as a
|
||||||
// mistake.
|
// mistake.
|
||||||
let mut cmd = Command::new(outdir.path().join("rust-out"));
|
let mut cmd = Command::new(&outdir.path().join("rust-out"));
|
||||||
|
let var = DynamicLibrary::envvar();
|
||||||
let newpath = {
|
let newpath = {
|
||||||
let mut path = DynamicLibrary::search_path();
|
let path = env::var_os(var).unwrap_or(OsString::new());
|
||||||
|
let mut path = env::split_paths(&path).collect::<Vec<_>>();
|
||||||
path.insert(0, libdir.clone());
|
path.insert(0, libdir.clone());
|
||||||
DynamicLibrary::create_path(&path)
|
env::join_paths(path.iter()).unwrap()
|
||||||
};
|
};
|
||||||
cmd.env(DynamicLibrary::envvar(), newpath);
|
cmd.env(var, &newpath);
|
||||||
|
|
||||||
match cmd.output() {
|
match cmd.output() {
|
||||||
Err(e) => panic!("couldn't run the test: {}{}", e,
|
Err(e) => panic!("couldn't run the test: {}{}", e,
|
||||||
if e.kind == old_io::PermissionDenied {
|
if e.kind() == io::ErrorKind::PermissionDenied {
|
||||||
" - maybe your tempdir is mounted with noexec?"
|
" - maybe your tempdir is mounted with noexec?"
|
||||||
} else { "" }),
|
} else { "" }),
|
||||||
Ok(out) => {
|
Ok(out) => {
|
||||||
@ -205,7 +213,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
|
|||||||
panic!("test executable succeeded when it should have failed");
|
panic!("test executable succeeded when it should have failed");
|
||||||
} else if !should_fail && !out.status.success() {
|
} else if !should_fail && !out.status.success() {
|
||||||
panic!("test executable failed:\n{:?}",
|
panic!("test executable failed:\n{:?}",
|
||||||
str::from_utf8(&out.error));
|
str::from_utf8(&out.stdout));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ Core encoding and decoding interfaces.
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
|
#![feature(path)]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|
||||||
// test harness access
|
// test harness access
|
||||||
|
@ -15,6 +15,7 @@ Core encoding and decoding interfaces.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use std::old_path;
|
use std::old_path;
|
||||||
|
use std::path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -564,6 +565,19 @@ impl Decodable for old_path::windows::Path {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for path::PathBuf {
|
||||||
|
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
|
||||||
|
self.to_str().unwrap().encode(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for path::PathBuf {
|
||||||
|
fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> {
|
||||||
|
let bytes: String = try!(Decodable::decode(d));
|
||||||
|
Ok(path::PathBuf::new(&bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Encodable + Copy> Encodable for Cell<T> {
|
impl<T: Encodable + Copy> Encodable for Cell<T> {
|
||||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
self.get().encode(s)
|
self.get().encode(s)
|
||||||
|
@ -82,6 +82,8 @@ use sys_common;
|
|||||||
/// attempted against it for which its underlying file descriptor was not
|
/// attempted against it for which its underlying file descriptor was not
|
||||||
/// configured at creation time, via the `FileAccess` parameter to
|
/// configured at creation time, via the `FileAccess` parameter to
|
||||||
/// `File::open_mode()`.
|
/// `File::open_mode()`.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
fd: fs_imp::FileDesc,
|
fd: fs_imp::FileDesc,
|
||||||
path: Path,
|
path: Path,
|
||||||
@ -94,6 +96,8 @@ impl sys_common::AsInner<fs_imp::FileDesc> for File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
impl File {
|
impl File {
|
||||||
/// Open a file at `path` in the mode specified by the `mode` and `access`
|
/// Open a file at `path` in the mode specified by the `mode` and `access`
|
||||||
/// arguments
|
/// arguments
|
||||||
@ -133,6 +137,8 @@ impl File {
|
|||||||
/// * Attempting to open a file with a `FileAccess` that the user lacks
|
/// * Attempting to open a file with a `FileAccess` that the user lacks
|
||||||
/// permissions for
|
/// permissions for
|
||||||
/// * Filesystem-level errors (full disk, etc)
|
/// * Filesystem-level errors (full disk, etc)
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::OpenOptions")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn open_mode(path: &Path,
|
pub fn open_mode(path: &Path,
|
||||||
mode: FileMode,
|
mode: FileMode,
|
||||||
access: FileAccess) -> IoResult<File> {
|
access: FileAccess) -> IoResult<File> {
|
||||||
@ -174,6 +180,8 @@ impl File {
|
|||||||
///
|
///
|
||||||
/// let contents = File::open(&Path::new("foo.txt")).read_to_end();
|
/// let contents = File::open(&Path::new("foo.txt")).read_to_end();
|
||||||
/// ```
|
/// ```
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::open")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn open(path: &Path) -> IoResult<File> {
|
pub fn open(path: &Path) -> IoResult<File> {
|
||||||
File::open_mode(path, Open, Read)
|
File::open_mode(path, Open, Read)
|
||||||
}
|
}
|
||||||
@ -195,12 +203,16 @@ impl File {
|
|||||||
/// # drop(f);
|
/// # drop(f);
|
||||||
/// # ::std::old_io::fs::unlink(&Path::new("foo.txt"));
|
/// # ::std::old_io::fs::unlink(&Path::new("foo.txt"));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::create")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn create(path: &Path) -> IoResult<File> {
|
pub fn create(path: &Path) -> IoResult<File> {
|
||||||
File::open_mode(path, Truncate, Write)
|
File::open_mode(path, Truncate, Write)
|
||||||
.update_desc("couldn't create file")
|
.update_desc("couldn't create file")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the original path that was used to open this file.
|
/// Returns the original path that was used to open this file.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn path<'a>(&'a self) -> &'a Path {
|
pub fn path<'a>(&'a self) -> &'a Path {
|
||||||
&self.path
|
&self.path
|
||||||
}
|
}
|
||||||
@ -208,6 +220,8 @@ impl File {
|
|||||||
/// Synchronizes all modifications to this file to its permanent storage
|
/// Synchronizes all modifications to this file to its permanent storage
|
||||||
/// device. This will flush any internal buffers necessary to perform this
|
/// device. This will flush any internal buffers necessary to perform this
|
||||||
/// operation.
|
/// operation.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn fsync(&mut self) -> IoResult<()> {
|
pub fn fsync(&mut self) -> IoResult<()> {
|
||||||
self.fd.fsync()
|
self.fd.fsync()
|
||||||
.update_err("couldn't fsync file",
|
.update_err("couldn't fsync file",
|
||||||
@ -218,6 +232,8 @@ impl File {
|
|||||||
/// file metadata to the filesystem. This is intended for use cases that
|
/// file metadata to the filesystem. This is intended for use cases that
|
||||||
/// must synchronize content, but don't need the metadata on disk. The goal
|
/// must synchronize content, but don't need the metadata on disk. The goal
|
||||||
/// of this method is to reduce disk operations.
|
/// of this method is to reduce disk operations.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn datasync(&mut self) -> IoResult<()> {
|
pub fn datasync(&mut self) -> IoResult<()> {
|
||||||
self.fd.datasync()
|
self.fd.datasync()
|
||||||
.update_err("couldn't datasync file",
|
.update_err("couldn't datasync file",
|
||||||
@ -232,6 +248,8 @@ impl File {
|
|||||||
/// be shrunk. If it is greater than the current file's size, then the file
|
/// be shrunk. If it is greater than the current file's size, then the file
|
||||||
/// will be extended to `size` and have all of the intermediate data filled
|
/// will be extended to `size` and have all of the intermediate data filled
|
||||||
/// in with 0s.
|
/// in with 0s.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn truncate(&mut self, size: i64) -> IoResult<()> {
|
pub fn truncate(&mut self, size: i64) -> IoResult<()> {
|
||||||
self.fd.truncate(size)
|
self.fd.truncate(size)
|
||||||
.update_err("couldn't truncate file", |e|
|
.update_err("couldn't truncate file", |e|
|
||||||
@ -247,11 +265,15 @@ impl File {
|
|||||||
/// until you have attempted to read past the end of the file, so if
|
/// until you have attempted to read past the end of the file, so if
|
||||||
/// you've read _exactly_ the number of bytes in the file, this will
|
/// you've read _exactly_ the number of bytes in the file, this will
|
||||||
/// return `false`, not `true`.
|
/// return `false`, not `true`.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn eof(&self) -> bool {
|
pub fn eof(&self) -> bool {
|
||||||
self.last_nread == 0
|
self.last_nread == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queries information about the underlying file.
|
/// Queries information about the underlying file.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn stat(&self) -> IoResult<FileStat> {
|
pub fn stat(&self) -> IoResult<FileStat> {
|
||||||
self.fd.fstat()
|
self.fd.fstat()
|
||||||
.update_err("couldn't fstat file", |e|
|
.update_err("couldn't fstat file", |e|
|
||||||
@ -280,6 +302,8 @@ impl File {
|
|||||||
/// This function will return an error if `path` points to a directory, if the
|
/// This function will return an error if `path` points to a directory, if the
|
||||||
/// user lacks permissions to remove the file, or if some other filesystem-level
|
/// user lacks permissions to remove the file, or if some other filesystem-level
|
||||||
/// error occurs.
|
/// error occurs.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_file")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn unlink(path: &Path) -> IoResult<()> {
|
pub fn unlink(path: &Path) -> IoResult<()> {
|
||||||
fs_imp::unlink(path)
|
fs_imp::unlink(path)
|
||||||
.update_err("couldn't unlink path", |e|
|
.update_err("couldn't unlink path", |e|
|
||||||
@ -307,6 +331,8 @@ pub fn unlink(path: &Path) -> IoResult<()> {
|
|||||||
/// This function will return an error if the user lacks the requisite permissions
|
/// This function will return an error if the user lacks the requisite permissions
|
||||||
/// to perform a `stat` call on the given `path` or if there is no entry in the
|
/// to perform a `stat` call on the given `path` or if there is no entry in the
|
||||||
/// filesystem at the provided path.
|
/// filesystem at the provided path.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::metadata")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn stat(path: &Path) -> IoResult<FileStat> {
|
pub fn stat(path: &Path) -> IoResult<FileStat> {
|
||||||
fs_imp::stat(path)
|
fs_imp::stat(path)
|
||||||
.update_err("couldn't stat path", |e|
|
.update_err("couldn't stat path", |e|
|
||||||
@ -321,6 +347,7 @@ pub fn stat(path: &Path) -> IoResult<FileStat> {
|
|||||||
/// # Error
|
/// # Error
|
||||||
///
|
///
|
||||||
/// See `stat`
|
/// See `stat`
|
||||||
|
#[unstable(feature = "old_fs")]
|
||||||
pub fn lstat(path: &Path) -> IoResult<FileStat> {
|
pub fn lstat(path: &Path) -> IoResult<FileStat> {
|
||||||
fs_imp::lstat(path)
|
fs_imp::lstat(path)
|
||||||
.update_err("couldn't lstat path", |e|
|
.update_err("couldn't lstat path", |e|
|
||||||
@ -343,6 +370,8 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> {
|
|||||||
/// This function will return an error if the provided `from` doesn't exist, if
|
/// This function will return an error if the provided `from` doesn't exist, if
|
||||||
/// the process lacks permissions to view the contents, or if some other
|
/// the process lacks permissions to view the contents, or if some other
|
||||||
/// intermittent I/O error occurs.
|
/// intermittent I/O error occurs.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::rename")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
|
pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
|
||||||
fs_imp::rename(from, to)
|
fs_imp::rename(from, to)
|
||||||
.update_err("couldn't rename path", |e|
|
.update_err("couldn't rename path", |e|
|
||||||
@ -377,6 +406,8 @@ pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
|
|||||||
/// Note that this copy is not atomic in that once the destination is
|
/// Note that this copy is not atomic in that once the destination is
|
||||||
/// ensured to not exist, there is nothing preventing the destination from
|
/// ensured to not exist, there is nothing preventing the destination from
|
||||||
/// being created and then destroyed by this operation.
|
/// being created and then destroyed by this operation.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::copy")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
|
pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
|
||||||
fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> {
|
fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> {
|
||||||
result.update_err("couldn't copy path", |e| {
|
result.update_err("couldn't copy path", |e| {
|
||||||
@ -421,6 +452,8 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
|
|||||||
/// This function will return an error if the provided `path` doesn't exist, if
|
/// This function will return an error if the provided `path` doesn't exist, if
|
||||||
/// the process lacks permissions to change the attributes of the file, or if
|
/// the process lacks permissions to change the attributes of the file, or if
|
||||||
/// some other I/O error is encountered.
|
/// some other I/O error is encountered.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_permissions")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> {
|
pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> {
|
||||||
fs_imp::chmod(path, mode.bits() as uint)
|
fs_imp::chmod(path, mode.bits() as uint)
|
||||||
.update_err("couldn't chmod path", |e|
|
.update_err("couldn't chmod path", |e|
|
||||||
@ -428,6 +461,7 @@ pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change the user and group owners of a file at the specified path.
|
/// Change the user and group owners of a file at the specified path.
|
||||||
|
#[unstable(feature = "old_fs")]
|
||||||
pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
|
pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
|
||||||
fs_imp::chown(path, uid, gid)
|
fs_imp::chown(path, uid, gid)
|
||||||
.update_err("couldn't chown path", |e|
|
.update_err("couldn't chown path", |e|
|
||||||
@ -437,6 +471,8 @@ pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
|
|||||||
/// Creates a new hard link on the filesystem. The `dst` path will be a
|
/// Creates a new hard link on the filesystem. The `dst` path will be a
|
||||||
/// link pointing to the `src` path. Note that systems often require these
|
/// link pointing to the `src` path. Note that systems often require these
|
||||||
/// two paths to both be located on the same filesystem.
|
/// two paths to both be located on the same filesystem.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::hard_link")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
|
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
|
||||||
fs_imp::link(src, dst)
|
fs_imp::link(src, dst)
|
||||||
.update_err("couldn't link path", |e|
|
.update_err("couldn't link path", |e|
|
||||||
@ -445,6 +481,8 @@ pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
|
|||||||
|
|
||||||
/// Creates a new symbolic link on the filesystem. The `dst` path will be a
|
/// Creates a new symbolic link on the filesystem. The `dst` path will be a
|
||||||
/// symlink pointing to the `src` path.
|
/// symlink pointing to the `src` path.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::soft_link")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
|
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
|
||||||
fs_imp::symlink(src, dst)
|
fs_imp::symlink(src, dst)
|
||||||
.update_err("couldn't symlink path", |e|
|
.update_err("couldn't symlink path", |e|
|
||||||
@ -457,6 +495,8 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
|
|||||||
///
|
///
|
||||||
/// This function will return an error on failure. Failure conditions include
|
/// This function will return an error on failure. Failure conditions include
|
||||||
/// reading a file that does not exist or reading a file that is not a symlink.
|
/// reading a file that does not exist or reading a file that is not a symlink.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_link")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn readlink(path: &Path) -> IoResult<Path> {
|
pub fn readlink(path: &Path) -> IoResult<Path> {
|
||||||
fs_imp::readlink(path)
|
fs_imp::readlink(path)
|
||||||
.update_err("couldn't resolve symlink for path", |e|
|
.update_err("couldn't resolve symlink for path", |e|
|
||||||
@ -480,6 +520,7 @@ pub fn readlink(path: &Path) -> IoResult<Path> {
|
|||||||
///
|
///
|
||||||
/// This function will return an error if the user lacks permissions to make a
|
/// This function will return an error if the user lacks permissions to make a
|
||||||
/// new directory at the provided `path`, or if the directory already exists.
|
/// new directory at the provided `path`, or if the directory already exists.
|
||||||
|
#[unstable(feature = "old_fs")]
|
||||||
pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
|
pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
|
||||||
fs_imp::mkdir(path, mode.bits() as uint)
|
fs_imp::mkdir(path, mode.bits() as uint)
|
||||||
.update_err("couldn't create directory", |e|
|
.update_err("couldn't create directory", |e|
|
||||||
@ -502,6 +543,8 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
|
|||||||
///
|
///
|
||||||
/// This function will return an error if the user lacks permissions to remove
|
/// This function will return an error if the user lacks permissions to remove
|
||||||
/// the directory at the provided `path`, or if the directory isn't empty.
|
/// the directory at the provided `path`, or if the directory isn't empty.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn rmdir(path: &Path) -> IoResult<()> {
|
pub fn rmdir(path: &Path) -> IoResult<()> {
|
||||||
fs_imp::rmdir(path)
|
fs_imp::rmdir(path)
|
||||||
.update_err("couldn't remove directory", |e|
|
.update_err("couldn't remove directory", |e|
|
||||||
@ -542,6 +585,8 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
|
|||||||
/// This function will return an error if the provided `path` doesn't exist, if
|
/// This function will return an error if the provided `path` doesn't exist, if
|
||||||
/// the process lacks permissions to view the contents or if the `path` points
|
/// the process lacks permissions to view the contents or if the `path` points
|
||||||
/// at a non-directory file
|
/// at a non-directory file
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_dir")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
|
pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
|
||||||
fs_imp::readdir(path)
|
fs_imp::readdir(path)
|
||||||
.update_err("couldn't read directory",
|
.update_err("couldn't read directory",
|
||||||
@ -552,6 +597,8 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
|
|||||||
/// rooted at `path`. The path given will not be iterated over, and this will
|
/// rooted at `path`. The path given will not be iterated over, and this will
|
||||||
/// perform iteration in some top-down order. The contents of unreadable
|
/// perform iteration in some top-down order. The contents of unreadable
|
||||||
/// subdirectories are ignored.
|
/// subdirectories are ignored.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::walk_dir")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn walk_dir(path: &Path) -> IoResult<Directories> {
|
pub fn walk_dir(path: &Path) -> IoResult<Directories> {
|
||||||
Ok(Directories {
|
Ok(Directories {
|
||||||
stack: try!(readdir(path).update_err("couldn't walk directory",
|
stack: try!(readdir(path).update_err("couldn't walk directory",
|
||||||
@ -561,6 +608,8 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> {
|
|||||||
|
|
||||||
/// An iterator that walks over a directory
|
/// An iterator that walks over a directory
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::ReadDir")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub struct Directories {
|
pub struct Directories {
|
||||||
stack: Vec<Path>,
|
stack: Vec<Path>,
|
||||||
}
|
}
|
||||||
@ -590,6 +639,7 @@ impl Iterator for Directories {
|
|||||||
/// # Error
|
/// # Error
|
||||||
///
|
///
|
||||||
/// See `fs::mkdir`.
|
/// See `fs::mkdir`.
|
||||||
|
#[unstable(feature = "old_fs")]
|
||||||
pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
|
pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
|
||||||
// tjc: if directory exists but with different permissions,
|
// tjc: if directory exists but with different permissions,
|
||||||
// should we return false?
|
// should we return false?
|
||||||
@ -627,6 +677,8 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
|
|||||||
/// # Error
|
/// # Error
|
||||||
///
|
///
|
||||||
/// See `file::unlink` and `fs::readdir`
|
/// See `file::unlink` and `fs::readdir`
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir_all")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
|
pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
|
||||||
let mut rm_stack = Vec::new();
|
let mut rm_stack = Vec::new();
|
||||||
rm_stack.push(path.clone());
|
rm_stack.push(path.clone());
|
||||||
@ -689,6 +741,8 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
|
|||||||
/// `atime` and its modification time set to `mtime`. The times specified should
|
/// `atime` and its modification time set to `mtime`. The times specified should
|
||||||
/// be in milliseconds.
|
/// be in milliseconds.
|
||||||
// FIXME(#10301) these arguments should not be u64
|
// FIXME(#10301) these arguments should not be u64
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_file_times")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
|
pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
|
||||||
fs_imp::utime(path, atime, mtime)
|
fs_imp::utime(path, atime, mtime)
|
||||||
.update_err("couldn't change_file_times", |e|
|
.update_err("couldn't change_file_times", |e|
|
||||||
@ -748,6 +802,8 @@ impl Seek for File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Utility methods for paths.
|
/// Utility methods for paths.
|
||||||
|
#[deprecated(since = "1.0.0", reason = "replaced with std::fs::PathExt")]
|
||||||
|
#[unstable(feature = "old_io")]
|
||||||
pub trait PathExtensions {
|
pub trait PathExtensions {
|
||||||
/// Get information on the file, directory, etc at this path.
|
/// Get information on the file, directory, etc at this path.
|
||||||
///
|
///
|
||||||
|
@ -54,6 +54,7 @@ pub trait AsRawFd {
|
|||||||
fn as_raw_fd(&self) -> Fd;
|
fn as_raw_fd(&self) -> Fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl AsRawFd for old_io::fs::File {
|
impl AsRawFd for old_io::fs::File {
|
||||||
fn as_raw_fd(&self) -> Fd {
|
fn as_raw_fd(&self) -> Fd {
|
||||||
self.as_inner().fd()
|
self.as_inner().fd()
|
||||||
|
@ -39,6 +39,7 @@ pub trait AsRawHandle {
|
|||||||
fn as_raw_handle(&self) -> Handle;
|
fn as_raw_handle(&self) -> Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
impl AsRawHandle for old_io::fs::File {
|
impl AsRawHandle for old_io::fs::File {
|
||||||
fn as_raw_handle(&self) -> Handle {
|
fn as_raw_handle(&self) -> Handle {
|
||||||
self.as_inner().handle()
|
self.as_inner().handle()
|
||||||
|
@ -17,7 +17,7 @@ use hash::Hash;
|
|||||||
use libc::{pid_t, c_void};
|
use libc::{pid_t, c_void};
|
||||||
use libc;
|
use libc;
|
||||||
use mem;
|
use mem;
|
||||||
use old_io::fs::PathExtensions;
|
#[allow(deprecated)] use old_io::fs::PathExtensions;
|
||||||
use old_io::process::{ProcessExit, ExitStatus};
|
use old_io::process::{ProcessExit, ExitStatus};
|
||||||
use old_io::{IoResult, IoError};
|
use old_io::{IoResult, IoError};
|
||||||
use old_io;
|
use old_io;
|
||||||
|
@ -25,7 +25,7 @@ use visit::{self, Visitor};
|
|||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::old_io::IoResult;
|
use std::io;
|
||||||
use std::iter::{self, repeat};
|
use std::iter::{self, repeat};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@ -997,11 +997,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait NodePrinter {
|
pub trait NodePrinter {
|
||||||
fn print_node(&mut self, node: &Node) -> IoResult<()>;
|
fn print_node(&mut self, node: &Node) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NodePrinter for pprust::State<'a> {
|
impl<'a> NodePrinter for pprust::State<'a> {
|
||||||
fn print_node(&mut self, node: &Node) -> IoResult<()> {
|
fn print_node(&mut self, node: &Node) -> io::Result<()> {
|
||||||
match *node {
|
match *node {
|
||||||
NodeItem(a) => self.print_item(&*a),
|
NodeItem(a) => self.print_item(&*a),
|
||||||
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
||||||
|
@ -20,7 +20,9 @@ use print::pprust;
|
|||||||
use ptr::P;
|
use ptr::P;
|
||||||
use util::small_vector::SmallVector;
|
use util::small_vector::SmallVector;
|
||||||
|
|
||||||
use std::old_io::File;
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
// These macros all relate to the file system; they either return
|
// These macros all relate to the file system; they either return
|
||||||
@ -97,7 +99,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
|
|||||||
cx.cfg(),
|
cx.cfg(),
|
||||||
&res_rel_file(cx,
|
&res_rel_file(cx,
|
||||||
sp,
|
sp,
|
||||||
&Path::new(file)),
|
Path::new(&file)),
|
||||||
true,
|
true,
|
||||||
None,
|
None,
|
||||||
sp);
|
sp);
|
||||||
@ -136,8 +138,10 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => return DummyResult::expr(sp)
|
None => return DummyResult::expr(sp)
|
||||||
};
|
};
|
||||||
let file = res_rel_file(cx, sp, &Path::new(file));
|
let file = res_rel_file(cx, sp, Path::new(&file));
|
||||||
let bytes = match File::open(&file).read_to_end() {
|
let mut bytes = Vec::new();
|
||||||
|
match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
|
||||||
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
cx.span_err(sp,
|
cx.span_err(sp,
|
||||||
&format!("couldn't read {}: {}",
|
&format!("couldn't read {}: {}",
|
||||||
@ -145,7 +149,6 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||||||
e));
|
e));
|
||||||
return DummyResult::expr(sp);
|
return DummyResult::expr(sp);
|
||||||
}
|
}
|
||||||
Ok(bytes) => bytes,
|
|
||||||
};
|
};
|
||||||
match String::from_utf8(bytes) {
|
match String::from_utf8(bytes) {
|
||||||
Ok(src) => {
|
Ok(src) => {
|
||||||
@ -172,15 +175,15 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => return DummyResult::expr(sp)
|
None => return DummyResult::expr(sp)
|
||||||
};
|
};
|
||||||
let file = res_rel_file(cx, sp, &Path::new(file));
|
let file = res_rel_file(cx, sp, Path::new(&file));
|
||||||
match File::open(&file).read_to_end() {
|
let mut bytes = Vec::new();
|
||||||
|
match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
cx.span_err(sp,
|
cx.span_err(sp,
|
||||||
&format!("couldn't read {}: {}", file.display(), e));
|
&format!("couldn't read {}: {}", file.display(), e));
|
||||||
return DummyResult::expr(sp);
|
return DummyResult::expr(sp);
|
||||||
}
|
}
|
||||||
Ok(bytes) => {
|
Ok(..) => {
|
||||||
let bytes = bytes.iter().cloned().collect();
|
|
||||||
base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
|
base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,14 +191,18 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||||||
|
|
||||||
// resolve a file-system path to an absolute file-system path (if it
|
// resolve a file-system path to an absolute file-system path (if it
|
||||||
// isn't already)
|
// isn't already)
|
||||||
fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path {
|
fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf {
|
||||||
// NB: relative paths are resolved relative to the compilation unit
|
// NB: relative paths are resolved relative to the compilation unit
|
||||||
if !arg.is_absolute() {
|
if !arg.is_absolute() {
|
||||||
let mut cu = Path::new(cx.codemap().span_to_filename(sp));
|
let mut cu = PathBuf::new(&cx.codemap().span_to_filename(sp));
|
||||||
cu.pop();
|
if cu.parent().is_some() {
|
||||||
|
cu.pop();
|
||||||
|
} else {
|
||||||
|
cu = PathBuf::new("");
|
||||||
|
}
|
||||||
cu.push(arg);
|
cu.push(arg);
|
||||||
cu
|
cu
|
||||||
} else {
|
} else {
|
||||||
arg.clone()
|
arg.to_path_buf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1432,7 +1432,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T)
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::old_io;
|
use std::io;
|
||||||
use ast;
|
use ast;
|
||||||
use util::parser_testing::{string_to_crate, matches_codepattern};
|
use util::parser_testing::{string_to_crate, matches_codepattern};
|
||||||
use parse::token;
|
use parse::token;
|
||||||
@ -1442,7 +1442,7 @@ mod test {
|
|||||||
|
|
||||||
// this version doesn't care about getting comments or docstrings in.
|
// this version doesn't care about getting comments or docstrings in.
|
||||||
fn fake_print_crate(s: &mut pprust::State,
|
fn fake_print_crate(s: &mut pprust::State,
|
||||||
krate: &ast::Crate) -> old_io::IoResult<()> {
|
krate: &ast::Crate) -> io::Result<()> {
|
||||||
s.print_mod(&krate.module, &krate.attrs)
|
s.print_mod(&krate.module, &krate.attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,9 @@
|
|||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(io)]
|
||||||
|
|
||||||
extern crate arena;
|
extern crate arena;
|
||||||
extern crate fmt_macros;
|
extern crate fmt_macros;
|
||||||
|
@ -19,9 +19,8 @@ use parse::lexer::is_block_doc_comment;
|
|||||||
use parse::lexer;
|
use parse::lexer;
|
||||||
use print::pprust;
|
use print::pprust;
|
||||||
|
|
||||||
use std::old_io;
|
use std::io::Read;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::string::String;
|
|
||||||
use std::usize;
|
use std::usize;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
@ -337,9 +336,10 @@ pub struct Literal {
|
|||||||
// probably not a good thing.
|
// probably not a good thing.
|
||||||
pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
|
pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
|
||||||
path: String,
|
path: String,
|
||||||
srdr: &mut old_io::Reader)
|
srdr: &mut Read)
|
||||||
-> (Vec<Comment>, Vec<Literal>) {
|
-> (Vec<Comment>, Vec<Literal>) {
|
||||||
let src = srdr.read_to_end().unwrap();
|
let mut src = Vec::new();
|
||||||
|
srdr.read_to_end(&mut src).unwrap();
|
||||||
let src = String::from_utf8(src).unwrap();
|
let src = String::from_utf8(src).unwrap();
|
||||||
let cm = CodeMap::new();
|
let cm = CodeMap::new();
|
||||||
let filemap = cm.new_filemap(path, src);
|
let filemap = cm.new_filemap(path, src);
|
||||||
|
@ -18,11 +18,13 @@ use parse::parser::Parser;
|
|||||||
use ptr::P;
|
use ptr::P;
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::old_io::File;
|
use std::fs::File;
|
||||||
use std::rc::Rc;
|
use std::io::Read;
|
||||||
use std::num::Int;
|
|
||||||
use std::str;
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::num::Int;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
@ -39,7 +41,7 @@ pub mod obsolete;
|
|||||||
pub struct ParseSess {
|
pub struct ParseSess {
|
||||||
pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
|
pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
|
||||||
/// Used to determine and report recursive mod inclusions
|
/// Used to determine and report recursive mod inclusions
|
||||||
included_mod_stack: RefCell<Vec<Path>>,
|
included_mod_stack: RefCell<Vec<PathBuf>>,
|
||||||
pub node_id: Cell<ast::NodeId>,
|
pub node_id: Cell<ast::NodeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,24 +252,24 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
|
|||||||
None => sess.span_diagnostic.handler().fatal(msg),
|
None => sess.span_diagnostic.handler().fatal(msg),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let bytes = match File::open(path).read_to_end() {
|
let mut bytes = Vec::new();
|
||||||
Ok(bytes) => bytes,
|
match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) {
|
||||||
|
Ok(..) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err(&format!("couldn't read {:?}: {}",
|
err(&format!("couldn't read {:?}: {}", path.display(), e));
|
||||||
path.display(), e));
|
unreachable!();
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match str::from_utf8(&bytes[..]).ok() {
|
match str::from_utf8(&bytes[..]).ok() {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
return string_to_filemap(sess, s.to_string(),
|
string_to_filemap(sess, s.to_string(),
|
||||||
path.as_str().unwrap().to_string())
|
path.to_str().unwrap().to_string())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
err(&format!("{:?} is not UTF-8 encoded", path.display()))
|
err(&format!("{:?} is not UTF-8 encoded", path.display()));
|
||||||
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a session and a string, add the string to
|
/// Given a session and a string, add the string to
|
||||||
|
@ -78,10 +78,11 @@ use ptr::P;
|
|||||||
use owned_slice::OwnedSlice;
|
use owned_slice::OwnedSlice;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::io::prelude::*;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::Float;
|
use std::num::Float;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
@ -5248,14 +5249,23 @@ impl<'a> Parser<'a> {
|
|||||||
outer_attrs: &[ast::Attribute],
|
outer_attrs: &[ast::Attribute],
|
||||||
id_sp: Span)
|
id_sp: Span)
|
||||||
-> (ast::Item_, Vec<ast::Attribute> ) {
|
-> (ast::Item_, Vec<ast::Attribute> ) {
|
||||||
let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
|
let mut prefix = PathBuf::new(&self.sess.span_diagnostic.cm
|
||||||
prefix.pop();
|
.span_to_filename(self.span));
|
||||||
let mod_path = Path::new(".").join_many(&self.mod_path_stack);
|
// FIXME(acrichto): right now "a".pop() == "a", but need to confirm with
|
||||||
let dir_path = prefix.join(&mod_path);
|
// aturon whether this is expected or not.
|
||||||
|
if prefix.parent().is_some() {
|
||||||
|
prefix.pop();
|
||||||
|
} else {
|
||||||
|
prefix = PathBuf::new("");
|
||||||
|
}
|
||||||
|
let mut dir_path = prefix;
|
||||||
|
for part in &self.mod_path_stack {
|
||||||
|
dir_path.push(&**part);
|
||||||
|
}
|
||||||
let mod_string = token::get_ident(id);
|
let mod_string = token::get_ident(id);
|
||||||
let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
|
let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
|
||||||
outer_attrs, "path") {
|
outer_attrs, "path") {
|
||||||
Some(d) => (dir_path.join(d), true),
|
Some(d) => (dir_path.join(&*d), true),
|
||||||
None => {
|
None => {
|
||||||
let mod_name = mod_string.to_string();
|
let mod_name = mod_string.to_string();
|
||||||
let default_path_str = format!("{}.rs", mod_name);
|
let default_path_str = format!("{}.rs", mod_name);
|
||||||
@ -5319,7 +5329,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eval_src_mod_from_path(&mut self,
|
fn eval_src_mod_from_path(&mut self,
|
||||||
path: Path,
|
path: PathBuf,
|
||||||
owns_directory: bool,
|
owns_directory: bool,
|
||||||
name: String,
|
name: String,
|
||||||
id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
|
id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
|
||||||
@ -5329,10 +5339,10 @@ impl<'a> Parser<'a> {
|
|||||||
let mut err = String::from_str("circular modules: ");
|
let mut err = String::from_str("circular modules: ");
|
||||||
let len = included_mod_stack.len();
|
let len = included_mod_stack.len();
|
||||||
for p in &included_mod_stack[i.. len] {
|
for p in &included_mod_stack[i.. len] {
|
||||||
err.push_str(&p.display().as_cow());
|
err.push_str(&p.to_string_lossy());
|
||||||
err.push_str(" -> ");
|
err.push_str(" -> ");
|
||||||
}
|
}
|
||||||
err.push_str(&path.display().as_cow());
|
err.push_str(&path.to_string_lossy());
|
||||||
self.span_fatal(id_sp, &err[..]);
|
self.span_fatal(id_sp, &err[..]);
|
||||||
}
|
}
|
||||||
None => ()
|
None => ()
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
//! line (which it can't) and so naturally place the content on its own line to
|
//! line (which it can't) and so naturally place the content on its own line to
|
||||||
//! avoid combining it with other lines and making matters even worse.
|
//! avoid combining it with other lines and making matters even worse.
|
||||||
|
|
||||||
use std::old_io;
|
use std::io;
|
||||||
use std::string;
|
use std::string;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ pub struct PrintStackElem {
|
|||||||
|
|
||||||
const SIZE_INFINITY: isize = 0xffff;
|
const SIZE_INFINITY: isize = 0xffff;
|
||||||
|
|
||||||
pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer {
|
pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||||
// Yes 3, it makes the ring buffers big enough to never
|
// Yes 3, it makes the ring buffers big enough to never
|
||||||
// fall behind.
|
// fall behind.
|
||||||
let n: usize = 3 * linewidth;
|
let n: usize = 3 * linewidth;
|
||||||
@ -265,8 +265,8 @@ pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer
|
|||||||
/// In this implementation (following the paper, again) the SCAN process is
|
/// In this implementation (following the paper, again) the SCAN process is
|
||||||
/// the method called 'pretty_print', and the 'PRINT' process is the method
|
/// the method called 'pretty_print', and the 'PRINT' process is the method
|
||||||
/// called 'print'.
|
/// called 'print'.
|
||||||
pub struct Printer {
|
pub struct Printer<'a> {
|
||||||
pub out: Box<old_io::Writer+'static>,
|
pub out: Box<io::Write+'a>,
|
||||||
buf_len: usize,
|
buf_len: usize,
|
||||||
/// Width of lines we're constrained to
|
/// Width of lines we're constrained to
|
||||||
margin: isize,
|
margin: isize,
|
||||||
@ -303,7 +303,7 @@ pub struct Printer {
|
|||||||
pending_indentation: isize,
|
pending_indentation: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Printer {
|
impl<'a> Printer<'a> {
|
||||||
pub fn last_token(&mut self) -> Token {
|
pub fn last_token(&mut self) -> Token {
|
||||||
self.token[self.right].clone()
|
self.token[self.right].clone()
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ impl Printer {
|
|||||||
pub fn replace_last_token(&mut self, t: Token) {
|
pub fn replace_last_token(&mut self, t: Token) {
|
||||||
self.token[self.right] = t;
|
self.token[self.right] = t;
|
||||||
}
|
}
|
||||||
pub fn pretty_print(&mut self, token: Token) -> old_io::IoResult<()> {
|
pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
|
||||||
debug!("pp ~[{},{}]", self.left, self.right);
|
debug!("pp ~[{},{}]", self.left, self.right);
|
||||||
match token {
|
match token {
|
||||||
Token::Eof => {
|
Token::Eof => {
|
||||||
@ -385,7 +385,7 @@ impl Printer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn check_stream(&mut self) -> old_io::IoResult<()> {
|
pub fn check_stream(&mut self) -> io::Result<()> {
|
||||||
debug!("check_stream ~[{}, {}] with left_total={}, right_total={}",
|
debug!("check_stream ~[{}, {}] with left_total={}, right_total={}",
|
||||||
self.left, self.right, self.left_total, self.right_total);
|
self.left, self.right, self.left_total, self.right_total);
|
||||||
if self.right_total - self.left_total > self.space {
|
if self.right_total - self.left_total > self.space {
|
||||||
@ -445,7 +445,7 @@ impl Printer {
|
|||||||
self.right %= self.buf_len;
|
self.right %= self.buf_len;
|
||||||
assert!((self.right != self.left));
|
assert!((self.right != self.left));
|
||||||
}
|
}
|
||||||
pub fn advance_left(&mut self) -> old_io::IoResult<()> {
|
pub fn advance_left(&mut self) -> io::Result<()> {
|
||||||
debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
|
debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
|
||||||
self.left, self.size[self.left]);
|
self.left, self.size[self.left]);
|
||||||
|
|
||||||
@ -506,7 +506,7 @@ impl Printer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn print_newline(&mut self, amount: isize) -> old_io::IoResult<()> {
|
pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
|
||||||
debug!("NEWLINE {}", amount);
|
debug!("NEWLINE {}", amount);
|
||||||
let ret = write!(self.out, "\n");
|
let ret = write!(self.out, "\n");
|
||||||
self.pending_indentation = 0;
|
self.pending_indentation = 0;
|
||||||
@ -529,14 +529,14 @@ impl Printer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> {
|
pub fn print_str(&mut self, s: &str) -> io::Result<()> {
|
||||||
while self.pending_indentation > 0 {
|
while self.pending_indentation > 0 {
|
||||||
try!(write!(self.out, " "));
|
try!(write!(self.out, " "));
|
||||||
self.pending_indentation -= 1;
|
self.pending_indentation -= 1;
|
||||||
}
|
}
|
||||||
write!(self.out, "{}", s)
|
write!(self.out, "{}", s)
|
||||||
}
|
}
|
||||||
pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
|
pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
|
||||||
debug!("print {} {} (remaining line space={})", tok_str(&token), l,
|
debug!("print {} {} (remaining line space={})", tok_str(&token), l,
|
||||||
self.space);
|
self.space);
|
||||||
debug!("{}", buf_str(&self.token,
|
debug!("{}", buf_str(&self.token,
|
||||||
@ -620,61 +620,61 @@ impl Printer {
|
|||||||
// Convenience functions to talk to the printer.
|
// Convenience functions to talk to the printer.
|
||||||
//
|
//
|
||||||
// "raw box"
|
// "raw box"
|
||||||
pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> old_io::IoResult<()> {
|
pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
|
||||||
p.pretty_print(Token::Begin(BeginToken {
|
p.pretty_print(Token::Begin(BeginToken {
|
||||||
offset: indent as isize,
|
offset: indent as isize,
|
||||||
breaks: b
|
breaks: b
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ibox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
|
pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> {
|
||||||
rbox(p, indent, Breaks::Inconsistent)
|
rbox(p, indent, Breaks::Inconsistent)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cbox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
|
pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> {
|
||||||
rbox(p, indent, Breaks::Consistent)
|
rbox(p, indent, Breaks::Consistent)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> old_io::IoResult<()> {
|
pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> {
|
||||||
p.pretty_print(Token::Break(BreakToken {
|
p.pretty_print(Token::Break(BreakToken {
|
||||||
offset: off,
|
offset: off,
|
||||||
blank_space: n as isize
|
blank_space: n as isize
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end(p: &mut Printer) -> old_io::IoResult<()> {
|
pub fn end(p: &mut Printer) -> io::Result<()> {
|
||||||
p.pretty_print(Token::End)
|
p.pretty_print(Token::End)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eof(p: &mut Printer) -> old_io::IoResult<()> {
|
pub fn eof(p: &mut Printer) -> io::Result<()> {
|
||||||
p.pretty_print(Token::Eof)
|
p.pretty_print(Token::Eof)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
|
pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> {
|
||||||
p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize))
|
p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn huge_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
|
pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
|
||||||
p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
|
p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zero_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
|
pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
|
||||||
p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
|
p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spaces(p: &mut Printer, n: usize) -> old_io::IoResult<()> {
|
pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> {
|
||||||
break_offset(p, n, 0)
|
break_offset(p, n, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zerobreak(p: &mut Printer) -> old_io::IoResult<()> {
|
pub fn zerobreak(p: &mut Printer) -> io::Result<()> {
|
||||||
spaces(p, 0)
|
spaces(p, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn space(p: &mut Printer) -> old_io::IoResult<()> {
|
pub fn space(p: &mut Printer) -> io::Result<()> {
|
||||||
spaces(p, 1)
|
spaces(p, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardbreak(p: &mut Printer) -> old_io::IoResult<()> {
|
pub fn hardbreak(p: &mut Printer) -> io::Result<()> {
|
||||||
spaces(p, SIZE_INFINITY as usize)
|
spaces(p, SIZE_INFINITY as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ use ptr::P;
|
|||||||
use std_inject;
|
use std_inject;
|
||||||
|
|
||||||
use std::{ascii, mem};
|
use std::{ascii, mem};
|
||||||
use std::old_io::{self, IoResult};
|
use std::io::{self, Write, Read};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
pub enum AnnNode<'a> {
|
pub enum AnnNode<'a> {
|
||||||
@ -43,8 +43,8 @@ pub enum AnnNode<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait PpAnn {
|
pub trait PpAnn {
|
||||||
fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
|
fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
|
||||||
fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
|
fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
@ -59,7 +59,7 @@ pub struct CurrentCommentAndLiteral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct State<'a> {
|
pub struct State<'a> {
|
||||||
pub s: pp::Printer,
|
pub s: pp::Printer<'a>,
|
||||||
cm: Option<&'a CodeMap>,
|
cm: Option<&'a CodeMap>,
|
||||||
comments: Option<Vec<comments::Comment> >,
|
comments: Option<Vec<comments::Comment> >,
|
||||||
literals: Option<Vec<comments::Literal> >,
|
literals: Option<Vec<comments::Literal> >,
|
||||||
@ -69,12 +69,12 @@ pub struct State<'a> {
|
|||||||
encode_idents_with_hygiene: bool,
|
encode_idents_with_hygiene: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rust_printer(writer: Box<old_io::Writer+'static>) -> State<'static> {
|
pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> {
|
||||||
static NO_ANN: NoAnn = NoAnn;
|
static NO_ANN: NoAnn = NoAnn;
|
||||||
rust_printer_annotated(writer, &NO_ANN)
|
rust_printer_annotated(writer, &NO_ANN)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rust_printer_annotated<'a>(writer: Box<old_io::Writer+'static>,
|
pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>,
|
||||||
ann: &'a PpAnn) -> State<'a> {
|
ann: &'a PpAnn) -> State<'a> {
|
||||||
State {
|
State {
|
||||||
s: pp::mk_printer(writer, default_columns),
|
s: pp::mk_printer(writer, default_columns),
|
||||||
@ -104,10 +104,10 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
|
|||||||
span_diagnostic: &diagnostic::SpanHandler,
|
span_diagnostic: &diagnostic::SpanHandler,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
filename: String,
|
filename: String,
|
||||||
input: &mut old_io::Reader,
|
input: &mut Read,
|
||||||
out: Box<old_io::Writer+'static>,
|
out: Box<Write+'a>,
|
||||||
ann: &'a PpAnn,
|
ann: &'a PpAnn,
|
||||||
is_expanded: bool) -> IoResult<()> {
|
is_expanded: bool) -> io::Result<()> {
|
||||||
let mut s = State::new_from_input(cm,
|
let mut s = State::new_from_input(cm,
|
||||||
span_diagnostic,
|
span_diagnostic,
|
||||||
filename,
|
filename,
|
||||||
@ -143,8 +143,8 @@ impl<'a> State<'a> {
|
|||||||
pub fn new_from_input(cm: &'a CodeMap,
|
pub fn new_from_input(cm: &'a CodeMap,
|
||||||
span_diagnostic: &diagnostic::SpanHandler,
|
span_diagnostic: &diagnostic::SpanHandler,
|
||||||
filename: String,
|
filename: String,
|
||||||
input: &mut old_io::Reader,
|
input: &mut Read,
|
||||||
out: Box<old_io::Writer+'static>,
|
out: Box<Write+'a>,
|
||||||
ann: &'a PpAnn,
|
ann: &'a PpAnn,
|
||||||
is_expanded: bool) -> State<'a> {
|
is_expanded: bool) -> State<'a> {
|
||||||
let (cmnts, lits) = comments::gather_comments_and_literals(
|
let (cmnts, lits) = comments::gather_comments_and_literals(
|
||||||
@ -164,7 +164,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(cm: &'a CodeMap,
|
pub fn new(cm: &'a CodeMap,
|
||||||
out: Box<old_io::Writer+'static>,
|
out: Box<Write+'a>,
|
||||||
ann: &'a PpAnn,
|
ann: &'a PpAnn,
|
||||||
comments: Option<Vec<comments::Comment>>,
|
comments: Option<Vec<comments::Comment>>,
|
||||||
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
||||||
@ -185,14 +185,14 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_string<F>(f: F) -> String where
|
pub fn to_string<F>(f: F) -> String where
|
||||||
F: FnOnce(&mut State) -> IoResult<()>,
|
F: FnOnce(&mut State) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
use std::raw::TraitObject;
|
use std::raw::TraitObject;
|
||||||
let mut s = rust_printer(box Vec::new());
|
let mut s = rust_printer(box Vec::new());
|
||||||
f(&mut s).unwrap();
|
f(&mut s).unwrap();
|
||||||
eof(&mut s.s).unwrap();
|
eof(&mut s.s).unwrap();
|
||||||
let wr = unsafe {
|
let wr = unsafe {
|
||||||
// FIXME(pcwalton): A nasty function to extract the string from an `old_io::Writer`
|
// FIXME(pcwalton): A nasty function to extract the string from an `Write`
|
||||||
// that we "know" to be a `Vec<u8>` that works around the lack of checked
|
// that we "know" to be a `Vec<u8>` that works around the lack of checked
|
||||||
// downcasts.
|
// downcasts.
|
||||||
let obj: &TraitObject = mem::transmute(&s.s.out);
|
let obj: &TraitObject = mem::transmute(&s.s.out);
|
||||||
@ -440,13 +440,13 @@ thing_to_string_impls! { to_string }
|
|||||||
pub mod with_hygiene {
|
pub mod with_hygiene {
|
||||||
use abi;
|
use abi;
|
||||||
use ast;
|
use ast;
|
||||||
use std::old_io::IoResult;
|
use std::io;
|
||||||
use super::indent_unit;
|
use super::indent_unit;
|
||||||
|
|
||||||
// This function is the trick that all the rest of the routines
|
// This function is the trick that all the rest of the routines
|
||||||
// hang on.
|
// hang on.
|
||||||
pub fn to_string_hyg<F>(f: F) -> String where
|
pub fn to_string_hyg<F>(f: F) -> String where
|
||||||
F: FnOnce(&mut super::State) -> IoResult<()>,
|
F: FnOnce(&mut super::State) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
super::to_string(move |s| {
|
super::to_string(move |s| {
|
||||||
s.encode_idents_with_hygiene = true;
|
s.encode_idents_with_hygiene = true;
|
||||||
@ -474,44 +474,44 @@ fn needs_parentheses(expr: &ast::Expr) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
pub fn ibox(&mut self, u: usize) -> IoResult<()> {
|
pub fn ibox(&mut self, u: usize) -> io::Result<()> {
|
||||||
self.boxes.push(pp::Breaks::Inconsistent);
|
self.boxes.push(pp::Breaks::Inconsistent);
|
||||||
pp::ibox(&mut self.s, u)
|
pp::ibox(&mut self.s, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end(&mut self) -> IoResult<()> {
|
pub fn end(&mut self) -> io::Result<()> {
|
||||||
self.boxes.pop().unwrap();
|
self.boxes.pop().unwrap();
|
||||||
pp::end(&mut self.s)
|
pp::end(&mut self.s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cbox(&mut self, u: usize) -> IoResult<()> {
|
pub fn cbox(&mut self, u: usize) -> io::Result<()> {
|
||||||
self.boxes.push(pp::Breaks::Consistent);
|
self.boxes.push(pp::Breaks::Consistent);
|
||||||
pp::cbox(&mut self.s, u)
|
pp::cbox(&mut self.s, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
// "raw box"
|
// "raw box"
|
||||||
pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> IoResult<()> {
|
pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> {
|
||||||
self.boxes.push(b);
|
self.boxes.push(b);
|
||||||
pp::rbox(&mut self.s, u, b)
|
pp::rbox(&mut self.s, u, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") }
|
pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") }
|
||||||
|
|
||||||
pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> {
|
pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, w));
|
try!(word(&mut self.s, w));
|
||||||
self.nbsp()
|
self.nbsp()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn word_space(&mut self, w: &str) -> IoResult<()> {
|
pub fn word_space(&mut self, w: &str) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, w));
|
try!(word(&mut self.s, w));
|
||||||
space(&mut self.s)
|
space(&mut self.s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") }
|
pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") }
|
||||||
|
|
||||||
pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") }
|
pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") }
|
||||||
|
|
||||||
pub fn head(&mut self, w: &str) -> IoResult<()> {
|
pub fn head(&mut self, w: &str) -> io::Result<()> {
|
||||||
// outer-box is consistent
|
// outer-box is consistent
|
||||||
try!(self.cbox(indent_unit));
|
try!(self.cbox(indent_unit));
|
||||||
// head-box is inconsistent
|
// head-box is inconsistent
|
||||||
@ -523,17 +523,17 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bopen(&mut self) -> IoResult<()> {
|
pub fn bopen(&mut self) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, "{"));
|
try!(word(&mut self.s, "{"));
|
||||||
self.end() // close the head-box
|
self.end() // close the head-box
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bclose_(&mut self, span: codemap::Span,
|
pub fn bclose_(&mut self, span: codemap::Span,
|
||||||
indented: usize) -> IoResult<()> {
|
indented: usize) -> io::Result<()> {
|
||||||
self.bclose_maybe_open(span, indented, true)
|
self.bclose_maybe_open(span, indented, true)
|
||||||
}
|
}
|
||||||
pub fn bclose_maybe_open (&mut self, span: codemap::Span,
|
pub fn bclose_maybe_open (&mut self, span: codemap::Span,
|
||||||
indented: usize, close_box: bool) -> IoResult<()> {
|
indented: usize, close_box: bool) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(span.hi));
|
try!(self.maybe_print_comment(span.hi));
|
||||||
try!(self.break_offset_if_not_bol(1, -(indented as isize)));
|
try!(self.break_offset_if_not_bol(1, -(indented as isize)));
|
||||||
try!(word(&mut self.s, "}"));
|
try!(word(&mut self.s, "}"));
|
||||||
@ -542,7 +542,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> {
|
pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
|
||||||
self.bclose_(span, indent_unit)
|
self.bclose_(span, indent_unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,18 +572,18 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> {
|
pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> {
|
||||||
if !self.is_bol() {
|
if !self.is_bol() {
|
||||||
try!(hardbreak(&mut self.s))
|
try!(hardbreak(&mut self.s))
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn space_if_not_bol(&mut self) -> IoResult<()> {
|
pub fn space_if_not_bol(&mut self) -> io::Result<()> {
|
||||||
if !self.is_bol() { try!(space(&mut self.s)); }
|
if !self.is_bol() { try!(space(&mut self.s)); }
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn break_offset_if_not_bol(&mut self, n: usize,
|
pub fn break_offset_if_not_bol(&mut self, n: usize,
|
||||||
off: isize) -> IoResult<()> {
|
off: isize) -> io::Result<()> {
|
||||||
if !self.is_bol() {
|
if !self.is_bol() {
|
||||||
break_offset(&mut self.s, n, off)
|
break_offset(&mut self.s, n, off)
|
||||||
} else {
|
} else {
|
||||||
@ -599,7 +599,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
// Synthesizes a comment that was not textually present in the original source
|
// Synthesizes a comment that was not textually present in the original source
|
||||||
// file.
|
// file.
|
||||||
pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
|
pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, "/*"));
|
try!(word(&mut self.s, "/*"));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(word(&mut self.s, &text[..]));
|
try!(word(&mut self.s, &text[..]));
|
||||||
@ -607,8 +607,8 @@ impl<'a> State<'a> {
|
|||||||
word(&mut self.s, "*/")
|
word(&mut self.s, "*/")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where
|
pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where
|
||||||
F: FnMut(&mut State, &T) -> IoResult<()>,
|
F: FnMut(&mut State, &T) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
try!(self.rbox(0, b));
|
try!(self.rbox(0, b));
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
@ -624,8 +624,8 @@ impl<'a> State<'a> {
|
|||||||
b: Breaks,
|
b: Breaks,
|
||||||
elts: &[T],
|
elts: &[T],
|
||||||
mut op: F,
|
mut op: F,
|
||||||
mut get_span: G) -> IoResult<()> where
|
mut get_span: G) -> io::Result<()> where
|
||||||
F: FnMut(&mut State, &T) -> IoResult<()>,
|
F: FnMut(&mut State, &T) -> io::Result<()>,
|
||||||
G: FnMut(&T) -> codemap::Span,
|
G: FnMut(&T) -> codemap::Span,
|
||||||
{
|
{
|
||||||
try!(self.rbox(0, b));
|
try!(self.rbox(0, b));
|
||||||
@ -646,12 +646,12 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn commasep_exprs(&mut self, b: Breaks,
|
pub fn commasep_exprs(&mut self, b: Breaks,
|
||||||
exprs: &[P<ast::Expr>]) -> IoResult<()> {
|
exprs: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
|
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||||
try!(self.print_inner_attributes(attrs));
|
try!(self.print_inner_attributes(attrs));
|
||||||
for item in &_mod.items {
|
for item in &_mod.items {
|
||||||
try!(self.print_item(&**item));
|
try!(self.print_item(&**item));
|
||||||
@ -660,7 +660,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||||
try!(self.print_inner_attributes(attrs));
|
try!(self.print_inner_attributes(attrs));
|
||||||
for item in &nmod.items {
|
for item in &nmod.items {
|
||||||
try!(self.print_foreign_item(&**item));
|
try!(self.print_foreign_item(&**item));
|
||||||
@ -669,7 +669,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_opt_lifetime(&mut self,
|
pub fn print_opt_lifetime(&mut self,
|
||||||
lifetime: &Option<ast::Lifetime>) -> IoResult<()> {
|
lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
|
||||||
if let Some(l) = *lifetime {
|
if let Some(l) = *lifetime {
|
||||||
try!(self.print_lifetime(&l));
|
try!(self.print_lifetime(&l));
|
||||||
try!(self.nbsp());
|
try!(self.nbsp());
|
||||||
@ -677,7 +677,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
|
pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(ty.span.lo));
|
try!(self.maybe_print_comment(ty.span.lo));
|
||||||
try!(self.ibox(0));
|
try!(self.ibox(0));
|
||||||
match ty.node {
|
match ty.node {
|
||||||
@ -762,7 +762,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_foreign_item(&mut self,
|
pub fn print_foreign_item(&mut self,
|
||||||
item: &ast::ForeignItem) -> IoResult<()> {
|
item: &ast::ForeignItem) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
try!(self.maybe_print_comment(item.span.lo));
|
try!(self.maybe_print_comment(item.span.lo));
|
||||||
try!(self.print_outer_attributes(&item.attrs));
|
try!(self.print_outer_attributes(&item.attrs));
|
||||||
@ -791,7 +791,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
try!(self.print_outer_attributes(&typedef.attrs));
|
try!(self.print_outer_attributes(&typedef.attrs));
|
||||||
try!(self.word_space("type"));
|
try!(self.word_space("type"));
|
||||||
@ -799,7 +799,7 @@ impl<'a> State<'a> {
|
|||||||
word(&mut self.s, ";")
|
word(&mut self.s, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> {
|
fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> {
|
||||||
try!(self.word_space("type"));
|
try!(self.word_space("type"));
|
||||||
try!(self.print_ident(typedef.ident));
|
try!(self.print_ident(typedef.ident));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
@ -809,7 +809,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pretty-print an item
|
/// Pretty-print an item
|
||||||
pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
|
pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
try!(self.maybe_print_comment(item.span.lo));
|
try!(self.maybe_print_comment(item.span.lo));
|
||||||
try!(self.print_outer_attributes(&item.attrs));
|
try!(self.print_outer_attributes(&item.attrs));
|
||||||
@ -1032,11 +1032,11 @@ impl<'a> State<'a> {
|
|||||||
self.ann.post(self, NodeItem(item))
|
self.ann.post(self, NodeItem(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> {
|
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
|
||||||
self.print_path(&t.path, false, 0)
|
self.print_path(&t.path, false, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> {
|
fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
|
||||||
if !lifetimes.is_empty() {
|
if !lifetimes.is_empty() {
|
||||||
try!(word(&mut self.s, "for<"));
|
try!(word(&mut self.s, "for<"));
|
||||||
let mut comma = false;
|
let mut comma = false;
|
||||||
@ -1052,7 +1052,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
|
||||||
try!(self.print_formal_lifetime_list(&t.bound_lifetimes));
|
try!(self.print_formal_lifetime_list(&t.bound_lifetimes));
|
||||||
self.print_trait_ref(&t.trait_ref)
|
self.print_trait_ref(&t.trait_ref)
|
||||||
}
|
}
|
||||||
@ -1060,7 +1060,7 @@ impl<'a> State<'a> {
|
|||||||
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
|
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
|
||||||
generics: &ast::Generics, ident: ast::Ident,
|
generics: &ast::Generics, ident: ast::Ident,
|
||||||
span: codemap::Span,
|
span: codemap::Span,
|
||||||
visibility: ast::Visibility) -> IoResult<()> {
|
visibility: ast::Visibility) -> io::Result<()> {
|
||||||
try!(self.head(&visibility_qualified(visibility, "enum")));
|
try!(self.head(&visibility_qualified(visibility, "enum")));
|
||||||
try!(self.print_ident(ident));
|
try!(self.print_ident(ident));
|
||||||
try!(self.print_generics(generics));
|
try!(self.print_generics(generics));
|
||||||
@ -1071,7 +1071,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_variants(&mut self,
|
pub fn print_variants(&mut self,
|
||||||
variants: &[P<ast::Variant>],
|
variants: &[P<ast::Variant>],
|
||||||
span: codemap::Span) -> IoResult<()> {
|
span: codemap::Span) -> io::Result<()> {
|
||||||
try!(self.bopen());
|
try!(self.bopen());
|
||||||
for v in variants {
|
for v in variants {
|
||||||
try!(self.space_if_not_bol());
|
try!(self.space_if_not_bol());
|
||||||
@ -1086,7 +1086,7 @@ impl<'a> State<'a> {
|
|||||||
self.bclose(span)
|
self.bclose(span)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> {
|
pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> {
|
||||||
match vis {
|
match vis {
|
||||||
ast::Public => self.word_nbsp("pub"),
|
ast::Public => self.word_nbsp("pub"),
|
||||||
ast::Inherited => Ok(())
|
ast::Inherited => Ok(())
|
||||||
@ -1097,7 +1097,7 @@ impl<'a> State<'a> {
|
|||||||
struct_def: &ast::StructDef,
|
struct_def: &ast::StructDef,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
ident: ast::Ident,
|
ident: ast::Ident,
|
||||||
span: codemap::Span) -> IoResult<()> {
|
span: codemap::Span) -> io::Result<()> {
|
||||||
try!(self.print_ident(ident));
|
try!(self.print_ident(ident));
|
||||||
try!(self.print_generics(generics));
|
try!(self.print_generics(generics));
|
||||||
if ast_util::struct_def_is_tuple_like(struct_def) {
|
if ast_util::struct_def_is_tuple_like(struct_def) {
|
||||||
@ -1155,7 +1155,7 @@ impl<'a> State<'a> {
|
|||||||
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
/// appropriate macro, transcribe back into the grammar we just parsed from,
|
||||||
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
/// and then pretty-print the resulting AST nodes (so, e.g., we print
|
||||||
/// expression arguments as expressions). It can be done! I think.
|
/// expression arguments as expressions). It can be done! I think.
|
||||||
pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
|
pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> {
|
||||||
match *tt {
|
match *tt {
|
||||||
ast::TtToken(_, ref tk) => {
|
ast::TtToken(_, ref tk) => {
|
||||||
try!(word(&mut self.s, &token_to_string(tk)));
|
try!(word(&mut self.s, &token_to_string(tk)));
|
||||||
@ -1193,7 +1193,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> {
|
pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> {
|
||||||
try!(self.ibox(0));
|
try!(self.ibox(0));
|
||||||
let mut suppress_space = false;
|
let mut suppress_space = false;
|
||||||
for (i, tt) in tts.iter().enumerate() {
|
for (i, tt) in tts.iter().enumerate() {
|
||||||
@ -1213,7 +1213,7 @@ impl<'a> State<'a> {
|
|||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
|
pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
|
||||||
try!(self.print_visibility(v.node.vis));
|
try!(self.print_visibility(v.node.vis));
|
||||||
match v.node.kind {
|
match v.node.kind {
|
||||||
ast::TupleVariantKind(ref args) => {
|
ast::TupleVariantKind(ref args) => {
|
||||||
@ -1242,7 +1242,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
|
pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
try!(self.maybe_print_comment(m.span.lo));
|
try!(self.maybe_print_comment(m.span.lo));
|
||||||
try!(self.print_outer_attributes(&m.attrs));
|
try!(self.print_outer_attributes(&m.attrs));
|
||||||
@ -1256,7 +1256,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_trait_method(&mut self,
|
pub fn print_trait_method(&mut self,
|
||||||
m: &ast::TraitItem) -> IoResult<()> {
|
m: &ast::TraitItem) -> io::Result<()> {
|
||||||
match *m {
|
match *m {
|
||||||
RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
|
RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
|
||||||
ProvidedMethod(ref m) => self.print_method(&**m),
|
ProvidedMethod(ref m) => self.print_method(&**m),
|
||||||
@ -1264,14 +1264,14 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
|
pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
|
||||||
match *ii {
|
match *ii {
|
||||||
MethodImplItem(ref m) => self.print_method(&**m),
|
MethodImplItem(ref m) => self.print_method(&**m),
|
||||||
TypeImplItem(ref td) => self.print_typedef(&**td),
|
TypeImplItem(ref td) => self.print_typedef(&**td),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
|
pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
try!(self.maybe_print_comment(meth.span.lo));
|
try!(self.maybe_print_comment(meth.span.lo));
|
||||||
try!(self.print_outer_attributes(&meth.attrs));
|
try!(self.print_outer_attributes(&meth.attrs));
|
||||||
@ -1310,7 +1310,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_outer_attributes(&mut self,
|
pub fn print_outer_attributes(&mut self,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
match attr.node.style {
|
match attr.node.style {
|
||||||
@ -1328,7 +1328,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_inner_attributes(&mut self,
|
pub fn print_inner_attributes(&mut self,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
match attr.node.style {
|
match attr.node.style {
|
||||||
@ -1345,7 +1345,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> {
|
pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
|
||||||
try!(self.hardbreak_if_not_bol());
|
try!(self.hardbreak_if_not_bol());
|
||||||
try!(self.maybe_print_comment(attr.span.lo));
|
try!(self.maybe_print_comment(attr.span.lo));
|
||||||
if attr.node.is_sugared_doc {
|
if attr.node.is_sugared_doc {
|
||||||
@ -1361,7 +1361,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> {
|
pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(st.span.lo));
|
try!(self.maybe_print_comment(st.span.lo));
|
||||||
match st.node {
|
match st.node {
|
||||||
ast::StmtDecl(ref decl, _) => {
|
ast::StmtDecl(ref decl, _) => {
|
||||||
@ -1395,22 +1395,22 @@ impl<'a> State<'a> {
|
|||||||
self.maybe_print_trailing_comment(st.span, None)
|
self.maybe_print_trailing_comment(st.span, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> {
|
pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> {
|
||||||
self.print_block_with_attrs(blk, &[])
|
self.print_block_with_attrs(blk, &[])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> {
|
pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> {
|
||||||
self.print_block_unclosed_indent(blk, indent_unit)
|
self.print_block_unclosed_indent(blk, indent_unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
|
pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
|
||||||
indented: usize) -> IoResult<()> {
|
indented: usize) -> io::Result<()> {
|
||||||
self.print_block_maybe_unclosed(blk, indented, &[], false)
|
self.print_block_maybe_unclosed(blk, indented, &[], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_block_with_attrs(&mut self,
|
pub fn print_block_with_attrs(&mut self,
|
||||||
blk: &ast::Block,
|
blk: &ast::Block,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> io::Result<()> {
|
||||||
self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
|
self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,7 +1418,7 @@ impl<'a> State<'a> {
|
|||||||
blk: &ast::Block,
|
blk: &ast::Block,
|
||||||
indented: usize,
|
indented: usize,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
close_box: bool) -> IoResult<()> {
|
close_box: bool) -> io::Result<()> {
|
||||||
match blk.rules {
|
match blk.rules {
|
||||||
ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
|
ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
|
||||||
ast::DefaultBlock => ()
|
ast::DefaultBlock => ()
|
||||||
@ -1444,7 +1444,7 @@ impl<'a> State<'a> {
|
|||||||
self.ann.post(self, NodeBlock(blk))
|
self.ann.post(self, NodeBlock(blk))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
|
fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
|
||||||
match els {
|
match els {
|
||||||
Some(_else) => {
|
Some(_else) => {
|
||||||
match _else.node {
|
match _else.node {
|
||||||
@ -1489,7 +1489,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
|
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
|
||||||
elseopt: Option<&ast::Expr>) -> IoResult<()> {
|
elseopt: Option<&ast::Expr>) -> io::Result<()> {
|
||||||
try!(self.head("if"));
|
try!(self.head("if"));
|
||||||
try!(self.print_expr(test));
|
try!(self.print_expr(test));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
@ -1498,7 +1498,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
|
pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
|
||||||
elseopt: Option<&ast::Expr>) -> IoResult<()> {
|
elseopt: Option<&ast::Expr>) -> io::Result<()> {
|
||||||
try!(self.head("if let"));
|
try!(self.head("if let"));
|
||||||
try!(self.print_pat(pat));
|
try!(self.print_pat(pat));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
@ -1510,7 +1510,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
|
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
match m.node {
|
match m.node {
|
||||||
// I think it's reasonable to hide the ctxt here:
|
// I think it's reasonable to hide the ctxt here:
|
||||||
ast::MacInvocTT(ref pth, ref tts, _) => {
|
ast::MacInvocTT(ref pth, ref tts, _) => {
|
||||||
@ -1532,13 +1532,13 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> {
|
fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
try!(self.commasep_exprs(Inconsistent, args));
|
try!(self.commasep_exprs(Inconsistent, args));
|
||||||
self.pclose()
|
self.pclose()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> {
|
pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> {
|
||||||
let needs_par = needs_parentheses(expr);
|
let needs_par = needs_parentheses(expr);
|
||||||
if needs_par {
|
if needs_par {
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
@ -1552,7 +1552,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn print_expr_box(&mut self,
|
fn print_expr_box(&mut self,
|
||||||
place: &Option<P<ast::Expr>>,
|
place: &Option<P<ast::Expr>>,
|
||||||
expr: &ast::Expr) -> IoResult<()> {
|
expr: &ast::Expr) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, "box"));
|
try!(word(&mut self.s, "box"));
|
||||||
try!(word(&mut self.s, "("));
|
try!(word(&mut self.s, "("));
|
||||||
try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
|
try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
|
||||||
@ -1560,7 +1560,7 @@ impl<'a> State<'a> {
|
|||||||
self.print_expr(expr)
|
self.print_expr(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
|
fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
try!(word(&mut self.s, "["));
|
try!(word(&mut self.s, "["));
|
||||||
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
|
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
|
||||||
@ -1570,7 +1570,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn print_expr_repeat(&mut self,
|
fn print_expr_repeat(&mut self,
|
||||||
element: &ast::Expr,
|
element: &ast::Expr,
|
||||||
count: &ast::Expr) -> IoResult<()> {
|
count: &ast::Expr) -> io::Result<()> {
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
try!(word(&mut self.s, "["));
|
try!(word(&mut self.s, "["));
|
||||||
try!(self.print_expr(element));
|
try!(self.print_expr(element));
|
||||||
@ -1583,7 +1583,7 @@ impl<'a> State<'a> {
|
|||||||
fn print_expr_struct(&mut self,
|
fn print_expr_struct(&mut self,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
fields: &[ast::Field],
|
fields: &[ast::Field],
|
||||||
wth: &Option<P<ast::Expr>>) -> IoResult<()> {
|
wth: &Option<P<ast::Expr>>) -> io::Result<()> {
|
||||||
try!(self.print_path(path, true, 0));
|
try!(self.print_path(path, true, 0));
|
||||||
if !(fields.is_empty() && wth.is_none()) {
|
if !(fields.is_empty() && wth.is_none()) {
|
||||||
try!(word(&mut self.s, "{"));
|
try!(word(&mut self.s, "{"));
|
||||||
@ -1616,7 +1616,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
|
fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
|
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
|
||||||
if exprs.len() == 1 {
|
if exprs.len() == 1 {
|
||||||
@ -1627,7 +1627,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn print_expr_call(&mut self,
|
fn print_expr_call(&mut self,
|
||||||
func: &ast::Expr,
|
func: &ast::Expr,
|
||||||
args: &[P<ast::Expr>]) -> IoResult<()> {
|
args: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
try!(self.print_expr_maybe_paren(func));
|
try!(self.print_expr_maybe_paren(func));
|
||||||
self.print_call_post(args)
|
self.print_call_post(args)
|
||||||
}
|
}
|
||||||
@ -1635,7 +1635,7 @@ impl<'a> State<'a> {
|
|||||||
fn print_expr_method_call(&mut self,
|
fn print_expr_method_call(&mut self,
|
||||||
ident: ast::SpannedIdent,
|
ident: ast::SpannedIdent,
|
||||||
tys: &[P<ast::Ty>],
|
tys: &[P<ast::Ty>],
|
||||||
args: &[P<ast::Expr>]) -> IoResult<()> {
|
args: &[P<ast::Expr>]) -> io::Result<()> {
|
||||||
let base_args = &args[1..];
|
let base_args = &args[1..];
|
||||||
try!(self.print_expr(&*args[0]));
|
try!(self.print_expr(&*args[0]));
|
||||||
try!(word(&mut self.s, "."));
|
try!(word(&mut self.s, "."));
|
||||||
@ -1652,7 +1652,7 @@ impl<'a> State<'a> {
|
|||||||
fn print_expr_binary(&mut self,
|
fn print_expr_binary(&mut self,
|
||||||
op: ast::BinOp,
|
op: ast::BinOp,
|
||||||
lhs: &ast::Expr,
|
lhs: &ast::Expr,
|
||||||
rhs: &ast::Expr) -> IoResult<()> {
|
rhs: &ast::Expr) -> io::Result<()> {
|
||||||
try!(self.print_expr(lhs));
|
try!(self.print_expr(lhs));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space(ast_util::binop_to_string(op.node)));
|
try!(self.word_space(ast_util::binop_to_string(op.node)));
|
||||||
@ -1661,20 +1661,20 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
fn print_expr_unary(&mut self,
|
fn print_expr_unary(&mut self,
|
||||||
op: ast::UnOp,
|
op: ast::UnOp,
|
||||||
expr: &ast::Expr) -> IoResult<()> {
|
expr: &ast::Expr) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, ast_util::unop_to_string(op)));
|
try!(word(&mut self.s, ast_util::unop_to_string(op)));
|
||||||
self.print_expr_maybe_paren(expr)
|
self.print_expr_maybe_paren(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_addr_of(&mut self,
|
fn print_expr_addr_of(&mut self,
|
||||||
mutability: ast::Mutability,
|
mutability: ast::Mutability,
|
||||||
expr: &ast::Expr) -> IoResult<()> {
|
expr: &ast::Expr) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, "&"));
|
try!(word(&mut self.s, "&"));
|
||||||
try!(self.print_mutability(mutability));
|
try!(self.print_mutability(mutability));
|
||||||
self.print_expr_maybe_paren(expr)
|
self.print_expr_maybe_paren(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
|
pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(expr.span.lo));
|
try!(self.maybe_print_comment(expr.span.lo));
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
try!(self.ann.pre(self, NodeExpr(expr)));
|
try!(self.ann.pre(self, NodeExpr(expr)));
|
||||||
@ -1958,7 +1958,7 @@ impl<'a> State<'a> {
|
|||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
|
pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> {
|
||||||
try!(self.print_pat(&*loc.pat));
|
try!(self.print_pat(&*loc.pat));
|
||||||
if let Some(ref ty) = loc.ty {
|
if let Some(ref ty) = loc.ty {
|
||||||
try!(self.word_space(":"));
|
try!(self.word_space(":"));
|
||||||
@ -1967,7 +1967,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
|
pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(decl.span.lo));
|
try!(self.maybe_print_comment(decl.span.lo));
|
||||||
match decl.node {
|
match decl.node {
|
||||||
ast::DeclLocal(ref loc) => {
|
ast::DeclLocal(ref loc) => {
|
||||||
@ -1989,7 +1989,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
|
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
|
||||||
if self.encode_idents_with_hygiene {
|
if self.encode_idents_with_hygiene {
|
||||||
let encoded = ident.encode_with_hygiene();
|
let encoded = ident.encode_with_hygiene();
|
||||||
try!(word(&mut self.s, &encoded[..]))
|
try!(word(&mut self.s, &encoded[..]))
|
||||||
@ -1999,17 +1999,17 @@ impl<'a> State<'a> {
|
|||||||
self.ann.post(self, NodeIdent(&ident))
|
self.ann.post(self, NodeIdent(&ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_usize(&mut self, i: usize) -> IoResult<()> {
|
pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
|
||||||
word(&mut self.s, &i.to_string())
|
word(&mut self.s, &i.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
|
pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, &token::get_name(name)));
|
try!(word(&mut self.s, &token::get_name(name)));
|
||||||
self.ann.post(self, NodeName(&name))
|
self.ann.post(self, NodeName(&name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_for_decl(&mut self, loc: &ast::Local,
|
pub fn print_for_decl(&mut self, loc: &ast::Local,
|
||||||
coll: &ast::Expr) -> IoResult<()> {
|
coll: &ast::Expr) -> io::Result<()> {
|
||||||
try!(self.print_local_decl(loc));
|
try!(self.print_local_decl(loc));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space("in"));
|
try!(self.word_space("in"));
|
||||||
@ -2020,7 +2020,7 @@ impl<'a> State<'a> {
|
|||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
colons_before_params: bool,
|
colons_before_params: bool,
|
||||||
depth: usize)
|
depth: usize)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
try!(self.maybe_print_comment(path.span.lo));
|
try!(self.maybe_print_comment(path.span.lo));
|
||||||
|
|
||||||
@ -2044,7 +2044,7 @@ impl<'a> State<'a> {
|
|||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
qself: &ast::QSelf,
|
qself: &ast::QSelf,
|
||||||
colons_before_params: bool)
|
colons_before_params: bool)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
try!(word(&mut self.s, "<"));
|
try!(word(&mut self.s, "<"));
|
||||||
try!(self.print_type(&qself.ty));
|
try!(self.print_type(&qself.ty));
|
||||||
@ -2064,7 +2064,7 @@ impl<'a> State<'a> {
|
|||||||
fn print_path_parameters(&mut self,
|
fn print_path_parameters(&mut self,
|
||||||
parameters: &ast::PathParameters,
|
parameters: &ast::PathParameters,
|
||||||
colons_before_params: bool)
|
colons_before_params: bool)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
if parameters.is_empty() {
|
if parameters.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -2134,7 +2134,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
|
pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(pat.span.lo));
|
try!(self.maybe_print_comment(pat.span.lo));
|
||||||
try!(self.ann.pre(self, NodePat(pat)));
|
try!(self.ann.pre(self, NodePat(pat)));
|
||||||
/* Pat isn't normalized, but the beauty of it
|
/* Pat isn't normalized, but the beauty of it
|
||||||
@ -2253,7 +2253,7 @@ impl<'a> State<'a> {
|
|||||||
self.ann.post(self, NodePat(pat))
|
self.ann.post(self, NodePat(pat))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
|
fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
|
||||||
// I have no idea why this check is necessary, but here it
|
// I have no idea why this check is necessary, but here it
|
||||||
// is :(
|
// is :(
|
||||||
if arm.attrs.is_empty() {
|
if arm.attrs.is_empty() {
|
||||||
@ -2302,7 +2302,7 @@ impl<'a> State<'a> {
|
|||||||
// Returns whether it printed anything
|
// Returns whether it printed anything
|
||||||
fn print_explicit_self(&mut self,
|
fn print_explicit_self(&mut self,
|
||||||
explicit_self: &ast::ExplicitSelf_,
|
explicit_self: &ast::ExplicitSelf_,
|
||||||
mutbl: ast::Mutability) -> IoResult<bool> {
|
mutbl: ast::Mutability) -> io::Result<bool> {
|
||||||
try!(self.print_mutability(mutbl));
|
try!(self.print_mutability(mutbl));
|
||||||
match *explicit_self {
|
match *explicit_self {
|
||||||
ast::SelfStatic => { return Ok(false); }
|
ast::SelfStatic => { return Ok(false); }
|
||||||
@ -2331,7 +2331,7 @@ impl<'a> State<'a> {
|
|||||||
name: ast::Ident,
|
name: ast::Ident,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||||
vis: ast::Visibility) -> IoResult<()> {
|
vis: ast::Visibility) -> io::Result<()> {
|
||||||
try!(self.head(""));
|
try!(self.head(""));
|
||||||
try!(self.print_fn_header_info(unsafety, abi, vis));
|
try!(self.print_fn_header_info(unsafety, abi, vis));
|
||||||
try!(self.nbsp());
|
try!(self.nbsp());
|
||||||
@ -2343,7 +2343,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
|
pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
|
||||||
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
// It is unfortunate to duplicate the commasep logic, but we want the
|
// It is unfortunate to duplicate the commasep logic, but we want the
|
||||||
// self type and the args all in the same box.
|
// self type and the args all in the same box.
|
||||||
try!(self.rbox(0, Inconsistent));
|
try!(self.rbox(0, Inconsistent));
|
||||||
@ -2376,7 +2376,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
|
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
|
||||||
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
try!(self.popen());
|
try!(self.popen());
|
||||||
try!(self.print_fn_args(decl, opt_explicit_self));
|
try!(self.print_fn_args(decl, opt_explicit_self));
|
||||||
if decl.variadic {
|
if decl.variadic {
|
||||||
@ -2390,7 +2390,7 @@ impl<'a> State<'a> {
|
|||||||
pub fn print_fn_block_args(
|
pub fn print_fn_block_args(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &ast::FnDecl)
|
decl: &ast::FnDecl)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
try!(word(&mut self.s, "|"));
|
try!(word(&mut self.s, "|"));
|
||||||
try!(self.print_fn_args(decl, None));
|
try!(self.print_fn_args(decl, None));
|
||||||
try!(word(&mut self.s, "|"));
|
try!(word(&mut self.s, "|"));
|
||||||
@ -2415,7 +2415,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
|
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
match capture_clause {
|
match capture_clause {
|
||||||
ast::CaptureByValue => self.word_space("move"),
|
ast::CaptureByValue => self.word_space("move"),
|
||||||
ast::CaptureByRef => Ok(()),
|
ast::CaptureByRef => Ok(()),
|
||||||
@ -2425,7 +2425,7 @@ impl<'a> State<'a> {
|
|||||||
pub fn print_bounds(&mut self,
|
pub fn print_bounds(&mut self,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
bounds: &[ast::TyParamBound])
|
bounds: &[ast::TyParamBound])
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
if !bounds.is_empty() {
|
if !bounds.is_empty() {
|
||||||
try!(word(&mut self.s, prefix));
|
try!(word(&mut self.s, prefix));
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
@ -2458,14 +2458,14 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_lifetime(&mut self,
|
pub fn print_lifetime(&mut self,
|
||||||
lifetime: &ast::Lifetime)
|
lifetime: &ast::Lifetime)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
self.print_name(lifetime.name)
|
self.print_name(lifetime.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_lifetime_def(&mut self,
|
pub fn print_lifetime_def(&mut self,
|
||||||
lifetime: &ast::LifetimeDef)
|
lifetime: &ast::LifetimeDef)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
try!(self.print_lifetime(&lifetime.lifetime));
|
try!(self.print_lifetime(&lifetime.lifetime));
|
||||||
let mut sep = ":";
|
let mut sep = ":";
|
||||||
@ -2479,7 +2479,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_generics(&mut self,
|
pub fn print_generics(&mut self,
|
||||||
generics: &ast::Generics)
|
generics: &ast::Generics)
|
||||||
-> IoResult<()>
|
-> io::Result<()>
|
||||||
{
|
{
|
||||||
let total = generics.lifetimes.len() + generics.ty_params.len();
|
let total = generics.lifetimes.len() + generics.ty_params.len();
|
||||||
if total == 0 {
|
if total == 0 {
|
||||||
@ -2508,7 +2508,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
|
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
|
||||||
try!(self.print_ident(param.ident));
|
try!(self.print_ident(param.ident));
|
||||||
try!(self.print_bounds(":", ¶m.bounds));
|
try!(self.print_bounds(":", ¶m.bounds));
|
||||||
match param.default {
|
match param.default {
|
||||||
@ -2522,7 +2522,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_where_clause(&mut self, generics: &ast::Generics)
|
pub fn print_where_clause(&mut self, generics: &ast::Generics)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
if generics.where_clause.predicates.len() == 0 {
|
if generics.where_clause.predicates.len() == 0 {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
@ -2573,7 +2573,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
|
pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::MetaWord(ref name) => {
|
ast::MetaWord(ref name) => {
|
||||||
@ -2596,7 +2596,7 @@ impl<'a> State<'a> {
|
|||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
|
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
|
||||||
match vp.node {
|
match vp.node {
|
||||||
ast::ViewPathSimple(ident, ref path) => {
|
ast::ViewPathSimple(ident, ref path) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0));
|
||||||
@ -2640,19 +2640,19 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_mutability(&mut self,
|
pub fn print_mutability(&mut self,
|
||||||
mutbl: ast::Mutability) -> IoResult<()> {
|
mutbl: ast::Mutability) -> io::Result<()> {
|
||||||
match mutbl {
|
match mutbl {
|
||||||
ast::MutMutable => self.word_nbsp("mut"),
|
ast::MutMutable => self.word_nbsp("mut"),
|
||||||
ast::MutImmutable => Ok(()),
|
ast::MutImmutable => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> {
|
pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> {
|
||||||
try!(self.print_mutability(mt.mutbl));
|
try!(self.print_mutability(mt.mutbl));
|
||||||
self.print_type(&*mt.ty)
|
self.print_type(&*mt.ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
|
pub fn print_arg(&mut self, input: &ast::Arg) -> io::Result<()> {
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
match input.ty.node {
|
match input.ty.node {
|
||||||
ast::TyInfer => try!(self.print_pat(&*input.pat)),
|
ast::TyInfer => try!(self.print_pat(&*input.pat)),
|
||||||
@ -2675,7 +2675,7 @@ impl<'a> State<'a> {
|
|||||||
self.end()
|
self.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
|
pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> {
|
||||||
if let ast::DefaultReturn(..) = decl.output {
|
if let ast::DefaultReturn(..) = decl.output {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -2705,7 +2705,7 @@ impl<'a> State<'a> {
|
|||||||
id: Option<ast::Ident>,
|
id: Option<ast::Ident>,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
try!(self.ibox(indent_unit));
|
try!(self.ibox(indent_unit));
|
||||||
try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
|
try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
|
||||||
|
|
||||||
@ -2726,7 +2726,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
|
pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
|
||||||
next_pos: Option<BytePos>)
|
next_pos: Option<BytePos>)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
let cm = match self.cm {
|
let cm = match self.cm {
|
||||||
Some(cm) => cm,
|
Some(cm) => cm,
|
||||||
_ => return Ok(())
|
_ => return Ok(())
|
||||||
@ -2749,7 +2749,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_remaining_comments(&mut self) -> IoResult<()> {
|
pub fn print_remaining_comments(&mut self) -> io::Result<()> {
|
||||||
// If there aren't any remaining comments, then we need to manually
|
// If there aren't any remaining comments, then we need to manually
|
||||||
// make sure there is a line break at the end.
|
// make sure there is a line break at the end.
|
||||||
if self.next_comment().is_none() {
|
if self.next_comment().is_none() {
|
||||||
@ -2767,7 +2767,7 @@ impl<'a> State<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
|
pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
|
||||||
try!(self.maybe_print_comment(lit.span.lo));
|
try!(self.maybe_print_comment(lit.span.lo));
|
||||||
match self.next_lit(lit.span.lo) {
|
match self.next_lit(lit.span.lo) {
|
||||||
Some(ref ltrl) => {
|
Some(ref ltrl) => {
|
||||||
@ -2848,7 +2848,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> {
|
pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next_comment() {
|
match self.next_comment() {
|
||||||
Some(ref cmnt) => {
|
Some(ref cmnt) => {
|
||||||
@ -2864,7 +2864,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_comment(&mut self,
|
pub fn print_comment(&mut self,
|
||||||
cmnt: &comments::Comment) -> IoResult<()> {
|
cmnt: &comments::Comment) -> io::Result<()> {
|
||||||
match cmnt.style {
|
match cmnt.style {
|
||||||
comments::Mixed => {
|
comments::Mixed => {
|
||||||
assert_eq!(cmnt.lines.len(), 1);
|
assert_eq!(cmnt.lines.len(), 1);
|
||||||
@ -2915,7 +2915,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_string(&mut self, st: &str,
|
pub fn print_string(&mut self, st: &str,
|
||||||
style: ast::StrStyle) -> IoResult<()> {
|
style: ast::StrStyle) -> io::Result<()> {
|
||||||
let st = match style {
|
let st = match style {
|
||||||
ast::CookedStr => {
|
ast::CookedStr => {
|
||||||
(format!("\"{}\"", st.escape_default()))
|
(format!("\"{}\"", st.escape_default()))
|
||||||
@ -2943,7 +2943,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_opt_unsafety(&mut self,
|
pub fn print_opt_unsafety(&mut self,
|
||||||
opt_unsafety: Option<ast::Unsafety>) -> IoResult<()> {
|
opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> {
|
||||||
match opt_unsafety {
|
match opt_unsafety {
|
||||||
Some(unsafety) => self.print_unsafety(unsafety),
|
Some(unsafety) => self.print_unsafety(unsafety),
|
||||||
None => Ok(())
|
None => Ok(())
|
||||||
@ -2952,7 +2952,7 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
|
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
|
||||||
opt_abi: Option<abi::Abi>)
|
opt_abi: Option<abi::Abi>)
|
||||||
-> IoResult<()> {
|
-> io::Result<()> {
|
||||||
match opt_abi {
|
match opt_abi {
|
||||||
Some(abi::Rust) => Ok(()),
|
Some(abi::Rust) => Ok(()),
|
||||||
Some(abi) => {
|
Some(abi) => {
|
||||||
@ -2964,7 +2964,7 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_extern_opt_abi(&mut self,
|
pub fn print_extern_opt_abi(&mut self,
|
||||||
opt_abi: Option<abi::Abi>) -> IoResult<()> {
|
opt_abi: Option<abi::Abi>) -> io::Result<()> {
|
||||||
match opt_abi {
|
match opt_abi {
|
||||||
Some(abi) => {
|
Some(abi) => {
|
||||||
try!(self.word_nbsp("extern"));
|
try!(self.word_nbsp("extern"));
|
||||||
@ -2977,7 +2977,7 @@ impl<'a> State<'a> {
|
|||||||
pub fn print_fn_header_info(&mut self,
|
pub fn print_fn_header_info(&mut self,
|
||||||
opt_unsafety: Option<ast::Unsafety>,
|
opt_unsafety: Option<ast::Unsafety>,
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
vis: ast::Visibility) -> IoResult<()> {
|
vis: ast::Visibility) -> io::Result<()> {
|
||||||
try!(word(&mut self.s, &visibility_qualified(vis, "")));
|
try!(word(&mut self.s, &visibility_qualified(vis, "")));
|
||||||
try!(self.print_opt_unsafety(opt_unsafety));
|
try!(self.print_opt_unsafety(opt_unsafety));
|
||||||
|
|
||||||
@ -2989,7 +2989,7 @@ impl<'a> State<'a> {
|
|||||||
word(&mut self.s, "fn")
|
word(&mut self.s, "fn")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_unsafety(&mut self, s: ast::Unsafety) -> IoResult<()> {
|
pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
|
||||||
match s {
|
match s {
|
||||||
ast::Unsafety::Normal => Ok(()),
|
ast::Unsafety::Normal => Ok(()),
|
||||||
ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
|
ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
|
||||||
|
@ -52,14 +52,15 @@
|
|||||||
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(collections)]
|
#![feature(collections)]
|
||||||
|
#![feature(fs)]
|
||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
|
#![feature(io)]
|
||||||
#![feature(old_io)]
|
#![feature(old_io)]
|
||||||
#![feature(old_path)]
|
#![feature(path)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(unicode)]
|
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
#![feature(os)]
|
#![feature(unicode)]
|
||||||
#![cfg_attr(windows, feature(libc))]
|
#![cfg_attr(windows, feature(libc))]
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
//! ncurses-compatible compiled terminfo format parsing (term(5))
|
//! ncurses-compatible compiled terminfo format parsing (term(5))
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::old_io;
|
use std::io::prelude::*;
|
||||||
|
use std::io;
|
||||||
use super::super::TermInfo;
|
use super::super::TermInfo;
|
||||||
|
|
||||||
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
|
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
|
||||||
@ -158,7 +159,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb
|
|||||||
"box1"];
|
"box1"];
|
||||||
|
|
||||||
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
|
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
|
||||||
pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
pub fn parse(file: &mut Read, longnames: bool)
|
||||||
-> Result<Box<TermInfo>, String> {
|
-> Result<Box<TermInfo>, String> {
|
||||||
macro_rules! try { ($e:expr) => (
|
macro_rules! try { ($e:expr) => (
|
||||||
match $e {
|
match $e {
|
||||||
@ -182,17 +183,17 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check magic number
|
// Check magic number
|
||||||
let magic = try!(file.read_le_u16());
|
let magic = try!(read_le_u16(file));
|
||||||
if magic != 0x011A {
|
if magic != 0x011A {
|
||||||
return Err(format!("invalid magic number: expected {:x}, found {:x}",
|
return Err(format!("invalid magic number: expected {:x}, found {:x}",
|
||||||
0x011A as usize, magic as usize));
|
0x011A as usize, magic as usize));
|
||||||
}
|
}
|
||||||
|
|
||||||
let names_bytes = try!(file.read_le_i16()) as int;
|
let names_bytes = try!(read_le_u16(file)) as int;
|
||||||
let bools_bytes = try!(file.read_le_i16()) as int;
|
let bools_bytes = try!(read_le_u16(file)) as int;
|
||||||
let numbers_count = try!(file.read_le_i16()) as int;
|
let numbers_count = try!(read_le_u16(file)) as int;
|
||||||
let string_offsets_count = try!(file.read_le_i16()) as int;
|
let string_offsets_count = try!(read_le_u16(file)) as int;
|
||||||
let string_table_bytes = try!(file.read_le_i16()) as int;
|
let string_table_bytes = try!(read_le_u16(file)) as int;
|
||||||
|
|
||||||
assert!(names_bytes > 0);
|
assert!(names_bytes > 0);
|
||||||
|
|
||||||
@ -212,7 +213,7 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't read NUL
|
// don't read NUL
|
||||||
let bytes = try!(file.read_exact(names_bytes as uint - 1));
|
let bytes = try!(read_exact(file, names_bytes as uint - 1));
|
||||||
let names_str = match String::from_utf8(bytes) {
|
let names_str = match String::from_utf8(bytes) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return Err("input not utf-8".to_string()),
|
Err(_) => return Err("input not utf-8".to_string()),
|
||||||
@ -222,12 +223,12 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
try!(file.read_byte()); // consume NUL
|
try!(read_byte(file)); // consume NUL
|
||||||
|
|
||||||
let mut bools_map = HashMap::new();
|
let mut bools_map = HashMap::new();
|
||||||
if bools_bytes != 0 {
|
if bools_bytes != 0 {
|
||||||
for i in 0..bools_bytes {
|
for i in 0..bools_bytes {
|
||||||
let b = try!(file.read_byte());
|
let b = try!(read_byte(file));
|
||||||
if b == 1 {
|
if b == 1 {
|
||||||
bools_map.insert(bnames[i as uint].to_string(), true);
|
bools_map.insert(bnames[i as uint].to_string(), true);
|
||||||
}
|
}
|
||||||
@ -235,13 +236,13 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bools_bytes + names_bytes) % 2 == 1 {
|
if (bools_bytes + names_bytes) % 2 == 1 {
|
||||||
try!(file.read_byte()); // compensate for padding
|
try!(read_byte(file)); // compensate for padding
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut numbers_map = HashMap::new();
|
let mut numbers_map = HashMap::new();
|
||||||
if numbers_count != 0 {
|
if numbers_count != 0 {
|
||||||
for i in 0..numbers_count {
|
for i in 0..numbers_count {
|
||||||
let n = try!(file.read_le_u16());
|
let n = try!(read_le_u16(file));
|
||||||
if n != 0xFFFF {
|
if n != 0xFFFF {
|
||||||
numbers_map.insert(nnames[i as uint].to_string(), n);
|
numbers_map.insert(nnames[i as uint].to_string(), n);
|
||||||
}
|
}
|
||||||
@ -253,10 +254,10 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
if string_offsets_count != 0 {
|
if string_offsets_count != 0 {
|
||||||
let mut string_offsets = Vec::with_capacity(10);
|
let mut string_offsets = Vec::with_capacity(10);
|
||||||
for _ in 0..string_offsets_count {
|
for _ in 0..string_offsets_count {
|
||||||
string_offsets.push(try!(file.read_le_u16()));
|
string_offsets.push(try!(read_le_u16(file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let string_table = try!(file.read_exact(string_table_bytes as uint));
|
let string_table = try!(read_exact(file, string_table_bytes as usize));
|
||||||
|
|
||||||
if string_table.len() != string_table_bytes as uint {
|
if string_table.len() != string_table_bytes as uint {
|
||||||
return Err("error: hit EOF before end of string \
|
return Err("error: hit EOF before end of string \
|
||||||
@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_le_u16<R: Read + ?Sized>(r: &mut R) -> io::Result<u16> {
|
||||||
|
let mut b = [0; 2];
|
||||||
|
assert_eq!(try!(r.read(&mut b)), 2);
|
||||||
|
Ok((b[0] as u16) | ((b[1] as u16) << 8))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_byte<R: Read + ?Sized>(r: &mut R) -> io::Result<u8> {
|
||||||
|
let mut b = [0; 1];
|
||||||
|
assert_eq!(try!(r.read(&mut b)), 1);
|
||||||
|
Ok(b[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_exact<R: Read + ?Sized>(r: &mut R, sz: usize) -> io::Result<Vec<u8>> {
|
||||||
|
let mut v = Vec::with_capacity(sz);
|
||||||
|
try!(r.take(sz as u64).read_to_end(&mut v));
|
||||||
|
assert_eq!(v.len(), sz);
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a dummy TermInfo struct for msys terminals
|
/// Create a dummy TermInfo struct for msys terminals
|
||||||
pub fn msys_terminfo() -> Box<TermInfo> {
|
pub fn msys_terminfo() -> Box<TermInfo> {
|
||||||
let mut strings = HashMap::new();
|
let mut strings = HashMap::new();
|
||||||
|
@ -12,26 +12,27 @@
|
|||||||
//!
|
//!
|
||||||
//! Does not support hashed database, only filesystem!
|
//! Does not support hashed database, only filesystem!
|
||||||
|
|
||||||
use std::old_io::File;
|
|
||||||
use std::old_io::fs::PathExtensions;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// Return path to database entry for `term`
|
/// Return path to database entry for `term`
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
|
pub fn get_dbpath_for_term(term: &str) -> Option<Box<PathBuf>> {
|
||||||
if term.len() == 0 {
|
if term.len() == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let homedir = ::std::os::homedir();
|
let homedir = env::home_dir();
|
||||||
|
|
||||||
let mut dirs_to_search = Vec::new();
|
let mut dirs_to_search = Vec::new();
|
||||||
let first_char = term.char_at(0);
|
let first_char = term.char_at(0);
|
||||||
|
|
||||||
// Find search directory
|
// Find search directory
|
||||||
match env::var("TERMINFO") {
|
match env::var_os("TERMINFO") {
|
||||||
Ok(dir) => dirs_to_search.push(Path::new(dir)),
|
Some(dir) => dirs_to_search.push(PathBuf::new(&dir)),
|
||||||
Err(..) => {
|
None => {
|
||||||
if homedir.is_some() {
|
if homedir.is_some() {
|
||||||
// ncurses compatibility;
|
// ncurses compatibility;
|
||||||
dirs_to_search.push(homedir.unwrap().join(".terminfo"))
|
dirs_to_search.push(homedir.unwrap().join(".terminfo"))
|
||||||
@ -39,9 +40,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
|
|||||||
match env::var("TERMINFO_DIRS") {
|
match env::var("TERMINFO_DIRS") {
|
||||||
Ok(dirs) => for i in dirs.split(':') {
|
Ok(dirs) => for i in dirs.split(':') {
|
||||||
if i == "" {
|
if i == "" {
|
||||||
dirs_to_search.push(Path::new("/usr/share/terminfo"));
|
dirs_to_search.push(PathBuf::new("/usr/share/terminfo"));
|
||||||
} else {
|
} else {
|
||||||
dirs_to_search.push(Path::new(i));
|
dirs_to_search.push(PathBuf::new(i));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Found nothing in TERMINFO_DIRS, use the default paths:
|
// Found nothing in TERMINFO_DIRS, use the default paths:
|
||||||
@ -49,9 +50,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
|
|||||||
// ~/.terminfo, ncurses will search /etc/terminfo, then
|
// ~/.terminfo, ncurses will search /etc/terminfo, then
|
||||||
// /lib/terminfo, and eventually /usr/share/terminfo.
|
// /lib/terminfo, and eventually /usr/share/terminfo.
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
dirs_to_search.push(Path::new("/etc/terminfo"));
|
dirs_to_search.push(PathBuf::new("/etc/terminfo"));
|
||||||
dirs_to_search.push(Path::new("/lib/terminfo"));
|
dirs_to_search.push(PathBuf::new("/lib/terminfo"));
|
||||||
dirs_to_search.push(Path::new("/usr/share/terminfo"));
|
dirs_to_search.push(PathBuf::new("/usr/share/terminfo"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,13 +62,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
|
|||||||
for p in &dirs_to_search {
|
for p in &dirs_to_search {
|
||||||
if p.exists() {
|
if p.exists() {
|
||||||
let f = first_char.to_string();
|
let f = first_char.to_string();
|
||||||
let newp = p.join_many(&[&f[..], term]);
|
let newp = p.join(&f).join(term);
|
||||||
if newp.exists() {
|
if newp.exists() {
|
||||||
return Some(box newp);
|
return Some(box newp);
|
||||||
}
|
}
|
||||||
// on some installations the dir is named after the hex of the char (e.g. OS X)
|
// on some installations the dir is named after the hex of the char (e.g. OS X)
|
||||||
let f = format!("{:x}", first_char as uint);
|
let f = format!("{:x}", first_char as uint);
|
||||||
let newp = p.join_many(&[&f[..], term]);
|
let newp = p.join(&f).join(term);
|
||||||
if newp.exists() {
|
if newp.exists() {
|
||||||
return Some(box newp);
|
return Some(box newp);
|
||||||
}
|
}
|
||||||
@ -100,7 +101,7 @@ fn test_get_dbpath_for_term() {
|
|||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
fn x(t: &str) -> String {
|
fn x(t: &str) -> String {
|
||||||
let p = get_dbpath_for_term(t).expect("no terminfo entry found");
|
let p = get_dbpath_for_term(t).expect("no terminfo entry found");
|
||||||
p.as_str().unwrap().to_string()
|
p.to_str().unwrap().to_string()
|
||||||
};
|
};
|
||||||
assert!(x("screen") == "/usr/share/terminfo/s/screen");
|
assert!(x("screen") == "/usr/share/terminfo/s/screen");
|
||||||
assert!(get_dbpath_for_term("") == None);
|
assert!(get_dbpath_for_term("") == None);
|
||||||
|
@ -38,10 +38,12 @@
|
|||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
#![feature(int_uint)]
|
#![feature(int_uint)]
|
||||||
#![feature(old_io)]
|
#![feature(old_io)]
|
||||||
#![feature(old_path)]
|
#![feature(path)]
|
||||||
|
#![feature(fs)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(std_misc)]
|
#![feature(std_misc)]
|
||||||
|
#![feature(io)]
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
@ -65,13 +67,16 @@ use term::color::{Color, RED, YELLOW, GREEN, CYAN};
|
|||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::env;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::old_io::stdio::StdWriter;
|
use std::fs::File;
|
||||||
use std::old_io::{File, ChanReader, ChanWriter};
|
use std::io::{self, Write};
|
||||||
use std::old_io;
|
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::num::{Float, Int};
|
use std::num::{Float, Int};
|
||||||
use std::env;
|
use std::old_io::stdio::StdWriter;
|
||||||
|
use std::old_io::{ChanReader, ChanWriter};
|
||||||
|
use std::old_io;
|
||||||
|
use std::path::{PathBuf};
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thunk::{Thunk, Invoke};
|
use std::thunk::{Thunk, Invoke};
|
||||||
@ -287,7 +292,7 @@ pub struct TestOpts {
|
|||||||
pub run_ignored: bool,
|
pub run_ignored: bool,
|
||||||
pub run_tests: bool,
|
pub run_tests: bool,
|
||||||
pub run_benchmarks: bool,
|
pub run_benchmarks: bool,
|
||||||
pub logfile: Option<Path>,
|
pub logfile: Option<PathBuf>,
|
||||||
pub nocapture: bool,
|
pub nocapture: bool,
|
||||||
pub color: ColorConfig,
|
pub color: ColorConfig,
|
||||||
}
|
}
|
||||||
@ -376,7 +381,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
|
|||||||
let run_ignored = matches.opt_present("ignored");
|
let run_ignored = matches.opt_present("ignored");
|
||||||
|
|
||||||
let logfile = matches.opt_str("logfile");
|
let logfile = matches.opt_str("logfile");
|
||||||
let logfile = logfile.map(|s| Path::new(s));
|
let logfile = logfile.map(|s| PathBuf::new(&s));
|
||||||
|
|
||||||
let run_benchmarks = matches.opt_present("bench");
|
let run_benchmarks = matches.opt_present("bench");
|
||||||
let run_tests = ! run_benchmarks ||
|
let run_tests = ! run_benchmarks ||
|
||||||
@ -446,11 +451,19 @@ struct ConsoleTestState<T> {
|
|||||||
max_name_len: uint, // number of columns to fill when aligning names
|
max_name_len: uint, // number of columns to fill when aligning names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new2old(new: io::Error) -> old_io::IoError {
|
||||||
|
old_io::IoError {
|
||||||
|
kind: old_io::OtherIoError,
|
||||||
|
desc: "other error",
|
||||||
|
detail: Some(new.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Writer> ConsoleTestState<T> {
|
impl<T: Writer> ConsoleTestState<T> {
|
||||||
pub fn new(opts: &TestOpts,
|
pub fn new(opts: &TestOpts,
|
||||||
_: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> {
|
_: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> {
|
||||||
let log_out = match opts.logfile {
|
let log_out = match opts.logfile {
|
||||||
Some(ref path) => Some(try!(File::create(path))),
|
Some(ref path) => Some(try!(File::create(path).map_err(new2old))),
|
||||||
None => None
|
None => None
|
||||||
};
|
};
|
||||||
let out = match term::stdout() {
|
let out = match term::stdout() {
|
||||||
@ -560,7 +573,7 @@ impl<T: Writer> ConsoleTestState<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_log(&mut self, test: &TestDesc,
|
pub fn write_log(&mut self, test: &TestDesc,
|
||||||
result: &TestResult) -> old_io::IoResult<()> {
|
result: &TestResult) -> io::Result<()> {
|
||||||
match self.log_out {
|
match self.log_out {
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
Some(ref mut o) => {
|
Some(ref mut o) => {
|
||||||
@ -646,7 +659,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io:
|
|||||||
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
||||||
TeWait(ref test, padding) => st.write_test_start(test, padding),
|
TeWait(ref test, padding) => st.write_test_start(test, padding),
|
||||||
TeResult(test, result, stdout) => {
|
TeResult(test, result, stdout) => {
|
||||||
try!(st.write_log(&test, &result));
|
try!(st.write_log(&test, &result).map_err(new2old));
|
||||||
try!(st.write_result(&result));
|
try!(st.write_result(&result));
|
||||||
match result {
|
match result {
|
||||||
TrOk => st.passed += 1,
|
TrOk => st.passed += 1,
|
||||||
|
@ -10,14 +10,16 @@
|
|||||||
|
|
||||||
//! Basic data structures for representing a book.
|
//! Basic data structures for representing a book.
|
||||||
|
|
||||||
use std::old_io::BufferedReader;
|
use std::io::prelude::*;
|
||||||
|
use std::io::BufReader;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::iter::AdditiveIterator;
|
use std::iter::AdditiveIterator;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub struct BookItem {
|
pub struct BookItem {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub path: Path,
|
pub path: PathBuf,
|
||||||
pub path_to_root: Path,
|
pub path_to_root: PathBuf,
|
||||||
pub children: Vec<BookItem>,
|
pub children: Vec<BookItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +78,7 @@ impl Book {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a book by parsing a summary (markdown table of contents).
|
/// Construct a book by parsing a summary (markdown table of contents).
|
||||||
pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
|
pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>> {
|
||||||
fn collapse(stack: &mut Vec<BookItem>,
|
fn collapse(stack: &mut Vec<BookItem>,
|
||||||
top_items: &mut Vec<BookItem>,
|
top_items: &mut Vec<BookItem>,
|
||||||
to_level: usize) {
|
to_level: usize) {
|
||||||
@ -100,16 +102,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String
|
|||||||
// always include the introduction
|
// always include the introduction
|
||||||
top_items.push(BookItem {
|
top_items.push(BookItem {
|
||||||
title: "Introduction".to_string(),
|
title: "Introduction".to_string(),
|
||||||
path: Path::new("README.md"),
|
path: PathBuf::new("README.md"),
|
||||||
path_to_root: Path::new("."),
|
path_to_root: PathBuf::new("."),
|
||||||
children: vec!(),
|
children: vec!(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for line_result in BufferedReader::new(input).lines() {
|
for line_result in BufReader::new(input).lines() {
|
||||||
let line = match line_result {
|
let line = match line_result {
|
||||||
Ok(line) => line,
|
Ok(line) => line,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
errors.push(err.desc.to_string()); // FIXME: include detail
|
errors.push(err.to_string());
|
||||||
return Err(errors);
|
return Err(errors);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -125,16 +127,16 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String
|
|||||||
let title = line[start_bracket + 1..end_bracket].to_string();
|
let title = line[start_bracket + 1..end_bracket].to_string();
|
||||||
let indent = &line[..star_idx];
|
let indent = &line[..star_idx];
|
||||||
|
|
||||||
let path_from_root = match src.join(given_path).path_relative_from(src) {
|
let path_from_root = match src.join(given_path).relative_from(src) {
|
||||||
Some(p) => p,
|
Some(p) => p.to_path_buf(),
|
||||||
None => {
|
None => {
|
||||||
errors.push(format!("paths in SUMMARY.md must be relative, \
|
errors.push(format!("paths in SUMMARY.md must be relative, \
|
||||||
but path '{}' for section '{}' is not.",
|
but path '{}' for section '{}' is not.",
|
||||||
given_path, title));
|
given_path, title));
|
||||||
Path::new("")
|
PathBuf::new("")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let path_to_root = Path::new(iter::repeat("../")
|
let path_to_root = PathBuf::new(&iter::repeat("../")
|
||||||
.take(path_from_root.components().count() - 1)
|
.take(path_from_root.components().count() - 1)
|
||||||
.collect::<String>());
|
.collect::<String>());
|
||||||
let item = BookItem {
|
let item = BookItem {
|
||||||
|
@ -11,13 +11,14 @@
|
|||||||
//! Implementation of the `build` subcommand, used to compile a book.
|
//! Implementation of the `build` subcommand, used to compile a book.
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::os;
|
use std::fs::{self, File, TempDir};
|
||||||
use std::old_io;
|
use std::io::prelude::*;
|
||||||
use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult};
|
use std::io::{self, BufWriter};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use subcommand::Subcommand;
|
use subcommand::Subcommand;
|
||||||
use term::Term;
|
use term::Term;
|
||||||
use error::{Error, CliResult, CommandResult};
|
use error::{err, CliResult, CommandResult};
|
||||||
use book;
|
use book;
|
||||||
use book::{Book, BookItem};
|
use book::{Book, BookItem};
|
||||||
use css;
|
use css;
|
||||||
@ -29,17 +30,17 @@ struct Build;
|
|||||||
|
|
||||||
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
||||||
if name == "build" {
|
if name == "build" {
|
||||||
Some(box Build as Box<Subcommand>)
|
Some(Box::new(Build))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> {
|
fn write_toc(book: &Book, path_to_root: &Path, out: &mut Write) -> io::Result<()> {
|
||||||
fn walk_items(items: &[BookItem],
|
fn walk_items(items: &[BookItem],
|
||||||
section: &str,
|
section: &str,
|
||||||
path_to_root: &Path,
|
path_to_root: &Path,
|
||||||
out: &mut Writer) -> IoResult<()> {
|
out: &mut Write) -> io::Result<()> {
|
||||||
for (i, item) in items.iter().enumerate() {
|
for (i, item) in items.iter().enumerate() {
|
||||||
try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out));
|
try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out));
|
||||||
}
|
}
|
||||||
@ -48,9 +49,9 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()>
|
|||||||
fn walk_item(item: &BookItem,
|
fn walk_item(item: &BookItem,
|
||||||
section: &str,
|
section: &str,
|
||||||
path_to_root: &Path,
|
path_to_root: &Path,
|
||||||
out: &mut Writer) -> IoResult<()> {
|
out: &mut Write) -> io::Result<()> {
|
||||||
try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>",
|
try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>",
|
||||||
path_to_root.join(item.path.with_extension("html")).display(),
|
path_to_root.join(&item.path.with_extension("html")).display(),
|
||||||
section,
|
section,
|
||||||
item.title));
|
item.title));
|
||||||
if !item.children.is_empty() {
|
if !item.children.is_empty() {
|
||||||
@ -75,30 +76,35 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()>
|
|||||||
fn render(book: &Book, tgt: &Path) -> CliResult<()> {
|
fn render(book: &Book, tgt: &Path) -> CliResult<()> {
|
||||||
let tmp = try!(TempDir::new("rust-book"));
|
let tmp = try!(TempDir::new("rust-book"));
|
||||||
|
|
||||||
for (section, item) in book.iter() {
|
for (_section, item) in book.iter() {
|
||||||
println!("{} {}", section, item.title);
|
let out_path = match item.path.parent() {
|
||||||
|
Some(p) => tgt.join(p),
|
||||||
let out_path = tgt.join(item.path.dirname());
|
None => tgt.to_path_buf(),
|
||||||
|
};
|
||||||
|
|
||||||
let src;
|
let src;
|
||||||
if env::args().len() < 3 {
|
if env::args().len() < 3 {
|
||||||
src = os::getcwd().unwrap().clone();
|
src = env::current_dir().unwrap().clone();
|
||||||
} else {
|
} else {
|
||||||
src = Path::new(env::args().nth(2).unwrap().clone());
|
src = PathBuf::new(&env::args().nth(2).unwrap());
|
||||||
}
|
}
|
||||||
// preprocess the markdown, rerouting markdown references to html references
|
// preprocess the markdown, rerouting markdown references to html references
|
||||||
let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string());
|
let mut markdown_data = String::new();
|
||||||
let preprocessed_path = tmp.path().join(item.path.filename().unwrap());
|
try!(File::open(&src.join(&item.path)).and_then(|mut f| {
|
||||||
|
f.read_to_string(&mut markdown_data)
|
||||||
|
}));
|
||||||
|
let preprocessed_path = tmp.path().join(item.path.file_name().unwrap());
|
||||||
{
|
{
|
||||||
let urls = markdown_data.replace(".md)", ".html)");
|
let urls = markdown_data.replace(".md)", ".html)");
|
||||||
try!(File::create(&preprocessed_path)
|
try!(File::create(&preprocessed_path).and_then(|mut f| {
|
||||||
.write_str(&urls[..]));
|
f.write_all(urls.as_bytes())
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the prelude to a temporary HTML file for rustdoc inclusion
|
// write the prelude to a temporary HTML file for rustdoc inclusion
|
||||||
let prelude = tmp.path().join("prelude.html");
|
let prelude = tmp.path().join("prelude.html");
|
||||||
{
|
{
|
||||||
let mut toc = BufferedWriter::new(try!(File::create(&prelude)));
|
let mut toc = BufWriter::new(try!(File::create(&prelude)));
|
||||||
try!(writeln!(&mut toc, r#"<div id="nav">
|
try!(writeln!(&mut toc, r#"<div id="nav">
|
||||||
<button id="toggle-nav">
|
<button id="toggle-nav">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">Toggle navigation</span>
|
||||||
@ -115,12 +121,12 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
|
|||||||
// write the postlude to a temporary HTML file for rustdoc inclusion
|
// write the postlude to a temporary HTML file for rustdoc inclusion
|
||||||
let postlude = tmp.path().join("postlude.html");
|
let postlude = tmp.path().join("postlude.html");
|
||||||
{
|
{
|
||||||
let mut toc = BufferedWriter::new(try!(File::create(&postlude)));
|
let mut toc = BufWriter::new(try!(File::create(&postlude)));
|
||||||
try!(toc.write_str(javascript::JAVASCRIPT));
|
try!(toc.write_all(javascript::JAVASCRIPT.as_bytes()));
|
||||||
try!(writeln!(&mut toc, "</div></div>"));
|
try!(writeln!(&mut toc, "</div></div>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(fs::mkdir_recursive(&out_path, old_io::USER_DIR));
|
try!(fs::create_dir_all(&out_path));
|
||||||
|
|
||||||
let rustdoc_args: &[String] = &[
|
let rustdoc_args: &[String] = &[
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
@ -135,7 +141,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
|
|||||||
if output_result != 0 {
|
if output_result != 0 {
|
||||||
let message = format!("Could not execute `rustdoc` with {:?}: {}",
|
let message = format!("Could not execute `rustdoc` with {:?}: {}",
|
||||||
rustdoc_args, output_result);
|
rustdoc_args, output_result);
|
||||||
return Err(box message as Box<Error>);
|
return Err(err(&message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,28 +156,30 @@ impl Subcommand for Build {
|
|||||||
}
|
}
|
||||||
fn usage(&self) {}
|
fn usage(&self) {}
|
||||||
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
|
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
|
||||||
let cwd = os::getcwd().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
let src;
|
let src;
|
||||||
let tgt;
|
let tgt;
|
||||||
|
|
||||||
if env::args().len() < 3 {
|
if env::args().len() < 3 {
|
||||||
src = cwd.clone();
|
src = cwd.clone();
|
||||||
} else {
|
} else {
|
||||||
src = Path::new(env::args().nth(2).unwrap().clone());
|
src = PathBuf::new(&env::args().nth(2).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
if env::args().len() < 4 {
|
if env::args().len() < 4 {
|
||||||
tgt = cwd.join("_book");
|
tgt = cwd.join("_book");
|
||||||
} else {
|
} else {
|
||||||
tgt = Path::new(env::args().nth(3).unwrap().clone());
|
tgt = PathBuf::new(&env::args().nth(3).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(fs::mkdir(&tgt, old_io::USER_DIR));
|
try!(fs::create_dir(&tgt));
|
||||||
|
|
||||||
try!(File::create(&tgt.join("rust-book.css")).write_str(css::STYLE));
|
try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| {
|
||||||
|
f.write_all(css::STYLE.as_bytes())
|
||||||
|
}));
|
||||||
|
|
||||||
let summary = try!(File::open(&src.join("SUMMARY.md")));
|
let mut summary = try!(File::open(&src.join("SUMMARY.md")));
|
||||||
match book::parse_summary(summary, &src) {
|
match book::parse_summary(&mut summary, &src) {
|
||||||
Ok(book) => {
|
Ok(book) => {
|
||||||
// execute rustdoc on the whole book
|
// execute rustdoc on the whole book
|
||||||
render(&book, &tgt)
|
render(&book, &tgt)
|
||||||
@ -182,7 +190,7 @@ impl Subcommand for Build {
|
|||||||
term.err(&format!("error: {}", err)[..]);
|
term.err(&format!("error: {}", err)[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(box format!("{} errors occurred", n) as Box<Error>)
|
Err(err(&format!("{} errors occurred", n)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
//! Error handling utilities. WIP.
|
//! Error handling utilities. WIP.
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
|
|
||||||
use std::old_io::IoError;
|
|
||||||
|
|
||||||
pub type CliError = Box<Error + 'static>;
|
pub type CliError = Box<Error + 'static>;
|
||||||
pub type CliResult<T> = Result<T, CliError>;
|
pub type CliResult<T> = Result<T, CliError>;
|
||||||
@ -21,63 +19,17 @@ pub type CliResult<T> = Result<T, CliError>;
|
|||||||
pub type CommandError = Box<Error + 'static>;
|
pub type CommandError = Box<Error + 'static>;
|
||||||
pub type CommandResult<T> = Result<T, CommandError>;
|
pub type CommandResult<T> = Result<T, CommandError>;
|
||||||
|
|
||||||
pub trait Error {
|
pub fn err(s: &str) -> CliError {
|
||||||
fn description(&self) -> &str;
|
struct E(String);
|
||||||
|
|
||||||
fn detail(&self) -> Option<&str> { None }
|
impl Error for E {
|
||||||
fn cause(&self) -> Option<&Error> { None }
|
fn description(&self) -> &str { &self.0 }
|
||||||
}
|
|
||||||
|
|
||||||
pub trait FromError<E> {
|
|
||||||
fn from_err(err: E) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Box<Error + 'static> {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.description())
|
|
||||||
}
|
}
|
||||||
}
|
impl fmt::Display for E {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
impl<E: Error + 'static> FromError<E> for Box<Error + 'static> {
|
self.0.fmt(f)
|
||||||
fn from_err(err: E) -> Box<Error + 'static> {
|
}
|
||||||
box err as Box<Error>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box::new(E(s.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Error for &'a str {
|
|
||||||
fn description<'b>(&'b self) -> &'b str {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for String {
|
|
||||||
fn description<'a>(&'a self) -> &'a str {
|
|
||||||
&self[..]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Error for Box<Error + 'a> {
|
|
||||||
fn description(&self) -> &str { (**self).description() }
|
|
||||||
fn detail(&self) -> Option<&str> { (**self).detail() }
|
|
||||||
fn cause(&self) -> Option<&Error> { (**self).cause() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromError<()> for () {
|
|
||||||
fn from_err(_: ()) -> () { () }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromError<IoError> for IoError {
|
|
||||||
fn from_err(error: IoError) -> IoError { error }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for IoError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.desc
|
|
||||||
}
|
|
||||||
fn detail(&self) -> Option<&str> {
|
|
||||||
self.detail.as_ref().map(|s| &s[..])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//fn iter_map_err<T, U, E, I: Iterator<Result<T,E>>>(iter: I,
|
|
||||||
|
@ -19,7 +19,7 @@ struct Help;
|
|||||||
|
|
||||||
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
||||||
match name {
|
match name {
|
||||||
"help" | "--help" | "-h" | "-?" => Some(box Help as Box<Subcommand>),
|
"help" | "--help" | "-h" | "-?" => Some(Box::new(Help)),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,31 +8,24 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
#![deny(warnings)]
|
||||||
#![feature(collections)]
|
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
|
#![feature(exit_status)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(io)]
|
||||||
#![feature(old_io)]
|
#![feature(old_io)]
|
||||||
#![feature(env)]
|
#![feature(path)]
|
||||||
#![feature(os)]
|
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(rustdoc)]
|
#![feature(rustdoc)]
|
||||||
|
#![feature(tempdir)]
|
||||||
|
|
||||||
extern crate rustdoc;
|
extern crate rustdoc;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
use subcommand::Subcommand;
|
use subcommand::Subcommand;
|
||||||
use term::Term;
|
use term::Term;
|
||||||
|
|
||||||
macro_rules! try (
|
|
||||||
($expr:expr) => ({
|
|
||||||
use error;
|
|
||||||
match $expr {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => return Err(error::FromError::from_err(err))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
mod term;
|
mod term;
|
||||||
mod error;
|
mod error;
|
||||||
mod book;
|
mod book;
|
||||||
@ -56,15 +49,12 @@ fn main() {
|
|||||||
} else {
|
} else {
|
||||||
match subcommand::parse_name(&cmd[1][..]) {
|
match subcommand::parse_name(&cmd[1][..]) {
|
||||||
Some(mut subcmd) => {
|
Some(mut subcmd) => {
|
||||||
match subcmd.parse_args(cmd.tail()) {
|
match subcmd.parse_args(&cmd[..cmd.len()-1]) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
match subcmd.execute(&mut term) {
|
match subcmd.execute(&mut term) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
term.err(&format!("error: {}", err.description())[..]);
|
term.err(&format!("error: {}", err));
|
||||||
err.detail().map(|detail| {
|
|
||||||
term.err(&format!("detail: {}", detail)[..]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ struct Serve;
|
|||||||
|
|
||||||
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
||||||
if name == "serve" {
|
if name == "serve" {
|
||||||
Some(box Serve as Box<Subcommand>)
|
Some(Box::new(Serve))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ pub struct Term {
|
|||||||
impl Term {
|
impl Term {
|
||||||
pub fn new() -> Term {
|
pub fn new() -> Term {
|
||||||
Term {
|
Term {
|
||||||
err: box stdio::stderr() as Box<Writer>,
|
err: Box::new(stdio::stderr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,19 +11,19 @@
|
|||||||
//! Implementation of the `test` subcommand. Just a stub for now.
|
//! Implementation of the `test` subcommand. Just a stub for now.
|
||||||
|
|
||||||
use subcommand::Subcommand;
|
use subcommand::Subcommand;
|
||||||
use error::CliResult;
|
use error::{err, CliResult, CommandResult};
|
||||||
use error::CommandResult;
|
|
||||||
use error::Error;
|
|
||||||
use term::Term;
|
use term::Term;
|
||||||
use book;
|
use book;
|
||||||
use std::old_io::{Command, File};
|
|
||||||
use std::os;
|
use std::fs::File;
|
||||||
|
use std::env;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
struct Test;
|
struct Test;
|
||||||
|
|
||||||
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
|
||||||
if name == "test" {
|
if name == "test" {
|
||||||
Some(box Test as Box<Subcommand>)
|
Some(Box::new(Test))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -35,11 +35,11 @@ impl Subcommand for Test {
|
|||||||
}
|
}
|
||||||
fn usage(&self) {}
|
fn usage(&self) {}
|
||||||
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
|
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
|
||||||
let cwd = os::getcwd().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
let src = cwd.clone();
|
let src = cwd.clone();
|
||||||
|
|
||||||
let summary = File::open(&src.join("SUMMARY.md"));
|
let mut summary = try!(File::open(&src.join("SUMMARY.md")));
|
||||||
match book::parse_summary(summary, &src) {
|
match book::parse_summary(&mut summary, &src) {
|
||||||
Ok(book) => {
|
Ok(book) => {
|
||||||
for (_, item) in book.iter() {
|
for (_, item) in book.iter() {
|
||||||
let output_result = Command::new("rustdoc")
|
let output_result = Command::new("rustdoc")
|
||||||
@ -50,15 +50,15 @@ impl Subcommand for Test {
|
|||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
term.err(&format!("{}\n{}",
|
term.err(&format!("{}\n{}",
|
||||||
String::from_utf8_lossy(&output.output[..]),
|
String::from_utf8_lossy(&output.stdout),
|
||||||
String::from_utf8_lossy(&output.error[..]))[..]);
|
String::from_utf8_lossy(&output.stderr)));
|
||||||
return Err(box "Some tests failed." as Box<Error>);
|
return Err(err("some tests failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let message = format!("Could not execute `rustdoc`: {}", e);
|
let message = format!("could not execute `rustdoc`: {}", e);
|
||||||
return Err(box message as Box<Error>);
|
return Err(err(&message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ impl Subcommand for Test {
|
|||||||
for err in errors {
|
for err in errors {
|
||||||
term.err(&err[..]);
|
term.err(&err[..]);
|
||||||
}
|
}
|
||||||
return Err(box "There was an error." as Box<Error>);
|
return Err(err("there was an error"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(()) // lol
|
Ok(()) // lol
|
||||||
|
@ -9,6 +9,6 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// compile-flags: --extern std=
|
// compile-flags: --extern std=
|
||||||
// error-pattern: is not a file
|
// error-pattern: can't find crate for `std`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[path = "circular_modules_hello.rs"]
|
#[path = "circular_modules_hello.rs"]
|
||||||
mod circular_modules_hello; //~ERROR: circular modules
|
mod circular_modules_hello; //~ ERROR: circular modules
|
||||||
|
|
||||||
pub fn hi_str() -> String {
|
pub fn hi_str() -> String {
|
||||||
"Hi!".to_string()
|
"Hi!".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -8,15 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
// ignore-windows
|
||||||
// file at the top-level directory of this distribution and at
|
// ignore-freebsd
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#[path = "../compile-fail"]
|
#[path = "../compile-fail"]
|
||||||
mod foo; //~ ERROR: a directory
|
mod foo; //~ ERROR: a directory
|
||||||
|
@ -18,6 +18,8 @@ use rustc::session::config::{basic_options, build_configuration, Input, OutputTy
|
|||||||
use rustc_driver::driver::{compile_input, CompileController};
|
use rustc_driver::driver::{compile_input, CompileController};
|
||||||
use syntax::diagnostics::registry::Registry;
|
use syntax::diagnostics::registry::Registry;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let src = r#"
|
let src = r#"
|
||||||
fn main() {}
|
fn main() {}
|
||||||
@ -29,9 +31,9 @@ fn main() {
|
|||||||
panic!("expected rustc path");
|
panic!("expected rustc path");
|
||||||
}
|
}
|
||||||
|
|
||||||
let tmpdir = Path::new(&args[1]);
|
let tmpdir = PathBuf::new(&args[1]);
|
||||||
|
|
||||||
let mut sysroot = Path::new(&args[3]);
|
let mut sysroot = PathBuf::new(&args[3]);
|
||||||
sysroot.pop();
|
sysroot.pop();
|
||||||
sysroot.pop();
|
sysroot.pop();
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ fn main() {
|
|||||||
compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
|
compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_sess(sysroot: Path) -> Session {
|
fn basic_sess(sysroot: PathBuf) -> Session {
|
||||||
let mut opts = basic_options();
|
let mut opts = basic_options();
|
||||||
opts.output_types = vec![OutputTypeExe];
|
opts.output_types = vec![OutputTypeExe];
|
||||||
opts.maybe_sysroot = Some(sysroot);
|
opts.maybe_sysroot = Some(sysroot);
|
||||||
@ -51,7 +53,7 @@ fn basic_sess(sysroot: Path) -> Session {
|
|||||||
sess
|
sess
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile(code: String, output: Path, sysroot: Path) {
|
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
|
||||||
let sess = basic_sess(sysroot);
|
let sess = basic_sess(sysroot);
|
||||||
let cfg = build_configuration(&sess);
|
let cfg = build_configuration(&sess);
|
||||||
let control = CompileController::basic();
|
let control = CompileController::basic();
|
||||||
|
@ -25,6 +25,7 @@ use rustc::session::config::{self, Input};
|
|||||||
use rustc_driver::{driver, CompilerCalls, Compilation};
|
use rustc_driver::{driver, CompilerCalls, Compilation};
|
||||||
use syntax::diagnostics;
|
use syntax::diagnostics;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
struct TestCalls {
|
struct TestCalls {
|
||||||
count: u32
|
count: u32
|
||||||
@ -43,14 +44,15 @@ impl<'a> CompilerCalls<'a> for TestCalls {
|
|||||||
_: &getopts::Matches,
|
_: &getopts::Matches,
|
||||||
_: &Session,
|
_: &Session,
|
||||||
_: &Input,
|
_: &Input,
|
||||||
_: &Option<Path>,
|
_: &Option<PathBuf>,
|
||||||
_: &Option<Path>)
|
_: &Option<PathBuf>)
|
||||||
-> Compilation {
|
-> Compilation {
|
||||||
self.count *= 3;
|
self.count *= 3;
|
||||||
Compilation::Stop
|
Compilation::Stop
|
||||||
}
|
}
|
||||||
|
|
||||||
fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
|
fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
|
||||||
|
-> (Input, Option<PathBuf>) {
|
||||||
self.count *= 5;
|
self.count *= 5;
|
||||||
(input, input_path)
|
(input, input_path)
|
||||||
}
|
}
|
||||||
@ -58,10 +60,10 @@ impl<'a> CompilerCalls<'a> for TestCalls {
|
|||||||
fn no_input(&mut self,
|
fn no_input(&mut self,
|
||||||
_: &getopts::Matches,
|
_: &getopts::Matches,
|
||||||
_: &config::Options,
|
_: &config::Options,
|
||||||
_: &Option<Path>,
|
_: &Option<PathBuf>,
|
||||||
_: &Option<Path>,
|
_: &Option<PathBuf>,
|
||||||
_: &diagnostics::registry::Registry)
|
_: &diagnostics::registry::Registry)
|
||||||
-> Option<(Input, Option<Path>)> {
|
-> Option<(Input, Option<PathBuf>)> {
|
||||||
panic!("This shouldn't happen");
|
panic!("This shouldn't happen");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user