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