auto merge of #14233 : pcwalton/rust/detildestr-morelibs, r=alexcrichton

r? @alexcrichton
This commit is contained in:
bors
2014-05-16 13:11:23 -07:00
39 changed files with 1347 additions and 1002 deletions
+11 -11
View File
@@ -56,10 +56,10 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[deriving(Clone)]
pub struct Config {
// The library paths required for running the compiler
pub compile_lib_path: ~str,
pub compile_lib_path: StrBuf,
// The library paths required for running compiled programs
pub run_lib_path: ~str,
pub run_lib_path: StrBuf,
// The rustc executable
pub rustc_path: Path,
@@ -80,7 +80,7 @@ pub struct Config {
pub aux_base: Path,
// The name of the stage being built (stage1, etc)
pub stage_id: ~str,
pub stage_id: StrBuf,
// The test mode, compile-fail, run-fail, run-pass
pub mode: Mode,
@@ -110,37 +110,37 @@ pub struct Config {
// A command line to prefix program execution with,
// for running under valgrind
pub runtool: Option<~str>,
pub runtool: Option<StrBuf>,
// Flags to pass to the compiler when building for the host
pub host_rustcflags: Option<~str>,
pub host_rustcflags: Option<StrBuf>,
// Flags to pass to the compiler when building for the target
pub target_rustcflags: Option<~str>,
pub target_rustcflags: Option<StrBuf>,
// Run tests using the JIT
pub jit: bool,
// Target system to be tested
pub target: ~str,
pub target: StrBuf,
// Host triple for the compiler being invoked
pub host: ~str,
pub host: StrBuf,
// Path to the android tools
pub android_cross_path: Path,
// Extra parameter to run adb on arm-linux-androideabi
pub adb_path: ~str,
pub adb_path: StrBuf,
// Extra parameter to run test sute on arm-linux-androideabi
pub adb_test_dir: ~str,
pub adb_test_dir: StrBuf,
// status whether android device available or not
pub adb_device_status: bool,
// the path containing LLDB's Python module
pub lldb_python_dir: Option<~str>,
pub lldb_python_dir: Option<StrBuf>,
// Explain what's going on
pub verbose: bool
+85 -58
View File
@@ -48,12 +48,14 @@ fn start(argc: int, argv: **u8) -> int {
pub fn main() {
let args = os::args();
let config = parse_config(args.move_iter().collect());
let config = parse_config(args.move_iter()
.map(|x| x.to_strbuf())
.collect());
log_config(&config);
run_tests(&config);
}
pub fn parse_config(args: Vec<~str> ) -> Config {
pub fn parse_config(args: Vec<StrBuf> ) -> Config {
let groups : Vec<getopts::OptGroup> =
vec!(reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"),
@@ -91,7 +93,7 @@ pub fn parse_config(args: Vec<~str> ) -> Config {
assert!(!args.is_empty());
let argv0 = (*args.get(0)).clone();
let args_ = args.tail();
if *args.get(1) == "-h".to_owned() || *args.get(1) == "--help".to_owned() {
if args.get(1).as_slice() == "-h" || args.get(1).as_slice() == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", getopts::usage(message, groups.as_slice()));
println!("");
@@ -99,7 +101,7 @@ pub fn parse_config(args: Vec<~str> ) -> Config {
}
let matches =
&match getopts::getopts(args_, groups.as_slice()) {
&match getopts::getopts(args_.as_slice(), groups.as_slice()) {
Ok(m) => m,
Err(f) => fail!("{}", f.to_err_msg())
};
@@ -129,16 +131,20 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
};
Config {
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
compile_lib_path: matches.opt_str("compile-lib-path")
.unwrap()
.to_strbuf(),
run_lib_path: matches.opt_str("run-lib-path").unwrap().to_strbuf(),
rustc_path: opt_path(matches, "rustc-path"),
clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)),
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)),
src_base: opt_path(matches, "src-base"),
build_base: opt_path(matches, "build-base"),
aux_base: opt_path(matches, "aux-base"),
stage_id: matches.opt_str("stage-id").unwrap(),
mode: FromStr::from_str(matches.opt_str("mode").unwrap()).expect("invalid mode"),
stage_id: matches.opt_str("stage-id").unwrap().to_strbuf(),
mode: FromStr::from_str(matches.opt_str("mode")
.unwrap()
.as_slice()).expect("invalid mode"),
run_ignored: matches.opt_present("ignored"),
filter: filter,
logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
@@ -146,22 +152,32 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
ratchet_metrics:
matches.opt_str("ratchet-metrics").map(|s| Path::new(s)),
ratchet_noise_percent:
matches.opt_str("ratchet-noise-percent").and_then(|s| from_str::<f64>(s)),
runtool: matches.opt_str("runtool"),
host_rustcflags: matches.opt_str("host-rustcflags"),
target_rustcflags: matches.opt_str("target-rustcflags"),
matches.opt_str("ratchet-noise-percent")
.and_then(|s| from_str::<f64>(s.as_slice())),
runtool: matches.opt_str("runtool").map(|x| x.to_strbuf()),
host_rustcflags: matches.opt_str("host-rustcflags")
.map(|x| x.to_strbuf()),
target_rustcflags: matches.opt_str("target-rustcflags")
.map(|x| x.to_strbuf()),
jit: matches.opt_present("jit"),
target: opt_str2(matches.opt_str("target")).to_str(),
host: opt_str2(matches.opt_str("host")).to_str(),
target: opt_str2(matches.opt_str("target").map(|x| x.to_strbuf())),
host: opt_str2(matches.opt_str("host").map(|x| x.to_strbuf())),
android_cross_path: opt_path(matches, "android-cross-path"),
adb_path: opt_str2(matches.opt_str("adb-path")).to_str(),
adb_test_dir:
opt_str2(matches.opt_str("adb-test-dir")).to_str(),
adb_path: opt_str2(matches.opt_str("adb-path")
.map(|x| x.to_strbuf())),
adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")
.map(|x| x.to_strbuf())),
adb_device_status:
"arm-linux-androideabi" == opt_str2(matches.opt_str("target")) &&
"(none)" != opt_str2(matches.opt_str("adb-test-dir")) &&
!opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
lldb_python_dir: matches.opt_str("lldb-python-dir"),
"arm-linux-androideabi" ==
opt_str2(matches.opt_str("target")
.map(|x| x.to_strbuf())).as_slice() &&
"(none)" !=
opt_str2(matches.opt_str("adb-test-dir")
.map(|x| x.to_strbuf())).as_slice() &&
!opt_str2(matches.opt_str("adb-test-dir")
.map(|x| x.to_strbuf())).is_empty(),
lldb_python_dir: matches.opt_str("lldb-python-dir")
.map(|x| x.to_strbuf()),
test_shard: test::opt_shard(matches.opt_str("test-shard")
.map(|x| x.to_strbuf())),
verbose: matches.opt_present("verbose")
@@ -170,50 +186,59 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
pub fn log_config(config: &Config) {
let c = config;
logv(c, format!("configuration:"));
logv(c, format!("compile_lib_path: {}", config.compile_lib_path));
logv(c, format!("run_lib_path: {}", config.run_lib_path));
logv(c, format!("rustc_path: {}", config.rustc_path.display()));
logv(c, format!("src_base: {}", config.src_base.display()));
logv(c, format!("build_base: {}", config.build_base.display()));
logv(c, format!("stage_id: {}", config.stage_id));
logv(c, format!("mode: {}", config.mode));
logv(c, format!("run_ignored: {}", config.run_ignored));
logv(c, format!("filter: {}", opt_str(&config.filter.as_ref().map(|re| re.to_str()))));
logv(c, format!("runtool: {}", opt_str(&config.runtool)));
logv(c, format!("host-rustcflags: {}", opt_str(&config.host_rustcflags)));
logv(c, format!("target-rustcflags: {}", opt_str(&config.target_rustcflags)));
logv(c, format!("jit: {}", config.jit));
logv(c, format!("target: {}", config.target));
logv(c, format!("host: {}", config.host));
logv(c, format!("android-cross-path: {}", config.android_cross_path.display()));
logv(c, format!("adb_path: {}", config.adb_path));
logv(c, format!("adb_test_dir: {}", config.adb_test_dir));
logv(c, format!("adb_device_status: {}", config.adb_device_status));
logv(c, format_strbuf!("configuration:"));
logv(c, format_strbuf!("compile_lib_path: {}", config.compile_lib_path));
logv(c, format_strbuf!("run_lib_path: {}", config.run_lib_path));
logv(c, format_strbuf!("rustc_path: {}", config.rustc_path.display()));
logv(c, format_strbuf!("src_base: {}", config.src_base.display()));
logv(c, format_strbuf!("build_base: {}", config.build_base.display()));
logv(c, format_strbuf!("stage_id: {}", config.stage_id));
logv(c, format_strbuf!("mode: {}", config.mode));
logv(c, format_strbuf!("run_ignored: {}", config.run_ignored));
logv(c, format_strbuf!("filter: {}",
opt_str(&config.filter
.as_ref()
.map(|re| {
re.to_str().into_strbuf()
}))));
logv(c, format_strbuf!("runtool: {}", opt_str(&config.runtool)));
logv(c, format_strbuf!("host-rustcflags: {}",
opt_str(&config.host_rustcflags)));
logv(c, format_strbuf!("target-rustcflags: {}",
opt_str(&config.target_rustcflags)));
logv(c, format_strbuf!("jit: {}", config.jit));
logv(c, format_strbuf!("target: {}", config.target));
logv(c, format_strbuf!("host: {}", config.host));
logv(c, format_strbuf!("android-cross-path: {}",
config.android_cross_path.display()));
logv(c, format_strbuf!("adb_path: {}", config.adb_path));
logv(c, format_strbuf!("adb_test_dir: {}", config.adb_test_dir));
logv(c, format_strbuf!("adb_device_status: {}",
config.adb_device_status));
match config.test_shard {
None => logv(c, "test_shard: (all)".to_owned()),
Some((a,b)) => logv(c, format!("test_shard: {}.{}", a, b))
None => logv(c, "test_shard: (all)".to_strbuf()),
Some((a,b)) => logv(c, format_strbuf!("test_shard: {}.{}", a, b))
}
logv(c, format!("verbose: {}", config.verbose));
logv(c, format!("\n"));
logv(c, format_strbuf!("verbose: {}", config.verbose));
logv(c, format_strbuf!("\n"));
}
pub fn opt_str<'a>(maybestr: &'a Option<~str>) -> &'a str {
pub fn opt_str<'a>(maybestr: &'a Option<StrBuf>) -> &'a str {
match *maybestr {
None => "(none)",
Some(ref s) => {
let s: &'a str = *s;
s
}
Some(ref s) => s.as_slice(),
}
}
pub fn opt_str2(maybestr: Option<~str>) -> ~str {
match maybestr { None => "(none)".to_owned(), Some(s) => { s } }
pub fn opt_str2(maybestr: Option<StrBuf>) -> StrBuf {
match maybestr {
None => "(none)".to_strbuf(),
Some(s) => s,
}
}
pub fn run_tests(config: &Config) {
if config.target == "arm-linux-androideabi".to_owned() {
if config.target.as_slice() == "arm-linux-androideabi" {
match config.mode {
DebugInfoGdb => {
println!("arm-linux-androideabi debug-info \
@@ -321,11 +346,11 @@ pub fn make_test(config: &Config, testfile: &Path, f: || -> test::TestFn)
pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
// Try to elide redundant long paths
fn shorten(path: &Path) -> ~str {
fn shorten(path: &Path) -> StrBuf {
let filename = path.filename_str();
let p = path.dir_path();
let dir = p.filename_str();
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
format_strbuf!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
}
test::DynTestName(format_strbuf!("[{}] {}",
@@ -336,14 +361,16 @@ fn shorten(path: &Path) -> ~str {
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
let config = (*config).clone();
// FIXME (#9639): This needs to handle non-utf8 paths
let testfile = testfile.as_str().unwrap().to_owned();
test::DynTestFn(proc() { runtest::run(config, testfile) })
let testfile = testfile.as_str().unwrap().to_strbuf();
test::DynTestFn(proc() {
runtest::run(config, testfile)
})
}
pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
let config = (*config).clone();
// FIXME (#9639): This needs to handle non-utf8 paths
let testfile = testfile.as_str().unwrap().to_owned();
let testfile = testfile.as_str().unwrap().to_strbuf();
test::DynMetricFn(proc(mm) {
runtest::run_metrics(config, testfile, mm)
})
+26 -16
View File
@@ -12,8 +12,8 @@
pub struct ExpectedError {
pub line: uint,
pub kind: ~str,
pub msg: ~str,
pub kind: StrBuf,
pub msg: StrBuf,
}
// Load any test directives embedded in the file
@@ -23,17 +23,18 @@ pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
let mut line_num = 1u;
for ln in rdr.lines() {
error_patterns.push_all_move(parse_expected(line_num, ln.unwrap()));
error_patterns.push_all_move(parse_expected(line_num,
ln.unwrap().to_strbuf()));
line_num += 1u;
}
return error_patterns;
}
fn parse_expected(line_num: uint, line: ~str) -> Vec<ExpectedError> {
let line = line.trim();
let error_tag = "//~".to_owned();
fn parse_expected(line_num: uint, line: StrBuf) -> Vec<ExpectedError> {
let line = line.as_slice().trim().to_strbuf();
let error_tag = "//~".to_strbuf();
let mut idx;
match line.find_str(error_tag) {
match line.as_slice().find_str(error_tag.as_slice()) {
None => return Vec::new(),
Some(nn) => { idx = (nn as uint) + error_tag.len(); }
}
@@ -42,25 +43,34 @@ fn parse_expected(line_num: uint, line: ~str) -> Vec<ExpectedError> {
// three lines above current line:
let mut adjust_line = 0u;
let len = line.len();
while idx < len && line[idx] == ('^' as u8) {
while idx < len && line.as_slice()[idx] == ('^' as u8) {
adjust_line += 1u;
idx += 1u;
}
// Extract kind:
while idx < len && line[idx] == (' ' as u8) { idx += 1u; }
while idx < len && line.as_slice()[idx] == (' ' as u8) {
idx += 1u;
}
let start_kind = idx;
while idx < len && line[idx] != (' ' as u8) { idx += 1u; }
while idx < len && line.as_slice()[idx] != (' ' as u8) {
idx += 1u;
}
let kind = line.slice(start_kind, idx);
let kind = kind.to_ascii().to_lower().into_str();
let kind = line.as_slice().slice(start_kind, idx);
let kind = kind.to_ascii().to_lower().into_str().to_strbuf();
// Extract msg:
while idx < len && line[idx] == (' ' as u8) { idx += 1u; }
let msg = line.slice(idx, len).to_owned();
while idx < len && line.as_slice()[idx] == (' ' as u8) {
idx += 1u;
}
let msg = line.as_slice().slice(idx, len).to_strbuf();
debug!("line={} kind={} msg={}", line_num - adjust_line, kind, msg);
return vec!(ExpectedError{line: line_num - adjust_line, kind: kind,
msg: msg});
return vec!(ExpectedError{
line: line_num - adjust_line,
kind: kind,
msg: msg,
});
}
+50 -39
View File
@@ -14,20 +14,20 @@
pub struct TestProps {
// Lines that should be expected, in order, on standard out
pub error_patterns: Vec<~str> ,
pub error_patterns: Vec<StrBuf> ,
// Extra flags to pass to the compiler
pub compile_flags: Option<~str>,
pub compile_flags: Option<StrBuf>,
// Extra flags to pass when the compiled code is run (such as --bench)
pub run_flags: Option<~str>,
pub run_flags: Option<StrBuf>,
// If present, the name of a file that this test should match when
// pretty-printed
pub pp_exact: Option<Path>,
// Modules from aux directory that should be compiled
pub aux_builds: Vec<~str> ,
pub aux_builds: Vec<StrBuf> ,
// Environment settings to use during execution
pub exec_env: Vec<(~str,~str)> ,
pub exec_env: Vec<(StrBuf,StrBuf)> ,
// Lines to check if they appear in the expected debugger output
pub check_lines: Vec<~str> ,
pub check_lines: Vec<StrBuf> ,
// Flag to force a crate to be built with the host architecture
pub force_host: bool,
// Check stdout for error-pattern output as well as stderr
@@ -119,22 +119,30 @@ pub fn load_props(testfile: &Path) -> TestProps {
}
pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
fn ignore_target(config: &Config) -> ~str {
"ignore-".to_owned() + util::get_os(config.target)
fn ignore_target(config: &Config) -> StrBuf {
format_strbuf!("ignore-{}", util::get_os(config.target.as_slice()))
}
fn ignore_stage(config: &Config) -> ~str {
"ignore-".to_owned() + config.stage_id.split('-').next().unwrap()
fn ignore_stage(config: &Config) -> StrBuf {
format_strbuf!("ignore-{}",
config.stage_id.as_slice().split('-').next().unwrap())
}
let val = iter_header(testfile, |ln| {
if parse_name_directive(ln, "ignore-test") { false }
else if parse_name_directive(ln, ignore_target(config)) { false }
else if parse_name_directive(ln, ignore_stage(config)) { false }
else if config.mode == common::Pretty &&
parse_name_directive(ln, "ignore-pretty") { false }
else if config.target != config.host &&
parse_name_directive(ln, "ignore-cross-compile") { false }
else { true }
if parse_name_directive(ln, "ignore-test") {
false
} else if parse_name_directive(ln, ignore_target(config).as_slice()) {
false
} else if parse_name_directive(ln, ignore_stage(config).as_slice()) {
false
} else if config.mode == common::Pretty &&
parse_name_directive(ln, "ignore-pretty") {
false
} else if config.target != config.host &&
parse_name_directive(ln, "ignore-cross-compile") {
false
} else {
true
}
});
!val
@@ -156,24 +164,24 @@ fn iter_header(testfile: &Path, it: |&str| -> bool) -> bool {
return true;
}
fn parse_error_pattern(line: &str) -> Option<~str> {
parse_name_value_directive(line, "error-pattern".to_owned())
fn parse_error_pattern(line: &str) -> Option<StrBuf> {
parse_name_value_directive(line, "error-pattern".to_strbuf())
}
fn parse_aux_build(line: &str) -> Option<~str> {
parse_name_value_directive(line, "aux-build".to_owned())
fn parse_aux_build(line: &str) -> Option<StrBuf> {
parse_name_value_directive(line, "aux-build".to_strbuf())
}
fn parse_compile_flags(line: &str) -> Option<~str> {
parse_name_value_directive(line, "compile-flags".to_owned())
fn parse_compile_flags(line: &str) -> Option<StrBuf> {
parse_name_value_directive(line, "compile-flags".to_strbuf())
}
fn parse_run_flags(line: &str) -> Option<~str> {
parse_name_value_directive(line, "run-flags".to_owned())
fn parse_run_flags(line: &str) -> Option<StrBuf> {
parse_name_value_directive(line, "run-flags".to_strbuf())
}
fn parse_check_line(line: &str) -> Option<~str> {
parse_name_value_directive(line, "check".to_owned())
fn parse_check_line(line: &str) -> Option<StrBuf> {
parse_name_value_directive(line, "check".to_strbuf())
}
fn parse_force_host(line: &str) -> bool {
@@ -192,13 +200,16 @@ fn parse_no_pretty_expanded(line: &str) -> bool {
parse_name_directive(line, "no-pretty-expanded")
}
fn parse_exec_env(line: &str) -> Option<(~str, ~str)> {
parse_name_value_directive(line, "exec-env".to_owned()).map(|nv| {
fn parse_exec_env(line: &str) -> Option<(StrBuf, StrBuf)> {
parse_name_value_directive(line, "exec-env".to_strbuf()).map(|nv| {
// nv is either FOO or FOO=BAR
let mut strs: Vec<~str> = nv.splitn('=', 1).map(|s| s.to_owned()).collect();
let mut strs: Vec<StrBuf> = nv.as_slice()
.splitn('=', 1)
.map(|s| s.to_strbuf())
.collect();
match strs.len() {
1u => (strs.pop().unwrap(), "".to_owned()),
1u => (strs.pop().unwrap(), "".to_strbuf()),
2u => {
let end = strs.pop().unwrap();
(strs.pop().unwrap(), end)
@@ -209,7 +220,7 @@ fn parse_exec_env(line: &str) -> Option<(~str, ~str)> {
}
fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> {
match parse_name_value_directive(line, "pp-exact".to_owned()) {
match parse_name_value_directive(line, "pp-exact".to_strbuf()) {
Some(s) => Some(Path::new(s)),
None => {
if parse_name_directive(line, "pp-exact") {
@@ -225,14 +236,14 @@ fn parse_name_directive(line: &str, directive: &str) -> bool {
line.contains(directive)
}
pub fn parse_name_value_directive(line: &str,
directive: ~str) -> Option<~str> {
let keycolon = directive + ":";
match line.find_str(keycolon) {
pub fn parse_name_value_directive(line: &str, directive: StrBuf)
-> Option<StrBuf> {
let keycolon = format_strbuf!("{}:", directive);
match line.find_str(keycolon.as_slice()) {
Some(colon) => {
let value = line.slice(colon + keycolon.len(),
line.len()).to_owned();
debug!("{}: {}", directive, value);
line.len()).to_strbuf();
debug!("{}: {}", directive, value);
Some(value)
}
None => None
+23 -20
View File
@@ -13,7 +13,7 @@
use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
#[cfg(target_os = "win32")]
fn target_env(lib_path: &str, prog: &str) -> Vec<(~str, ~str)> {
fn target_env(lib_path: &str, prog: &str) -> Vec<(StrBuf, StrBuf)> {
let env = os::env();
// Make sure we include the aux directory in the path
@@ -22,14 +22,14 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(~str, ~str)> {
let mut new_env: Vec<_> = env.move_iter().map(|(k, v)| {
let new_v = if "PATH" == k {
format!("{};{};{}", v, lib_path, aux_path)
format_strbuf!("{};{};{}", v, lib_path, aux_path)
} else {
v
v.to_strbuf()
};
(k, new_v)
(k.to_strbuf(), new_v)
}).collect();
if prog.ends_with("rustc.exe") {
new_env.push(("RUST_THREADS".to_owned(), "1".to_owned()));
new_env.push(("RUST_THREADS".to_strbuf(), "1".to_strbuf()));
}
return new_env;
}
@@ -37,11 +37,14 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(~str, ~str)> {
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
fn target_env(lib_path: &str, prog: &str) -> Vec<(~str,~str)> {
fn target_env(lib_path: &str, prog: &str) -> Vec<(StrBuf,StrBuf)> {
// Make sure we include the aux directory in the path
let aux_path = prog + ".libaux";
let mut env: Vec<(~str,~str)> = os::env().move_iter().collect();
let mut env: Vec<(StrBuf,StrBuf)> =
os::env().move_iter()
.map(|(ref k, ref v)| (k.to_strbuf(), v.to_strbuf()))
.collect();
let var = if cfg!(target_os = "macos") {
"DYLD_LIBRARY_PATH"
} else {
@@ -49,23 +52,23 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(~str,~str)> {
};
let prev = match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
Some(i) => env.remove(i).unwrap().val1(),
None => "".to_owned(),
None => "".to_strbuf(),
};
env.push((var.to_owned(), if prev.is_empty() {
lib_path + ":" + aux_path
env.push((var.to_strbuf(), if prev.is_empty() {
format_strbuf!("{}:{}", lib_path, aux_path)
} else {
lib_path + ":" + aux_path + ":" + prev
format_strbuf!("{}:{}:{}", lib_path, aux_path, prev)
}));
return env;
}
pub struct Result {pub status: ProcessExit, pub out: ~str, pub err: ~str}
pub struct Result {pub status: ProcessExit, pub out: StrBuf, pub err: StrBuf}
pub fn run(lib_path: &str,
prog: &str,
args: &[~str],
env: Vec<(~str, ~str)> ,
input: Option<~str>) -> Option<Result> {
args: &[StrBuf],
env: Vec<(StrBuf, StrBuf)> ,
input: Option<StrBuf>) -> Option<Result> {
let env = env.clone().append(target_env(lib_path, prog).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() {
@@ -78,8 +81,8 @@ pub fn run(lib_path: &str,
Some(Result {
status: status,
out: str::from_utf8(output.as_slice()).unwrap().to_owned(),
err: str::from_utf8(error.as_slice()).unwrap().to_owned()
out: str::from_utf8(output.as_slice()).unwrap().to_strbuf(),
err: str::from_utf8(error.as_slice()).unwrap().to_strbuf()
})
},
Err(..) => None
@@ -88,9 +91,9 @@ pub fn run(lib_path: &str,
pub fn run_background(lib_path: &str,
prog: &str,
args: &[~str],
env: Vec<(~str, ~str)> ,
input: Option<~str>) -> Option<Process> {
args: &[StrBuf],
env: Vec<(StrBuf, StrBuf)> ,
input: Option<StrBuf>) -> Option<Process> {
let env = env.clone().append(target_env(lib_path, prog).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+495 -273
View File
@@ -31,7 +31,7 @@
use std::task;
use test::MetricMap;
pub fn run(config: Config, testfile: ~str) {
pub fn run(config: Config, testfile: StrBuf) {
match config.target.as_slice() {
@@ -48,7 +48,7 @@ pub fn run(config: Config, testfile: ~str) {
run_metrics(config, testfile, &mut _mm);
}
pub fn run_metrics(config: Config, testfile: ~str, mm: &mut MetricMap) {
pub fn run_metrics(config: Config, testfile: StrBuf, mm: &mut MetricMap) {
if config.verbose {
// We're going to be dumping a lot of info. Start on a new line.
print!("\n\n");
@@ -72,7 +72,8 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
let proc_res = compile_test(config, props, testfile);
if proc_res.status.success() {
fatal_ProcRes("compile-fail test compiled successfully!".to_owned(), &proc_res);
fatal_ProcRes("compile-fail test compiled successfully!".to_strbuf(),
&proc_res);
}
check_correct_failure_status(&proc_res);
@@ -80,7 +81,8 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
let expected_errors = errors::load_errors(testfile);
if !expected_errors.is_empty() {
if !props.error_patterns.is_empty() {
fatal("both error pattern and expected errors specified".to_owned());
fatal("both error pattern and expected errors \
specified".to_strbuf());
}
check_expected_errors(expected_errors, testfile, &proc_res);
} else {
@@ -94,7 +96,7 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
let proc_res = compile_test(config, props, testfile);
if !proc_res.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &proc_res);
fatal_ProcRes("compilation failed!".to_strbuf(), &proc_res);
}
exec_compiled_test(config, props, testfile)
@@ -105,7 +107,8 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
// The value our Makefile configures valgrind to return on failure
static VALGRIND_ERR: int = 100;
if proc_res.status.matches_exit_status(VALGRIND_ERR) {
fatal_ProcRes("run-fail test isn't valgrind-clean!".to_owned(), &proc_res);
fatal_ProcRes("run-fail test isn't valgrind-clean!".to_strbuf(),
&proc_res);
}
check_correct_failure_status(&proc_res);
@@ -117,7 +120,8 @@ fn check_correct_failure_status(proc_res: &ProcRes) {
static RUST_ERR: int = 101;
if !proc_res.status.matches_exit_status(RUST_ERR) {
fatal_ProcRes(
format!("failure produced the wrong error: {}", proc_res.status),
format_strbuf!("failure produced the wrong error: {}",
proc_res.status),
proc_res);
}
}
@@ -127,40 +131,49 @@ fn run_rpass_test(config: &Config, props: &TestProps, testfile: &Path) {
let mut proc_res = compile_test(config, props, testfile);
if !proc_res.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &proc_res);
fatal_ProcRes("compilation failed!".to_strbuf(), &proc_res);
}
proc_res = exec_compiled_test(config, props, testfile);
if !proc_res.status.success() {
fatal_ProcRes("test run failed!".to_owned(), &proc_res);
fatal_ProcRes("test run failed!".to_strbuf(), &proc_res);
}
} else {
let proc_res = jit_test(config, props, testfile);
if !proc_res.status.success() { fatal_ProcRes("jit failed!".to_owned(), &proc_res); }
if !proc_res.status.success() {
fatal_ProcRes("jit failed!".to_strbuf(), &proc_res);
}
}
}
fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
if props.pp_exact.is_some() {
logv(config, "testing for exact pretty-printing".to_owned());
} else { logv(config, "testing for converging pretty-printing".to_owned()); }
logv(config, "testing for exact pretty-printing".to_strbuf());
} else {
logv(config, "testing for converging pretty-printing".to_strbuf());
}
let rounds =
match props.pp_exact { Some(_) => 1, None => 2 };
let src = File::open(testfile).read_to_end().unwrap();
let src = str::from_utf8(src.as_slice()).unwrap().to_owned();
let src = str::from_utf8(src.as_slice()).unwrap().to_strbuf();
let mut srcs = vec!(src);
let mut round = 0;
while round < rounds {
logv(config, format!("pretty-printing round {}", round));
let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "normal");
logv(config, format_strbuf!("pretty-printing round {}", round));
let proc_res = print_source(config,
props,
testfile,
(*srcs.get(round)).to_strbuf(),
"normal");
if !proc_res.status.success() {
fatal_ProcRes(format!("pretty-printing failed in round {}", round),
fatal_ProcRes(format_strbuf!("pretty-printing failed in round {}",
round),
&proc_res);
}
@@ -173,7 +186,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
Some(ref file) => {
let filepath = testfile.dir_path().join(file);
let s = File::open(&filepath).read_to_end().unwrap();
str::from_utf8(s.as_slice()).unwrap().to_owned()
str::from_utf8(s.as_slice()).unwrap().to_strbuf()
}
None => { (*srcs.get(srcs.len() - 2u)).clone() }
};
@@ -181,31 +194,35 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
if props.pp_exact.is_some() {
// Now we have to care about line endings
let cr = "\r".to_owned();
actual = actual.replace(cr, "");
expected = expected.replace(cr, "");
let cr = "\r".to_strbuf();
actual = actual.replace(cr.as_slice(), "").to_strbuf();
expected = expected.replace(cr.as_slice(), "").to_strbuf();
}
compare_source(expected, actual);
compare_source(expected.as_slice(), actual.as_slice());
// Finally, let's make sure it actually appears to remain valid code
let proc_res = typecheck_source(config, props, testfile, actual);
if !proc_res.status.success() {
fatal_ProcRes("pretty-printed source does not typecheck".to_owned(), &proc_res);
fatal_ProcRes("pretty-printed source does not typecheck".to_strbuf(),
&proc_res);
}
if props.no_pretty_expanded { return }
// additionally, run `--pretty expanded` and try to build it.
let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded");
if !proc_res.status.success() {
fatal_ProcRes(format!("pretty-printing (expanded) failed"), &proc_res);
fatal_ProcRes(format_strbuf!("pretty-printing (expanded) failed"),
&proc_res);
}
let ProcRes{ stdout: expanded_src, .. } = proc_res;
let proc_res = typecheck_source(config, props, testfile, expanded_src);
if !proc_res.status.success() {
fatal_ProcRes(format!("pretty-printed source (expanded) does not typecheck"), &proc_res);
fatal_ProcRes(format_strbuf!("pretty-printed source (expanded) does \
not typecheck"),
&proc_res);
}
return;
@@ -213,30 +230,43 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
fn print_source(config: &Config,
props: &TestProps,
testfile: &Path,
src: ~str,
src: StrBuf,
pretty_type: &str) -> ProcRes {
compose_and_run(config, testfile,
make_pp_args(config, props, testfile, pretty_type.to_owned()),
props.exec_env.clone(), config.compile_lib_path, Some(src))
compose_and_run(config,
testfile,
make_pp_args(config,
props,
testfile,
pretty_type.to_strbuf()),
props.exec_env.clone(),
config.compile_lib_path.as_slice(),
Some(src))
}
fn make_pp_args(config: &Config,
props: &TestProps,
testfile: &Path,
pretty_type: ~str) -> ProcArgs {
pretty_type: StrBuf) -> ProcArgs {
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
let mut args = vec!("-".to_owned(), "--pretty".to_owned(), pretty_type,
"--target=".to_owned() + config.target,
"-L".to_owned(), aux_dir.as_str().unwrap().to_owned());
let mut args = vec!("-".to_strbuf(),
"--pretty".to_strbuf(),
pretty_type,
format_strbuf!("--target={}", config.target),
"-L".to_strbuf(),
aux_dir.as_str().unwrap().to_strbuf());
args.push_all_move(split_maybe_args(&config.target_rustcflags));
args.push_all_move(split_maybe_args(&props.compile_flags));
return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args};
return ProcArgs {
prog: config.rustc_path.as_str().unwrap().to_strbuf(),
args: args,
};
}
fn compare_source(expected: &str, actual: &str) {
if expected != actual {
error("pretty-printed source does not match expected source".to_owned());
error("pretty-printed source does not match expected \
source".to_strbuf());
println!("\n\
expected:\n\
------------------------------------------\n\
@@ -253,7 +283,7 @@ fn compare_source(expected: &str, actual: &str) {
}
fn typecheck_source(config: &Config, props: &TestProps,
testfile: &Path, src: ~str) -> ProcRes {
testfile: &Path, src: StrBuf) -> ProcRes {
let args = make_typecheck_args(config, props, testfile);
compose_and_run_compiler(config, props, testfile, args, Some(src))
}
@@ -266,16 +296,21 @@ fn make_typecheck_args(config: &Config, props: &TestProps, testfile: &Path) -> P
config.target.as_slice()
};
// FIXME (#9639): This needs to handle non-utf8 paths
let mut args = vec!("-".to_owned(),
"--no-trans".to_owned(), "--crate-type=lib".to_owned(),
"--target=".to_owned() + target,
"-L".to_owned(), config.build_base.as_str().unwrap().to_owned(),
"-L".to_owned(),
aux_dir.as_str().unwrap().to_owned());
let mut args = vec!("-".to_strbuf(),
"--no-trans".to_strbuf(),
"--crate-type=lib".to_strbuf(),
format_strbuf!("--target={}", target),
"-L".to_strbuf(),
config.build_base.as_str().unwrap().to_strbuf(),
"-L".to_strbuf(),
aux_dir.as_str().unwrap().to_strbuf());
args.push_all_move(split_maybe_args(&config.target_rustcflags));
args.push_all_move(split_maybe_args(&props.compile_flags));
// FIXME (#9639): This needs to handle non-utf8 paths
return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args};
return ProcArgs {
prog: config.rustc_path.as_str().unwrap().to_strbuf(),
args: args,
};
}
}
@@ -288,12 +323,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
let config = &mut config;
let DebuggerCommands { commands, check_lines, .. } = parse_debugger_commands(testfile, "gdb");
let mut cmds = commands.connect("\n");
let mut cmds = commands.connect("\n").to_strbuf();
// compile test file (it shoud have 'compile-flags:-g' in the header)
let compiler_run_result = compile_test(config, props, testfile);
if !compiler_run_result.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &compiler_run_result);
fatal_ProcRes("compilation failed!".to_strbuf(), &compiler_run_result);
}
let exe_file = make_exe_name(config, testfile);
@@ -303,38 +338,64 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
match config.target.as_slice() {
"arm-linux-androideabi" => {
cmds = cmds.replace("run","continue");
cmds = cmds.replace("run", "continue").to_strbuf();
// write debugger script
let script_str = ["set charset UTF-8".to_owned(),
format!("file {}",exe_file.as_str().unwrap().to_owned()),
"target remote :5039".to_owned(),
let script_str = ["set charset UTF-8".to_strbuf(),
format_strbuf!("file {}",
exe_file.as_str()
.unwrap()
.to_strbuf()),
"target remote :5039".to_strbuf(),
cmds,
"quit".to_owned()].connect("\n");
"quit".to_strbuf()].connect("\n");
debug!("script_str = {}", script_str);
dump_output_file(config, testfile, script_str, "debugger.script");
procsrv::run("", config.adb_path,
["push".to_owned(), exe_file.as_str().unwrap().to_owned(),
config.adb_test_dir.clone()],
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
procsrv::run("",
config.adb_path.as_slice(),
[
"push".to_strbuf(),
exe_file.as_str().unwrap().to_strbuf(),
config.adb_test_dir.clone()
],
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`",
config.adb_path));
procsrv::run("", config.adb_path,
["forward".to_owned(), "tcp:5039".to_owned(), "tcp:5039".to_owned()],
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
procsrv::run("",
config.adb_path.as_slice(),
[
"forward".to_strbuf(),
"tcp:5039".to_strbuf(),
"tcp:5039".to_strbuf()
],
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
let adb_arg = format!("export LD_LIBRARY_PATH={}; gdbserver :5039 {}/{}",
config.adb_test_dir.clone(), config.adb_test_dir.clone(),
str::from_utf8(exe_file.filename().unwrap()).unwrap());
let adb_arg = format_strbuf!("export LD_LIBRARY_PATH={}; \
gdbserver :5039 {}/{}",
config.adb_test_dir.clone(),
config.adb_test_dir.clone(),
str::from_utf8(
exe_file.filename()
.unwrap()).unwrap());
let mut process = procsrv::run_background("", config.adb_path,
["shell".to_owned(),adb_arg.clone()],
vec!(("".to_owned(),"".to_owned())),
Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
let mut process = procsrv::run_background("",
config.adb_path
.as_slice(),
[
"shell".to_strbuf(),
adb_arg.clone()
],
vec!(("".to_strbuf(),
"".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`",
config.adb_path));
loop {
//waiting 1 second for gdbserver start
timer::sleep(1000);
@@ -349,27 +410,34 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
let tool_path = match config.android_cross_path.as_str() {
Some(x) => x.to_strbuf(),
None => fatal("cannot find android cross path".to_owned())
None => fatal("cannot find android cross path".to_strbuf())
};
let debugger_script = make_out_name(config, testfile, "debugger.script");
// FIXME (#9639): This needs to handle non-utf8 paths
let debugger_opts = vec!("-quiet".to_owned(), "-batch".to_owned(), "-nx".to_owned(),
"-command=" + debugger_script.as_str().unwrap().to_owned());
let debugger_opts =
vec!("-quiet".to_strbuf(),
"-batch".to_strbuf(),
"-nx".to_strbuf(),
format_strbuf!("-command={}",
debugger_script.as_str().unwrap()));
let gdb_path = tool_path.append("/bin/arm-linux-androideabi-gdb");
let procsrv::Result{ out, err, status }=
procsrv::run("",
let procsrv::Result {
out,
err,
status
} = procsrv::run("",
gdb_path.as_slice(),
debugger_opts.as_slice(),
vec!(("".to_owned(),"".to_owned())),
vec!(("".to_strbuf(), "".to_strbuf())),
None)
.expect(format!("failed to exec `{}`", gdb_path));
.expect(format_strbuf!("failed to exec `{}`", gdb_path));
let cmdline = {
let cmdline = make_cmdline("",
"arm-linux-androideabi-gdb",
debugger_opts.as_slice());
logv(config, format!("executing {}", cmdline));
logv(config, format_strbuf!("executing {}", cmdline));
cmdline
};
@@ -384,25 +452,38 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
_=> {
// write debugger script
let script_str = ["set charset UTF-8".to_owned(),
let script_str = [
"set charset UTF-8".to_strbuf(),
cmds,
"quit\n".to_owned()].connect("\n");
"quit\n".to_strbuf()
].connect("\n");
debug!("script_str = {}", script_str);
dump_output_file(config, testfile, script_str, "debugger.script");
// run debugger script with gdb
#[cfg(windows)]
fn debugger() -> ~str { "gdb.exe".to_owned() }
fn debugger() -> StrBuf {
"gdb.exe".to_strbuf()
}
#[cfg(unix)]
fn debugger() -> ~str { "gdb".to_owned() }
fn debugger() -> StrBuf {
"gdb".to_strbuf()
}
let debugger_script = make_out_name(config, testfile, "debugger.script");
// FIXME (#9639): This needs to handle non-utf8 paths
let debugger_opts = vec!("-quiet".to_owned(), "-batch".to_owned(), "-nx".to_owned(),
"-command=" + debugger_script.as_str().unwrap().to_owned(),
exe_file.as_str().unwrap().to_owned());
proc_args = ProcArgs {prog: debugger(), args: debugger_opts};
let debugger_opts =
vec!("-quiet".to_strbuf(),
"-batch".to_strbuf(),
"-nx".to_strbuf(),
format_strbuf!("-command={}",
debugger_script.as_str().unwrap()),
exe_file.as_str().unwrap().to_strbuf());
proc_args = ProcArgs {
prog: debugger(),
args: debugger_opts,
};
debugger_run_result = compose_and_run(config,
testfile,
proc_args,
@@ -413,7 +494,7 @@ fn debugger() -> ~str { "gdb".to_owned() }
}
if !debugger_run_result.status.success() {
fatal("gdb failed to execute".to_owned());
fatal("gdb failed to execute".to_strbuf());
}
check_debugger_output(&debugger_run_result, check_lines.as_slice());
@@ -423,7 +504,8 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
use std::io::process::{Command, ProcessOutput};
if config.lldb_python_dir.is_none() {
fatal("Can't run LLDB test because LLDB's python path is not set.".to_owned());
fatal("Can't run LLDB test because LLDB's python path is not \
set.".to_strbuf());
}
let mut config = Config {
@@ -437,7 +519,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
// compile test file (it shoud have 'compile-flags:-g' in the header)
let compile_result = compile_test(config, props, testfile);
if !compile_result.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &compile_result);
fatal_ProcRes("compilation failed!".to_strbuf(), &compile_result);
}
let exe_file = make_exe_name(config, testfile);
@@ -476,7 +558,8 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
let debugger_run_result = run_lldb(config, &exe_file, &debugger_script);
if !debugger_run_result.status.success() {
fatal_ProcRes("Error while running LLDB".to_owned(), &debugger_run_result);
fatal_ProcRes("Error while running LLDB".to_strbuf(),
&debugger_run_result);
}
check_debugger_output(&debugger_run_result, check_lines.as_slice());
@@ -495,32 +578,34 @@ fn run_lldb(config: &Config, test_executable: &Path, debugger_script: &Path) ->
process.wait_with_output().unwrap();
(status,
str::from_utf8(output.as_slice()).unwrap().to_owned(),
str::from_utf8(error.as_slice()).unwrap().to_owned())
str::from_utf8(output.as_slice()).unwrap().to_strbuf(),
str::from_utf8(error.as_slice()).unwrap().to_strbuf())
},
Err(e) => {
fatal(format!("Failed to setup Python process for LLDB script: {}", e))
fatal(format_strbuf!("Failed to setup Python process for \
LLDB script: {}",
e))
}
};
dump_output(config, test_executable, out, err);
dump_output(config, test_executable, out.as_slice(), err.as_slice());
return ProcRes {
status: status,
stdout: out,
stderr: err,
cmdline: format!("{}", cmd)
cmdline: format_strbuf!("{}", cmd)
};
}
}
struct DebuggerCommands
{
commands: Vec<~str>,
check_lines: Vec<~str>,
breakpoint_lines: Vec<uint>
struct DebuggerCommands {
commands: Vec<StrBuf>,
check_lines: Vec<StrBuf>,
breakpoint_lines: Vec<uint>,
}
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerCommands {
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
-> DebuggerCommands {
use std::io::{BufferedReader, File};
let command_directive = debugger_prefix + "-command";
@@ -538,14 +623,22 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerC
breakpoint_lines.push(counter);
}
header::parse_name_value_directive(line, command_directive.clone())
.map(|cmd| commands.push(cmd));
header::parse_name_value_directive(
line,
command_directive.to_strbuf()).map(|cmd| {
commands.push(cmd)
});
header::parse_name_value_directive(line, check_directive.clone())
.map(|cmd| check_lines.push(cmd));
header::parse_name_value_directive(
line,
check_directive.to_strbuf()).map(|cmd| {
check_lines.push(cmd)
});
}
Err(e) => {
fatal(format!("Error while parsing debugger commands: {}", e))
fatal(format_strbuf!("Error while parsing debugger commands: \
{}",
e))
}
}
counter += 1;
@@ -558,41 +651,55 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str) -> DebuggerC
}
}
fn cleanup_debug_info_options(options: &Option<~str>) -> Option<~str> {
fn cleanup_debug_info_options(options: &Option<StrBuf>) -> Option<StrBuf> {
if options.is_none() {
return None;
}
// Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
let new_options = split_maybe_args(options).move_iter()
.filter(|x| !options_to_remove.contains(x))
.collect::<Vec<~str>>()
.connect(" ");
let options_to_remove = [
"-O".to_strbuf(),
"-g".to_strbuf(),
"--debuginfo".to_strbuf()
];
let new_options =
split_maybe_args(options).move_iter()
.filter(|x| !options_to_remove.contains(x))
.collect::<Vec<StrBuf>>()
.connect(" ")
.to_strbuf();
Some(new_options)
}
fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[~str]) {
fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[StrBuf]) {
let num_check_lines = check_lines.len();
if num_check_lines > 0 {
// Allow check lines to leave parts unspecified (e.g., uninitialized
// bits in the wrong case of an enum) with the notation "[...]".
let check_fragments: Vec<Vec<~str>> =
let check_fragments: Vec<Vec<StrBuf>> =
check_lines.iter().map(|s| {
s.trim().split_str("[...]").map(|x| x.to_str()).collect()
s.as_slice()
.trim()
.split_str("[...]")
.map(|x| x.to_strbuf())
.collect()
}).collect();
// check if each line in props.check_lines appears in the
// output (in order)
let mut i = 0u;
for line in debugger_run_result.stdout.lines() {
for line in debugger_run_result.stdout.as_slice().lines() {
let mut rest = line.trim();
let mut first = true;
let mut failed = false;
for frag in check_fragments.get(i).iter() {
let found = if first {
if rest.starts_with(*frag) { Some(0) } else { None }
if rest.starts_with(frag.as_slice()) {
Some(0)
} else {
None
}
} else {
rest.find_str(*frag)
rest.find_str(frag.as_slice())
};
match found {
None => {
@@ -614,8 +721,10 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[~str]) {
}
}
if i != num_check_lines {
fatal_ProcRes(format!("line not found in debugger output: {}",
check_lines.get(i).unwrap()), debugger_run_result);
fatal_ProcRes(format_strbuf!("line not found in debugger output: \
{}",
check_lines.get(i).unwrap()),
debugger_run_result);
}
}
}
@@ -624,24 +733,24 @@ fn check_error_patterns(props: &TestProps,
testfile: &Path,
proc_res: &ProcRes) {
if props.error_patterns.is_empty() {
fatal("no error pattern specified in ".to_owned() +
testfile.display().as_maybe_owned().as_slice());
fatal(format_strbuf!("no error pattern specified in {}",
testfile.display().as_maybe_owned().as_slice()));
}
if proc_res.status.success() {
fatal("process did not return an error status".to_owned());
fatal("process did not return an error status".to_strbuf());
}
let mut next_err_idx = 0u;
let mut next_err_pat = props.error_patterns.get(next_err_idx);
let mut done = false;
let output_to_check = if props.check_stdout {
proc_res.stdout + proc_res.stderr
format_strbuf!("{}{}", proc_res.stdout, proc_res.stderr)
} else {
proc_res.stderr.clone()
};
for line in output_to_check.lines() {
if line.contains(*next_err_pat) {
for line in output_to_check.as_slice().lines() {
if line.contains(next_err_pat.as_slice()) {
debug!("found error pattern {}", *next_err_pat);
next_err_idx += 1u;
if next_err_idx == props.error_patterns.len() {
@@ -657,20 +766,22 @@ fn check_error_patterns(props: &TestProps,
let missing_patterns =
props.error_patterns.slice(next_err_idx, props.error_patterns.len());
if missing_patterns.len() == 1u {
fatal_ProcRes(format!("error pattern '{}' not found!",
missing_patterns[0]), proc_res);
fatal_ProcRes(format_strbuf!("error pattern '{}' not found!",
missing_patterns[0]),
proc_res);
} else {
for pattern in missing_patterns.iter() {
error(format!("error pattern '{}' not found!", *pattern));
error(format_strbuf!("error pattern '{}' not found!", *pattern));
}
fatal_ProcRes("multiple error patterns not found".to_owned(), proc_res);
fatal_ProcRes("multiple error patterns not found".to_strbuf(),
proc_res);
}
}
fn check_no_compiler_crash(proc_res: &ProcRes) {
for line in proc_res.stderr.lines() {
for line in proc_res.stderr.as_slice().lines() {
if line.starts_with("error: internal compiler error:") {
fatal_ProcRes("compiler encountered internal error".to_owned(),
fatal_ProcRes("compiler encountered internal error".to_strbuf(),
proc_res);
}
}
@@ -685,15 +796,15 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
expected_errors.len(), false);
if proc_res.status.success() {
fatal("process did not return an error status".to_owned());
fatal("process did not return an error status".to_strbuf());
}
let prefixes = expected_errors.iter().map(|ee| {
format!("{}:{}:", testfile.display(), ee.line)
}).collect::<Vec<~str> >();
format_strbuf!("{}:{}:", testfile.display(), ee.line)
}).collect::<Vec<StrBuf> >();
#[cfg(target_os = "win32")]
fn to_lower( s : &str ) -> ~str {
fn to_lower( s : &str ) -> StrBuf {
let i = s.chars();
let c : Vec<char> = i.map( |c| {
if c.is_ascii() {
@@ -702,12 +813,12 @@ fn to_lower( s : &str ) -> ~str {
c
}
} ).collect();
str::from_chars(c.as_slice())
str::from_chars(c.as_slice()).to_strbuf()
}
#[cfg(target_os = "win32")]
fn prefix_matches( line : &str, prefix : &str ) -> bool {
to_lower(line).starts_with( to_lower(prefix) )
to_lower(line).as_slice().starts_with(to_lower(prefix).as_slice())
}
#[cfg(target_os = "linux")]
@@ -723,15 +834,18 @@ fn prefix_matches( line : &str, prefix : &str ) -> bool {
// filename:line1:col1: line2:col2: *warning:* msg
// where line1:col1: is the starting point, line2:col2:
// is the ending point, and * represents ANSI color codes.
for line in proc_res.stderr.lines() {
for line in proc_res.stderr.as_slice().lines() {
let mut was_expected = false;
for (i, ee) in expected_errors.iter().enumerate() {
if !*found_flags.get(i) {
debug!("prefix={} ee.kind={} ee.msg={} line={}",
*prefixes.get(i), ee.kind, ee.msg, line);
if prefix_matches(line, *prefixes.get(i)) &&
line.contains(ee.kind) &&
line.contains(ee.msg) {
prefixes.get(i).as_slice(),
ee.kind,
ee.msg,
line);
if prefix_matches(line, prefixes.get(i).as_slice()) &&
line.contains(ee.kind.as_slice()) &&
line.contains(ee.msg.as_slice()) {
*found_flags.get_mut(i) = true;
was_expected = true;
break;
@@ -745,8 +859,9 @@ fn prefix_matches( line : &str, prefix : &str ) -> bool {
}
if !was_expected && is_compiler_error_or_warning(line) {
fatal_ProcRes(format!("unexpected compiler error or warning: '{}'",
line),
fatal_ProcRes(format_strbuf!("unexpected compiler error or \
warning: '{}'",
line),
proc_res);
}
}
@@ -754,8 +869,12 @@ fn prefix_matches( line : &str, prefix : &str ) -> bool {
for (i, &flag) in found_flags.iter().enumerate() {
if !flag {
let ee = expected_errors.get(i);
fatal_ProcRes(format!("expected {} on line {} not found: {}",
ee.kind, ee.line, ee.msg), proc_res);
fatal_ProcRes(format_strbuf!("expected {} on line {} not found: \
{}",
ee.kind,
ee.line,
ee.msg),
proc_res);
}
}
}
@@ -835,9 +954,17 @@ fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool {
return true;
}
struct ProcArgs {prog: ~str, args: Vec<~str> }
struct ProcArgs {
prog: StrBuf,
args: Vec<StrBuf>,
}
struct ProcRes {status: ProcessExit, stdout: ~str, stderr: ~str, cmdline: ~str}
struct ProcRes {
status: ProcessExit,
stdout: StrBuf,
stderr: StrBuf,
cmdline: StrBuf,
}
fn compile_test(config: &Config, props: &TestProps,
testfile: &Path) -> ProcRes {
@@ -845,14 +972,15 @@ fn compile_test(config: &Config, props: &TestProps,
}
fn jit_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes {
compile_test_(config, props, testfile, ["--jit".to_owned()])
compile_test_(config, props, testfile, ["--jit".to_strbuf()])
}
fn compile_test_(config: &Config, props: &TestProps,
testfile: &Path, extra_args: &[~str]) -> ProcRes {
testfile: &Path, extra_args: &[StrBuf]) -> ProcRes {
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
let link_args = vec!("-L".to_owned(), aux_dir.as_str().unwrap().to_owned());
let link_args = vec!("-L".to_strbuf(),
aux_dir.as_str().unwrap().to_strbuf());
let args = make_compile_args(config,
props,
link_args.append(extra_args),
@@ -872,10 +1000,12 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
}
_=> {
compose_and_run(config, testfile,
compose_and_run(config,
testfile,
make_run_args(config, props, testfile),
env,
config.run_lib_path, None)
config.run_lib_path.as_slice(),
None)
}
}
}
@@ -885,7 +1015,7 @@ fn compose_and_run_compiler(
props: &TestProps,
testfile: &Path,
args: ProcArgs,
input: Option<~str>) -> ProcRes {
input: Option<StrBuf>) -> ProcRes {
if !props.aux_builds.is_empty() {
ensure_dir(&aux_output_dir_name(config, testfile));
@@ -901,37 +1031,48 @@ fn compose_and_run_compiler(
let crate_type = if aux_props.no_prefer_dynamic {
Vec::new()
} else {
vec!("--crate-type=dylib".to_owned())
vec!("--crate-type=dylib".to_strbuf())
};
let aux_args =
make_compile_args(config,
&aux_props,
crate_type.append(extra_link_args.as_slice()),
crate_type.append(
extra_link_args.iter()
.map(|x| x.to_strbuf())
.collect::<Vec<_>>()
.as_slice()),
|a,b| {
let f = make_lib_name(a, b, testfile);
ThisDirectory(f.dir_path())
}, &abs_ab);
let auxres = compose_and_run(config, &abs_ab, aux_args, Vec::new(),
config.compile_lib_path, None);
},
&abs_ab);
let auxres = compose_and_run(config,
&abs_ab,
aux_args,
Vec::new(),
config.compile_lib_path.as_slice(),
None);
if !auxres.status.success() {
fatal_ProcRes(
format!("auxiliary build of {} failed to compile: ",
abs_ab.display()),
format_strbuf!("auxiliary build of {} failed to compile: ",
abs_ab.display()),
&auxres);
}
match config.target.as_slice() {
"arm-linux-androideabi" => {
_arm_push_aux_shared_library(config, testfile);
}
_=> { }
_ => {}
}
}
compose_and_run(config, testfile, args, Vec::new(),
config.compile_lib_path, input)
compose_and_run(config,
testfile,
args,
Vec::new(),
config.compile_lib_path.as_slice(),
input)
}
fn ensure_dir(path: &Path) {
@@ -941,9 +1082,9 @@ fn ensure_dir(path: &Path) {
fn compose_and_run(config: &Config, testfile: &Path,
ProcArgs{ args, prog }: ProcArgs,
procenv: Vec<(~str, ~str)> ,
procenv: Vec<(StrBuf, StrBuf)> ,
lib_path: &str,
input: Option<~str>) -> ProcRes {
input: Option<StrBuf>) -> ProcRes {
return program_output(config, testfile, lib_path,
prog, args, procenv, input);
}
@@ -955,7 +1096,7 @@ enum TargetLocation {
fn make_compile_args(config: &Config,
props: &TestProps,
extras: Vec<~str> ,
extras: Vec<StrBuf> ,
xform: |&Config, &Path| -> TargetLocation,
testfile: &Path)
-> ProcArgs {
@@ -966,26 +1107,36 @@ fn make_compile_args(config: &Config,
config.target.as_slice()
};
// FIXME (#9639): This needs to handle non-utf8 paths
let mut args = vec!(testfile.as_str().unwrap().to_owned(),
"-L".to_owned(), config.build_base.as_str().unwrap().to_owned(),
"--target=".to_owned() + target);
let mut args = vec!(testfile.as_str().unwrap().to_strbuf(),
"-L".to_strbuf(),
config.build_base.as_str().unwrap().to_strbuf(),
format_strbuf!("--target={}", target));
args.push_all(extras.as_slice());
if !props.no_prefer_dynamic {
args.push("-C".to_owned());
args.push("prefer-dynamic".to_owned());
args.push("-C".to_strbuf());
args.push("prefer-dynamic".to_strbuf());
}
let path = match xform_file {
ThisFile(path) => { args.push("-o".to_owned()); path }
ThisDirectory(path) => { args.push("--out-dir".to_owned()); path }
ThisFile(path) => {
args.push("-o".to_strbuf());
path
}
ThisDirectory(path) => {
args.push("--out-dir".to_strbuf());
path
}
};
args.push(path.as_str().unwrap().to_owned());
args.push(path.as_str().unwrap().to_strbuf());
if props.force_host {
args.push_all_move(split_maybe_args(&config.host_rustcflags));
} else {
args.push_all_move(split_maybe_args(&config.target_rustcflags));
}
args.push_all_move(split_maybe_args(&props.compile_flags));
return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args};
return ProcArgs {
prog: config.rustc_path.as_str().unwrap().to_strbuf(),
args: args,
};
}
fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path {
@@ -1014,64 +1165,88 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) ->
let exe_file = make_exe_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
args.push(exe_file.as_str().unwrap().to_owned());
args.push(exe_file.as_str().unwrap().to_strbuf());
// Add the arguments in the run_flags directive
args.push_all_move(split_maybe_args(&props.run_flags));
let prog = args.shift().unwrap();
return ProcArgs {prog: prog, args: args};
return ProcArgs {
prog: prog,
args: args,
};
}
fn split_maybe_args(argstr: &Option<~str>) -> Vec<~str> {
fn split_maybe_args(argstr: &Option<StrBuf>) -> Vec<StrBuf> {
match *argstr {
Some(ref s) => {
s.split(' ')
.filter_map(|s| if s.is_whitespace() {None} else {Some(s.to_owned())})
.collect()
s.as_slice()
.split(' ')
.filter_map(|s| {
if s.is_whitespace() {
None
} else {
Some(s.to_strbuf())
}
}).collect()
}
None => Vec::new()
}
}
fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: ~str,
args: Vec<~str> , env: Vec<(~str, ~str)> ,
input: Option<~str>) -> ProcRes {
fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: StrBuf,
args: Vec<StrBuf> , env: Vec<(StrBuf, StrBuf)> ,
input: Option<StrBuf>) -> ProcRes {
let cmdline =
{
let cmdline = make_cmdline(lib_path, prog, args.as_slice());
logv(config, format!("executing {}", cmdline));
let cmdline = make_cmdline(lib_path,
prog.as_slice(),
args.as_slice());
logv(config, format_strbuf!("executing {}", cmdline));
cmdline
};
let procsrv::Result{ out, err, status } =
procsrv::run(lib_path, prog, args.as_slice(), env, input)
.expect(format!("failed to exec `{}`", prog));
dump_output(config, testfile, out, err);
return ProcRes {status: status,
stdout: out,
stderr: err,
cmdline: cmdline};
let procsrv::Result {
out,
err,
status
} = procsrv::run(lib_path,
prog.as_slice(),
args.as_slice(),
env,
input).expect(format_strbuf!("failed to exec `{}`",
prog));
dump_output(config, testfile, out.as_slice(), err.as_slice());
return ProcRes {
status: status,
stdout: out,
stderr: err,
cmdline: cmdline,
};
}
// Linux and mac don't require adjusting the library search path
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
fn make_cmdline(_libpath: &str, prog: &str, args: &[~str]) -> ~str {
format!("{} {}", prog, args.connect(" "))
fn make_cmdline(_libpath: &str, prog: &str, args: &[StrBuf]) -> StrBuf {
format_strbuf!("{} {}", prog, args.connect(" "))
}
#[cfg(target_os = "win32")]
fn make_cmdline(libpath: &str, prog: &str, args: &[~str]) -> ~str {
format!("{} {} {}", lib_path_cmd_prefix(libpath), prog,
args.connect(" "))
fn make_cmdline(libpath: &str, prog: &str, args: &[StrBuf]) -> StrBuf {
format_strbuf!("{} {} {}",
lib_path_cmd_prefix(libpath),
prog,
args.connect(" "))
}
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
// for diagnostic purposes
#[cfg(target_os = "win32")]
fn lib_path_cmd_prefix(path: &str) -> ~str {
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
fn lib_path_cmd_prefix(path: &str) -> StrBuf {
format_strbuf!("{}=\"{}\"",
util::lib_path_env_var(),
util::make_new_path(path))
}
fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
@@ -1119,11 +1294,11 @@ fn maybe_dump_to_stdout(config: &Config, out: &str, err: &str) {
}
}
fn error(err: ~str) { println!("\nerror: {}", err); }
fn error(err: StrBuf) { println!("\nerror: {}", err); }
fn fatal(err: ~str) -> ! { error(err); fail!(); }
fn fatal(err: StrBuf) -> ! { error(err); fail!(); }
fn fatal_ProcRes(err: ~str, proc_res: &ProcRes) -> ! {
fn fatal_ProcRes(err: StrBuf, proc_res: &ProcRes) -> ! {
print!("\n\
error: {}\n\
status: {}\n\
@@ -1142,63 +1317,85 @@ fn fatal_ProcRes(err: ~str, proc_res: &ProcRes) -> ! {
fail!();
}
fn _arm_exec_compiled_test(config: &Config, props: &TestProps,
testfile: &Path, env: Vec<(~str, ~str)> ) -> ProcRes {
fn _arm_exec_compiled_test(config: &Config,
props: &TestProps,
testfile: &Path,
env: Vec<(StrBuf, StrBuf)>)
-> ProcRes {
let args = make_run_args(config, props, testfile);
let cmdline = make_cmdline("", args.prog, args.args.as_slice());
let cmdline = make_cmdline("",
args.prog.as_slice(),
args.args.as_slice());
// get bare program string
let mut tvec: Vec<~str> = args.prog.split('/').map(|ts| ts.to_owned()).collect();
let mut tvec: Vec<StrBuf> = args.prog
.as_slice()
.split('/')
.map(|ts| ts.to_strbuf())
.collect();
let prog_short = tvec.pop().unwrap();
// copy to target
let copy_result = procsrv::run("", config.adb_path,
["push".to_owned(), args.prog.clone(), config.adb_test_dir.clone()],
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
let copy_result = procsrv::run("",
config.adb_path.as_slice(),
[
"push".to_strbuf(),
args.prog.clone(),
config.adb_test_dir.clone()
],
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
if config.verbose {
println!("push ({}) {} {} {}",
config.target, args.prog,
copy_result.out, copy_result.err);
config.target,
args.prog,
copy_result.out,
copy_result.err);
}
logv(config, format!("executing ({}) {}", config.target, cmdline));
logv(config, format_strbuf!("executing ({}) {}", config.target, cmdline));
let mut runargs = Vec::new();
// run test via adb_run_wrapper
runargs.push("shell".to_owned());
runargs.push("shell".to_strbuf());
for (key, val) in env.move_iter() {
runargs.push(format!("{}={}", key, val));
runargs.push(format_strbuf!("{}={}", key, val));
}
runargs.push(format!("{}/adb_run_wrapper.sh", config.adb_test_dir));
runargs.push(format!("{}", config.adb_test_dir));
runargs.push(format!("{}", prog_short));
runargs.push(format_strbuf!("{}/adb_run_wrapper.sh",
config.adb_test_dir));
runargs.push(format_strbuf!("{}", config.adb_test_dir));
runargs.push(format_strbuf!("{}", prog_short));
for tv in args.args.iter() {
runargs.push(tv.to_owned());
runargs.push(tv.to_strbuf());
}
procsrv::run("",
config.adb_path,
config.adb_path.as_slice(),
runargs.as_slice(),
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
vec!(("".to_strbuf(), "".to_strbuf())), Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
// get exitcode of result
runargs = Vec::new();
runargs.push("shell".to_owned());
runargs.push("cat".to_owned());
runargs.push(format!("{}/{}.exitcode", config.adb_test_dir, prog_short));
runargs.push("shell".to_strbuf());
runargs.push("cat".to_strbuf());
runargs.push(format_strbuf!("{}/{}.exitcode",
config.adb_test_dir,
prog_short));
let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
procsrv::run("", config.adb_path, runargs.as_slice(), vec!(("".to_owned(),"".to_owned())),
Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
procsrv::run("",
config.adb_path.as_slice(),
runargs.as_slice(),
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
let mut exitcode : int = 0;
for c in exitcode_out.chars() {
let mut exitcode: int = 0;
for c in exitcode_out.as_slice().chars() {
if !c.is_digit() { break; }
exitcode = exitcode * 10 + match c {
'0' .. '9' => c as int - ('0' as int),
@@ -1208,31 +1405,40 @@ fn _arm_exec_compiled_test(config: &Config, props: &TestProps,
// get stdout of result
runargs = Vec::new();
runargs.push("shell".to_owned());
runargs.push("cat".to_owned());
runargs.push(format!("{}/{}.stdout", config.adb_test_dir, prog_short));
runargs.push("shell".to_strbuf());
runargs.push("cat".to_strbuf());
runargs.push(format_strbuf!("{}/{}.stdout",
config.adb_test_dir,
prog_short));
let procsrv::Result{ out: stdout_out, err: _, status: _ } =
procsrv::run("",
config.adb_path,
config.adb_path.as_slice(),
runargs.as_slice(),
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
// get stderr of result
runargs = Vec::new();
runargs.push("shell".to_owned());
runargs.push("cat".to_owned());
runargs.push(format!("{}/{}.stderr", config.adb_test_dir, prog_short));
runargs.push("shell".to_strbuf());
runargs.push("cat".to_strbuf());
runargs.push(format_strbuf!("{}/{}.stderr",
config.adb_test_dir,
prog_short));
let procsrv::Result{ out: stderr_out, err: _, status: _ } =
procsrv::run("",
config.adb_path,
config.adb_path.as_slice(),
runargs.as_slice(),
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
vec!(("".to_strbuf(), "".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`", config.adb_path));
dump_output(config, testfile, stdout_out, stderr_out);
dump_output(config,
testfile,
stdout_out.as_slice(),
stderr_out.as_slice());
ProcRes {
status: process::ExitStatus(exitcode),
@@ -1249,10 +1455,20 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
for file in dirs.iter() {
if file.extension_str() == Some("so") {
// FIXME (#9639): This needs to handle non-utf8 paths
let copy_result = procsrv::run("", config.adb_path,
["push".to_owned(), file.as_str().unwrap().to_owned(), config.adb_test_dir.clone()],
vec!(("".to_owned(),"".to_owned())), Some("".to_owned()))
.expect(format!("failed to exec `{}`", config.adb_path));
let copy_result = procsrv::run("",
config.adb_path.as_slice(),
[
"push".to_strbuf(),
file.as_str()
.unwrap()
.to_strbuf(),
config.adb_test_dir.to_strbuf()
],
vec!(("".to_strbuf(),
"".to_strbuf())),
Some("".to_strbuf()))
.expect(format_strbuf!("failed to exec `{}`",
config.adb_path));
if config.verbose {
println!("push ({}) {} {} {}",
@@ -1282,9 +1498,12 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
testfile: &Path) -> ProcRes {
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
let link_args = vec!("-L".to_owned(), aux_dir.as_str().unwrap().to_owned());
let llvm_args = vec!("--emit=obj".to_owned(), "--crate-type=lib".to_owned(),
"-C".to_owned(), "save-temps".to_owned());
let link_args = vec!("-L".to_strbuf(),
aux_dir.as_str().unwrap().to_strbuf());
let llvm_args = vec!("--emit=obj".to_strbuf(),
"--crate-type=lib".to_strbuf(),
"-C".to_strbuf(),
"save-temps".to_strbuf());
let args = make_compile_args(config,
props,
link_args.append(llvm_args.as_slice()),
@@ -1299,11 +1518,12 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps,
let testcc = testfile.with_extension("cc");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
prog: config.clang_path.get_ref().as_str().unwrap().to_owned(),
args: vec!("-c".to_owned(),
"-emit-llvm".to_owned(),
"-o".to_owned(), bitcodefile.as_str().unwrap().to_owned(),
testcc.as_str().unwrap().to_owned() )
prog: config.clang_path.get_ref().as_str().unwrap().to_strbuf(),
args: vec!("-c".to_strbuf(),
"-emit-llvm".to_strbuf(),
"-o".to_strbuf(),
bitcodefile.as_str().unwrap().to_strbuf(),
testcc.as_str().unwrap().to_strbuf())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
}
@@ -1317,10 +1537,10 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
let prog = config.llvm_bin_path.get_ref().join("llvm-extract");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
prog: prog.as_str().unwrap().to_owned(),
args: vec!("-func=" + fname,
"-o=" + extracted_bc.as_str().unwrap(),
bitcodefile.as_str().unwrap().to_owned() )
prog: prog.as_str().unwrap().to_strbuf(),
args: vec!(format_strbuf!("-func={}", fname),
format_strbuf!("-o={}", extracted_bc.as_str().unwrap()),
bitcodefile.as_str().unwrap().to_strbuf())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
}
@@ -1334,9 +1554,9 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
let prog = config.llvm_bin_path.get_ref().join("llvm-dis");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
prog: prog.as_str().unwrap().to_owned(),
args: vec!("-o=" + extracted_ll.as_str().unwrap(),
extracted_bc.as_str().unwrap().to_owned() )
prog: prog.as_str().unwrap().to_strbuf(),
args: vec!(format_strbuf!("-o={}", extracted_ll.as_str().unwrap()),
extracted_bc.as_str().unwrap().to_strbuf())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None)
}
@@ -1353,42 +1573,44 @@ fn run_codegen_test(config: &Config, props: &TestProps,
testfile: &Path, mm: &mut MetricMap) {
if config.llvm_bin_path.is_none() {
fatal("missing --llvm-bin-path".to_owned());
fatal("missing --llvm-bin-path".to_strbuf());
}
if config.clang_path.is_none() {
fatal("missing --clang-path".to_owned());
fatal("missing --clang-path".to_strbuf());
}
let mut proc_res = compile_test_and_save_bitcode(config, props, testfile);
if !proc_res.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &proc_res);
fatal_ProcRes("compilation failed!".to_strbuf(), &proc_res);
}
proc_res = extract_function_from_bitcode(config, props, "test", testfile, "");
if !proc_res.status.success() {
fatal_ProcRes("extracting 'test' function failed".to_owned(), &proc_res);
fatal_ProcRes("extracting 'test' function failed".to_strbuf(),
&proc_res);
}
proc_res = disassemble_extract(config, props, testfile, "");
if !proc_res.status.success() {
fatal_ProcRes("disassembling extract failed".to_owned(), &proc_res);
fatal_ProcRes("disassembling extract failed".to_strbuf(), &proc_res);
}
let mut proc_res = compile_cc_with_clang_and_save_bitcode(config, props, testfile);
if !proc_res.status.success() {
fatal_ProcRes("compilation failed!".to_owned(), &proc_res);
fatal_ProcRes("compilation failed!".to_strbuf(), &proc_res);
}
proc_res = extract_function_from_bitcode(config, props, "test", testfile, "clang");
if !proc_res.status.success() {
fatal_ProcRes("extracting 'test' function failed".to_owned(), &proc_res);
fatal_ProcRes("extracting 'test' function failed".to_strbuf(),
&proc_res);
}
proc_res = disassemble_extract(config, props, testfile, "clang");
if !proc_res.status.success() {
fatal_ProcRes("disassembling extract failed".to_owned(), &proc_res);
fatal_ProcRes("disassembling extract failed".to_strbuf(), &proc_res);
}
let base = output_base_name(config, testfile);
+7 -7
View File
@@ -33,25 +33,25 @@ pub fn get_os(triple: &str) -> &'static str {
}
#[cfg(target_os = "win32")]
pub fn make_new_path(path: &str) -> ~str {
pub fn make_new_path(path: &str) -> StrBuf {
// Windows just uses PATH as the library search path, so we have to
// maintain the current value while adding our own
match getenv(lib_path_env_var()) {
match getenv(lib_path_env_var().as_slice()) {
Some(curr) => {
format!("{}{}{}", path, path_div(), curr)
format_strbuf!("{}{}{}", path, path_div(), curr)
}
None => path.to_str()
None => path.to_str().to_strbuf()
}
}
#[cfg(target_os = "win32")]
pub fn lib_path_env_var() -> ~str { "PATH".to_owned() }
pub fn lib_path_env_var() -> StrBuf { "PATH".to_strbuf() }
#[cfg(target_os = "win32")]
pub fn path_div() -> ~str { ";".to_owned() }
pub fn path_div() -> StrBuf { ";".to_strbuf() }
pub fn logv(config: &Config, s: ~str) {
pub fn logv(config: &Config, s: StrBuf) {
debug!("{}", s);
if config.verbose { println!("{}", s); }
}
+13 -12
View File
@@ -8,7 +8,7 @@ Use [`ToStr`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToStr.html
~~~
let x: int = 42;
let y: ~str = x.to_str();
let y: StrBuf = x.to_str().to_strbuf();
~~~
**String to int**
@@ -22,14 +22,14 @@ let y: int = x.unwrap();
**Int to string, in non-base-10**
Use the `format!` syntax extension.
Use the `format_strbuf!` syntax extension.
~~~
let x: int = 42;
let y: ~str = format!("{:t}", x); // binary
let y: ~str = format!("{:o}", x); // octal
let y: ~str = format!("{:x}", x); // lowercase hexadecimal
let y: ~str = format!("{:X}", x); // uppercase hexadecimal
let y: StrBuf = format_strbuf!("{:t}", x); // binary
let y: StrBuf = format_strbuf!("{:o}", x); // octal
let y: StrBuf = format_strbuf!("{:x}", x); // lowercase hexadecimal
let y: StrBuf = format_strbuf!("{:X}", x); // uppercase hexadecimal
~~~
**String to int, in non-base-10**
@@ -55,13 +55,14 @@ let x: Option<&str> = str::from_utf8(bytes);
let y: &str = x.unwrap();
~~~
To return an Owned String (~str) use the str helper function [`from_utf8_owned`](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8_owned.html).
To return an Owned String (StrBuf) use the str helper function [`from_utf8_owned`](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8_owned.html).
~~~
use std::str;
let x: Result<~str,~[u8]> = str::from_utf8_owned(~[104u8,105u8]);
let y: ~str = x.unwrap();
let x: Result<StrBuf,~[u8]> =
str::from_utf8_owned(~[104u8,105u8]).map(|x| x.to_strbuf());
let y: StrBuf = x.unwrap();
~~~
To return a [`MaybeOwned`](http://static.rust-lang.org/doc/master/std/str/enum.MaybeOwned.html) use the str helper function [`from_utf8_lossy`](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8_owned.html). This function also replaces non-valid utf-8 sequences with U+FFFD replacement character.
@@ -181,7 +182,7 @@ enum Closed {}
Phantom types are useful for enforcing state at compile time. For example:
~~~
struct Door<State>(~str);
struct Door<State>(StrBuf);
struct Open;
struct Closed;
@@ -194,13 +195,13 @@ fn open(Door(name): Door<Closed>) -> Door<Open> {
Door::<Open>(name)
}
let _ = close(Door::<Open>("front".to_owned()));
let _ = close(Door::<Open>("front".to_strbuf()));
~~~
Attempting to close a closed door is prevented statically:
~~~ {.ignore}
let _ = close(Door::<Closed>("front".to_owned())); // error: mismatched types: expected `main::Door<main::Open>` but found `main::Door<main::Closed>`
let _ = close(Door::<Closed>("front".to_strbuf())); // error: mismatched types: expected `main::Door<main::Open>` but found `main::Door<main::Closed>`
~~~
# FFI (Foreign Function Interface)
+1 -1
View File
@@ -85,7 +85,7 @@ To take as an argument a fragment of Rust code, write `$` followed by a name
`foo`.)
* `expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`;
`f(42)`.)
* `ty` (a type. Examples: `int`, `~[(char, ~str)]`, `&T`.)
* `ty` (a type. Examples: `int`, `~[(char, StrBuf)]`, `&T`.)
* `pat` (a pattern, usually appearing in a `match` or on the left-hand side of
a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.)
* `block` (a sequence of actions. Example: `{ log(error, "hi"); return 12; }`)
+7 -7
View File
@@ -463,11 +463,11 @@ Here is the function that implements the child task:
~~~
extern crate sync;
# fn main() {
fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
fn stringifier(channel: &sync::DuplexStream<StrBuf, uint>) {
let mut value: uint;
loop {
value = channel.recv();
channel.send(value.to_str());
channel.send(value.to_str().to_strbuf());
if value == 0 { break; }
}
}
@@ -488,11 +488,11 @@ Here is the code for the parent task:
extern crate sync;
# use std::task::spawn;
# use sync::DuplexStream;
# fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
# fn stringifier(channel: &sync::DuplexStream<StrBuf, uint>) {
# let mut value: uint;
# loop {
# value = channel.recv();
# channel.send(value.to_str());
# channel.send(value.to_str().to_strbuf());
# if value == 0u { break; }
# }
# }
@@ -505,13 +505,13 @@ spawn(proc() {
});
from_child.send(22);
assert!(from_child.recv() == "22".to_owned());
assert!(from_child.recv().as_slice() == "22");
from_child.send(23);
from_child.send(0);
assert!(from_child.recv() == "23".to_owned());
assert!(from_child.recv() == "0".to_owned());
assert!(from_child.recv().as_slice() == "23");
assert!(from_child.recv().as_slice() == "0");
# }
~~~
+2 -2
View File
@@ -34,7 +34,7 @@ msgstr ""
#, fuzzy
#| msgid ""
#| "~~~~ let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
msgid "~~~ let x: int = 42; let y: ~str = x.to_str(); ~~~"
msgid "~~~ let x: int = 42; let y: StrBuf = x.to_str(); ~~~"
msgstr ""
"~~~~\n"
"let x: f64 = 4.0;\n"
@@ -96,7 +96,7 @@ msgstr ""
#, fuzzy
#| msgid ""
#| "~~~~ let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
msgid "let x: int = 42; let y: ~str = x.to_str_radix(16); ~~~"
msgid "let x: int = 42; let y: StrBuf = x.to_str_radix(16); ~~~"
msgstr ""
"~~~~\n"
"let x: f64 = 4.0;\n"
+5 -5
View File
@@ -1641,7 +1641,7 @@ msgstr "## 最小限の例"
msgid ""
"~~~~\n"
"trait Printable {\n"
" fn to_string(&self) -> ~str;\n"
" fn to_string(&self) -> StrBuf;\n"
"}\n"
msgstr ""
"~~~~ {.ignore}\n"
@@ -1656,7 +1656,7 @@ msgstr ""
#| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"impl Printable for int {\n"
" fn to_string(&self) -> ~str { self.to_str() }\n"
" fn to_string(&self) -> StrBuf { self.to_str() }\n"
"}\n"
msgstr ""
"~~~~ {.ignore}\n"
@@ -1702,7 +1702,7 @@ msgstr "# クロージャ"
msgid ""
"~~~~\n"
"trait Printable {\n"
" fn make_string(&self) -> ~str;\n"
" fn make_string(&self) -> StrBuf;\n"
"}\n"
msgstr ""
"~~~~ {.ignore}\n"
@@ -1716,8 +1716,8 @@ msgstr ""
#, fuzzy, no-wrap
#| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"impl Printable for ~str {\n"
" fn make_string(&self) -> ~str {\n"
"impl Printable for StrBuf {\n"
" fn make_string(&self) -> StrBuf {\n"
" (*self).clone()\n"
" }\n"
"}\n"
+4 -4
View File
@@ -3755,15 +3755,15 @@ msgstr ""
#| msgid ""
#| "Traits may be implemented for specific types with [impls]. An impl that "
#| "implements a trait includes the name of the trait at the start of the "
#| "definition, as in the following impls of `Printable` for `int` and `~str`."
#| "definition, as in the following impls of `Printable` for `int` and `StrBuf`."
msgid ""
"Traits may be implemented for specific types with [impls]. An impl for a "
"particular trait gives an implementation of the methods that trait "
"provides. For instance, the following impls of `Printable` for `int` and "
"`~str` give implementations of the `print` method."
"`StrBuf` give implementations of the `print` method."
msgstr ""
"[impl][impls] により特定の型にトレイトを実装することができます。トレイトを実"
"装する impl は、以下の `Printable` の `int` と `~str` に対する実装のように、"
"装する impl は、以下の `Printable` の `int` と `StrBuf` に対する実装のように、"
"定義の先頭にトレイトの名前を含みます。"
#. type: Plain text
@@ -3776,7 +3776,7 @@ msgstr "[impls]: #メソッド"
#, fuzzy, no-wrap
#| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"impl Printable for ~str {\n"
"impl Printable for StrBuf {\n"
" fn print(&self) { println!(\"{}\", *self) }\n"
"}\n"
msgstr ""
+13 -13
View File
@@ -473,7 +473,7 @@ Two examples of paths with type arguments:
# struct HashMap<K, V>;
# fn f() {
# fn id<T>(t: T) -> T { t }
type T = HashMap<int,~str>; // Type arguments used in a type expression
type T = HashMap<int,StrBuf>; // Type arguments used in a type expression
let x = id::<int>(10); // Type arguments used in a call expression
# }
~~~~
@@ -1259,12 +1259,12 @@ Enumeration constructors can have either named or unnamed fields:
~~~~
enum Animal {
Dog (~str, f64),
Cat { name: ~str, weight: f64 }
Dog (StrBuf, f64),
Cat { name: StrBuf, weight: f64 }
}
let mut a: Animal = Dog("Cocoa".to_owned(), 37.2);
a = Cat{ name: "Spotty".to_owned(), weight: 2.7 };
let mut a: Animal = Dog("Cocoa".to_strbuf(), 37.2);
a = Cat { name: "Spotty".to_strbuf(), weight: 2.7 };
~~~~
In this example, `Cat` is a _struct-like enum variant_,
@@ -2081,7 +2081,7 @@ These are functions:
* `str_eq`
: Compare two strings (`&str`) for equality.
* `uniq_str_eq`
: Compare two owned strings (`~str`) for equality.
: Compare two owned strings (`StrBuf`) for equality.
* `strdup_uniq`
: Return a new unique string
containing a copy of the contents of a unique string.
@@ -3309,7 +3309,7 @@ A value of type `str` is a Unicode string,
represented as a vector of 8-bit unsigned bytes holding a sequence of UTF-8 codepoints.
Since `str` is of unknown size, it is not a _first class_ type,
but can only be instantiated through a pointer type,
such as `&str` or `~str`.
such as `&str` or `StrBuf`.
### Tuple types
@@ -3573,11 +3573,11 @@ An example of an object type:
~~~~
trait Printable {
fn to_string(&self) -> ~str;
fn to_string(&self) -> StrBuf;
}
impl Printable for int {
fn to_string(&self) -> ~str { self.to_str() }
fn to_string(&self) -> StrBuf { self.to_str().to_strbuf() }
}
fn print(a: Box<Printable>) {
@@ -3618,17 +3618,17 @@ example, in:
~~~~
trait Printable {
fn make_string(&self) -> ~str;
fn make_string(&self) -> StrBuf;
}
impl Printable for ~str {
fn make_string(&self) -> ~str {
impl Printable for StrBuf {
fn make_string(&self) -> StrBuf {
(*self).clone()
}
}
~~~~
`self` refers to the value of type `~str` that is the receiver for a
`self` refers to the value of type `StrBuf` that is the receiver for a
call to the method `make_string`.
## Type kinds
+1 -1
View File
@@ -26,7 +26,7 @@ comments":
pub struct Widget {
/// All widgets have a purpose (this is a doc comment, and will show up
/// the field's documentation).
purpose: ~str,
purpose: StrBuf,
/// Humans are not allowed to understand some widgets
understandable: bool
}
+6 -6
View File
@@ -2213,7 +2213,7 @@ don't provide any methods.
Traits may be implemented for specific types with [impls]. An impl for
a particular trait gives an implementation of the methods that
trait provides. For instance, the following impls of
`Printable` for `int` and `~str` give implementations of the `print`
`Printable` for `int` and `StrBuf` give implementations of the `print`
method.
[impls]: #methods
@@ -2224,12 +2224,12 @@ impl Printable for int {
fn print(&self) { println!("{:?}", *self) }
}
impl Printable for ~str {
impl Printable for StrBuf {
fn print(&self) { println!("{}", *self) }
}
# 1.print();
# ("foo".to_owned()).print();
# ("foo".to_strbuf()).print();
~~~~
Methods defined in an impl for a trait may be called just like
@@ -2270,7 +2270,7 @@ trait Printable {
impl Printable for int {}
impl Printable for ~str {
impl Printable for StrBuf {
fn print(&self) { println!("{}", *self) }
}
@@ -2279,7 +2279,7 @@ impl Printable for bool {}
impl Printable for f32 {}
# 1.print();
# ("foo".to_owned()).print();
# ("foo".to_strbuf()).print();
# true.print();
# 3.14159.print();
~~~~
@@ -2291,7 +2291,7 @@ provided in the trait definition. Depending on the trait, default
methods can save a great deal of boilerplate code from having to be
written in impls. Of course, individual impls can still override the
default method for `print`, as is being done above in the impl for
`~str`.
`StrBuf`.
## Type-parameterized traits
+3 -3
View File
@@ -203,7 +203,7 @@ pub struct Parser<'a> {
cur: str::CharOffsets<'a>,
depth: uint,
/// Error messages accumulated during parsing
pub errors: Vec<~str>,
pub errors: Vec<StrBuf>,
}
impl<'a> Iterator<Piece<'a>> for Parser<'a> {
@@ -246,10 +246,10 @@ pub fn new<'a>(s: &'a str) -> Parser<'a> {
}
/// Notifies of an error. The message doesn't actually need to be of type
/// ~str, but I think it does when this eventually uses conditions so it
/// StrBuf, but I think it does when this eventually uses conditions so it
/// might as well start using it now.
fn err(&mut self, msg: &str) {
self.errors.push(msg.to_owned());
self.errors.push(msg.to_strbuf());
}
/// Optionally consumes the specified character. If the character is not at
+227 -204
View File
@@ -34,7 +34,7 @@
//! use getopts::{optopt,optflag,getopts,OptGroup};
//! use std::os;
//!
//! fn do_work(inp: &str, out: Option<~str>) {
//! fn do_work(inp: &str, out: Option<StrBuf>) {
//! println!("{}", inp);
//! match out {
//! Some(x) => println!("{}", x),
@@ -49,7 +49,9 @@
//! }
//!
//! fn main() {
//! let args = os::args();
//! let args: Vec<StrBuf> = os::args().iter()
//! .map(|x| x.to_strbuf())
//! .collect();
//!
//! let program = args.get(0).clone();
//!
@@ -62,17 +64,17 @@
//! Err(f) => { fail!(f.to_err_msg()) }
//! };
//! if matches.opt_present("h") {
//! print_usage(program, opts);
//! print_usage(program.as_slice(), opts);
//! return;
//! }
//! let output = matches.opt_str("o");
//! let input: &str = if !matches.free.is_empty() {
//! let input = if !matches.free.is_empty() {
//! (*matches.free.get(0)).clone()
//! } else {
//! print_usage(program, opts);
//! print_usage(program.as_slice(), opts);
//! return;
//! };
//! do_work(input, output);
//! do_work(input.as_slice(), output);
//! }
//! ~~~
@@ -99,7 +101,7 @@
pub enum Name {
/// A string representing the long name of an option.
/// For example: "help"
Long(~str),
Long(StrBuf),
/// A char representing the short name of an option.
/// For example: 'h'
Short(char),
@@ -145,13 +147,13 @@ pub struct Opt {
#[deriving(Clone, Eq)]
pub struct OptGroup {
/// Short Name of the `OptGroup`
pub short_name: ~str,
pub short_name: StrBuf,
/// Long Name of the `OptGroup`
pub long_name: ~str,
pub long_name: StrBuf,
/// Hint
pub hint: ~str,
pub hint: StrBuf,
/// Description
pub desc: ~str,
pub desc: StrBuf,
/// Whether it has an argument
pub hasarg: HasArg,
/// How often it can occur
@@ -161,7 +163,7 @@ pub struct OptGroup {
/// Describes wether an option is given at all or has a value.
#[deriving(Clone, Eq)]
enum Optval {
Val(~str),
Val(StrBuf),
Given,
}
@@ -174,7 +176,7 @@ pub struct Matches {
/// Values of the Options that matched
vals: Vec<Vec<Optval> > ,
/// Free string fragments
pub free: Vec<~str>,
pub free: Vec<StrBuf>,
}
/// The type returned when the command line does not conform to the
@@ -183,15 +185,15 @@ pub struct Matches {
#[deriving(Clone, Eq, Show)]
pub enum Fail_ {
/// The option requires an argument but none was passed.
ArgumentMissing(~str),
ArgumentMissing(StrBuf),
/// The passed option is not declared among the possible options.
UnrecognizedOption(~str),
UnrecognizedOption(StrBuf),
/// A required option is not present.
OptionMissing(~str),
OptionMissing(StrBuf),
/// A single occurence option is being used multiple times.
OptionDuplicated(~str),
OptionDuplicated(StrBuf),
/// There's an argument being passed to a non-argument option.
UnexpectedArgument(~str),
UnexpectedArgument(StrBuf),
}
/// The type of failure that occurred.
@@ -213,14 +215,14 @@ fn from_str(nm: &str) -> Name {
if nm.len() == 1u {
Short(nm.char_at(0u))
} else {
Long(nm.to_owned())
Long(nm.to_strbuf())
}
}
fn to_str(&self) -> ~str {
fn to_str(&self) -> StrBuf {
match *self {
Short(ch) => ch.to_str(),
Long(ref s) => s.to_owned()
Short(ch) => ch.to_str().to_strbuf(),
Long(ref s) => s.to_strbuf()
}
}
}
@@ -246,7 +248,7 @@ pub fn long_to_short(&self) -> Opt {
aliases: Vec::new()
},
(1,0) => Opt {
name: Short(short_name.char_at(0)),
name: Short(short_name.as_slice().char_at(0)),
hasarg: hasarg,
occur: occur,
aliases: Vec::new()
@@ -257,7 +259,7 @@ pub fn long_to_short(&self) -> Opt {
occur: occur,
aliases: vec!(
Opt {
name: Short(short_name.char_at(0)),
name: Short(short_name.as_slice().char_at(0)),
hasarg: hasarg,
occur: occur,
aliases: Vec::new()
@@ -297,9 +299,10 @@ pub fn opt_count(&self, nm: &str) -> uint {
}
/// Returns true if any of several options were matched.
pub fn opts_present(&self, names: &[~str]) -> bool {
pub fn opts_present(&self, names: &[StrBuf]) -> bool {
for nm in names.iter() {
match find_opt(self.opts.as_slice(), Name::from_str(*nm)) {
match find_opt(self.opts.as_slice(),
Name::from_str(nm.as_slice())) {
Some(id) if !self.vals.get(id).is_empty() => return true,
_ => (),
};
@@ -308,9 +311,9 @@ pub fn opts_present(&self, names: &[~str]) -> bool {
}
/// Returns the string argument supplied to one of several matching options or `None`.
pub fn opts_str(&self, names: &[~str]) -> Option<~str> {
pub fn opts_str(&self, names: &[StrBuf]) -> Option<StrBuf> {
for nm in names.iter() {
match self.opt_val(*nm) {
match self.opt_val(nm.as_slice()) {
Some(Val(ref s)) => return Some(s.clone()),
_ => ()
}
@@ -322,8 +325,8 @@ pub fn opts_str(&self, names: &[~str]) -> Option<~str> {
/// option.
///
/// Used when an option accepts multiple values.
pub fn opt_strs(&self, nm: &str) -> Vec<~str> {
let mut acc: Vec<~str> = Vec::new();
pub fn opt_strs(&self, nm: &str) -> Vec<StrBuf> {
let mut acc: Vec<StrBuf> = Vec::new();
let r = self.opt_vals(nm);
for v in r.iter() {
match *v {
@@ -335,10 +338,10 @@ pub fn opt_strs(&self, nm: &str) -> Vec<~str> {
}
/// Returns the string argument supplied to a matching option or `None`.
pub fn opt_str(&self, nm: &str) -> Option<~str> {
pub fn opt_str(&self, nm: &str) -> Option<StrBuf> {
let vals = self.opt_vals(nm);
if vals.is_empty() {
return None::<~str>;
return None::<StrBuf>;
}
match vals.get(0) {
&Val(ref s) => Some((*s).clone()),
@@ -352,12 +355,14 @@ pub fn opt_str(&self, nm: &str) -> Option<~str> {
/// Returns none if the option was not present, `def` if the option was
/// present but no argument was provided, and the argument if the option was
/// present and an argument was provided.
pub fn opt_default(&self, nm: &str, def: &str) -> Option<~str> {
pub fn opt_default(&self, nm: &str, def: &str) -> Option<StrBuf> {
let vals = self.opt_vals(nm);
if vals.is_empty() { return None; }
if vals.is_empty() {
return None;
}
match vals.get(0) {
&Val(ref s) => Some((*s).clone()),
_ => Some(def.to_owned())
_ => Some(def.to_strbuf())
}
}
@@ -389,10 +394,10 @@ pub fn reqopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptG
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: hint.to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: hint.to_strbuf(),
desc: desc.to_strbuf(),
hasarg: Yes,
occur: Req
}
@@ -403,10 +408,10 @@ pub fn optopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptG
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: hint.to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: hint.to_strbuf(),
desc: desc.to_strbuf(),
hasarg: Yes,
occur: Optional
}
@@ -417,10 +422,10 @@ pub fn optflag(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: "".to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: "".to_strbuf(),
desc: desc.to_strbuf(),
hasarg: No,
occur: Optional
}
@@ -432,10 +437,10 @@ pub fn optflagmulti(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: "".to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: "".to_strbuf(),
desc: desc.to_strbuf(),
hasarg: No,
occur: Multi
}
@@ -446,10 +451,10 @@ pub fn optflagopt(short_name: &str, long_name: &str, desc: &str, hint: &str) ->
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: hint.to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: hint.to_strbuf(),
desc: desc.to_strbuf(),
hasarg: Maybe,
occur: Optional
}
@@ -461,10 +466,10 @@ pub fn optmulti(short_name: &str, long_name: &str, desc: &str, hint: &str) -> Op
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: hint.to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: hint.to_strbuf(),
desc: desc.to_strbuf(),
hasarg: Yes,
occur: Multi
}
@@ -480,10 +485,10 @@ pub fn opt(short_name: &str,
let len = short_name.len();
assert!(len == 1 || len == 0);
OptGroup {
short_name: short_name.to_owned(),
long_name: long_name.to_owned(),
hint: hint.to_owned(),
desc: desc.to_owned(),
short_name: short_name.to_strbuf(),
long_name: long_name.to_strbuf(),
hint: hint.to_strbuf(),
desc: desc.to_strbuf(),
hasarg: hasarg,
occur: occur
}
@@ -491,22 +496,22 @@ pub fn opt(short_name: &str,
impl Fail_ {
/// Convert a `Fail_` enum into an error string.
pub fn to_err_msg(self) -> ~str {
pub fn to_err_msg(self) -> StrBuf {
match self {
ArgumentMissing(ref nm) => {
format!("Argument to option '{}' missing.", *nm)
format_strbuf!("Argument to option '{}' missing.", *nm)
}
UnrecognizedOption(ref nm) => {
format!("Unrecognized option: '{}'.", *nm)
format_strbuf!("Unrecognized option: '{}'.", *nm)
}
OptionMissing(ref nm) => {
format!("Required option '{}' missing.", *nm)
format_strbuf!("Required option '{}' missing.", *nm)
}
OptionDuplicated(ref nm) => {
format!("Option '{}' given more than once.", *nm)
format_strbuf!("Option '{}' given more than once.", *nm)
}
UnexpectedArgument(ref nm) => {
format!("Option '{}' does not take an argument.", *nm)
format_strbuf!("Option '{}' does not take an argument.", *nm)
}
}
}
@@ -517,44 +522,44 @@ pub fn to_err_msg(self) -> ~str {
/// On success returns `Ok(Opt)`. Use methods such as `opt_present`
/// `opt_str`, etc. to interrogate results. Returns `Err(Fail_)` on failure.
/// Use `to_err_msg` to get an error message.
pub fn getopts(args: &[~str], optgrps: &[OptGroup]) -> Result {
pub fn getopts(args: &[StrBuf], optgrps: &[OptGroup]) -> Result {
let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();
let n_opts = opts.len();
fn f(_x: uint) -> Vec<Optval> { return Vec::new(); }
let mut vals = Vec::from_fn(n_opts, f);
let mut free: Vec<~str> = Vec::new();
let mut free: Vec<StrBuf> = Vec::new();
let l = args.len();
let mut i = 0;
while i < l {
let cur = args[i].clone();
let curlen = cur.len();
if !is_arg(cur) {
if !is_arg(cur.as_slice()) {
free.push(cur);
} else if cur == "--".to_owned() {
} else if cur.as_slice() == "--" {
let mut j = i + 1;
while j < l { free.push(args[j].clone()); j += 1; }
break;
} else {
let mut names;
let mut i_arg = None;
if cur[1] == '-' as u8 {
let tail = cur.slice(2, curlen);
if cur.as_slice()[1] == '-' as u8 {
let tail = cur.as_slice().slice(2, curlen);
let tail_eq: Vec<&str> = tail.split('=').collect();
if tail_eq.len() <= 1 {
names = vec!(Long(tail.to_owned()));
names = vec!(Long(tail.to_strbuf()));
} else {
names =
vec!(Long((*tail_eq.get(0)).to_owned()));
i_arg = Some((*tail_eq.get(1)).to_owned());
vec!(Long((*tail_eq.get(0)).to_strbuf()));
i_arg = Some((*tail_eq.get(1)).to_strbuf());
}
} else {
let mut j = 1;
let mut last_valid_opt_id = None;
names = Vec::new();
while j < curlen {
let range = cur.char_range_at(j);
let range = cur.as_slice().char_range_at(j);
let opt = Short(range.ch);
/* In a series of potential options (eg. -aheJ), if we
@@ -576,7 +581,8 @@ pub fn getopts(args: &[~str], optgrps: &[OptGroup]) -> Result {
No => false
};
if arg_follows && j < curlen {
i_arg = Some(cur.slice(j, curlen).to_owned());
i_arg = Some(cur.as_slice()
.slice(j, curlen).to_strbuf());
break;
} else {
last_valid_opt_id = None;
@@ -606,8 +612,8 @@ pub fn getopts(args: &[~str], optgrps: &[OptGroup]) -> Result {
vals.get_mut(optid)
.push(Val((i_arg.clone())
.unwrap()));
} else if name_pos < names.len() ||
i + 1 == l || is_arg(args[i + 1]) {
} else if name_pos < names.len() || i + 1 == l ||
is_arg(args[i + 1].as_slice()) {
vals.get_mut(optid).push(Given);
} else {
i += 1;
@@ -653,7 +659,7 @@ pub fn getopts(args: &[~str], optgrps: &[OptGroup]) -> Result {
}
/// Derive a usage message from a set of long options.
pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
pub fn usage(brief: &str, opts: &[OptGroup]) -> StrBuf {
let desc_sep = "\n" + " ".repeat(24);
@@ -672,7 +678,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
0 => {}
1 => {
row.push_char('-');
row.push_str(short_name);
row.push_str(short_name.as_slice());
row.push_char(' ');
}
_ => fail!("the short name should only be 1 ascii char long"),
@@ -683,7 +689,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
0 => {}
_ => {
row.push_str("--");
row.push_str(long_name);
row.push_str(long_name.as_slice());
row.push_char(' ');
}
}
@@ -691,10 +697,10 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
// arg
match hasarg {
No => {}
Yes => row.push_str(hint),
Yes => row.push_str(hint.as_slice()),
Maybe => {
row.push_char('[');
row.push_str(hint);
row.push_str(hint.as_slice());
row.push_char(']');
}
}
@@ -712,7 +718,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
// Normalize desc to contain words separated by one space character
let mut desc_normalized_whitespace = StrBuf::new();
for word in desc.words() {
for word in desc.as_slice().words() {
desc_normalized_whitespace.push_str(word);
desc_normalized_whitespace.push_char(' ');
}
@@ -730,13 +736,15 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
// wrapped description
row.push_str(desc_rows.connect(desc_sep));
row.into_owned()
row
});
format!("{}\n\nOptions:\n{}\n", brief, rows.collect::<Vec<~str> >().connect("\n"))
format_strbuf!("{}\n\nOptions:\n{}\n",
brief,
rows.collect::<Vec<StrBuf>>().connect("\n"))
}
fn format_option(opt: &OptGroup) -> ~str {
fn format_option(opt: &OptGroup) -> StrBuf {
let mut line = StrBuf::new();
if opt.occur != Req {
@@ -746,10 +754,10 @@ fn format_option(opt: &OptGroup) -> ~str {
// Use short_name is possible, but fallback to long_name.
if opt.short_name.len() > 0 {
line.push_char('-');
line.push_str(opt.short_name);
line.push_str(opt.short_name.as_slice());
} else {
line.push_str("--");
line.push_str(opt.long_name);
line.push_str(opt.long_name.as_slice());
}
if opt.hasarg != No {
@@ -757,7 +765,7 @@ fn format_option(opt: &OptGroup) -> ~str {
if opt.hasarg == Maybe {
line.push_char('[');
}
line.push_str(opt.hint);
line.push_str(opt.hint.as_slice());
if opt.hasarg == Maybe {
line.push_char(']');
}
@@ -770,14 +778,14 @@ fn format_option(opt: &OptGroup) -> ~str {
line.push_str("..");
}
line.into_owned()
line
}
/// Derive a short one-line usage summary from a set of long options.
pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> ~str {
let mut line = StrBuf::from_str("Usage: " + program_name + " ");
line.push_str(opts.iter().map(format_option).collect::<Vec<~str>>().connect(" "));
line.into_owned()
pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> StrBuf {
let mut line = format_strbuf!("Usage: {} ", program_name);
line.push_str(opts.iter().map(format_option).collect::<Vec<StrBuf>>().connect(" "));
line
}
@@ -886,18 +894,21 @@ enum LengthLimit {
#[test]
fn test_split_within() {
fn t(s: &str, i: uint, u: &[~str]) {
fn t(s: &str, i: uint, u: &[StrBuf]) {
let mut v = Vec::new();
each_split_within(s, i, |s| { v.push(s.to_owned()); true });
each_split_within(s, i, |s| { v.push(s.to_strbuf()); true });
assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
}
t("", 0, []);
t("", 15, []);
t("hello", 15, ["hello".to_owned()]);
t("\nMary had a little lamb\nLittle lamb\n", 15,
["Mary had a".to_owned(), "little lamb".to_owned(), "Little lamb".to_owned()]);
t("hello", 15, ["hello".to_strbuf()]);
t("\nMary had a little lamb\nLittle lamb\n", 15, [
"Mary had a".to_strbuf(),
"little lamb".to_strbuf(),
"Little lamb".to_strbuf()
]);
t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX,
["Mary had a little lamb\nLittle lamb".to_owned()]);
["Mary had a little lamb\nLittle lamb".to_strbuf()]);
}
#[cfg(test)]
@@ -920,25 +931,25 @@ fn check_fail_type(f: Fail_, ft: FailType) {
// Tests for reqopt
#[test]
fn test_reqopt() {
let long_args = vec!("--test=20".to_owned());
let long_args = vec!("--test=20".to_strbuf());
let opts = vec!(reqopt("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
assert!(m.opt_present("test"));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!(m.opt_present("t"));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => { fail!("test_reqopt failed (long arg)"); }
}
let short_args = vec!("-t".to_owned(), "20".to_owned());
let short_args = vec!("-t".to_strbuf(), "20".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Ok(ref m) => {
assert!((m.opt_present("test")));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!((m.opt_present("t")));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => { fail!("test_reqopt failed (short arg)"); }
}
@@ -946,7 +957,7 @@ fn test_reqopt() {
#[test]
fn test_reqopt_missing() {
let args = vec!("blah".to_owned());
let args = vec!("blah".to_strbuf());
let opts = vec!(reqopt("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -957,14 +968,14 @@ fn test_reqopt_missing() {
#[test]
fn test_reqopt_no_arg() {
let long_args = vec!("--test".to_owned());
let long_args = vec!("--test".to_strbuf());
let opts = vec!(reqopt("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
}
let short_args = vec!("-t".to_owned());
let short_args = vec!("-t".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
@@ -973,7 +984,7 @@ fn test_reqopt_no_arg() {
#[test]
fn test_reqopt_multi() {
let args = vec!("--test=20".to_owned(), "-t".to_owned(), "30".to_owned());
let args = vec!("--test=20".to_strbuf(), "-t".to_strbuf(), "30".to_strbuf());
let opts = vec!(reqopt("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -985,25 +996,25 @@ fn test_reqopt_multi() {
// Tests for optopt
#[test]
fn test_optopt() {
let long_args = vec!("--test=20".to_owned());
let long_args = vec!("--test=20".to_strbuf());
let opts = vec!(optopt("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
assert!(m.opt_present("test"));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!((m.opt_present("t")));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => fail!()
}
let short_args = vec!("-t".to_owned(), "20".to_owned());
let short_args = vec!("-t".to_strbuf(), "20".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Ok(ref m) => {
assert!((m.opt_present("test")));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!((m.opt_present("t")));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => fail!()
}
@@ -1011,7 +1022,7 @@ fn test_optopt() {
#[test]
fn test_optopt_missing() {
let args = vec!("blah".to_owned());
let args = vec!("blah".to_strbuf());
let opts = vec!(optopt("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1025,14 +1036,14 @@ fn test_optopt_missing() {
#[test]
fn test_optopt_no_arg() {
let long_args = vec!("--test".to_owned());
let long_args = vec!("--test".to_strbuf());
let opts = vec!(optopt("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
}
let short_args = vec!("-t".to_owned());
let short_args = vec!("-t".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
@@ -1041,7 +1052,7 @@ fn test_optopt_no_arg() {
#[test]
fn test_optopt_multi() {
let args = vec!("--test=20".to_owned(), "-t".to_owned(), "30".to_owned());
let args = vec!("--test=20".to_strbuf(), "-t".to_strbuf(), "30".to_strbuf());
let opts = vec!(optopt("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1053,7 +1064,7 @@ fn test_optopt_multi() {
// Tests for optflag
#[test]
fn test_optflag() {
let long_args = vec!("--test".to_owned());
let long_args = vec!("--test".to_strbuf());
let opts = vec!(optflag("t", "test", "testing"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
@@ -1063,7 +1074,7 @@ fn test_optflag() {
}
_ => fail!()
}
let short_args = vec!("-t".to_owned());
let short_args = vec!("-t".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Ok(ref m) => {
assert!(m.opt_present("test"));
@@ -1075,7 +1086,7 @@ fn test_optflag() {
#[test]
fn test_optflag_missing() {
let args = vec!("blah".to_owned());
let args = vec!("blah".to_strbuf());
let opts = vec!(optflag("t", "test", "testing"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1089,7 +1100,7 @@ fn test_optflag_missing() {
#[test]
fn test_optflag_long_arg() {
let args = vec!("--test=20".to_owned());
let args = vec!("--test=20".to_strbuf());
let opts = vec!(optflag("t", "test", "testing"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1103,7 +1114,7 @@ fn test_optflag_long_arg() {
#[test]
fn test_optflag_multi() {
let args = vec!("--test".to_owned(), "-t".to_owned());
let args = vec!("--test".to_strbuf(), "-t".to_strbuf());
let opts = vec!(optflag("t", "test", "testing"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1114,14 +1125,14 @@ fn test_optflag_multi() {
#[test]
fn test_optflag_short_arg() {
let args = vec!("-t".to_owned(), "20".to_owned());
let args = vec!("-t".to_strbuf(), "20".to_strbuf());
let opts = vec!(optflag("t", "test", "testing"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
// The next variable after the flag is just a free argument
assert!(*m.free.get(0) == "20".to_owned());
assert!(*m.free.get(0) == "20".to_strbuf());
}
_ => fail!()
}
@@ -1130,7 +1141,7 @@ fn test_optflag_short_arg() {
// Tests for optflagmulti
#[test]
fn test_optflagmulti_short1() {
let args = vec!("-v".to_owned());
let args = vec!("-v".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1143,7 +1154,7 @@ fn test_optflagmulti_short1() {
#[test]
fn test_optflagmulti_short2a() {
let args = vec!("-v".to_owned(), "-v".to_owned());
let args = vec!("-v".to_strbuf(), "-v".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1156,7 +1167,7 @@ fn test_optflagmulti_short2a() {
#[test]
fn test_optflagmulti_short2b() {
let args = vec!("-vv".to_owned());
let args = vec!("-vv".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1169,7 +1180,7 @@ fn test_optflagmulti_short2b() {
#[test]
fn test_optflagmulti_long1() {
let args = vec!("--verbose".to_owned());
let args = vec!("--verbose".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1182,7 +1193,7 @@ fn test_optflagmulti_long1() {
#[test]
fn test_optflagmulti_long2() {
let args = vec!("--verbose".to_owned(), "--verbose".to_owned());
let args = vec!("--verbose".to_strbuf(), "--verbose".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1195,8 +1206,8 @@ fn test_optflagmulti_long2() {
#[test]
fn test_optflagmulti_mix() {
let args = vec!("--verbose".to_owned(), "-v".to_owned(),
"-vv".to_owned(), "verbose".to_owned());
let args = vec!("--verbose".to_strbuf(), "-v".to_strbuf(),
"-vv".to_strbuf(), "verbose".to_strbuf());
let opts = vec!(optflagmulti("v", "verbose", "verbosity"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1211,25 +1222,25 @@ fn test_optflagmulti_mix() {
// Tests for optmulti
#[test]
fn test_optmulti() {
let long_args = vec!("--test=20".to_owned());
let long_args = vec!("--test=20".to_strbuf());
let opts = vec!(optmulti("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
assert!((m.opt_present("test")));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!((m.opt_present("t")));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => fail!()
}
let short_args = vec!("-t".to_owned(), "20".to_owned());
let short_args = vec!("-t".to_strbuf(), "20".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Ok(ref m) => {
assert!((m.opt_present("test")));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!((m.opt_present("t")));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
}
_ => fail!()
}
@@ -1237,7 +1248,7 @@ fn test_optmulti() {
#[test]
fn test_optmulti_missing() {
let args = vec!("blah".to_owned());
let args = vec!("blah".to_strbuf());
let opts = vec!(optmulti("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
@@ -1251,14 +1262,14 @@ fn test_optmulti_missing() {
#[test]
fn test_optmulti_no_arg() {
let long_args = vec!("--test".to_owned());
let long_args = vec!("--test".to_strbuf());
let opts = vec!(optmulti("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
}
let short_args = vec!("-t".to_owned());
let short_args = vec!("-t".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Err(f) => check_fail_type(f, ArgumentMissing_),
_ => fail!()
@@ -1267,18 +1278,18 @@ fn test_optmulti_no_arg() {
#[test]
fn test_optmulti_multi() {
let args = vec!("--test=20".to_owned(), "-t".to_owned(), "30".to_owned());
let args = vec!("--test=20".to_strbuf(), "-t".to_strbuf(), "30".to_strbuf());
let opts = vec!(optmulti("t", "test", "testing", "TEST"));
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
assert!(m.opt_present("test"));
assert_eq!(m.opt_str("test").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("test").unwrap(), "20".to_strbuf());
assert!(m.opt_present("t"));
assert_eq!(m.opt_str("t").unwrap(), "20".to_owned());
assert_eq!(m.opt_str("t").unwrap(), "20".to_strbuf());
let pair = m.opt_strs("test");
assert!(*pair.get(0) == "20".to_owned());
assert!(*pair.get(1) == "30".to_owned());
assert!(*pair.get(0) == "20".to_strbuf());
assert!(*pair.get(1) == "30".to_strbuf());
}
_ => fail!()
}
@@ -1286,14 +1297,14 @@ fn test_optmulti_multi() {
#[test]
fn test_unrecognized_option() {
let long_args = vec!("--untest".to_owned());
let long_args = vec!("--untest".to_strbuf());
let opts = vec!(optmulti("t", "test", "testing", "TEST"));
let rs = getopts(long_args.as_slice(), opts.as_slice());
match rs {
Err(f) => check_fail_type(f, UnrecognizedOption_),
_ => fail!()
}
let short_args = vec!("-u".to_owned());
let short_args = vec!("-u".to_strbuf());
match getopts(short_args.as_slice(), opts.as_slice()) {
Err(f) => check_fail_type(f, UnrecognizedOption_),
_ => fail!()
@@ -1303,10 +1314,22 @@ fn test_unrecognized_option() {
#[test]
fn test_combined() {
let args =
vec!("prog".to_owned(), "free1".to_owned(), "-s".to_owned(), "20".to_owned(),
"free2".to_owned(), "--flag".to_owned(), "--long=30".to_owned(), "-f".to_owned(),
"-m".to_owned(), "40".to_owned(), "-m".to_owned(), "50".to_owned(), "-n".to_owned(),
"-A B".to_owned(), "-n".to_owned(), "-60 70".to_owned());
vec!("prog".to_strbuf(),
"free1".to_strbuf(),
"-s".to_strbuf(),
"20".to_strbuf(),
"free2".to_strbuf(),
"--flag".to_strbuf(),
"--long=30".to_strbuf(),
"-f".to_strbuf(),
"-m".to_strbuf(),
"40".to_strbuf(),
"-m".to_strbuf(),
"50".to_strbuf(),
"-n".to_strbuf(),
"-A B".to_strbuf(),
"-n".to_strbuf(),
"-60 70".to_strbuf());
let opts =
vec!(optopt("s", "something", "something", "SOMETHING"),
optflag("", "flag", "a flag"),
@@ -1318,19 +1341,19 @@ fn test_combined() {
let rs = getopts(args.as_slice(), opts.as_slice());
match rs {
Ok(ref m) => {
assert!(*m.free.get(0) == "prog".to_owned());
assert!(*m.free.get(1) == "free1".to_owned());
assert_eq!(m.opt_str("s").unwrap(), "20".to_owned());
assert!(*m.free.get(2) == "free2".to_owned());
assert!(*m.free.get(0) == "prog".to_strbuf());
assert!(*m.free.get(1) == "free1".to_strbuf());
assert_eq!(m.opt_str("s").unwrap(), "20".to_strbuf());
assert!(*m.free.get(2) == "free2".to_strbuf());
assert!((m.opt_present("flag")));
assert_eq!(m.opt_str("long").unwrap(), "30".to_owned());
assert_eq!(m.opt_str("long").unwrap(), "30".to_strbuf());
assert!((m.opt_present("f")));
let pair = m.opt_strs("m");
assert!(*pair.get(0) == "40".to_owned());
assert!(*pair.get(1) == "50".to_owned());
assert!(*pair.get(0) == "40".to_strbuf());
assert!(*pair.get(1) == "50".to_strbuf());
let pair = m.opt_strs("n");
assert!(*pair.get(0) == "-A B".to_owned());
assert!(*pair.get(1) == "-60 70".to_owned());
assert!(*pair.get(0) == "-A B".to_strbuf());
assert!(*pair.get(1) == "-60 70".to_strbuf());
assert!((!m.opt_present("notpresent")));
}
_ => fail!()
@@ -1343,68 +1366,68 @@ fn test_multi() {
optopt("", "encrypt", "encrypt", "ENCRYPT"),
optopt("f", "", "flag", "FLAG"));
let args_single = vec!("-e".to_owned(), "foo".to_owned());
let args_single = vec!("-e".to_strbuf(), "foo".to_strbuf());
let matches_single = &match getopts(args_single.as_slice(),
opts.as_slice()) {
result::Ok(m) => m,
result::Err(_) => fail!()
};
assert!(matches_single.opts_present(["e".to_owned()]));
assert!(matches_single.opts_present(["encrypt".to_owned(), "e".to_owned()]));
assert!(matches_single.opts_present(["e".to_owned(), "encrypt".to_owned()]));
assert!(!matches_single.opts_present(["encrypt".to_owned()]));
assert!(!matches_single.opts_present(["thing".to_owned()]));
assert!(matches_single.opts_present(["e".to_strbuf()]));
assert!(matches_single.opts_present(["encrypt".to_strbuf(), "e".to_strbuf()]));
assert!(matches_single.opts_present(["e".to_strbuf(), "encrypt".to_strbuf()]));
assert!(!matches_single.opts_present(["encrypt".to_strbuf()]));
assert!(!matches_single.opts_present(["thing".to_strbuf()]));
assert!(!matches_single.opts_present([]));
assert_eq!(matches_single.opts_str(["e".to_owned()]).unwrap(), "foo".to_owned());
assert_eq!(matches_single.opts_str(["e".to_owned(), "encrypt".to_owned()]).unwrap(),
"foo".to_owned());
assert_eq!(matches_single.opts_str(["encrypt".to_owned(), "e".to_owned()]).unwrap(),
"foo".to_owned());
assert_eq!(matches_single.opts_str(["e".to_strbuf()]).unwrap(), "foo".to_strbuf());
assert_eq!(matches_single.opts_str(["e".to_strbuf(), "encrypt".to_strbuf()]).unwrap(),
"foo".to_strbuf());
assert_eq!(matches_single.opts_str(["encrypt".to_strbuf(), "e".to_strbuf()]).unwrap(),
"foo".to_strbuf());
let args_both = vec!("-e".to_owned(), "foo".to_owned(), "--encrypt".to_owned(),
"foo".to_owned());
let args_both = vec!("-e".to_strbuf(), "foo".to_strbuf(), "--encrypt".to_strbuf(),
"foo".to_strbuf());
let matches_both = &match getopts(args_both.as_slice(),
opts.as_slice()) {
result::Ok(m) => m,
result::Err(_) => fail!()
};
assert!(matches_both.opts_present(["e".to_owned()]));
assert!(matches_both.opts_present(["encrypt".to_owned()]));
assert!(matches_both.opts_present(["encrypt".to_owned(), "e".to_owned()]));
assert!(matches_both.opts_present(["e".to_owned(), "encrypt".to_owned()]));
assert!(!matches_both.opts_present(["f".to_owned()]));
assert!(!matches_both.opts_present(["thing".to_owned()]));
assert!(matches_both.opts_present(["e".to_strbuf()]));
assert!(matches_both.opts_present(["encrypt".to_strbuf()]));
assert!(matches_both.opts_present(["encrypt".to_strbuf(), "e".to_strbuf()]));
assert!(matches_both.opts_present(["e".to_strbuf(), "encrypt".to_strbuf()]));
assert!(!matches_both.opts_present(["f".to_strbuf()]));
assert!(!matches_both.opts_present(["thing".to_strbuf()]));
assert!(!matches_both.opts_present([]));
assert_eq!(matches_both.opts_str(["e".to_owned()]).unwrap(), "foo".to_owned());
assert_eq!(matches_both.opts_str(["encrypt".to_owned()]).unwrap(), "foo".to_owned());
assert_eq!(matches_both.opts_str(["e".to_owned(), "encrypt".to_owned()]).unwrap(),
"foo".to_owned());
assert_eq!(matches_both.opts_str(["encrypt".to_owned(), "e".to_owned()]).unwrap(),
"foo".to_owned());
assert_eq!(matches_both.opts_str(["e".to_strbuf()]).unwrap(), "foo".to_strbuf());
assert_eq!(matches_both.opts_str(["encrypt".to_strbuf()]).unwrap(), "foo".to_strbuf());
assert_eq!(matches_both.opts_str(["e".to_strbuf(), "encrypt".to_strbuf()]).unwrap(),
"foo".to_strbuf());
assert_eq!(matches_both.opts_str(["encrypt".to_strbuf(), "e".to_strbuf()]).unwrap(),
"foo".to_strbuf());
}
#[test]
fn test_nospace() {
let args = vec!("-Lfoo".to_owned(), "-M.".to_owned());
let args = vec!("-Lfoo".to_strbuf(), "-M.".to_strbuf());
let opts = vec!(optmulti("L", "", "library directory", "LIB"),
optmulti("M", "", "something", "MMMM"));
let matches = &match getopts(args.as_slice(), opts.as_slice()) {
result::Ok(m) => m,
result::Err(_) => fail!()
};
assert!(matches.opts_present(["L".to_owned()]));
assert_eq!(matches.opts_str(["L".to_owned()]).unwrap(), "foo".to_owned());
assert!(matches.opts_present(["M".to_owned()]));
assert_eq!(matches.opts_str(["M".to_owned()]).unwrap(), ".".to_owned());
assert!(matches.opts_present(["L".to_strbuf()]));
assert_eq!(matches.opts_str(["L".to_strbuf()]).unwrap(), "foo".to_strbuf());
assert!(matches.opts_present(["M".to_strbuf()]));
assert_eq!(matches.opts_str(["M".to_strbuf()]).unwrap(), ".".to_strbuf());
}
#[test]
fn test_long_to_short() {
let mut short = Opt {
name: Long("banana".to_owned()),
name: Long("banana".to_strbuf()),
hasarg: Yes,
occur: Req,
aliases: Vec::new(),
@@ -1423,7 +1446,7 @@ fn test_aliases_long_and_short() {
let opts = vec!(
optflagmulti("a", "apple", "Desc"));
let args = vec!("-a".to_owned(), "--apple".to_owned(), "-a".to_owned());
let args = vec!("-a".to_strbuf(), "--apple".to_strbuf(), "-a".to_strbuf());
let matches = getopts(args.as_slice(), opts.as_slice()).unwrap();
assert_eq!(3, matches.opt_count("a"));
@@ -1450,7 +1473,7 @@ fn test_usage() {
-k --kiwi Desc
-p [VAL] Desc
-l VAL Desc
".to_owned();
".to_strbuf();
let generated_usage = usage("Usage: fruits", optgroups.as_slice());
@@ -1477,7 +1500,7 @@ fn test_usage_description_wrapping() {
-k --kiwi This is a long description which won't be wrapped..+..
-a --apple This is a long description which _will_ be
wrapped..+..
".to_owned();
".to_strbuf();
let usage = usage("Usage: fruits", optgroups.as_slice());
@@ -1503,7 +1526,7 @@ fn test_usage_description_multibyte_handling() {
-a --apple This “description” has some characters that could
confuse the line wrapping; an apple costs 0.51€ in
some parts of Europe.
".to_owned();
".to_strbuf();
let usage = usage("Usage: fruits", optgroups.as_slice());
@@ -1522,7 +1545,7 @@ fn test_short_usage() {
optflagopt("p", "", "Desc", "VAL"),
optmulti("l", "", "Desc", "VAL"));
let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_owned();
let expected = "Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..".to_strbuf();
let generated_usage = short_usage("fruits", optgroups.as_slice());
debug!("expected: <<{}>>", expected);
+9 -6
View File
@@ -319,7 +319,7 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
{
let mut cg = basic_codegen_options();
for option in matches.opt_strs("C").move_iter() {
let mut iter = option.splitn('=', 1);
let mut iter = option.as_slice().splitn('=', 1);
let key = iter.next().unwrap();
let value = iter.next();
let option_to_lookup = key.replace("-", "_");
@@ -563,7 +563,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let mut crate_types: Vec<CrateType> = Vec::new();
let unparsed_crate_types = matches.opt_strs("crate-type");
for unparsed_crate_type in unparsed_crate_types.iter() {
for part in unparsed_crate_type.split(',') {
for part in unparsed_crate_type.as_slice().split(',') {
let new_part = match part {
"lib" => default_lib_output(),
"rlib" => CrateTypeRlib,
@@ -612,7 +612,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let mut this_bit = 0;
for tuple in debug_map.iter() {
let (name, bit) = match *tuple { (ref a, _, b) => (a, b) };
if *name == *debug_flag { this_bit = bit; break; }
if *name == debug_flag.as_slice() {
this_bit = bit;
break;
}
}
if this_bit == 0 {
early_error(format!("unknown debug flag: {}", *debug_flag))
@@ -628,7 +631,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
if !parse_only && !no_trans {
let unparsed_output_types = matches.opt_strs("emit");
for unparsed_output_type in unparsed_output_types.iter() {
for part in unparsed_output_type.split(',') {
for part in unparsed_output_type.as_slice().split(',') {
let output_type = match part.as_slice() {
"asm" => link::OutputTypeAssembly,
"ir" => link::OutputTypeLlvmAssembly,
@@ -765,7 +768,7 @@ mod test {
#[test]
fn test_switch_implies_cfg_test() {
let matches =
&match getopts(["--test".to_owned()], optgroups().as_slice()) {
&match getopts(["--test".to_strbuf()], optgroups().as_slice()) {
Ok(m) => m,
Err(f) => fail!("test_switch_implies_cfg_test: {}", f.to_err_msg())
};
@@ -780,7 +783,7 @@ fn test_switch_implies_cfg_test() {
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() {
let matches =
&match getopts(["--test".to_owned(), "--cfg=test".to_owned()],
&match getopts(["--test".to_strbuf(), "--cfg=test".to_strbuf()],
optgroups().as_slice()) {
Ok(m) => m,
Err(f) => {
+14 -11
View File
@@ -35,7 +35,7 @@
pub mod config;
pub fn main_args(args: &[~str]) -> int {
pub fn main_args(args: &[StrBuf]) -> int {
let owned_args = args.to_owned();
monitor(proc() run_compiler(owned_args));
0
@@ -44,7 +44,7 @@ pub fn main_args(args: &[~str]) -> int {
static BUG_REPORT_URL: &'static str =
"http://static.rust-lang.org/doc/master/complement-bugreport.html";
fn run_compiler(args: &[~str]) {
fn run_compiler(args: &[StrBuf]) {
let matches = match handle_options(Vec::from_slice(args)) {
Some(matches) => matches,
None => return
@@ -73,7 +73,7 @@ fn run_compiler(args: &[~str]) {
let ofile = matches.opt_str("o").map(|o| Path::new(o));
let pretty = matches.opt_default("pretty", "normal").map(|a| {
parse_pretty(&sess, a)
parse_pretty(&sess, a.as_slice())
});
match pretty {
Some::<PpMode>(ppm) => {
@@ -84,7 +84,7 @@ fn run_compiler(args: &[~str]) {
}
let r = matches.opt_strs("Z");
if r.contains(&("ls".to_owned())) {
if r.contains(&("ls".to_strbuf())) {
match input {
FileInput(ref ifile) => {
let mut stdout = io::stdout();
@@ -191,17 +191,20 @@ fn describe_codegen_flags() {
/// Process command line options. Emits messages as appropirate.If compilation
/// should continue, returns a getopts::Matches object parsed from args, otherwise
/// returns None.
pub fn handle_options(mut args: Vec<~str>) -> Option<getopts::Matches> {
pub fn handle_options(mut args: Vec<StrBuf>) -> Option<getopts::Matches> {
// Throw away the first argument, the name of the binary
let _binary = args.shift().unwrap();
if args.is_empty() { usage(); return None; }
if args.is_empty() {
usage();
return None;
}
let matches =
match getopts::getopts(args.as_slice(), config::optgroups().as_slice()) {
Ok(m) => m,
Err(f) => {
early_error(f.to_err_msg());
early_error(f.to_err_msg().as_slice());
}
};
@@ -212,24 +215,24 @@ pub fn handle_options(mut args: Vec<~str>) -> Option<getopts::Matches> {
let lint_flags = matches.opt_strs("W").move_iter().collect::<Vec<_>>().append(
matches.opt_strs("warn").as_slice());
if lint_flags.iter().any(|x| x == &"help".to_owned()) {
if lint_flags.iter().any(|x| x.as_slice() == "help") {
describe_warnings();
return None;
}
let r = matches.opt_strs("Z");
if r.iter().any(|x| x == &"help".to_owned()) {
if r.iter().any(|x| x.as_slice() == "help") {
describe_debug_flags();
return None;
}
let cg_flags = matches.opt_strs("C");
if cg_flags.iter().any(|x| x == &"help".to_owned()) {
if cg_flags.iter().any(|x| x.as_slice() == "help") {
describe_codegen_flags();
return None;
}
if cg_flags.contains(&"passes=list".to_owned()) {
if cg_flags.contains(&"passes=list".to_strbuf()) {
unsafe { ::lib::llvm::llvm::LLVMRustPrintPasses(); }
return None;
}
+4 -1
View File
@@ -121,5 +121,8 @@ pub mod lib {
}
pub fn main() {
std::os::set_exit_status(driver::main_args(std::os::args().as_slice()));
let args = std::os::args().iter()
.map(|x| x.to_strbuf())
.collect::<Vec<_>>();
std::os::set_exit_status(driver::main_args(args.as_slice()));
}
+20 -20
View File
@@ -137,12 +137,7 @@ pub fn usage(argv0: &str) {
}
pub fn main_args(args: &[StrBuf]) -> int {
let matches = match getopts::getopts(args.tail()
.iter()
.map(|x| (*x).to_owned())
.collect::<Vec<_>>()
.as_slice(),
opts().as_slice()) {
let matches = match getopts::getopts(args.tail(), opts().as_slice()) {
Ok(m) => m,
Err(err) => {
println!("{}", err.to_err_msg());
@@ -170,7 +165,7 @@ pub fn main_args(args: &[StrBuf]) -> int {
let test_args = matches.opt_strs("test-args");
let test_args: Vec<StrBuf> = test_args.iter()
.flat_map(|s| s.words())
.flat_map(|s| s.as_slice().words())
.map(|s| s.to_strbuf())
.collect();
@@ -199,7 +194,7 @@ pub fn main_args(args: &[StrBuf]) -> int {
(false, false) => {}
}
if matches.opt_strs("passes").as_slice() == &["list".to_owned()] {
if matches.opt_strs("passes").as_slice() == &["list".to_strbuf()] {
println!("Available passes for running rustdoc:");
for &(name, _, description) in PASSES.iter() {
println!("{:>20s} - {}", name, description);
@@ -306,7 +301,7 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
clean::NameValue(ref x, ref value)
if "passes" == x.as_slice() => {
for pass in value.as_slice().words() {
passes.push(pass.to_owned());
passes.push(pass.to_strbuf());
}
}
clean::NameValue(ref x, ref value)
@@ -323,15 +318,19 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
}
if default_passes {
for name in DEFAULT_PASSES.iter().rev() {
passes.unshift(name.to_owned());
passes.unshift(name.to_strbuf());
}
}
// Load all plugins/passes into a PluginManager
let path = matches.opt_str("plugin-path").unwrap_or("/tmp/rustdoc/plugins".to_owned());
let path = matches.opt_str("plugin-path")
.unwrap_or("/tmp/rustdoc/plugins".to_strbuf());
let mut pm = plugins::PluginManager::new(Path::new(path));
for pass in passes.iter() {
let plugin = match PASSES.iter().position(|&(p, _, _)| p == *pass) {
let plugin = match PASSES.iter()
.position(|&(p, _, _)| {
p == pass.as_slice()
}) {
Some(i) => PASSES[i].val1(),
None => {
error!("unknown pass {}, skipping", *pass);
@@ -364,7 +363,7 @@ fn json_input(input: &str) -> Result<Output, StrBuf> {
Ok(json::Object(obj)) => {
let mut obj = obj;
// Make sure the schema is what we expect
match obj.pop(&"schema".to_owned()) {
match obj.pop(&"schema".to_strbuf()) {
Some(json::String(version)) => {
if version.as_slice() != SCHEMA_VERSION {
return Err(format_strbuf!(
@@ -375,7 +374,7 @@ fn json_input(input: &str) -> Result<Output, StrBuf> {
Some(..) => return Err("malformed json".to_strbuf()),
None => return Err("expected a schema version".to_strbuf()),
}
let krate = match obj.pop(&"crate".to_str()) {
let krate = match obj.pop(&"crate".to_strbuf()) {
Some(json) => {
let mut d = json::Decoder::new(json);
Decodable::decode(&mut d).unwrap()
@@ -404,13 +403,14 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
// "plugins": { output of plugins ... }
// }
let mut json = box collections::TreeMap::new();
json.insert("schema".to_owned(), json::String(SCHEMA_VERSION.to_owned()));
json.insert("schema".to_strbuf(),
json::String(SCHEMA_VERSION.to_strbuf()));
let plugins_json = box res.move_iter()
.filter_map(|opt| {
match opt {
None => None,
Some((string, json)) => {
Some((string.to_owned(), json))
Some((string.to_strbuf(), json))
}
}
}).collect();
@@ -423,15 +423,15 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
let mut encoder = json::Encoder::new(&mut w as &mut io::Writer);
krate.encode(&mut encoder).unwrap();
}
str::from_utf8(w.unwrap().as_slice()).unwrap().to_owned()
str::from_utf8(w.unwrap().as_slice()).unwrap().to_strbuf()
};
let crate_json = match json::from_str(crate_json_str) {
let crate_json = match json::from_str(crate_json_str.as_slice()) {
Ok(j) => j,
Err(e) => fail!("Rust generated JSON is invalid: {:?}", e)
};
json.insert("crate".to_owned(), crate_json);
json.insert("plugins".to_owned(), json::Object(plugins_json));
json.insert("crate".to_strbuf(), crate_json);
json.insert("plugins".to_strbuf(), json::Object(plugins_json));
let mut file = try!(File::create(&dst));
try!(json::Object(json).to_writer(&mut file));
+4 -4
View File
@@ -353,21 +353,21 @@ fn get_blockers(&self) -> uint {
pub struct UvError(c_int);
impl UvError {
pub fn name(&self) -> ~str {
pub fn name(&self) -> StrBuf {
unsafe {
let inner = match self { &UvError(a) => a };
let name_str = uvll::uv_err_name(inner);
assert!(name_str.is_not_null());
from_c_str(name_str)
from_c_str(name_str).to_strbuf()
}
}
pub fn desc(&self) -> ~str {
pub fn desc(&self) -> StrBuf {
unsafe {
let inner = match self { &UvError(a) => a };
let desc_str = uvll::uv_strerror(inner);
assert!(desc_str.is_not_null());
from_c_str(desc_str)
from_c_str(desc_str).to_strbuf()
}
}
+2 -2
View File
@@ -851,7 +851,7 @@ mod test {
fn connect_close_ip4() {
match TcpWatcher::connect(local_loop(), next_test_ip4(), None) {
Ok(..) => fail!(),
Err(e) => assert_eq!(e.name(), "ECONNREFUSED".to_owned()),
Err(e) => assert_eq!(e.name(), "ECONNREFUSED".to_strbuf()),
}
}
@@ -859,7 +859,7 @@ fn connect_close_ip4() {
fn connect_close_ip6() {
match TcpWatcher::connect(local_loop(), next_test_ip6(), None) {
Ok(..) => fail!(),
Err(e) => assert_eq!(e.name(), "ECONNREFUSED".to_owned()),
Err(e) => assert_eq!(e.name(), "ECONNREFUSED".to_strbuf()),
}
}
+1 -1
View File
@@ -338,7 +338,7 @@ fn connect_err() {
fn bind_err() {
match PipeListener::bind(local_loop(), &"path/to/nowhere".to_c_str()) {
Ok(..) => fail!(),
Err(e) => assert_eq!(e.name(), "EACCES".to_owned()),
Err(e) => assert_eq!(e.name(), "EACCES".to_strbuf()),
}
}
+25 -19
View File
@@ -54,7 +54,7 @@ pub struct Config {
pub trait ToBase64 {
/// Converts the value of `self` to a base64 value following the specified
/// format configuration, returning the owned string.
fn to_base64(&self, config: Config) -> ~str;
fn to_base64(&self, config: Config) -> StrBuf;
}
impl<'a> ToBase64 for &'a [u8] {
@@ -73,7 +73,7 @@ impl<'a> ToBase64 for &'a [u8] {
* }
* ```
*/
fn to_base64(&self, config: Config) -> ~str {
fn to_base64(&self, config: Config) -> StrBuf {
let bytes = match config.char_set {
Standard => STANDARD_CHARS,
UrlSafe => URLSAFE_CHARS
@@ -146,7 +146,7 @@ fn to_base64(&self, config: Config) -> ~str {
}
unsafe {
str::raw::from_utf8(v.as_slice()).to_owned()
str::raw::from_utf8(v.as_slice()).to_strbuf()
}
}
}
@@ -195,7 +195,7 @@ impl<'a> FromBase64 for &'a str {
* fn main () {
* let hello_str = bytes!("Hello, World").to_base64(STANDARD);
* println!("base64 output: {}", hello_str);
* let res = hello_str.from_base64();
* let res = hello_str.as_slice().from_base64();
* if res.is_ok() {
* let opt_bytes = StrBuf::from_utf8(res.unwrap());
* if opt_bytes.is_ok() {
@@ -267,34 +267,35 @@ mod tests {
#[test]
fn test_to_base64_basic() {
assert_eq!("".as_bytes().to_base64(STANDARD), "".to_owned());
assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg==".to_owned());
assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8=".to_owned());
assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v".to_owned());
assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg==".to_owned());
assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE=".to_owned());
assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy".to_owned());
assert_eq!("".as_bytes().to_base64(STANDARD), "".to_strbuf());
assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg==".to_strbuf());
assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8=".to_strbuf());
assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v".to_strbuf());
assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg==".to_strbuf());
assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE=".to_strbuf());
assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy".to_strbuf());
}
#[test]
fn test_to_base64_line_break() {
assert!(![0u8, ..1000].to_base64(Config {line_length: None, ..STANDARD})
.contains("\r\n"));
.as_slice()
.contains("\r\n"));
assert_eq!("foobar".as_bytes().to_base64(Config {line_length: Some(4),
..STANDARD}),
"Zm9v\r\nYmFy".to_owned());
"Zm9v\r\nYmFy".to_strbuf());
}
#[test]
fn test_to_base64_padding() {
assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg".to_owned());
assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8".to_owned());
assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg".to_strbuf());
assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8".to_strbuf());
}
#[test]
fn test_to_base64_url_safe() {
assert_eq!([251, 255].to_base64(URL_SAFE), "-_8".to_owned());
assert_eq!([251, 255].to_base64(STANDARD), "+/8=".to_owned());
assert_eq!([251, 255].to_base64(URL_SAFE), "-_8".to_strbuf());
assert_eq!([251, 255].to_base64(STANDARD), "+/8=".to_strbuf());
}
#[test]
@@ -339,7 +340,12 @@ fn test_base64_random() {
for _ in range(0, 1000) {
let times = task_rng().gen_range(1u, 100);
let v = Vec::from_fn(times, |_| random::<u8>());
assert_eq!(v.as_slice().to_base64(STANDARD).from_base64().unwrap().as_slice(),
assert_eq!(v.as_slice()
.to_base64(STANDARD)
.as_slice()
.from_base64()
.unwrap()
.as_slice(),
v.as_slice());
}
}
@@ -360,7 +366,7 @@ pub fn bench_from_base64(b: &mut Bencher) {
";
let sb = s.as_bytes().to_base64(STANDARD);
b.iter(|| {
sb.from_base64().unwrap();
sb.as_slice().from_base64().unwrap();
});
b.bytes = sb.len() as u64;
}
+24 -11
View File
@@ -34,8 +34,8 @@ pub fn as_str_slice<'a>(&'a self) -> &'a str {
str::from_utf8(self.data.slice(self.start, self.end)).unwrap()
}
pub fn as_str(&self) -> ~str {
self.as_str_slice().to_owned()
pub fn as_str(&self) -> StrBuf {
self.as_str_slice().to_strbuf()
}
}
@@ -80,7 +80,7 @@ pub enum EbmlEncoderTag {
#[deriving(Show)]
pub enum Error {
IntTooBig(uint),
Expected(~str),
Expected(StrBuf),
IoError(io::IoError)
}
// --------------------------------------
@@ -312,7 +312,10 @@ fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
self.pos = r_doc.end;
let str = r_doc.as_str_slice();
if lbl != str {
return Err(Expected(format!("Expected label {} but found {}", lbl, str)));
return Err(Expected(format_strbuf!("Expected label \
{} but found {}",
lbl,
str)));
}
}
}
@@ -322,7 +325,8 @@ fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
debug!(". next_doc(exp_tag={:?})", exp_tag);
if self.pos >= self.parent.end {
return Err(Expected(format!("no more documents in current node!")));
return Err(Expected(format_strbuf!("no more documents in \
current node!")));
}
let TaggedDoc { tag: r_tag, doc: r_doc } =
try!(doc_at(self.parent.data, self.pos));
@@ -334,12 +338,18 @@ fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
r_doc.start,
r_doc.end);
if r_tag != (exp_tag as uint) {
return Err(Expected(format!("expected EBML doc with tag {:?} but found tag {:?}",
exp_tag, r_tag)));
return Err(Expected(format_strbuf!("expected EBML doc with \
tag {:?} but found tag \
{:?}",
exp_tag,
r_tag)));
}
if r_doc.end > self.parent.end {
return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to {:#x}",
r_doc.end, self.parent.end)));
return Err(Expected(format_strbuf!("invalid EBML, child \
extends to {:#x}, parent \
to {:#x}",
r_doc.end,
self.parent.end)));
}
self.pos = r_doc.end;
Ok(r_doc)
@@ -433,7 +443,7 @@ fn read_f32(&mut self) -> DecodeResult<f32> {
fn read_char(&mut self) -> DecodeResult<char> {
Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
}
fn read_str(&mut self) -> DecodeResult<~str> {
fn read_str(&mut self) -> DecodeResult<StrBuf> {
Ok(try!(self.next_doc(EsStr)).as_str())
}
@@ -570,7 +580,10 @@ fn read_option<T>(&mut self,
match idx {
0 => f(this, false),
1 => f(this, true),
_ => Err(Expected(format!("Expected None or Some"))),
_ => {
Err(Expected(format_strbuf!("Expected None or \
Some")))
}
}
})
})
+8 -7
View File
@@ -16,7 +16,7 @@
pub trait ToHex {
/// Converts the value of `self` to a hex value, returning the owned
/// string.
fn to_hex(&self) -> ~str;
fn to_hex(&self) -> StrBuf;
}
static CHARS: &'static[u8] = bytes!("0123456789abcdef");
@@ -37,7 +37,7 @@ impl<'a> ToHex for &'a [u8] {
* }
* ```
*/
fn to_hex(&self) -> ~str {
fn to_hex(&self) -> StrBuf {
let mut v = Vec::with_capacity(self.len() * 2);
for &byte in self.iter() {
v.push(CHARS[(byte >> 4) as uint]);
@@ -45,7 +45,7 @@ fn to_hex(&self) -> ~str {
}
unsafe {
str::raw::from_utf8(v.as_slice()).to_owned()
str::raw::from_utf8(v.as_slice()).to_strbuf()
}
}
}
@@ -94,7 +94,7 @@ impl<'a> FromHex for &'a str {
* fn main () {
* let hello_str = "Hello, World".as_bytes().to_hex();
* println!("{}", hello_str);
* let bytes = hello_str.from_hex().unwrap();
* let bytes = hello_str.as_slice().from_hex().unwrap();
* println!("{:?}", bytes);
* let result_str = StrBuf::from_utf8(bytes).unwrap();
* println!("{}", result_str);
@@ -143,7 +143,7 @@ mod tests {
#[test]
pub fn test_to_hex() {
assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172".to_owned());
assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172".to_strbuf());
}
#[test]
@@ -174,7 +174,8 @@ pub fn test_from_hex_ignores_whitespace() {
#[test]
pub fn test_to_hex_all_bytes() {
for i in range(0, 256) {
assert_eq!([i as u8].to_hex(), format!("{:02x}", i as uint));
assert_eq!([i as u8].to_hex(),
format_strbuf!("{:02x}", i as uint));
}
}
@@ -202,7 +203,7 @@ pub fn bench_from_hex(b: &mut Bencher) {
";
let sb = s.as_bytes().to_hex();
b.iter(|| {
sb.from_hex().unwrap();
sb.as_slice().from_hex().unwrap();
});
b.bytes = sb.len() as u64;
}
+232 -204
View File
@@ -64,11 +64,11 @@
#[deriving(Encodable)]
pub struct TestStruct {
data_str: ~str,
data_str: StrBuf,
}
fn main() {
let to_encode_object = TestStruct{data_str:"example of string to encode".to_owned()};
let to_encode_object = TestStruct{data_str:"example of string to encode".to_strbuf()};
let mut m = io::MemWriter::new();
{
let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer);
@@ -81,12 +81,12 @@ fn main() {
```
Two wrapper functions are provided to encode a Encodable object
into a string (~str) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m)`.
into a string (StrBuf) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m)`.
```rust
use serialize::json;
let to_encode_object = "example of string to encode".to_owned();
let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object);
let to_encode_object = "example of string to encode".to_strbuf();
let encoded_str: StrBuf = json::Encoder::str_encode(&to_encode_object);
```
JSON API provide an enum `json::Json` and a trait `ToJson` to encode object.
@@ -108,22 +108,22 @@ fn main() {
pub struct MyStruct {
attr1: u8,
attr2: ~str,
attr2: StrBuf,
}
impl ToJson for MyStruct {
fn to_json( &self ) -> json::Json {
let mut d = box TreeMap::new();
d.insert("attr1".to_owned(), self.attr1.to_json());
d.insert("attr2".to_owned(), self.attr2.to_json());
d.insert("attr1".to_strbuf(), self.attr1.to_json());
d.insert("attr2".to_strbuf(), self.attr2.to_json());
json::Object(d)
}
}
fn main() {
let test2: MyStruct = MyStruct {attr1: 1, attr2:"test".to_owned()};
let test2: MyStruct = MyStruct {attr1: 1, attr2:"test".to_strbuf()};
let tjson: json::Json = test2.to_json();
let json_str: ~str = tjson.to_str();
let json_str: StrBuf = tjson.to_str().into_strbuf();
}
```
@@ -136,13 +136,13 @@ fn main() {
#[deriving(Decodable)]
pub struct MyStruct {
attr1: u8,
attr2: ~str,
attr2: StrBuf,
}
fn main() {
let json_str_to_decode: ~str =
"{\"attr1\":1,\"attr2\":\"toto\"}".to_owned();
let json_object = json::from_str(json_str_to_decode);
let json_str_to_decode: StrBuf =
"{\"attr1\":1,\"attr2\":\"toto\"}".to_strbuf();
let json_object = json::from_str(json_str_to_decode.as_slice());
let mut decoder = json::Decoder::new(json_object.unwrap());
let decoded_object: MyStruct = match Decodable::decode(&mut decoder) {
Ok(v) => v,
@@ -165,7 +165,7 @@ fn main() {
#[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl.
pub struct TestStruct1 {
data_int: u8,
data_str: ~str,
data_str: StrBuf,
data_vector: Vec<u8>,
}
@@ -173,12 +173,12 @@ pub struct TestStruct1 {
// It calls the generated `Encodable` impl.
fn main() {
let to_encode_object = TestStruct1
{data_int: 1, data_str:"toto".to_owned(), data_vector:vec![2,3,4,5]};
let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object);
{data_int: 1, data_str:"toto".to_strbuf(), data_vector:vec![2,3,4,5]};
let encoded_str: StrBuf = json::Encoder::str_encode(&to_encode_object);
// To deserialize use the `json::from_str` and `json::Decoder`
let json_object = json::from_str(encoded_str);
let json_object = json::from_str(encoded_str.as_slice());
let mut decoder = json::Decoder::new(json_object.unwrap());
let decoded1: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); // create the final object
}
@@ -200,16 +200,16 @@ fn main() {
#[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl.
pub struct TestStruct1 {
data_int: u8,
data_str: ~str,
data_str: StrBuf,
data_vector: Vec<u8>,
}
impl ToJson for TestStruct1 {
fn to_json( &self ) -> json::Json {
let mut d = box TreeMap::new();
d.insert("data_int".to_owned(), self.data_int.to_json());
d.insert("data_str".to_owned(), self.data_str.to_json());
d.insert("data_vector".to_owned(), self.data_vector.to_json());
d.insert("data_int".to_strbuf(), self.data_int.to_json());
d.insert("data_str".to_strbuf(), self.data_str.to_json());
d.insert("data_vector".to_strbuf(), self.data_vector.to_json());
json::Object(d)
}
}
@@ -217,14 +217,15 @@ fn to_json( &self ) -> json::Json {
fn main() {
// Serialization using our impl of to_json
let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:"toto".to_owned(),
let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:"toto".to_strbuf(),
data_vector:vec![2,3,4,5]};
let tjson: json::Json = test2.to_json();
let json_str: ~str = tjson.to_str();
let json_str: StrBuf = tjson.to_str().into_strbuf();
// Deserialize like before.
let mut decoder = json::Decoder::new(json::from_str(json_str).unwrap());
let mut decoder =
json::Decoder::new(json::from_str(json_str.as_slice()).unwrap());
// create the final object
let decoded2: TestStruct1 = Decodable::decode(&mut decoder).unwrap();
}
@@ -251,7 +252,7 @@ fn main() {
#[deriving(Clone, Eq)]
pub enum Json {
Number(f64),
String(~str),
String(StrBuf),
Boolean(bool),
List(List),
Object(Box<Object>),
@@ -259,7 +260,7 @@ pub enum Json {
}
pub type List = Vec<Json>;
pub type Object = TreeMap<~str, Json>;
pub type Object = TreeMap<StrBuf, Json>;
/// The errors that can arise while parsing a JSON stream.
#[deriving(Clone, Eq)]
@@ -295,9 +296,9 @@ pub enum ParserError {
#[deriving(Clone, Eq, Show)]
pub enum DecoderError {
ParseError(ParserError),
ExpectedError(~str, ~str),
MissingFieldError(~str),
UnknownVariantError(~str),
ExpectedError(StrBuf, StrBuf),
MissingFieldError(StrBuf),
UnknownVariantError(StrBuf),
}
/// Returns a readable error string for a given error code.
@@ -336,7 +337,7 @@ fn io_error_to_error(io: io::IoError) -> ParserError {
pub type EncodeResult = io::IoResult<()>;
pub type DecodeResult<T> = Result<T, DecoderError>;
fn escape_str(s: &str) -> ~str {
fn escape_str(s: &str) -> StrBuf {
let mut escaped = StrBuf::from_str("\"");
for c in s.chars() {
match c {
@@ -351,15 +352,15 @@ fn escape_str(s: &str) -> ~str {
}
};
escaped.push_char('"');
escaped.into_owned()
escaped
}
fn spaces(n: uint) -> ~str {
fn spaces(n: uint) -> StrBuf {
let mut ss = StrBuf::new();
for _ in range(0, n) {
ss.push_str(" ");
}
return ss.into_owned();
return ss
}
/// A structure for implementing serialization to JSON.
@@ -387,9 +388,12 @@ pub fn buffer_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T
}
/// Encode the specified struct into a json str
pub fn str_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T) -> ~str {
pub fn str_encode<T:Encodable<Encoder<'a>,
io::IoError>>(
to_encode_object: &T)
-> StrBuf {
let buff = Encoder::buffer_encode(to_encode_object);
str::from_utf8(buff.as_slice()).unwrap().to_owned()
str::from_utf8(buff.as_slice()).unwrap().to_strbuf()
}
}
@@ -826,15 +830,15 @@ pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> EncodeResult {
}
/// Encodes a json value into a string
pub fn to_pretty_str(&self) -> ~str {
pub fn to_pretty_str(&self) -> StrBuf {
let mut s = MemWriter::new();
self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
str::from_utf8(s.unwrap().as_slice()).unwrap().to_owned()
str::from_utf8(s.unwrap().as_slice()).unwrap().to_strbuf()
}
/// If the Json value is an Object, returns the value associated with the provided key.
/// Otherwise, returns None.
pub fn find<'a>(&'a self, key: &~str) -> Option<&'a Json>{
pub fn find<'a>(&'a self, key: &StrBuf) -> Option<&'a Json>{
match self {
&Object(ref map) => map.find(key),
_ => None
@@ -844,7 +848,7 @@ pub fn find<'a>(&'a self, key: &~str) -> Option<&'a Json>{
/// Attempts to get a nested Json Object for each key in `keys`.
/// If any key is found not to exist, find_path will return None.
/// Otherwise, it will return the Json value associated with the final key.
pub fn find_path<'a>(&'a self, keys: &[&~str]) -> Option<&'a Json>{
pub fn find_path<'a>(&'a self, keys: &[&StrBuf]) -> Option<&'a Json>{
let mut target = self;
for key in keys.iter() {
match target.find(*key) {
@@ -858,7 +862,7 @@ pub fn find_path<'a>(&'a self, keys: &[&~str]) -> Option<&'a Json>{
/// If the Json value is an Object, performs a depth-first search until
/// a value associated with the provided key is found. If no value is found
/// or the Json value is not an Object, returns None.
pub fn search<'a>(&'a self, key: &~str) -> Option<&'a Json> {
pub fn search<'a>(&'a self, key: &StrBuf) -> Option<&'a Json> {
match self {
&Object(ref map) => {
match map.find(key) {
@@ -973,7 +977,7 @@ pub enum JsonEvent {
ListEnd,
BooleanValue(bool),
NumberValue(f64),
StringValue(~str),
StringValue(StrBuf),
NullValue,
Error(ParserError),
}
@@ -1091,7 +1095,7 @@ pub fn top<'l>(&'l self) -> Option<StackElement<'l>> {
}
// Used by Parser to insert Key elements at the top of the stack.
fn push_key(&mut self, key: ~str) {
fn push_key(&mut self, key: StrBuf) {
self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16));
for c in key.as_bytes().iter() {
self.str_buffer.push(*c);
@@ -1378,7 +1382,7 @@ fn decode_hex_escape(&mut self) -> Result<u16, ParserError> {
Ok(n)
}
fn parse_str(&mut self) -> Result<~str, ParserError> {
fn parse_str(&mut self) -> Result<StrBuf, ParserError> {
let mut escape = false;
let mut res = StrBuf::new();
@@ -1462,7 +1466,7 @@ fn parse_str(&mut self) -> Result<~str, ParserError> {
match self.ch {
Some('"') => {
self.bump();
return Ok(res.into_owned());
return Ok(res);
},
Some(c) => res.push_char(c),
None => unreachable!()
@@ -1738,7 +1742,7 @@ fn build_value(&mut self) -> Result<Json, BuilderError> {
Some(NumberValue(n)) => { Ok(Number(n)) }
Some(BooleanValue(b)) => { Ok(Boolean(b)) }
Some(StringValue(ref mut s)) => {
let mut temp = "".to_owned();
let mut temp = StrBuf::new();
swap(s, &mut temp);
Ok(String(temp))
}
@@ -1780,7 +1784,7 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
_ => {}
}
let key = match self.parser.stack().top() {
Some(Key(k)) => { k.into_owned() }
Some(Key(k)) => { k.to_strbuf() }
_ => { fail!("invalid state"); }
};
match self.build_value() {
@@ -1801,10 +1805,10 @@ pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, BuilderError> {
Err(e) => return Err(io_error_to_error(e))
};
let s = match str::from_utf8(contents.as_slice()) {
Some(s) => s.to_owned(),
Some(s) => s.to_strbuf(),
None => return Err(SyntaxError(NotUtf8, 0, 0))
};
let mut builder = Builder::new(s.chars());
let mut builder = Builder::new(s.as_slice().chars());
builder.build()
}
@@ -1838,13 +1842,17 @@ macro_rules! expect(
($e:expr, Null) => ({
match $e {
Null => Ok(()),
other => Err(ExpectedError("Null".to_owned(), format!("{}", other)))
other => Err(ExpectedError("Null".to_strbuf(),
format_strbuf!("{}", other)))
}
});
($e:expr, $t:ident) => ({
match $e {
$t(v) => Ok(v),
other => Err(ExpectedError(stringify!($t).to_owned(), format!("{}", other)))
other => {
Err(ExpectedError(stringify!($t).to_strbuf(),
format_strbuf!("{}", other)))
}
}
})
)
@@ -1881,9 +1889,12 @@ fn read_f64(&mut self) -> DecodeResult<f64> {
String(s) => {
// re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
// is going to have a string here, as per JSON spec..
Ok(FromStr::from_str(s).unwrap())
Ok(FromStr::from_str(s.as_slice()).unwrap())
},
value => Err(ExpectedError("Number".to_owned(), format!("{}", value)))
value => {
Err(ExpectedError("Number".to_strbuf(),
format_strbuf!("{}", value)))
}
}
}
@@ -1892,17 +1903,18 @@ fn read_f32(&mut self) -> DecodeResult<f32> { Ok(try!(self.read_f64()) as f32) }
fn read_char(&mut self) -> DecodeResult<char> {
let s = try!(self.read_str());
{
let mut it = s.chars();
let mut it = s.as_slice().chars();
match (it.next(), it.next()) {
// exactly one character
(Some(c), None) => return Ok(c),
_ => ()
}
}
Err(ExpectedError("single character string".to_owned(), format!("{}", s)))
Err(ExpectedError("single character string".to_strbuf(),
format_strbuf!("{}", s)))
}
fn read_str(&mut self) -> DecodeResult<~str> {
fn read_str(&mut self) -> DecodeResult<StrBuf> {
debug!("read_str");
Ok(try!(expect!(self.pop(), String)))
}
@@ -1922,25 +1934,41 @@ fn read_enum_variant<T>(&mut self,
let name = match self.pop() {
String(s) => s,
Object(mut o) => {
let n = match o.pop(&"variant".to_owned()) {
let n = match o.pop(&"variant".to_strbuf()) {
Some(String(s)) => s,
Some(val) => return Err(ExpectedError("String".to_owned(), format!("{}", val))),
None => return Err(MissingFieldError("variant".to_owned()))
Some(val) => {
return Err(ExpectedError("String".to_strbuf(),
format_strbuf!("{}", val)))
}
None => {
return Err(MissingFieldError("variant".to_strbuf()))
}
};
match o.pop(&"fields".to_owned()) {
match o.pop(&"fields".to_strbuf()) {
Some(List(l)) => {
for field in l.move_iter().rev() {
self.stack.push(field.clone());
}
},
Some(val) => return Err(ExpectedError("List".to_owned(), format!("{}", val))),
None => return Err(MissingFieldError("fields".to_owned()))
Some(val) => {
return Err(ExpectedError("List".to_strbuf(),
format_strbuf!("{}", val)))
}
None => {
return Err(MissingFieldError("fields".to_strbuf()))
}
}
n
}
json => return Err(ExpectedError("String or Object".to_owned(), format!("{}", json)))
json => {
return Err(ExpectedError("String or Object".to_strbuf(),
format_strbuf!("{}", json)))
}
};
let idx = match names.iter().position(|n| str::eq_slice(*n, name)) {
let idx = match names.iter()
.position(|n| {
str::eq_slice(*n, name.as_slice())
}) {
Some(idx) => idx,
None => return Err(UnknownVariantError(name))
};
@@ -1990,8 +2018,8 @@ fn read_struct_field<T>(&mut self,
debug!("read_struct_field(name={}, idx={})", name, idx);
let mut obj = try!(expect!(self.pop(), Object));
let value = match obj.pop(&name.to_owned()) {
None => return Err(MissingFieldError(name.to_owned())),
let value = match obj.pop(&name.to_strbuf()) {
None => return Err(MissingFieldError(name.to_strbuf())),
Some(json) => {
self.stack.push(json);
try!(f(self))
@@ -2199,12 +2227,8 @@ impl ToJson for bool {
fn to_json(&self) -> Json { Boolean(*self) }
}
impl ToJson for ~str {
fn to_json(&self) -> Json { String((*self).clone()) }
}
impl ToJson for StrBuf {
fn to_json(&self) -> Json { String((*self).as_slice().into_owned()) }
fn to_json(&self) -> Json { String((*self).clone()) }
}
impl<A:ToJson,B:ToJson> ToJson for (A, B) {
@@ -2235,7 +2259,7 @@ impl<A:ToJson> ToJson for Vec<A> {
fn to_json(&self) -> Json { List(self.iter().map(|elt| elt.to_json()).collect()) }
}
impl<A:ToJson> ToJson for TreeMap<~str, A> {
impl<A:ToJson> ToJson for TreeMap<StrBuf, A> {
fn to_json(&self) -> Json {
let mut d = TreeMap::new();
for (key, value) in self.iter() {
@@ -2245,7 +2269,7 @@ fn to_json(&self) -> Json {
}
}
impl<A:ToJson> ToJson for HashMap<~str, A> {
impl<A:ToJson> ToJson for HashMap<StrBuf, A> {
fn to_json(&self) -> Json {
let mut d = TreeMap::new();
for (key, value) in self.iter() {
@@ -2291,14 +2315,14 @@ mod tests {
#[deriving(Eq, Encodable, Decodable, Show)]
enum Animal {
Dog,
Frog(~str, int)
Frog(StrBuf, int)
}
#[deriving(Eq, Encodable, Decodable, Show)]
struct Inner {
a: (),
b: uint,
c: Vec<~str>,
c: Vec<StrBuf>,
}
#[deriving(Eq, Encodable, Decodable, Show)]
@@ -2306,7 +2330,7 @@ struct Outer {
inner: Vec<Inner>,
}
fn mk_object(items: &[(~str, Json)]) -> Json {
fn mk_object(items: &[(StrBuf, Json)]) -> Json {
let mut d = box TreeMap::new();
for item in items.iter() {
@@ -2320,67 +2344,67 @@ fn mk_object(items: &[(~str, Json)]) -> Json {
#[test]
fn test_write_null() {
assert_eq!(Null.to_str(), "null".to_owned());
assert_eq!(Null.to_pretty_str(), "null".to_owned());
assert_eq!(Null.to_str().into_strbuf(), "null".to_strbuf());
assert_eq!(Null.to_pretty_str().into_strbuf(), "null".to_strbuf());
}
#[test]
fn test_write_number() {
assert_eq!(Number(3.0).to_str(), "3".to_owned());
assert_eq!(Number(3.0).to_pretty_str(), "3".to_owned());
assert_eq!(Number(3.0).to_str().into_strbuf(), "3".to_strbuf());
assert_eq!(Number(3.0).to_pretty_str().into_strbuf(), "3".to_strbuf());
assert_eq!(Number(3.1).to_str(), "3.1".to_owned());
assert_eq!(Number(3.1).to_pretty_str(), "3.1".to_owned());
assert_eq!(Number(3.1).to_str().into_strbuf(), "3.1".to_strbuf());
assert_eq!(Number(3.1).to_pretty_str().into_strbuf(), "3.1".to_strbuf());
assert_eq!(Number(-1.5).to_str(), "-1.5".to_owned());
assert_eq!(Number(-1.5).to_pretty_str(), "-1.5".to_owned());
assert_eq!(Number(-1.5).to_str().into_strbuf(), "-1.5".to_strbuf());
assert_eq!(Number(-1.5).to_pretty_str().into_strbuf(), "-1.5".to_strbuf());
assert_eq!(Number(0.5).to_str(), "0.5".to_owned());
assert_eq!(Number(0.5).to_pretty_str(), "0.5".to_owned());
assert_eq!(Number(0.5).to_str().into_strbuf(), "0.5".to_strbuf());
assert_eq!(Number(0.5).to_pretty_str().into_strbuf(), "0.5".to_strbuf());
}
#[test]
fn test_write_str() {
assert_eq!(String("".to_owned()).to_str(), "\"\"".to_owned());
assert_eq!(String("".to_owned()).to_pretty_str(), "\"\"".to_owned());
assert_eq!(String("".to_strbuf()).to_str().into_strbuf(), "\"\"".to_strbuf());
assert_eq!(String("".to_strbuf()).to_pretty_str().into_strbuf(), "\"\"".to_strbuf());
assert_eq!(String("foo".to_owned()).to_str(), "\"foo\"".to_owned());
assert_eq!(String("foo".to_owned()).to_pretty_str(), "\"foo\"".to_owned());
assert_eq!(String("foo".to_strbuf()).to_str().into_strbuf(), "\"foo\"".to_strbuf());
assert_eq!(String("foo".to_strbuf()).to_pretty_str().into_strbuf(), "\"foo\"".to_strbuf());
}
#[test]
fn test_write_bool() {
assert_eq!(Boolean(true).to_str(), "true".to_owned());
assert_eq!(Boolean(true).to_pretty_str(), "true".to_owned());
assert_eq!(Boolean(true).to_str().into_strbuf(), "true".to_strbuf());
assert_eq!(Boolean(true).to_pretty_str().into_strbuf(), "true".to_strbuf());
assert_eq!(Boolean(false).to_str(), "false".to_owned());
assert_eq!(Boolean(false).to_pretty_str(), "false".to_owned());
assert_eq!(Boolean(false).to_str().into_strbuf(), "false".to_strbuf());
assert_eq!(Boolean(false).to_pretty_str().into_strbuf(), "false".to_strbuf());
}
#[test]
fn test_write_list() {
assert_eq!(List(vec![]).to_str(), "[]".to_owned());
assert_eq!(List(vec![]).to_pretty_str(), "[]".to_owned());
assert_eq!(List(vec![]).to_str().into_strbuf(), "[]".to_strbuf());
assert_eq!(List(vec![]).to_pretty_str().into_strbuf(), "[]".to_strbuf());
assert_eq!(List(vec![Boolean(true)]).to_str(), "[true]".to_owned());
assert_eq!(List(vec![Boolean(true)]).to_str().into_strbuf(), "[true]".to_strbuf());
assert_eq!(
List(vec![Boolean(true)]).to_pretty_str(),
List(vec![Boolean(true)]).to_pretty_str().into_strbuf(),
"\
[\n \
true\n\
]".to_owned()
]".to_strbuf()
);
let long_test_list = List(vec![
Boolean(false),
Null,
List(vec![String("foo\nbar".to_owned()), Number(3.5)])]);
List(vec![String("foo\nbar".to_strbuf()), Number(3.5)])]);
assert_eq!(long_test_list.to_str(),
"[false,null,[\"foo\\nbar\",3.5]]".to_owned());
assert_eq!(long_test_list.to_str().into_strbuf(),
"[false,null,[\"foo\\nbar\",3.5]]".to_strbuf());
assert_eq!(
long_test_list.to_pretty_str(),
long_test_list.to_pretty_str().into_strbuf(),
"\
[\n \
false,\n \
@@ -2389,45 +2413,47 @@ fn test_write_list() {
\"foo\\nbar\",\n \
3.5\n \
]\n\
]".to_owned()
]".to_strbuf()
);
}
#[test]
fn test_write_object() {
assert_eq!(mk_object([]).to_str(), "{}".to_owned());
assert_eq!(mk_object([]).to_pretty_str(), "{}".to_owned());
assert_eq!(mk_object([]).to_str().into_strbuf(), "{}".to_strbuf());
assert_eq!(mk_object([]).to_pretty_str().into_strbuf(), "{}".to_strbuf());
assert_eq!(
mk_object([("a".to_owned(), Boolean(true))]).to_str(),
"{\"a\":true}".to_owned()
mk_object([
("a".to_strbuf(), Boolean(true))
]).to_str().into_strbuf(),
"{\"a\":true}".to_strbuf()
);
assert_eq!(
mk_object([("a".to_owned(), Boolean(true))]).to_pretty_str(),
mk_object([("a".to_strbuf(), Boolean(true))]).to_pretty_str(),
"\
{\n \
\"a\": true\n\
}".to_owned()
}".to_strbuf()
);
let complex_obj = mk_object([
("b".to_owned(), List(vec![
mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
mk_object([("d".to_owned(), String("".to_owned()))])
("b".to_strbuf(), List(vec![
mk_object([("c".to_strbuf(), String("\x0c\r".to_strbuf()))]),
mk_object([("d".to_strbuf(), String("".to_strbuf()))])
]))
]);
assert_eq!(
complex_obj.to_str(),
complex_obj.to_str().into_strbuf(),
"{\
\"b\":[\
{\"c\":\"\\f\\r\"},\
{\"d\":\"\"}\
]\
}".to_owned()
}".to_strbuf()
);
assert_eq!(
complex_obj.to_pretty_str(),
complex_obj.to_pretty_str().into_strbuf(),
"\
{\n \
\"b\": [\n \
@@ -2438,30 +2464,31 @@ fn test_write_object() {
\"d\": \"\"\n \
}\n \
]\n\
}".to_owned()
}".to_strbuf()
);
let a = mk_object([
("a".to_owned(), Boolean(true)),
("b".to_owned(), List(vec![
mk_object([("c".to_owned(), String("\x0c\r".to_owned()))]),
mk_object([("d".to_owned(), String("".to_owned()))])
("a".to_strbuf(), Boolean(true)),
("b".to_strbuf(), List(vec![
mk_object([("c".to_strbuf(), String("\x0c\r".to_strbuf()))]),
mk_object([("d".to_strbuf(), String("".to_strbuf()))])
]))
]);
// We can't compare the strings directly because the object fields be
// printed in a different order.
assert_eq!(a.clone(), from_str(a.to_str()).unwrap());
assert_eq!(a.clone(), from_str(a.to_pretty_str()).unwrap());
assert_eq!(a.clone(),
from_str(a.to_pretty_str().as_slice()).unwrap());
}
fn with_str_writer(f: |&mut io::Writer|) -> ~str {
fn with_str_writer(f: |&mut io::Writer|) -> StrBuf {
use std::io::MemWriter;
use std::str;
let mut m = MemWriter::new();
f(&mut m as &mut io::Writer);
str::from_utf8(m.unwrap().as_slice()).unwrap().to_owned()
str::from_utf8(m.unwrap().as_slice()).unwrap().to_strbuf()
}
#[test]
@@ -2472,23 +2499,23 @@ fn test_write_enum() {
let mut encoder = Encoder::new(wr);
animal.encode(&mut encoder).unwrap();
}),
"\"Dog\"".to_owned()
"\"Dog\"".to_strbuf()
);
assert_eq!(
with_str_writer(|wr| {
let mut encoder = PrettyEncoder::new(wr);
animal.encode(&mut encoder).unwrap();
}),
"\"Dog\"".to_owned()
"\"Dog\"".to_strbuf()
);
let animal = Frog("Henry".to_owned(), 349);
let animal = Frog("Henry".to_strbuf(), 349);
assert_eq!(
with_str_writer(|wr| {
let mut encoder = Encoder::new(wr);
animal.encode(&mut encoder).unwrap();
}),
"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}".to_owned()
"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}".to_strbuf()
);
assert_eq!(
with_str_writer(|wr| {
@@ -2500,41 +2527,41 @@ fn test_write_enum() {
\"Frog\",\n \
\"Henry\",\n \
349\n\
]".to_owned()
]".to_strbuf()
);
}
#[test]
fn test_write_some() {
let value = Some("jodhpurs".to_owned());
let value = Some("jodhpurs".to_strbuf());
let s = with_str_writer(|wr| {
let mut encoder = Encoder::new(wr);
value.encode(&mut encoder).unwrap();
});
assert_eq!(s, "\"jodhpurs\"".to_owned());
assert_eq!(s, "\"jodhpurs\"".to_strbuf());
let value = Some("jodhpurs".to_owned());
let value = Some("jodhpurs".to_strbuf());
let s = with_str_writer(|wr| {
let mut encoder = PrettyEncoder::new(wr);
value.encode(&mut encoder).unwrap();
});
assert_eq!(s, "\"jodhpurs\"".to_owned());
assert_eq!(s, "\"jodhpurs\"".to_strbuf());
}
#[test]
fn test_write_none() {
let value: Option<~str> = None;
let value: Option<StrBuf> = None;
let s = with_str_writer(|wr| {
let mut encoder = Encoder::new(wr);
value.encode(&mut encoder).unwrap();
});
assert_eq!(s, "null".to_owned());
assert_eq!(s, "null".to_strbuf());
let s = with_str_writer(|wr| {
let mut encoder = Encoder::new(wr);
value.encode(&mut encoder).unwrap();
});
assert_eq!(s, "null".to_owned());
assert_eq!(s, "null".to_strbuf());
}
#[test]
@@ -2635,16 +2662,16 @@ fn test_read_str() {
assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2)));
assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5)));
assert_eq!(from_str("\"\""), Ok(String("".to_owned())));
assert_eq!(from_str("\"foo\""), Ok(String("foo".to_owned())));
assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_owned())));
assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_owned())));
assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_owned())));
assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_owned())));
assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_owned())));
assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_owned())));
assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".to_owned())));
assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".to_owned())));
assert_eq!(from_str("\"\""), Ok(String("".to_strbuf())));
assert_eq!(from_str("\"foo\""), Ok(String("foo".to_strbuf())));
assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_strbuf())));
assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_strbuf())));
assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_strbuf())));
assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_strbuf())));
assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_strbuf())));
assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_strbuf())));
assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u12ab".to_strbuf())));
assert_eq!(from_str("\"\\uAB12\""), Ok(String("\uAB12".to_strbuf())));
}
#[test]
@@ -2665,8 +2692,8 @@ fn test_decode_str() {
assert_eq!(v.as_slice(), o);
let mut decoder = Decoder::new(from_str(i).unwrap());
let v: ~str = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, o.to_owned());
let v: StrBuf = Decodable::decode(&mut decoder).unwrap();
assert_eq!(v, o.to_strbuf());
}
}
@@ -2735,39 +2762,39 @@ fn test_read_object() {
assert_eq!(from_str("{}").unwrap(), mk_object([]));
assert_eq!(from_str("{\"a\": 3}").unwrap(),
mk_object([("a".to_owned(), Number(3.0))]));
mk_object([("a".to_strbuf(), Number(3.0))]));
assert_eq!(from_str(
"{ \"a\": null, \"b\" : true }").unwrap(),
mk_object([
("a".to_owned(), Null),
("b".to_owned(), Boolean(true))]));
("a".to_strbuf(), Null),
("b".to_strbuf(), Boolean(true))]));
assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(),
mk_object([
("a".to_owned(), Null),
("b".to_owned(), Boolean(true))]));
("a".to_strbuf(), Null),
("b".to_strbuf(), Boolean(true))]));
assert_eq!(from_str(
"{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
mk_object([
("a".to_owned(), Number(1.0)),
("b".to_owned(), List(vec![Boolean(true)]))
("a".to_strbuf(), Number(1.0)),
("b".to_strbuf(), List(vec![Boolean(true)]))
]));
assert_eq!(from_str(
"{".to_owned() +
"\"a\": 1.0, " +
"\"b\": [" +
"true," +
"\"foo\\nbar\", " +
"{ \"c\": {\"d\": null} } " +
"]" +
"}").unwrap(),
"{\
\"a\": 1.0, \
\"b\": [\
true,\
\"foo\\nbar\", \
{ \"c\": {\"d\": null} } \
]\
}").unwrap(),
mk_object([
("a".to_owned(), Number(1.0)),
("b".to_owned(), List(vec![
("a".to_strbuf(), Number(1.0)),
("b".to_strbuf(), List(vec![
Boolean(true),
String("foo\nbar".to_owned()),
String("foo\nbar".to_strbuf()),
mk_object([
("c".to_owned(), mk_object([("d".to_owned(), Null)]))
("c".to_strbuf(), mk_object([("d".to_strbuf(), Null)]))
])
]))
]));
@@ -2779,14 +2806,14 @@ fn test_decode_struct() {
\"inner\": [
{ \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
]
}".to_owned();
}";
let mut decoder = Decoder::new(from_str(s).unwrap());
let v: Outer = Decodable::decode(&mut decoder).unwrap();
assert_eq!(
v,
Outer {
inner: vec![
Inner { a: (), b: 2, c: vec!["abc".to_owned(), "xyz".to_owned()] }
Inner { a: (), b: 2, c: vec!["abc".to_strbuf(), "xyz".to_strbuf()] }
]
}
);
@@ -2795,12 +2822,12 @@ fn test_decode_struct() {
#[test]
fn test_decode_option() {
let mut decoder = Decoder::new(from_str("null").unwrap());
let value: Option<~str> = Decodable::decode(&mut decoder).unwrap();
let value: Option<StrBuf> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(value, None);
let mut decoder = Decoder::new(from_str("\"jodhpurs\"").unwrap());
let value: Option<~str> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(value, Some("jodhpurs".to_owned()));
let value: Option<StrBuf> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(value, Some("jodhpurs".to_strbuf()));
}
#[test]
@@ -2812,18 +2839,18 @@ fn test_decode_enum() {
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
let mut decoder = Decoder::new(from_str(s).unwrap());
let value: Animal = Decodable::decode(&mut decoder).unwrap();
assert_eq!(value, Frog("Henry".to_owned(), 349));
assert_eq!(value, Frog("Henry".to_strbuf(), 349));
}
#[test]
fn test_decode_map() {
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
\"fields\":[\"Henry\", 349]}}".to_owned();
\"fields\":[\"Henry\", 349]}}";
let mut decoder = Decoder::new(from_str(s).unwrap());
let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder).unwrap();
let mut map: TreeMap<StrBuf, Animal> = Decodable::decode(&mut decoder).unwrap();
assert_eq!(map.pop(&"a".to_owned()), Some(Dog));
assert_eq!(map.pop(&"b".to_owned()), Some(Frog("Henry".to_owned(), 349)));
assert_eq!(map.pop(&"a".to_strbuf()), Some(Dog));
assert_eq!(map.pop(&"b".to_strbuf()), Some(Frog("Henry".to_strbuf(), 349)));
}
#[test]
@@ -2836,13 +2863,13 @@ fn test_multiline_errors() {
struct DecodeStruct {
x: f64,
y: bool,
z: ~str,
z: StrBuf,
w: Vec<DecodeStruct>
}
#[deriving(Decodable)]
enum DecodeEnum {
A(f64),
B(~str)
B(StrBuf)
}
fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
expected: DecoderError) {
@@ -2862,51 +2889,51 @@ fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
}
#[test]
fn test_decode_errors_struct() {
check_err::<DecodeStruct>("[]", ExpectedError("Object".to_owned(), "[]".to_owned()));
check_err::<DecodeStruct>("[]", ExpectedError("Object".to_strbuf(), "[]".to_strbuf()));
check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
ExpectedError("Number".to_owned(), "true".to_owned()));
ExpectedError("Number".to_strbuf(), "true".to_strbuf()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
ExpectedError("Boolean".to_owned(), "[]".to_owned()));
ExpectedError("Boolean".to_strbuf(), "[]".to_strbuf()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
ExpectedError("String".to_owned(), "{}".to_owned()));
ExpectedError("String".to_strbuf(), "{}".to_strbuf()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
ExpectedError("List".to_owned(), "null".to_owned()));
ExpectedError("List".to_strbuf(), "null".to_strbuf()));
check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}",
MissingFieldError("w".to_owned()));
MissingFieldError("w".to_strbuf()));
}
#[test]
fn test_decode_errors_enum() {
check_err::<DecodeEnum>("{}",
MissingFieldError("variant".to_owned()));
MissingFieldError("variant".to_strbuf()));
check_err::<DecodeEnum>("{\"variant\": 1}",
ExpectedError("String".to_owned(), "1".to_owned()));
ExpectedError("String".to_strbuf(), "1".to_strbuf()));
check_err::<DecodeEnum>("{\"variant\": \"A\"}",
MissingFieldError("fields".to_owned()));
MissingFieldError("fields".to_strbuf()));
check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}",
ExpectedError("List".to_owned(), "null".to_owned()));
ExpectedError("List".to_strbuf(), "null".to_strbuf()));
check_err::<DecodeEnum>("{\"variant\": \"C\", \"fields\": []}",
UnknownVariantError("C".to_owned()));
UnknownVariantError("C".to_strbuf()));
}
#[test]
fn test_find(){
let json_value = from_str("{\"dog\" : \"cat\"}").unwrap();
let found_str = json_value.find(&"dog".to_owned());
let found_str = json_value.find(&"dog".to_strbuf());
assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == "cat");
}
#[test]
fn test_find_path(){
let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap();
let found_str = json_value.find_path(&[&"dog".to_owned(),
&"cat".to_owned(), &"mouse".to_owned()]);
let found_str = json_value.find_path(&[&"dog".to_strbuf(),
&"cat".to_strbuf(), &"mouse".to_strbuf()]);
assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == "cheese");
}
#[test]
fn test_search(){
let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap();
let found_str = json_value.search(&"mouse".to_owned()).and_then(|j| j.as_string());
let found_str = json_value.search(&"mouse".to_strbuf()).and_then(|j| j.as_string());
assert!(found_str.is_some());
assert!(found_str.unwrap() == "cheese");
}
@@ -3069,7 +3096,7 @@ fn test_streaming_parser() {
r#"{ "foo":"bar", "array" : [0, 1, 2,3 ,4,5], "idents":[null,true,false]}"#,
~[
(ObjectStart, ~[]),
(StringValue("bar".to_owned()), ~[Key("foo")]),
(StringValue("bar".to_strbuf()), ~[Key("foo")]),
(ListStart, ~[Key("array")]),
(NumberValue(0.0), ~[Key("array"), Index(0)]),
(NumberValue(1.0), ~[Key("array"), Index(1)]),
@@ -3158,7 +3185,7 @@ fn test_read_object_streaming() {
(NumberValue(1.0), ~[Key("a")]),
(ListStart, ~[Key("b")]),
(BooleanValue(true), ~[Key("b"), Index(0)]),
(StringValue("foo\nbar".to_owned()), ~[Key("b"), Index(1)]),
(StringValue("foo\nbar".to_strbuf()), ~[Key("b"), Index(1)]),
(ObjectStart, ~[Key("b"), Index(2)]),
(ObjectStart, ~[Key("b"), Index(2), Key("c")]),
(NullValue, ~[Key("b"), Index(2), Key("c"), Key("d")]),
@@ -3291,7 +3318,7 @@ fn test_stack() {
assert!(stack.last_is_index());
assert!(stack.get(0) == Index(1));
stack.push_key("foo".to_owned());
stack.push_key("foo".to_strbuf());
assert!(stack.len() == 2);
assert!(stack.is_equal_to([Index(1), Key("foo")]));
@@ -3303,7 +3330,7 @@ fn test_stack() {
assert!(stack.get(0) == Index(1));
assert!(stack.get(1) == Key("foo"));
stack.push_key("bar".to_owned());
stack.push_key("bar".to_strbuf());
assert!(stack.len() == 3);
assert!(stack.is_equal_to([Index(1), Key("foo"), Key("bar")]));
@@ -3366,12 +3393,13 @@ fn bench_small(b: &mut Bencher) {
});
}
fn big_json() -> ~str {
let mut src = "[\n".to_owned();
fn big_json() -> StrBuf {
let mut src = "[\n".to_strbuf();
for _ in range(0, 500) {
src = src + r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": [1,2,3]},"#;
src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \
[1,2,3]},"#);
}
src = src + "{}]";
src.push_str("{}]");
return src;
}
@@ -3379,7 +3407,7 @@ fn big_json() -> ~str {
fn bench_streaming_large(b: &mut Bencher) {
let src = big_json();
b.iter( || {
let mut parser = Parser::new(src.chars());
let mut parser = Parser::new(src.as_slice().chars());
loop {
match parser.next() {
None => return,
@@ -3391,6 +3419,6 @@ fn bench_streaming_large(b: &mut Bencher) {
#[bench]
fn bench_large(b: &mut Bencher) {
let src = big_json();
b.iter( || { let _ = from_str(src); });
b.iter( || { let _ = from_str(src.as_slice()); });
}
}
+2 -14
View File
@@ -108,7 +108,7 @@ pub trait Decoder<E> {
fn read_f64(&mut self) -> Result<f64, E>;
fn read_f32(&mut self) -> Result<f32, E>;
fn read_char(&mut self) -> Result<char, E>;
fn read_str(&mut self) -> Result<~str, E>;
fn read_str(&mut self) -> Result<StrBuf, E>;
// Compound types:
fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
@@ -301,18 +301,6 @@ fn encode(&self, s: &mut S) -> Result<(), E> {
}
}
impl<E, S:Encoder<E>> Encodable<S, E> for ~str {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_str(*self)
}
}
impl<E, D:Decoder<E>> Decodable<D, E> for ~str {
fn decode(d: &mut D) -> Result<~str, E> {
d.read_str()
}
}
impl<E, S:Encoder<E>> Encodable<S, E> for StrBuf {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_str(self.as_slice())
@@ -321,7 +309,7 @@ fn encode(&self, s: &mut S) -> Result<(), E> {
impl<E, D:Decoder<E>> Decodable<D, E> for StrBuf {
fn decode(d: &mut D) -> Result<StrBuf, E> {
Ok(StrBuf::from_str(try!(d.read_str())))
Ok(StrBuf::from_str(try!(d.read_str()).as_slice()))
}
}
+1 -1
View File
@@ -106,7 +106,7 @@ fn encode(&self, s: &mut S) -> Result<(), E> {
impl<D:Decoder<E>, E> Decodable<D, E> for Ident {
fn decode(d: &mut D) -> Result<Ident, E> {
Ok(str_to_ident(try!(d.read_str())))
Ok(str_to_ident(try!(d.read_str()).as_slice()))
}
}
+3 -1
View File
@@ -886,7 +886,9 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
}
match parser.errors.shift() {
Some(error) => {
cx.ecx.span_err(efmt.span, "invalid format string: " + error);
cx.ecx.span_err(efmt.span,
format_strbuf!("invalid format string: {}",
error).as_slice());
return DummyResult::raw_expr(sp);
}
None => {}
+2 -1
View File
@@ -606,7 +606,8 @@ fn equiv(&self, other: & &'a str) -> bool {
impl<D:Decoder<E>, E> Decodable<D, E> for InternedString {
fn decode(d: &mut D) -> Result<InternedString, E> {
Ok(get_name(get_ident_interner().intern(try!(d.read_str()))))
Ok(get_name(get_ident_interner().intern(
try!(d.read_str()).as_slice())))
}
}
+6 -9
View File
@@ -354,11 +354,7 @@ fn usage(binary: &str) {
pub fn parse_opts(args: &[StrBuf]) -> Option<OptRes> {
let args_ = args.tail();
let matches =
match getopts::getopts(args_.iter()
.map(|x| x.to_owned())
.collect::<Vec<_>>()
.as_slice(),
optgroups().as_slice()) {
match getopts::getopts(args_.as_slice(), optgroups().as_slice()) {
Ok(m) => m,
Err(f) => return Some(Err(f.to_err_msg().to_strbuf()))
};
@@ -388,7 +384,8 @@ pub fn parse_opts(args: &[StrBuf]) -> Option<OptRes> {
let ratchet_metrics = ratchet_metrics.map(|s| Path::new(s));
let ratchet_noise_percent = matches.opt_str("ratchet-noise-percent");
let ratchet_noise_percent = ratchet_noise_percent.map(|s| from_str::<f64>(s).unwrap());
let ratchet_noise_percent =
ratchet_noise_percent.map(|s| from_str::<f64>(s.as_slice()).unwrap());
let save_metrics = matches.opt_str("save-metrics");
let save_metrics = save_metrics.map(|s| Path::new(s));
@@ -1068,8 +1065,8 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
impl ToJson for Metric {
fn to_json(&self) -> json::Json {
let mut map = box TreeMap::new();
map.insert("value".to_owned(), json::Number(self.value));
map.insert("noise".to_owned(), json::Number(self.noise));
map.insert("value".to_strbuf(), json::Number(self.value));
map.insert("noise".to_strbuf(), json::Number(self.noise));
json::Object(map)
}
}
@@ -1106,7 +1103,7 @@ pub fn save(&self, p: &Path) -> io::IoResult<()> {
// FIXME(pcwalton): Yuck.
let mut new_map = TreeMap::new();
for (ref key, ref value) in map.iter() {
new_map.insert(key.to_owned(), (*value).clone());
new_map.insert(key.to_strbuf(), (*value).clone());
}
new_map.to_json().to_pretty_writer(&mut file)
+1 -1
View File
@@ -192,7 +192,7 @@ pub fn tzset() {
/// Holds a calendar date and time broken down into its components (year, month, day, and so on),
/// also called a broken-down time value.
#[deriving(Clone, Eq, Encodable, Decodable, Show)]
#[deriving(Clone, Eq, Show)]
pub struct Tm {
/// Seconds after the minute [0, 60]
pub tm_sec: i32,
+1 -1
View File
@@ -500,7 +500,7 @@ fn encode(&self, e: &mut T) -> Result<(), E> {
impl<T: Decoder<E>, E> Decodable<T, E> for Uuid {
/// Decode a UUID from a string
fn decode(d: &mut T) -> Result<Uuid, E> {
Ok(from_str(try!(d.read_str())).unwrap())
Ok(from_str(try!(d.read_str()).as_slice()).unwrap())
}
}
+7 -4
View File
@@ -190,7 +190,7 @@ fn save(&self) -> io::IoResult<()> {
// FIXME(pcwalton): Yuck.
let mut new_db_cache = TreeMap::new();
for (ref k, ref v) in self.db_cache.iter() {
new_db_cache.insert((*k).to_owned(), (*v).to_owned());
new_db_cache.insert((*k).to_strbuf(), (*v).to_strbuf());
}
new_db_cache.to_json().to_pretty_writer(&mut f)
@@ -513,10 +513,13 @@ fn make_path(filename: StrBuf) -> Path {
let pth = pth.clone();
let contents = File::open(&pth).read_to_end().unwrap();
let file_content = from_utf8(contents.as_slice()).unwrap().to_owned();
let file_content = from_utf8(contents.as_slice()).unwrap()
.to_strbuf();
// FIXME (#9639): This needs to handle non-utf8 paths
prep.declare_input("file", pth.as_str().unwrap(), file_content);
prep.declare_input("file",
pth.as_str().unwrap(),
file_content.as_slice());
prep.exec(proc(_exe) {
let out = make_path("foo.o".to_strbuf());
let compiler = if cfg!(windows) {"gcc"} else {"cc"};
@@ -526,7 +529,7 @@ fn make_path(filename: StrBuf) -> Path {
// Could run sub-rules inside here.
// FIXME (#9639): This needs to handle non-utf8 paths
out.as_str().unwrap().to_owned()
out.as_str().unwrap().to_strbuf()
})
});
+1 -1
View File
@@ -55,7 +55,7 @@ struct Config {
fn parse_opts(argv: Vec<StrBuf> ) -> Config {
let opts = vec!(getopts::optflag("", "stress", ""));
let argv = argv.iter().map(|x| x.to_str()).collect::<Vec<_>>();
let argv = argv.iter().map(|x| x.to_strbuf()).collect::<Vec<_>>();
let opt_args = argv.slice(1, argv.len());
match getopts::getopts(opt_args, opts.as_slice()) {
+1 -1
View File
@@ -23,7 +23,7 @@ enum object {
fn lookup(table: Box<json::Object>, key: StrBuf, default: StrBuf) -> StrBuf
{
match table.find(&key.to_owned()) {
match table.find(&key.to_strbuf()) {
option::Some(&json::String(ref s)) => {
(*s).to_strbuf()
}