diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2012-08-24 15:28:43 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-08-24 15:51:16 -0700 |
| commit | c284b8b1dc348ab8b9c82350dd1b4e53fac1225c (patch) | |
| tree | 99de39b149969275f6f9ddebd7a9f555d91c5bff | |
| parent | a8f1bee4574b8427a052e2fad93a90839288584b (diff) | |
| download | rust-c284b8b1dc348ab8b9c82350dd1b4e53fac1225c.tar.gz rust-c284b8b1dc348ab8b9c82350dd1b4e53fac1225c.zip | |
Start using core::path2::Path in a lot of places.
43 files changed, 1135 insertions, 1111 deletions
diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index 2330078a7bb..abd50520f50 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -43,12 +43,12 @@ type source = @{ type cargo = { pgp: bool, - root: ~str, - installdir: ~str, - bindir: ~str, - libdir: ~str, - workdir: ~str, - sourcedir: ~str, + root: Path, + installdir: Path, + bindir: Path, + libdir: Path, + workdir: Path, + sourcedir: Path, sources: map::hashmap<~str, source>, mut current_install: ~str, dep_cache: map::hashmap<~str, bool>, @@ -185,7 +185,7 @@ fn has_archive_extension(p: ~str) -> bool { } fn is_archive_path(u: ~str) -> bool { - has_archive_extension(u) && os::path_exists(u) + has_archive_extension(u) && os::path_exists(&Path(u)) } fn is_archive_url(u: ~str) -> bool { @@ -209,7 +209,7 @@ fn assume_source_method(url: ~str) -> ~str { if is_git_url(url) { return ~"git"; } - if str::starts_with(url, ~"file://") || os::path_exists(url) { + if str::starts_with(url, ~"file://") || os::path_exists(&Path(url)) { return ~"file"; } @@ -238,7 +238,7 @@ fn load_link(mis: ~[@ast::meta_item]) -> (option<~str>, (name, vers, uuid) } -fn load_crate(filename: ~str) -> option<crate> { +fn load_crate(filename: &Path) -> option<crate> { let sess = parse::new_parse_sess(none); let c = parse::parse_crate_from_crate_file(filename, ~[], sess); @@ -368,10 +368,10 @@ fn rest(s: ~str, start: uint) -> ~str { } } -fn need_dir(s: ~str) { +fn need_dir(s: &Path) { if os::path_is_dir(s) { return; } if !os::make_dir(s, 493_i32 /* oct: 755 */) { - fail fmt!("can't make_dir %s", s); + fail fmt!("can't make_dir %s", s.to_str()); } } @@ -411,7 +411,7 @@ fn parse_source(name: ~str, j: json::json) -> source { _ => none }; if method == ~"file" { - url = os::make_absolute(url); + url = os::make_absolute(&Path(url)).to_str(); } return @{ name: name, @@ -425,7 +425,7 @@ fn parse_source(name: ~str, j: json::json) -> source { }; } -fn try_parse_sources(filename: ~str, sources: map::hashmap<~str, source>) { +fn try_parse_sources(filename: &Path, sources: map::hashmap<~str, source>) { if !os::path_exists(filename) { return; } let c = io::read_whole_file_str(filename); match json::from_str(result::get(c)) { @@ -436,7 +436,7 @@ fn try_parse_sources(filename: ~str, sources: map::hashmap<~str, source>) { } } ok(_) => fail ~"malformed sources.json", - err(e) => fail fmt!("%s:%s", filename, e.to_str()) + err(e) => fail fmt!("%s:%s", filename.to_str(), e.to_str()) } } @@ -543,10 +543,10 @@ fn load_one_source_package(src: source, p: map::hashmap<~str, json::json>) { } fn load_source_info(c: cargo, src: source) { - let dir = path::connect(c.sourcedir, src.name); - let srcfile = path::connect(dir, ~"source.json"); - if !os::path_exists(srcfile) { return; } - let srcstr = io::read_whole_file_str(srcfile); + let dir = c.sourcedir.push(src.name); + let srcfile = dir.push("source.json"); + if !os::path_exists(&srcfile) { return; } + let srcstr = io::read_whole_file_str(&srcfile); match json::from_str(result::get(srcstr)) { ok(json::dict(s)) => { let o = parse_source(src.name, json::dict(s)); @@ -565,10 +565,10 @@ fn load_source_info(c: cargo, src: source) { } fn load_source_packages(c: cargo, src: source) { log(debug, ~"loading source: " + src.name); - let dir = path::connect(c.sourcedir, src.name); - let pkgfile = path::connect(dir, ~"packages.json"); - if !os::path_exists(pkgfile) { return; } - let pkgstr = io::read_whole_file_str(pkgfile); + let dir = c.sourcedir.push(src.name); + let pkgfile = dir.push("packages.json"); + if !os::path_exists(&pkgfile) { return; } + let pkgstr = io::read_whole_file_str(&pkgfile); match json::from_str(result::get(pkgstr)) { ok(json::list(js)) => { for (*js).each |j| { @@ -639,8 +639,8 @@ fn configure(opts: options) -> cargo { let p = result::get(get_cargo_dir()); let sources = map::str_hash(); - try_parse_sources(path::connect(home, ~"sources.json"), sources); - try_parse_sources(path::connect(home, ~"local-sources.json"), sources); + try_parse_sources(&home.push("sources.json"), sources); + try_parse_sources(&home.push("local-sources.json"), sources); let dep_cache = map::str_hash(); @@ -648,22 +648,22 @@ fn configure(opts: options) -> cargo { pgp: pgp::supported(), root: home, installdir: p, - bindir: path::connect(p, ~"bin"), - libdir: path::connect(p, ~"lib"), - workdir: path::connect(p, ~"work"), - sourcedir: path::connect(home, ~"sources"), + bindir: p.push("bin"), + libdir: p.push("lib"), + workdir: p.push("work"), + sourcedir: home.push("sources"), sources: sources, mut current_install: ~"", dep_cache: dep_cache, opts: opts }; - need_dir(c.root); - need_dir(c.installdir); - need_dir(c.sourcedir); - need_dir(c.workdir); - need_dir(c.libdir); - need_dir(c.bindir); + need_dir(&c.root); + need_dir(&c.installdir); + need_dir(&c.sourcedir); + need_dir(&c.workdir); + need_dir(&c.libdir); + need_dir(&c.bindir); for sources.each_key |k| { let mut s = sources.get(k); @@ -672,7 +672,7 @@ fn configure(opts: options) -> cargo { } if c.pgp { - pgp::init(c.root); + pgp::init(&c.root); } else { warn(~"command `gpg` was not found"); warn(~"you have to install gpg from source " + @@ -694,22 +694,24 @@ fn for_each_package(c: cargo, b: fn(source, package)) { } // Runs all programs in directory <buildpath> -fn run_programs(buildpath: ~str) { +fn run_programs(buildpath: &Path) { let newv = os::list_dir_path(buildpath); for newv.each |ct| { - run::run_program(ct, ~[]); + run::run_program(ct.to_str(), ~[]); } } // Runs rustc in <path + subdir> with the given flags -// and returns <path + subdir> -fn run_in_buildpath(what: ~str, path: ~str, subdir: ~str, cf: ~str, - extra_flags: ~[~str]) -> option<~str> { - let buildpath = path::connect(path, subdir); - need_dir(buildpath); - debug!("%s: %s -> %s", what, cf, buildpath); +// and returns <patho + subdir> +fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path, + extra_flags: ~[~str]) -> option<Path> { + let buildpath = path.push_rel(subdir); + need_dir(&buildpath); + debug!("%s: %s -> %s", what, cf.to_str(), buildpath.to_str()); let p = run::program_output(rustc_sysroot(), - ~[~"--out-dir", buildpath, cf] + extra_flags); + ~[~"--out-dir", + buildpath.to_str(), + cf.to_str()] + extra_flags); if p.status != 0 { error(fmt!("rustc failed: %d\n%s\n%s", p.status, p.err, p.out)); return none; @@ -717,37 +719,42 @@ fn run_in_buildpath(what: ~str, path: ~str, subdir: ~str, cf: ~str, some(buildpath) } -fn test_one_crate(_c: cargo, path: ~str, cf: ~str) { - let buildpath = match run_in_buildpath(~"testing", path, ~"/test", cf, - ~[ ~"--test"]) { +fn test_one_crate(_c: cargo, path: &Path, cf: &Path) { + let buildpath = match run_in_buildpath(~"testing", path, + &Path("test"), + cf, + ~[ ~"--test"]) { none => return, - some(bp) => bp + some(bp) => bp }; - run_programs(buildpath); + run_programs(&buildpath); } -fn install_one_crate(c: cargo, path: ~str, cf: ~str) { +fn install_one_crate(c: cargo, path: &Path, cf: &Path) { let buildpath = match run_in_buildpath(~"installing", path, - ~"/build", cf, ~[]) { + &Path("build"), + cf, ~[]) { none => return, some(bp) => bp }; - let newv = os::list_dir_path(buildpath); + let newv = os::list_dir_path(&buildpath); let exec_suffix = os::exe_suffix(); for newv.each |ct| { - if (exec_suffix != ~"" && str::ends_with(ct, exec_suffix)) || - (exec_suffix == ~"" && !str::starts_with(path::basename(ct), - ~"lib")) { - debug!(" bin: %s", ct); - install_to_dir(ct, c.bindir); + if (exec_suffix != ~"" && str::ends_with(ct.to_str(), + exec_suffix)) || + (exec_suffix == ~"" && + !str::starts_with(option::get(ct.filename()), + ~"lib")) { + debug!(" bin: %s", ct.to_str()); + install_to_dir(ct, &c.bindir); if c.opts.mode == system_mode { // FIXME (#2662): Put this file in PATH / symlink it so it can // be used as a generic executable // `cargo install -G rustray` and `rustray file.obj` } } else { - debug!(" lib: %s", ct); - install_to_dir(ct, c.libdir); + debug!(" lib: %s", ct.to_str()); + install_to_dir(ct, &c.libdir); } } } @@ -756,23 +763,22 @@ fn install_one_crate(c: cargo, path: ~str, cf: ~str) { fn rustc_sysroot() -> ~str { match os::self_exe_path() { some(path) => { - let path = ~[path, ~"..", ~"bin", ~"rustc"]; - let rustc = path::normalize(path::connect_many(path)); - debug!(" rustc: %s", rustc); - rustc + let rustc = path.push_many([~"..", ~"bin", ~"rustc"]); + debug!(" rustc: %s", rustc.to_str()); + rustc.to_str() } none => ~"rustc" } } -fn install_source(c: cargo, path: ~str) { - debug!("source: %s", path); +fn install_source(c: cargo, path: &Path) { + debug!("source: %s", path.to_str()); os::change_dir(path); let mut cratefiles = ~[]; - for os::walk_dir(~".") |p| { - if str::ends_with(p, ~".rc") { - vec::push(cratefiles, p); + for os::walk_dir(&Path(".")) |p| { + if p.filetype() == some(~"rc") { + vec::push(cratefiles, *p); } } @@ -781,7 +787,7 @@ fn install_source(c: cargo, path: ~str) { } for cratefiles.each |cf| { - match load_crate(cf) { + match load_crate(&cf) { none => again, some(crate) => { for crate.deps.each |query| { @@ -789,28 +795,23 @@ fn install_source(c: cargo, path: ~str) { // (n.b. #1356 says "Cyclic dependency is an error // condition") - let wd_base = c.workdir + path::path_sep(); - let wd = match tempfile::mkdtemp(wd_base, ~"") { - some(wd) => wd, - none => fail fmt!("needed temp dir: %s", wd_base) - }; - - install_query(c, wd, query); + let wd = get_temp_workdir(c); + install_query(c, &wd, query); } os::change_dir(path); if c.opts.test { - test_one_crate(c, path, cf); + test_one_crate(c, path, &cf); } - install_one_crate(c, path, cf); + install_one_crate(c, path, &cf); } } } } -fn install_git(c: cargo, wd: ~str, url: ~str, reference: option<~str>) { - run::program_output(~"git", ~[~"clone", url, wd]); +fn install_git(c: cargo, wd: &Path, url: ~str, reference: option<~str>) { + run::program_output(~"git", ~[~"clone", url, wd.to_str()]); if option::is_some(reference) { let r = option::get(reference); os::change_dir(wd); @@ -820,25 +821,27 @@ fn install_git(c: cargo, wd: ~str, url: ~str, reference: option<~str>) { install_source(c, wd); } -fn install_curl(c: cargo, wd: ~str, url: ~str) { - let tarpath = path::connect(wd, ~"pkg.tar"); +fn install_curl(c: cargo, wd: &Path, url: ~str) { + let tarpath = wd.push("pkg.tar"); let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", - tarpath, url]); + tarpath.to_str(), url]); if p.status != 0 { fail fmt!("fetch of %s failed: %s", url, p.err); } run::run_program(~"tar", ~[~"-x", ~"--strip-components=1", - ~"-C", wd, ~"-f", tarpath]); + ~"-C", wd.to_str(), + ~"-f", tarpath.to_str()]); install_source(c, wd); } -fn install_file(c: cargo, wd: ~str, path: ~str) { +fn install_file(c: cargo, wd: &Path, path: &Path) { run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", - ~"-C", wd, ~"-f", path]); + ~"-C", wd.to_str(), + ~"-f", path.to_str()]); install_source(c, wd); } -fn install_package(c: cargo, src: ~str, wd: ~str, pkg: package) { +fn install_package(c: cargo, src: ~str, wd: &Path, pkg: package) { let url = copy pkg.url; let method = match pkg.method { ~"git" => ~"git", @@ -850,7 +853,7 @@ fn install_package(c: cargo, src: ~str, wd: ~str, pkg: package) { match method { ~"git" => install_git(c, wd, url, copy pkg.reference), - ~"file" => install_file(c, wd, url), + ~"file" => install_file(c, wd, &Path(url)), ~"curl" => install_curl(c, wd, copy url), _ => () } @@ -866,7 +869,7 @@ fn cargo_suggestion(c: cargo, fallback: fn()) fallback(); } -fn install_uuid(c: cargo, wd: ~str, uuid: ~str) { +fn install_uuid(c: cargo, wd: &Path, uuid: ~str) { let mut ps = ~[]; for_each_package(c, |s, p| { if p.uuid == uuid { @@ -890,7 +893,7 @@ fn install_uuid(c: cargo, wd: ~str, uuid: ~str) { } } -fn install_named(c: cargo, wd: ~str, name: ~str) { +fn install_named(c: cargo, wd: &Path, name: ~str) { let mut ps = ~[]; for_each_package(c, |s, p| { if p.name == name { @@ -914,7 +917,7 @@ fn install_named(c: cargo, wd: ~str, name: ~str) { } } -fn install_uuid_specific(c: cargo, wd: ~str, src: ~str, uuid: ~str) { +fn install_uuid_specific(c: cargo, wd: &Path, src: ~str, uuid: ~str) { match c.sources.find(src) { some(s) => { let packages = copy s.packages; @@ -930,7 +933,7 @@ fn install_uuid_specific(c: cargo, wd: ~str, src: ~str, uuid: ~str) { error(~"can't find package: " + src + ~"/" + uuid); } -fn install_named_specific(c: cargo, wd: ~str, src: ~str, name: ~str) { +fn install_named_specific(c: cargo, wd: &Path, src: ~str, name: ~str) { match c.sources.find(src) { some(s) => { let packages = copy s.packages; @@ -952,59 +955,45 @@ fn cmd_uninstall(c: cargo) { return; } - let lib = c.libdir; - let bin = c.bindir; + let lib = &c.libdir; + let bin = &c.bindir; let target = c.opts.free[2u]; // FIXME (#2662): needs stronger pattern matching // FIXME (#2662): needs to uninstall from a specified location in a // cache instead of looking for it (binaries can be uninstalled by // name only) + + fn try_uninstall(p: &Path) -> bool { + if os::remove_file(p) { + info(~"uninstalled: '" + p.to_str() + ~"'"); + true + } else { + error(~"could not uninstall: '" + + p.to_str() + ~"'"); + false + } + } + if is_uuid(target) { for os::list_dir(lib).each |file| { match str::find_str(file, ~"-" + target + ~"-") { - some(idx) => { - let full = path::normalize(path::connect(lib, file)); - if os::remove_file(full) { - info(~"uninstalled: '" + full + ~"'"); - } else { - error(~"could not uninstall: '" + full + ~"'"); - } - return; - } - none => again + some(_) => if !try_uninstall(&lib.push(file)) { return }, + none => () } } - error(~"can't find package with uuid: " + target); } else { for os::list_dir(lib).each |file| { match str::find_str(file, ~"lib" + target + ~"-") { - some(idx) => { - let full = path::normalize(path::connect(lib, - file)); - if os::remove_file(full) { - info(~"uninstalled: '" + full + ~"'"); - } else { - error(~"could not uninstall: '" + full + ~"'"); - } - return; - } - none => again + some(_) => if !try_uninstall(&lib.push(file)) { return }, + none => () } } for os::list_dir(bin).each |file| { match str::find_str(file, target) { - some(idx) => { - let full = path::normalize(path::connect(bin, file)); - if os::remove_file(full) { - info(~"uninstalled: '" + full + ~"'"); - } else { - error(~"could not uninstall: '" + full + ~"'"); - } - return; - } - none => again + some(_) => if !try_uninstall(&lib.push(file)) { return }, + none => () } } @@ -1012,7 +1001,7 @@ fn cmd_uninstall(c: cargo) { } } -fn install_query(c: cargo, wd: ~str, target: ~str) { +fn install_query(c: cargo, wd: &Path, target: ~str) { match c.dep_cache.find(target) { some(inst) => { if inst { @@ -1025,7 +1014,7 @@ fn install_query(c: cargo, wd: ~str, target: ~str) { c.dep_cache.insert(target, true); if is_archive_path(target) { - install_file(c, wd, target); + install_file(c, wd, &Path(target)); return; } else if is_git_url(target) { let reference = if c.opts.free.len() >= 4u { @@ -1072,31 +1061,36 @@ fn install_query(c: cargo, wd: ~str, target: ~str) { } } +fn get_temp_workdir(c: cargo) -> Path { + match tempfile::mkdtemp(&c.workdir, "cargo") { + some(wd) => wd, + none => fail fmt!("needed temp dir: %s", + c.workdir.to_str()) + } +} + fn cmd_install(c: cargo) unsafe { - let wd_base = c.workdir + path::path_sep(); - let wd = match tempfile::mkdtemp(wd_base, ~"") { - some(wd) => wd, - none => fail fmt!("needed temp dir: %s", wd_base) - }; + let wd = get_temp_workdir(c); if vec::len(c.opts.free) == 2u { let cwd = os::getcwd(); - let status = run::run_program(~"cp", ~[~"-R", cwd, wd]); + let status = run::run_program(~"cp", ~[~"-R", cwd.to_str(), + wd.to_str()]); if status != 0 { - fail fmt!("could not copy directory: %s", cwd); + fail fmt!("could not copy directory: %s", cwd.to_str()); } - install_source(c, wd); + install_source(c, &wd); return; } sync(c); let query = c.opts.free[2]; - c.current_install = copy query; + c.current_install = query.to_str(); - install_query(c, wd, copy query); + install_query(c, &wd, query); } fn sync(c: cargo) { @@ -1107,45 +1101,47 @@ fn sync(c: cargo) { } } -fn sync_one_file(c: cargo, dir: ~str, src: source) -> bool { +fn sync_one_file(c: cargo, dir: &Path, src: source) -> bool { let name = src.name; - let srcfile = path::connect(dir, ~"source.json.new"); - let destsrcfile = path::connect(dir, ~"source.json"); - let pkgfile = path::connect(dir, ~"packages.json.new"); - let destpkgfile = path::connect(dir, ~"packages.json"); - let keyfile = path::connect(dir, ~"key.gpg"); - let srcsigfile = path::connect(dir, ~"source.json.sig"); - let sigfile = path::connect(dir, ~"packages.json.sig"); - let url = src.url; + let srcfile = dir.push("source.json.new"); + let destsrcfile = dir.push("source.json"); + let pkgfile = dir.push("packages.json.new"); + let destpkgfile = dir.push("packages.json"); + let keyfile = dir.push("key.gpg"); + let srcsigfile = dir.push("source.json.sig"); + let sigfile = dir.push("packages.json.sig"); + let url = Path(src.url); let mut has_src_file = false; - if !os::copy_file(path::connect(url, ~"packages.json"), pkgfile) { - error(fmt!("fetch for source %s (url %s) failed", name, url)); + if !os::copy_file(&url.push("packages.json"), &pkgfile) { + error(fmt!("fetch for source %s (url %s) failed", + name, url.to_str())); return false; } - if os::copy_file(path::connect(url, ~"source.json"), srcfile) { + if os::copy_file(&url.push("source.json"), &srcfile) { has_src_file = false; } - os::copy_file(path::connect(url, ~"source.json.sig"), srcsigfile); - os::copy_file(path::connect(url, ~"packages.json.sig"), sigfile); + os::copy_file(&url.push("source.json.sig"), &srcsigfile); + os::copy_file(&url.push("packages.json.sig"), &sigfile); match copy src.key { some(u) => { let p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", keyfile, u]); + ~[~"-f", ~"-s", + ~"-o", keyfile.to_str(), u]); if p.status != 0 { error(fmt!("fetch for source %s (key %s) failed", name, u)); return false; } - pgp::add(c.root, keyfile); + pgp::add(&c.root, &keyfile); } _ => () } match (src.key, src.keyfp) { (some(_), some(f)) => { - let r = pgp::verify(c.root, pkgfile, sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); if !r { error(fmt!("signature verification failed for source %s", @@ -1154,7 +1150,7 @@ fn sync_one_file(c: cargo, dir: ~str, src: source) -> bool { } if has_src_file { - let e = pgp::verify(c.root, srcfile, srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); if !e { error(fmt!("signature verification failed for source %s", @@ -1166,33 +1162,33 @@ fn sync_one_file(c: cargo, dir: ~str, src: source) -> bool { _ => () } - copy_warn(pkgfile, destpkgfile); + copy_warn(&pkgfile, &destpkgfile); if has_src_file { - copy_warn(srcfile, destsrcfile); + copy_warn(&srcfile, &destsrcfile); } - os::remove_file(keyfile); - os::remove_file(srcfile); - os::remove_file(srcsigfile); - os::remove_file(pkgfile); - os::remove_file(sigfile); + os::remove_file(&keyfile); + os::remove_file(&srcfile); + os::remove_file(&srcsigfile); + os::remove_file(&pkgfile); + os::remove_file(&sigfile); info(fmt!("synced source: %s", name)); return true; } -fn sync_one_git(c: cargo, dir: ~str, src: source) -> bool { +fn sync_one_git(c: cargo, dir: &Path, src: source) -> bool { let name = src.name; - let srcfile = path::connect(dir, ~"source.json"); - let pkgfile = path::connect(dir, ~"packages.json"); - let keyfile = path::connect(dir, ~"key.gpg"); - let srcsigfile = path::connect(dir, ~"source.json.sig"); - let sigfile = path::connect(dir, ~"packages.json.sig"); + let srcfile = dir.push("source.json"); + let pkgfile = dir.push("packages.json"); + let keyfile = dir.push("key.gpg"); + let srcsigfile = dir.push("source.json.sig"); + let sigfile = dir.push("packages.json.sig"); let url = src.url; - fn rollback(name: ~str, dir: ~str, insecure: bool) { + fn rollback(name: ~str, dir: &Path, insecure: bool) { fn msg(name: ~str, insecure: bool) { error(fmt!("could not rollback source: %s", name)); @@ -1216,8 +1212,8 @@ fn sync_one_git(c: cargo, dir: ~str, src: source) -> bool { } } - if !os::path_exists(path::connect(dir, ~".git")) { - let p = run::program_output(~"git", ~[~"clone", url, dir]); + if !os::path_exists(&dir.push(".git")) { + let p = run::program_output(~"git", ~[~"clone", url, dir.to_str()]); if p.status != 0 { error(fmt!("fetch for source %s (url %s) failed", name, url)); @@ -1238,24 +1234,25 @@ fn sync_one_git(c: cargo, dir: ~str, src: source) -> bool { } } - let has_src_file = os::path_exists(srcfile); + let has_src_file = os::path_exists(&srcfile); match copy src.key { some(u) => { let p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", keyfile, u]); + ~[~"-f", ~"-s", + ~"-o", keyfile.to_str(), u]); if p.status != 0 { error(fmt!("fetch for source %s (key %s) failed", name, u)); rollback(name, dir, false); return false; } - pgp::add(c.root, keyfile); + pgp::add(&c.root, &keyfile); } _ => () } match (src.key, src.keyfp) { (some(_), some(f)) => { - let r = pgp::verify(c.root, pkgfile, sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); if !r { error(fmt!("signature verification failed for source %s", @@ -1265,7 +1262,7 @@ fn sync_one_git(c: cargo, dir: ~str, src: source) -> bool { } if has_src_file { - let e = pgp::verify(c.root, srcfile, srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); if !e { error(fmt!("signature verification failed for source %s", @@ -1278,22 +1275,22 @@ fn sync_one_git(c: cargo, dir: ~str, src: source) -> bool { _ => () } - os::remove_file(keyfile); + os::remove_file(&keyfile); info(fmt!("synced source: %s", name)); return true; } -fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { +fn sync_one_curl(c: cargo, dir: &Path, src: source) -> bool { let name = src.name; - let srcfile = path::connect(dir, ~"source.json.new"); - let destsrcfile = path::connect(dir, ~"source.json"); - let pkgfile = path::connect(dir, ~"packages.json.new"); - let destpkgfile = path::connect(dir, ~"packages.json"); - let keyfile = path::connect(dir, ~"key.gpg"); - let srcsigfile = path::connect(dir, ~"source.json.sig"); - let sigfile = path::connect(dir, ~"packages.json.sig"); + let srcfile = dir.push("source.json.new"); + let destsrcfile = dir.push("source.json"); + let pkgfile = dir.push("packages.json.new"); + let destpkgfile = dir.push("packages.json"); + let keyfile = dir.push("key.gpg"); + let srcsigfile = dir.push("source.json.sig"); + let sigfile = dir.push("packages.json.sig"); let mut url = src.url; let smart = !str::ends_with(src.url, ~"packages.json"); let mut has_src_file = false; @@ -1303,7 +1300,8 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { } let p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", pkgfile, url]); + ~[~"-f", ~"-s", + ~"-o", pkgfile.to_str(), url]); if p.status != 0 { error(fmt!("fetch for source %s (url %s) failed", name, url)); @@ -1313,7 +1311,8 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { url = src.url + ~"/source.json"; let p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", srcfile, url]); + ~[~"-f", ~"-s", + ~"-o", srcfile.to_str(), url]); if p.status == 0 { has_src_file = true; @@ -1323,12 +1322,13 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { match copy src.key { some(u) => { let p = run::program_output(~"curl", - ~[~"-f", ~"-s", ~"-o", keyfile, u]); + ~[~"-f", ~"-s", + ~"-o", keyfile.to_str(), u]); if p.status != 0 { error(fmt!("fetch for source %s (key %s) failed", name, u)); return false; } - pgp::add(c.root, keyfile); + pgp::add(&c.root, &keyfile); } _ => () } @@ -1341,14 +1341,15 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { url = src.url + ~".sig"; } - let mut p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", - sigfile, url]); + let mut p = run::program_output(~"curl", + ~[~"-f", ~"-s", ~"-o", + sigfile.to_str(), url]); if p.status != 0 { error(fmt!("fetch for source %s (sig %s) failed", name, url)); return false; } - let r = pgp::verify(c.root, pkgfile, sigfile, f); + let r = pgp::verify(&c.root, &pkgfile, &sigfile, f); if !r { error(fmt!("signature verification failed for source %s", @@ -1361,14 +1362,14 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", - srcsigfile, url]); + srcsigfile.to_str(), url]); if p.status != 0 { error(fmt!("fetch for source %s (sig %s) failed", name, url)); return false; } - let e = pgp::verify(c.root, srcfile, srcsigfile, f); + let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f); if !e { error(~"signature verification failed for " + @@ -1380,17 +1381,17 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { _ => () } - copy_warn(pkgfile, destpkgfile); + copy_warn(&pkgfile, &destpkgfile); if smart && has_src_file { - copy_warn(srcfile, destsrcfile); + copy_warn(&srcfile, &destsrcfile); } - os::remove_file(keyfile); - os::remove_file(srcfile); - os::remove_file(srcsigfile); - os::remove_file(pkgfile); - os::remove_file(sigfile); + os::remove_file(&keyfile); + os::remove_file(&srcfile); + os::remove_file(&srcsigfile); + os::remove_file(&pkgfile); + os::remove_file(&sigfile); info(fmt!("synced source: %s", name)); @@ -1399,16 +1400,16 @@ fn sync_one_curl(c: cargo, dir: ~str, src: source) -> bool { fn sync_one(c: cargo, src: source) { let name = src.name; - let dir = path::connect(c.sourcedir, name); + let dir = c.sourcedir.push(name); info(fmt!("syncing source: %s...", name)); - need_dir(dir); + need_dir(&dir); let result = match src.method { - ~"git" => sync_one_git(c, dir, src), - ~"file" => sync_one_file(c, dir, src), - _ => sync_one_curl(c, dir, src) + ~"git" => sync_one_git(c, &dir, src), + ~"file" => sync_one_file(c, &dir, src), + _ => sync_one_curl(c, &dir, src) }; if result { @@ -1421,35 +1422,39 @@ fn cmd_init(c: cargo) { let srcurl = ~"http://www.rust-lang.org/cargo/sources.json"; let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig"; - let srcfile = path::connect(c.root, ~"sources.json.new"); - let sigfile = path::connect(c.root, ~"sources.json.sig"); - let destsrcfile = path::connect(c.root, ~"sources.json"); + let srcfile = c.root.push("sources.json.new"); + let sigfile = c.root.push("sources.json.sig"); + let destsrcfile = c.root.push("sources.json"); let p = - run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", srcfile, srcurl]); + run::program_output(~"curl", ~[~"-f", ~"-s", + ~"-o", srcfile.to_str(), srcurl]); if p.status != 0 { error(fmt!("fetch of sources.json failed: %s", p.out)); return; } let p = - run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", sigfile, sigurl]); + run::program_output(~"curl", ~[~"-f", ~"-s", + ~"-o", sigfile.to_str(), sigurl]); if p.status != 0 { error(fmt!("fetch of sources.json.sig failed: %s", p.out)); return; } - let r = pgp::verify(c.root, srcfile, sigfile, pgp::signing_key_fp()); + let r = pgp::verify(&c.root, &srcfile, &sigfile, + pgp::signing_key_fp()); if !r { - error(fmt!("signature verification failed for '%s'", srcfile)); + error(fmt!("signature verification failed for '%s'", + srcfile.to_str())); return; } - copy_warn(srcfile, destsrcfile); - os::remove_file(srcfile); - os::remove_file(sigfile); + copy_warn(&srcfile, &destsrcfile); + os::remove_file(&srcfile); + os::remove_file(&sigfile); - info(fmt!("initialized .cargo in %s", c.root)); + info(fmt!("initialized .cargo in %s", c.root.to_str())); } fn print_pkg(s: source, p: package) { @@ -1530,25 +1535,26 @@ fn cmd_search(c: cargo) { info(fmt!("found %d packages", n)); } -fn install_to_dir(srcfile: ~str, destdir: ~str) { - let newfile = path::connect(destdir, path::basename(srcfile)); +fn install_to_dir(srcfile: &Path, destdir: &Path) { + let newfile = destdir.push(option::get(srcfile.filename())); - let status = run::run_program(~"cp", ~[~"-r", srcfile, newfile]); + let status = run::run_program(~"cp", ~[~"-r", srcfile.to_str(), + newfile.to_str()]); if status == 0 { - info(fmt!("installed: '%s'", newfile)); + info(fmt!("installed: '%s'", newfile.to_str())); } else { - error(fmt!("could not install: '%s'", newfile)); + error(fmt!("could not install: '%s'", newfile.to_str())); } } fn dump_cache(c: cargo) { - need_dir(c.root); + need_dir(&c.root); - let out = path::connect(c.root, ~"cache.json"); + let out = c.root.push("cache.json"); let _root = json::dict(map::str_hash()); - if os::path_exists(out) { - copy_warn(out, path::connect(c.root, ~"cache.json.old")); + if os::path_exists(&out) { + copy_warn(&out, &c.root.push("cache.json.old")); } } fn dump_sources(c: cargo) { @@ -1556,15 +1562,15 @@ fn dump_sources(c: cargo) { return; } - need_dir(c.root); + need_dir(&c.root); - let out = path::connect(c.root, ~"sources.json"); + let out = c.root.push("sources.json"); - if os::path_exists(out) { - copy_warn(out, path::connect(c.root, ~"sources.json.old")); + if os::path_exists(&out) { + copy_warn(&out, &c.root.push("sources.json.old")); } - match io::buffered_file_writer(out) { + match io::buffered_file_writer(&out) { result::ok(writer) => { let hash = map::str_hash(); let root = json::dict(hash); @@ -1600,9 +1606,10 @@ fn dump_sources(c: cargo) { } } -fn copy_warn(srcfile: ~str, destfile: ~str) { +fn copy_warn(srcfile: &Path, destfile: &Path) { if !os::copy_file(srcfile, destfile) { - warn(fmt!("copying %s to %s failed", srcfile, destfile)); + warn(fmt!("copying %s to %s failed", + srcfile.to_str(), destfile.to_str())); } } @@ -1894,7 +1901,7 @@ fn main(argv: ~[~str]) { let mut c = configure(o); let home = c.root; - let first_time = os::path_exists(path::connect(home, ~"sources.json")); + let first_time = os::path_exists(&home.push("sources.json")); if !first_time && o.free[1] != ~"init" { cmd_init(c); diff --git a/src/cargo/pgp.rs b/src/cargo/pgp.rs index c79d7f3bcf3..17f3a2060aa 100644 --- a/src/cargo/pgp.rs +++ b/src/cargo/pgp.rs @@ -63,11 +63,13 @@ fn supported() -> bool { r.status == 0 } -fn init(root: ~str) { - let p = path::connect(root, ~"gpg"); - if !os::path_is_dir(p) { - os::make_dir(p, 0x1c0i32); - let p = run::start_program(~"gpg", ~[~"--homedir", p, ~"--import"]); +fn init(root: &Path) { + let p = root.push("gpg"); + if !os::path_is_dir(&p) { + os::make_dir(&p, 0x1c0i32); + let p = run::start_program(~"gpg", ~[~"--homedir", + p.to_str(), + ~"--import"]); p.input().write_str(signing_key()); let s = p.finish(); if s != 0 { @@ -76,19 +78,22 @@ fn init(root: ~str) { } } -fn add(root: ~str, key: ~str) { - let path = path::connect(root, ~"gpg"); +fn add(root: &Path, key: &Path) { + let path = root.push("gpg"); let p = - run::program_output(~"gpg", ~[~"--homedir", path, ~"--import", key]); + run::program_output(~"gpg", ~[~"--homedir", path.to_str(), + ~"--import", key.to_str()]); if p.status != 0 { fail ~"pgp add failed: " + p.out; } } -fn verify(root: ~str, data: ~str, sig: ~str, keyfp: ~str) -> bool { - let path = path::connect(root, ~"gpg"); - let p = gpg(~[~"--homedir", path, ~"--with-fingerprint", ~"--verify", sig, - data]); +fn verify(root: &Path, data: &Path, sig: &Path, keyfp: ~str) -> bool { + let path = root.push("gpg"); + let p = gpg(~[~"--homedir", path.to_str(), + ~"--with-fingerprint", + ~"--verify", sig.to_str(), + data.to_str()]); let res = ~"Primary key fingerprint: " + keyfp; for str::split_char(p.err, '\n').each |line| { if line == res { return true; } diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index a7bcc8d67cc..021b138ffc1 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -10,16 +10,16 @@ type config = { run_lib_path: ~str, // The rustc executable - rustc_path: ~str, + rustc_path: Path, // The directory containing the tests to run - src_base: ~str, + src_base: Path, // The directory where programs should be built - build_base: ~str, + build_base: Path, // Directory for auxiliary libraries - aux_base: ~str, + aux_base: Path, // The name of the stage being built (stage1, etc) stage_id: ~str, @@ -34,7 +34,7 @@ type config = { filter: option<~str>, // Write out a parseable log of tests that were run - logfile: option<~str>, + logfile: option<Path>, // A command line to prefix program execution with, // for running under valgrind diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 73c824285ab..6a08c148461 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -42,12 +42,16 @@ fn parse_config(args: ~[~str]) -> config { err(f) => fail getopts::fail_str(f) }; + fn opt_path(m: getopts::matches, nm: ~str) -> Path { + Path(getopts::opt_str(m, nm)) + } + return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), - rustc_path: getopts::opt_str(matches, ~"rustc-path"), - src_base: getopts::opt_str(matches, ~"src-base"), - build_base: getopts::opt_str(matches, ~"build-base"), - aux_base: getopts::opt_str(matches, ~"aux-base"), + rustc_path: opt_path(matches, ~"rustc-path"), + src_base: opt_path(matches, ~"src-base"), + build_base: opt_path(matches, ~"build-base"), + aux_base: opt_path(matches, ~"aux-base"), stage_id: getopts::opt_str(matches, ~"stage-id"), mode: str_mode(getopts::opt_str(matches, ~"mode")), run_ignored: getopts::opt_present(matches, ~"ignored"), @@ -55,7 +59,9 @@ fn parse_config(args: ~[~str]) -> config { if vec::len(matches.free) > 0u { option::some(matches.free[0]) } else { option::none }, - logfile: getopts::opt_maybe_str(matches, ~"logfile"), + logfile: option::map(getopts::opt_maybe_str(matches, + ~"logfile"), + |s| Path(s)), runtool: getopts::opt_maybe_str(matches, ~"runtool"), rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), verbose: getopts::opt_present(matches, ~"verbose")}; @@ -66,9 +72,9 @@ fn log_config(config: config) { logv(c, fmt!("configuration:")); logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path)); logv(c, fmt!("run_lib_path: %s", config.run_lib_path)); - logv(c, fmt!("rustc_path: %s", config.rustc_path)); - logv(c, fmt!("src_base: %s", config.src_base)); - logv(c, fmt!("build_base: %s", config.build_base)); + logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str())); + logv(c, fmt!("src_base: %s", config.src_base.to_str())); + logv(c, fmt!("build_base: %s", config.build_base.to_str())); logv(c, fmt!("stage_id: %s", config.stage_id)); logv(c, fmt!("mode: %s", mode_str(config.mode))); logv(c, fmt!("run_ignored: %b", config.run_ignored)); @@ -122,18 +128,19 @@ fn test_opts(config: config) -> test::test_opts { run_ignored: config.run_ignored, logfile: match config.logfile { - option::some(s) => option::some(s), + option::some(s) => option::some(s.to_str()), option::none => option::none } } } fn make_tests(config: config) -> ~[test::test_desc] { - debug!("making tests from %s", config.src_base); + debug!("making tests from %s", + config.src_base.to_str()); let mut tests = ~[]; - for os::list_dir_path(config.src_base).each |file| { - let file = file; - debug!("inspecting file %s", file); + for os::list_dir_path(&config.src_base).each |file| { + let file = copy file; + debug!("inspecting file %s", file.to_str()); if is_test(config, file) { vec::push(tests, make_test(config, file)) } @@ -141,7 +148,7 @@ fn make_tests(config: config) -> ~[test::test_desc] { return tests; } -fn is_test(config: config, testfile: ~str) -> bool { +fn is_test(config: config, testfile: &Path) -> bool { // Pretty-printer does not work with .rc files yet let valid_extensions = match config.mode { @@ -149,7 +156,7 @@ fn is_test(config: config, testfile: ~str) -> bool { _ => ~[~".rc", ~".rs"] }; let invalid_prefixes = ~[~".", ~"#", ~"~"]; - let name = path::basename(testfile); + let name = option::get(testfile.filename()); let mut valid = false; @@ -164,7 +171,7 @@ fn is_test(config: config, testfile: ~str) -> bool { return valid; } -fn make_test(config: config, testfile: ~str) -> +fn make_test(config: config, testfile: &Path) -> test::test_desc { { name: make_test_name(config, testfile), @@ -174,12 +181,13 @@ fn make_test(config: config, testfile: ~str) -> } } -fn make_test_name(config: config, testfile: ~str) -> ~str { - fmt!("[%s] %s", mode_str(config.mode), testfile) +fn make_test_name(config: config, testfile: &Path) -> ~str { + fmt!("[%s] %s", mode_str(config.mode), testfile.to_str()) } -fn make_test_closure(config: config, testfile: ~str) -> test::test_fn { - fn~() { runtest::run(config, copy testfile) } +fn make_test_closure(config: config, testfile: &Path) -> test::test_fn { + let testfile = testfile.to_str(); + fn~() { runtest::run(config, testfile) } } // Local Variables: diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 030e1d01ab0..9dde2f86f96 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -6,7 +6,7 @@ export expected_error; type expected_error = { line: uint, kind: ~str, msg: ~str }; // Load any test directives embedded in the file -fn load_errors(testfile: ~str) -> ~[expected_error] { +fn load_errors(testfile: &Path) -> ~[expected_error] { let mut error_patterns = ~[]; let rdr = result::get(io::file_reader(testfile)); let mut line_num = 1u; diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index efaa822d015..2905537d6a1 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -14,7 +14,7 @@ type test_props = { compile_flags: option<~str>, // If present, the name of a file that this test should match when // pretty-printed - pp_exact: option<~str>, + pp_exact: option<Path>, // Modules from aux directory that should be compiled aux_builds: ~[~str], // Environment settings to use during execution @@ -22,7 +22,7 @@ type test_props = { }; // Load any test directives embedded in the file -fn load_props(testfile: ~str) -> test_props { +fn load_props(testfile: &Path) -> test_props { let mut error_patterns = ~[]; let mut aux_builds = ~[]; let mut exec_env = ~[]; @@ -59,7 +59,7 @@ fn load_props(testfile: ~str) -> test_props { }; } -fn is_test_ignored(config: config, testfile: ~str) -> bool { +fn is_test_ignored(config: config, testfile: &Path) -> bool { let mut found = false; for iter_header(testfile) |ln| { if parse_name_directive(ln, ~"xfail-test") { return true; } @@ -74,7 +74,7 @@ fn is_test_ignored(config: config, testfile: ~str) -> bool { } } -fn iter_header(testfile: ~str, it: fn(~str) -> bool) -> bool { +fn iter_header(testfile: &Path, it: fn(~str) -> bool) -> bool { let rdr = result::get(io::file_reader(testfile)); while !rdr.eof() { let ln = rdr.read_line(); @@ -114,12 +114,12 @@ fn parse_exec_env(line: ~str) -> option<(~str, ~str)> { } } -fn parse_pp_exact(line: ~str, testfile: ~str) -> option<~str> { +fn parse_pp_exact(line: ~str, testfile: &Path) -> option<Path> { match parse_name_value_directive(line, ~"pp-exact") { - option::some(s) => option::some(s), + option::some(s) => option::some(Path(s)), option::none => { if parse_name_directive(line, ~"pp-exact") { - option::some(path::basename(testfile)) + option::some(testfile.file_path()) } else { option::none } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 6498a7d8952..fa003646699 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -16,17 +16,18 @@ fn run(config: config, testfile: ~str) { // We're going to be dumping a lot of info. Start on a new line. io::stdout().write_str(~"\n\n"); } - debug!("running %s", testfile); - let props = load_props(testfile); + let testfile = Path(testfile); + debug!("running %s", testfile.to_str()); + let props = load_props(&testfile); match config.mode { - mode_compile_fail => run_cfail_test(config, props, testfile), - mode_run_fail => run_rfail_test(config, props, testfile), - mode_run_pass => run_rpass_test(config, props, testfile), - mode_pretty => run_pretty_test(config, props, testfile) + mode_compile_fail => run_cfail_test(config, props, &testfile), + mode_run_fail => run_rfail_test(config, props, &testfile), + mode_run_pass => run_rpass_test(config, props, &testfile), + mode_pretty => run_pretty_test(config, props, &testfile) } } -fn run_cfail_test(config: config, props: test_props, testfile: ~str) { +fn run_cfail_test(config: config, props: test_props, testfile: &Path) { let procres = compile_test(config, props, testfile); if procres.status == 0 { @@ -46,7 +47,7 @@ fn run_cfail_test(config: config, props: test_props, testfile: ~str) { } } -fn run_rfail_test(config: config, props: test_props, testfile: ~str) { +fn run_rfail_test(config: config, props: test_props, testfile: &Path) { let mut procres = compile_test(config, props, testfile); if procres.status != 0 { fatal_procres(~"compilation failed!", procres); } @@ -74,7 +75,7 @@ fn check_correct_failure_status(procres: procres) { } } -fn run_rpass_test(config: config, props: test_props, testfile: ~str) { +fn run_rpass_test(config: config, props: test_props, testfile: &Path) { let mut procres = compile_test(config, props, testfile); if procres.status != 0 { fatal_procres(~"compilation failed!", procres); } @@ -84,7 +85,7 @@ fn run_rpass_test(config: config, props: test_props, testfile: ~str) { if procres.status != 0 { fatal_procres(~"test run failed!", procres); } } -fn run_pretty_test(config: config, props: test_props, testfile: ~str) { +fn run_pretty_test(config: config, props: test_props, testfile: &Path) { if option::is_some(props.pp_exact) { logv(config, ~"testing for exact pretty-printing"); } else { logv(config, ~"testing for converging pretty-printing"); } @@ -111,8 +112,8 @@ fn run_pretty_test(config: config, props: test_props, testfile: ~str) { let mut expected = match props.pp_exact { option::some(file) => { - let filepath = path::connect(path::dirname(testfile), file); - result::get(io::read_whole_file_str(filepath)) + let filepath = testfile.dir_path().push_rel(&file); + result::get(io::read_whole_file_str(&filepath)) } option::none => { srcs[vec::len(srcs) - 2u] } }; @@ -136,15 +137,15 @@ fn run_pretty_test(config: config, props: test_props, testfile: ~str) { return; - fn print_source(config: config, testfile: ~str, src: ~str) -> procres { + fn print_source(config: config, testfile: &Path, src: ~str) -> procres { compose_and_run(config, testfile, make_pp_args(config, testfile), ~[], config.compile_lib_path, option::some(src)) } - fn make_pp_args(config: config, _testfile: ~str) -> procargs { + fn make_pp_args(config: config, _testfile: &Path) -> procargs { let prog = config.rustc_path; let args = ~[~"-", ~"--pretty", ~"normal"]; - return {prog: prog, args: args}; + return {prog: prog.to_str(), args: args}; } fn compare_source(expected: ~str, actual: ~str) { @@ -168,28 +169,30 @@ actual:\n\ } fn typecheck_source(config: config, props: test_props, - testfile: ~str, src: ~str) -> procres { + testfile: &Path, src: ~str) -> procres { compose_and_run_compiler( config, props, testfile, make_typecheck_args(config, testfile), option::some(src)) } - fn make_typecheck_args(config: config, testfile: ~str) -> procargs { + fn make_typecheck_args(config: config, testfile: &Path) -> procargs { let prog = config.rustc_path; let mut args = ~[~"-", - ~"--no-trans", ~"--lib", ~"-L", config.build_base, - ~"-L", aux_output_dir_name(config, testfile)]; + ~"--no-trans", ~"--lib", + ~"-L", config.build_base.to_str(), + ~"-L", + aux_output_dir_name(config, testfile).to_str()]; args += split_maybe_args(config.rustcflags); - return {prog: prog, args: args}; + return {prog: prog.to_str(), args: args}; } } fn check_error_patterns(props: test_props, - testfile: ~str, + testfile: &Path, procres: procres) { if vec::is_empty(props.error_patterns) { - fatal(~"no error pattern specified in " + testfile); + fatal(~"no error pattern specified in " + testfile.to_str()); } if procres.status == 0 { @@ -228,7 +231,7 @@ fn check_error_patterns(props: test_props, } fn check_expected_errors(expected_errors: ~[errors::expected_error], - testfile: ~str, + testfile: &Path, procres: procres) { // true if we found the error in question @@ -240,7 +243,7 @@ fn check_expected_errors(expected_errors: ~[errors::expected_error], } let prefixes = vec::map(expected_errors, |ee| { - fmt!("%s:%u:", testfile, ee.line) + fmt!("%s:%u:", testfile.to_str(), ee.line) }); // Scan and extract our error/warning messages, @@ -291,8 +294,8 @@ type procargs = {prog: ~str, args: ~[~str]}; type procres = {status: int, stdout: ~str, stderr: ~str, cmdline: ~str}; fn compile_test(config: config, props: test_props, - testfile: ~str) -> procres { - let link_args = ~[~"-L", aux_output_dir_name(config, testfile)]; + testfile: &Path) -> procres { + let link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()]; compose_and_run_compiler( config, props, testfile, make_compile_args(config, props, link_args, @@ -301,7 +304,7 @@ fn compile_test(config: config, props: test_props, } fn exec_compiled_test(config: config, props: test_props, - testfile: ~str) -> procres { + testfile: &Path) -> procres { compose_and_run(config, testfile, make_run_args(config, props, testfile), props.exec_env, @@ -311,26 +314,28 @@ fn exec_compiled_test(config: config, props: test_props, fn compose_and_run_compiler( config: config, props: test_props, - testfile: ~str, + testfile: &Path, args: procargs, input: option<~str>) -> procres { if props.aux_builds.is_not_empty() { - ensure_dir(aux_output_dir_name(config, testfile)); + ensure_dir(&aux_output_dir_name(config, testfile)); } - let extra_link_args = ~[~"-L", aux_output_dir_name(config, testfile)]; + let extra_link_args = ~[~"-L", + aux_output_dir_name(config, testfile).to_str()]; do vec::iter(props.aux_builds) |rel_ab| { - let abs_ab = path::connect(config.aux_base, rel_ab); + let abs_ab = config.aux_base.push_rel(&Path(rel_ab)); let aux_args = make_compile_args(config, props, ~[~"--lib"] + extra_link_args, - |a,b| make_lib_name(a, b, testfile), abs_ab); - let auxres = compose_and_run(config, abs_ab, aux_args, ~[], + |a,b| make_lib_name(a, b, testfile), &abs_ab); + let auxres = compose_and_run(config, &abs_ab, aux_args, ~[], config.compile_lib_path, option::none); if auxres.status != 0 { fatal_procres( - fmt!("auxiliary build of %s failed to compile: ", abs_ab), + fmt!("auxiliary build of %s failed to compile: ", + abs_ab.to_str()), auxres); } } @@ -339,14 +344,14 @@ fn compose_and_run_compiler( config.compile_lib_path, input) } -fn ensure_dir(path: Path) { +fn ensure_dir(path: &Path) { if os::path_is_dir(path) { return; } if !os::make_dir(path, 0x1c0i32) { - fail fmt!("can't make dir %s", path); + fail fmt!("can't make dir %s", path.to_str()); } } -fn compose_and_run(config: config, testfile: ~str, +fn compose_and_run(config: config, testfile: &Path, procargs: procargs, procenv: ~[(~str, ~str)], lib_path: ~str, @@ -356,28 +361,30 @@ fn compose_and_run(config: config, testfile: ~str, } fn make_compile_args(config: config, props: test_props, extras: ~[~str], - xform: fn(config, ~str) -> ~str, testfile: ~str) -> - procargs { + xform: fn(config, (&Path)) -> Path, + testfile: &Path) -> procargs { let prog = config.rustc_path; - let mut args = ~[testfile, ~"-o", xform(config, testfile), - ~"-L", config.build_base] + extras; + let mut args = ~[testfile.to_str(), + ~"-o", xform(config, testfile).to_str(), + ~"-L", config.build_base.to_str()] + + extras; args += split_maybe_args(config.rustcflags); args += split_maybe_args(props.compile_flags); - return {prog: prog, args: args}; + return {prog: prog.to_str(), args: args}; } -fn make_lib_name(config: config, auxfile: ~str, testfile: ~str) -> ~str { +fn make_lib_name(config: config, auxfile: &Path, testfile: &Path) -> Path { // what we return here is not particularly important, as it // happens; rustc ignores everything except for the directory. let auxname = output_testname(auxfile); - path::connect(aux_output_dir_name(config, testfile), auxname) + aux_output_dir_name(config, testfile).push_rel(&auxname) } -fn make_exe_name(config: config, testfile: ~str) -> ~str { - output_base_name(config, testfile) + os::exe_suffix() +fn make_exe_name(config: config, testfile: &Path) -> Path { + Path(output_base_name(config, testfile).to_str() + os::exe_suffix()) } -fn make_run_args(config: config, _props: test_props, testfile: ~str) -> +fn make_run_args(config: config, _props: test_props, testfile: &Path) -> procargs { let toolargs = { // If we've got another tool to run under (valgrind), @@ -390,7 +397,7 @@ fn make_run_args(config: config, _props: test_props, testfile: ~str) -> split_maybe_args(runtool) }; - let args = toolargs + ~[make_exe_name(config, testfile)]; + let args = toolargs + ~[make_exe_name(config, testfile).to_str()]; return {prog: args[0], args: vec::slice(args, 1u, vec::len(args))}; } @@ -408,7 +415,7 @@ fn split_maybe_args(argstr: option<~str>) -> ~[~str] { } } -fn program_output(config: config, testfile: ~str, lib_path: ~str, prog: ~str, +fn program_output(config: config, testfile: &Path, lib_path: ~str, prog: ~str, args: ~[~str], env: ~[(~str, ~str)], input: option<~str>) -> procres { let cmdline = @@ -445,37 +452,36 @@ fn lib_path_cmd_prefix(path: ~str) -> ~str { fmt!("%s=\"%s\"", util::lib_path_env_var(), util::make_new_path(path)) } -fn dump_output(config: config, testfile: ~str, out: ~str, err: ~str) { +fn dump_output(config: config, testfile: &Path, out: ~str, err: ~str) { dump_output_file(config, testfile, out, ~"out"); dump_output_file(config, testfile, err, ~"err"); maybe_dump_to_stdout(config, out, err); } -fn dump_output_file(config: config, testfile: ~str, +fn dump_output_file(config: config, testfile: &Path, out: ~str, extension: ~str) { let outfile = make_out_name(config, testfile, extension); let writer = result::get( - io::file_writer(outfile, ~[io::Create, io::Truncate])); + io::file_writer(&outfile, ~[io::Create, io::Truncate])); writer.write_str(out); } -fn make_out_name(config: config, testfile: ~str, extension: ~str) -> ~str { - output_base_name(config, testfile) + ~"." + extension +fn make_out_name(config: config, testfile: &Path, extension: ~str) -> Path { + output_base_name(config, testfile).with_filetype(extension) } -fn aux_output_dir_name(config: config, testfile: ~str) -> ~str { - output_base_name(config, testfile) + ~".libaux" +fn aux_output_dir_name(config: config, testfile: &Path) -> Path { + output_base_name(config, testfile).with_filetype("libaux") } -fn output_testname(testfile: ~str) -> ~str { - let parts = str::split_char(path::basename(testfile), '.'); - str::connect(vec::slice(parts, 0u, vec::len(parts) - 1u), ~".") +fn output_testname(testfile: &Path) -> Path { + Path(option::get(testfile.filestem())) } -fn output_base_name(config: config, testfile: ~str) -> ~str { - let base = config.build_base; - let filename = output_testname(testfile); - fmt!("%s%s.%s", base, filename, config.stage_id) +fn output_base_name(config: config, testfile: &Path) -> Path { + config.build_base + .push_rel(&output_testname(testfile)) + .with_filetype(config.stage_id) } fn maybe_dump_to_stdout(config: config, out: ~str, err: ~str) { diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 5d04ab8bf1a..7f496acda8f 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -8,7 +8,7 @@ import syntax::diagnostic; enum test_mode { tm_converge, tm_run, } type context = { mode: test_mode }; // + rng -fn write_file(filename: ~str, content: ~str) { +fn write_file(filename: &Path, content: ~str) { result::get( io::file_writer(filename, ~[io::Create, io::Truncate])) .write_str(content); @@ -18,13 +18,13 @@ fn contains(haystack: ~str, needle: ~str) -> bool { str::contains(haystack, needle) } -fn find_rust_files(&files: ~[~str], path: ~str) { - if str::ends_with(path, ~".rs") && !contains(path, ~"utf8") { +fn find_rust_files(files: &mut ~[Path], path: &Path) { + if path.filetype() == some(~"rs") && !contains(path.to_str(), ~"utf8") { // ignoring "utf8" tests because something is broken - files += ~[path]; + vec::push(*files, *path); } else if os::path_is_dir(path) - && !contains(path, ~"compile-fail") - && !contains(path, ~"build") { + && !contains(path.to_str(), ~"compile-fail") + && !contains(path.to_str(), ~"build") { for os::list_dir_path(path).each |p| { find_rust_files(files, p); } @@ -221,7 +221,7 @@ fn as_str(f: fn@(io::Writer)) -> ~str { } fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap, - filename: ~str, cx: context) { + filename: &Path, cx: context) { let stolen = steal(crate, cx.mode); let extra_exprs = vec::filter(common_exprs(), |a| safe_to_use_expr(a, cx.mode) ); @@ -235,14 +235,14 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap, fn check_variants_T<T: copy>( crate: ast::crate, codemap: codemap::codemap, - filename: ~str, + filename: &Path, thing_label: ~str, things: ~[T], stringifier: fn@(@T, syntax::parse::token::ident_interner) -> ~str, replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate, cx: context ) { - error!("%s contains %u %s objects", filename, + error!("%s contains %u %s objects", filename.to_str(), vec::len(things), thing_label); // Assuming we're not generating any token_trees @@ -253,6 +253,7 @@ fn check_variants_T<T: copy>( if L < 100u { do under(uint::min(L, 20u)) |i| { log(error, ~"Replacing... #" + uint::str(i)); + let fname = str::from_slice(filename.to_str()); do under(uint::min(L, 30u)) |j| { log(error, ~"With... " + stringifier(@things[j], intr)); let crate2 = @replacer(crate, i, things[j], cx.mode); @@ -265,7 +266,7 @@ fn check_variants_T<T: copy>( intr, diagnostic::mk_span_handler(handler, codemap), crate2, - filename, + fname, rdr, a, pprust::no_ann(), false)) @@ -276,11 +277,12 @@ fn check_variants_T<T: copy>( } tm_run => { let file_label = fmt!("rusttmp/%s_%s_%u_%u", - last_part(filename), + last_part(filename.to_str()), thing_label, i, j); let safe_to_run = !(content_is_dangerous_to_run(*str3) || has_raw_pointers(*crate2)); - check_whole_compiler(*str3, file_label, safe_to_run); + check_whole_compiler(*str3, &Path(file_label), + safe_to_run); } } } @@ -305,9 +307,9 @@ enum happiness { // - that would be tricky, requiring use of tasks or serialization // or randomness. // This seems to find plenty of bugs as it is :) -fn check_whole_compiler(code: ~str, suggested_filename_prefix: ~str, +fn check_whole_compiler(code: ~str, suggested_filename_prefix: &Path, allow_running: bool) { - let filename = suggested_filename_prefix + ~".rs"; + let filename = &suggested_filename_prefix.with_filetype("rs"); write_file(filename, code); let compile_result = check_compiling(filename); @@ -320,32 +322,32 @@ fn check_whole_compiler(code: ~str, suggested_filename_prefix: ~str, match run_result { passed | cleanly_rejected(_) | known_bug(_) => { removeIfExists(suggested_filename_prefix); - removeIfExists(suggested_filename_prefix + ~".rs"); - removeDirIfExists(suggested_filename_prefix + ~".dSYM"); + removeIfExists(&suggested_filename_prefix.with_filetype("rs")); + removeDirIfExists(&suggested_filename_prefix.with_filetype("dSYM")); } failed(s) => { log(error, ~"check_whole_compiler failure: " + s); - log(error, ~"Saved as: " + filename); + log(error, ~"Saved as: " + filename.to_str()); } } } -fn removeIfExists(filename: ~str) { +fn removeIfExists(filename: &Path) { // So sketchy! - assert !contains(filename, ~" "); - run::program_output(~"bash", ~[~"-c", ~"rm " + filename]); + assert !contains(filename.to_str(), ~" "); + run::program_output(~"bash", ~[~"-c", ~"rm " + filename.to_str()]); } -fn removeDirIfExists(filename: ~str) { +fn removeDirIfExists(filename: &Path) { // So sketchy! - assert !contains(filename, ~" "); - run::program_output(~"bash", ~[~"-c", ~"rm -r " + filename]); + assert !contains(filename.to_str(), ~" "); + run::program_output(~"bash", ~[~"-c", ~"rm -r " + filename.to_str()]); } -fn check_running(exe_filename: ~str) -> happiness { +fn check_running(exe_filename: &Path) -> happiness { let p = run::program_output( ~"/Users/jruderman/scripts/timed_run_rust_program.py", - ~[exe_filename]); + ~[exe_filename.to_str()]); let comb = p.out + ~"\n" + p.err; if str::len(comb) > 1u { log(error, ~"comb comb comb: " + comb); @@ -381,11 +383,11 @@ fn check_running(exe_filename: ~str) -> happiness { } } -fn check_compiling(filename: ~str) -> happiness { +fn check_compiling(filename: &Path) -> happiness { let p = run::program_output( ~"/Users/jruderman/code/rust/build/x86_64-apple-darwin/\ stage1/bin/rustc", - ~[filename]); + ~[filename.to_str()]); //error!("Status: %d", p.status); if p.status == 0 { @@ -415,11 +417,11 @@ fn check_compiling(filename: ~str) -> happiness { fn parse_and_print(code: @~str) -> ~str { - let filename = ~"tmp.rs"; + let filename = Path("tmp.rs"); let sess = parse::new_parse_sess(option::none); - write_file(filename, *code); + write_file(&filename, *code); let crate = parse::parse_crate_from_source_str( - filename, code, ~[], sess); + filename.to_str(), code, ~[], sess); do io::with_str_reader(*code) |rdr| { as_str(|a| pprust::print_crate( @@ -428,7 +430,7 @@ fn parse_and_print(code: @~str) -> ~str { syntax::parse::token::mk_fake_ident_interner(), sess.span_diagnostic, crate, - filename, + filename.to_str(), rdr, a, pprust::no_ann(), false) ) @@ -486,7 +488,7 @@ fn content_might_not_converge(code: ~str) -> bool { return false; } -fn file_might_not_converge(filename: ~str) -> bool { +fn file_might_not_converge(filename: &Path) -> bool { let confusing_files = ~[ ~"expr-alt.rs", // pretty-printing "(a = b) = c" // vs "a = b = c" and wrapping @@ -496,7 +498,11 @@ fn file_might_not_converge(filename: ~str) -> bool { ]; - for confusing_files.each |f| { if contains(filename, f) { return true; } } + for confusing_files.each |f| { + if contains(filename.to_str(), f) { + return true; + } + } return false; } @@ -519,8 +525,8 @@ fn check_roundtrip_convergence(code: @~str, maxIters: uint) { error!("Converged after %u iterations", i); } else { error!("Did not converge after %u iterations!", i); - write_file(~"round-trip-a.rs", *oldv); - write_file(~"round-trip-b.rs", *newv); + write_file(&Path("round-trip-a.rs"), *oldv); + write_file(&Path("round-trip-b.rs"), *newv); run::run_program(~"diff", ~[~"-w", ~"-u", ~"round-trip-a.rs", ~"round-trip-b.rs"]); @@ -528,13 +534,13 @@ fn check_roundtrip_convergence(code: @~str, maxIters: uint) { } } -fn check_convergence(files: ~[~str]) { +fn check_convergence(files: &[Path]) { error!("pp convergence tests: %u files", vec::len(files)); for files.each |file| { - if !file_might_not_converge(file) { - let s = @result::get(io::read_whole_file_str(file)); + if !file_might_not_converge(&file) { + let s = @result::get(io::read_whole_file_str(&file)); if !content_might_not_converge(*s) { - error!("pp converge: %s", file); + error!("pp converge: %s", file.to_str()); // Change from 7u to 2u once // https://github.com/mozilla/rust/issues/850 is fixed check_roundtrip_convergence(s, 7u); @@ -543,15 +549,16 @@ fn check_convergence(files: ~[~str]) { } } -fn check_variants(files: ~[~str], cx: context) { +fn check_variants(files: &[Path], cx: context) { for files.each |file| { - if cx.mode == tm_converge && file_might_not_converge(file) { + if cx.mode == tm_converge && + file_might_not_converge(&file) { error!("Skipping convergence test based on\ file_might_not_converge"); again; } - let s = @result::get(io::read_whole_file_str(file)); + let s = @result::get(io::read_whole_file_str(&file)); if contains(*s, ~"#") { again; // Macros are confusing } @@ -562,11 +569,11 @@ fn check_variants(files: ~[~str], cx: context) { again; } - log(error, ~"check_variants: " + file); + log(error, ~"check_variants: " + file.to_str()); let sess = parse::new_parse_sess(option::none); let crate = parse::parse_crate_from_source_str( - file, + file.to_str(), s, ~[], sess); io::with_str_reader(*s, |rdr| { error!("%s", @@ -576,12 +583,12 @@ fn check_variants(files: ~[~str], cx: context) { syntax::parse::token::mk_fake_ident_interner(), sess.span_diagnostic, crate, - file, + file.to_str(), rdr, a, pprust::no_ann(), false) )) }); - check_variants_of_ast(*crate, sess.cm, file, cx); + check_variants_of_ast(*crate, sess.cm, &file, cx); } } @@ -591,9 +598,9 @@ fn main(args: ~[~str]) { return; } let mut files = ~[]; - let root = args[1]; + let root = Path(args[1]); - find_rust_files(files, root); + find_rust_files(&mut files, &root); error!("== check_convergence =="); check_convergence(files); error!("== check_variants: converge =="); diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 4b1ace5651b..84c0568797c 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -54,7 +54,7 @@ export send_map; export hash; export cmp; export num; -export path; +export path, path2; export managed; // NDM seems to be necessary for resolve to work diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 2f7ae426517..c95a42ea3ec 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -4,7 +4,12 @@ import option::{some, none}; import option = option::option; -import Path = path::Path; + +import Path = path2::Path; +import GenericPath = path2::GenericPath; +import WindowsPath = path2::WindowsPath; +import PosixPath = path2::PosixPath; + import tuple::{TupleOps, ExtendedTupleOps}; import str::{StrSlice, UniqueStr}; import vec::{ConstVector, CopyableVector, ImmutableVector}; @@ -14,7 +19,8 @@ import num::Num; import ptr::Ptr; import to_str::ToStr; -export Path, option, some, none, unreachable; +export Path, WindowsPath, PosixPath, GenericPath; +export option, some, none, unreachable; export extensions; // The following exports are the extension impls for numeric types export Num, Times, TimesIx; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index a2b02f55b22..452aae49984 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -257,13 +257,14 @@ fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader { fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader } -fn file_reader(path: ~str) -> result<Reader, ~str> { - let f = os::as_c_charp(path, |pathbuf| { - os::as_c_charp(~"r", |modebuf| +fn file_reader(path: &Path) -> result<Reader, ~str> { + let f = os::as_c_charp(path.to_str(), |pathbuf| { + os::as_c_charp("r", |modebuf| libc::fopen(pathbuf, modebuf) ) }); - return if f as uint == 0u { result::err(~"error opening " + path) } + return if f as uint == 0u { result::err(~"error opening " + + path.to_str()) } else { result::ok(FILE_reader(f, true)) } @@ -412,7 +413,7 @@ fn fd_writer(fd: fd_t, cleanup: bool) -> Writer { } -fn mk_file_writer(path: ~str, flags: ~[FileFlag]) +fn mk_file_writer(path: &Path, flags: ~[FileFlag]) -> result<Writer, ~str> { #[cfg(windows)] @@ -430,12 +431,13 @@ fn mk_file_writer(path: ~str, flags: ~[FileFlag]) NoFlag => () } } - let fd = do os::as_c_charp(path) |pathbuf| { + let fd = do os::as_c_charp(path.to_str()) |pathbuf| { libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int) }; if fd < (0 as c_int) { - result::err(fmt!("error opening %s: %s", path, os::last_os_error())) + result::err(fmt!("error opening %s: %s", path.to_str(), + os::last_os_error())) } else { result::ok(fd_writer(fd, true)) } @@ -614,19 +616,20 @@ impl<T: Writer> T : WriterUtil { fn write_u8(n: u8) { self.write(&[n]) } } -fn file_writer(path: ~str, flags: ~[FileFlag]) -> result<Writer, ~str> { +fn file_writer(path: &Path, flags: ~[FileFlag]) -> result<Writer, ~str> { result::chain(mk_file_writer(path, flags), |w| result::ok(w)) } // FIXME: fileflags // #2004 -fn buffered_file_writer(path: ~str) -> result<Writer, ~str> { - let f = do os::as_c_charp(path) |pathbuf| { - do os::as_c_charp(~"w") |modebuf| { +fn buffered_file_writer(path: &Path) -> result<Writer, ~str> { + let f = do os::as_c_charp(path.to_str()) |pathbuf| { + do os::as_c_charp("w") |modebuf| { libc::fopen(pathbuf, modebuf) } }; - return if f as uint == 0u { result::err(~"error opening " + path) } + return if f as uint == 0u { result::err(~"error opening " + + path.to_str()) } else { result::ok(FILE_writer(f, true)) } } @@ -709,19 +712,19 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) -> return bpos as uint; } -fn read_whole_file_str(file: ~str) -> result<~str, ~str> { +fn read_whole_file_str(file: &Path) -> result<~str, ~str> { result::chain(read_whole_file(file), |bytes| { if str::is_utf8(bytes) { result::ok(str::from_bytes(bytes)) } else { - result::err(file + ~" is not UTF-8") + result::err(file.to_str() + ~" is not UTF-8") } }) } // FIXME (#2004): implement this in a low-level way. Going through the // abstractions is pointless. -fn read_whole_file(file: ~str) -> result<~[u8], ~str> { +fn read_whole_file(file: &Path) -> result<~[u8], ~str> { result::chain(file_reader(file), |rdr| { result::ok(rdr.read_whole_stream()) }) @@ -810,7 +813,7 @@ mod tests { #[test] fn test_simple() { - let tmpfile: ~str = ~"tmp/lib-io-test-simple.tmp"; + let tmpfile = &Path("tmp/lib-io-test-simple.tmp"); log(debug, tmpfile); let frood: ~str = ~"A hoopy frood who really knows where his towel is."; @@ -881,7 +884,7 @@ mod tests { #[test] fn file_reader_not_exist() { - match io::file_reader(~"not a file") { + match io::file_reader(&Path("not a file")) { result::err(e) => { assert e == ~"error opening not a file"; } @@ -891,9 +894,9 @@ mod tests { #[test] fn file_writer_bad_name() { - match io::file_writer(~"?/?", ~[]) { + match io::file_writer(&Path("?/?"), ~[]) { result::err(e) => { - assert str::starts_with(e, ~"error opening ?/?"); + assert str::starts_with(e, "error opening"); } result::ok(_) => fail } @@ -901,9 +904,9 @@ mod tests { #[test] fn buffered_file_writer_bad_name() { - match io::buffered_file_writer(~"?/?") { + match io::buffered_file_writer(&Path("?/?")) { result::err(e) => { - assert e == ~"error opening ?/?"; + assert str::starts_with(e, "error opening"); } result::ok(_) => fail } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 749cb246af2..4fb3e744235 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -1,3 +1,7 @@ +// NB: transitionary, de-mode-ing. +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + /*! * Higher-level interfaces to libc::* functions and operating system services. * @@ -16,16 +20,12 @@ * to write OS-ignorant code by default. */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - import libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t, mode_t, pid_t, FILE}; import libc::{close, fclose}; import option::{some, none}; -import getcwd = rustrt::rust_getcwd; import consts::*; import task::TaskBuilder; @@ -56,7 +56,11 @@ extern mod rustrt { const tmpbuf_sz : uint = 1000u; -fn as_c_charp<T>(+s: ~str, f: fn(*c_char) -> T) -> T { +fn getcwd() -> Path { + Path(rustrt::rust_getcwd()) +} + +fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T { str::as_c_str(s, |b| f(b as *c_char)) } @@ -106,7 +110,7 @@ mod win32 { return res; } - fn as_utf16_p<T>(+s: ~str, f: fn(*u16) -> T) -> T { + fn as_utf16_p<T>(s: &str, f: fn(*u16) -> T) -> T { let mut t = str::to_utf16(s); // Null terminate before passing on. t += ~[0u16]; @@ -114,11 +118,11 @@ mod win32 { } } -fn getenv(+n: ~str) -> option<~str> { +fn getenv(n: &str) -> option<~str> { global_env::getenv(n) } -fn setenv(+n: ~str, +v: ~str) { +fn setenv(n: &str, v: &str) { global_env::setenv(n, v) } @@ -143,17 +147,20 @@ mod global_env { MsgEnv(comm::Chan<~[(~str,~str)]>) } - fn getenv(+n: ~str) -> option<~str> { + fn getenv(n: &str) -> option<~str> { let env_ch = get_global_env_chan(); let po = comm::port(); - comm::send(env_ch, MsgGetEnv(n, comm::chan(po))); + comm::send(env_ch, MsgGetEnv(str::from_slice(n), + comm::chan(po))); comm::recv(po) } - fn setenv(+n: ~str, +v: ~str) { + fn setenv(n: &str, v: &str) { let env_ch = get_global_env_chan(); let po = comm::port(); - comm::send(env_ch, MsgSetEnv(n, v, comm::chan(po))); + comm::send(env_ch, MsgSetEnv(str::from_slice(n), + str::from_slice(v), + comm::chan(po))); comm::recv(po) } @@ -212,7 +219,7 @@ mod global_env { } #[cfg(unix)] - fn getenv(+n: ~str) -> option<~str> { + fn getenv(n: &str) -> option<~str> { unsafe { let s = str::as_c_str(n, libc::getenv); return if unsafe::reinterpret_cast(s) == 0 { @@ -225,7 +232,7 @@ mod global_env { } #[cfg(windows)] - fn getenv(+n: ~str) -> option<~str> { + fn getenv(n: &str) -> option<~str> { import libc::types::os::arch::extra::*; import libc::funcs::extra::kernel32::*; import win32::*; @@ -238,7 +245,7 @@ mod global_env { #[cfg(unix)] - fn setenv(+n: ~str, +v: ~str) { + fn setenv(n: &str, v: &str) { // FIXME: remove this when export globs work properly. #1238 import libc::funcs::posix01::unistd::setenv; @@ -251,7 +258,7 @@ mod global_env { #[cfg(windows)] - fn setenv(+n: ~str, +v: ~str) { + fn setenv(n: &str, v: &str) { // FIXME: remove imports when export globs work properly. #1238 import libc::funcs::extra::kernel32::*; import win32::*; @@ -266,7 +273,7 @@ mod global_env { } fn fdopen(fd: c_int) -> *FILE { - return do as_c_charp(~"r") |modebuf| { + return do as_c_charp("r") |modebuf| { libc::fdopen(fd, modebuf) }; } @@ -365,8 +372,8 @@ fn dup2(src: c_int, dst: c_int) -> c_int { } -fn dll_filename(+base: ~str) -> ~str { - return pre() + base + dll_suffix(); +fn dll_filename(base: &str) -> ~str { + return pre() + str::from_slice(base) + dll_suffix(); #[cfg(unix)] fn pre() -> ~str { ~"lib" } @@ -379,7 +386,7 @@ fn dll_filename(+base: ~str) -> ~str { fn self_exe_path() -> option<Path> { #[cfg(target_os = "freebsd")] - fn load_self() -> option<Path> { + fn load_self() -> option<~str> { unsafe { import libc::funcs::bsd44::*; import libc::consts::os::extra::*; @@ -395,17 +402,17 @@ fn self_exe_path() -> option<Path> { } #[cfg(target_os = "linux")] - fn load_self() -> option<Path> { + fn load_self() -> option<~str> { import libc::funcs::posix01::unistd::readlink; do fill_charp_buf() |buf, sz| { - do as_c_charp(~"/proc/self/exe") |proc_self_buf| { + do as_c_charp("/proc/self/exe") |proc_self_buf| { readlink(proc_self_buf, buf, sz) != (-1 as ssize_t) } } } #[cfg(target_os = "macos")] - fn load_self() -> option<Path> { + fn load_self() -> option<~str> { // FIXME: remove imports when export globs work properly. #1238 import libc::funcs::extra::*; do fill_charp_buf() |buf, sz| { @@ -415,7 +422,7 @@ fn self_exe_path() -> option<Path> { } #[cfg(windows)] - fn load_self() -> option<Path> { + fn load_self() -> option<~str> { // FIXME: remove imports when export globs work properly. #1238 import libc::types::os::arch::extra::*; import libc::funcs::extra::kernel32::*; @@ -426,7 +433,7 @@ fn self_exe_path() -> option<Path> { } do option::map(load_self()) |pth| { - path::dirname(pth) + path::path_sep() + Path(pth).dir_path() } } @@ -447,7 +454,7 @@ fn self_exe_path() -> option<Path> { fn homedir() -> option<Path> { return match getenv(~"HOME") { some(p) => if !str::is_empty(p) { - some(p) + some(Path(p)) } else { secondary() }, @@ -463,7 +470,7 @@ fn homedir() -> option<Path> { fn secondary() -> option<Path> { do option::chain(getenv(~"USERPROFILE")) |p| { if !str::is_empty(p) { - some(p) + some(Path(p)) } else { none } @@ -484,13 +491,13 @@ fn homedir() -> option<Path> { fn tmpdir() -> Path { return lookup(); - fn getenv_nonempty(+v: Path) -> option<Path> { + fn getenv_nonempty(v: &str) -> option<Path> { match getenv(v) { some(x) => if str::is_empty(x) { none } else { - some(x) + some(Path(x)) }, _ => none } @@ -498,28 +505,29 @@ fn tmpdir() -> Path { #[cfg(unix)] fn lookup() -> Path { - option::get_default(getenv_nonempty(~"TMPDIR"), ~"/tmp") + option::get_default(getenv_nonempty("TMPDIR"), + Path("/tmp")) } #[cfg(windows)] fn lookup() -> Path { option::get_default( - option::or(getenv_nonempty(~"TMP"), - option::or(getenv_nonempty(~"TEMP"), - option::or(getenv_nonempty(~"USERPROFILE"), - getenv_nonempty(~"WINDIR")))), - ~"C:\\Windows") + option::or(getenv_nonempty("TMP"), + option::or(getenv_nonempty("TEMP"), + option::or(getenv_nonempty("USERPROFILE"), + getenv_nonempty("WINDIR")))), + Path("C:\\Windows")) } } /// Recursively walk a directory structure -fn walk_dir(+p: Path, f: fn(Path) -> bool) { +fn walk_dir(p: &Path, f: fn((&Path)) -> bool) { walk_dir_(p, f); - fn walk_dir_(+p: Path, f: fn(Path) -> bool) -> bool { + fn walk_dir_(p: &Path, f: fn((&Path)) -> bool) -> bool { let mut keepgoing = true; do list_dir(p).each |q| { - let path = path::connect(p, q); + let path = &p.push(q); if !f(path) { keepgoing = false; false @@ -541,15 +549,15 @@ fn walk_dir(+p: Path, f: fn(Path) -> bool) { } /// Indicates whether a path represents a directory -fn path_is_dir(+p: Path) -> bool { - do str::as_c_str(p) |buf| { +fn path_is_dir(p: &Path) -> bool { + do str::as_c_str(p.to_str()) |buf| { rustrt::rust_path_is_dir(buf) != 0 as c_int } } /// Indicates whether a path exists -fn path_exists(+p: Path) -> bool { - do str::as_c_str(p) |buf| { +fn path_exists(p: &Path) -> bool { + do str::as_c_str(p.to_str()) |buf| { rustrt::rust_path_exists(buf) != 0 as c_int } } @@ -566,58 +574,50 @@ fn path_exists(+p: Path) -> bool { // NB: this is here rather than in path because it is a form of environment // querying; what it does depends on the process working directory, not just // the input paths. -fn make_absolute(+p: Path) -> Path { - if path::path_is_absolute(p) { - p +fn make_absolute(p: &Path) -> Path { + if p.is_absolute { + copy *p } else { - path::connect(getcwd(), p) + getcwd().push_many(p.components) } } /// Creates a directory at the specified path -fn make_dir(+p: Path, mode: c_int) -> bool { +fn make_dir(p: &Path, mode: c_int) -> bool { return mkdir(p, mode); #[cfg(windows)] - fn mkdir(+p: Path, _mode: c_int) -> bool { + fn mkdir(p: &Path, _mode: c_int) -> bool { // FIXME: remove imports when export globs work properly. #1238 import libc::types::os::arch::extra::*; import libc::funcs::extra::kernel32::*; import win32::*; // FIXME: turn mode into something useful? #2623 - do as_utf16_p(p) |buf| { + do as_utf16_p(p.to_str()) |buf| { CreateDirectoryW(buf, unsafe { unsafe::reinterpret_cast(0) }) != (0 as BOOL) } } #[cfg(unix)] - fn mkdir(+p: Path, mode: c_int) -> bool { - do as_c_charp(p) |c| { + fn mkdir(p: &Path, mode: c_int) -> bool { + do as_c_charp(p.to_str()) |c| { libc::mkdir(c, mode as mode_t) == (0 as c_int) } } } /// Lists the contents of a directory -fn list_dir(+p: Path) -> ~[~str] { +fn list_dir(p: &Path) -> ~[~str] { #[cfg(unix)] - fn star(+p: ~str) -> ~str { p } + fn star(p: &Path) -> Path { copy *p } #[cfg(windows)] - fn star(+p: ~str) -> ~str { - let pl = str::len(p); - if pl == 0u || (p[pl - 1u] as char != path::consts::path_sep - || p[pl - 1u] as char != path::consts::alt_path_sep) { - p + path::path_sep() + ~"*" - } else { - p + ~"*" - } - } + fn star(p: &Path) -> Path { p.push("*") } - do rustrt::rust_list_files(star(p)).filter |filename| { + do rustrt::rust_list_files(star(p).to_str()).filter |filename| { filename != ~"." && filename != ~".." } } @@ -627,90 +627,84 @@ fn list_dir(+p: Path) -> ~[~str] { * * This version prepends each entry with the directory. */ -fn list_dir_path(+p: Path) -> ~[~str] { - let mut p = p; - let pl = str::len(p); - if pl == 0u || (p[pl - 1u] as char != path::consts::path_sep - && p[pl - 1u] as char != path::consts::alt_path_sep) { - p += path::path_sep(); - } - os::list_dir(p).map(|f| p + f) +fn list_dir_path(p: &Path) -> ~[~Path] { + os::list_dir(p).map(|f| ~p.push(f)) } /// Removes a directory at the specified path -fn remove_dir(+p: Path) -> bool { +fn remove_dir(p: &Path) -> bool { return rmdir(p); #[cfg(windows)] - fn rmdir(+p: Path) -> bool { + fn rmdir(p: &Path) -> bool { // FIXME: remove imports when export globs work properly. #1238 import libc::funcs::extra::kernel32::*; import libc::types::os::arch::extra::*; import win32::*; - return do as_utf16_p(p) |buf| { + return do as_utf16_p(p.to_str()) |buf| { RemoveDirectoryW(buf) != (0 as BOOL) }; } #[cfg(unix)] - fn rmdir(+p: Path) -> bool { - return do as_c_charp(p) |buf| { + fn rmdir(p: &Path) -> bool { + return do as_c_charp(p.to_str()) |buf| { libc::rmdir(buf) == (0 as c_int) }; } } -fn change_dir(+p: Path) -> bool { +fn change_dir(p: &Path) -> bool { return chdir(p); #[cfg(windows)] - fn chdir(+p: Path) -> bool { + fn chdir(p: &Path) -> bool { // FIXME: remove imports when export globs work properly. #1238 import libc::funcs::extra::kernel32::*; import libc::types::os::arch::extra::*; import win32::*; - return do as_utf16_p(p) |buf| { + return do as_utf16_p(p.to_str()) |buf| { SetCurrentDirectoryW(buf) != (0 as BOOL) }; } #[cfg(unix)] - fn chdir(+p: Path) -> bool { - return do as_c_charp(p) |buf| { + fn chdir(p: &Path) -> bool { + return do as_c_charp(p.to_str()) |buf| { libc::chdir(buf) == (0 as c_int) }; } } /// Copies a file from one location to another -fn copy_file(+from: Path, +to: Path) -> bool { +fn copy_file(from: &Path, to: &Path) -> bool { return do_copy_file(from, to); #[cfg(windows)] - fn do_copy_file(+from: Path, +to: Path) -> bool { + fn do_copy_file(from: &Path, to: &Path) -> bool { // FIXME: remove imports when export globs work properly. #1238 import libc::funcs::extra::kernel32::*; import libc::types::os::arch::extra::*; import win32::*; - return do as_utf16_p(from) |fromp| { - do as_utf16_p(to) |top| { + return do as_utf16_p(from.to_str()) |fromp| { + do as_utf16_p(to.to_str()) |top| { CopyFileW(fromp, top, (0 as BOOL)) != (0 as BOOL) } } } #[cfg(unix)] - fn do_copy_file(+from: Path, +to: Path) -> bool { - let istream = do as_c_charp(from) |fromp| { - do as_c_charp(~"rb") |modebuf| { + fn do_copy_file(from: &Path, to: &Path) -> bool { + let istream = do as_c_charp(from.to_str()) |fromp| { + do as_c_charp("rb") |modebuf| { libc::fopen(fromp, modebuf) } }; if istream as uint == 0u { return false; } - let ostream = do as_c_charp(to) |top| { - do as_c_charp(~"w+b") |modebuf| { + let ostream = do as_c_charp(to.to_str()) |top| { + do as_c_charp("w+b") |modebuf| { libc::fopen(top, modebuf) } }; @@ -746,24 +740,24 @@ fn copy_file(+from: Path, +to: Path) -> bool { } /// Deletes an existing file -fn remove_file(+p: Path) -> bool { +fn remove_file(p: &Path) -> bool { return unlink(p); #[cfg(windows)] - fn unlink(+p: Path) -> bool { + fn unlink(p: &Path) -> bool { // FIXME (similar to Issue #2006): remove imports when export globs // work properly. import libc::funcs::extra::kernel32::*; import libc::types::os::arch::extra::*; import win32::*; - return do as_utf16_p(p) |buf| { + return do as_utf16_p(p.to_str()) |buf| { DeleteFileW(buf) != (0 as BOOL) }; } #[cfg(unix)] - fn unlink(+p: Path) -> bool { - return do as_c_charp(p) |buf| { + fn unlink(p: &Path) -> bool { + return do as_c_charp(p.to_str()) |buf| { libc::unlink(buf) == (0 as c_int) }; } @@ -887,11 +881,7 @@ mod tests { log(debug, path); // Hard to test this function - if os::sysname() != ~"win32" { - assert str::starts_with(path, path::path_sep()); - } else { - assert path[1] == ':' as u8; - } + assert path.is_absolute; } #[test] @@ -926,10 +916,10 @@ mod tests { fn test() { assert (!path::path_is_absolute(~"test-path")); - log(debug, ~"Current working directory: " + getcwd()); + log(debug, ~"Current working directory: " + getcwd().to_str()); - log(debug, make_absolute(~"test-path")); - log(debug, make_absolute(~"/usr/bin")); + log(debug, make_absolute(&Path("test-path"))); + log(debug, make_absolute(&Path("/usr/bin"))); } #[test] @@ -938,7 +928,7 @@ mod tests { let oldhome = getenv(~"HOME"); setenv(~"HOME", ~"/home/MountainView"); - assert os::homedir() == some(~"/home/MountainView"); + assert os::homedir() == some(Path("/home/MountainView")); setenv(~"HOME", ~""); assert os::homedir() == none; @@ -959,16 +949,16 @@ mod tests { assert os::homedir() == none; setenv(~"HOME", ~"/home/MountainView"); - assert os::homedir() == some(~"/home/MountainView"); + assert os::homedir() == some(Path("/home/MountainView")); setenv(~"HOME", ~""); setenv(~"USERPROFILE", ~"/home/MountainView"); - assert os::homedir() == some(~"/home/MountainView"); + assert os::homedir() == some(Path("/home/MountainView")); setenv(~"HOME", ~"/home/MountainView"); setenv(~"USERPROFILE", ~"/home/PaloAlto"); - assert os::homedir() == some(~"/home/MountainView"); + assert os::homedir() == some(Path("/home/MountainView")); option::iter(oldhome, |s| setenv(~"HOME", s)); option::iter(olduserprofile, @@ -977,16 +967,18 @@ mod tests { #[test] fn tmpdir() { - assert !str::is_empty(os::tmpdir()); + assert !str::is_empty(os::tmpdir().to_str()); } // Issue #712 #[test] - fn test_list_dir_no_invalid_memory_access() { os::list_dir(~"."); } + fn test_list_dir_no_invalid_memory_access() { + os::list_dir(&Path(".")); + } #[test] fn list_dir() { - let dirs = os::list_dir(~"."); + let dirs = os::list_dir(&Path(".")); // Just assuming that we've got some contents in the current directory assert (vec::len(dirs) > 0u); @@ -995,34 +987,34 @@ mod tests { #[test] fn path_is_dir() { - assert (os::path_is_dir(~".")); - assert (!os::path_is_dir(~"test/stdtest/fs.rs")); + assert (os::path_is_dir(&Path("."))); + assert (!os::path_is_dir(&Path("test/stdtest/fs.rs"))); } #[test] fn path_exists() { - assert (os::path_exists(~".")); - assert (!os::path_exists(~"test/nonexistent-bogus-path")); + assert (os::path_exists(&Path("."))); + assert (!os::path_exists(&Path("test/nonexistent-bogus-path"))); } #[test] fn copy_file_does_not_exist() { - assert !os::copy_file(~"test/nonexistent-bogus-path", - ~"test/other-bogus-path"); - assert !os::path_exists(~"test/other-bogus-path"); + assert !os::copy_file(&Path("test/nonexistent-bogus-path"), + &Path("test/other-bogus-path")); + assert !os::path_exists(&Path("test/other-bogus-path")); } #[test] fn copy_file_ok() { let tempdir = getcwd(); // would like to use $TMPDIR, // doesn't seem to work on Linux - assert (str::len(tempdir) > 0u); - let in = tempdir + path::path_sep() + ~"in.txt"; - let out = tempdir + path::path_sep() + ~"out.txt"; + assert (str::len(tempdir.to_str()) > 0u); + let in = tempdir.push("in.txt"); + let out = tempdir.push("out.txt"); /* Write the temp input file */ - let ostream = do as_c_charp(in) |fromp| { - do as_c_charp(~"w+b") |modebuf| { + let ostream = do as_c_charp(in.to_str()) |fromp| { + do as_c_charp("w+b") |modebuf| { libc::fopen(fromp, modebuf) } }; @@ -1034,14 +1026,14 @@ mod tests { (str::len(s) + 1u) as size_t, ostream) == buf.len() as size_t)}; assert (libc::fclose(ostream) == (0u as c_int)); - let rs = os::copy_file(in, out); - if (!os::path_exists(in)) { - fail (fmt!("%s doesn't exist", in)); + let rs = os::copy_file(&in, &out); + if (!os::path_exists(&in)) { + fail (fmt!("%s doesn't exist", in.to_str())); } assert(rs); - let rslt = run::run_program(~"diff", ~[in, out]); + let rslt = run::run_program(~"diff", ~[in.to_str(), out.to_str()]); assert (rslt == 0); - assert (remove_file(in)); - assert (remove_file(out)); + assert (remove_file(&in)); + assert (remove_file(&out)); } } diff --git a/src/libcore/path2.rs b/src/libcore/path2.rs index 50996c7876b..9d1351db3ac 100644 --- a/src/libcore/path2.rs +++ b/src/libcore/path2.rs @@ -14,73 +14,82 @@ struct PosixPath { components: ~[~str]; } -trait Path { +trait GenericPath { - static fn from_str((&str)) -> self; - fn to_str() -> ~str; + static pure fn from_str((&str)) -> self; - fn dirname() -> ~str; - fn filename() -> option<~str>; - fn filestem() -> option<~str>; - fn filetype() -> option<~str>; + pure fn dirname() -> ~str; + pure fn filename() -> option<~str>; + pure fn filestem() -> option<~str>; + pure fn filetype() -> option<~str>; - fn with_dirname((&str)) -> self; - fn with_filename((&str)) -> self; - fn with_filestem((&str)) -> self; - fn with_filetype((&str)) -> self; + pure fn with_dirname((&str)) -> self; + pure fn with_filename((&str)) -> self; + pure fn with_filestem((&str)) -> self; + pure fn with_filetype((&str)) -> self; - fn push_components((&[~str])) -> self; - fn pop_component() -> self; + pure fn push((&str)) -> self; + pure fn push_rel((&self)) -> self; + pure fn push_many((&[~str])) -> self; + pure fn pop() -> self; } -// FIXME (#3227): when default methods in traits are working, de-duplicate -// PosixPath and WindowsPath, most of their methods are common. +#[cfg(windows)] +type Path = WindowsPath; + +#[cfg(windows)] +pure fn Path(s: &str) -> Path { + from_str::<WindowsPath>(s) +} + +#[cfg(unix)] +type Path = PosixPath; -impl PosixPath : Path { +#[cfg(unix)] +pure fn Path(s: &str) -> Path { + from_str::<PosixPath>(s) +} + +impl PosixPath : ToStr { fn to_str() -> ~str { - match self.filename() { - none => self.dirname(), - some(ref f) => - if (self.components.len() == 1 && - !self.is_absolute) { - copy *f - } else { - self.dirname() + "/" + *f - } + let mut s = ~""; + if self.is_absolute { + s += "/"; } + s + str::connect(self.components, "/") } +} - static fn from_str(s: &str) -> PosixPath { +// FIXME (#3227): when default methods in traits are working, de-duplicate +// PosixPath and WindowsPath, most of their methods are common. +impl PosixPath : GenericPath { + + static pure fn from_str(s: &str) -> PosixPath { let mut components = str::split_nonempty(s, |c| c == '/'); let is_absolute = (s.len() != 0 && s[0] == '/' as u8); return PosixPath { is_absolute: is_absolute, components: normalize(components) } } - fn dirname() -> ~str { - let mut s = ~""; - if self.is_absolute { - s += "/"; - } - let mut d = copy self.components; - if d.len() != 0 { - vec::pop(d); - } - s += str::connect(d, "/"); - if s.len() == 0 { - s = ~"."; + pure fn dirname() -> ~str { + unchecked { + let s = self.dir_path().to_str(); + if s.len() == 0 { + ~"." + } else { + s + } } - return s; } - fn filename() -> option<~str> { + pure fn filename() -> option<~str> { match self.components.len() { 0 => none, n => some(copy self.components[n - 1]) } } - fn filestem() -> option<~str> { + pure fn filestem() -> option<~str> { match self.filename() { none => none, some(ref f) => { @@ -92,7 +101,7 @@ impl PosixPath : Path { } } - fn filetype() -> option<~str> { + pure fn filetype() -> option<~str> { match self.filename() { none => none, some(ref f) => { @@ -104,20 +113,22 @@ impl PosixPath : Path { } } - fn with_dirname(d: &str) -> PosixPath { + pure fn with_dirname(d: &str) -> PosixPath { let dpath = from_str::<PosixPath>(d); match self.filename() { - some(ref f) => dpath.push_components(~[copy *f]), + some(ref f) => dpath.push(*f), none => dpath } } - fn with_filename(f: &str) -> PosixPath { - assert ! str::any(f, |c| windows::is_sep(c as u8)); - self.dir_path().push_components(~[str::from_slice(f)]) + pure fn with_filename(f: &str) -> PosixPath { + unchecked { + assert ! str::any(f, |c| windows::is_sep(c as u8)); + self.dir_path().push(f) + } } - fn with_filestem(s: &str) -> PosixPath { + pure fn with_filestem(s: &str) -> PosixPath { match self.filetype() { none => self.with_filename(s), some(ref t) => @@ -125,7 +136,7 @@ impl PosixPath : Path { } } - fn with_filetype(t: &str) -> PosixPath { + pure fn with_filetype(t: &str) -> PosixPath { if t.len() == 0 { match self.filestem() { none => copy self, @@ -141,15 +152,15 @@ impl PosixPath : Path { } } - fn dir_path() -> PosixPath { + pure fn dir_path() -> PosixPath { if self.components.len() != 0 { - self.pop_component() + self.pop() } else { copy self } } - fn file_path() -> PosixPath { + pure fn file_path() -> PosixPath { let cs = match self.filename() { none => ~[], some(ref f) => ~[copy *f] @@ -158,42 +169,56 @@ impl PosixPath : Path { components: cs } } - fn push_components(cs: &[~str]) -> PosixPath { + pure fn push_rel(other: &PosixPath) -> PosixPath { + assert !other.is_absolute; + self.push_many(other.components) + } + + pure fn push_many(cs: &[~str]) -> PosixPath { return PosixPath { components: normalize(self.components + cs), ..self } } - fn pop_component() -> PosixPath { + pure fn push(s: &str) -> PosixPath { + let mut cs = self.components; + unchecked { vec::push(cs, move str::from_slice(s)); } + cs = normalize(cs); + return PosixPath { components: move cs, + ..self } + } + + pure fn pop() -> PosixPath { let mut cs = copy self.components; if cs.len() != 0 { - vec::pop(cs); + unchecked { vec::pop(cs); } } - return PosixPath { components: cs, ..self } + return PosixPath { components: move cs, ..self } } - - - } -impl WindowsPath : Path { - +impl WindowsPath : ToStr { fn to_str() -> ~str { - match self.filename() { - none => self.dirname(), - some(ref f) => - if (self.components.len() == 1 && - !self.is_absolute && - self.host == none && - self.device == none) { - copy *f - } else { - self.dirname() + "\\" + *f - } + let mut s = ~""; + match self.host { + some(h) => { s += "\\\\"; s += h; } + none => { } + } + match self.device { + some(d) => { s += d; s += ":"; } + none => { } + } + if self.is_absolute { + s += "\\"; } + s + str::connect(self.components, "\\") } +} + - static fn from_str(s: &str) -> WindowsPath { +impl WindowsPath : GenericPath { + + static pure fn from_str(s: &str) -> WindowsPath { let host; let device; let rest; @@ -229,38 +254,25 @@ impl WindowsPath : Path { components: normalize(components) } } - fn dirname() -> ~str { - let mut s = ~""; - match self.host { - some(h) => { s += "\\\\"; s += h; } - none => { } - } - match self.device { - some(d) => { s += d; s += ":"; } - none => { } - } - if self.is_absolute { - s += "\\"; - } - let mut d = copy self.components; - if d.len() != 0 { - vec::pop(d); - } - s += str::connect(d, "\\"); - if s.len() == 0 { - s = ~"."; + pure fn dirname() -> ~str { + unchecked { + let s = self.dir_path().to_str(); + if s.len() == 0 { + ~"." + } else { + s + } } - return s; } - fn filename() -> option<~str> { + pure fn filename() -> option<~str> { match self.components.len() { 0 => none, n => some(copy self.components[n - 1]) } } - fn filestem() -> option<~str> { + pure fn filestem() -> option<~str> { match self.filename() { none => none, some(ref f) => { @@ -272,7 +284,7 @@ impl WindowsPath : Path { } } - fn filetype() -> option<~str> { + pure fn filetype() -> option<~str> { match self.filename() { none => none, some(ref f) => { @@ -284,20 +296,20 @@ impl WindowsPath : Path { } } - fn with_dirname(d: &str) -> WindowsPath { + pure fn with_dirname(d: &str) -> WindowsPath { let dpath = from_str::<WindowsPath>(d); match self.filename() { - some(ref f) => dpath.push_components(~[copy *f]), + some(ref f) => dpath.push(*f), none => dpath } } - fn with_filename(f: &str) -> WindowsPath { + pure fn with_filename(f: &str) -> WindowsPath { assert ! str::any(f, |c| windows::is_sep(c as u8)); - self.dir_path().push_components(~[str::from_slice(f)]) + self.dir_path().push(f) } - fn with_filestem(s: &str) -> WindowsPath { + pure fn with_filestem(s: &str) -> WindowsPath { match self.filetype() { none => self.with_filename(s), some(ref t) => @@ -305,7 +317,7 @@ impl WindowsPath : Path { } } - fn with_filetype(t: &str) -> WindowsPath { + pure fn with_filetype(t: &str) -> WindowsPath { if t.len() == 0 { match self.filestem() { none => copy self, @@ -321,15 +333,15 @@ impl WindowsPath : Path { } } - fn dir_path() -> WindowsPath { + pure fn dir_path() -> WindowsPath { if self.components.len() != 0 { - self.pop_component() + self.pop() } else { copy self } } - fn file_path() -> WindowsPath { + pure fn file_path() -> WindowsPath { let cs = match self.filename() { none => ~[], some(ref f) => ~[copy *f] @@ -340,30 +352,47 @@ impl WindowsPath : Path { components: cs } } - fn push_components(cs: &[~str]) -> WindowsPath { + pure fn push_rel(other: &WindowsPath) -> WindowsPath { + assert !other.is_absolute; + self.push_many(other.components) + } + + pure fn push_many(cs: &[~str]) -> WindowsPath { return WindowsPath { components: normalize(self.components + cs), ..self } } - fn pop_component() -> WindowsPath { + pure fn push(s: &str) -> WindowsPath { + let mut cs = self.components; + unchecked { vec::push(cs, move str::from_slice(s)); } + cs = normalize(cs); + return WindowsPath { components: move cs, + ..self } + } + + pure fn pop() -> WindowsPath { let mut cs = copy self.components; if cs.len() != 0 { - vec::pop(cs); + unchecked { vec::pop(cs); } } - return WindowsPath { components: cs, ..self } + return WindowsPath { components: move cs, ..self } } } -fn normalize(components: &[~str]) -> ~[~str] { +pure fn normalize(components: &[~str]) -> ~[~str] { let mut cs = ~[]; - for components.each |c| { - if c == ~"." { again; } - if c == ~".." && cs.len() != 0 { - vec::pop(cs); - again; + unchecked { + for components.each |c| { + unchecked { + if c == ~"." && components.len() > 1 { again; } + if c == ~".." && cs.len() != 0 { + vec::pop(cs); + again; + } + vec::push(cs, copy c); + } } - vec::push(cs, copy c); } cs } @@ -384,6 +413,7 @@ mod posix { } t(&(mk("hi")), "hi"); + t(&(mk("/lib")), "/lib"); t(&(mk("hi/there")), "hi/there"); t(&(mk("hi/there.txt")), "hi/there.txt"); @@ -401,7 +431,7 @@ mod posix { "a/foo.txt"); t(&(mk("a/b/c") - .push_components([~".."])), "a/b"); + .push("..")), "a/b"); t(&(mk("there.txt") .with_filetype("o")), "there.o"); @@ -425,7 +455,7 @@ mod posix { "/usr/lib/there.o"); t(&(mk("/usr/bin/rust") - .push_components([~"lib", ~"thingy.so"]) + .push_many([~"lib", ~"thingy.so"]) .with_filestem("librustc")), "/usr/bin/rust/lib/librustc.so"); @@ -437,11 +467,11 @@ mod posix { mod windows { #[inline(always)] - fn is_sep(u: u8) -> bool { + pure fn is_sep(u: u8) -> bool { u == '/' as u8 || u == '\\' as u8 } - fn extract_unc_prefix(s: &str) -> option<(~str,~str)> { + pure fn extract_unc_prefix(s: &str) -> option<(~str,~str)> { if (s.len() > 1 && s[0] == '\\' as u8 && s[1] == '\\' as u8) { @@ -458,14 +488,20 @@ mod windows { none } - fn extract_drive_prefix(s: &str) -> option<(~str,~str)> { - if (s.len() > 1 && - libc::isalpha(s[0] as libc::c_int) != 0 && - s[1] == ':' as u8) { - let rest = if s.len() == 2 { ~"" } else { s.slice(2, s.len()) }; - return some((s.slice(0,1), rest)); + pure fn extract_drive_prefix(s: &str) -> option<(~str,~str)> { + unchecked { + if (s.len() > 1 && + libc::isalpha(s[0] as libc::c_int) != 0 && + s[1] == ':' as u8) { + let rest = if s.len() == 2 { + ~"" + } else { + s.slice(2, s.len()) + }; + return some((s.slice(0,1), rest)); + } + none } - none } #[test] @@ -532,7 +568,7 @@ mod windows { "c:\\program files C\\there.o"); t(&(mk("c:\\program files (x86)\\rust") - .push_components([~"lib", ~"thingy.dll"]) + .push_many([~"lib", ~"thingy.dll"]) .with_filename("librustc.dll")), "c:\\program files (x86)\\rust\\lib\\librustc.dll"); diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs index a4e68c78bba..8aa798d4576 100644 --- a/src/libstd/tempfile.rs +++ b/src/libstd/tempfile.rs @@ -4,13 +4,14 @@ import core::option; import option::{none, some}; import rand; -fn mkdtemp(prefix: ~str, suffix: ~str) -> option<~str> { +fn mkdtemp(tmpdir: &Path, suffix: &str) -> option<Path> { let r = rand::rng(); let mut i = 0u; while (i < 1000u) { - let s = prefix + r.gen_str(16u) + suffix; - if os::make_dir(s, 0x1c0i32) { // FIXME: u+rwx (#2349) - return some(s); + let p = tmpdir.push(r.gen_str(16u) + + str::from_slice(suffix)); + if os::make_dir(&p, 0x1c0i32) { // FIXME: u+rwx (#2349) + return some(p); } i += 1u; } @@ -19,11 +20,11 @@ fn mkdtemp(prefix: ~str, suffix: ~str) -> option<~str> { #[test] fn test_mkdtemp() { - let r = mkdtemp(~"./", ~"foobar"); + let r = mkdtemp(&Path("."), "foobar"); match r { some(p) => { - os::remove_dir(p); - assert(str::ends_with(p, ~"foobar")); + os::remove_dir(&p); + assert(str::ends_with(p.to_str(), "foobar")); } _ => assert(false) } diff --git a/src/libstd/test.rs b/src/libstd/test.rs index a0cc26b6658..bd22b8b56d2 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -141,7 +141,7 @@ fn run_tests_console(opts: test_opts, } let log_out = match opts.logfile { - some(path) => match io::file_writer(path, + some(path) => match io::file_writer(&Path(path), ~[io::Create, io::Truncate]) { result::ok(w) => some(w), result::err(s) => { diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index b74a1165b79..881691b5f5c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -59,7 +59,7 @@ fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg, let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), ~"include"); let file = expr_to_str(cx, args[0], ~"#include_str requires a string"); let p = parse::new_parser_from_file(cx.parse_sess(), cx.cfg(), - res_rel_file(cx, sp, file), + &res_rel_file(cx, sp, &Path(file)), parse::parser::SOURCE_FILE); return p.parse_expr(); } @@ -70,7 +70,7 @@ fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, let file = expr_to_str(cx, args[0], ~"#include_str requires a string"); - let res = io::read_whole_file_str(res_rel_file(cx, sp, file)); + let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file))); match res { result::ok(_) => { /* Continue. */ } result::err(e) => { @@ -87,7 +87,7 @@ fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, let file = expr_to_str(cx, args[0], ~"#include_bin requires a string"); - match io::read_whole_file(res_rel_file(cx, sp, file)) { + match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) { result::ok(src) => { let u8_exprs = vec::map(src, |char: u8| { mk_u8(cx, sp, char) @@ -100,14 +100,13 @@ fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, } } -fn res_rel_file(cx: ext_ctxt, sp: codemap::span, +arg: Path) -> Path { +fn res_rel_file(cx: ext_ctxt, sp: codemap::span, arg: &Path) -> Path { // NB: relative paths are resolved relative to the compilation unit - if !path::path_is_absolute(arg) { - let cu = codemap::span_to_filename(sp, cx.codemap()); - let dir = path::dirname(cu); - return path::connect(dir, arg); + if !arg.is_absolute { + let cu = Path(codemap::span_to_filename(sp, cx.codemap())); + cu.dir_path().push_many(arg.components) } else { - return arg; + copy *arg } } diff --git a/src/libsyntax/parse.rs b/src/libsyntax/parse.rs index bb21ba92679..b83c687b94b 100644 --- a/src/libsyntax/parse.rs +++ b/src/libsyntax/parse.rs @@ -49,33 +49,33 @@ fn new_parse_sess_special_handler(sh: span_handler, cm: codemap::codemap) mut chpos: 0u, mut byte_pos: 0u}; } -fn parse_crate_from_file(input: ~str, cfg: ast::crate_cfg, +fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { - if str::ends_with(input, ~".rc") { + if input.filetype() == some(~"rc") { parse_crate_from_crate_file(input, cfg, sess) - } else if str::ends_with(input, ~".rs") { + } else if input.filetype() == some(~"rs") { parse_crate_from_source_file(input, cfg, sess) } else { sess.span_diagnostic.handler().fatal(~"unknown input file type: " + - input) + input.to_str()) } } -fn parse_crate_from_crate_file(input: ~str, cfg: ast::crate_cfg, +fn parse_crate_from_crate_file(input: &Path, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { let (p, rdr) = new_parser_etc_from_file(sess, cfg, input, parser::CRATE_FILE); let lo = p.span.lo; - let prefix = path::dirname(input); + let prefix = input.dir_path(); let leading_attrs = p.parse_inner_attrs_and_next(); let { inner: crate_attrs, next: first_cdir_attr } = leading_attrs; let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr); sess.chpos = rdr.chpos; sess.byte_pos = sess.byte_pos + rdr.pos; let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg}; - let (companionmod, _) = path::splitext(path::basename(input)); + let companionmod = option::map(input.filestem(), |s| Path(s)); let (m, attrs) = eval::eval_crate_directives_to_mod( - cx, cdirs, prefix, option::some(companionmod)); + cx, cdirs, &prefix, &companionmod); let mut hi = p.span.hi; p.expect(token::EOF); return @ast_util::respan(ast_util::mk_sp(lo, hi), @@ -85,7 +85,7 @@ fn parse_crate_from_crate_file(input: ~str, cfg: ast::crate_cfg, config: /* FIXME (#2543) */ copy p.cfg}); } -fn parse_crate_from_source_file(input: ~str, cfg: ast::crate_cfg, +fn parse_crate_from_source_file(input: &Path, cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate { let (p, rdr) = new_parser_etc_from_file(sess, cfg, input, parser::SOURCE_FILE); @@ -183,7 +183,7 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg, fn new_parser_etc_from_file(sess: parse_sess, cfg: ast::crate_cfg, - +path: ~str, ftype: parser::file_type) -> + path: &Path, ftype: parser::file_type) -> (parser, string_reader) { let res = io::read_whole_file_str(path); match res { @@ -191,14 +191,15 @@ fn new_parser_etc_from_file(sess: parse_sess, cfg: ast::crate_cfg, result::err(e) => sess.span_diagnostic.handler().fatal(e) } let src = @result::unwrap(res); - let filemap = codemap::new_filemap(path, src, sess.chpos, sess.byte_pos); + let filemap = codemap::new_filemap(path.to_str(), src, + sess.chpos, sess.byte_pos); sess.cm.files.push(filemap); let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap, sess.interner); return (parser(sess, cfg, srdr as reader, ftype), srdr); } -fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, +path: ~str, +fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: &Path, ftype: parser::file_type) -> parser { let (p, _) = new_parser_etc_from_file(sess, cfg, path, ftype); return p; diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index 615d546bb96..54ec79de4c1 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -9,7 +9,7 @@ type ctx = fn eval_crate_directives(cx: ctx, cdirs: ~[@ast::crate_directive], - prefix: ~str, + prefix: &Path, &view_items: ~[@ast::view_item], &items: ~[@ast::item]) { for cdirs.each |sub_cdir| { @@ -18,11 +18,8 @@ fn eval_crate_directives(cx: ctx, } fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive], - prefix: ~str, suffix: option<~str>) + prefix: &Path, suffix: &option<Path>) -> (ast::_mod, ~[ast::attribute]) { - debug!("eval crate prefix: %s", prefix); - debug!("eval crate suffix: %s", - option::get_default(suffix, ~"none")); let (cview_items, citems, cattrs) = parse_companion_mod(cx, prefix, suffix); let mut view_items: ~[@ast::view_item] = ~[]; @@ -43,17 +40,17 @@ companion mod is a .rs file with the same name as the directory. We build the path to the companion mod by combining the prefix and the optional suffix then adding the .rs extension. */ -fn parse_companion_mod(cx: ctx, prefix: ~str, suffix: option<~str>) +fn parse_companion_mod(cx: ctx, prefix: &Path, suffix: &option<Path>) -> (~[@ast::view_item], ~[@ast::item], ~[ast::attribute]) { - fn companion_file(+prefix: ~str, suffix: option<~str>) -> ~str { - return match suffix { - option::some(s) => path::connect(prefix, s), - option::none => prefix - } + ~".rs"; + fn companion_file(prefix: &Path, suffix: &option<Path>) -> Path { + return match *suffix { + option::some(s) => prefix.push_many(s.components), + option::none => copy *prefix + }.with_filetype("rs"); } - fn file_exists(path: ~str) -> bool { + fn file_exists(path: &Path) -> bool { // Crude, but there's no lib function for this and I'm not // up to writing it just now match io::file_reader(path) { @@ -62,8 +59,7 @@ fn parse_companion_mod(cx: ctx, prefix: ~str, suffix: option<~str>) } } - let modpath = companion_file(prefix, suffix); - debug!("looking for companion mod %s", modpath); + let modpath = &companion_file(prefix, suffix); if file_exists(modpath) { debug!("found companion mod"); let (p0, r0) = new_parser_etc_from_file(cx.sess, cx.cfg, @@ -85,19 +81,21 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str { } } -fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: ~str, +fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path, &view_items: ~[@ast::view_item], &items: ~[@ast::item]) { match cdir.node { ast::cdir_src_mod(id, attrs) => { - let file_path = cdir_path_opt((cx.sess.interner.get(id) + ~".rs"), - attrs); - let full_path = - if path::path_is_absolute(file_path) { - file_path - } else { prefix + path::path_sep() + file_path }; + let file_path = Path(cdir_path_opt( + cx.sess.interner.get(id) + ~".rs", attrs)); + let full_path = if file_path.is_absolute { + copy file_path + } else { + prefix.push_many(file_path.components) + }; let (p0, r0) = - new_parser_etc_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE); + new_parser_etc_from_file(cx.sess, cx.cfg, + &full_path, SOURCE_FILE); let inner_attrs = p0.parse_inner_attrs_and_next(); let mod_attrs = vec::append(attrs, inner_attrs.inner); let first_item_outer_attrs = inner_attrs.next; @@ -112,13 +110,14 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: ~str, vec::push(items, i); } ast::cdir_dir_mod(id, cdirs, attrs) => { - let path = cdir_path_opt(*cx.sess.interner.get(id), attrs); - let full_path = - if path::path_is_absolute(path) { - path - } else { prefix + path::path_sep() + path }; + let path = Path(cdir_path_opt(*cx.sess.interner.get(id), attrs)); + let full_path = if path.is_absolute { + copy path + } else { + prefix.push_many(path.components) + }; let (m0, a0) = eval_crate_directives_to_mod( - cx, cdirs, full_path, none); + cx, cdirs, &full_path, &none); let i = @{ident: /* FIXME (#2543) */ copy id, attrs: vec::append(attrs, a0), diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs index 33fce8bc72c..7c227e012a9 100644 --- a/src/rustc/back/link.rs +++ b/src/rustc/back/link.rs @@ -57,18 +57,7 @@ mod write { return false; } - // Decides what to call an intermediate file, given the name of the output - // and the extension to use. - fn mk_intermediate_name(output_path: ~str, extension: ~str) -> - ~str unsafe { - let stem = match str::find_char(output_path, '.') { - some(dot_pos) => str::slice(output_path, 0u, dot_pos), - none => output_path - }; - return stem + ~"." + extension; - } - - fn run_passes(sess: session, llmod: ModuleRef, output: ~str) { + fn run_passes(sess: session, llmod: ModuleRef, output: &Path) { let opts = sess.opts; if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); } let mut pm = mk_pass_manager(); @@ -85,15 +74,15 @@ mod write { match opts.output_type { output_type_bitcode => { if opts.optimize != session::No { - let filename = mk_intermediate_name(output, ~"no-opt.bc"); - str::as_c_str(filename, |buf| { + let filename = output.with_filetype("no-opt.bc"); + str::as_c_str(filename.to_str(), |buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf) }); } } _ => { - let filename = mk_intermediate_name(output, ~"bc"); - str::as_c_str(filename, |buf| { + let filename = output.with_filetype("bc"); + str::as_c_str(filename.to_str(), |buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf) }); } @@ -163,9 +152,9 @@ mod write { if opts.save_temps { // Always output the bitcode file with --save-temps - let filename = mk_intermediate_name(output, ~"opt.bc"); + let filename = output.with_filetype("opt.bc"); llvm::LLVMRunPassManager(pm.llpm, llmod); - str::as_c_str(filename, |buf| { + str::as_c_str(filename.to_str(), |buf| { llvm::LLVMWriteBitcodeToFile(llmod, buf) }); pm = mk_pass_manager(); @@ -175,7 +164,7 @@ mod write { let _: () = str::as_c_str( sess.targ_cfg.target_strs.target_triple, |buf_t| { - str::as_c_str(output, |buf_o| { + str::as_c_str(output.to_str(), |buf_o| { WriteOutputFile( sess, pm.llpm, @@ -197,7 +186,7 @@ mod write { let _: () = str::as_c_str( sess.targ_cfg.target_strs.target_triple, |buf_t| { - str::as_c_str(output, |buf_o| { + str::as_c_str(output.to_str(), |buf_o| { WriteOutputFile( sess, pm.llpm, @@ -217,7 +206,7 @@ mod write { let _: () = str::as_c_str( sess.targ_cfg.target_strs.target_triple, |buf_t| { - str::as_c_str(output, |buf_o| { + str::as_c_str(output.to_str(), |buf_o| { WriteOutputFile( sess, pm.llpm, @@ -239,13 +228,13 @@ mod write { if opts.output_type == output_type_llvm_assembly { // Given options "-S --emit-llvm": output LLVM assembly - str::as_c_str(output, |buf_o| { + str::as_c_str(output.to_str(), |buf_o| { llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)}); } else { // If only a bitcode file is asked for by using the '--emit-llvm' // flag, then output it here llvm::LLVMRunPassManager(pm.llpm, llmod); - str::as_c_str(output, + str::as_c_str(output.to_str(), |buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) ); } @@ -306,7 +295,7 @@ mod write { * */ -fn build_link_meta(sess: session, c: ast::crate, output: ~str, +fn build_link_meta(sess: session, c: ast::crate, output: &Path, symbol_hasher: &hash::State) -> link_meta { type provided_metas = @@ -384,21 +373,16 @@ fn build_link_meta(sess: session, c: ast::crate, output: ~str, } fn crate_meta_name(sess: session, _crate: ast::crate, - output: ~str, metas: provided_metas) -> ~str { + output: &Path, metas: provided_metas) -> ~str { return match metas.name { some(v) => v, none => { - let name = - { - let mut os = - str::split_char(path::basename(output), '.'); - if (vec::len(os) < 2u) { - sess.fatal(fmt!("output file name `%s` doesn't\ - appear to have an extension", output)); - } - vec::pop(os); - str::connect(os, ~".") - }; + let name = match output.filestem() { + none => sess.fatal(fmt!("output file name `%s` doesn't\ + appear to have a stem", + output.to_str())), + some(s) => s + }; warn_missing(sess, ~"name", name); name } @@ -552,31 +536,17 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str { // If the user wants an exe generated we need to invoke // cc to link the object file with some libs fn link_binary(sess: session, - obj_filename: ~str, - out_filename: ~str, + obj_filename: &Path, + out_filename: &Path, lm: link_meta) { - // Converts a library file name into a cc -l argument - fn unlib(config: @session::config, filename: ~str) -> ~str unsafe { - let rmlib = fn@(filename: ~str) -> ~str { - let found = str::find_str(filename, ~"lib"); - if config.os == session::os_macos || - (config.os == session::os_linux || - config.os == session::os_freebsd) && - option::is_some(found) && option::get(found) == 0u { - return str::slice(filename, 3u, str::len(filename)); - } else { return filename; } - }; - fn rmext(filename: ~str) -> ~str { - let mut parts = str::split_char(filename, '.'); - vec::pop(parts); - return str::connect(parts, ~"."); + // Converts a library file-stem into a cc -l argument + fn unlib(config: @session::config, stem: ~str) -> ~str { + if stem.starts_with("lib") && + config.os != session::os_win32 { + stem.slice(3, stem.len()) + } else { + stem } - return match config.os { - session::os_macos => rmext(rmlib(filename)), - session::os_linux => rmext(rmlib(filename)), - session::os_freebsd => rmext(rmlib(filename)), - _ => rmext(filename) - }; } let output = if sess.building_library { @@ -585,17 +555,19 @@ fn link_binary(sess: session, lm.name, lm.extras_hash, lm.vers)); debug!("link_meta.name: %s", lm.name); debug!("long_libname: %s", long_libname); - debug!("out_filename: %s", out_filename); - debug!("dirname(out_filename): %s", path::dirname(out_filename)); + debug!("out_filename: %s", out_filename.to_str()); + debug!("dirname(out_filename): %s", out_filename.dir_path().to_str()); - path::connect(path::dirname(out_filename), long_libname) - } else { out_filename }; + out_filename.dir_path().push(long_libname) + } else { + *out_filename + }; - log(debug, ~"output: " + output); + log(debug, ~"output: " + output.to_str()); // The default library location, we need this to find the runtime. // The location of crates will be determined as needed. - let stage: ~str = ~"-L" + sess.filesearch.get_target_lib_path(); + let stage: ~str = ~"-L" + sess.filesearch.get_target_lib_path().to_str(); // In the future, FreeBSD will use clang as default compiler. // It would be flexible to use cc (system's default C compiler) @@ -609,27 +581,28 @@ fn link_binary(sess: session, let mut cc_args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args); vec::push(cc_args, ~"-o"); - vec::push(cc_args, output); - vec::push(cc_args, obj_filename); + vec::push(cc_args, output.to_str()); + vec::push(cc_args, obj_filename.to_str()); let mut lib_cmd; let os = sess.targ_cfg.os; if os == session::os_macos { lib_cmd = ~"-dynamiclib"; - } else { lib_cmd = ~"-shared"; } + } else { + lib_cmd = ~"-shared"; + } // # Crate linking let cstore = sess.cstore; for cstore::get_used_crate_files(cstore).each |cratepath| { - if str::ends_with(cratepath, ~".rlib") { - vec::push(cc_args, cratepath); + if cratepath.filetype() == some(~"rlib") { + vec::push(cc_args, cratepath.to_str()); again; } - let cratepath = cratepath; - let dir = path::dirname(cratepath); + let dir = cratepath.dirname(); if dir != ~"" { vec::push(cc_args, ~"-L" + dir); } - let libarg = unlib(sess.targ_cfg, path::basename(cratepath)); + let libarg = unlib(sess.targ_cfg, option::get(cratepath.filestem())); vec::push(cc_args, ~"-l" + libarg); } @@ -645,7 +618,7 @@ fn link_binary(sess: session, // forces to make sure that library can be found at runtime. let addl_paths = sess.opts.addl_lib_search_paths; - for addl_paths.each |path| { vec::push(cc_args, ~"-L" + path); } + for addl_paths.each |path| { vec::push(cc_args, ~"-L" + path.to_str()); } // The names of the extern libraries let used_libs = cstore::get_used_libraries(cstore); @@ -658,7 +631,7 @@ fn link_binary(sess: session, // be rpathed if sess.targ_cfg.os == session::os_macos { vec::push(cc_args, ~"-Wl,-install_name,@rpath/" - + path::basename(output)); + + option::get(output.filename())); } } @@ -701,7 +674,7 @@ fn link_binary(sess: session, // FIXME (#2397): At some point we want to rpath our guesses as to where // extern libraries might live, based on the addl_lib_search_paths - vec::push_all(cc_args, rpath::get_rpath_flags(sess, output)); + vec::push_all(cc_args, rpath::get_rpath_flags(sess, &output)); debug!("%s link args: %s", cc_prog, str::connect(cc_args, ~" ")); // We run 'cc' here @@ -717,14 +690,14 @@ fn link_binary(sess: session, // Clean up on Darwin if sess.targ_cfg.os == session::os_macos { - run::run_program(~"dsymutil", ~[output]); + run::run_program(~"dsymutil", ~[output.to_str()]); } // Remove the temporary object file if we aren't saving temps if !sess.opts.save_temps { if ! os::remove_file(obj_filename) { sess.warn(fmt!("failed to delete object file `%s`", - obj_filename)); + obj_filename.to_str())); } } } diff --git a/src/rustc/back/rpath.rs b/src/rustc/back/rpath.rs index b6f6d17e444..0d02821a24c 100644 --- a/src/rustc/back/rpath.rs +++ b/src/rustc/back/rpath.rs @@ -13,7 +13,7 @@ pure fn not_win32(os: session::os) -> bool { } } -fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] { +fn get_rpath_flags(sess: session::session, out_filename: &Path) -> ~[~str] { let os = sess.targ_cfg.os; // No rpath on windows @@ -23,7 +23,6 @@ fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] { debug!("preparing the RPATH!"); - let cwd = os::getcwd(); let sysroot = sess.filesearch.sysroot(); let output = out_filename; let libs = cstore::get_used_crate_files(sess.cstore); @@ -32,50 +31,48 @@ fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] { let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess)); let target_triple = sess.opts.target_triple; - let rpaths = get_rpaths(os, cwd, sysroot, output, libs, target_triple); + let rpaths = get_rpaths(os, &sysroot, output, libs, target_triple); rpaths_to_flags(rpaths) } -fn get_sysroot_absolute_rt_lib(sess: session::session) -> path::Path { - let mut path = vec::append(~[sess.filesearch.sysroot()], - filesearch::relative_target_lib_path( - sess.opts.target_triple)); - vec::push(path, os::dll_filename(~"rustrt")); - path::connect_many(path) +fn get_sysroot_absolute_rt_lib(sess: session::session) -> Path { + let r = filesearch::relative_target_lib_path(sess.opts.target_triple); + sess.filesearch.sysroot().push_rel(&r).push(os::dll_filename("rustrt")) } -fn rpaths_to_flags(rpaths: ~[~str]) -> ~[~str] { - vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath) ) +fn rpaths_to_flags(rpaths: &[Path]) -> ~[~str] { + vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath.to_str())) } -fn get_rpaths(os: session::os, cwd: path::Path, sysroot: path::Path, - output: path::Path, libs: ~[path::Path], - target_triple: ~str) -> ~[~str] { - debug!("cwd: %s", cwd); - debug!("sysroot: %s", sysroot); - debug!("output: %s", output); +fn get_rpaths(os: session::os, + sysroot: &Path, + output: &Path, + libs: &[Path], + target_triple: &str) -> ~[Path] { + debug!("sysroot: %s", sysroot.to_str()); + debug!("output: %s", output.to_str()); debug!("libs:"); for libs.each |libpath| { - debug!(" %s", libpath); + debug!(" %s", libpath.to_str()); } debug!("target_triple: %s", target_triple); // Use relative paths to the libraries. Binaries can be moved // as long as they maintain the relative relationship to the // crates they depend on. - let rel_rpaths = get_rpaths_relative_to_output(os, cwd, output, libs); + let rel_rpaths = get_rpaths_relative_to_output(os, output, libs); // Make backup absolute paths to the libraries. Binaries can // be moved as long as the crates they link against don't move. - let abs_rpaths = get_absolute_rpaths(cwd, libs); + let abs_rpaths = get_absolute_rpaths(libs); // And a final backup rpath to the global library location. - let fallback_rpaths = ~[get_install_prefix_rpath(cwd, target_triple)]; + let fallback_rpaths = ~[get_install_prefix_rpath(target_triple)]; - fn log_rpaths(desc: ~str, rpaths: ~[~str]) { + fn log_rpaths(desc: &str, rpaths: &[Path]) { debug!("%s rpaths:", desc); for rpaths.each |rpath| { - debug!(" %s", rpath); + debug!(" %s", rpath.to_str()); } } @@ -93,43 +90,37 @@ fn get_rpaths(os: session::os, cwd: path::Path, sysroot: path::Path, } fn get_rpaths_relative_to_output(os: session::os, - cwd: path::Path, - output: path::Path, - libs: ~[path::Path]) -> ~[~str] { + output: &Path, + libs: &[Path]) -> ~[Path] { vec::map(libs, |a| { - get_rpath_relative_to_output(os, cwd, output, a) + get_rpath_relative_to_output(os, output, &a) }) } fn get_rpath_relative_to_output(os: session::os, - cwd: path::Path, - output: path::Path, - &&lib: path::Path) -> ~str { + output: &Path, + lib: &Path) -> Path { assert not_win32(os); // Mac doesn't appear to support $ORIGIN let prefix = match os { - session::os_linux => ~"$ORIGIN" + path::path_sep(), - session::os_freebsd => ~"$ORIGIN" + path::path_sep(), - session::os_macos => ~"@executable_path" + path::path_sep(), + session::os_linux | session::os_freebsd => "$ORIGIN", + session::os_macos => "@executable_path", session::os_win32 => core::unreachable() }; - prefix + get_relative_to( - get_absolute(cwd, output), - get_absolute(cwd, lib)) + Path(prefix).push_rel(&get_relative_to(&os::make_absolute(output), + &os::make_absolute(lib))) } // Find the relative path from one file to another -fn get_relative_to(abs1: path::Path, abs2: path::Path) -> path::Path { - assert path::path_is_absolute(abs1); - assert path::path_is_absolute(abs2); +fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { + assert abs1.is_absolute; + assert abs2.is_absolute; debug!("finding relative path from %s to %s", - abs1, abs2); - let normal1 = path::normalize(abs1); - let normal2 = path::normalize(abs2); - let split1 = path::split(normal1); - let split2 = path::split(normal2); + abs1.to_str(), abs2.to_str()); + let split1 = abs1.components; + let split2 = abs2.components; let len1 = vec::len(split1); let len2 = vec::len(split2); assert len1 > 0u; @@ -148,48 +139,39 @@ fn get_relative_to(abs1: path::Path, abs2: path::Path) -> path::Path { vec::push_all(path, vec::view(split2, start_idx, len2 - 1u)); if vec::is_not_empty(path) { - return path::connect_many(path); + return Path("").push_many(path); } else { - return ~"."; + return Path("."); } } -fn get_absolute_rpaths(cwd: path::Path, libs: ~[path::Path]) -> ~[~str] { - vec::map(libs, |a| get_absolute_rpath(cwd, a) ) +fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] { + vec::map(libs, |a| get_absolute_rpath(&a) ) } -fn get_absolute_rpath(cwd: path::Path, &&lib: path::Path) -> ~str { - path::dirname(get_absolute(cwd, lib)) +fn get_absolute_rpath(lib: &Path) -> Path { + os::make_absolute(lib).dir_path() } -fn get_absolute(cwd: path::Path, lib: path::Path) -> path::Path { - if path::path_is_absolute(lib) { - lib - } else { - path::connect(cwd, lib) - } -} - -fn get_install_prefix_rpath(cwd: path::Path, target_triple: ~str) -> ~str { +fn get_install_prefix_rpath(target_triple: &str) -> Path { let install_prefix = env!("CFG_PREFIX"); if install_prefix == ~"" { fail ~"rustc compiled without CFG_PREFIX environment variable"; } - let path = vec::append( - ~[install_prefix], - filesearch::relative_target_lib_path(target_triple)); - get_absolute(cwd, path::connect_many(path)) + let tlib = filesearch::relative_target_lib_path(target_triple); + os::make_absolute(&Path(install_prefix).push_rel(&tlib)) } -fn minimize_rpaths(rpaths: ~[~str]) -> ~[~str] { +fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { let set = map::str_hash::<()>(); let mut minimized = ~[]; for rpaths.each |rpath| { - if !set.contains_key(rpath) { + let s = rpath.to_str(); + if !set.contains_key(s) { vec::push(minimized, rpath); - set.insert(rpath, ()); + set.insert(s, ()); } } return minimized; @@ -199,116 +181,112 @@ fn minimize_rpaths(rpaths: ~[~str]) -> ~[~str] { mod test { #[test] fn test_rpaths_to_flags() { - let flags = rpaths_to_flags(~[~"path1", ~"path2"]); + let flags = rpaths_to_flags(~[Path("path1"), + Path("path2")]); assert flags == ~[~"-Wl,-rpath,path1", ~"-Wl,-rpath,path2"]; } #[test] - fn test_get_absolute1() { - let cwd = ~"/dir"; - let lib = ~"some/path/lib"; - let res = get_absolute(cwd, lib); - assert res == ~"/dir/some/path/lib"; - } - - #[test] - fn test_get_absolute2() { - let cwd = ~"/dir"; - let lib = ~"/some/path/lib"; - let res = get_absolute(cwd, lib); - assert res == ~"/some/path/lib"; - } - - #[test] fn test_prefix_rpath() { - let res = get_install_prefix_rpath(~"/usr/lib", ~"triple"); - let d = path::connect(env!("CFG_PREFIX"), ~"/lib/rustc/triple/lib"); - assert str::ends_with(res, d); + let res = get_install_prefix_rpath("triple"); + let d = Path(env!("CFG_PREFIX")) + .push_rel(&Path("lib/rustc/triple/lib")); + debug!("test_prefix_path: %s vs. %s", + res.to_str(), + d.to_str()); + assert str::ends_with(res.to_str(), d.to_str()); } #[test] fn test_prefix_rpath_abs() { - let res = get_install_prefix_rpath(~"/usr/lib", ~"triple"); - assert path::path_is_absolute(res); + let res = get_install_prefix_rpath("triple"); + assert res.is_absolute; } #[test] fn test_minimize1() { - let res = minimize_rpaths(~[~"rpath1", ~"rpath2", ~"rpath1"]); - assert res == ~[~"rpath1", ~"rpath2"]; + let res = minimize_rpaths([Path("rpath1"), + Path("rpath2"), + Path("rpath1")]); + assert res == ~[Path("rpath1"), Path("rpath2")]; } #[test] fn test_minimize2() { - let res = minimize_rpaths(~[~"1a", ~"2", ~"2", ~"1a", ~"4a", - ~"1a", ~"2", ~"3", ~"4a", ~"3"]); - assert res == ~[~"1a", ~"2", ~"4a", ~"3"]; + let res = minimize_rpaths(~[Path("1a"), Path("2"), Path("2"), + Path("1a"), Path("4a"),Path("1a"), + Path("2"), Path("3"), Path("4a"), + Path("3")]); + assert res == ~[Path("1a"), Path("2"), Path("4a"), Path("3")]; } #[test] fn test_relative_to1() { - let p1 = ~"/usr/bin/rustc"; - let p2 = ~"/usr/lib/mylib"; - let res = get_relative_to(p1, p2); - assert res == ~"../lib"; + let p1 = Path("/usr/bin/rustc"); + let p2 = Path("/usr/lib/mylib"); + let res = get_relative_to(&p1, &p2); + assert res == Path("../lib"); } #[test] fn test_relative_to2() { - let p1 = ~"/usr/bin/rustc"; - let p2 = ~"/usr/bin/../lib/mylib"; - let res = get_relative_to(p1, p2); - assert res == ~"../lib"; + let p1 = Path("/usr/bin/rustc"); + let p2 = Path("/usr/bin/../lib/mylib"); + let res = get_relative_to(&p1, &p2); + assert res == Path("../lib"); } #[test] fn test_relative_to3() { - let p1 = ~"/usr/bin/whatever/rustc"; - let p2 = ~"/usr/lib/whatever/mylib"; - let res = get_relative_to(p1, p2); - assert res == ~"../../lib/whatever"; + let p1 = Path("/usr/bin/whatever/rustc"); + let p2 = Path("/usr/lib/whatever/mylib"); + let res = get_relative_to(&p1, &p2); + assert res == Path("../../lib/whatever"); } #[test] fn test_relative_to4() { - let p1 = ~"/usr/bin/whatever/../rustc"; - let p2 = ~"/usr/lib/whatever/mylib"; - let res = get_relative_to(p1, p2); - assert res == ~"../lib/whatever"; + let p1 = Path("/usr/bin/whatever/../rustc"); + let p2 = Path("/usr/lib/whatever/mylib"); + let res = get_relative_to(&p1, &p2); + assert res == Path("../lib/whatever"); } #[test] fn test_relative_to5() { - let p1 = ~"/usr/bin/whatever/../rustc"; - let p2 = ~"/usr/lib/whatever/../mylib"; - let res = get_relative_to(p1, p2); - assert res == ~"../lib"; + let p1 = Path("/usr/bin/whatever/../rustc"); + let p2 = Path("/usr/lib/whatever/../mylib"); + let res = get_relative_to(&p1, &p2); + assert res == Path("../lib"); } #[test] fn test_relative_to6() { - let p1 = ~"/1"; - let p2 = ~"/2/3"; - let res = get_relative_to(p1, p2); - assert res == ~"2"; + let p1 = Path("/1"); + let p2 = Path("/2/3"); + let res = get_relative_to(&p1, &p2); + assert res == Path("2"); } #[test] fn test_relative_to7() { - let p1 = ~"/1/2"; - let p2 = ~"/3"; - let res = get_relative_to(p1, p2); - assert res == ~".."; + let p1 = Path("/1/2"); + let p2 = Path("/3"); + let res = get_relative_to(&p1, &p2); + assert res == Path(".."); } #[test] fn test_relative_to8() { - let p1 = ~"/home/brian/Dev/rust/build/" - + ~"stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so"; - let p2 = ~"/home/brian/Dev/rust/build/stage2/bin/.." - + ~"/lib/rustc/i686-unknown-linux-gnu/lib/libstd.so"; - let res = get_relative_to(p1, p2); - assert res == ~"."; + let p1 = Path("/home/brian/Dev/rust/build/").push_rel( + &Path("stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so")); + let p2 = Path("/home/brian/Dev/rust/build/stage2/bin/..").push_rel( + &Path("lib/rustc/i686-unknown-linux-gnu/lib/libstd.so")); + let res = get_relative_to(&p1, &p2); + debug!("test_relative_tu8: %s vs. %s", + res.to_str(), + Path(".").to_str()); + assert res == Path("."); } #[test] @@ -316,8 +294,8 @@ mod test { fn test_rpath_relative() { let o = session::os_linux; let res = get_rpath_relative_to_output(o, - ~"/usr", ~"bin/rustc", ~"lib/libstd.so"); - assert res == ~"$ORIGIN/../lib"; + &Path("bin/rustc"), &Path("lib/libstd.so")); + assert res == Path("$ORIGIN/../lib"); } #[test] @@ -325,8 +303,8 @@ mod test { fn test_rpath_relative() { let o = session::os_freebsd; let res = get_rpath_relative_to_output(o, - ~"/usr", ~"bin/rustc", ~"lib/libstd.so"); - assert res == ~"$ORIGIN/../lib"; + &Path("bin/rustc"), &Path("lib/libstd.so")); + assert res == Path("$ORIGIN/../lib"); } #[test] @@ -334,14 +312,19 @@ mod test { fn test_rpath_relative() { // this is why refinements would be nice let o = session::os_macos; - let res = get_rpath_relative_to_output(o, ~"/usr", ~"bin/rustc", - ~"lib/libstd.so"); - assert res == ~"@executable_path/../lib"; + let res = get_rpath_relative_to_output(o, + &Path("bin/rustc"), + &Path("lib/libstd.so")); + assert res == Path("@executable_path/../lib"); } #[test] fn test_get_absolute_rpath() { - let res = get_absolute_rpath(~"/usr", ~"lib/libstd.so"); - assert res == ~"/usr/lib"; + let res = get_absolute_rpath(&Path("lib/libstd.so")); + debug!("test_get_absolute_rpath: %s vs. %s", + res.to_str(), + os::make_absolute(&Path("lib")).to_str()); + + assert res == os::make_absolute(&Path("lib")); } } diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 087c6c3b833..c1a371af4dd 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -27,7 +27,7 @@ fn anon_src() -> ~str { ~"<anon>" } fn source_name(input: input) -> ~str { match input { - file_input(ifile) => ifile, + file_input(ifile) => ifile.to_str(), str_input(_) => anon_src() } } @@ -92,7 +92,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg { enum input { /// Load source from file - file_input(~str), + file_input(Path), /// The string is the source str_input(~str) } @@ -101,7 +101,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: input) -> @ast::crate { match input { file_input(file) => { - parse::parse_crate_from_file(file, cfg, sess.parse_sess) + parse::parse_crate_from_file(&file, cfg, sess.parse_sess) } str_input(src) => { // FIXME (#2319): Don't really want to box the source string @@ -236,11 +236,13 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, vtable_map: vtable_map}; let (llmod, link_meta) = time(time_passes, ~"translation", || - trans::base::trans_crate(sess, crate, ty_cx, outputs.obj_filename, + trans::base::trans_crate(sess, crate, ty_cx, + &outputs.obj_filename, exp_map, exp_map2, maps)); time(time_passes, ~"LLVM passes", || - link::write::run_passes(sess, llmod, outputs.obj_filename)); + link::write::run_passes(sess, llmod, + &outputs.obj_filename)); let stop_after_codegen = sess.opts.output_type != link::output_type_exe || @@ -249,14 +251,15 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, if stop_after_codegen { return {crate: crate, tcx: some(ty_cx)}; } time(time_passes, ~"linking", || - link::link_binary(sess, outputs.obj_filename, - outputs.out_filename, link_meta)); + link::link_binary(sess, + &outputs.obj_filename, + &outputs.out_filename, link_meta)); return {crate: crate, tcx: some(ty_cx)}; } fn compile_input(sess: session, cfg: ast::crate_cfg, input: input, - outdir: option<~str>, output: option<~str>) { + outdir: &option<Path>, output: &option<Path>) { let upto = if sess.opts.parse_only { cu_parse } else if sess.opts.no_trans { cu_no_trans } @@ -483,6 +486,7 @@ fn build_session_options(matches: getopts::matches, let extra_debuginfo = opt_present(matches, ~"xg"); let debuginfo = opt_present(matches, ~"g") || extra_debuginfo; let sysroot_opt = getopts::opt_maybe_str(matches, ~"sysroot"); + let sysroot_opt = option::map(sysroot_opt, |m| Path(m)); let target_opt = getopts::opt_maybe_str(matches, ~"target"); let save_temps = getopts::opt_present(matches, ~"save-temps"); match output_type { @@ -514,7 +518,9 @@ fn build_session_options(matches: getopts::matches, some(s) => s }; - let addl_lib_search_paths = getopts::opt_strs(matches, ~"L"); + let addl_lib_search_paths = + getopts::opt_strs(matches, ~"L") + .map(|s| Path(s)); let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg")); let test = opt_present(matches, ~"test"); let sopts: @session::options = @@ -614,11 +620,11 @@ fn opts() -> ~[getopts::opt] { optflag(~"static"), optflag(~"gc")]; } -type output_filenames = @{out_filename: ~str, obj_filename:~str}; +type output_filenames = @{out_filename:Path, obj_filename:Path}; fn build_output_filenames(input: input, - odir: option<~str>, - ofile: option<~str>, + odir: &option<Path>, + ofile: &option<Path>, sess: session) -> output_filenames { let obj_path; @@ -639,37 +645,30 @@ fn build_output_filenames(input: input, link::output_type_object | link::output_type_exe => ~"o" }; - match ofile { + match *ofile { none => { // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirname = match odir { + let dirpath = match *odir { some(d) => d, none => match input { str_input(_) => os::getcwd(), - file_input(ifile) => path::dirname(ifile) + file_input(ifile) => ifile.dir_path() } }; - let base_filename = match input { - file_input(ifile) => { - let (path, _) = path::splitext(ifile); - path::basename(path) - } + let stem = match input { + file_input(ifile) => option::get(ifile.filestem()), str_input(_) => ~"rust_out" }; - let base_path = path::connect(dirname, base_filename); - if sess.building_library { - let basename = path::basename(base_path); - let dylibname = os::dll_filename(basename); - out_path = path::connect(dirname, dylibname); - obj_path = path::connect(dirname, basename + ~"." + obj_suffix); + out_path = dirpath.push(os::dll_filename(stem)); + obj_path = dirpath.push(stem).with_filetype(obj_suffix); } else { - out_path = base_path; - obj_path = base_path + ~"." + obj_suffix; + out_path = dirpath.push(stem); + obj_path = dirpath.push(stem).with_filetype(obj_suffix); } } @@ -678,9 +677,7 @@ fn build_output_filenames(input: input, obj_path = if stop_after_codegen { out_file } else { - let (base, _) = path::splitext(out_file); - let modified = base + ~"." + obj_suffix; - modified + out_file.with_filetype(obj_suffix) }; if sess.building_library { @@ -690,13 +687,13 @@ fn build_output_filenames(input: input, // lib<basename>-<hash>-<version>.so no matter what. } - if odir != none { + if *odir != none { sess.warn(~"ignoring --out-dir flag due to -o flag."); } } } return @{out_filename: out_path, - obj_filename: obj_path}; + obj_filename: obj_path}; } fn early_error(emitter: diagnostic::emitter, msg: ~str) -> ! { @@ -704,7 +701,7 @@ fn early_error(emitter: diagnostic::emitter, msg: ~str) -> ! { fail; } -fn list_metadata(sess: session, path: ~str, out: io::Writer) { +fn list_metadata(sess: session, path: &Path, out: io::Writer) { metadata::loader::list_file_metadata( sess.parse_sess.interner, session::sess_os_to_meta_os(sess.targ_cfg.os), path, out); diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index 0770a132a1d..e26465fce5d 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -159,7 +159,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { let src = str::from_bytes(io::stdin().read_whole_stream()); str_input(src) } else { - file_input(ifile) + file_input(Path(ifile)) } } _ => early_error(demitter, ~"multiple input filenames provided") @@ -168,7 +168,9 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { let sopts = build_session_options(matches, demitter); let sess = build_session(sopts, demitter); let odir = getopts::opt_maybe_str(matches, ~"out-dir"); + let odir = option::map(odir, |o| Path(o)); let ofile = getopts::opt_maybe_str(matches, ~"o"); + let ofile = option::map(ofile, |o| Path(o)); let cfg = build_configuration(sess, binary, input); let pretty = option::map(getopts::opt_default(matches, ~"pretty", @@ -185,7 +187,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { if ls { match input { file_input(ifile) => { - list_metadata(sess, ifile, io::stdout()); + list_metadata(sess, &ifile, io::stdout()); } str_input(_) => { early_error(demitter, ~"can not list metadata for stdin"); @@ -194,7 +196,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { return; } - compile_input(sess, cfg, input, odir, ofile); + compile_input(sess, cfg, input, &odir, &ofile); } /* diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index cd663c06ce7..10c0f283525 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -89,8 +89,8 @@ type options = lint_opts: ~[(lint::lint, lint::level)], save_temps: bool, output_type: back::link::output_type, - addl_lib_search_paths: ~[~str], - maybe_sysroot: option<~str>, + addl_lib_search_paths: ~[Path], + maybe_sysroot: option<Path>, target_triple: ~str, cfg: ast::crate_cfg, test: bool, @@ -111,7 +111,7 @@ type session_ = {targ_cfg: @config, span_diagnostic: diagnostic::span_handler, filesearch: filesearch::filesearch, mut building_library: bool, - working_dir: ~str, + working_dir: Path, lint_settings: lint::lint_settings}; enum session { diff --git a/src/rustc/metadata/creader.rs b/src/rustc/metadata/creader.rs index 5867dc12672..685717e8e8d 100644 --- a/src/rustc/metadata/creader.rs +++ b/src/rustc/metadata/creader.rs @@ -199,7 +199,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item], }; let cinfo = loader::load_library_crate(load_ctxt); - let cfilename = cinfo.ident; + let cfilename = Path(cinfo.ident); let cdata = cinfo.data; let attrs = decoder::get_crate_attributes(cdata); @@ -225,7 +225,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item], let cstore = e.cstore; cstore::set_crate_data(cstore, cnum, cmeta); - cstore::add_used_crate_file(cstore, cfilename); + cstore::add_used_crate_file(cstore, &cfilename); return cnum; } some(cnum) => { diff --git a/src/rustc/metadata/cstore.rs b/src/rustc/metadata/cstore.rs index 4b65953781a..d2cab8c3177 100644 --- a/src/rustc/metadata/cstore.rs +++ b/src/rustc/metadata/cstore.rs @@ -56,7 +56,7 @@ type cstore_private = @{metas: map::hashmap<ast::crate_num, crate_metadata>, use_crate_map: use_crate_map, mod_path_map: mod_path_map, - mut used_crate_files: ~[~str], + mut used_crate_files: ~[Path], mut used_libraries: ~[~str], mut used_link_args: ~[~str], intr: ident_interner}; @@ -114,13 +114,13 @@ fn iter_crate_data(cstore: cstore, i: fn(ast::crate_num, crate_metadata)) { for p(cstore).metas.each |k,v| { i(k, v);}; } -fn add_used_crate_file(cstore: cstore, lib: ~str) { - if !vec::contains(p(cstore).used_crate_files, lib) { - vec::push(p(cstore).used_crate_files, lib); +fn add_used_crate_file(cstore: cstore, lib: &Path) { + if !vec::contains(p(cstore).used_crate_files, copy *lib) { + vec::push(p(cstore).used_crate_files, copy *lib); } } -fn get_used_crate_files(cstore: cstore) -> ~[~str] { +fn get_used_crate_files(cstore: cstore) -> ~[Path] { return p(cstore).used_crate_files; } diff --git a/src/rustc/metadata/filesearch.rs b/src/rustc/metadata/filesearch.rs index 72661891163..de0c31b9c3d 100644 --- a/src/rustc/metadata/filesearch.rs +++ b/src/rustc/metadata/filesearch.rs @@ -14,12 +14,10 @@ export get_cargo_root; export get_cargo_root_nearest; export libdir; -import path::Path; +type pick<T> = fn(path: &Path) -> option<T>; -type pick<T> = fn(path: Path) -> option<T>; - -fn pick_file(file: Path, path: Path) -> option<Path> { - if path::basename(path) == file { option::some(path) } +fn pick_file(file: Path, path: &Path) -> option<Path> { + if path.file_path() == file { option::some(copy *path) } else { option::none } } @@ -27,11 +25,11 @@ trait filesearch { fn sysroot() -> Path; fn lib_search_paths() -> ~[Path]; fn get_target_lib_path() -> Path; - fn get_target_lib_file_path(file: Path) -> Path; + fn get_target_lib_file_path(file: &Path) -> Path; } fn mk_filesearch(maybe_sysroot: option<Path>, - target_triple: ~str, + target_triple: &str, addl_lib_search_paths: ~[Path]) -> filesearch { type filesearch_impl = {sysroot: Path, addl_lib_search_paths: ~[Path], @@ -42,7 +40,8 @@ fn mk_filesearch(maybe_sysroot: option<Path>, let mut paths = self.addl_lib_search_paths; vec::push(paths, - make_target_lib_path(self.sysroot, self.target_triple)); + make_target_lib_path(&self.sysroot, + self.target_triple)); match get_cargo_lib_path_nearest() { result::ok(p) => vec::push(paths, p), result::err(p) => () @@ -54,33 +53,33 @@ fn mk_filesearch(maybe_sysroot: option<Path>, paths } fn get_target_lib_path() -> Path { - make_target_lib_path(self.sysroot, self.target_triple) + make_target_lib_path(&self.sysroot, self.target_triple) } - fn get_target_lib_file_path(file: Path) -> Path { - path::connect(self.get_target_lib_path(), file) + fn get_target_lib_file_path(file: &Path) -> Path { + self.get_target_lib_path().push_rel(file) } } let sysroot = get_sysroot(maybe_sysroot); - debug!("using sysroot = %s", sysroot); + debug!("using sysroot = %s", sysroot.to_str()); {sysroot: sysroot, addl_lib_search_paths: addl_lib_search_paths, - target_triple: target_triple} as filesearch + target_triple: str::from_slice(target_triple)} as filesearch } fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> { let mut rslt = none; for filesearch.lib_search_paths().each |lib_search_path| { - debug!("searching %s", lib_search_path); - for os::list_dir_path(lib_search_path).each |path| { - debug!("testing %s", path); + debug!("searching %s", lib_search_path.to_str()); + for os::list_dir_path(&lib_search_path).each |path| { + debug!("testing %s", path.to_str()); let maybe_picked = pick(path); if option::is_some(maybe_picked) { - debug!("picked %s", path); + debug!("picked %s", path.to_str()); rslt = maybe_picked; break; } else { - debug!("rejected %s", path); + debug!("rejected %s", path.to_str()); } } if option::is_some(rslt) { break; } @@ -88,21 +87,20 @@ fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> { return rslt; } -fn relative_target_lib_path(target_triple: ~str) -> ~[Path] { - ~[libdir(), ~"rustc", target_triple, libdir()] +fn relative_target_lib_path(target_triple: &str) -> Path { + Path(libdir()).push_many([~"rustc", + str::from_slice(target_triple), + libdir()]) } -fn make_target_lib_path(sysroot: Path, - target_triple: ~str) -> Path { - let path = vec::append(~[sysroot], - relative_target_lib_path(target_triple)); - let path = path::connect_many(path); - return path; +fn make_target_lib_path(sysroot: &Path, + target_triple: &str) -> Path { + sysroot.push_rel(&relative_target_lib_path(target_triple)) } fn get_default_sysroot() -> Path { match os::self_exe_path() { - option::some(p) => path::normalize(path::connect(p, ~"..")), + option::some(p) => p.pop(), option::none => fail ~"can't determine value for sysroot" } } @@ -115,15 +113,14 @@ fn get_sysroot(maybe_sysroot: option<Path>) -> Path { } fn get_cargo_sysroot() -> result<Path, ~str> { - let path = ~[get_default_sysroot(), libdir(), ~"cargo"]; - result::ok(path::connect_many(path)) + result::ok(get_default_sysroot().push_many([libdir(), ~"cargo"])) } fn get_cargo_root() -> result<Path, ~str> { match os::getenv(~"CARGO_ROOT") { - some(_p) => result::ok(_p), + some(_p) => result::ok(Path(_p)), none => match os::homedir() { - some(_q) => result::ok(path::connect(_q, ~".cargo")), + some(_q) => result::ok(_q.push(".cargo")), none => result::err(~"no CARGO_ROOT or home directory") } } @@ -132,21 +129,21 @@ fn get_cargo_root() -> result<Path, ~str> { fn get_cargo_root_nearest() -> result<Path, ~str> { do result::chain(get_cargo_root()) |p| { let cwd = os::getcwd(); - let mut dirname = path::dirname(cwd); - let mut dirpath = path::split(dirname); - let cwd_cargo = path::connect(cwd, ~".cargo"); - let mut par_cargo = path::connect(dirname, ~".cargo"); + let cwd_cargo = cwd.push(".cargo"); + let mut par_cargo = cwd.pop().push(".cargo"); let mut rslt = result::ok(cwd_cargo); - if !os::path_is_dir(cwd_cargo) && cwd_cargo != p { - while vec::is_not_empty(dirpath) && par_cargo != p { - if os::path_is_dir(par_cargo) { + if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p { + while par_cargo != p { + if os::path_is_dir(&par_cargo) { rslt = result::ok(par_cargo); break; } - vec::pop(dirpath); - dirname = path::dirname(dirname); - par_cargo = path::connect(dirname, ~".cargo"); + if par_cargo.components.len() == 1 { + // We just checked /.cargo, stop now. + break; + } + par_cargo = par_cargo.pop().pop().push(".cargo"); } } rslt @@ -155,13 +152,13 @@ fn get_cargo_root_nearest() -> result<Path, ~str> { fn get_cargo_lib_path() -> result<Path, ~str> { do result::chain(get_cargo_root()) |p| { - result::ok(path::connect(p, libdir())) + result::ok(p.push(libdir())) } } fn get_cargo_lib_path_nearest() -> result<Path, ~str> { do result::chain(get_cargo_root_nearest()) |p| { - result::ok(path::connect(p, libdir())) + result::ok(p.push(libdir())) } } diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs index f010b7e9754..513b4dd4216 100644 --- a/src/rustc/metadata/loader.rs +++ b/src/rustc/metadata/loader.rs @@ -74,27 +74,28 @@ fn find_library_crate_aux(cx: ctxt, let mut matches = ~[]; filesearch::search(filesearch, |path| { - debug!("inspecting file %s", path); - let f: ~str = path::basename(path); + debug!("inspecting file %s", path.to_str()); + let f: ~str = option::get(path.filename()); if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) { - debug!("skipping %s, doesn't look like %s*%s", path, prefix, - suffix); + debug!("skipping %s, doesn't look like %s*%s", path.to_str(), + prefix, suffix); option::none::<()> } else { - debug!("%s is a candidate", path); + debug!("%s is a candidate", path.to_str()); match get_metadata_section(cx.os, path) { option::some(cvec) => { if !crate_matches(cvec, cx.metas, cx.hash) { - debug!("skipping %s, metadata doesn't match", path); + debug!("skipping %s, metadata doesn't match", + path.to_str()); option::none::<()> } else { - debug!("found %s with matching metadata", path); - vec::push(matches, {ident: path, data: cvec}); + debug!("found %s with matching metadata", path.to_str()); + vec::push(matches, {ident: path.to_str(), data: cvec}); option::none::<()> } } _ => { - debug!("could not load metadata for %s", path); + debug!("could not load metadata for %s", path.to_str()); option::none::<()> } } @@ -168,10 +169,10 @@ fn metadata_matches(extern_metas: ~[@ast::meta_item], } fn get_metadata_section(os: os, - filename: ~str) -> option<@~[u8]> unsafe { - let mb = str::as_c_str(filename, |buf| { + filename: &Path) -> option<@~[u8]> unsafe { + let mb = str::as_c_str(filename.to_str(), |buf| { llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) - }); + }); if mb as int == 0 { return option::none::<@~[u8]>; } let of = match mk_object_file(mb) { option::some(of) => of, @@ -204,12 +205,13 @@ fn meta_section_name(os: os) -> ~str { } // A diagnostic function for dumping crate metadata to an output stream -fn list_file_metadata(intr: ident_interner, os: os, path: ~str, - out: io::Writer) { +fn list_file_metadata(intr: ident_interner, + os: os, path: &Path, out: io::Writer) { match get_metadata_section(os, path) { option::some(bytes) => decoder::list_crate_metadata(intr, bytes, out), option::none => { - out.write_str(~"could not find metadata in " + path + ~".\n"); + out.write_str(~"could not find metadata in " + + path.to_str() + ~".\n"); } } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index dddcdd64da3..fe0d49a3532 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -5778,7 +5778,7 @@ fn write_abi_version(ccx: @crate_ctxt) { fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, - output: ~str, + output: &Path, emap: resolve3::ExportMap, emap2: resolve3::ExportMap2, maps: astencode::maps) diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 04e0f7be75f..42b8274d78c 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -172,7 +172,7 @@ fn create_compile_unit(cx: @crate_ctxt) option::none => () } - let (_, work_dir) = get_file_path_and_dir(cx.sess.working_dir, + let (_, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(), crate_name); let unit_metadata = ~[lltag(tg), llunused(), @@ -197,13 +197,13 @@ fn get_cache(cx: @crate_ctxt) -> metadata_cache { option::get(cx.dbg_cx).llmetadata } -fn get_file_path_and_dir(work_dir: ~str, full_path: ~str) -> (~str, ~str) { +fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) { (if str::starts_with(full_path, work_dir) { str::slice(full_path, str::len(work_dir) + 1u, str::len(full_path)) } else { - full_path - }, work_dir) + str::from_slice(full_path) + }, str::from_slice(work_dir)) } fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> { @@ -215,8 +215,9 @@ fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> { option::none => () } - let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir, - full_path); + let (file_path, work_dir) = + get_file_path_and_dir(cx.sess.working_dir.to_str(), + full_path); let unit_node = create_compile_unit(cx).node; let file_md = ~[lltag(tg), llstr(file_path), diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index 1634d38577e..9d952517052 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -210,6 +210,9 @@ fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str { ty::vstore_fixed(_) => { fmt!("%s/%s", ty, vstore_to_str(cx, vs)) } + ty::vstore_slice(_) => { + fmt!("%s/%s", vstore_to_str(cx, vs), ty) + } _ => fmt!("%s%s", vstore_to_str(cx, vs), ty) } } diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs index 3dd029f2307..91f910f5280 100644 --- a/src/rustdoc/astsrv.rs +++ b/src/rustdoc/astsrv.rs @@ -51,7 +51,7 @@ fn from_str<T>(source: ~str, owner: srv_owner<T>) -> T { } fn from_file<T>(file: ~str, owner: srv_owner<T>) -> T { - run(owner, file, parse::from_file_sess) + run(owner, file, |sess, f| parse::from_file_sess(sess, &Path(f))) } fn run<T>(owner: srv_owner<T>, source: ~str, +parse: parser) -> T { diff --git a/src/rustdoc/config.rs b/src/rustdoc/config.rs index 96f418247af..9bb3d4730d4 100644 --- a/src/rustdoc/config.rs +++ b/src/rustdoc/config.rs @@ -28,8 +28,8 @@ enum output_style { /// The configuration for a rustdoc session type config = { - input_crate: ~str, - output_dir: ~str, + input_crate: Path, + output_dir: Path, output_format: output_format, output_style: output_style, pandoc_cmd: option<~str> @@ -67,10 +67,10 @@ fn usage() { println(~""); } -fn default_config(input_crate: ~str) -> config { +fn default_config(input_crate: &Path) -> config { { - input_crate: input_crate, - output_dir: ~".", + input_crate: *input_crate, + output_dir: Path("."), output_format: pandoc_html, output_style: doc_per_mod, pandoc_cmd: none @@ -103,8 +103,8 @@ fn parse_config_( match getopts::getopts(args, opts) { result::ok(matches) => { if vec::len(matches.free) == 1u { - let input_crate = vec::head(matches.free); - config_from_opts(input_crate, matches, program_output) + let input_crate = Path(vec::head(matches.free)); + config_from_opts(&input_crate, matches, program_output) } else if vec::is_empty(matches.free) { result::err(~"no crates specified") } else { @@ -118,7 +118,7 @@ fn parse_config_( } fn config_from_opts( - input_crate: ~str, + input_crate: &Path, matches: getopts::matches, program_output: program_output ) -> result<config, ~str> { @@ -127,6 +127,7 @@ fn config_from_opts( let result = result::ok(config); let result = do result::chain(result) |config| { let output_dir = getopts::opt_maybe_str(matches, opt_output_dir()); + let output_dir = option::map(output_dir, |s| Path(s)); result::ok({ output_dir: option::get_default(output_dir, config.output_dir) with config @@ -205,7 +206,7 @@ fn maybe_find_pandoc( none => { ~[~"pandoc"] + match os::homedir() { some(dir) => { - ~[path::connect(dir, ~".cabal/bin/pandoc")] + ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()] } none => ~[] } @@ -229,7 +230,7 @@ fn maybe_find_pandoc( fn should_find_pandoc() { let config = { output_format: pandoc_html - with default_config(~"test") + with default_config(&Path("test")) }; let mock_program_output = fn~(_prog: &str, _args: &[~str]) -> { status: int, out: ~str, err: ~str @@ -246,7 +247,7 @@ fn should_find_pandoc() { fn should_error_with_no_pandoc() { let config = { output_format: pandoc_html - with default_config(~"test") + with default_config(&Path("test")) }; let mock_program_output = fn~(_prog: &str, _args: &[~str]) -> { status: int, out: ~str, err: ~str @@ -282,7 +283,7 @@ fn should_error_with_multiple_crates() { #[test] fn should_set_output_dir_to_cwd_if_not_provided() { let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]); - assert result::get(config).output_dir == ~"."; + assert result::get(config).output_dir == Path("."); } #[test] @@ -290,7 +291,7 @@ fn should_set_output_dir_if_provided() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles" ]); - assert result::get(config).output_dir == ~"snuggles"; + assert result::get(config).output_dir == Path("snuggles"); } #[test] diff --git a/src/rustdoc/markdown_index_pass.rs b/src/rustdoc/markdown_index_pass.rs index 9a58d0c9179..47b1cee019c 100644 --- a/src/rustdoc/markdown_index_pass.rs +++ b/src/rustdoc/markdown_index_pass.rs @@ -81,7 +81,7 @@ fn item_to_entry( let link = match doc { doc::modtag(_) | doc::nmodtag(_) if config.output_style == config::doc_per_mod => { - markdown_writer::make_filename(config, doc::itempage(doc)) + markdown_writer::make_filename(config, doc::itempage(doc)).to_str() } _ => { ~"#" + pandoc_header_id(markdown_pass::header_text(doc)) @@ -230,7 +230,7 @@ mod test { do astsrv::from_str(source) |srv| { let config = { output_style: output_style - with config::default_config(~"whatever") + with config::default_config(&Path("whatever")) }; let doc = extract::from_srv(srv, ~""); let doc = attr_pass::mk_pass().f(srv, doc); diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index 6ed6dc4abab..da05b935cef 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -785,7 +785,7 @@ mod test { let config = { output_style: config::doc_per_crate - with config::default_config(~"whatever") + with config::default_config(&Path("whatever")) }; let doc = extract::from_srv(srv, ~""); diff --git a/src/rustdoc/markdown_writer.rs b/src/rustdoc/markdown_writer.rs index 74932ca579d..a62f275acc8 100644 --- a/src/rustdoc/markdown_writer.rs +++ b/src/rustdoc/markdown_writer.rs @@ -66,7 +66,7 @@ fn markdown_writer( ) -> writer { let filename = make_local_filename(config, page); do generic_writer |markdown| { - write_file(filename, markdown); + write_file(&filename, markdown); } } @@ -84,7 +84,7 @@ fn pandoc_writer( ~"--from=markdown", ~"--to=html", ~"--css=rust.css", - ~"--output=" + filename + ~"--output=" + filename.to_str() ]; do generic_writer |markdown| { @@ -166,15 +166,15 @@ fn generic_writer(+process: fn~(markdown: ~str)) -> writer { fn make_local_filename( config: config::config, page: doc::page -) -> ~str { +) -> Path { let filename = make_filename(config, page); - path::connect(config.output_dir, filename) + config.output_dir.push_rel(&filename) } fn make_filename( config: config::config, page: doc::page -) -> ~str { +) -> Path { let filename = { match page { doc::cratepage(doc) => { @@ -196,50 +196,50 @@ fn make_filename( config::pandoc_html => ~"html" }; - filename + ~"." + ext + Path(filename).with_filetype(ext) } #[test] fn should_use_markdown_file_name_based_off_crate() { let config = { - output_dir: ~"output/dir", + output_dir: Path("output/dir"), output_format: config::markdown, output_style: config::doc_per_crate - with config::default_config(~"input/test.rc") + with config::default_config(&Path("input/test.rc")) }; let doc = test::mk_doc(~"test", ~""); let page = doc::cratepage(doc.cratedoc()); let filename = make_local_filename(config, page); - assert filename == ~"output/dir/test.md"; + assert filename.to_str() == ~"output/dir/test.md"; } #[test] fn should_name_html_crate_file_name_index_html_when_doc_per_mod() { let config = { - output_dir: ~"output/dir", + output_dir: Path("output/dir"), output_format: config::pandoc_html, output_style: config::doc_per_mod - with config::default_config(~"input/test.rc") + with config::default_config(&Path("input/test.rc")) }; let doc = test::mk_doc(~"", ~""); let page = doc::cratepage(doc.cratedoc()); let filename = make_local_filename(config, page); - assert filename == ~"output/dir/index.html"; + assert filename.to_str() == ~"output/dir/index.html"; } #[test] fn should_name_mod_file_names_by_path() { let config = { - output_dir: ~"output/dir", + output_dir: Path("output/dir"), output_format: config::pandoc_html, output_style: config::doc_per_mod - with config::default_config(~"input/test.rc") + with config::default_config(&Path("input/test.rc")) }; let doc = test::mk_doc(~"", ~"mod a { mod b { } }"); let modb = doc.cratemod().mods()[0].mods()[0]; let page = doc::itempage(doc::modtag(modb)); let filename = make_local_filename(config, page); - assert filename == ~"output/dir/a_b.html"; + assert filename == Path("output/dir/a_b.html"); } #[cfg(test)] @@ -253,7 +253,7 @@ mod test { } } -fn write_file(path: ~str, s: ~str) { +fn write_file(path: &Path, s: ~str) { import io::WriterUtil; match io::file_writer(path, ~[io::Create, io::Truncate]) { diff --git a/src/rustdoc/parse.rs b/src/rustdoc/parse.rs index ca30e8aa8a8..e74700b7b67 100644 --- a/src/rustdoc/parse.rs +++ b/src/rustdoc/parse.rs @@ -10,7 +10,7 @@ import syntax::parse; export from_file, from_str, from_file_sess, from_str_sess; -fn from_file(file: ~str) -> @ast::crate { +fn from_file(file: &Path) -> @ast::crate { parse::parse_crate_from_file( file, ~[], parse::new_parse_sess(none)) } @@ -20,9 +20,9 @@ fn from_str(source: ~str) -> @ast::crate { ~"-", @source, ~[], parse::new_parse_sess(none)) } -fn from_file_sess(sess: session::session, file: ~str) -> @ast::crate { +fn from_file_sess(sess: session::session, file: &Path) -> @ast::crate { parse::parse_crate_from_file( - file, cfg(sess, file_input(file)), sess.parse_sess) + file, cfg(sess, file_input(*file)), sess.parse_sess) } fn from_str_sess(sess: session::session, source: ~str) -> @ast::crate { diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 751e94e8649..ec7556afa0a 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -130,13 +130,13 @@ fn time<T>(what: ~str, f: fn() -> T) -> T { fn run(config: config::config) { let source_file = config.input_crate; - do astsrv::from_file(source_file) |srv| { + do astsrv::from_file(source_file.to_str()) |srv| { do time(~"wait_ast") { do astsrv::exec(srv) |_ctxt| { } }; let doc = time(~"extract", || { let default_name = source_file; - extract::from_srv(srv, default_name) + extract::from_srv(srv, default_name.to_str()) }); run_passes(srv, doc, ~[ tystr_pass::mk_pass(), diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index b912b2cb12d..21525424b1b 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -52,13 +52,11 @@ fn shift_push() { } fn read_line() { - let path = path::connect( - env!("CFG_SRC_DIR"), - ~"src/test/bench/shootout-k-nucleotide.data" - ); + let path = Path(env!("CFG_SRC_DIR")) + .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); for int::range(0, 3) |_i| { - let reader = result::get(io::file_reader(path)); + let reader = result::get(io::file_reader(&path)); while !reader.eof() { reader.read_line(); } diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index 4b83b14c98f..b9dc89c43c5 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -85,7 +85,8 @@ fn main(args: ~[~str]) { }; let writer = if os::getenv(~"RUST_BENCH").is_some() { - result::get(io::file_writer(~"./shootout-fasta.data", ~[io::Truncate, io::Create])) + result::get(io::file_writer(&Path("./shootout-fasta.data"), + ~[io::Truncate, io::Create])) } else { io::stdout() }; diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 75a4c4f7ea4..4204a3110de 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -128,11 +128,9 @@ fn main(args: ~[~str]) { let rdr = if os::getenv(~"RUST_BENCH").is_some() { // FIXME: Using this compile-time env variable is a crummy way to // get to this massive data set, but #include_bin chokes on it (#2598) - let path = path::connect( - env!("CFG_SRC_DIR"), - ~"src/test/bench/shootout-k-nucleotide.data" - ); - result::get(io::file_reader(path)) + let path = Path(env!("CFG_SRC_DIR")) + .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); + result::get(io::file_reader(&path)) } else { io::stdin() }; diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 5e7b705714d..54ff0cde9ef 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -126,11 +126,9 @@ fn main(args: ~[~str]) { let rdr = if os::getenv(~"RUST_BENCH").is_some() { // FIXME: Using this compile-time env variable is a crummy way to // get to this massive data set, but #include_bin chokes on it (#2598) - let path = path::connect( - env!("CFG_SRC_DIR"), - ~"src/test/bench/shootout-k-nucleotide.data" - ); - result::get(io::file_reader(path)) + let path = Path(env!("CFG_SRC_DIR")) + .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); + result::get(io::file_reader(&path)) } else { io::stdin() }; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index 1f380d79269..1d1c2e2ac29 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -112,7 +112,7 @@ fn writer(path: ~str, writech: comm::Chan<comm::Chan<line>>, size: uint) } _ => { result::get( - io::file_writer(path, + io::file_writer(&Path(path), ~[io::Create, io::Truncate])) } }; diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 06ecec92d8d..3ab3a08c8a4 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -80,7 +80,7 @@ impl io::Reader: word_reader { } fn file_word_reader(filename: ~str) -> word_reader { - match io::file_reader(filename) { + match io::file_reader(&Path(filename)) { result::ok(f) => { f as word_reader } result::err(e) => { fail fmt!("%?", e) } } |
