Start using core::path2::Path in a lot of places.
This commit is contained in:
parent
a8f1bee457
commit
c284b8b1dc
43 changed files with 1139 additions and 1115 deletions
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 ==");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
type Path = WindowsPath;
|
||||
|
||||
#[cfg(windows)]
|
||||
pure fn Path(s: &str) -> Path {
|
||||
from_str::<WindowsPath>(s)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
type Path = PosixPath;
|
||||
|
||||
#[cfg(unix)]
|
||||
pure fn Path(s: &str) -> Path {
|
||||
from_str::<PosixPath>(s)
|
||||
}
|
||||
|
||||
impl PosixPath : ToStr {
|
||||
fn to_str() -> ~str {
|
||||
let mut s = ~"";
|
||||
if self.is_absolute {
|
||||
s += "/";
|
||||
}
|
||||
s + str::connect(self.components, "/")
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#3227): when default methods in traits are working, de-duplicate
|
||||
// PosixPath and WindowsPath, most of their methods are common.
|
||||
impl PosixPath : GenericPath {
|
||||
|
||||
impl PosixPath : Path {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fn from_str(s: &str) -> PosixPath {
|
||||
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 += "/";
|
||||
pure fn dirname() -> ~str {
|
||||
unchecked {
|
||||
let s = self.dir_path().to_str();
|
||||
if s.len() == 0 {
|
||||
~"."
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
let mut d = copy self.components;
|
||||
if d.len() != 0 {
|
||||
vec::pop(d);
|
||||
}
|
||||
s += str::connect(d, "/");
|
||||
if s.len() == 0 {
|
||||
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 {
|
||||
let mut cs = copy self.components;
|
||||
if cs.len() != 0 {
|
||||
vec::pop(cs);
|
||||
}
|
||||
return PosixPath { components: cs, ..self }
|
||||
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 {
|
||||
unchecked { vec::pop(cs); }
|
||||
}
|
||||
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 => { }
|
||||
pure fn dirname() -> ~str {
|
||||
unchecked {
|
||||
let s = self.dir_path().to_str();
|
||||
if s.len() == 0 {
|
||||
~"."
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
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 = ~".";
|
||||
}
|
||||
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");
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ~"");
|
||||
|
|
|
@ -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]) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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]))
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue