- Move io, run and rand to core.
- Remove incorrect ctypes module (use libc).
- Remove os-specific modules for os and fs.
- Split fs between core::path and core::os.
we have a file `hello.rs` containing this program:
~~~~
-use std;
fn main(args: [str]) {
- std::io::println("hello world from '" + args[0] + "'!");
+ io::println("hello world from '" + args[0] + "'!");
}
~~~~
If the Rust compiler was installed successfully, running `rustc
hello.rs` will produce a binary called `hello` (or `hello.exe`).
-If you modify the program to make it invalid (for example, remove the
-`use std` line), and then compile it, you'll see an error message like
-this:
+If you modify the program to make it invalid (for example, change the
+function to an unknown name), and then compile it, you'll see an error
+message like this:
~~~~
## notrust
-hello.rs:2:4: 2:20 error: unresolved modulename: std
-hello.rs:2 std::io::println("hello world!");
- ^~~~~~~~~~~~~~~~
+hello.rs:2:4: 2:16 error: unresolved name: io::print_it
+hello.rs:2 io::print_it("hello world from '" + args[0] + "'!");
+ ^~~~~~~~~~~~
~~~~
The Rust compiler tries to provide useful information when it runs
characters. This is a bug that will eventually be fixed.
The double-colon (`::`) is used as a module separator, so
-`std::io::println` means 'the thing named `println` in the module
-named `io` in the module named `std`'.
+`io::println` means 'the thing named `println` in the module
+named `io`.
Rust will normally emit warnings about unused variables. These can be
suppressed by using a variable name that starts with an underscore.
fn main() {
let count = 0u;
while count < repeat {
- std::io::println("Hi!");
+ io::println("Hi!");
count += 1u;
}
}
at compile time.
~~~~
-std::io::println(#fmt("%s is %d", "the answer", 42));
+io::println(#fmt("%s is %d", "the answer", 42));
~~~~
`#fmt` supports most of the directives that [printf][pf] supports, but
compile-time.
~~~~
-std::io::println(#env("PATH"));
+io::println(#env("PATH"));
~~~~
# Control structures
~~~~
if false {
- std::io::println("that's odd");
+ io::println("that's odd");
} else if true {
- std::io::println("right");
+ io::println("right");
} else {
- std::io::println("neither true nor false");
+ io::println("neither true nor false");
}
~~~~
~~~~
# let my_number = 1;
alt my_number {
- 0 { std::io::println("zero"); }
- 1 | 2 { std::io::println("one or two"); }
- 3 to 10 { std::io::println("three to ten"); }
- _ { std::io::println("something else"); }
+ 0 { io::println("zero"); }
+ 1 | 2 { io::println("one or two"); }
+ 3 to 10 { io::println("three to ten"); }
+ _ { io::println("something else"); }
}
~~~~
while true {
x += x - 3;
if x % 5 == 0 { break; }
- std::io::println(int::str(x));
+ io::println(int::str(x));
}
~~~~
~~~~
for elt in ["red", "green", "blue"] {
- std::io::println(elt);
+ io::println(elt);
}
~~~~
fn main() {
let shout = mk_appender("!");
- std::io::println(shout("hey ho, let's go"));
+ io::println(shout("hey ho, let's go"));
}
~~~~
~~~~
let myvec = [true, false, true, false];
-if myvec[1] { std::io::println("boom"); }
+if myvec[1] { io::println("boom"); }
~~~~
By default, vectors are immutable—you can not replace their elements.
fn cow() -> str { "mooo" }
}
fn main() {
- std::io::println(farm::chicken());
+ io::println(farm::chicken());
}
~~~~
// main.rs
use std;
use mylib;
-fn main() { std::io::println("hello " + mylib::world()); }
+fn main() { io::println("hello " + mylib::world()); }
~~~~
Now compile and run like this (adjust to your platform if necessary):
~~~~
use std;
-import std::io::println;
+import io::println;
fn main() {
println("that was easy");
}
~~~~
It is also possible to import just the name of a module (`import
-std::io;`, then use `io::println`), to import all identifiers exported
-by a given module (`import std::io::*`), or to import a specific set
+std::list;`, then use `list::find`), to import all identifiers exported
+by a given module (`import io::*`), or to import a specific set
of identifiers (`import math::{min, max, pi}`).
You can rename an identifier when importing using the `=` operator:
~~~~
-import prnt = std::io::println;
+import prnt = io::println;
~~~~
## Exporting
}
fn main(args: [str]) {
- std::io::println(sha1(args[1]));
+ io::println(sha1(args[1]));
}
~~~~
~~~~
let some_value = 22;
task::spawn {||
- std::io::println("This executes in the child task.");
- std::io::println(#fmt("%d", some_value));
+ io::println("This executes in the child task.");
+ io::println(#fmt("%d", some_value));
}
~~~~
import rustc::driver::diagnostic;
import result::{ok, err};
-import std::fs;
-import std::io;
import io::writer_util;
import std::json;
import result;
import std::map;
import std::map::hashmap;
-import std::os;
-import std::run;
import str;
import std::tempfile;
import vec;
}
fn need_dir(s: str) {
- if fs::path_is_dir(s) { ret; }
- if !fs::make_dir(s, 0x1c0i32) {
+ if os::path_is_dir(s) { ret; }
+ if !os::make_dir(s, 0x1c0i32) {
fail #fmt["can't make_dir %s", s];
}
}
}
fn try_parse_sources(filename: str, sources: map::hashmap<str, source>) {
- if !fs::path_exists(filename) { ret; }
+ if !os::path_exists(filename) { ret; }
let c = io::read_whole_file_str(filename);
alt json::from_str(result::get(c)) {
ok(json::dict(j)) {
fn load_source_packages(&c: cargo, &src: source) {
log(debug, "Loading source: " + src.name);
- let dir = fs::connect(c.sourcedir, src.name);
- let pkgfile = fs::connect(dir, "packages.json");
- if !fs::path_exists(pkgfile) { ret; }
+ let dir = path::connect(c.sourcedir, src.name);
+ let pkgfile = path::connect(dir, "packages.json");
+ if !os::path_exists(pkgfile) { ret; }
let pkgstr = io::read_whole_file_str(pkgfile);
alt json::from_str(result::get(pkgstr)) {
ok(json::list(js)) {
};
let sources = map::new_str_hash::<source>();
- try_parse_sources(fs::connect(syscargo, "sources.json"), sources);
- try_parse_sources(fs::connect(syscargo, "local-sources.json"), sources);
+ try_parse_sources(path::connect(syscargo, "sources.json"), sources);
+ try_parse_sources(path::connect(syscargo, "local-sources.json"), sources);
let c = {
pgp: pgp::supported(),
root: p,
- bindir: fs::connect(p, "bin"),
- libdir: fs::connect(p, "lib"),
- workdir: fs::connect(p, "work"),
- sourcedir: fs::connect(syscargo, "sources"),
+ bindir: path::connect(p, "bin"),
+ libdir: path::connect(p, "lib"),
+ workdir: path::connect(p, "work"),
+ sourcedir: path::connect(syscargo, "sources"),
sources: sources,
opts: opts
};
// FIXME: deduplicate code with install_one_crate
fn test_one_crate(_c: cargo, _path: str, cf: str, _p: pkg) {
- let buildpath = fs::connect(_path, "/test");
+ let buildpath = path::connect(_path, "/test");
need_dir(buildpath);
#debug("Testing: %s -> %s", cf, buildpath);
let p = run::program_output(rustc_sysroot(),
error(#fmt["rustc failed: %d\n%s\n%s", p.status, p.err, p.out]);
ret;
}
- let new = fs::list_dir(buildpath);
+ let new = os::list_dir(buildpath);
for ct: str in new {
run::run_program(ct, []);
}
}
fn install_one_crate(c: cargo, _path: str, cf: str, _p: pkg) {
- let buildpath = fs::connect(_path, "/build");
+ let buildpath = path::connect(_path, "/build");
need_dir(buildpath);
#debug("Installing: %s -> %s", cf, buildpath);
let p = run::program_output(rustc_sysroot(),
error(#fmt["rustc failed: %d\n%s\n%s", p.status, p.err, p.out]);
ret;
}
- let new = fs::list_dir(buildpath);
- let exec_suffix = os::exec_suffix();
+ let new = os::list_dir(buildpath);
+ let exec_suffix = os::exe_suffix();
for ct: str in new {
if (exec_suffix != "" && str::ends_with(ct, exec_suffix)) ||
- (exec_suffix == "" && !str::starts_with(fs::basename(ct),
+ (exec_suffix == "" && !str::starts_with(path::basename(ct),
"lib")) {
#debug(" bin: %s", ct);
- // FIXME: need libstd fs::copy or something
+ // FIXME: need libstd os::copy or something
run::run_program("cp", [ct, c.bindir]);
if c.opts.mode == system_mode {
install_one_crate_to_sysroot(ct, "bin");
}
fn install_one_crate_to_sysroot(ct: str, target: str) {
- alt os::get_exe_path() {
+ alt os::self_exe_path() {
some(_path) {
let path = [_path, "..", target];
check vec::is_not_empty(path);
- let target_dir = fs::normalize(fs::connect_many(path));
+ let target_dir = path::normalize(path::connect_many(path));
let p = run::program_output("cp", [ct, target_dir]);
if p.status != 0 {
warn(#fmt["Copying %s to %s is failed", ct, target_dir]);
}
fn rustc_sysroot() -> str {
- alt os::get_exe_path() {
+ alt os::self_exe_path() {
some(_path) {
let path = [_path, "..", "bin", "rustc"];
check vec::is_not_empty(path);
- let rustc = fs::normalize(fs::connect_many(path));
+ let rustc = path::normalize(path::connect_many(path));
#debug(" rustc: %s", rustc);
rustc
}
fn install_source(c: cargo, path: str) {
#debug("source: %s", path);
- fs::change_dir(path);
- let contents = fs::list_dir(".");
+ os::change_dir(path);
+ let contents = os::list_dir(".");
#debug("contents: %s", str::connect(contents, ", "));
run::run_program("git", ["clone", url, wd]);
if option::is_some::<str>(ref) {
let r = option::get::<str>(ref);
- fs::change_dir(wd);
+ os::change_dir(wd);
run::run_program("git", ["checkout", r]);
}
}
fn install_curl(c: cargo, wd: str, url: str) {
- let tarpath = fs::connect(wd, "pkg.tar");
+ let tarpath = path::connect(wd, "pkg.tar");
let p = run::program_output("curl", ["-f", "-s", "-o",
tarpath, url]);
if p.status != 0 {
let target = c.opts.free[2];
- let wd = alt tempfile::mkdtemp(c.workdir + fs::path_sep(), "") {
+ let wd = alt tempfile::mkdtemp(c.workdir + path::path_sep(), "") {
some(_wd) { _wd }
none { fail "needed temp dir"; }
};
}
fn sync_one(c: cargo, name: str, src: source) {
- let dir = fs::connect(c.sourcedir, name);
- let pkgfile = fs::connect(dir, "packages.json.new");
- let destpkgfile = fs::connect(dir, "packages.json");
- let sigfile = fs::connect(dir, "packages.json.sig");
- let keyfile = fs::connect(dir, "key.gpg");
+ let dir = path::connect(c.sourcedir, name);
+ let pkgfile = path::connect(dir, "packages.json.new");
+ let destpkgfile = path::connect(dir, "packages.json");
+ let sigfile = path::connect(dir, "packages.json.sig");
+ let keyfile = path::connect(dir, "key.gpg");
let url = src.url;
need_dir(dir);
info(#fmt["fetching source %s...", name]);
let srcurl = "http://www.rust-lang.org/cargo/sources.json";
let sigurl = "http://www.rust-lang.org/cargo/sources.json.sig";
- let srcfile = fs::connect(c.root, "sources.json.new");
- let sigfile = fs::connect(c.root, "sources.json.sig");
- let destsrcfile = fs::connect(c.root, "sources.json");
+ let srcfile = path::connect(c.root, "sources.json.new");
+ let sigfile = path::connect(c.root, "sources.json.sig");
+ let destsrcfile = path::connect(c.root, "sources.json");
let p = run::program_output("curl", ["-f", "-s", "-o", srcfile, srcurl]);
if p.status != 0 {
use std;
-import std::fs;
-import std::run;
-
fn gpg(args: [str]) -> { status: int, out: str, err: str } {
ret run::program_output("gpg", args);
}
}
fn init(root: str) {
- let p = fs::connect(root, "gpg");
- if !fs::path_is_dir(p) {
- fs::make_dir(p, 0x1c0i32);
+ let p = path::connect(root, "gpg");
+ if !os::path_is_dir(p) {
+ os::make_dir(p, 0x1c0i32);
let p = run::start_program("gpg", ["--homedir", p, "--import"]);
p.input().write_str(signing_key());
let s = p.finish();
}
fn add(root: str, key: str) {
- let path = fs::connect(root, "gpg");
+ let path = path::connect(root, "gpg");
let p = run::program_output("gpg", ["--homedir", path, "--import", key]);
if p.status != 0 {
fail "pgp add failed: " + p.out;
}
fn verify(root: str, data: str, sig: str, keyfp: str) -> bool {
- let path = fs::connect(root, "gpg");
+ let path = path::connect(root, "gpg");
let p = gpg(["--homedir", path, "--with-fingerprint", "--verify", sig,
data]);
let res = "Primary key fingerprint: " + keyfp;
import option;
import std::getopts;
import std::test;
-import std::fs;
import str;
import vec;
import task;
fn make_tests(config: config) -> [test::test_desc] {
#debug("making tests from %s", config.src_base);
let tests = [];
- for file: str in fs::list_dir(config.src_base) {
+ for file: str in os::list_dir(config.src_base) {
let file = file;
#debug("inspecting file %s", file);
if is_test(config, file) {
let valid_extensions =
alt config.mode { mode_pretty { [".rs"] } _ { [".rc", ".rs"] } };
let invalid_prefixes = [".", "#", "~"];
- let name = fs::basename(testfile);
+ let name = path::basename(testfile);
let valid = false;
-import std::io;
import io::reader_util;
-import std::fs;
import common::config;
import option;
import str;
-import std::io;
import io::reader_util;
-import std::fs;
import common::config;
ret found;
fn xfail_target() -> str {
- "xfail-" + std::os::target_os()
+ "xfail-" + os::sysname()
}
}
option::some(s) { option::some(s) }
option::none {
if parse_name_directive(line, "pp-exact") {
- option::some(fs::basename(testfile))
+ option::some(path::basename(testfile))
} else {
option::none
}
-import std::run;
-import std::run::spawn_process;
-import std::io;
-import std::os;
+import run::spawn_process;
import io::writer_util;
-import ctypes::{pid_t, fd_t};
+import libc::{c_int, pid_t};
export run;
#[cfg(target_os = "win32")]
fn target_env(lib_path: str, prog: str) -> option<[(str,str)]> {
- let env = std::generic_os::env();
+ let env = os::env();
env = vec::map(env) {|pair|
let (k,v) = pair;
ret {status: status, out: outs, err: errs};
}
-fn writeclose(fd: fd_t, s: option<str>) {
+fn writeclose(fd: c_int, s: option<str>) {
if option::is_some(s) {
let writer = io::fd_writer(fd, false);
writer.write_str(option::get(s));
os::close(fd);
}
-fn readclose(fd: fd_t) -> str {
+fn readclose(fd: c_int) -> str {
// Copied from run::program_output
- let file = os::fd_FILE(fd);
+ let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let buf = "";
while !reader.eof() {
-import std::io;
import io::writer_util;
-import std::fs;
-import std::os;
import common::mode_run_pass;
import common::mode_run_fail;
let expected =
alt props.pp_exact {
option::some(file) {
- let filepath = fs::connect(fs::dirname(testfile), file);
+ let filepath = path::connect(path::dirname(testfile), file);
result::get(io::read_whole_file_str(filepath))
}
option::none { srcs[vec::len(srcs) - 2u] }
fn compile_test(config: config, props: test_props,
testfile: str) -> procres {
vec::iter(props.aux_builds) {|rel_ab|
- let abs_ab = fs::connect(config.aux_base, rel_ab);
+ let abs_ab = path::connect(config.aux_base, rel_ab);
let auxres = compose_and_run(config, abs_ab,
make_compile_args(_, props, ["--lib"],
make_lib_name, _),
}
fn make_exe_name(config: config, testfile: str) -> str {
- output_base_name(config, testfile) + os::exec_suffix()
+ output_base_name(config, testfile) + os::exe_suffix()
}
fn make_run_args(config: config, _props: test_props, testfile: str) ->
fn output_base_name(config: config, testfile: str) -> str {
let base = config.build_base;
let filename = {
- let parts = str::split_char(fs::basename(testfile), '.');
+ let parts = str::split_char(path::basename(testfile), '.');
str::connect(vec::slice(parts, 0u, vec::len(parts) - 1u), ".")
};
#fmt["%s%s.%s", base, filename, config.stage_id]
import option;
-import std::generic_os::getenv;
-import std::io;
+import os::getenv;
import common::config;
d.write("use std;\n")
d.write("use run_pass_stage2;\n")
d.write("import run_pass_stage2::*;\n")
-d.write("import std::io::writer_util;\n");
+d.write("import io::writer_util;\n");
d.write("fn main() {\n");
-d.write(" let out = std::io::stdout();\n");
+d.write(" let out = io::stdout();\n");
i = 0
for t in stage2_tests:
p = os.path.join("test", "run-pass", t)
put_const(X_OK, int);
#endif
-#ifdef STDERR_FILENO
- put_const(STDERR_FILENO, int);
-#endif
#ifdef STDIN_FILENO
put_const(STDIN_FILENO, int);
#endif
#ifdef STDOUT_FILENO
put_const(STDOUT_FILENO, int);
#endif
+#ifdef STDERR_FILENO
+ put_const(STDERR_FILENO, int);
+#endif
#ifdef F_LOCK
put_const(F_LOCK, int);
-import std::{fs, io};
import io::writer_util;
import rustc::syntax::{ast, ast_util, fold, visit, codemap};
if str::ends_with(path, ".rs") && !contains(path, "utf8") {
// ignoring "utf8" tests because something is broken
files += [path];
- } else if fs::path_is_dir(path)
+ } else if os::path_is_dir(path)
&& !contains(path, "compile-fail")
&& !contains(path, "build") {
- for p in fs::list_dir(path) {
+ for p in os::list_dir(path) {
find_rust_files(files, p);
}
}
fn removeIfExists(filename: str) {
// So sketchy!
assert !contains(filename, " ");
- std::run::program_output("bash", ["-c", "rm " + filename]);
+ run::program_output("bash", ["-c", "rm " + filename]);
}
fn removeDirIfExists(filename: str) {
// So sketchy!
assert !contains(filename, " ");
- std::run::program_output("bash", ["-c", "rm -r " + filename]);
+ run::program_output("bash", ["-c", "rm -r " + filename]);
}
fn check_running(exe_filename: str) -> happiness {
- let p = std::run::program_output("/Users/jruderman/scripts/timed_run_rust_program.py", [exe_filename]);
+ let p = run::program_output("/Users/jruderman/scripts/timed_run_rust_program.py", [exe_filename]);
let comb = p.out + "\n" + p.err;
if str::len(comb) > 1u {
log(error, "comb comb comb: " + comb);
}
fn check_compiling(filename: str) -> happiness {
- let p = std::run::program_output(
+ let p = run::program_output(
"/Users/jruderman/code/rust/build/x86_64-apple-darwin/stage1/bin/rustc",
[filename]);
#error("Did not converge after %u iterations!", i);
write_file("round-trip-a.rs", *old);
write_file("round-trip-b.rs", *new);
- std::run::run_program("diff",
- ["-w", "-u", "round-trip-a.rs",
- "round-trip-b.rs"]);
+ run::run_program("diff",
+ ["-w", "-u", "round-trip-a.rs",
+ "round-trip-b.rs"]);
fail "Mismatch";
}
}
export c_float_targ_consts;
export c_double_targ_consts;
-import ctypes::c_int;
-import ctypes::c_float;
-import ctypes::c_double;
+import libc::c_int;
+import libc::c_float;
+import libc::c_double;
// function names are almost identical to C's libmath, a few have been
// renamed, grep for "rename:"
fn get_task_id() -> task_id;
fn chan_id_send<T: send>(t: *sys::type_desc,
target_task: task_id, target_port: port_id,
- data: T) -> ctypes::uintptr_t;
+ data: T) -> libc::uintptr_t;
- fn new_port(unit_sz: ctypes::size_t) -> *rust_port;
+ fn new_port(unit_sz: libc::size_t) -> *rust_port;
fn del_port(po: *rust_port);
fn rust_port_begin_detach(po: *rust_port,
- yield: *ctypes::uintptr_t);
+ yield: *libc::uintptr_t);
fn rust_port_end_detach(po: *rust_port);
fn get_port_id(po: *rust_port) -> port_id;
- fn rust_port_size(po: *rust_port) -> ctypes::size_t;
+ fn rust_port_size(po: *rust_port) -> libc::size_t;
fn port_recv(dptr: *uint, po: *rust_port,
- yield: *ctypes::uintptr_t);
+ yield: *libc::uintptr_t);
fn rust_port_select(dptr: **rust_port, ports: **rust_port,
- n_ports: ctypes::size_t,
- yield: *ctypes::uintptr_t);
+ n_ports: libc::size_t,
+ yield: *libc::uintptr_t);
}
#[abi = "rust-intrinsic"]
// that will grab the value of the return pointer, then call this
// function, which we will then use to call the runtime.
fn recv(dptr: *uint, port: *rust_port,
- yield: *ctypes::uintptr_t) unsafe {
+ yield: *libc::uintptr_t) unsafe {
rustrt::port_recv(dptr, port, yield);
}
let yield = 0u;
) -> either::t<A, B> unsafe {
fn select(dptr: **rust_port, ports: **rust_port,
- n_ports: ctypes::size_t, yield: *ctypes::uintptr_t) {
+ n_ports: libc::size_t, yield: *libc::uintptr_t) {
rustrt::rust_port_select(dptr, ports, n_ports, yield)
}
let mut ports = [];
ports += [***p_a, ***p_b];
- let n_ports = 2 as ctypes::size_t;
+ let n_ports = 2 as libc::size_t;
let yield = 0u;
let yieldp = ptr::addr_of(yield);
#[doc = "Returns true if there are messages available"]
fn peek<T: send>(p: port<T>) -> bool {
- rustrt::rust_port_size(***p) != 0u as ctypes::size_t
+ rustrt::rust_port_size(***p) != 0u as libc::size_t
}
#[doc = "
export float, f32, f64;
export box, char, str, ptr, vec, bool;
export either, option, result, iter;
-export libc, os, ctypes, sys, unsafe, logging;
+export libc, os, io, run, rand, sys, unsafe, logging;
export comm, task, future;
export extfmt;
export tuple;
mod libc;
mod os;
+mod io;
+mod run;
+mod rand;
mod path;
-mod ctypes;
mod cmath;
mod sys;
mod unsafe;
--- /dev/null
+/*
+Module: io
+
+Basic input/output
+*/
+
+import libc::{c_int, c_uint, c_void, size_t, ssize_t};
+import libc::consts::os::posix88::*;
+import libc::consts::os::extra::*;
+
+type fd_t = c_int;
+
+#[abi = "cdecl"]
+native mod rustrt {
+ fn rust_get_stdin() -> *libc::FILE;
+ fn rust_get_stdout() -> *libc::FILE;
+ fn rust_get_stderr() -> *libc::FILE;
+}
+
+// Reading
+
+// FIXME This is all buffered. We might need an unbuffered variant as well
+enum seek_style { seek_set, seek_end, seek_cur, }
+
+
+// The raw underlying reader iface. All readers must implement this.
+iface reader {
+ // FIXME: Seekable really should be orthogonal.
+ fn read_bytes(uint) -> [u8];
+ fn read_byte() -> int;
+ fn unread_byte(int);
+ fn eof() -> bool;
+ fn seek(int, seek_style);
+ fn tell() -> uint;
+}
+
+// Generic utility functions defined on readers
+
+impl reader_util for reader {
+ fn read_chars(n: uint) -> [char] {
+ // returns the (consumed offset, n_req), appends characters to &chars
+ fn chars_from_buf(buf: [u8], &chars: [char]) -> (uint, uint) {
+ let mut i = 0u;
+ while i < vec::len(buf) {
+ let b0 = buf[i];
+ let w = str::utf8_char_width(b0);
+ let end = i + w;
+ i += 1u;
+ assert (w > 0u);
+ if w == 1u {
+ chars += [ b0 as char ];
+ cont;
+ }
+ // can't satisfy this char with the existing data
+ if end > vec::len(buf) {
+ ret (i - 1u, end - vec::len(buf));
+ }
+ let mut val = 0u;
+ while i < end {
+ let next = buf[i] as int;
+ i += 1u;
+ assert (next > -1);
+ assert (next & 192 == 128);
+ val <<= 6u;
+ val += (next & 63) as uint;
+ }
+ // See str::char_at
+ val += ((b0 << ((w + 1u) as u8)) as uint)
+ << (w - 1u) * 6u - w - 1u;
+ chars += [ val as char ];
+ }
+ ret (i, 0u);
+ }
+ let mut buf: [u8] = [];
+ let mut chars: [char] = [];
+ // might need more bytes, but reading n will never over-read
+ let mut nbread = n;
+ while nbread > 0u {
+ let data = self.read_bytes(nbread);
+ if vec::len(data) == 0u {
+ // eof - FIXME should we do something if
+ // we're split in a unicode char?
+ break;
+ }
+ buf += data;
+ let (offset, nbreq) = chars_from_buf(buf, chars);
+ let ncreq = n - vec::len(chars);
+ // again we either know we need a certain number of bytes
+ // to complete a character, or we make sure we don't
+ // over-read by reading 1-byte per char needed
+ nbread = if ncreq > nbreq { ncreq } else { nbreq };
+ if nbread > 0u {
+ buf = vec::slice(buf, offset, vec::len(buf));
+ }
+ }
+ chars
+ }
+
+ fn read_char() -> char {
+ let c = self.read_chars(1u);
+ if vec::len(c) == 0u {
+ ret -1 as char; // FIXME will this stay valid?
+ }
+ assert(vec::len(c) == 1u);
+ ret c[0];
+ }
+
+ fn read_line() -> str {
+ let mut buf: [u8] = [];
+ while true {
+ let ch = self.read_byte();
+ if ch == -1 || ch == 10 { break; }
+ buf += [ch as u8];
+ }
+ str::from_bytes(buf)
+ }
+
+ fn read_c_str() -> str {
+ let mut buf: [u8] = [];
+ while true {
+ let ch = self.read_byte();
+ if ch < 1 { break; } else { buf += [ch as u8]; }
+ }
+ str::from_bytes(buf)
+ }
+
+ // FIXME deal with eof?
+ fn read_le_uint(size: uint) -> uint {
+ let mut val = 0u, pos = 0u, i = size;
+ while i > 0u {
+ val += (self.read_byte() as uint) << pos;
+ pos += 8u;
+ i -= 1u;
+ }
+ val
+ }
+ fn read_le_int(size: uint) -> int {
+ let mut val = 0u, pos = 0u, i = size;
+ while i > 0u {
+ val += (self.read_byte() as uint) << pos;
+ pos += 8u;
+ i -= 1u;
+ }
+ val as int
+ }
+ fn read_be_uint(size: uint) -> uint {
+ let mut val = 0u, i = size;
+ while i > 0u {
+ i -= 1u;
+ val += (self.read_byte() as uint) << i * 8u;
+ }
+ val
+ }
+
+ fn read_whole_stream() -> [u8] {
+ let mut buf: [u8] = [];
+ while !self.eof() { buf += self.read_bytes(2048u); }
+ buf
+ }
+}
+
+// Reader implementations
+
+fn convert_whence(whence: seek_style) -> i32 {
+ ret alt whence {
+ seek_set { 0i32 }
+ seek_cur { 1i32 }
+ seek_end { 2i32 }
+ };
+}
+
+impl of reader for *libc::FILE {
+ fn read_bytes(len: uint) -> [u8] unsafe {
+ let mut buf : [mutable u8] = [mutable];
+ vec::reserve(buf, len);
+ vec::as_mut_buf(buf) {|b|
+ let read = libc::fread(b as *mutable c_void, 1u,
+ len, self);
+ vec::unsafe::set_len(buf, read);
+ }
+ ret vec::from_mut(buf);
+ }
+ fn read_byte() -> int { ret libc::fgetc(self) as int; }
+ fn unread_byte(byte: int) { libc::ungetc(byte as c_int, self); }
+ fn eof() -> bool { ret libc::feof(self) != 0 as c_int; }
+ fn seek(offset: int, whence: seek_style) {
+ assert libc::fseek(self, offset, convert_whence(whence))
+ == 0 as c_int;
+ }
+ fn tell() -> uint { ret libc::ftell(self) as uint; }
+}
+
+// A forwarding impl of reader that also holds on to a resource for the
+// duration of its lifetime.
+// FIXME there really should be a better way to do this
+impl <T: reader, C> of reader for {base: T, cleanup: C} {
+ fn read_bytes(len: uint) -> [u8] { self.base.read_bytes(len) }
+ fn read_byte() -> int { self.base.read_byte() }
+ fn unread_byte(byte: int) { self.base.unread_byte(byte); }
+ fn eof() -> bool { self.base.eof() }
+ fn seek(off: int, whence: seek_style) { self.base.seek(off, whence) }
+ fn tell() -> uint { self.base.tell() }
+}
+
+resource FILE_res(f: *libc::FILE) { libc::fclose(f); }
+
+fn FILE_reader(f: *libc::FILE, cleanup: bool) -> reader {
+ if cleanup {
+ {base: f, cleanup: FILE_res(f)} as reader
+ } else {
+ f as reader
+ }
+}
+
+// FIXME: this should either be an iface-less impl, a set of top-level
+// functions that take a reader, or a set of default methods on reader
+// (which can then be called reader)
+
+fn stdin() -> reader { rustrt::rust_get_stdin() as reader }
+
+fn file_reader(path: str) -> result::t<reader, str> {
+ let f = os::as_c_charp(path, {|pathbuf|
+ os::as_c_charp("r", {|modebuf|
+ libc::fopen(pathbuf, modebuf)
+ })
+ });
+ ret if f as uint == 0u { result::err("error opening " + path) }
+ else {
+ result::ok(FILE_reader(f, true))
+ }
+}
+
+
+// Byte buffer readers
+
+// TODO: const u8, but this fails with rustboot.
+type byte_buf = {buf: [u8], mutable pos: uint, len: uint};
+
+impl of reader for byte_buf {
+ fn read_bytes(len: uint) -> [u8] {
+ let rest = self.len - self.pos;
+ let mut to_read = len;
+ if rest < to_read { to_read = rest; }
+ let range = vec::slice(self.buf, self.pos, self.pos + to_read);
+ self.pos += to_read;
+ ret range;
+ }
+ fn read_byte() -> int {
+ if self.pos == self.len { ret -1; }
+ let b = self.buf[self.pos];
+ self.pos += 1u;
+ ret b as int;
+ }
+ fn unread_byte(_byte: int) { #error("TODO: unread_byte"); fail; }
+ fn eof() -> bool { self.pos == self.len }
+ fn seek(offset: int, whence: seek_style) {
+ let pos = self.pos;
+ self.pos = seek_in_buf(offset, pos, self.len, whence);
+ }
+ fn tell() -> uint { self.pos }
+}
+
+fn bytes_reader(bytes: [u8]) -> reader {
+ bytes_reader_between(bytes, 0u, vec::len(bytes))
+}
+
+fn bytes_reader_between(bytes: [u8], start: uint, end: uint) -> reader {
+ {buf: bytes, mutable pos: start, len: end} as reader
+}
+
+fn with_bytes_reader<t>(bytes: [u8], f: fn(reader) -> t) -> t {
+ f(bytes_reader(bytes))
+}
+
+fn with_bytes_reader_between<t>(bytes: [u8], start: uint, end: uint,
+ f: fn(reader) -> t) -> t {
+ f(bytes_reader_between(bytes, start, end))
+}
+
+fn str_reader(s: str) -> reader {
+ bytes_reader(str::bytes(s))
+}
+
+fn with_str_reader<T>(s: str, f: fn(reader) -> T) -> T {
+ str::as_bytes(s) { |bytes|
+ with_bytes_reader_between(bytes, 0u, str::len(s), f)
+ }
+}
+
+// Writing
+enum fileflag { append, create, truncate, no_flag, }
+
+// FIXME: Seekable really should be orthogonal.
+// FIXME: eventually u64
+iface writer {
+ fn write([const u8]);
+ fn seek(int, seek_style);
+ fn tell() -> uint;
+ fn flush() -> int;
+}
+
+impl <T: writer, C> of writer for {base: T, cleanup: C} {
+ fn write(bs: [const u8]) { self.base.write(bs); }
+ fn seek(off: int, style: seek_style) { self.base.seek(off, style); }
+ fn tell() -> uint { self.base.tell() }
+ fn flush() -> int { self.base.flush() }
+}
+
+impl of writer for *libc::FILE {
+ fn write(v: [const u8]) unsafe {
+ let len = vec::len(v);
+ vec::as_buf(v) {|vbuf|
+ let nout = libc::fwrite(vbuf as *c_void, len, 1u, self);
+ if nout < 1 as size_t {
+ #error("error writing buffer");
+ log(error, sys::last_os_error());
+ fail;
+ }
+ }
+ }
+ fn seek(offset: int, whence: seek_style) {
+ assert libc::fseek(self, offset, convert_whence(whence))
+ == 0 as c_int;
+ }
+ fn tell() -> uint { libc::ftell(self) as uint }
+ fn flush() -> int { libc::fflush(self) as int }
+}
+
+fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
+ if cleanup {
+ {base: f, cleanup: FILE_res(f)} as writer
+ } else {
+ f as writer
+ }
+}
+
+impl of writer for fd_t {
+ fn write(v: [const u8]) unsafe {
+ let len = vec::len(v);
+ let mut count = 0u;
+ vec::as_buf(v) {|vbuf|
+ while count < len {
+ let vb = ptr::offset(vbuf, count) as *c_void;
+ let nout = libc::write(self, vb, len);
+ if nout < 0 as ssize_t {
+ #error("error writing buffer");
+ log(error, sys::last_os_error());
+ fail;
+ }
+ count += nout as uint;
+ }
+ }
+ }
+ fn seek(_offset: int, _whence: seek_style) {
+ #error("need 64-bit native calls for seek, sorry");
+ fail;
+ }
+ fn tell() -> uint {
+ #error("need 64-bit native calls for tell, sorry");
+ fail;
+ }
+ fn flush() -> int { 0 }
+}
+
+resource fd_res(fd: fd_t) { libc::close(fd); }
+
+fn fd_writer(fd: fd_t, cleanup: bool) -> writer {
+ if cleanup {
+ {base: fd, cleanup: fd_res(fd)} as writer
+ } else {
+ fd as writer
+ }
+}
+
+
+fn mk_file_writer(path: str, flags: [fileflag])
+ -> result::t<writer, str> {
+
+ #[cfg(target_os = "win32")]
+ fn wb() -> c_int { (O_WRONLY | O_BINARY) as c_int }
+
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ fn wb() -> c_int { O_WRONLY as c_int }
+
+ let mut fflags: c_int = wb();
+ for f: fileflag in flags {
+ alt f {
+ append { fflags |= O_APPEND as c_int; }
+ create { fflags |= O_CREAT as c_int; }
+ truncate { fflags |= O_TRUNC as c_int; }
+ no_flag { }
+ }
+ }
+ let fd = os::as_c_charp(path) {|pathbuf|
+ libc::open(pathbuf, fflags,
+ (S_IRUSR | S_IWUSR) as c_int)
+ };
+ if fd < (0 as c_int) {
+ // FIXME don't log this! put it in the returned error string
+ log(error, sys::last_os_error());
+ result::err("error opening " + path)
+ } else {
+ result::ok(fd_writer(fd, true))
+ }
+}
+
+fn u64_to_le_bytes(n: u64, size: uint) -> [u8] {
+ let mut bytes: [u8] = [], i = size, n = n;
+ while i > 0u {
+ bytes += [(n & 255_u64) as u8];
+ n >>= 8_u64;
+ i -= 1u;
+ }
+ ret bytes;
+}
+
+fn u64_to_be_bytes(n: u64, size: uint) -> [u8] {
+ assert size <= 8u;
+ let mut bytes: [u8] = [];
+ let mut i = size;
+ while i > 0u {
+ let shift = ((i - 1u) * 8u) as u64;
+ bytes += [(n >> shift) as u8];
+ i -= 1u;
+ }
+ ret bytes;
+}
+
+fn u64_from_be_bytes(data: [u8], start: uint, size: uint) -> u64 {
+ let mut sz = size;
+ assert (sz <= 8u);
+ let mut val = 0_u64;
+ let mut pos = start;
+ while sz > 0u {
+ sz -= 1u;
+ val += (data[pos] as u64) << ((sz * 8u) as u64);
+ pos += 1u;
+ }
+ ret val;
+}
+
+impl writer_util for writer {
+ fn write_char(ch: char) {
+ if ch as uint < 128u {
+ self.write([ch as u8]);
+ } else {
+ self.write(str::bytes(str::from_char(ch)));
+ }
+ }
+ fn write_str(s: str) { self.write(str::bytes(s)); }
+ fn write_line(s: str) { self.write(str::bytes(s + "\n")); }
+ fn write_int(n: int) { self.write(str::bytes(int::to_str(n, 10u))); }
+ fn write_uint(n: uint) { self.write(str::bytes(uint::to_str(n, 10u))); }
+
+ fn write_le_uint(n: uint, size: uint) {
+ self.write(u64_to_le_bytes(n as u64, size));
+ }
+ fn write_le_int(n: int, size: uint) {
+ self.write(u64_to_le_bytes(n as u64, size));
+ }
+
+ fn write_be_uint(n: uint, size: uint) {
+ self.write(u64_to_be_bytes(n as u64, size));
+ }
+ fn write_be_int(n: int, size: uint) {
+ self.write(u64_to_be_bytes(n as u64, size));
+ }
+
+ fn write_be_u64(n: u64) { self.write(u64_to_be_bytes(n, 8u)); }
+ fn write_be_u32(n: u32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
+ fn write_be_u16(n: u16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
+
+ fn write_be_i64(n: i64) { self.write(u64_to_be_bytes(n as u64, 8u)); }
+ fn write_be_i32(n: i32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
+ fn write_be_i16(n: i16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
+
+ fn write_le_u64(n: u64) { self.write(u64_to_le_bytes(n, 8u)); }
+ fn write_le_u32(n: u32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
+ fn write_le_u16(n: u16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
+
+ fn write_le_i64(n: i64) { self.write(u64_to_le_bytes(n as u64, 8u)); }
+ fn write_le_i32(n: i32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
+ fn write_le_i16(n: i16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
+
+ fn write_u8(n: u8) { self.write([n]) }
+}
+
+fn file_writer(path: str, flags: [fileflag]) -> result::t<writer, str> {
+ result::chain(mk_file_writer(path, flags), { |w| result::ok(w)})
+}
+
+
+// FIXME: fileflags
+fn buffered_file_writer(path: str) -> result::t<writer, str> {
+ let f = os::as_c_charp(path) {|pathbuf|
+ os::as_c_charp("w") {|modebuf|
+ libc::fopen(pathbuf, modebuf)
+ }
+ };
+ ret if f as uint == 0u { result::err("error opening " + path) }
+ else { result::ok(FILE_writer(f, true)) }
+}
+
+// FIXME it would be great if this could be a const
+// FIXME why are these different from the way stdin() is implemented?
+fn stdout() -> writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
+fn stderr() -> writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
+
+fn print(s: str) { stdout().write_str(s); }
+fn println(s: str) { stdout().write_line(s); }
+
+type mem_buffer = @{mutable buf: [mutable u8],
+ mutable pos: uint};
+
+impl of writer for mem_buffer {
+ fn write(v: [const u8]) {
+ // Fast path.
+ if self.pos == vec::len(self.buf) {
+ for b: u8 in v { self.buf += [mutable b]; }
+ self.pos += vec::len(v);
+ ret;
+ }
+ // FIXME: Optimize: These should be unique pointers.
+ let vlen = vec::len(v);
+ let mut vpos = 0u;
+ while vpos < vlen {
+ let b = v[vpos];
+ if self.pos == vec::len(self.buf) {
+ self.buf += [mutable b];
+ } else { self.buf[self.pos] = b; }
+ self.pos += 1u;
+ vpos += 1u;
+ }
+ }
+ fn seek(offset: int, whence: seek_style) {
+ let pos = self.pos;
+ let len = vec::len(self.buf);
+ self.pos = seek_in_buf(offset, pos, len, whence);
+ }
+ fn tell() -> uint { self.pos }
+ fn flush() -> int { 0 }
+}
+
+fn mk_mem_buffer() -> mem_buffer {
+ @{mutable buf: [mutable], mutable pos: 0u}
+}
+fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer }
+fn mem_buffer_buf(b: mem_buffer) -> [u8] { vec::from_mut(b.buf) }
+fn mem_buffer_str(b: mem_buffer) -> str {
+ let b_ = vec::from_mut(b.buf);
+ str::from_bytes(b_)
+}
+
+fn with_str_writer(f: fn(writer)) -> str {
+ let buf = mk_mem_buffer();
+ let wr = mem_buffer_writer(buf);
+ f(wr);
+ io::mem_buffer_str(buf)
+}
+
+fn with_buf_writer(f: fn(writer)) -> [u8] {
+ let buf = mk_mem_buffer();
+ let wr = mem_buffer_writer(buf);
+ f(wr);
+ io::mem_buffer_buf(buf)
+}
+
+// Utility functions
+fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
+ uint {
+ let mut bpos = pos as int;
+ let blen = len as int;
+ alt whence {
+ seek_set { bpos = offset; }
+ seek_cur { bpos += offset; }
+ seek_end { bpos = blen + offset; }
+ }
+ if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
+ ret bpos as uint;
+}
+
+fn read_whole_file_str(file: str) -> result::t<str, str> {
+ result::chain(read_whole_file(file), { |bytes|
+ result::ok(str::from_bytes(bytes))
+ })
+}
+
+// FIXME implement this in a low-level way. Going through the abstractions is
+// pointless.
+fn read_whole_file(file: str) -> result::t<[u8], str> {
+ result::chain(file_reader(file), { |rdr|
+ result::ok(rdr.read_whole_stream())
+ })
+}
+
+// fsync related
+
+mod fsync {
+
+ enum level {
+ // whatever fsync does on that platform
+ fsync,
+
+ // fdatasync on linux, similiar or more on other platforms
+ fdatasync,
+
+ // full fsync
+ //
+ // You must additionally sync the parent directory as well!
+ fullfsync,
+ }
+
+
+ // Resource of artifacts that need to fsync on destruction
+ resource res<t>(arg: arg<t>) {
+ alt arg.opt_level {
+ option::none { }
+ option::some(level) {
+ // fail hard if not succesful
+ assert(arg.fsync_fn(arg.val, level) != -1);
+ }
+ }
+ }
+
+ type arg<t> = {
+ val: t,
+ opt_level: option<level>,
+ fsync_fn: fn@(t, level) -> int
+ };
+
+ // fsync file after executing blk
+ // FIXME find better way to create resources within lifetime of outer res
+ fn FILE_res_sync(&&file: FILE_res, opt_level: option<level>,
+ blk: fn(&&res<*libc::FILE>)) {
+ blk(res({
+ val: *file, opt_level: opt_level,
+ fsync_fn: fn@(&&file: *libc::FILE, l: level) -> int {
+ ret os::fsync_fd(libc::fileno(file), l) as int;
+ }
+ }));
+ }
+
+ // fsync fd after executing blk
+ fn fd_res_sync(&&fd: fd_res, opt_level: option<level>,
+ blk: fn(&&res<fd_t>)) {
+ blk(res({
+ val: *fd, opt_level: opt_level,
+ fsync_fn: fn@(&&fd: fd_t, l: level) -> int {
+ ret os::fsync_fd(fd, l) as int;
+ }
+ }));
+ }
+
+ // Type of objects that may want to fsync
+ iface t { fn fsync(l: level) -> int; }
+
+ // Call o.fsync after executing blk
+ fn obj_sync(&&o: t, opt_level: option<level>, blk: fn(&&res<t>)) {
+ blk(res({
+ val: o, opt_level: opt_level,
+ fsync_fn: fn@(&&o: t, l: level) -> int { ret o.fsync(l); }
+ }));
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ #[test]
+ fn test_simple() {
+ let tmpfile: str = "tmp/lib-io-test-simple.tmp";
+ log(debug, tmpfile);
+ let frood: str = "A hoopy frood who really knows where his towel is.";
+ log(debug, frood);
+ {
+ let out: io::writer =
+ result::get(
+ io::file_writer(tmpfile, [io::create, io::truncate]));
+ out.write_str(frood);
+ }
+ let inp: io::reader = result::get(io::file_reader(tmpfile));
+ let frood2: str = inp.read_c_str();
+ log(debug, frood2);
+ assert (str::eq(frood, frood2));
+ }
+
+ #[test]
+ fn test_readchars_empty() {
+ let inp : io::reader = io::str_reader("");
+ let res : [char] = inp.read_chars(128u);
+ assert(vec::len(res) == 0u);
+ }
+
+ #[test]
+ fn test_readchars_wide() {
+ let wide_test = "生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
+ let ivals : [int] = [
+ 29983, 38152, 30340, 27748,
+ 21273, 20999, 32905, 27748,
+ 104, 101, 108, 108, 111,
+ 29983, 38152, 30340, 27748,
+ 21273, 20999, 32905, 27748];
+ fn check_read_ln(len : uint, s: str, ivals: [int]) {
+ let inp : io::reader = io::str_reader(s);
+ let res : [char] = inp.read_chars(len);
+ if (len <= vec::len(ivals)) {
+ assert(vec::len(res) == len);
+ }
+ assert(vec::slice(ivals, 0u, vec::len(res)) ==
+ vec::map(res, {|x| x as int}));
+ }
+ let i = 0u;
+ while i < 8u {
+ check_read_ln(i, wide_test, ivals);
+ i += 1u;
+ }
+ // check a long read for good measure
+ check_read_ln(128u, wide_test, ivals);
+ }
+
+ #[test]
+ fn test_readchar() {
+ let inp : io::reader = io::str_reader("生");
+ let res : char = inp.read_char();
+ assert(res as int == 29983);
+ }
+
+ #[test]
+ fn test_readchar_empty() {
+ let inp : io::reader = io::str_reader("");
+ let res : char = inp.read_char();
+ assert(res as int == -1);
+ }
+
+ #[test]
+ fn file_reader_not_exist() {
+ alt io::file_reader("not a file") {
+ result::err(e) {
+ assert e == "error opening not a file";
+ }
+ result::ok(_) { fail; }
+ }
+ }
+
+ #[test]
+ fn file_writer_bad_name() {
+ alt io::file_writer("?/?", []) {
+ result::err(e) {
+ assert e == "error opening ?/?";
+ }
+ result::ok(_) { fail; }
+ }
+ }
+
+ #[test]
+ fn buffered_file_writer_bad_name() {
+ alt io::buffered_file_writer("?/?") {
+ result::err(e) {
+ assert e == "error opening ?/?";
+ }
+ result::ok(_) { fail; }
+ }
+ }
+}
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
export c_longlong, c_ulonglong, intptr_t, uintptr_t;
export off_t, dev_t, ino_t, pid_t, mode_t, ssize_t;
+export EXIT_FAILURE, EXIT_SUCCESS, RAND_MAX,
+ EOF, SEEK_SET, SEEK_CUR, SEEK_END, _IOFBF, _IONBF, _IOLBF,
+ BUFSIZ, FOPEN_MAX, FILENAME_MAX, L_tmpnam, TMP_MAX,
+ O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_EXCL, O_TRUNC,
+ S_IFIFO, S_IFCHR, S_IFBLK, S_IFDIR, S_IFREG, S_IFMT, S_IEXEC,
+ S_IWRITE, S_IREAD, S_IRWXU, S_IXUSR, S_IWUSR, S_IRUSR, F_OK, R_OK,
+ W_OK, X_OK, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO;
+
export isalnum, isalpha, iscntrl, isdigit, islower, isprint, ispunct,
isspace, isupper, isxdigit, tolower, toupper;
strxfrm, memcpy, memmove, memcmp, memchr, memset;
export chmod, mkdir;
-export popen, pclose, fdopen;
+export popen, pclose, fdopen, fileno;
export open, creat;
export access, chdir, close, dup, dup2, execv, execve, execvp, getcwd,
getpid, isatty, lseek, pipe, read, rmdir, unlink, write;
const R_OK : int = 4;
const W_OK : int = 2;
const X_OK : int = 1;
- const STDERR_FILENO : int = 2;
const STDIN_FILENO : int = 0;
const STDOUT_FILENO : int = 1;
+ const STDERR_FILENO : int = 2;
}
mod posix01 { }
mod posix08 { }
const R_OK : int = 4;
const W_OK : int = 2;
const X_OK : int = 1;
+ const STDIN_FILENO : int = 0;
+ const STDOUT_FILENO : int = 1;
+ const STDERR_FILENO : int = 2;
const F_LOCK : int = 1;
const F_TEST : int = 3;
const F_TLOCK : int = 2;
const R_OK : int = 4;
const W_OK : int = 2;
const X_OK : int = 1;
- const STDERR_FILENO : int = 2;
const STDIN_FILENO : int = 0;
const STDOUT_FILENO : int = 1;
+ const STDERR_FILENO : int = 2;
const F_LOCK : int = 1;
const F_TEST : int = 3;
const F_TLOCK : int = 2;
const R_OK : int = 4;
const W_OK : int = 2;
const X_OK : int = 1;
- const STDERR_FILENO : int = 2;
const STDIN_FILENO : int = 0;
const STDOUT_FILENO : int = 1;
+ const STDERR_FILENO : int = 2;
const F_LOCK : int = 1;
const F_TEST : int = 3;
const F_TLOCK : int = 2;
fn setbuf(stream: *FILE, buf: *c_char);
// Omitted: printf and scanf variants.
fn fgetc(stream: *FILE) -> c_int;
- fn fgets(buf: *c_char, n: c_int, stream: *FILE) -> *c_char;
+ fn fgets(buf: *mutable c_char, n: c_int,
+ stream: *FILE) -> *c_char;
fn fputc(c: c_int, stream: *FILE) -> c_int;
fn fputs(s: *c_char, stream: *FILE) -> *c_char;
// Omitted: getc, getchar (might be macros).
// Omitted: putc, putchar (might be macros).
fn puts(s: *c_char) -> c_int;
fn ungetc(c: c_int, stream: *FILE) -> c_int;
- fn fread(ptr: *c_void, size: size_t,
+ fn fread(ptr: *mutable c_void, size: size_t,
nobj: size_t, stream: *FILE) -> size_t;
fn fwrite(ptr: *c_void, size: size_t,
nobj: size_t, stream: *FILE) -> size_t;
#[abi = "cdecl"]
native mod fcntl {
#[link_name = "_open"]
- fn open(path: *c_char, oflag: c_int) -> c_int;
+ fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
#[link_name = "_creat"]
fn creat(path: *c_char, mode: c_int) -> c_int;
textmode: c_int) -> c_int;
#[link_name = "_read"]
- fn read(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
+ fn read(fd: c_int, buf: *mutable c_void, count: c_uint) -> c_int;
#[link_name = "_rmdir"]
fn rmdir(path: *c_char) -> c_int;
fn unlink(c: *c_char) -> c_int;
#[link_name = "_write"]
- fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_uint;
+ fn write(fd: c_int, buf: *c_void, count: c_uint) -> c_int;
}
}
#[nolink]
#[abi = "cdecl"]
native mod fcntl {
- fn open(path: *c_char, oflag: c_int) -> c_int;
+ fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int;
fn creat(path: *c_char, mode: mode_t) -> c_int;
fn fcntl(fd: c_int, cmd: c_int) -> c_int;
}
fn getegid() -> gid_t;
fn geteuid() -> uid_t;
fn getgid() -> gid_t ;
- fn getgroups(ngroups_max: c_int, groups: *gid_t) -> c_int;
+ fn getgroups(ngroups_max: c_int, groups: *mutable gid_t) -> c_int;
fn getlogin() -> *c_char;
fn getopt(argc: c_int, argv: **c_char, optstr: *c_char) -> c_int;
fn getpgrp() -> pid_t;
fn pathconf(path: *c_char, name: c_int) -> c_long;
fn pause() -> c_int;
fn pipe(fds: *mutable c_int) -> c_int;
- fn read(fd: c_int, buf: *c_void, count: size_t) -> ssize_t;
+ fn read(fd: c_int, buf: *mutable c_void,
+ count: size_t) -> ssize_t;
fn rmdir(path: *c_char) -> c_int;
fn setgid(gid: gid_t) -> c_int;
fn setpgid(pid: pid_t, pgid: pid_t) -> c_int;
import getcwd = rustrt::rust_getcwd;
import consts::*;
-export close, fclose, fsync_fd;
+export close, fclose, fsync_fd, waitpid;
export env, getenv, setenv, fdopen, pipe;
export getcwd, dll_filename, self_exe_path;
export exe_suffix, dll_suffix, sysname;
-export homedir, list_dir, path_is_dir, path_exists;
+export homedir, list_dir, path_is_dir, path_exists, make_absolute,
+ make_dir, remove_dir, change_dir, remove_file;
+
+// FIXME: move these to str perhaps?
+export as_c_charp, fill_charp_buf;
native mod rustrt {
fn rust_env_pairs() -> [str];
fn fill_utf16_buf_and_decode(f: fn(*mutable u16, dword) -> dword)
-> option<str> {
- let buf = vec::to_mut(vec::init_elt(tmpbuf_sz, 0u16));
- vec::as_mut_buf(buf) {|b|
- let k : dword = f(b, tmpbuf_sz as dword);
- if k == (0 as dword) {
- none
- } else {
- let sub = vec::slice(buf, 0u, k as uint);
- option::some::<str>(str::from_utf16(sub))
+
+ // FIXME: remove these when export globs work properly.
+ import libc::funcs::extra::kernel32::*;
+ import libc::consts::os::extra::*;
+
+ let mut n = tmpbuf_sz;
+ let mut res = none;
+ let mut done = false;
+ while !done {
+ let buf = vec::to_mut(vec::init_elt(n, 0u16));
+ vec::as_mut_buf(buf) {|b|
+ let k : dword = f(b, tmpbuf_sz as dword);
+ if k == (0 as dword) {
+ done = true;
+ } else if (k == n &&
+ GetLastError() ==
+ ERROR_INSUFFICIENT_BUFFER as dword) {
+ n *= (2 as dword);
+ } else {
+ let sub = vec::slice(buf, 0u, k as uint);
+ res = option::some::<str>(str::from_utf16(sub));
+ done = true;
+ }
}
}
+ ret res;
}
fn as_utf16_p<T>(s: str, f: fn(*u16) -> T) -> T {
// fsync related
-enum fsync_level {
- // whatever fsync does on that platform
- fsync,
-
- // fdatasync on linux, similiar or more on other platforms
- fdatasync,
-
- // full fsync
- //
- // You must additionally sync the parent directory as well!
- fullfsync,
-}
-
#[cfg(target_os = "win32")]
-fn fsync_fd(fd: c_int, _level: fsync_level) -> c_int {
+fn fsync_fd(fd: c_int, _level: io::fsync::level) -> c_int {
import libc::funcs::extra::msvcrt::*;
ret commit(fd);
}
#[cfg(target_os = "linux")]
-fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
+fn fsync_fd(fd: c_int, level: io::fsync::level) -> c_int {
import libc::funcs::posix01::unistd::*;
alt level {
- fsync | fullfsync { ret fsync(fd); }
- fdatasync { ret fdatasync(fd); }
+ io::fsync::fsync
+ | io::fsync::fullfsync { ret fsync(fd); }
+ io::fsync::fdatasync { ret fdatasync(fd); }
}
}
#[cfg(target_os = "macos")]
-fn fsync_fd(fd: c_int, level: fsync_level) -> c_int {
+fn fsync_fd(fd: c_int, level: io::fsync::level) -> c_int {
import libc::consts::os::extra::*;
import libc::funcs::posix88::fcntl::*;
import libc::funcs::posix01::unistd::*;
alt level {
- fsync { ret fsync(fd); }
+ io::fsync::fsync { ret fsync(fd); }
_ {
// According to man fnctl, the ok retval is only specified to be !=-1
if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
}
#[cfg(target_os = "freebsd")]
-fn fsync_fd(fd: c_int, _l: fsync_level) -> c_int {
+fn fsync_fd(fd: c_int, _l: io::fsync::level) -> c_int {
import libc::funcs::posix01::unistd::*;
ret fsync(fd);
}
#[cfg(test)]
mod tests {
+
+ fn make_rand_name() -> str {
+ import rand;
+ let rng: rand::rng = rand::mk_rng();
+ let n = "TEST" + rng.gen_str(10u);
+ assert option::is_none(getenv(n));
+ n
+ }
+
+ #[test]
+ #[ignore(reason = "fails periodically on mac")]
+ fn test_setenv() {
+ let n = make_rand_name();
+ setenv(n, "VALUE");
+ assert getenv(n) == option::some("VALUE");
+ }
+
+ #[test]
+ #[ignore(reason = "fails periodically on mac")]
+ fn test_setenv_overwrite() {
+ let n = make_rand_name();
+ setenv(n, "1");
+ setenv(n, "2");
+ assert getenv(n) == option::some("2");
+ setenv(n, "");
+ assert getenv(n) == option::some("");
+ }
+
+ // Windows GetEnvironmentVariable requires some extra work to make sure
+ // the buffer the variable is copied into is the right size
+ #[test]
+ #[ignore(reason = "fails periodically on mac")]
+ fn test_getenv_big() {
+ let s = "";
+ let i = 0;
+ while i < 100 { s += "aaaaaaaaaa"; i += 1; }
+ let n = make_rand_name();
+ setenv(n, s);
+ log(debug, s);
+ assert getenv(n) == option::some(s);
+ }
+
+ #[test]
+ fn test_self_exe_path() {
+ let path = os::self_exe_path();
+ assert option::is_some(path);
+ let path = option::get(path);
+ log(debug, path);
+
+ // Hard to test this function
+ if os::sysname() != "win32" {
+ assert str::starts_with(path, path::path_sep());
+ } else {
+ assert path[1] == ':' as u8;
+ }
+ }
+
+ #[test]
+ fn test_env_getenv() {
+ let e = env();
+ assert vec::len(e) > 0u;
+ for (n, v) in e {
+ log(debug, n);
+ let v2 = getenv(n);
+ // MingW seems to set some funky environment variables like
+ // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
+ // from env() but not visible from getenv().
+ assert option::is_none(v2) || v2 == option::some(v);
+ }
+ }
+
+ #[test]
+ fn test_env_setenv() {
+ let n = make_rand_name();
+
+ let e = env();
+ setenv(n, "VALUE");
+ assert !vec::contains(e, (n, "VALUE"));
+
+ e = env();
+ assert vec::contains(e, (n, "VALUE"));
+ }
+
#[test]
fn test() {
assert (!path::path_is_absolute("test-path"));
#[abi = "rust-intrinsic"]
native mod rusti {
fn addr_of<T>(val: T) -> *T;
- fn ptr_offset<T>(ptr: *T, count: ctypes::uintptr_t) -> *T;
- fn memcpy<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
- fn memmove<T>(dst: *T, src: *T, count: ctypes::uintptr_t);
+ fn ptr_offset<T>(ptr: *T, count: libc::uintptr_t) -> *T;
+ fn memcpy<T>(dst: *T, src: *T, count: libc::uintptr_t);
+ fn memmove<T>(dst: *T, src: *T, count: libc::uintptr_t);
}
#[doc = "Get an unsafe pointer to a value"]
--- /dev/null
+#[doc = "Random number generation"]
+
+enum rctx {}
+
+#[abi = "cdecl"]
+native mod rustrt {
+ fn rand_new() -> *rctx;
+ fn rand_next(c: *rctx) -> u32;
+ fn rand_free(c: *rctx);
+}
+
+#[doc = "A random number generator"]
+iface rng {
+ #[doc = "Return the next random integer"]
+ fn next() -> u32;
+
+ #[doc = "Return the next random float"]
+ fn next_float() -> float;
+
+ #[doc = "Return a random string composed of A-Z, a-z, 0-9."]
+ fn gen_str(len: uint) -> str;
+
+ #[doc = "Return a random byte string."]
+ fn gen_bytes(len: uint) -> [u8];
+}
+
+resource rand_res(c: *rctx) { rustrt::rand_free(c); }
+
+#[doc = "Create a random number generator"]
+fn mk_rng() -> rng {
+ impl of rng for @rand_res {
+ fn next() -> u32 { ret rustrt::rand_next(**self); }
+ fn next_float() -> float {
+ let u1 = rustrt::rand_next(**self) as float;
+ let u2 = rustrt::rand_next(**self) as float;
+ let u3 = rustrt::rand_next(**self) as float;
+ let scale = u32::max_value as float;
+ ret ((u1 / scale + u2) / scale + u3) / scale;
+ }
+ fn gen_str(len: uint) -> str {
+ let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
+ "abcdefghijklmnopqrstuvwxyz" +
+ "0123456789";
+ let mut s = "";
+ let mut i = 0u;
+ while (i < len) {
+ let n = rustrt::rand_next(**self) as uint %
+ str::len(charset);
+ s = s + str::from_char(str::char_at(charset, n));
+ i += 1u;
+ }
+ s
+ }
+ fn gen_bytes(len: uint) -> [u8] {
+ let mut v = [];
+ let mut i = 0u;
+ while i < len {
+ let n = rustrt::rand_next(**self) as uint;
+ v += [(n % (u8::max_value as uint)) as u8];
+ i += 1u;
+ }
+ v
+ }
+ }
+ @rand_res(rustrt::rand_new()) as rng
+}
+
+#[cfg(test)]
+mod tests {
+
+ #[test]
+ fn test() {
+ let r1: rand::rng = rand::mk_rng();
+ log(debug, r1.next());
+ log(debug, r1.next());
+ {
+ let r2 = rand::mk_rng();
+ log(debug, r1.next());
+ log(debug, r2.next());
+ log(debug, r1.next());
+ log(debug, r1.next());
+ log(debug, r2.next());
+ log(debug, r2.next());
+ log(debug, r1.next());
+ log(debug, r1.next());
+ log(debug, r1.next());
+ log(debug, r2.next());
+ log(debug, r2.next());
+ log(debug, r2.next());
+ }
+ log(debug, r1.next());
+ log(debug, r1.next());
+ }
+
+ #[test]
+ fn genstr() {
+ let r: rand::rng = rand::mk_rng();
+ log(debug, r.gen_str(10u));
+ log(debug, r.gen_str(10u));
+ log(debug, r.gen_str(10u));
+ assert(str::len(r.gen_str(10u)) == 10u);
+ assert(str::len(r.gen_str(16u)) == 16u);
+ }
+}
+
+
+// Local Variables:
+// mode: rust;
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
--- /dev/null
+#[doc ="Process spawning"];
+import option::{some, none};
+import str::sbuf;
+import libc::{pid_t, c_void, c_int};
+
+export program;
+export run_program;
+export start_program;
+export program_output;
+export spawn_process;
+export waitpid;
+
+#[abi = "cdecl"]
+native mod rustrt {
+ fn rust_run_program(argv: *sbuf, envp: *c_void, dir: sbuf,
+ in_fd: c_int, out_fd: c_int, err_fd: c_int)
+ -> pid_t;
+}
+
+#[doc ="A value representing a child process"]
+iface program {
+ #[doc ="Returns the process id of the program"]
+ fn get_id() -> pid_t;
+
+ #[doc ="Returns an io::writer that can be used to write to stdin"]
+ fn input() -> io::writer;
+
+ #[doc ="Returns an io::reader that can be used to read from stdout"]
+ fn output() -> io::reader;
+
+ #[doc ="Returns an io::reader that can be used to read from stderr"]
+ fn err() -> io::reader;
+
+ #[doc = "Closes the handle to the child processes standard input"]
+ fn close_input();
+
+ #[doc = "
+ Waits for the child process to terminate. Closes the handle
+ to stdin if necessary.
+ "]
+ fn finish() -> int;
+
+ #[doc ="Closes open handles"]
+ fn destroy();
+}
+
+
+#[doc = "
+Run a program, providing stdin, stdout and stderr handles
+
+# Arguments
+
+* prog - The path to an executable
+* args - Vector of arguments to pass to the child process
+* env - optional env-modification for child
+* dir - optional dir to run child in (default current dir)
+* in_fd - A file descriptor for the child to use as std input
+* out_fd - A file descriptor for the child to use as std output
+* err_fd - A file descriptor for the child to use as std error
+
+# Return value
+
+The process id of the spawned process
+"]
+fn spawn_process(prog: str, args: [str],
+ env: option<[(str,str)]>,
+ dir: option<str>,
+ in_fd: c_int, out_fd: c_int, err_fd: c_int)
+ -> pid_t unsafe {
+ with_argv(prog, args) {|argv|
+ with_envp(env) { |envp|
+ with_dirp(dir) { |dirp|
+ rustrt::rust_run_program(argv, envp, dirp,
+ in_fd, out_fd, err_fd)
+ }
+ }
+ }
+}
+
+fn with_argv<T>(prog: str, args: [str],
+ cb: fn(*sbuf) -> T) -> T unsafe {
+ let mut argptrs = str::as_buf(prog) {|b| [b] };
+ let mut tmps = [];
+ for arg in args {
+ let t = @arg;
+ tmps += [t];
+ argptrs += str::as_buf(*t) {|b| [b] };
+ }
+ argptrs += [ptr::null()];
+ vec::as_buf(argptrs, cb)
+}
+
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "freebsd")]
+fn with_envp<T>(env: option<[(str,str)]>,
+ cb: fn(*c_void) -> T) -> T unsafe {
+ // On posixy systems we can pass a char** for envp, which is
+ // a null-terminated array of "k=v\n" strings.
+ alt env {
+ some (es) {
+ let mut tmps = [];
+ let mut ptrs = [];
+
+ for (k,v) in es {
+ let t = @(#fmt("%s=%s", k, v));
+ vec::push(tmps, t);
+ ptrs += str::as_buf(*t) {|b| [b]};
+ }
+ ptrs += [ptr::null()];
+ vec::as_buf(ptrs) { |p| cb(::unsafe::reinterpret_cast(p)) }
+ }
+ none {
+ cb(ptr::null())
+ }
+ }
+}
+
+#[cfg(target_os = "win32")]
+fn with_envp<T>(env: option<[(str,str)]>,
+ cb: fn(*c_void) -> T) -> T unsafe {
+ // On win32 we pass an "environment block" which is not a char**, but
+ // rather a concatenation of null-terminated k=v\0 sequences, with a final
+ // \0 to terminate.
+ alt env {
+ some (es) {
+ let mut blk : [u8] = [];
+ for (k,v) in es {
+ let t = #fmt("%s=%s", k, v);
+ let mut v : [u8] = ::unsafe::reinterpret_cast(t);
+ blk += v;
+ ::unsafe::leak(v);
+ }
+ blk += [0_u8];
+ vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
+ }
+ none {
+ cb(ptr::null())
+ }
+ }
+}
+
+fn with_dirp<T>(d: option<str>,
+ cb: fn(sbuf) -> T) -> T unsafe {
+ alt d {
+ some(dir) { str::as_buf(dir, cb) }
+ none { cb(ptr::null()) }
+ }
+}
+
+#[doc ="
+Spawns a process and waits for it to terminate
+
+# Arguments
+
+* prog - The path to an executable
+* args - Vector of arguments to pass to the child process
+
+# Return value
+
+The process id
+"]
+fn run_program(prog: str, args: [str]) -> int {
+ ret waitpid(spawn_process(prog, args, none, none,
+ 0i32, 0i32, 0i32));
+}
+
+#[doc ="
+Spawns a process and returns a program
+
+The returned value is a boxed resource containing a <program> object that can
+be used for sending and recieving data over the standard file descriptors.
+The resource will ensure that file descriptors are closed properly.
+
+# Arguments
+
+* prog - The path to an executable
+* args - Vector of arguments to pass to the child process
+
+# Return value
+
+A boxed resource of <program>
+"]
+fn start_program(prog: str, args: [str]) -> program {
+ let pipe_input = os::pipe();
+ let pipe_output = os::pipe();
+ let pipe_err = os::pipe();
+ let pid =
+ spawn_process(prog, args, none, none,
+ pipe_input.in, pipe_output.out,
+ pipe_err.out);
+
+ if pid == -1i32 { fail; }
+ libc::close(pipe_input.in);
+ libc::close(pipe_output.out);
+ libc::close(pipe_err.out);
+
+ type prog_repr = {pid: pid_t,
+ mutable in_fd: c_int,
+ out_file: *libc::FILE,
+ err_file: *libc::FILE,
+ mutable finished: bool};
+
+ fn close_repr_input(r: prog_repr) {
+ let invalid_fd = -1i32;
+ if r.in_fd != invalid_fd {
+ libc::close(r.in_fd);
+ r.in_fd = invalid_fd;
+ }
+ }
+ fn finish_repr(r: prog_repr) -> int {
+ if r.finished { ret 0; }
+ r.finished = true;
+ close_repr_input(r);
+ ret waitpid(r.pid);
+ }
+ fn destroy_repr(r: prog_repr) {
+ finish_repr(r);
+ libc::fclose(r.out_file);
+ libc::fclose(r.err_file);
+ }
+ resource prog_res(r: prog_repr) { destroy_repr(r); }
+
+ impl of program for prog_res {
+ fn get_id() -> pid_t { ret self.pid; }
+ fn input() -> io::writer { io::fd_writer(self.in_fd, false) }
+ fn output() -> io::reader { io::FILE_reader(self.out_file, false) }
+ fn err() -> io::reader { io::FILE_reader(self.err_file, false) }
+ fn close_input() { close_repr_input(*self); }
+ fn finish() -> int { finish_repr(*self) }
+ fn destroy() { destroy_repr(*self); }
+ }
+ let repr = {pid: pid,
+ mutable in_fd: pipe_input.out,
+ out_file: os::fdopen(pipe_output.in),
+ err_file: os::fdopen(pipe_err.in),
+ mutable finished: false};
+ ret prog_res(repr) as program;
+}
+
+fn read_all(rd: io::reader) -> str {
+ let mut buf = "";
+ while !rd.eof() {
+ let bytes = rd.read_bytes(4096u);
+ buf += str::from_bytes(bytes);
+ }
+ ret buf;
+}
+
+#[doc ="
+Spawns a process, waits for it to exit, and returns the exit code, and
+contents of stdout and stderr.
+
+# Arguments
+
+* prog - The path to an executable
+* args - Vector of arguments to pass to the child process
+
+# Return value
+
+A record, {status: int, out: str, err: str} containing the exit code,
+the contents of stdout and the contents of stderr.
+"]
+fn program_output(prog: str, args: [str]) ->
+ {status: int, out: str, err: str} {
+ let pr = start_program(prog, args);
+ pr.close_input();
+ let out = read_all(pr.output());
+ let err = read_all(pr.err());
+ ret {status: pr.finish(), out: out, err: err};
+}
+
+#[doc ="Waits for a process to exit and returns the exit code"]
+fn waitpid(pid: pid_t) -> int {
+ ret waitpid_os(pid);
+
+ #[cfg(target_os = "win32")]
+ fn waitpid_os(pid: pid_t) -> int {
+ os::waitpid(pid) as int
+ }
+
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ fn waitpid_os(pid: pid_t) -> int {
+ #[cfg(target_os = "linux")]
+ fn WIFEXITED(status: i32) -> bool {
+ (status & 0xffi32) == 0i32
+ }
+
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ fn WIFEXITED(status: i32) -> bool {
+ (status & 0x7fi32) == 0i32
+ }
+
+ #[cfg(target_os = "linux")]
+ fn WEXITSTATUS(status: i32) -> i32 {
+ (status >> 8i32) & 0xffi32
+ }
+
+ #[cfg(target_os = "macos")]
+ #[cfg(target_os = "freebsd")]
+ fn WEXITSTATUS(status: i32) -> i32 {
+ status >> 8i32
+ }
+
+ let status = os::waitpid(pid);
+ ret if WIFEXITED(status) {
+ WEXITSTATUS(status) as int
+ } else {
+ 1
+ };
+ }
+}
+
+#[cfg(test)]
+mod tests {
+
+ import io::writer_util;
+
+ // Regression test for memory leaks
+ #[ignore(cfg(target_os = "win32"))] // FIXME
+ fn test_leaks() {
+ run::run_program("echo", []);
+ run::start_program("echo", []);
+ run::program_output("echo", []);
+ }
+
+ #[test]
+ fn test_pipes() {
+ let pipe_in = os::pipe();
+ let pipe_out = os::pipe();
+ let pipe_err = os::pipe();
+
+ let pid =
+ run::spawn_process(
+ "cat", [], none, none,
+ pipe_in.in, pipe_out.out, pipe_err.out);
+ os::close(pipe_in.in);
+ os::close(pipe_out.out);
+ os::close(pipe_err.out);
+
+ if pid == -1i32 { fail; }
+ let expected = "test";
+ writeclose(pipe_in.out, expected);
+ let actual = readclose(pipe_out.in);
+ readclose(pipe_err.in);
+ os::waitpid(pid);
+
+ log(debug, expected);
+ log(debug, actual);
+ assert (expected == actual);
+
+ fn writeclose(fd: c_int, s: str) {
+ #error("writeclose %d, %s", fd as int, s);
+ let writer = io::fd_writer(fd, false);
+ writer.write_str(s);
+
+ os::close(fd);
+ }
+
+ fn readclose(fd: c_int) -> str {
+ // Copied from run::program_output
+ let file = os::fdopen(fd);
+ let reader = io::FILE_reader(file, false);
+ let buf = "";
+ while !reader.eof() {
+ let bytes = reader.read_bytes(4096u);
+ buf += str::from_bytes(bytes);
+ }
+ os::fclose(file);
+ ret buf;
+ }
+ }
+
+ #[test]
+ fn waitpid() {
+ let pid = run::spawn_process("false", [],
+ none, none,
+ 0i32, 0i32, 0i32);
+ let status = run::waitpid(pid);
+ assert status == 1;
+ }
+
+}
+
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
#[abi = "cdecl"]
native mod rustrt {
fn rust_str_push(&s: str, ch: u8);
- fn str_reserve_shared(&ss: str, nn: ctypes::size_t);
+ fn str_reserve_shared(&ss: str, nn: libc::size_t);
}
// FIXME: add pure to a lot of functions
export set_exit_status;
enum type_desc = {
- first_param: **ctypes::c_int,
- size: ctypes::size_t,
- align: ctypes::size_t
+ first_param: **libc::c_int,
+ size: libc::size_t,
+ align: libc::size_t
// Remaining fields not listed
};
// available outside this crate. Otherwise it's
// visible-in-crate, but not re-exported.
fn last_os_error() -> str;
- fn refcount<T>(t: @T) -> ctypes::intptr_t;
+ fn refcount<T>(t: @T) -> libc::intptr_t;
fn unsupervise();
fn shape_log_str<T>(t: *sys::type_desc, data: T) -> str;
- fn rust_set_exit_status(code: ctypes::intptr_t);
+ fn rust_set_exit_status(code: libc::intptr_t);
}
#[abi = "rust-intrinsic"]
// Invokes __builtin_frame_address().
// See <http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html>.
- fn frame_address(n: ctypes::c_uint) -> ctypes::uintptr_t;
+ fn frame_address(n: libc::c_uint) -> libc::uintptr_t;
}
#[doc = "
#[doc = "Returns the refcount of a shared box"]
fn refcount<T>(t: @T) -> uint {
- ret rustrt::refcount::<T>(t);
+ ret rustrt::refcount::<T>(t) as uint;
}
fn log_str<T>(t: T) -> str {
the process exits with the default failure status
"]
fn set_exit_status(code: int) {
- rustrt::rust_set_exit_status(code as ctypes::intptr_t);
+ rustrt::rust_set_exit_status(code as libc::intptr_t);
}
#[cfg(test)]
// These are both opaque runtime/compiler types that we don't know the
// structure of and should only deal with via unsafe pointer
-type rust_task = ctypes::void;
-type rust_closure = ctypes::void;
+type rust_task = libc::c_void;
+type rust_closure = libc::c_void;
fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
native mod rustrt {
fn rust_get_sched_id() -> sched_id;
- fn rust_new_sched(num_threads: ctypes::uintptr_t) -> sched_id;
+ fn rust_new_sched(num_threads: libc::uintptr_t) -> sched_id;
fn get_task_id() -> task_id;
fn rust_get_task() -> *rust_task;
#[nolink]
#[cfg(test)]
native mod testrt {
- fn rust_dbg_lock_create() -> *ctypes::void;
- fn rust_dbg_lock_destroy(lock: *ctypes::void);
- fn rust_dbg_lock_lock(lock: *ctypes::void);
- fn rust_dbg_lock_unlock(lock: *ctypes::void);
- fn rust_dbg_lock_wait(lock: *ctypes::void);
- fn rust_dbg_lock_signal(lock: *ctypes::void);
+ fn rust_dbg_lock_create() -> *libc::c_void;
+ fn rust_dbg_lock_destroy(lock: *libc::c_void);
+ fn rust_dbg_lock_lock(lock: *libc::c_void);
+ fn rust_dbg_lock_unlock(lock: *libc::c_void);
+ fn rust_dbg_lock_wait(lock: *libc::c_void);
+ fn rust_dbg_lock_signal(lock: *libc::c_void);
}
#[test]
#[abi = "rust-intrinsic"]
native mod rusti {
- fn vec_len<T>(&&v: [const T]) -> ctypes::size_t;
+ fn vec_len<T>(&&v: [const T]) -> libc::size_t;
}
#[abi = "cdecl"]
native mod rustrt {
fn vec_reserve_shared<T>(t: *sys::type_desc,
&v: [const T],
- n: ctypes::size_t);
+ n: libc::size_t);
fn vec_from_buf_shared<T>(t: *sys::type_desc,
ptr: *T,
- count: ctypes::size_t) -> [T];
+ count: libc::size_t) -> [T];
}
#[doc = "A function used to initialize the elements of a vector"]
pure fn cmp(&&a: [u8], &&b: [u8]) -> int unsafe {
let a_len = len(a);
let b_len = len(b);
- let n = uint::min(a_len, b_len) as ctypes::size_t;
+ let n = uint::min(a_len, b_len) as libc::size_t;
let r = libc::memcmp(unsafe::to_ptr(a) as *libc::c_void,
unsafe::to_ptr(b) as *libc::c_void, n) as int;
#[cfg(test)]
mod tests {
- import ctypes::*;
-
- #[nolink]
- #[abi = "cdecl"]
- native mod libc {
- fn malloc(n: size_t) -> *mutable u8;
- fn free(m: *mutable u8);
- }
+ import libc::*;
fn malloc(n: size_t) -> t<u8> {
let mem = libc::malloc(n);
assert mem as int != 0;
- ret unsafe { create_with_dtor(mem, n, bind libc::free(mem)) };
+ ret unsafe { create_with_dtor(mem as *mutable u8, n,
+ bind free(mem)) };
}
#[test]
+++ /dev/null
-/*
-Module: os
-
-TODO: Restructure and document
-*/
-
-import core::option;
-import core::ctypes::*;
-
-export libc;
-export libc_constants;
-export pipe;
-export FILE, fd_FILE;
-export close;
-export fclose;
-export waitpid;
-export getcwd;
-export exec_suffix;
-export target_os;
-export dylib_filename;
-export get_exe_path;
-export fsync_fd;
-export rustrt;
-
-// FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult
-// by https://github.com/graydon/rust/issues#issue/268
-
-enum FILE_opaque {}
-type FILE = *FILE_opaque;
-enum dir {}
-enum dirent {}
-
-#[nolink]
-#[abi = "cdecl"]
-native mod libc {
- fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn fread(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn fwrite(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t;
- fn close(fd: fd_t) -> c_int;
- fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
- fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
- fn fclose(f: FILE);
- fn fflush(f: FILE) -> c_int;
- fn fsync(fd: fd_t) -> c_int;
- fn fileno(f: FILE) -> fd_t;
- fn fgetc(f: FILE) -> c_int;
- fn ungetc(c: c_int, f: FILE);
- fn feof(f: FILE) -> c_int;
- fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
- fn ftell(f: FILE) -> long;
- fn opendir(d: str::sbuf) -> *dir;
- fn closedir(d: *dir) -> c_int;
- fn readdir(d: *dir) -> *dirent;
- fn getenv(n: str::sbuf) -> str::sbuf;
- fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int;
- fn unsetenv(n: str::sbuf) -> c_int;
- fn pipe(buf: *mutable fd_t) -> c_int;
- fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> pid_t;
- fn readlink(path: str::sbuf, buf: str::sbuf, bufsize: size_t) -> ssize_t;
- fn mkdir(path: str::sbuf, mode: c_int) -> c_int;
- fn rmdir(path: str::sbuf) -> c_int;
- fn chdir(path: str::sbuf) -> c_int;
- fn unlink(path: str::sbuf) -> c_int;
-
- fn sysctl(name: *c_int, namelen: c_uint,
- oldp: *u8, &oldlenp: size_t,
- newp: *u8, newlen: size_t) -> c_int;
-}
-
-mod libc_constants {
- const O_RDONLY: c_int = 0i32;
- const O_WRONLY: c_int = 1i32;
- const O_RDWR: c_int = 2i32;
- const O_APPEND: c_int = 8i32;
- const O_CREAT: c_int = 512i32;
- const O_EXCL: c_int = 2048i32;
- const O_TRUNC: c_int = 1024i32;
- const O_TEXT: c_int = 0i32; // nonexistent in FreeBSD libc
- const O_BINARY: c_int = 0i32; // nonexistent in FreeBSD libc
-
- const S_IRUSR: unsigned = 256u32;
- const S_IWUSR: unsigned = 128u32;
-
- const CTL_KERN: c_int = 1i32;
- const KERN_PROC: c_int = 14i32;
- const KERN_PROC_PATHNAME: c_int = 12i32;
-}
-
-fn pipe() -> {in: fd_t, out: fd_t} {
- let fds = {mutable in: 0i32, mutable out: 0i32};
- assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32);
- ret {in: fds.in, out: fds.out};
-}
-
-fn fd_FILE(fd: fd_t) -> FILE {
- ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
-}
-
-fn close(fd: fd_t) -> c_int {
- libc::close(fd)
-}
-
-fn fclose(file: FILE) {
- libc::fclose(file)
-}
-
-fn fsync_fd(fd: fd_t, _l: io::fsync::level) -> c_int {
- ret libc::fsync(fd);
-}
-
-fn waitpid(pid: pid_t) -> i32 {
- let status = 0i32;
- assert (os::libc::waitpid(pid, status, 0i32) != -1i32);
- ret status;
-}
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_env_pairs() -> [str];
- fn rust_getcwd() -> str;
-}
-
-fn getcwd() -> str { ret rustrt::rust_getcwd(); }
-
-fn exec_suffix() -> str { ret ""; }
-
-fn target_os() -> str { ret "freebsd"; }
-
-fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; }
-
-/// Returns the directory containing the running program
-/// followed by a path separator
-fn get_exe_path() -> option<fs::path> unsafe {
- let bufsize = 1023u;
- // FIXME: path "strings" will likely need fixing...
- let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
- let mib = [libc_constants::CTL_KERN,
- libc_constants::KERN_PROC,
- libc_constants::KERN_PROC_PATHNAME, -1i32];
- ret str::as_buf(path, { |path_buf|
- if libc::sysctl(vec::unsafe::to_ptr(mib),
- vec::len(mib) as c_uint,
- path_buf, bufsize,
- ptr::null(), 0u) == 0i32 {
- option::some(fs::dirname(path) + fs::path_sep())
- } else {
- option::none
- }
- });
-}
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-/*
-Module: fs
-
-File system manipulation
-*/
-
-import core::ctypes;
-import core::vec;
-import core::option;
-import os;
-import os::getcwd;
-import os_fs;
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_path_is_dir(path: str::sbuf) -> ctypes::c_int;
- fn rust_path_exists(path: str::sbuf) -> ctypes::c_int;
-}
-
-/*
-Function: path_sep
-
-Get the default path separator for the host platform
-*/
-fn path_sep() -> str { ret str::from_char(os_fs::path_sep); }
-
-// FIXME: This type should probably be constrained
-/*
-Type: path
-
-A path or fragment of a filesystem path
-*/
-type path = str;
-
-fn split_dirname_basename (pp: path) -> {dirname: str, basename: str} {
- alt str::rfind(pp, {|ch|
- ch == os_fs::path_sep || ch == os_fs::alt_path_sep
- }) {
- some(i) {
- {dirname: str::slice(pp, 0u, i),
- basename: str::slice(pp, i + 1u, str::len(pp))}
- }
- none { {dirname: ".", basename: pp} }
- }
-}
-
-/*
-Function: dirname
-
-Get the directory portion of a path
-
-Returns all of the path up to, but excluding, the final path separator.
-The dirname of "/usr/share" will be "/usr", but the dirname of
-"/usr/share/" is "/usr/share".
-
-If the path is not prefixed with a directory, then "." is returned.
-*/
-fn dirname(pp: path) -> path {
- ret split_dirname_basename(pp).dirname;
-}
-
-/*
-Function: basename
-
-Get the file name portion of a path
-
-Returns the portion of the path after the final path separator.
-The basename of "/usr/share" will be "share". If there are no
-path separators in the path then the returned path is identical to
-the provided path. If an empty path is provided or the path ends
-with a path separator then an empty path is returned.
-*/
-fn basename(pp: path) -> path {
- ret split_dirname_basename(pp).basename;
-}
-
-// FIXME: Need some typestate to avoid bounds check when len(pre) == 0
-/*
-Function: connect
-
-Connects to path segments
-
-Given paths `pre` and `post, removes any trailing path separator on `pre` and
-any leading path separator on `post`, and returns the concatenation of the two
-with a single path separator between them.
-*/
-
-fn connect(pre: path, post: path) -> path unsafe {
- let pre_ = pre;
- let post_ = post;
- let sep = os_fs::path_sep as u8;
- let pre_len = str::len(pre);
- let post_len = str::len(post);
- if pre_len > 1u && pre[pre_len-1u] == sep { str::unsafe::pop_byte(pre_); }
- if post_len > 1u && post[0] == sep { str::unsafe::shift_byte(post_); }
- ret pre_ + path_sep() + post_;
-}
-
-/*
-Function: connect_many
-
-Connects a vector of path segments into a single path.
-
-Inserts path separators as needed.
-*/
-fn connect_many(paths: [path]) -> path {
- ret if vec::len(paths) == 1u {
- paths[0]
- } else {
- let rest = vec::slice(paths, 1u, vec::len(paths));
- connect(paths[0], connect_many(rest))
- }
-}
-
-/*
-Function: path_is_dir
-
-Indicates whether a path represents a directory.
-*/
-fn path_is_dir(p: path) -> bool {
- ret str::as_buf(p, {|buf|
- rustrt::rust_path_is_dir(buf) != 0 as ctypes::c_int
- });
-}
-
-/*
-Function: path_exists
-
-Indicates whether a path exists.
-*/
-fn path_exists(p: path) -> bool {
- ret str::as_buf(p, {|buf|
- rustrt::rust_path_exists(buf) != 0 as ctypes::c_int
- });
-}
-
-/*
-Function: make_dir
-
-Creates a directory at the specified path.
-*/
-fn make_dir(p: path, mode: ctypes::c_int) -> bool {
- ret mkdir(p, mode);
-
- #[cfg(target_os = "win32")]
- fn mkdir(_p: path, _mode: ctypes::c_int) -> bool unsafe {
- // FIXME: turn mode into something useful?
- ret str::as_buf(_p, {|buf|
- os::kernel32::CreateDirectoryA(
- buf, unsafe::reinterpret_cast(0))
- });
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn mkdir(_p: path, _mode: ctypes::c_int) -> bool {
- ret str::as_buf(_p, {|buf| os::libc::mkdir(buf, _mode) == 0i32 });
- }
-}
-
-/*
-Function: list_dir
-
-Lists the contents of a directory.
-*/
-fn list_dir(p: path) -> [str] {
- let p = p;
- let pl = str::len(p);
- if pl == 0u || p[pl - 1u] as char != os_fs::path_sep { p += path_sep(); }
- let full_paths: [str] = [];
- for filename: str in os_fs::list_dir(p) {
- if !str::eq(filename, ".") {
- if !str::eq(filename, "..") { full_paths += [p + filename]; }
- }
- }
- ret full_paths;
-}
-
-/*
-Function: remove_dir
-
-Removes a directory at the specified path.
-*/
-fn remove_dir(p: path) -> bool {
- ret rmdir(p);
-
- #[cfg(target_os = "win32")]
- fn rmdir(_p: path) -> bool {
- ret str::as_buf(_p, {|buf| os::kernel32::RemoveDirectoryA(buf)});
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn rmdir(_p: path) -> bool {
- ret str::as_buf(_p, {|buf| os::libc::rmdir(buf) == 0i32 });
- }
-}
-
-fn change_dir(p: path) -> bool {
- ret chdir(p);
-
- #[cfg(target_os = "win32")]
- fn chdir(_p: path) -> bool {
- ret str::as_buf(_p, {|buf| os::kernel32::SetCurrentDirectoryA(buf)});
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn chdir(_p: path) -> bool {
- ret str::as_buf(_p, {|buf| os::libc::chdir(buf) == 0i32 });
- }
-}
-
-/*
-Function: path_is_absolute
-
-Indicates whether a path is absolute.
-
-A path is considered absolute if it begins at the filesystem root ("/") or,
-on Windows, begins with a drive letter.
-*/
-fn path_is_absolute(p: path) -> bool { ret os_fs::path_is_absolute(p); }
-
-// FIXME: under Windows, we should prepend the current drive letter to paths
-// that start with a slash.
-/*
-Function: make_absolute
-
-Convert a relative path to an absolute path
-
-If the given path is relative, return it prepended with the current working
-directory. If the given path is already an absolute path, return it
-as is.
-*/
-fn make_absolute(p: path) -> path {
- if path_is_absolute(p) { ret p; } else { ret connect(getcwd(), p); }
-}
-
-/*
-Function: split
-
-Split a path into it's individual components
-
-Splits a given path by path separators and returns a vector containing
-each piece of the path. On Windows, if the path is absolute then
-the first element of the returned vector will be the drive letter
-followed by a colon.
-*/
-fn split(p: path) -> [path] {
- str::split_nonempty(p, {|c|
- c == os_fs::path_sep || c == os_fs::alt_path_sep
- })
-}
-
-/*
-Function: splitext
-
-Split a path into a pair of strings with the first element being the filename
-without the extension and the second being either empty or the file extension
-including the period. Leading periods in the basename are ignored. If the
-path includes directory components then they are included in the filename part
-of the result pair.
-*/
-fn splitext(p: path) -> (str, str) {
- if str::is_empty(p) { ("", "") }
- else {
- let parts = str::split_char(p, '.');
- if vec::len(parts) > 1u {
- let base = str::connect(vec::init(parts), ".");
- // We just checked that parts is non-empty
- let ext = "." + vec::last(parts);
-
- fn is_dotfile(base: str) -> bool {
- str::is_empty(base)
- || str::ends_with(
- base, str::from_char(os_fs::path_sep))
- || str::ends_with(
- base, str::from_char(os_fs::alt_path_sep))
- }
-
- fn ext_contains_sep(ext: str) -> bool {
- vec::len(split(ext)) > 1u
- }
-
- fn no_basename(ext: str) -> bool {
- str::ends_with(
- ext, str::from_char(os_fs::path_sep))
- || str::ends_with(
- ext, str::from_char(os_fs::alt_path_sep))
- }
-
- if is_dotfile(base)
- || ext_contains_sep(ext)
- || no_basename(ext) {
- (p, "")
- } else {
- (base, ext)
- }
- } else {
- (p, "")
- }
- }
-}
-
-/*
-Function: normalize
-
-Removes extra "." and ".." entries from paths.
-
-Does not follow symbolic links.
-*/
-fn normalize(p: path) -> path {
- let s = split(p);
- let s = strip_dots(s);
- let s = rollup_doubledots(s);
-
- let s = if check vec::is_not_empty(s) {
- connect_many(s)
- } else {
- ""
- };
- let s = reabsolute(p, s);
- let s = reterminate(p, s);
-
- let s = if str::len(s) == 0u {
- "."
- } else {
- s
- };
-
- ret s;
-
- fn strip_dots(s: [path]) -> [path] {
- vec::filter_map(s, { |elem|
- if elem == "." {
- option::none
- } else {
- option::some(elem)
- }
- })
- }
-
- fn rollup_doubledots(s: [path]) -> [path] {
- if vec::is_empty(s) {
- ret [];
- }
-
- let t = [];
- let i = vec::len(s);
- let skip = 0;
- do {
- i -= 1u;
- if s[i] == ".." {
- skip += 1;
- } else {
- if skip == 0 {
- t += [s[i]];
- } else {
- skip -= 1;
- }
- }
- } while i != 0u;
- let t = vec::reversed(t);
- while skip > 0 {
- t += [".."];
- skip -= 1;
- }
- ret t;
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn reabsolute(orig: path, new: path) -> path {
- if path_is_absolute(orig) {
- path_sep() + new
- } else {
- new
- }
- }
-
- #[cfg(target_os = "win32")]
- fn reabsolute(orig: path, new: path) -> path {
- if path_is_absolute(orig) && orig[0] == os_fs::path_sep as u8 {
- str::from_char(os_fs::path_sep) + new
- } else {
- new
- }
- }
-
- fn reterminate(orig: path, new: path) -> path {
- let last = orig[str::len(orig) - 1u];
- if last == os_fs::path_sep as u8
- || last == os_fs::path_sep as u8 {
- ret new + path_sep();
- } else {
- ret new;
- }
- }
-}
-
-/*
-Function: homedir
-
-Returns the path to the user's home directory, if known.
-
-On Unix, returns the value of the "HOME" environment variable if it is set and
-not equal to the empty string.
-
-On Windows, returns the value of the "HOME" environment variable if it is set
-and not equal to the empty string. Otherwise, returns the value of the
-"USERPROFILE" environment variable if it is set and not equal to the empty
-string.
-
-Otherwise, homedir returns option::none.
-*/
-fn homedir() -> option<path> {
- ret alt generic_os::getenv("HOME") {
- some(p) {
- if !str::is_empty(p) {
- some(p)
- } else {
- secondary()
- }
- }
- none {
- secondary()
- }
- };
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn secondary() -> option<path> {
- none
- }
-
- #[cfg(target_os = "win32")]
- fn secondary() -> option<path> {
- option::maybe(none, generic_os::getenv("USERPROFILE")) {|p|
- if !str::is_empty(p) {
- some(p)
- } else {
- none
- }
- }
- }
-}
-
-/*
-Function: remove_file
-
-Deletes an existing file.
-*/
-fn remove_file(p: path) -> bool {
- ret unlink(p);
-
- #[cfg(target_os = "win32")]
- fn unlink(p: path) -> bool {
- ret str::as_buf(p, {|buf| os::kernel32::DeleteFileA(buf)});
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn unlink(_p: path) -> bool {
- ret str::as_buf(_p, {|buf| os::libc::unlink(buf) == 0i32 });
- }
-}
-
-#[cfg(test)]
-mod tests {
- #[test]
- fn test_connect() {
- let slash = fs::path_sep();
- log(error, fs::connect("a", "b"));
- assert (fs::connect("a", "b") == "a" + slash + "b");
- assert (fs::connect("a" + slash, "b") == "a" + slash + "b");
- }
-
- // Issue #712
- #[test]
- fn test_list_dir_no_invalid_memory_access() { fs::list_dir("."); }
-
- #[test]
- fn list_dir() {
- let dirs = fs::list_dir(".");
- // Just assuming that we've got some contents in the current directory
- assert (vec::len(dirs) > 0u);
-
- for dir in dirs { log(debug, dir); }
- }
-
- #[test]
- fn path_is_dir() {
- assert (fs::path_is_dir("."));
- assert (!fs::path_is_dir("test/stdtest/fs.rs"));
- }
-
- #[test]
- fn path_exists() {
- assert (fs::path_exists("."));
- assert (!fs::path_exists("test/nonexistent-bogus-path"));
- }
-
- fn ps() -> str {
- fs::path_sep()
- }
-
- fn aps() -> str {
- "/"
- }
-
- #[test]
- fn split1() {
- let actual = fs::split("a" + ps() + "b");
- let expected = ["a", "b"];
- assert actual == expected;
- }
-
- #[test]
- fn split2() {
- let actual = fs::split("a" + aps() + "b");
- let expected = ["a", "b"];
- assert actual == expected;
- }
-
- #[test]
- fn split3() {
- let actual = fs::split(ps() + "a" + ps() + "b");
- let expected = ["a", "b"];
- assert actual == expected;
- }
-
- #[test]
- fn split4() {
- let actual = fs::split("a" + ps() + "b" + aps() + "c");
- let expected = ["a", "b", "c"];
- assert actual == expected;
- }
-
- #[test]
- fn normalize1() {
- let actual = fs::normalize("a/b/..");
- let expected = "a";
- assert actual == expected;
- }
-
- #[test]
- fn normalize2() {
- let actual = fs::normalize("/a/b/..");
- let expected = "/a";
- assert actual == expected;
- }
-
- #[test]
- fn normalize3() {
- let actual = fs::normalize("a/../b");
- let expected = "b";
- assert actual == expected;
- }
-
- #[test]
- fn normalize4() {
- let actual = fs::normalize("/a/../b");
- let expected = "/b";
- assert actual == expected;
- }
-
- #[test]
- fn normalize5() {
- let actual = fs::normalize("a/.");
- let expected = "a";
- assert actual == expected;
- }
-
- #[test]
- fn normalize6() {
- let actual = fs::normalize("a/./b/");
- let expected = "a/b/";
- assert actual == expected;
- }
-
- #[test]
- fn normalize7() {
- let actual = fs::normalize("a/..");
- let expected = ".";
- assert actual == expected;
- }
-
- #[test]
- fn normalize8() {
- let actual = fs::normalize("../../..");
- let expected = "../../..";
- assert actual == expected;
- }
-
- #[test]
- fn normalize9() {
- let actual = fs::normalize("a/b/../../..");
- let expected = "..";
- assert actual == expected;
- }
-
- #[test]
- fn normalize10() {
- let actual = fs::normalize("/a/b/c/../d/./../../e/");
- let expected = "/a/e/";
- log(error, actual);
- assert actual == expected;
- }
-
- #[test]
- fn normalize11() {
- let actual = fs::normalize("/a/..");
- let expected = "/";
- assert actual == expected;
- }
-
- #[test]
- #[cfg(target_os = "win32")]
- fn normalize12() {
- let actual = fs::normalize("C:/whatever");
- let expected = "C:/whatever";
- log(error, actual);
- assert actual == expected;
- }
-
- #[test]
- #[cfg(target_os = "win32")]
- fn path_is_absolute_win32() {
- assert fs::path_is_absolute("C:/whatever");
- }
-
- #[test]
- fn splitext_empty() {
- let (base, ext) = fs::splitext("");
- assert base == "";
- assert ext == "";
- }
-
- #[test]
- fn splitext_ext() {
- let (base, ext) = fs::splitext("grum.exe");
- assert base == "grum";
- assert ext == ".exe";
- }
-
- #[test]
- fn splitext_noext() {
- let (base, ext) = fs::splitext("grum");
- assert base == "grum";
- assert ext == "";
- }
-
- #[test]
- fn splitext_dotfile() {
- let (base, ext) = fs::splitext(".grum");
- assert base == ".grum";
- assert ext == "";
- }
-
- #[test]
- fn splitext_path_ext() {
- let (base, ext) = fs::splitext("oh/grum.exe");
- assert base == "oh/grum";
- assert ext == ".exe";
- }
-
- #[test]
- fn splitext_path_noext() {
- let (base, ext) = fs::splitext("oh/grum");
- assert base == "oh/grum";
- assert ext == "";
- }
-
- #[test]
- fn splitext_dot_in_path() {
- let (base, ext) = fs::splitext("oh.my/grum");
- assert base == "oh.my/grum";
- assert ext == "";
- }
-
- #[test]
- fn splitext_nobasename() {
- let (base, ext) = fs::splitext("oh.my/");
- assert base == "oh.my/";
- assert ext == "";
- }
-
- #[test]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn homedir() {
- import getenv = generic_os::getenv;
- import setenv = generic_os::setenv;
-
- let oldhome = getenv("HOME");
-
- setenv("HOME", "/home/MountainView");
- assert fs::homedir() == some("/home/MountainView");
-
- setenv("HOME", "");
- assert fs::homedir() == none;
-
- option::may(oldhome, {|s| setenv("HOME", s)});
- }
-
- #[test]
- #[cfg(target_os = "win32")]
- fn homedir() {
- import getenv = generic_os::getenv;
- import setenv = generic_os::setenv;
-
- let oldhome = getenv("HOME");
- let olduserprofile = getenv("USERPROFILE");
-
- setenv("HOME", "");
- setenv("USERPROFILE", "");
-
- assert fs::homedir() == none;
-
- setenv("HOME", "/home/MountainView");
- assert fs::homedir() == some("/home/MountainView");
-
- setenv("HOME", "");
-
- setenv("USERPROFILE", "/home/MountainView");
- assert fs::homedir() == some("/home/MountainView");
-
- setenv("USERPROFILE", "/home/MountainView");
- assert fs::homedir() == some("/home/MountainView");
-
- setenv("HOME", "/home/MountainView");
- setenv("USERPROFILE", "/home/PaloAlto");
- assert fs::homedir() == some("/home/MountainView");
-
- option::may(oldhome, {|s| setenv("HOME", s)});
- option::may(olduserprofile, {|s| setenv("USERPROFILE", s)});
- }
-}
-
-
-#[test]
-fn test() {
- assert (!fs::path_is_absolute("test-path"));
-
- log(debug, "Current working directory: " + os::getcwd());
-
- log(debug, fs::make_absolute("test-path"));
- log(debug, fs::make_absolute("/usr/bin"));
-}
-
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-/*
-Module: generic_os
-
-Some miscellaneous platform functions.
-
-These should be rolled into another module.
-*/
-
-import core::option;
-
-// Wow, this is an ugly way to write doc comments
-
-#[cfg(bogus)]
-#[doc = "Get the value of an environment variable"]
-fn getenv(n: str) -> option<str> { }
-
-#[cfg(bogus)]
-#[doc = "Set the value of an environment variable"]
-fn setenv(n: str, v: str) { }
-
-fn env() -> [(str,str)] {
- let pairs = [];
- for p in os::rustrt::rust_env_pairs() {
- let vs = str::splitn_char(p, '=', 1u);
- assert vec::len(vs) == 2u;
- pairs += [(vs[0], vs[1])];
- }
- ret pairs;
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-fn getenv(n: str) -> option<str> unsafe {
- let s = str::as_buf(n, {|buf| os::libc::getenv(buf) });
- ret if unsafe::reinterpret_cast(s) == 0 {
- option::none::<str>
- } else {
- let s = unsafe::reinterpret_cast(s);
- option::some::<str>(str::from_cstr(s))
- };
-}
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "freebsd")]
-fn setenv(n: str, v: str) {
- // FIXME (868)
- str::as_buf(
- n,
- // FIXME (868)
- {|nbuf|
- str::as_buf(
- v,
- {|vbuf|
- os::libc::setenv(nbuf, vbuf, 1i32)})});
-}
-
-#[cfg(target_os = "win32")]
-fn getenv(n: str) -> option<str> {
- let nsize = 256u;
- loop {
- let v: [u8] = [];
- vec::reserve(v, nsize);
- let res =
- str::as_buf(n,
- {|nbuf|
- unsafe {
- let vbuf = vec::unsafe::to_ptr(v);
- os::kernel32::GetEnvironmentVariableA(nbuf, vbuf,
- nsize)
- }
- });
- if res == 0u {
- ret option::none;
- } else if res < nsize {
- unsafe {
- vec::unsafe::set_len(v, res);
- }
- ret option::some(str::from_bytes(v)); // UTF-8 or fail
- } else { nsize = res; }
- };
-}
-
-#[cfg(target_os = "win32")]
-fn setenv(n: str, v: str) {
- // FIXME (868)
- let _: () =
- str::as_buf(n, {|nbuf|
- let _: () =
- str::as_buf(v, {|vbuf|
- os::kernel32::SetEnvironmentVariableA(nbuf, vbuf);
- });
- });
-}
-
-
-#[cfg(test)]
-mod tests {
-
- fn make_rand_name() -> str {
- import rand;
- let rng: rand::rng = rand::mk_rng();
- let n = "TEST" + rng.gen_str(10u);
- assert option::is_none(getenv(n));
- n
- }
-
- #[test]
- #[ignore(reason = "fails periodically on mac")]
- fn test_setenv() {
- let n = make_rand_name();
- setenv(n, "VALUE");
- assert getenv(n) == option::some("VALUE");
- }
-
- #[test]
- #[ignore(reason = "fails periodically on mac")]
- fn test_setenv_overwrite() {
- let n = make_rand_name();
- setenv(n, "1");
- setenv(n, "2");
- assert getenv(n) == option::some("2");
- setenv(n, "");
- assert getenv(n) == option::some("");
- }
-
- // Windows GetEnvironmentVariable requires some extra work to make sure
- // the buffer the variable is copied into is the right size
- #[test]
- #[ignore(reason = "fails periodically on mac")]
- fn test_getenv_big() {
- let s = "";
- let i = 0;
- while i < 100 { s += "aaaaaaaaaa"; i += 1; }
- let n = make_rand_name();
- setenv(n, s);
- log(debug, s);
- assert getenv(n) == option::some(s);
- }
-
- #[test]
- fn test_get_exe_path() {
- let path = os::get_exe_path();
- assert option::is_some(path);
- let path = option::get(path);
- log(debug, path);
-
- // Hard to test this function
- if os::target_os() != "win32" {
- assert str::starts_with(path, fs::path_sep());
- } else {
- assert path[1] == ':' as u8;
- }
- }
-
- #[test]
- fn test_env_getenv() {
- let e = env();
- assert vec::len(e) > 0u;
- for (n, v) in e {
- log(debug, n);
- let v2 = getenv(n);
- // MingW seems to set some funky environment variables like
- // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
- // from env() but not visible from getenv().
- assert option::is_none(v2) || v2 == option::some(v);
- }
- }
-
- #[test]
- fn test_env_setenv() {
- let n = make_rand_name();
-
- let e = env();
- setenv(n, "VALUE");
- assert !vec::contains(e, (n, "VALUE"));
-
- e = env();
- assert vec::contains(e, (n, "VALUE"));
- }
-}
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-/*
-Module: io
-
-Basic input/output
-*/
-
-import core::ctypes::fd_t;
-import core::ctypes::c_int;
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_get_stdin() -> os::FILE;
- fn rust_get_stdout() -> os::FILE;
- fn rust_get_stderr() -> os::FILE;
-}
-
-// Reading
-
-// FIXME This is all buffered. We might need an unbuffered variant as well
-enum seek_style { seek_set, seek_end, seek_cur, }
-
-
-// The raw underlying reader iface. All readers must implement this.
-iface reader {
- // FIXME: Seekable really should be orthogonal.
- fn read_bytes(uint) -> [u8];
- fn read_byte() -> int;
- fn unread_byte(int);
- fn eof() -> bool;
- fn seek(int, seek_style);
- fn tell() -> uint;
-}
-
-// Generic utility functions defined on readers
-
-impl reader_util for reader {
- fn read_chars(n: uint) -> [char] {
- // returns the (consumed offset, n_req), appends characters to &chars
- fn chars_from_buf(buf: [u8], &chars: [char]) -> (uint, uint) {
- let i = 0u;
- while i < vec::len(buf) {
- let b0 = buf[i];
- let w = str::utf8_char_width(b0);
- let end = i + w;
- i += 1u;
- assert (w > 0u);
- if w == 1u {
- chars += [ b0 as char ];
- cont;
- }
- // can't satisfy this char with the existing data
- if end > vec::len(buf) {
- ret (i - 1u, end - vec::len(buf));
- }
- let val = 0u;
- while i < end {
- let next = buf[i] as int;
- i += 1u;
- assert (next > -1);
- assert (next & 192 == 128);
- val <<= 6u;
- val += (next & 63) as uint;
- }
- // See str::char_at
- val += ((b0 << ((w + 1u) as u8)) as uint)
- << (w - 1u) * 6u - w - 1u;
- chars += [ val as char ];
- }
- ret (i, 0u);
- }
- let buf: [u8] = [];
- let chars: [char] = [];
- // might need more bytes, but reading n will never over-read
- let nbread = n;
- while nbread > 0u {
- let data = self.read_bytes(nbread);
- if vec::len(data) == 0u {
- // eof - FIXME should we do something if
- // we're split in a unicode char?
- break;
- }
- buf += data;
- let (offset, nbreq) = chars_from_buf(buf, chars);
- let ncreq = n - vec::len(chars);
- // again we either know we need a certain number of bytes
- // to complete a character, or we make sure we don't
- // over-read by reading 1-byte per char needed
- nbread = if ncreq > nbreq { ncreq } else { nbreq };
- if nbread > 0u {
- buf = vec::slice(buf, offset, vec::len(buf));
- }
- }
- chars
- }
-
- fn read_char() -> char {
- let c = self.read_chars(1u);
- if vec::len(c) == 0u {
- ret -1 as char; // FIXME will this stay valid?
- }
- assert(vec::len(c) == 1u);
- ret c[0];
- }
-
- fn read_line() -> str {
- let buf: [u8] = [];
- loop {
- let ch = self.read_byte();
- if ch == -1 || ch == 10 { break; }
- buf += [ch as u8];
- }
- str::from_bytes(buf)
- }
-
- fn read_c_str() -> str {
- let buf: [u8] = [];
- loop {
- let ch = self.read_byte();
- if ch < 1 { break; } else { buf += [ch as u8]; }
- }
- str::from_bytes(buf)
- }
-
- // FIXME deal with eof?
- fn read_le_uint(size: uint) -> uint {
- let val = 0u, pos = 0u, i = size;
- while i > 0u {
- val += (self.read_byte() as uint) << pos;
- pos += 8u;
- i -= 1u;
- }
- val
- }
- fn read_le_int(size: uint) -> int {
- let val = 0u, pos = 0u, i = size;
- while i > 0u {
- val += (self.read_byte() as uint) << pos;
- pos += 8u;
- i -= 1u;
- }
- val as int
- }
- fn read_be_uint(size: uint) -> uint {
- let val = 0u, i = size;
- while i > 0u {
- i -= 1u;
- val += (self.read_byte() as uint) << i * 8u;
- }
- val
- }
-
- fn read_whole_stream() -> [u8] {
- let buf: [u8] = [];
- while !self.eof() { buf += self.read_bytes(2048u); }
- buf
- }
-}
-
-// Reader implementations
-
-fn convert_whence(whence: seek_style) -> i32 {
- ret alt whence {
- seek_set { 0i32 }
- seek_cur { 1i32 }
- seek_end { 2i32 }
- };
-}
-
-impl of reader for os::FILE {
- fn read_bytes(len: uint) -> [u8] unsafe {
- let buf = [];
- vec::reserve(buf, len);
- let read = os::libc::fread(vec::unsafe::to_ptr(buf), 1u, len, self);
- vec::unsafe::set_len(buf, read);
- ret buf;
- }
- fn read_byte() -> int { ret os::libc::fgetc(self) as int; }
- fn unread_byte(byte: int) { os::libc::ungetc(byte as i32, self); }
- fn eof() -> bool { ret os::libc::feof(self) != 0i32; }
- fn seek(offset: int, whence: seek_style) {
- assert os::libc::fseek(self, offset, convert_whence(whence)) == 0i32;
- }
- fn tell() -> uint { ret os::libc::ftell(self) as uint; }
-}
-
-// A forwarding impl of reader that also holds on to a resource for the
-// duration of its lifetime.
-// FIXME there really should be a better way to do this
-impl <T: reader, C> of reader for {base: T, cleanup: C} {
- fn read_bytes(len: uint) -> [u8] { self.base.read_bytes(len) }
- fn read_byte() -> int { self.base.read_byte() }
- fn unread_byte(byte: int) { self.base.unread_byte(byte); }
- fn eof() -> bool { self.base.eof() }
- fn seek(off: int, whence: seek_style) { self.base.seek(off, whence) }
- fn tell() -> uint { self.base.tell() }
-}
-
-resource FILE_res(f: os::FILE) { os::libc::fclose(f); }
-
-fn FILE_reader(f: os::FILE, cleanup: bool) -> reader {
- if cleanup {
- {base: f, cleanup: FILE_res(f)} as reader
- } else {
- f as reader
- }
-}
-
-// FIXME: this should either be an iface-less impl, a set of top-level
-// functions that take a reader, or a set of default methods on reader
-// (which can then be called reader)
-
-fn stdin() -> reader { rustrt::rust_get_stdin() as reader }
-
-fn file_reader(path: str) -> result::t<reader, str> {
- let f = str::as_buf(path, {|pathbuf|
- str::as_buf("r", {|modebuf|
- os::libc::fopen(pathbuf, modebuf)
- })
- });
- ret if f as uint == 0u { result::err("error opening " + path) }
- else {
- result::ok(FILE_reader(f, true))
- }
-}
-
-
-// Byte buffer readers
-
-// TODO: const u8, but this fails with rustboot.
-type byte_buf = {buf: [u8], mutable pos: uint, len: uint};
-
-impl of reader for byte_buf {
- fn read_bytes(len: uint) -> [u8] {
- let rest = self.len - self.pos;
- let to_read = len;
- if rest < to_read { to_read = rest; }
- let range = vec::slice(self.buf, self.pos, self.pos + to_read);
- self.pos += to_read;
- ret range;
- }
- fn read_byte() -> int {
- if self.pos == self.len { ret -1; }
- let b = self.buf[self.pos];
- self.pos += 1u;
- ret b as int;
- }
- fn unread_byte(_byte: int) { #error("TODO: unread_byte"); fail; }
- fn eof() -> bool { self.pos == self.len }
- fn seek(offset: int, whence: seek_style) {
- let pos = self.pos;
- self.pos = seek_in_buf(offset, pos, self.len, whence);
- }
- fn tell() -> uint { self.pos }
-}
-
-fn bytes_reader(bytes: [u8]) -> reader {
- bytes_reader_between(bytes, 0u, vec::len(bytes))
-}
-
-fn bytes_reader_between(bytes: [u8], start: uint, end: uint) -> reader {
- {buf: bytes, mutable pos: start, len: end} as reader
-}
-
-fn with_bytes_reader<t>(bytes: [u8], f: fn(reader) -> t) -> t {
- f(bytes_reader(bytes))
-}
-
-fn with_bytes_reader_between<t>(bytes: [u8], start: uint, end: uint,
- f: fn(reader) -> t) -> t {
- f(bytes_reader_between(bytes, start, end))
-}
-
-fn str_reader(s: str) -> reader {
- bytes_reader(str::bytes(s))
-}
-
-fn with_str_reader<T>(s: str, f: fn(reader) -> T) -> T {
- str::as_bytes(s) { |bytes|
- with_bytes_reader_between(bytes, 0u, str::len(s), f)
- }
-}
-
-// Writing
-enum fileflag { append, create, truncate, no_flag, }
-
-// FIXME: Seekable really should be orthogonal.
-// FIXME: eventually u64
-iface writer {
- fn write([const u8]);
- fn seek(int, seek_style);
- fn tell() -> uint;
- fn flush() -> int;
-}
-
-impl <T: writer, C> of writer for {base: T, cleanup: C} {
- fn write(bs: [const u8]) { self.base.write(bs); }
- fn seek(off: int, style: seek_style) { self.base.seek(off, style); }
- fn tell() -> uint { self.base.tell() }
- fn flush() -> int { self.base.flush() }
-}
-
-impl of writer for os::FILE {
- fn write(v: [const u8]) unsafe {
- let len = vec::len(v);
- let vbuf = vec::unsafe::to_ptr(v);
- let nout = os::libc::fwrite(vbuf, len, 1u, self);
- if nout < 1u { #error("error dumping buffer"); }
- }
- fn seek(offset: int, whence: seek_style) {
- assert os::libc::fseek(self, offset, convert_whence(whence)) == 0i32;
- }
- fn tell() -> uint { os::libc::ftell(self) as uint }
- fn flush() -> int { os::libc::fflush(self) as int }
-}
-
-fn FILE_writer(f: os::FILE, cleanup: bool) -> writer {
- if cleanup {
- {base: f, cleanup: FILE_res(f)} as writer
- } else {
- f as writer
- }
-}
-
-impl of writer for fd_t {
- fn write(v: [const u8]) unsafe {
- let len = vec::len(v);
- let count = 0u;
- let vbuf;
- while count < len {
- vbuf = ptr::offset(vec::unsafe::to_ptr(v), count);
- let nout = os::libc::write(self, vbuf, len);
- if nout < 0 {
- #error("error dumping buffer");
- log(error, sys::last_os_error());
- fail;
- }
- count += nout as uint;
- }
- }
- fn seek(_offset: int, _whence: seek_style) {
- #error("need 64-bit native calls for seek, sorry");
- fail;
- }
- fn tell() -> uint {
- #error("need 64-bit native calls for tell, sorry");
- fail;
- }
- fn flush() -> int { 0 }
-}
-
-resource fd_res(fd: fd_t) { os::libc::close(fd); }
-
-fn fd_writer(fd: fd_t, cleanup: bool) -> writer {
- if cleanup {
- {base: fd, cleanup: fd_res(fd)} as writer
- } else {
- fd as writer
- }
-}
-
-fn mk_file_writer(path: str, flags: [fileflag])
- -> result::t<writer, str> {
- let fflags: i32 =
- os::libc_constants::O_WRONLY | os::libc_constants::O_BINARY;
- for f: fileflag in flags {
- alt f {
- append { fflags |= os::libc_constants::O_APPEND; }
- create { fflags |= os::libc_constants::O_CREAT; }
- truncate { fflags |= os::libc_constants::O_TRUNC; }
- no_flag { }
- }
- }
- let fd = str::as_buf(path, {|pathbuf|
- os::libc::open(pathbuf, fflags, os::libc_constants::S_IRUSR |
- os::libc_constants::S_IWUSR)
- });
- if fd < 0i32 {
- // FIXME don't log this! put it in the returned error string
- log(error, sys::last_os_error());
- result::err("error opening " + path)
- } else {
- result::ok(fd_writer(fd, true))
- }
-}
-
-fn u64_to_le_bytes(n: u64, size: uint) -> [u8] {
- let bytes: [u8] = [], i = size, n = n;
- while i > 0u {
- bytes += [(n & 255_u64) as u8];
- n >>= 8_u64;
- i -= 1u;
- }
- ret bytes;
-}
-
-fn u64_to_be_bytes(n: u64, size: uint) -> [u8] {
- assert size <= 8u;
- let bytes: [u8] = [];
- let i = size;
- while i > 0u {
- let shift = ((i - 1u) * 8u) as u64;
- bytes += [(n >> shift) as u8];
- i -= 1u;
- }
- ret bytes;
-}
-
-fn u64_from_be_bytes(data: [u8], start: uint, size: uint) -> u64 {
- let sz = size;
- assert (sz <= 8u);
- let val = 0_u64;
- let pos = start;
- while sz > 0u {
- sz -= 1u;
- val += (data[pos] as u64) << ((sz * 8u) as u64);
- pos += 1u;
- }
- ret val;
-}
-
-impl writer_util for writer {
- fn write_char(ch: char) {
- if ch as uint < 128u {
- self.write([ch as u8]);
- } else {
- self.write(str::bytes(str::from_char(ch)));
- }
- }
- fn write_str(s: str) { self.write(str::bytes(s)); }
- fn write_line(s: str) { self.write(str::bytes(s + "\n")); }
- fn write_int(n: int) { self.write(str::bytes(int::to_str(n, 10u))); }
- fn write_uint(n: uint) { self.write(str::bytes(uint::to_str(n, 10u))); }
-
- fn write_le_uint(n: uint, size: uint) {
- self.write(u64_to_le_bytes(n as u64, size));
- }
- fn write_le_int(n: int, size: uint) {
- self.write(u64_to_le_bytes(n as u64, size));
- }
-
- fn write_be_uint(n: uint, size: uint) {
- self.write(u64_to_be_bytes(n as u64, size));
- }
- fn write_be_int(n: int, size: uint) {
- self.write(u64_to_be_bytes(n as u64, size));
- }
-
- fn write_be_u64(n: u64) { self.write(u64_to_be_bytes(n, 8u)); }
- fn write_be_u32(n: u32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
- fn write_be_u16(n: u16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
-
- fn write_be_i64(n: i64) { self.write(u64_to_be_bytes(n as u64, 8u)); }
- fn write_be_i32(n: i32) { self.write(u64_to_be_bytes(n as u64, 4u)); }
- fn write_be_i16(n: i16) { self.write(u64_to_be_bytes(n as u64, 2u)); }
-
- fn write_le_u64(n: u64) { self.write(u64_to_le_bytes(n, 8u)); }
- fn write_le_u32(n: u32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
- fn write_le_u16(n: u16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
-
- fn write_le_i64(n: i64) { self.write(u64_to_le_bytes(n as u64, 8u)); }
- fn write_le_i32(n: i32) { self.write(u64_to_le_bytes(n as u64, 4u)); }
- fn write_le_i16(n: i16) { self.write(u64_to_le_bytes(n as u64, 2u)); }
-
- fn write_u8(n: u8) { self.write([n]) }
-}
-
-fn file_writer(path: str, flags: [fileflag]) -> result::t<writer, str> {
- result::chain(mk_file_writer(path, flags), { |w| result::ok(w)})
-}
-
-
-// FIXME: fileflags
-fn buffered_file_writer(path: str) -> result::t<writer, str> {
- let f = str::as_buf(path, {|pathbuf|
- str::as_buf("w", {|modebuf| os::libc::fopen(pathbuf, modebuf) })
- });
- ret if f as uint == 0u { result::err("error opening " + path) }
- else { result::ok(FILE_writer(f, true)) }
-}
-
-// FIXME it would be great if this could be a const
-fn stdout() -> writer { fd_writer(1i32, false) }
-fn stderr() -> writer { fd_writer(2i32, false) }
-
-fn print(s: str) { stdout().write_str(s); }
-fn println(s: str) { stdout().write_line(s); }
-
-type mem_buffer = @{mutable buf: [mutable u8],
- mutable pos: uint};
-
-impl of writer for mem_buffer {
- fn write(v: [const u8]) {
- // Fast path.
- if self.pos == vec::len(self.buf) {
- for b: u8 in v { self.buf += [mutable b]; }
- self.pos += vec::len(v);
- ret;
- }
- // FIXME: Optimize: These should be unique pointers.
- let vlen = vec::len(v);
- let vpos = 0u;
- while vpos < vlen {
- let b = v[vpos];
- if self.pos == vec::len(self.buf) {
- self.buf += [mutable b];
- } else { self.buf[self.pos] = b; }
- self.pos += 1u;
- vpos += 1u;
- }
- }
- fn seek(offset: int, whence: seek_style) {
- let pos = self.pos;
- let len = vec::len(self.buf);
- self.pos = seek_in_buf(offset, pos, len, whence);
- }
- fn tell() -> uint { self.pos }
- fn flush() -> int { 0 }
-}
-
-fn mk_mem_buffer() -> mem_buffer {
- @{mutable buf: [mutable], mutable pos: 0u}
-}
-fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer }
-fn mem_buffer_buf(b: mem_buffer) -> [u8] { vec::from_mut(b.buf) }
-fn mem_buffer_str(b: mem_buffer) -> str {
- let b_ = vec::from_mut(b.buf);
- str::from_bytes(b_)
-}
-
-fn with_str_writer(f: fn(writer)) -> str {
- let buf = mk_mem_buffer();
- let wr = mem_buffer_writer(buf);
- f(wr);
- io::mem_buffer_str(buf)
-}
-
-fn with_buf_writer(f: fn(writer)) -> [u8] {
- let buf = mk_mem_buffer();
- let wr = mem_buffer_writer(buf);
- f(wr);
- io::mem_buffer_buf(buf)
-}
-
-// Utility functions
-fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
- uint {
- let bpos = pos as int;
- let blen = len as int;
- alt whence {
- seek_set { bpos = offset; }
- seek_cur { bpos += offset; }
- seek_end { bpos = blen + offset; }
- }
- if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
- ret bpos as uint;
-}
-
-fn read_whole_file_str(file: str) -> result::t<str, str> {
- result::chain(read_whole_file(file), { |bytes|
- result::ok(str::from_bytes(bytes))
- })
-}
-
-// FIXME implement this in a low-level way. Going through the abstractions is
-// pointless.
-fn read_whole_file(file: str) -> result::t<[u8], str> {
- result::chain(file_reader(file), { |rdr|
- result::ok(rdr.read_whole_stream())
- })
-}
-
-// fsync related
-
-mod fsync {
-
- enum level {
- // whatever fsync does on that platform
- fsync,
-
- // fdatasync on linux, similiar or more on other platforms
- fdatasync,
-
- // full fsync
- //
- // You must additionally sync the parent directory as well!
- fullfsync,
- }
-
-
- // Resource of artifacts that need to fsync on destruction
- resource res<t>(arg: arg<t>) {
- alt arg.opt_level {
- option::none { }
- option::some(level) {
- // fail hard if not succesful
- assert(arg.fsync_fn(arg.val, level) != -1);
- }
- }
- }
-
- type arg<t> = {
- val: t,
- opt_level: option<level>,
- fsync_fn: fn@(t, level) -> int
- };
-
- // fsync file after executing blk
- // FIXME find better way to create resources within lifetime of outer res
- fn FILE_res_sync(&&file: FILE_res, opt_level: option<level>,
- blk: fn(&&res<os::FILE>)) {
- blk(res({
- val: *file, opt_level: opt_level,
- fsync_fn: fn@(&&file: os::FILE, l: level) -> int {
- ret os::fsync_fd(os::libc::fileno(file), l) as int;
- }
- }));
- }
-
- // fsync fd after executing blk
- fn fd_res_sync(&&fd: fd_res, opt_level: option<level>,
- blk: fn(&&res<fd_t>)) {
- blk(res({
- val: *fd, opt_level: opt_level,
- fsync_fn: fn@(&&fd: fd_t, l: level) -> int {
- ret os::fsync_fd(fd, l) as int;
- }
- }));
- }
-
- // Type of objects that may want to fsync
- iface t { fn fsync(l: level) -> int; }
-
- // Call o.fsync after executing blk
- fn obj_sync(&&o: t, opt_level: option<level>, blk: fn(&&res<t>)) {
- blk(res({
- val: o, opt_level: opt_level,
- fsync_fn: fn@(&&o: t, l: level) -> int { ret o.fsync(l); }
- }));
- }
-}
-
-#[cfg(test)]
-mod tests {
-
- #[test]
- fn test_simple() {
- let tmpfile: str = "tmp/lib-io-test-simple.tmp";
- log(debug, tmpfile);
- let frood: str = "A hoopy frood who really knows where his towel is.";
- log(debug, frood);
- {
- let out: io::writer =
- result::get(
- io::file_writer(tmpfile, [io::create, io::truncate]));
- out.write_str(frood);
- }
- let inp: io::reader = result::get(io::file_reader(tmpfile));
- let frood2: str = inp.read_c_str();
- log(debug, frood2);
- assert (str::eq(frood, frood2));
- }
-
- #[test]
- fn test_readchars_empty() {
- let inp : io::reader = io::str_reader("");
- let res : [char] = inp.read_chars(128u);
- assert(vec::len(res) == 0u);
- }
-
- #[test]
- fn test_readchars_wide() {
- let wide_test = "生锈的汤匙切肉汤hello生锈的汤匙切肉汤";
- let ivals : [int] = [
- 29983, 38152, 30340, 27748,
- 21273, 20999, 32905, 27748,
- 104, 101, 108, 108, 111,
- 29983, 38152, 30340, 27748,
- 21273, 20999, 32905, 27748];
- fn check_read_ln(len : uint, s: str, ivals: [int]) {
- let inp : io::reader = io::str_reader(s);
- let res : [char] = inp.read_chars(len);
- if (len <= vec::len(ivals)) {
- assert(vec::len(res) == len);
- }
- assert(vec::slice(ivals, 0u, vec::len(res)) ==
- vec::map(res, {|x| x as int}));
- }
- let i = 0u;
- while i < 8u {
- check_read_ln(i, wide_test, ivals);
- i += 1u;
- }
- // check a long read for good measure
- check_read_ln(128u, wide_test, ivals);
- }
-
- #[test]
- fn test_readchar() {
- let inp : io::reader = io::str_reader("生");
- let res : char = inp.read_char();
- assert(res as int == 29983);
- }
-
- #[test]
- fn test_readchar_empty() {
- let inp : io::reader = io::str_reader("");
- let res : char = inp.read_char();
- assert(res as int == -1);
- }
-
- #[test]
- fn file_reader_not_exist() {
- alt io::file_reader("not a file") {
- result::err(e) {
- assert e == "error opening not a file";
- }
- result::ok(_) { fail; }
- }
- }
-
- #[test]
- fn file_writer_bad_name() {
- alt io::file_writer("?/?", []) {
- result::err(e) {
- assert e == "error opening ?/?";
- }
- result::ok(_) { fail; }
- }
- }
-
- #[test]
- fn buffered_file_writer_bad_name() {
- alt io::buffered_file_writer("?/?") {
- result::err(e) {
- assert e == "error opening ?/?";
- }
- result::ok(_) { fail; }
- }
- }
-}
-
-//
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-//
+++ /dev/null
-/*
-Module: os
-
-TODO: Restructure and document
-*/
-
-import core::option;
-import core::ctypes::*;
-
-export libc;
-export libc_constants;
-export pipe;
-export FILE, fd_FILE;
-export close;
-export fclose;
-export waitpid;
-export getcwd;
-export exec_suffix;
-export target_os;
-export dylib_filename;
-export get_exe_path;
-export fsync_fd;
-export rustrt;
-
-// FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult
-// by https://github.com/graydon/rust/issues#issue/268
-
-enum FILE_opaque {}
-type FILE = *FILE_opaque;
-enum dir {}
-enum dirent {}
-
-#[nolink]
-#[abi = "cdecl"]
-native mod libc {
- fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn fread(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn fwrite(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t;
- fn close(fd: fd_t) -> c_int;
- fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
- fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
- fn fclose(f: FILE);
- fn fflush(f: FILE) -> c_int;
- fn fsync(fd: fd_t) -> c_int;
- fn fdatasync(fd: fd_t) -> c_int;
- fn fileno(f: FILE) -> fd_t;
- fn fgetc(f: FILE) -> c_int;
- fn ungetc(c: c_int, f: FILE);
- fn feof(f: FILE) -> c_int;
- fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
- fn ftell(f: FILE) -> long;
- fn opendir(d: str::sbuf) -> *dir;
- fn closedir(d: *dir) -> c_int;
- fn readdir(d: *dir) -> *dirent;
- fn getenv(n: str::sbuf) -> str::sbuf;
- fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int;
- fn unsetenv(n: str::sbuf) -> c_int;
- fn pipe(buf: *mutable fd_t) -> c_int;
- fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> pid_t;
- fn readlink(path: str::sbuf, buf: str::sbuf, bufsize: size_t) -> ssize_t;
- fn mkdir(path: str::sbuf, mode: c_int) -> c_int;
- fn rmdir(path: str::sbuf) -> c_int;
- fn chdir(path: str::sbuf) -> c_int;
- fn unlink(path: str::sbuf) -> c_int;
-}
-
-mod libc_constants {
- const O_RDONLY: c_int = 0i32;
- const O_WRONLY: c_int = 1i32;
- const O_RDWR: c_int = 2i32;
- const O_APPEND: c_int = 1024i32;
- const O_CREAT: c_int = 64i32;
- const O_EXCL: c_int = 128i32;
- const O_TRUNC: c_int = 512i32;
- const O_TEXT: c_int = 0i32; // nonexistent in linux libc
- const O_BINARY: c_int = 0i32; // nonexistent in linux libc
-
- const S_IRUSR: unsigned = 256u32;
- const S_IWUSR: unsigned = 128u32;
-}
-
-fn pipe() -> {in: fd_t, out: fd_t} {
- let fds = {mutable in: 0i32, mutable out: 0i32};
- assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32);
- ret {in: fds.in, out: fds.out};
-}
-
-fn fd_FILE(fd: fd_t) -> FILE {
- ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
-}
-
-fn close(fd: fd_t) -> c_int {
- libc::close(fd)
-}
-
-fn fclose(file: FILE) {
- libc::fclose(file)
-}
-
-fn fsync_fd(fd: fd_t, level: io::fsync::level) -> c_int {
- alt level {
- io::fsync::fsync | io::fsync::fullfsync { ret libc::fsync(fd); }
- io::fsync::fdatasync { ret libc::fdatasync(fd); }
- }
-}
-
-fn waitpid(pid: pid_t) -> i32 {
- let status = 0i32;
- assert (os::libc::waitpid(pid, status, 0i32) != -1i32);
- ret status;
-}
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_env_pairs() -> [str];
- fn rust_getcwd() -> str;
-}
-
-fn getcwd() -> str { ret rustrt::rust_getcwd(); }
-
-fn exec_suffix() -> str { ret ""; }
-
-fn target_os() -> str { ret "linux"; }
-
-fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; }
-
-/// Returns the directory containing the running program
-/// followed by a path separator
-fn get_exe_path() -> option<fs::path> {
- let bufsize = 1023u;
- // FIXME: path "strings" will likely need fixing...
- let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
- ret str::as_buf("/proc/self/exe", { |proc_self_buf|
- str::as_buf(path, { |path_buf|
- if libc::readlink(proc_self_buf, path_buf, bufsize) != -1 {
- option::some(fs::dirname(path) + fs::path_sep())
- } else {
- option::none
- }
- })
- });
-}
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-import core::option;
-import core::ctypes::*;
-
-export libc;
-export libc_constants;
-export pipe;
-export FILE, fd_FILE;
-export close;
-export fclose;
-export waitpid;
-export getcwd;
-export exec_suffix;
-export target_os;
-export dylib_filename;
-export get_exe_path;
-export fsync_fd;
-export rustrt;
-
-// FIXME Refactor into unix_os module or some such. Doesn't
-// seem to work right now.
-
-enum FILE_opaque {}
-type FILE = *FILE_opaque;
-enum dir {}
-enum dirent {}
-
-#[nolink]
-#[abi = "cdecl"]
-native mod libc {
- fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn fread(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn fwrite(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> fd_t;
- fn close(fd: fd_t) -> c_int;
- fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
- fn fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
- fn fflush(f: FILE) -> c_int;
- fn fsync(fd: fd_t) -> c_int;
- fn fileno(f: FILE) -> fd_t;
- fn fclose(f: FILE);
- fn fgetc(f: FILE) -> c_int;
- fn ungetc(c: c_int, f: FILE);
- fn feof(f: FILE) -> c_int;
- fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
- fn ftell(f: FILE) -> long;
- fn opendir(d: str::sbuf) -> *dir;
- fn closedir(d: *dir) -> c_int;
- fn readdir(d: *dir) -> *dirent;
- fn getenv(n: str::sbuf) -> str::sbuf;
- fn setenv(n: str::sbuf, v: str::sbuf, overwrite: c_int) -> c_int;
- fn unsetenv(n: str::sbuf) -> c_int;
- fn pipe(buf: *mutable c_int) -> c_int;
- fn waitpid(pid: pid_t, &status: c_int, options: c_int) -> c_int;
- fn mkdir(s: str::sbuf, mode: c_int) -> c_int;
- fn rmdir(s: str::sbuf) -> c_int;
- fn chdir(s: str::sbuf) -> c_int;
- fn unlink(path: str::sbuf) -> c_int;
-
- // FIXME: Needs varags
- fn fcntl(fd: fd_t, cmd: c_int) -> c_int;
-}
-
-mod libc_constants {
- const O_RDONLY: c_int = 0i32;
- const O_WRONLY: c_int = 1i32;
- const O_RDWR: c_int = 2i32;
- const O_APPEND: c_int = 8i32;
- const O_CREAT: c_int = 512i32;
- const O_EXCL: c_int = 2048i32;
- const O_TRUNC: c_int = 1024i32;
- const O_TEXT: c_int = 0i32; // nonexistent in darwin libc
- const O_BINARY: c_int = 0i32; // nonexistent in darwin libc
-
- const S_IRUSR: unsigned = 256u32;
- const S_IWUSR: unsigned = 128u32;
-
- const F_FULLFSYNC: c_int = 51i32;
-}
-
-fn pipe() -> {in: fd_t, out: fd_t} {
- let fds = {mutable in: 0i32, mutable out: 0i32};
- assert (os::libc::pipe(ptr::mut_addr_of(fds.in)) == 0i32);
- ret {in: fds.in, out: fds.out};
-}
-
-fn fd_FILE(fd: fd_t) -> FILE {
- ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
-}
-
-fn close(fd: fd_t) -> c_int {
- libc::close(fd)
-}
-
-fn fclose(file: FILE) {
- libc::fclose(file)
-}
-
-fn waitpid(pid: pid_t) -> i32 {
- let status = 0i32;
- assert (os::libc::waitpid(pid, status, 0i32) != -1i32);
- ret status;
-}
-
-fn fsync_fd(fd: fd_t, level: io::fsync::level) -> c_int {
- alt level {
- io::fsync::fsync { ret libc::fsync(fd); }
- _ {
- // According to man fnctl, the ok retval is only specified to be !=-1
- if (libc::fcntl(libc_constants::F_FULLFSYNC, fd) == -1 as c_int)
- { ret -1 as c_int; }
- else
- { ret 0 as c_int; }
- }
- }
-}
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_env_pairs() -> [str];
- fn rust_getcwd() -> str;
-}
-
-fn getcwd() -> str { ret rustrt::rust_getcwd(); }
-
-#[nolink]
-#[abi = "cdecl"]
-native mod mac_libc {
- fn _NSGetExecutablePath(buf: str::sbuf,
- bufsize: *mutable uint32_t) -> c_int;
-}
-
-fn exec_suffix() -> str { ret ""; }
-
-fn target_os() -> str { ret "macos"; }
-
-fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; }
-
-fn get_exe_path() -> option<fs::path> {
- // FIXME: This doesn't handle the case where the buffer is too small
- // FIXME: path "strings" will likely need fixing...
- let bufsize = 1023u32;
- let path = str::from_bytes(vec::init_elt(bufsize as uint, 0u8));
- ret str::as_buf(path, { |path_buf|
- if mac_libc::_NSGetExecutablePath(path_buf,
- ptr::mut_addr_of(bufsize)) == 0i32 {
- option::some(fs::dirname(path) + fs::path_sep())
- } else {
- option::none
- }
- });
-}
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_list_files(path: str) -> [str];
-}
-
-fn list_dir(path: str) -> [str] {
- ret rustrt::rust_list_files(path);
-
- // FIXME: No idea why, but this appears to corrupt memory on OSX. I
- // suspect it has to do with the tasking primitives somehow, or perhaps
- // the FFI. Worth investigating more when we're digging into the FFI and
- // unsafe mode in more detail; in the meantime we just call list_files
- // above and skip this code.
-
- /*
- auto dir = os::libc::opendir(str::buf(path));
- assert (dir as uint != 0u);
- let vec<str> result = [];
- while (true) {
- auto ent = os::libc::readdir(dir);
- if (ent as int == 0) {
- os::libc::closedir(dir);
- ret result;
- }
- vec::push::<str>(result, rustrt::rust_dirent_filename(ent));
- }
- os::libc::closedir(dir);
- ret result;
- */
-
-}
-
-// FIXME make pure when str::char_at is
-fn path_is_absolute(p: str) -> bool { ret str::char_at(p, 0u) == '/'; }
-
-const path_sep: char = '/';
-
-const alt_path_sep: char = '/';
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-#[doc = "Random number generation"]
-
-enum rctx {}
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rand_new() -> *rctx;
- fn rand_next(c: *rctx) -> u32;
- fn rand_free(c: *rctx);
-}
-
-#[doc = "A random number generator"]
-iface rng {
- #[doc = "Return the next random integer"]
- fn next() -> u32;
-
- #[doc = "Return the next random float"]
- fn next_float() -> float;
-
- #[doc = "Return a random string composed of A-Z, a-z, 0-9."]
- fn gen_str(len: uint) -> str;
-
- #[doc = "Return a random byte string."]
- fn gen_bytes(len: uint) -> [u8];
-}
-
-resource rand_res(c: *rctx) { rustrt::rand_free(c); }
-
-#[doc = "Create a random number generator"]
-fn mk_rng() -> rng {
- impl of rng for @rand_res {
- fn next() -> u32 { ret rustrt::rand_next(**self); }
- fn next_float() -> float {
- let u1 = rustrt::rand_next(**self) as float;
- let u2 = rustrt::rand_next(**self) as float;
- let u3 = rustrt::rand_next(**self) as float;
- let scale = u32::max_value as float;
- ret ((u1 / scale + u2) / scale + u3) / scale;
- }
- fn gen_str(len: uint) -> str {
- let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
- "abcdefghijklmnopqrstuvwxyz" +
- "0123456789";
- let s = "";
- let i = 0u;
- while (i < len) {
- let n = rustrt::rand_next(**self) as uint %
- str::len(charset);
- s = s + str::from_char(str::char_at(charset, n));
- i += 1u;
- }
- s
- }
- fn gen_bytes(len: uint) -> [u8] {
- let v = [];
- let i = 0u;
- while i < len {
- let n = rustrt::rand_next(**self) as uint;
- v += [(n % (u8::max_value as uint)) as u8];
- i += 1u;
- }
- v
- }
- }
- @rand_res(rustrt::rand_new()) as rng
-}
-
-#[cfg(test)]
-mod tests {
-
- #[test]
- fn test() {
- let r1: rand::rng = rand::mk_rng();
- log(debug, r1.next());
- log(debug, r1.next());
- {
- let r2 = rand::mk_rng();
- log(debug, r1.next());
- log(debug, r2.next());
- log(debug, r1.next());
- log(debug, r1.next());
- log(debug, r2.next());
- log(debug, r2.next());
- log(debug, r1.next());
- log(debug, r1.next());
- log(debug, r1.next());
- log(debug, r2.next());
- log(debug, r2.next());
- log(debug, r2.next());
- }
- log(debug, r1.next());
- log(debug, r1.next());
- }
-
- #[test]
- fn genstr() {
- let r: rand::rng = rand::mk_rng();
- log(debug, r.gen_str(10u));
- log(debug, r.gen_str(10u));
- log(debug, r.gen_str(10u));
- assert(str::len(r.gen_str(10u)) == 10u);
- assert(str::len(r.gen_str(16u)) == 16u);
- }
-}
-
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-#[doc ="Process spawning"];
-import option::{some, none};
-import str::sbuf;
-import ctypes::{fd_t, pid_t, void};
-
-export program;
-export run_program;
-export start_program;
-export program_output;
-export spawn_process;
-export waitpid;
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_run_program(argv: *sbuf, envp: *void, dir: sbuf,
- in_fd: fd_t, out_fd: fd_t, err_fd: fd_t)
- -> pid_t;
-}
-
-#[doc ="A value representing a child process"]
-iface program {
- #[doc ="Returns the process id of the program"]
- fn get_id() -> pid_t;
-
- #[doc ="Returns an io::writer that can be used to write to stdin"]
- fn input() -> io::writer;
-
- #[doc ="Returns an io::reader that can be used to read from stdout"]
- fn output() -> io::reader;
-
- #[doc ="Returns an io::reader that can be used to read from stderr"]
- fn err() -> io::reader;
-
- #[doc = "Closes the handle to the child processes standard input"]
- fn close_input();
-
- #[doc = "
- Waits for the child process to terminate. Closes the handle
- to stdin if necessary.
- "]
- fn finish() -> int;
-
- #[doc ="Closes open handles"]
- fn destroy();
-}
-
-
-#[doc = "
-Run a program, providing stdin, stdout and stderr handles
-
-# Arguments
-
-* prog - The path to an executable
-* args - Vector of arguments to pass to the child process
-* env - optional env-modification for child
-* dir - optional dir to run child in (default current dir)
-* in_fd - A file descriptor for the child to use as std input
-* out_fd - A file descriptor for the child to use as std output
-* err_fd - A file descriptor for the child to use as std error
-
-# Return value
-
-The process id of the spawned process
-"]
-fn spawn_process(prog: str, args: [str],
- env: option<[(str,str)]>,
- dir: option<str>,
- in_fd: fd_t, out_fd: fd_t, err_fd: fd_t)
- -> pid_t unsafe {
- with_argv(prog, args) {|argv|
- with_envp(env) { |envp|
- with_dirp(dir) { |dirp|
- rustrt::rust_run_program(argv, envp, dirp,
- in_fd, out_fd, err_fd)
- }
- }
- }
-}
-
-fn with_argv<T>(prog: str, args: [str],
- cb: fn(*sbuf) -> T) -> T unsafe {
- let argptrs = str::as_buf(prog) {|b| [b] };
- let tmps = [];
- for arg in args {
- let t = @arg;
- tmps += [t];
- argptrs += str::as_buf(*t) {|b| [b] };
- }
- argptrs += [ptr::null()];
- vec::as_buf(argptrs, cb)
-}
-
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "freebsd")]
-fn with_envp<T>(env: option<[(str,str)]>,
- cb: fn(*void) -> T) -> T unsafe {
- // On posixy systems we can pass a char** for envp, which is
- // a null-terminated array of "k=v\n" strings.
- alt env {
- some (es) {
- let tmps = [];
- let ptrs = [];
-
- for (k,v) in es {
- let t = @(#fmt("%s=%s", k, v));
- vec::push(tmps, t);
- ptrs += str::as_buf(*t) {|b| [b]};
- }
- ptrs += [ptr::null()];
- vec::as_buf(ptrs) { |p| cb(::unsafe::reinterpret_cast(p)) }
- }
- none {
- cb(ptr::null())
- }
- }
-}
-
-#[cfg(target_os = "win32")]
-fn with_envp<T>(env: option<[(str,str)]>,
- cb: fn(*void) -> T) -> T unsafe {
- // On win32 we pass an "environment block" which is not a char**, but
- // rather a concatenation of null-terminated k=v\0 sequences, with a final
- // \0 to terminate.
- alt env {
- some (es) {
- let blk : [u8] = [];
- for (k,v) in es {
- let t = #fmt("%s=%s", k, v);
- let v : [u8] = ::unsafe::reinterpret_cast(t);
- blk += v;
- ::unsafe::leak(v);
- }
- blk += [0_u8];
- vec::as_buf(blk) {|p| cb(::unsafe::reinterpret_cast(p)) }
- }
- none {
- cb(ptr::null())
- }
- }
-}
-
-fn with_dirp<T>(d: option<str>,
- cb: fn(sbuf) -> T) -> T unsafe {
- alt d {
- some(dir) { str::as_buf(dir, cb) }
- none { cb(ptr::null()) }
- }
-}
-
-#[doc ="
-Spawns a process and waits for it to terminate
-
-# Arguments
-
-* prog - The path to an executable
-* args - Vector of arguments to pass to the child process
-
-# Return value
-
-The process id
-"]
-fn run_program(prog: str, args: [str]) -> int {
- ret waitpid(spawn_process(prog, args, none, none,
- 0i32, 0i32, 0i32));
-}
-
-#[doc ="
-Spawns a process and returns a program
-
-The returned value is a boxed resource containing a <program> object that can
-be used for sending and recieving data over the standard file descriptors.
-The resource will ensure that file descriptors are closed properly.
-
-# Arguments
-
-* prog - The path to an executable
-* args - Vector of arguments to pass to the child process
-
-# Return value
-
-A boxed resource of <program>
-"]
-fn start_program(prog: str, args: [str]) -> program {
- let pipe_input = os::pipe();
- let pipe_output = os::pipe();
- let pipe_err = os::pipe();
- let pid =
- spawn_process(prog, args, none, none,
- pipe_input.in, pipe_output.out,
- pipe_err.out);
-
- if pid == -1i32 { fail; }
- os::libc::close(pipe_input.in);
- os::libc::close(pipe_output.out);
- os::libc::close(pipe_err.out);
-
- type prog_repr = {pid: pid_t,
- mutable in_fd: fd_t,
- out_file: os::FILE,
- err_file: os::FILE,
- mutable finished: bool};
-
- fn close_repr_input(r: prog_repr) {
- let invalid_fd = -1i32;
- if r.in_fd != invalid_fd {
- os::libc::close(r.in_fd);
- r.in_fd = invalid_fd;
- }
- }
- fn finish_repr(r: prog_repr) -> int {
- if r.finished { ret 0; }
- r.finished = true;
- close_repr_input(r);
- ret waitpid(r.pid);
- }
- fn destroy_repr(r: prog_repr) {
- finish_repr(r);
- os::libc::fclose(r.out_file);
- os::libc::fclose(r.err_file);
- }
- resource prog_res(r: prog_repr) { destroy_repr(r); }
-
- impl of program for prog_res {
- fn get_id() -> pid_t { ret self.pid; }
- fn input() -> io::writer { io::fd_writer(self.in_fd, false) }
- fn output() -> io::reader { io::FILE_reader(self.out_file, false) }
- fn err() -> io::reader { io::FILE_reader(self.err_file, false) }
- fn close_input() { close_repr_input(*self); }
- fn finish() -> int { finish_repr(*self) }
- fn destroy() { destroy_repr(*self); }
- }
- let repr = {pid: pid,
- mutable in_fd: pipe_input.out,
- out_file: os::fd_FILE(pipe_output.in),
- err_file: os::fd_FILE(pipe_err.in),
- mutable finished: false};
- ret prog_res(repr) as program;
-}
-
-fn read_all(rd: io::reader) -> str {
- let buf = "";
- while !rd.eof() {
- let bytes = rd.read_bytes(4096u);
- buf += str::from_bytes(bytes);
- }
- ret buf;
-}
-
-#[doc ="
-Spawns a process, waits for it to exit, and returns the exit code, and
-contents of stdout and stderr.
-
-# Arguments
-
-* prog - The path to an executable
-* args - Vector of arguments to pass to the child process
-
-# Return value
-
-A record, {status: int, out: str, err: str} containing the exit code,
-the contents of stdout and the contents of stderr.
-"]
-fn program_output(prog: str, args: [str]) ->
- {status: int, out: str, err: str} {
- let pr = start_program(prog, args);
- pr.close_input();
- let out = read_all(pr.output());
- let err = read_all(pr.err());
- ret {status: pr.finish(), out: out, err: err};
-}
-
-#[doc ="Waits for a process to exit and returns the exit code"]
-fn waitpid(pid: pid_t) -> int {
- ret waitpid_os(pid);
-
- #[cfg(target_os = "win32")]
- fn waitpid_os(pid: pid_t) -> int {
- os::waitpid(pid) as int
- }
-
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn waitpid_os(pid: pid_t) -> int {
- #[cfg(target_os = "linux")]
- fn WIFEXITED(status: i32) -> bool {
- (status & 0xffi32) == 0i32
- }
-
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn WIFEXITED(status: i32) -> bool {
- (status & 0x7fi32) == 0i32
- }
-
- #[cfg(target_os = "linux")]
- fn WEXITSTATUS(status: i32) -> i32 {
- (status >> 8i32) & 0xffi32
- }
-
- #[cfg(target_os = "macos")]
- #[cfg(target_os = "freebsd")]
- fn WEXITSTATUS(status: i32) -> i32 {
- status >> 8i32
- }
-
- let status = os::waitpid(pid);
- ret if WIFEXITED(status) {
- WEXITSTATUS(status) as int
- } else {
- 1
- };
- }
-}
-
-#[cfg(test)]
-mod tests {
-
- import io::writer_util;
- import ctypes::fd_t;
-
- // Regression test for memory leaks
- #[ignore(cfg(target_os = "win32"))] // FIXME
- fn test_leaks() {
- run::run_program("echo", []);
- run::start_program("echo", []);
- run::program_output("echo", []);
- }
-
- #[test]
- fn test_pipes() {
- let pipe_in = os::pipe();
- let pipe_out = os::pipe();
- let pipe_err = os::pipe();
-
- let pid =
- run::spawn_process(
- "cat", [], none, none,
- pipe_in.in, pipe_out.out, pipe_err.out);
- os::close(pipe_in.in);
- os::close(pipe_out.out);
- os::close(pipe_err.out);
-
- if pid == -1i32 { fail; }
- let expected = "test";
- writeclose(pipe_in.out, expected);
- let actual = readclose(pipe_out.in);
- readclose(pipe_err.in);
- os::waitpid(pid);
-
- log(debug, expected);
- log(debug, actual);
- assert (expected == actual);
-
- fn writeclose(fd: fd_t, s: str) {
- #error("writeclose %d, %s", fd as int, s);
- let writer = io::fd_writer(fd, false);
- writer.write_str(s);
-
- os::close(fd);
- }
-
- fn readclose(fd: fd_t) -> str {
- // Copied from run::program_output
- let file = os::fd_FILE(fd);
- let reader = io::FILE_reader(file, false);
- let buf = "";
- while !reader.eof() {
- let bytes = reader.read_bytes(4096u);
- buf += str::from_bytes(bytes);
- }
- os::fclose(file);
- ret buf;
- }
- }
-
- #[test]
- fn waitpid() {
- let pid = run::spawn_process("false", [],
- none, none,
- 0i32, 0i32, 0i32);
- let status = run::waitpid(pid);
- assert status == 1;
- }
-
-}
-
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
#[comment = "The Rust standard library"];
#[license = "MIT"];
#[crate_type = "lib"];
-
#[doc = "The Rust standard library"];
-export fs, io, net, run, uv;
+export net, uv;
export c_vec, four, tri, util;
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
export rope;
export ebml, dbg, getopts, json, rand, sha1, term, time;
export test, tempfile, serialization;
-// FIXME: generic_os and os_fs shouldn't be exported
-export generic_os, os, os_fs;
// General io and system-services modules
-mod fs;
-mod io;
mod net;
-#[path = "run_program.rs"]
-mod run;
mod uv;
mod dbg;
mod getopts;
mod json;
-mod rand;
mod sha1;
mod md4;
mod tempfile;
mod test;
mod serialization;
-// Target-os module.
-
-// TODO: Have each os module re-export everything from genericos.
-mod generic_os;
-
-#[cfg(target_os = "win32")]
-#[path = "win32_os.rs"]
-mod os;
-#[cfg(target_os = "win32")]
-#[path = "win32_fs.rs"]
-mod os_fs;
-
-#[cfg(target_os = "macos")]
-#[path = "macos_os.rs"]
-mod os;
-#[cfg(target_os = "macos")]
-#[path = "posix_fs.rs"]
-mod os_fs;
-
-#[cfg(target_os = "linux")]
-#[path = "linux_os.rs"]
-mod os;
-#[cfg(target_os = "linux")]
-#[path = "posix_fs.rs"]
-mod os_fs;
-
-#[cfg(target_os = "freebsd")]
-#[path = "freebsd_os.rs"]
-mod os;
-#[cfg(target_os = "freebsd")]
-#[path = "posix_fs.rs"]
-mod os_fs;
-
// Local Variables:
// mode: rust;
// fill-column: 78;
#[doc = "Temporary files and directories"];
import core::option;
-import fs;
import option::{none, some};
import rand;
let i = 0u;
while (i < 1000u) {
let s = prefix + r.gen_str(16u) + suffix;
- if fs::make_dir(s, 0x1c0i32) { // FIXME: u+rwx
+ if os::make_dir(s, 0x1c0i32) { // FIXME: u+rwx
ret some(s);
}
i += 1u;
let r = mkdtemp("./", "foobar");
alt r {
some(p) {
- fs::remove_dir(p);
+ os::remove_dir(p);
assert(str::ends_with(p, "foobar"));
}
_ { assert(false); }
fn color_supported() -> bool {
let supported_terms = ["xterm-color", "xterm",
"screen-bce", "xterm-256color"];
- ret alt generic_os::getenv("TERM") {
+ ret alt os::getenv("TERM") {
option::some(env) {
for term: str in supported_terms {
if str::eq(term, env) { ret true; }
import result::{ok, err};
import io::writer_util;
-import core::ctypes;
export test_name;
export test_fn;
#[abi = "cdecl"]
native mod rustrt {
- fn sched_threads() -> ctypes::size_t;
+ fn sched_threads() -> libc::size_t;
}
// The name of a test. By convention this follows the rules for rust
// process_operation() crust fn below
enum uv_operation {
op_async_init([u8]),
- op_close(uv_handle, *ctypes::void),
+ op_close(uv_handle, *libc::c_void),
op_timer_init([u8]),
- op_timer_start([u8], *ctypes::void, u32, u32),
- op_timer_stop([u8], *ctypes::void, fn~(uv_handle)),
- op_teardown(*ctypes::void)
+ op_timer_start([u8], *libc::c_void, u32, u32),
+ op_timer_stop([u8], *libc::c_void, fn~(uv_handle)),
+ op_teardown(*libc::c_void)
}
enum uv_handle {
msg_timer_stop([u8], fn~(uv_handle)),
// dispatches from libuv
- uv_async_init([u8], *ctypes::void),
+ uv_async_init([u8], *libc::c_void),
uv_async_send([u8]),
uv_close([u8]),
- uv_timer_init([u8], *ctypes::void),
+ uv_timer_init([u8], *libc::c_void),
uv_timer_call([u8]),
uv_timer_stop([u8], fn~(uv_handle)),
uv_end(),
};
enum uv_loop {
- uv_loop_new(comm::chan<uv_msg>, *ctypes::void)
+ uv_loop_new(comm::chan<uv_msg>, *libc::c_void)
}
#[nolink]
native mod rustrt {
- fn rust_uv_loop_new() -> *ctypes::void;
- fn rust_uv_loop_delete(lp: *ctypes::void);
+ fn rust_uv_loop_new() -> *libc::c_void;
+ fn rust_uv_loop_delete(lp: *libc::c_void);
fn rust_uv_loop_set_data(
- lp: *ctypes::void,
+ lp: *libc::c_void,
data: *uv_loop_data);
- fn rust_uv_bind_op_cb(lp: *ctypes::void, cb: *u8)
- -> *ctypes::void;
- fn rust_uv_stop_op_cb(handle: *ctypes::void);
- fn rust_uv_run(loop_handle: *ctypes::void);
- fn rust_uv_close(handle: *ctypes::void, cb: *u8);
- fn rust_uv_close_async(handle: *ctypes::void);
- fn rust_uv_close_timer(handle: *ctypes::void);
- fn rust_uv_async_send(handle: *ctypes::void);
+ fn rust_uv_bind_op_cb(lp: *libc::c_void, cb: *u8)
+ -> *libc::c_void;
+ fn rust_uv_stop_op_cb(handle: *libc::c_void);
+ fn rust_uv_run(loop_handle: *libc::c_void);
+ fn rust_uv_close(handle: *libc::c_void, cb: *u8);
+ fn rust_uv_close_async(handle: *libc::c_void);
+ fn rust_uv_close_timer(handle: *libc::c_void);
+ fn rust_uv_async_send(handle: *libc::c_void);
fn rust_uv_async_init(
- loop_handle: *ctypes::void,
+ loop_handle: *libc::c_void,
cb: *u8,
- id: *u8) -> *ctypes::void;
+ id: *u8) -> *libc::c_void;
fn rust_uv_timer_init(
- loop_handle: *ctypes::void,
+ loop_handle: *libc::c_void,
cb: *u8,
- id: *u8) -> *ctypes::void;
+ id: *u8) -> *libc::c_void;
fn rust_uv_timer_start(
- timer_handle: *ctypes::void,
- timeout: ctypes::c_uint,
- repeat: ctypes::c_uint);
- fn rust_uv_timer_stop(handle: *ctypes::void);
+ timer_handle: *libc::c_void,
+ timeout: libc::c_uint,
+ repeat: libc::c_uint);
+ fn rust_uv_timer_stop(handle: *libc::c_void);
}
// public functions
process_operation);
// all state goes here
- let handles: map::hashmap<[u8], *ctypes::void> =
+ let handles: map::hashmap<[u8], *libc::c_void> =
map::new_bytes_hash();
let id_to_handle: map::hashmap<[u8], uv_handle> =
map::new_bytes_hash();
// internal functions
fn pass_to_libuv(
- op_handle: *ctypes::void,
+ op_handle: *libc::c_void,
operation_chan: comm::chan<uv_operation>,
op: uv_operation) unsafe {
comm::send(operation_chan, copy(op));
do_send(op_handle);
}
-fn do_send(h: *ctypes::void) {
+fn do_send(h: *libc::c_void) {
rustrt::rust_uv_async_send(h);
}
fn gen_handle_id() -> [u8] {
}
}
-fn get_loop_ptr_from_uv_loop(lp: uv_loop) -> *ctypes::void {
+fn get_loop_ptr_from_uv_loop(lp: uv_loop) -> *libc::c_void {
alt lp {
uv_loop_new(loop_chan, loop_ptr) {
ret loop_ptr;
// crust
crust fn process_operation(
- lp: *ctypes::void,
+ lp: *libc::c_void,
data: *uv_loop_data) unsafe {
let op_port = (*data).operation_port;
let loop_chan = get_loop_chan_from_data(data);
}
}
-fn handle_op_close(handle: uv_handle, handle_ptr: *ctypes::void) {
+fn handle_op_close(handle: uv_handle, handle_ptr: *libc::c_void) {
// it's just like im doing C
alt handle {
uv_async(id, lp) {
crust fn process_close_async(
id_buf: *u8,
- handle_ptr: *ctypes::void,
+ handle_ptr: *libc::c_void,
data: *uv_loop_data)
unsafe {
let id = get_handle_id_from(id_buf);
crust fn process_close_timer(
id_buf: *u8,
- handle_ptr: *ctypes::void,
+ handle_ptr: *libc::c_void,
data: *uv_loop_data)
unsafe {
let id = get_handle_id_from(id_buf);
+++ /dev/null
-
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_list_files(path: str) -> [str];
-}
-
-fn list_dir(path: str) -> [str] {
- let path = path + "*";
- ret rustrt::rust_list_files(path);
-}
-
-fn path_is_absolute(p: str) -> bool {
- ret str::char_at(p, 0u) == '/' ||
- str::char_at(p, 1u) == ':'
- && (str::char_at(p, 2u) == path_sep
- || str::char_at(p, 2u) == alt_path_sep);
-}
-
-/* FIXME: win32 path handling actually accepts '/' or '\' and has subtly
- * different semantics for each. Since we build on mingw, we are usually
- * dealing with /-separated paths. But the whole interface to splitting and
- * joining pathnames needs a bit more abstraction on win32. Possibly a vec or
- * enum type.
- */
-const path_sep: char = '/';
-
-const alt_path_sep: char = '\\';
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
+++ /dev/null
-import core::option;
-import core::ctypes::*;
-
-enum FILE_opaque {}
-type FILE = *FILE_opaque;
-
-#[abi = "cdecl"]
-#[nolink]
-native mod libc {
- fn read(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn write(fd: fd_t, buf: *u8, count: size_t) -> ssize_t;
- fn fread(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- fn fwrite(buf: *u8, size: size_t, n: size_t, f: FILE) -> size_t;
- #[link_name = "_open"]
- fn open(s: str::sbuf, flags: c_int, mode: unsigned) -> c_int;
- #[link_name = "_close"]
- fn close(fd: fd_t) -> c_int;
- fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE;
- fn _fdopen(fd: fd_t, mode: str::sbuf) -> FILE;
- fn fclose(f: FILE);
- fn fflush(f: FILE) -> c_int;
- fn fileno(f: FILE) -> fd_t;
- fn fgetc(f: FILE) -> c_int;
- fn ungetc(c: c_int, f: FILE);
- fn feof(f: FILE) -> c_int;
- fn fseek(f: FILE, offset: long, whence: c_int) -> c_int;
- fn ftell(f: FILE) -> long;
- fn _pipe(fds: *mutable fd_t, size: unsigned, mode: c_int) -> c_int;
-}
-
-mod libc_constants {
- const O_RDONLY: c_int = 0i32;
- const O_WRONLY: c_int = 1i32;
- const O_RDWR: c_int = 2i32;
- const O_APPEND: c_int = 8i32;
- const O_CREAT: c_int = 256i32;
- const O_EXCL: c_int = 1024i32;
- const O_TRUNC: c_int = 512i32;
- const O_TEXT: c_int = 16384i32;
- const O_BINARY: c_int = 32768i32;
- const O_NOINHERIT: c_int = 128i32;
- const S_IRUSR: unsigned = 256u32; // really _S_IREAD in win32
- const S_IWUSR: unsigned = 128u32; // really _S_IWRITE in win32
-}
-
-type DWORD = u32;
-type HMODULE = c_uint;
-type LPTSTR = str::sbuf;
-type LPCTSTR = str::sbuf;
-
-type LPSECURITY_ATTRIBUTES = *ctypes::void;
-
-#[abi = "stdcall"]
-native mod kernel32 {
- fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf, nsize: c_uint) ->
- c_uint;
- fn SetEnvironmentVariableA(n: str::sbuf, v: str::sbuf) -> c_int;
- fn GetModuleFileNameA(hModule: HMODULE,
- lpFilename: LPTSTR,
- nSize: DWORD) -> DWORD;
- fn CreateDirectoryA(lpPathName: LPCTSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES) -> bool;
- fn RemoveDirectoryA(lpPathName: LPCTSTR) -> bool;
- fn SetCurrentDirectoryA(lpPathName: LPCTSTR) -> bool;
- fn DeleteFileA(lpFileName: LPCTSTR) -> bool;
-}
-
-// FIXME turn into constants
-fn exec_suffix() -> str { ret ".exe"; }
-fn target_os() -> str { ret "win32"; }
-
-fn dylib_filename(base: str) -> str { ret base + ".dll"; }
-
-fn pipe() -> {in: fd_t, out: fd_t} {
- // Windows pipes work subtly differently than unix pipes, and their
- // inheritance has to be handled in a different way that I don't fully
- // understand. Here we explicitly make the pipe non-inheritable,
- // which means to pass it to a subprocess they need to be duplicated
- // first, as in rust_run_program.
- let fds = {mutable in: 0i32, mutable out: 0i32};
- let res =
- os::libc::_pipe(ptr::mut_addr_of(fds.in), 1024u32,
- libc_constants::O_BINARY |
- libc_constants::O_NOINHERIT);
- assert (res == 0i32);
- assert (fds.in != -1i32 && fds.in != 0i32);
- assert (fds.out != -1i32 && fds.in != 0i32);
- ret {in: fds.in, out: fds.out};
-}
-
-fn fd_FILE(fd: fd_t) -> FILE {
- ret str::as_buf("r", {|modebuf| libc::_fdopen(fd, modebuf) });
-}
-
-fn close(fd: fd_t) -> c_int {
- libc::close(fd)
-}
-
-fn fclose(file: FILE) {
- libc::fclose(file)
-}
-
-fn fsync_fd(_fd: fd_t, _level: io::fsync::level) -> c_int {
- // FIXME (1253)
- fail;
-}
-
-#[abi = "cdecl"]
-native mod rustrt {
- fn rust_env_pairs() -> [str];
- fn rust_process_wait(handle: c_int) -> c_int;
- fn rust_getcwd() -> str;
-}
-
-fn waitpid(pid: pid_t) -> i32 { ret rustrt::rust_process_wait(pid); }
-
-fn getcwd() -> str { ret rustrt::rust_getcwd(); }
-
-fn get_exe_path() -> option<fs::path> {
- // FIXME: This doesn't handle the case where the buffer is too small
- // FIXME: path "strings" will likely need fixing...
- let bufsize = 1023u;
- let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
- ret str::as_buf(path, { |path_buf|
- if kernel32::GetModuleFileNameA(0u, path_buf,
- bufsize as u32) != 0u32 {
- option::some(fs::dirname(path) + fs::path_sep())
- } else {
- option::none
- }
- });
-}
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-import ctypes::{c_int, c_uint};
+import libc::{c_int, c_uint};
import driver::session;
import session::session;
import lib::llvm::llvm;
import middle::ty;
import metadata::{encoder, cstore};
import middle::trans::common::crate_ctxt;
-import std::fs;
import std::map::hashmap;
-import std::run;
import std::sha1::sha1;
import syntax::ast;
import syntax::print::pprust;
none {
let name =
{
- let os = str::split_char(fs::basename(output), '.');
+ let os = str::split_char(path::basename(output), '.');
if (vec::len(os) < 2u) {
sess.fatal(#fmt("output file name %s doesn't\
appear to have an extension", output));
let output = if sess.building_library {
let long_libname =
- std::os::dylib_filename(#fmt("%s-%s-%s",
- lm.name, lm.extras_hash, lm.vers));
+ os::dll_filename(#fmt("%s-%s-%s",
+ lm.name, lm.extras_hash, lm.vers));
#debug("link_meta.name: %s", lm.name);
#debug("long_libname: %s", long_libname);
#debug("out_filename: %s", out_filename);
- #debug("dirname(out_filename): %s", fs::dirname(out_filename));
+ #debug("dirname(out_filename): %s", path::dirname(out_filename));
- fs::connect(fs::dirname(out_filename), long_libname)
+ path::connect(path::dirname(out_filename), long_libname)
} else { out_filename };
log(debug, "output: " + output);
cont;
}
let cratepath = cratepath;
- let dir = fs::dirname(cratepath);
+ let dir = path::dirname(cratepath);
if dir != "" { cc_args += ["-L" + dir]; }
- let libarg = unlib(sess.targ_cfg, fs::basename(cratepath));
+ let libarg = unlib(sess.targ_cfg, path::basename(cratepath));
cc_args += ["-l" + libarg];
}
// be rpathed
if sess.targ_cfg.os == session::os_macos {
cc_args += ["-Wl,-install_name,@rpath/"
- + fs::basename(output)];
+ + path::basename(output)];
}
} else {
// FIXME: why do we hardcode -lm?
-import std::{os, fs, os_fs, map};
+import std::map;
import std::map::hashmap;
import metadata::cstore;
import driver::session;
rpaths_to_flags(rpaths)
}
-fn get_sysroot_absolute_rt_lib(sess: session::session) -> fs::path {
+fn get_sysroot_absolute_rt_lib(sess: session::session) -> path::path {
let path = [sess.filesearch.sysroot()]
+ filesearch::relative_target_lib_path(
sess.opts.target_triple)
- + [os::dylib_filename("rustrt")];
- fs::connect_many(path)
+ + [os::dll_filename("rustrt")];
+ path::connect_many(path)
}
fn rpaths_to_flags(rpaths: [str]) -> [str] {
vec::map(rpaths, { |rpath| #fmt("-Wl,-rpath,%s",rpath)})
}
-fn get_rpaths(os: session::os, cwd: fs::path, sysroot: fs::path,
- output: fs::path, libs: [fs::path],
+fn get_rpaths(os: session::os, cwd: path::path, sysroot: path::path,
+ output: path::path, libs: [path::path],
target_triple: str) -> [str] {
#debug("cwd: %s", cwd);
#debug("sysroot: %s", sysroot);
}
fn get_rpaths_relative_to_output(os: session::os,
- cwd: fs::path,
- output: fs::path,
- libs: [fs::path]) -> [str] {
+ cwd: path::path,
+ output: path::path,
+ libs: [path::path]) -> [str] {
vec::map(libs, bind get_rpath_relative_to_output(os, cwd, output, _))
}
fn get_rpath_relative_to_output(os: session::os,
- cwd: fs::path,
- output: fs::path,
- &&lib: fs::path) : not_win32(os) -> str {
+ cwd: path::path,
+ output: path::path,
+ &&lib: path::path) : not_win32(os) -> str {
// Mac doesn't appear to support $ORIGIN
let prefix = alt os {
- session::os_linux { "$ORIGIN" + fs::path_sep() }
- session::os_freebsd { "$ORIGIN" + fs::path_sep() }
- session::os_macos { "@executable_path" + fs::path_sep() }
+ session::os_linux { "$ORIGIN" + path::path_sep() }
+ session::os_freebsd { "$ORIGIN" + path::path_sep() }
+ session::os_macos { "@executable_path" + path::path_sep() }
session::os_win32 { core::unreachable(); }
};
}
// Find the relative path from one file to another
-fn get_relative_to(abs1: fs::path, abs2: fs::path) -> fs::path {
- assert fs::path_is_absolute(abs1);
- assert fs::path_is_absolute(abs2);
+fn get_relative_to(abs1: path::path, abs2: path::path) -> path::path {
+ assert path::path_is_absolute(abs1);
+ assert path::path_is_absolute(abs2);
#debug("finding relative path from %s to %s",
abs1, abs2);
- let normal1 = fs::normalize(abs1);
- let normal2 = fs::normalize(abs2);
- let split1 = str::split_char(normal1, os_fs::path_sep);
- let split2 = str::split_char(normal2, os_fs::path_sep);
+ let normal1 = path::normalize(abs1);
+ let normal2 = path::normalize(abs2);
+ let split1 = path::split(normal1);
+ let split2 = path::split(normal2);
let len1 = vec::len(split1);
let len2 = vec::len(split2);
assert len1 > 0u;
path += vec::slice(split2, start_idx, len2 - 1u);
if check vec::is_not_empty(path) {
- ret fs::connect_many(path);
+ ret path::connect_many(path);
} else {
ret ".";
}
}
-fn get_absolute_rpaths(cwd: fs::path, libs: [fs::path]) -> [str] {
+fn get_absolute_rpaths(cwd: path::path, libs: [path::path]) -> [str] {
vec::map(libs, bind get_absolute_rpath(cwd, _))
}
-fn get_absolute_rpath(cwd: fs::path, &&lib: fs::path) -> str {
- fs::dirname(get_absolute(cwd, lib))
+fn get_absolute_rpath(cwd: path::path, &&lib: path::path) -> str {
+ path::dirname(get_absolute(cwd, lib))
}
-fn get_absolute(cwd: fs::path, lib: fs::path) -> fs::path {
- if fs::path_is_absolute(lib) {
+fn get_absolute(cwd: path::path, lib: path::path) -> path::path {
+ if path::path_is_absolute(lib) {
lib
} else {
- fs::connect(cwd, lib)
+ path::connect(cwd, lib)
}
}
-fn get_install_prefix_rpath(cwd: fs::path, target_triple: str) -> str {
+fn get_install_prefix_rpath(cwd: path::path, target_triple: str) -> str {
let install_prefix = #env("CFG_PREFIX");
if install_prefix == "" {
let path = [install_prefix]
+ filesearch::relative_target_lib_path(target_triple);
- get_absolute(cwd, fs::connect_many(path))
+ get_absolute(cwd, path::connect_many(path))
}
fn minimize_rpaths(rpaths: [str]) -> [str] {
#[test]
fn test_prefix_rpath() {
let res = get_install_prefix_rpath("/usr/lib", "triple");
- let d = fs::connect(#env("CFG_PREFIX"), "/lib/rustc/triple/lib");
+ let d = path::connect(#env("CFG_PREFIX"), "/lib/rustc/triple/lib");
assert str::ends_with(res, d);
}
#[test]
fn test_prefix_rpath_abs() {
let res = get_install_prefix_rpath("/usr/lib", "triple");
- assert fs::path_is_absolute(res);
+ assert path::path_is_absolute(res);
}
#[test]
-import std::{io, term};
+import std::term;
import io::writer_util;
import syntax::codemap;
import codemap::span;
-
// -*- rust -*-
import metadata::{creader, cstore};
import session::session;
import util::{ppaux, filesearch};
import back::link;
import result::{ok, err};
-import std::{fs, io, getopts};
+import std::getopts;
import io::{reader_util, writer_util};
import getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
import back::{x86, x86_64};
};
ret [ // Target bindings.
- mk("target_os", std::os::target_os()),
+ mk("target_os", os::sysname()),
mk("target_arch", arch),
mk("target_libc", libc),
// Build bindings.
span_diagnostic: span_diagnostic_handler,
filesearch: filesearch,
mutable building_library: false,
- working_dir: fs::dirname(input)}
+ working_dir: path::dirname(input)}
}
fn parse_pretty(sess: session, &&name: str) -> pp_mode {
some(d) { d }
none {
if input_is_stdin(ifile) {
- std::os::getcwd()
+ os::getcwd()
} else {
- fs::dirname(ifile)
+ path::dirname(ifile)
}
}
};
let base_filename = if !input_is_stdin(ifile) {
- let (path, _) = fs::splitext(ifile);
- fs::basename(path)
+ let (path, _) = path::splitext(ifile);
+ path::basename(path)
} else {
"rust_out"
};
- let base_path = fs::connect(dirname, base_filename);
+ let base_path = path::connect(dirname, base_filename);
if sess.building_library {
- let basename = fs::basename(base_path);
- let dylibname = std::os::dylib_filename(basename);
- out_path = fs::connect(dirname, dylibname);
- obj_path = fs::connect(dirname, basename + "." + obj_suffix);
+ let basename = path::basename(base_path);
+ let dylibname = os::dll_filename(basename);
+ out_path = path::connect(dirname, dylibname);
+ obj_path = path::connect(dirname, basename + "." + obj_suffix);
} else {
out_path = base_path;
obj_path = base_path + "." + obj_suffix;
obj_path = if stop_after_codegen {
out_file
} else {
- let (base, _) = fs::splitext(out_file);
+ let (base, _) = path::splitext(out_file);
let modified = base + "." + obj_suffix;
modified
};
// -*- rust -*-
import result::{ok, err};
-import std::{io, getopts};
+import std::getopts;
import io::writer_util;
import getopts::{opt_present};
import rustc::driver::driver::*;
import str::sbuf;
import std::map::hashmap;
-import ctypes::{c_int, c_uint, unsigned, longlong, ulonglong};
+import libc::{c_int, c_uint, c_longlong, c_ulonglong};
type Opcode = u32;
-type Bool = unsigned;
-const True: Bool = 1u32;
+type Bool = c_uint;
+const True: Bool = 1u32; // FIXME: should be '1 as Bool'
const False: Bool = 0u32;
// Consts for the LLVM CallConv type, pre-cast to uint.
fn LLVMContextCreate() -> ContextRef;
fn LLVMGetGlobalContext() -> ContextRef;
fn LLVMContextDispose(C: ContextRef);
- fn LLVMGetMDKindIDInContext(C: ContextRef, Name: sbuf, SLen: unsigned) ->
- unsigned;
- fn LLVMGetMDKindID(Name: sbuf, SLen: unsigned) -> unsigned;
+ fn LLVMGetMDKindIDInContext(C: ContextRef, Name: sbuf, SLen: c_uint) ->
+ c_uint;
+ fn LLVMGetMDKindID(Name: sbuf, SLen: c_uint) -> c_uint;
/* Create and destroy modules. */
fn LLVMModuleCreateWithNameInContext(ModuleID: sbuf, C: ContextRef) ->
fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
- fn LLVMIntTypeInContext(C: ContextRef, NumBits: unsigned) -> TypeRef;
+ fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint) -> TypeRef;
fn LLVMInt1Type() -> TypeRef;
fn LLVMInt8Type() -> TypeRef;
fn LLVMInt16Type() -> TypeRef;
fn LLVMInt32Type() -> TypeRef;
fn LLVMInt64Type() -> TypeRef;
- fn LLVMIntType(NumBits: unsigned) -> TypeRef;
- fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> unsigned;
+ fn LLVMIntType(NumBits: c_uint) -> TypeRef;
+ fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
/* Operations on real types */
fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
/* Operations on function types */
fn LLVMFunctionType(ReturnType: TypeRef, ParamTypes: *TypeRef,
- ParamCount: unsigned, IsVarArg: Bool) -> TypeRef;
+ ParamCount: c_uint, IsVarArg: Bool) -> TypeRef;
fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
- fn LLVMCountParamTypes(FunctionTy: TypeRef) -> unsigned;
+ fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *TypeRef);
/* Operations on struct types */
fn LLVMStructTypeInContext(C: ContextRef, ElementTypes: *TypeRef,
- ElementCount: unsigned,
+ ElementCount: c_uint,
Packed: Bool) -> TypeRef;
- fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: unsigned,
+ fn LLVMStructType(ElementTypes: *TypeRef, ElementCount: c_uint,
Packed: Bool) -> TypeRef;
- fn LLVMCountStructElementTypes(StructTy: TypeRef) -> unsigned;
+ fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
fn LLVMGetStructElementTypes(StructTy: TypeRef, Dest: *TypeRef);
fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
/* Operations on array, pointer, and vector types (sequence types) */
fn LLVMArrayType(ElementType: TypeRef,
- ElementCount: unsigned) -> TypeRef;
+ ElementCount: c_uint) -> TypeRef;
fn LLVMPointerType(ElementType: TypeRef,
- AddressSpace: unsigned) -> TypeRef;
+ AddressSpace: c_uint) -> TypeRef;
fn LLVMVectorType(ElementType: TypeRef,
- ElementCount: unsigned) -> TypeRef;
+ ElementCount: c_uint) -> TypeRef;
fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
- fn LLVMGetArrayLength(ArrayTy: TypeRef) -> unsigned;
- fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> unsigned;
- fn LLVMGetVectorSize(VectorTy: TypeRef) -> unsigned;
+ fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+ fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+ fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
/* Operations on other types */
fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
fn LLVMDumpValue(Val: ValueRef);
fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
fn LLVMHasMetadata(Val: ValueRef) -> c_int;
- fn LLVMGetMetadata(Val: ValueRef, KindID: unsigned) -> ValueRef;
- fn LLVMSetMetadata(Val: ValueRef, KindID: unsigned, Node: ValueRef);
+ fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
+ fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
/* Operations on Uses */
fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
/* Operations on Users */
- fn LLVMGetOperand(Val: ValueRef, Index: unsigned) -> ValueRef;
- fn LLVMSetOperand(Val: ValueRef, Index: unsigned, Op: ValueRef);
+ fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+ fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
/* Operations on constants of any type */
fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
/* Operations on metadata */
- fn LLVMMDStringInContext(C: ContextRef, Str: sbuf, SLen: unsigned) ->
+ fn LLVMMDStringInContext(C: ContextRef, Str: sbuf, SLen: c_uint) ->
ValueRef;
- fn LLVMMDString(Str: sbuf, SLen: unsigned) -> ValueRef;
- fn LLVMMDNodeInContext(C: ContextRef, Vals: *ValueRef, Count: unsigned) ->
+ fn LLVMMDString(Str: sbuf, SLen: c_uint) -> ValueRef;
+ fn LLVMMDNodeInContext(C: ContextRef, Vals: *ValueRef, Count: c_uint) ->
ValueRef;
- fn LLVMMDNode(Vals: *ValueRef, Count: unsigned) -> ValueRef;
+ fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: sbuf,
Val: ValueRef);
/* Operations on scalar constants */
- fn LLVMConstInt(IntTy: TypeRef, N: ulonglong, SignExtend: Bool) ->
+ fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) ->
ValueRef;
// FIXME: radix is actually u8, but our native layer can't handle this
// yet. lucky for us we're little-endian. Small miracles.
fn LLVMConstIntOfString(IntTy: TypeRef, Text: sbuf, Radix: c_int) ->
ValueRef;
- fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: sbuf, SLen: unsigned,
+ fn LLVMConstIntOfStringAndSize(IntTy: TypeRef, Text: sbuf, SLen: c_uint,
Radix: u8) -> ValueRef;
fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
fn LLVMConstRealOfString(RealTy: TypeRef, Text: sbuf) -> ValueRef;
fn LLVMConstRealOfStringAndSize(RealTy: TypeRef, Text: sbuf,
- SLen: unsigned) -> ValueRef;
- fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> ulonglong;
- fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> longlong;
+ SLen: c_uint) -> ValueRef;
+ fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+ fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
/* Operations on composite constants */
- fn LLVMConstStringInContext(C: ContextRef, Str: sbuf, Length: unsigned,
+ fn LLVMConstStringInContext(C: ContextRef, Str: sbuf, Length: c_uint,
DontNullTerminate: Bool) -> ValueRef;
fn LLVMConstStructInContext(C: ContextRef, ConstantVals: *ValueRef,
- Count: unsigned, Packed: Bool) -> ValueRef;
+ Count: c_uint, Packed: Bool) -> ValueRef;
- fn LLVMConstString(Str: sbuf, Length: unsigned,
+ fn LLVMConstString(Str: sbuf, Length: c_uint,
DontNullTerminate: Bool) -> ValueRef;
fn LLVMConstArray(ElementTy: TypeRef, ConstantVals: *ValueRef,
- Length: unsigned) -> ValueRef;
+ Length: c_uint) -> ValueRef;
fn LLVMConstStruct(ConstantVals: *ValueRef,
- Count: unsigned, Packed: Bool) -> ValueRef;
+ Count: c_uint, Packed: Bool) -> ValueRef;
fn LLVMConstVector(ScalarConstantVals: *ValueRef,
- Size: unsigned) -> ValueRef;
+ Size: c_uint) -> ValueRef;
/* Constant expressions */
fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef) ->
ValueRef;
fn LLVMConstGEP(ConstantVal: ValueRef, ConstantIndices: *uint,
- NumIndices: unsigned) -> ValueRef;
+ NumIndices: c_uint) -> ValueRef;
fn LLVMConstInBoundsGEP(ConstantVal: ValueRef, ConstantIndices: *uint,
- NumIndices: unsigned) -> ValueRef;
+ NumIndices: c_uint) -> ValueRef;
fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
VectorBConstant: ValueRef,
MaskConstant: ValueRef) -> ValueRef;
fn LLVMConstExtractValue(AggConstant: ValueRef, IdxList: *uint,
- NumIdx: unsigned) -> ValueRef;
+ NumIdx: c_uint) -> ValueRef;
fn LLVMConstInsertValue(AggConstant: ValueRef,
ElementValueConstant: ValueRef, IdxList: *uint,
- NumIdx: unsigned) -> ValueRef;
+ NumIdx: c_uint) -> ValueRef;
fn LLVMConstInlineAsm(Ty: TypeRef, AsmString: sbuf, Constraints: sbuf,
HasSideEffects: Bool, IsAlignStack: Bool) ->
ValueRef;
/* Operations on global variables, functions, and aliases (globals) */
fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
- fn LLVMGetLinkage(Global: ValueRef) -> unsigned;
- fn LLVMSetLinkage(Global: ValueRef, Link: unsigned);
+ fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+ fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
fn LLVMGetSection(Global: ValueRef) -> sbuf;
fn LLVMSetSection(Global: ValueRef, Section: sbuf);
- fn LLVMGetVisibility(Global: ValueRef) -> unsigned;
- fn LLVMSetVisibility(Global: ValueRef, Viz: unsigned);
- fn LLVMGetAlignment(Global: ValueRef) -> unsigned;
- fn LLVMSetAlignment(Global: ValueRef, Bytes: unsigned);
+ fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+ fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+ fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+ fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
/* Operations on global variables */
fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: sbuf) -> ValueRef;
fn LLVMAddGlobalInAddressSpace(M: ModuleRef, Ty: TypeRef, Name: sbuf,
- AddressSpace: unsigned) -> ValueRef;
+ AddressSpace: c_uint) -> ValueRef;
fn LLVMGetNamedGlobal(M: ModuleRef, Name: sbuf) -> ValueRef;
fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
fn LLVMDeleteFunction(Fn: ValueRef);
fn LLVMGetOrInsertFunction(M: ModuleRef, Name: sbuf, FunctionTy: TypeRef)
-> ValueRef;
- fn LLVMGetIntrinsicID(Fn: ValueRef) -> unsigned;
- fn LLVMGetFunctionCallConv(Fn: ValueRef) -> unsigned;
- fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: unsigned);
+ fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+ fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+ fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
fn LLVMGetGC(Fn: ValueRef) -> sbuf;
fn LLVMSetGC(Fn: ValueRef, Name: sbuf);
- fn LLVMAddFunctionAttr(Fn: ValueRef, PA: unsigned, HighPA: unsigned);
- fn LLVMGetFunctionAttr(Fn: ValueRef) -> unsigned;
- fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: unsigned, HighPA: unsigned);
+ fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint, HighPA: c_uint);
+ fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_uint;
+ fn LLVMRemoveFunctionAttr(Fn: ValueRef, PA: c_uint, HighPA: c_uint);
/* Operations on parameters */
- fn LLVMCountParams(Fn: ValueRef) -> unsigned;
+ fn LLVMCountParams(Fn: ValueRef) -> c_uint;
fn LLVMGetParams(Fn: ValueRef, Params: *ValueRef);
- fn LLVMGetParam(Fn: ValueRef, Index: unsigned) -> ValueRef;
+ fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
- fn LLVMAddAttribute(Arg: ValueRef, PA: unsigned);
- fn LLVMRemoveAttribute(Arg: ValueRef, PA: unsigned);
- fn LLVMGetAttribute(Arg: ValueRef) -> unsigned;
- fn LLVMSetParamAlignment(Arg: ValueRef, align: unsigned);
+ fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+ fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+ fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+ fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
/* Operations on basic blocks */
fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
- fn LLVMCountBasicBlocks(Fn: ValueRef) -> unsigned;
+ fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *ValueRef);
fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
/* Operations on call sites */
- fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: unsigned);
- fn LLVMGetInstructionCallConv(Instr: ValueRef) -> unsigned;
- fn LLVMAddInstrAttribute(Instr: ValueRef, index: unsigned, IA: unsigned);
- fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: unsigned,
- IA: unsigned);
- fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: unsigned,
- align: unsigned);
+ fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+ fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+ fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
+ fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint,
+ IA: c_uint);
+ fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint,
+ align: c_uint);
/* Operations on call instructions (only) */
fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
/* Operations on phi nodes */
fn LLVMAddIncoming(PhiNode: ValueRef, IncomingValues: *ValueRef,
- IncomingBlocks: *BasicBlockRef, Count: unsigned);
- fn LLVMCountIncoming(PhiNode: ValueRef) -> unsigned;
- fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: unsigned) -> ValueRef;
+ IncomingBlocks: *BasicBlockRef, Count: c_uint);
+ fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+ fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint) -> ValueRef;
fn LLVMGetIncomingBlock(PhiNode: ValueRef,
- Index: unsigned) -> BasicBlockRef;
+ Index: c_uint) -> BasicBlockRef;
/* Instruction builders */
fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
fn LLVMBuildAggregateRet(B: BuilderRef, RetVals: *ValueRef,
- N: unsigned) -> ValueRef;
+ N: c_uint) -> ValueRef;
fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
fn LLVMBuildCondBr(B: BuilderRef, If: ValueRef, Then: BasicBlockRef,
Else: BasicBlockRef) -> ValueRef;
fn LLVMBuildSwitch(B: BuilderRef, V: ValueRef, Else: BasicBlockRef,
- NumCases: unsigned) -> ValueRef;
+ NumCases: c_uint) -> ValueRef;
fn LLVMBuildIndirectBr(B: BuilderRef, Addr: ValueRef,
- NumDests: unsigned) -> ValueRef;
+ NumDests: c_uint) -> ValueRef;
fn LLVMBuildInvoke(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
- NumArgs: unsigned, Then: BasicBlockRef,
+ NumArgs: c_uint, Then: BasicBlockRef,
Catch: BasicBlockRef, Name: sbuf) -> ValueRef;
fn LLVMBuildLandingPad(B: BuilderRef, Ty: TypeRef, PersFn: ValueRef,
- NumClauses: unsigned, Name: sbuf) -> ValueRef;
+ NumClauses: c_uint, Name: sbuf) -> ValueRef;
fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef) ->
ValueRef;
fn LLVMBuildGEP(B: BuilderRef, Pointer: ValueRef, Indices: *ValueRef,
- NumIndices: unsigned, Name: sbuf) -> ValueRef;
+ NumIndices: c_uint, Name: sbuf) -> ValueRef;
fn LLVMBuildInBoundsGEP(B: BuilderRef, Pointer: ValueRef,
- Indices: *ValueRef, NumIndices: unsigned,
+ Indices: *ValueRef, NumIndices: c_uint,
Name: sbuf)
-> ValueRef;
- fn LLVMBuildStructGEP(B: BuilderRef, Pointer: ValueRef, Idx: unsigned,
+ fn LLVMBuildStructGEP(B: BuilderRef, Pointer: ValueRef, Idx: c_uint,
Name: sbuf) -> ValueRef;
fn LLVMBuildGlobalString(B: BuilderRef, Str: sbuf, Name: sbuf) ->
ValueRef;
Name: sbuf) -> ValueRef;
/* Comparisons */
- fn LLVMBuildICmp(B: BuilderRef, Op: unsigned, LHS: ValueRef,
+ fn LLVMBuildICmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
RHS: ValueRef, Name: sbuf) -> ValueRef;
- fn LLVMBuildFCmp(B: BuilderRef, Op: unsigned, LHS: ValueRef,
+ fn LLVMBuildFCmp(B: BuilderRef, Op: c_uint, LHS: ValueRef,
RHS: ValueRef, Name: sbuf) -> ValueRef;
/* Miscellaneous instructions */
fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: sbuf) -> ValueRef;
fn LLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: *ValueRef,
- NumArgs: unsigned, Name: sbuf) -> ValueRef;
+ NumArgs: c_uint, Name: sbuf) -> ValueRef;
fn LLVMBuildSelect(B: BuilderRef, If: ValueRef, Then: ValueRef,
Else: ValueRef, Name: sbuf) -> ValueRef;
fn LLVMBuildVAArg(B: BuilderRef, list: ValueRef, Ty: TypeRef, Name: sbuf)
-> ValueRef;
fn LLVMBuildShuffleVector(B: BuilderRef, V1: ValueRef, V2: ValueRef,
Mask: ValueRef, Name: sbuf) -> ValueRef;
- fn LLVMBuildExtractValue(B: BuilderRef, AggVal: ValueRef, Index: unsigned,
+ fn LLVMBuildExtractValue(B: BuilderRef, AggVal: ValueRef, Index: c_uint,
Name: sbuf) -> ValueRef;
fn LLVMBuildInsertValue(B: BuilderRef, AggVal: ValueRef, EltVal: ValueRef,
- Index: unsigned, Name: sbuf) -> ValueRef;
+ Index: c_uint, Name: sbuf) -> ValueRef;
fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: sbuf) -> ValueRef;
fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: sbuf) ->
/** Adds the target data to the given pass manager. The pass manager
references the target data only weakly. */
fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
- /** Returns the size of a type. FIXME: rv is actually a ULongLong! */
- fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef) -> unsigned;
+ /** Returns the size of a type. FIXME: rv is actually a C_Ulonglong! */
+ fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
/** Returns the alignment of a type. */
fn LLVMPreferredAlignmentOfType(TD: TargetDataRef,
- Ty: TypeRef) -> unsigned;
+ Ty: TypeRef) -> c_uint;
/** Disposes target data. */
fn LLVMDisposeTargetData(TD: TargetDataRef);
fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
- OptimizationLevel: unsigned);
+ OptimizationLevel: c_uint);
fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
Value: Bool);
fn LLVMPassManagerBuilderSetDisableUnitAtATime(PMB: PassManagerBuilderRef,
fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls
(PMB: PassManagerBuilderRef, Value: Bool);
fn LLVMPassManagerBuilderUseInlinerWithThreshold
- (PMB: PassManagerBuilderRef, threshold: unsigned);
+ (PMB: PassManagerBuilderRef, threshold: c_uint);
fn LLVMPassManagerBuilderPopulateModulePassManager
(PMB: PassManagerBuilderRef, PM: PassManagerRef);
/** Returns the current section name. */
fn LLVMGetSectionName(SI: SectionIteratorRef) -> sbuf;
/** Returns the current section size. */
- fn LLVMGetSectionSize(SI: SectionIteratorRef) -> ulonglong;
+ fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
/** Returns the current section contents as a string buffer. */
fn LLVMGetSectionContents(SI: SectionIteratorRef) -> sbuf;
/** Parses LLVM asm in the given file */
fn LLVMRustParseAssemblyFile(Filename: sbuf) -> ModuleRef;
- /** FiXME: Hacky adaptor for lack of ULongLong in FFI: */
- fn LLVMRustConstInt(IntTy: TypeRef, N_hi: unsigned, N_lo: unsigned,
+ /** FiXME: Hacky adaptor for lack of c_ulonglong in FFI: */
+ fn LLVMRustConstInt(IntTy: TypeRef, N_hi: c_uint, N_lo: c_uint,
SignExtend: Bool) -> ValueRef;
fn LLVMRustAddPrintModulePass(PM: PassManagerRef, M: ModuleRef,
fn LLVMStructCreateNamed(C: ContextRef, Name: sbuf) -> TypeRef;
fn LLVMStructSetBody(StructTy: TypeRef, ElementTypes: *TypeRef,
- ElementCount: unsigned, Packed: Bool);
+ ElementCount: c_uint, Packed: Bool);
fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
- Count: unsigned) -> ValueRef;
+ Count: c_uint) -> ValueRef;
/** Links LLVM modules together. `Src` is destroyed by this call and
must never be referenced again. */
}
fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
- llvm::LLVMSetInstructionCallConv(Instr, CC as unsigned);
+ llvm::LLVMSetInstructionCallConv(Instr, CC as c_uint);
}
fn SetFunctionCallConv(Fn: ValueRef, CC: CallConv) {
- llvm::LLVMSetFunctionCallConv(Fn, CC as unsigned);
+ llvm::LLVMSetFunctionCallConv(Fn, CC as c_uint);
}
fn SetLinkage(Global: ValueRef, Link: Linkage) {
- llvm::LLVMSetLinkage(Global, Link as unsigned);
+ llvm::LLVMSetLinkage(Global, Link as c_uint);
}
/* Memory-managed object interface to type handles. */
import e = encoder;
// used in testing:
-import std::io;
import driver::diagnostic;
import syntax::codemap;
import syntax::parse::parser;
import syntax::visit;
import syntax::codemap::span;
import util::{filesearch};
-import std::{io, fs};
import io::writer_util;
import std::map::{hashmap, new_int_hash};
import syntax::print::pprust;
ret filesearch::search(filesearch, { |path|
#debug("inspecting file %s", path);
- let f: str = fs::basename(path);
+ let f: str = path::basename(path);
if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) {
#debug("skipping %s, doesn't look like %s*%s", path, prefix,
suffix);
// Decoding metadata from a single crate's metadata
-import std::{ebml, map, io};
+import std::{ebml, map};
import std::map::hashmap;
import io::writer_util;
import syntax::{ast, ast_util};
// Metadata encoding
-import std::{io, ebml, map, list};
+import std::{ebml, map, list};
import std::map::hashmap;
import io::writer_util;
import ebml::writer;
// Type encoding
-import std::io;
import io::writer_util;
import std::map::hashmap;
import syntax::ast::*;
import middle::ty::ctxt;
import syntax::{ast, visit};
import front::attr;
-import std::io;
import std::map::hashmap;
import io::writer_util;
tcx.sess.span_warn(
ty.span,
"found rust type `int` in native module, while \
- ctypes::c_int or ctypes::long should be used");
+ libc::c_int or libc::c_long should be used");
}
ast::def_prim_ty(ast::ty_uint(ast::ty_u)) {
tcx.sess.span_warn(
ty.span,
"found rust type `uint` in native module, while \
- ctypes::c_uint or ctypes::ulong should be used");
+ libc::c_uint or libc::c_ulong should be used");
}
_ { }
}
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
-import ctypes::c_uint;
+import libc::c_uint;
import std::{map, time};
import std::map::hashmap;
import std::map::{new_int_hash, new_str_hash};
-import ctypes::{c_uint, c_int};
+import libc::{c_uint, c_int};
import str::sbuf;
import lib::llvm::llvm;
import syntax::codemap;
-import core::ctypes::c_uint;
+import libc::c_uint;
import syntax::ast;
import syntax::ast_util;
import lib::llvm::llvm;
*/
-import ctypes::unsigned;
+import libc::c_uint;
import vec::unsafe::to_ptr;
import std::map::hashmap;
import syntax::ast;
fn T_fn(inputs: [TypeRef], output: TypeRef) -> TypeRef unsafe {
ret llvm::LLVMFunctionType(output, to_ptr(inputs),
- inputs.len() as unsigned,
+ inputs.len() as c_uint,
False);
}
}
fn T_ptr(t: TypeRef) -> TypeRef {
- ret llvm::LLVMPointerType(t, 0u as unsigned);
+ ret llvm::LLVMPointerType(t, 0u as c_uint);
}
fn T_struct(elts: [TypeRef]) -> TypeRef unsafe {
- ret llvm::LLVMStructType(to_ptr(elts), elts.len() as unsigned, False);
+ ret llvm::LLVMStructType(to_ptr(elts), elts.len() as c_uint, False);
}
fn T_named_struct(name: str) -> TypeRef {
fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe {
llvm::LLVMStructSetBody(t, to_ptr(elts),
- elts.len() as unsigned, False);
+ elts.len() as c_uint, False);
}
fn T_empty_struct() -> TypeRef { ret T_struct([]); }
}
fn T_array(t: TypeRef, n: uint) -> TypeRef {
- ret llvm::LLVMArrayType(t, n as unsigned);
+ ret llvm::LLVMArrayType(t, n as c_uint);
}
// Interior vector.
fn C_null(t: TypeRef) -> ValueRef { ret llvm::LLVMConstNull(t); }
fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef {
- let u_hi = (u >> 32u64) as unsigned;
- let u_lo = u as unsigned;
+ let u_hi = (u >> 32u64) as c_uint;
+ let u_lo = u as c_uint;
ret llvm::LLVMRustConstInt(t, u_hi, u_lo, sign_extend);
}
// our boxed-and-length-annotated strings.
fn C_cstr(cx: crate_ctxt, s: str) -> ValueRef {
let sc = str::as_buf(s) {|buf|
- llvm::LLVMConstString(buf, str::len(s) as unsigned, False)
+ llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
let g =
str::as_buf(cx.names("str"),
// Returns a Plain Old LLVM String:
fn C_postr(s: str) -> ValueRef {
ret str::as_buf(s) {|buf|
- llvm::LLVMConstString(buf, str::len(s) as unsigned, False)
+ llvm::LLVMConstString(buf, str::len(s) as c_uint, False)
};
}
let elts: [ValueRef] = [];
while i < size { elts += [C_u8(0u)]; i += 1u; }
ret llvm::LLVMConstArray(T_i8(), vec::unsafe::to_ptr(elts),
- elts.len() as unsigned);
+ elts.len() as c_uint);
}
fn C_struct(elts: [ValueRef]) -> ValueRef unsafe {
ret llvm::LLVMConstStruct(vec::unsafe::to_ptr(elts),
- elts.len() as unsigned, False);
+ elts.len() as c_uint, False);
}
fn C_named_struct(T: TypeRef, elts: [ValueRef]) -> ValueRef unsafe {
ret llvm::LLVMConstNamedStruct(T, vec::unsafe::to_ptr(elts),
- elts.len() as unsigned);
+ elts.len() as c_uint);
}
fn C_array(ty: TypeRef, elts: [ValueRef]) -> ValueRef unsafe {
ret llvm::LLVMConstArray(ty, vec::unsafe::to_ptr(elts),
- elts.len() as unsigned);
+ elts.len() as c_uint);
}
fn C_bytes(bytes: [u8]) -> ValueRef unsafe {
ret llvm::LLVMConstString(
unsafe::reinterpret_cast(vec::unsafe::to_ptr(bytes)),
- bytes.len() as unsigned, False);
+ bytes.len() as c_uint, False);
}
fn C_shape(ccx: crate_ctxt, bytes: [u8]) -> ValueRef {
-import std::fs;
import std::map::hashmap;
import lib::llvm::llvm;
import lib::llvm::ValueRef;
fn llstr(s: str) -> ValueRef {
str::as_buf(s, {|sbuf|
- llvm::LLVMMDString(sbuf, str::len(s) as ctypes::c_uint)
+ llvm::LLVMMDString(sbuf, str::len(s) as libc::c_uint)
})
}
fn lltag(lltag: int) -> ValueRef {
}
fn llmdnode(elems: [ValueRef]) -> ValueRef unsafe {
llvm::LLVMMDNode(vec::unsafe::to_ptr(elems),
- vec::len(elems) as ctypes::c_uint)
+ vec::len(elems) as libc::c_uint)
}
fn llunused() -> ValueRef {
lli32(0x0)
option::none {}
}
- let fname = fs::basename(full_path);
- let path = fs::dirname(full_path);
+ let fname = path::basename(full_path);
+ let path = path::dirname(full_path);
let unit_node = create_compile_unit(cx, full_path).node;
let file_md = [lltag(tg),
llstr(fname),
option::some(md) { ret md; }
option::none {}
}*/
- let (size, align) = size_and_align_of::<ctypes::intptr_t>();
+ let (size, align) = size_and_align_of::<libc::intptr_t>();
let fname = filename_from_span(cx, span);
let file_node = create_file(cx, fname);
//let cu_node = create_compile_unit(cx, fname);
let scx = create_structure(file_node, ty_to_str(cx.tcx, vec_t), 0);
let size_t_type = create_basic_type(cx, ty::mk_uint(cx.tcx),
ast::ty_uint(ast::ty_u), vec_ty_span);
- add_member(scx, "fill", 0, sys::size_of::<ctypes::size_t>() as int,
- sys::align_of::<ctypes::size_t>() as int, size_t_type.node);
- add_member(scx, "alloc", 0, sys::size_of::<ctypes::size_t>() as int,
- sys::align_of::<ctypes::size_t>() as int, size_t_type.node);
+ add_member(scx, "fill", 0, sys::size_of::<libc::size_t>() as int,
+ sys::align_of::<libc::size_t>() as int, size_t_type.node);
+ add_member(scx, "alloc", 0, sys::size_of::<libc::size_t>() as int,
+ sys::align_of::<libc::size_t>() as int, size_t_type.node);
let subrange = llmdnode([lltag(SubrangeTag), lli64(0), lli64(0)]);
let (arr_size, arr_align) = member_size_and_align(cx.tcx, elem_ty);
let data_ptr = create_composite_type(ArrayTypeTag, "", file_node.node, 0,
}
}
ast::ty_box(_) | ast::ty_uniq(_) {
- size_and_align_of::<ctypes::uintptr_t>()
+ size_and_align_of::<libc::uintptr_t>()
}
ast::ty_rec(fields) {
let total_size = 0;
(total_size, 64) //XXX different align for other arches?
}
ast::ty_vec(_) {
- size_and_align_of::<ctypes::uintptr_t>()
+ size_and_align_of::<libc::uintptr_t>()
}
_ { fail "member_size_and_align: can't handle this type"; }
}
-import ctypes::c_uint;
+import libc::c_uint;
import base::*;
import common::*;
import type_of::*;
import driver::session::session;
import syntax::codemap::span;
-import ctypes::c_uint;
+import libc::c_uint;
import front::attr;
import lib::llvm::{ llvm, TypeRef, ValueRef };
import syntax::ast;
* should all get sucked into either the compiler syntax extension plugin
* interface.
*/
-import std::generic_os;
import base::*;
export expand_syntax_ext;
// option<str> rather than just an maybe-empty string.
let var = expr_to_str(cx, args[0], "#env requires a string");
- alt generic_os::getenv(var) {
+ alt os::getenv(var) {
option::none { ret make_new_str(cx, sp, ""); }
option::some(s) { ret make_new_str(cx, sp, s); }
}
import base::*;
import syntax::ast;
-import std::io::writer_util;
+import io::writer_util;
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
let arg = get_mac_arg(cx,sp,arg);
cx.print_backtrace();
- std::io::stdout().write_line(print::pprust::expr_to_str(arg));
+ io::stdout().write_line(print::pprust::expr_to_str(arg));
//trivial expression
ret @{id: cx.next_id(), node: ast::expr_rec([], option::none), span: sp};
import syntax::parse::parser::{parser, parse_from_source_str};
import syntax::print::*;
-import std::io::*;
+import io::*;
import codemap::span;
}
fn print_expr(expr: @ast::expr) {
- let stdout = std::io::stdout();
+ let stdout = io::stdout();
let pp = pprust::rust_printer(stdout);
pprust::print_expr(pp, expr);
pp::eof(pp.s);
-
import front::attr;
-import std::{io, fs};
import syntax::ast;
import syntax::parse::token;
import syntax::parse::parser::{parser, new_parser_from_file,
fn companion_file(prefix: str, suffix: option<str>) -> str {
ret alt suffix {
- option::some(s) { fs::connect(prefix, s) }
+ option::some(s) { path::connect(prefix, s) }
option::none { prefix }
} + ".rs";
}
ast::cdir_src_mod(id, attrs) {
let file_path = cdir_path_opt(id + ".rs", attrs);
let full_path =
- if std::fs::path_is_absolute(file_path) {
+ if path::path_is_absolute(file_path) {
file_path
- } else { prefix + std::fs::path_sep() + file_path };
+ } else { prefix + path::path_sep() + file_path };
let p0 =
new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE);
let inner_attrs = parse_inner_attrs_and_next(p0);
ast::cdir_dir_mod(id, cdirs, attrs) {
let path = cdir_path_opt(id, attrs);
let full_path =
- if std::fs::path_is_absolute(path) {
+ if path::path_is_absolute(path) {
path
- } else { prefix + std::fs::path_sep() + path };
+ } else { prefix + path::path_sep() + path };
let (m0, a0) = eval_crate_directives_to_mod(
cx, cdirs, full_path, none);
let i =
-
-import std::io;
import io::reader_util;
import util::interner;
import util::interner::intern;
-import std::{io, fs};
import either::{left, right};
import std::map::{hashmap, new_str_hash};
import token::can_begin_expr;
sess: parse_sess) -> @ast::crate {
let p = new_parser_from_file(sess, cfg, input, CRATE_FILE);
let lo = p.span.lo;
- let prefix = std::fs::dirname(p.reader.filemap.name);
+ let prefix = path::dirname(p.reader.filemap.name);
let leading_attrs = parse_inner_attrs_and_next(p);
let crate_attrs = leading_attrs.inner;
let first_cdir_attr = leading_attrs.next;
@{p: p,
sess: sess,
cfg: p.cfg};
- let (companionmod, _) = fs::splitext(fs::basename(input));
+ let (companionmod, _) = path::splitext(path::basename(input));
let (m, attrs) = eval::eval_crate_directives_to_mod(
cx, cdirs, prefix, option::some(companionmod));
let hi = p.span.hi;
-
-import std::io;
import io::writer_util;
/*
-
-import std::io;
import parse::lexer;
import syntax::codemap::codemap;
import pp::{break_offset, word, printer,
// FIXME: I'm not happy how this module turned out. Should probably
// just be folded into cstore.
-import std::{fs, os, generic_os};
-
export filesearch;
export mk_filesearch;
export pick;
export get_cargo_root_nearest;
export libdir;
-type pick<T> = fn(path: fs::path) -> option<T>;
+import path::path;
+
+type pick<T> = fn(path: path) -> option<T>;
-fn pick_file(file: fs::path, path: fs::path) -> option<fs::path> {
- if fs::basename(path) == file { option::some(path) }
+fn pick_file(file: path, path: path) -> option<path> {
+ if path::basename(path) == file { option::some(path) }
else { option::none }
}
iface filesearch {
- fn sysroot() -> fs::path;
- fn lib_search_paths() -> [fs::path];
- fn get_target_lib_path() -> fs::path;
- fn get_target_lib_file_path(file: fs::path) -> fs::path;
+ fn sysroot() -> path;
+ fn lib_search_paths() -> [path];
+ fn get_target_lib_path() -> path;
+ fn get_target_lib_file_path(file: path) -> path;
}
-fn mk_filesearch(maybe_sysroot: option<fs::path>,
+fn mk_filesearch(maybe_sysroot: option<path>,
target_triple: str,
- addl_lib_search_paths: [fs::path]) -> filesearch {
- type filesearch_impl = {sysroot: fs::path,
- addl_lib_search_paths: [fs::path],
+ addl_lib_search_paths: [path]) -> filesearch {
+ type filesearch_impl = {sysroot: path,
+ addl_lib_search_paths: [path],
target_triple: str};
impl of filesearch for filesearch_impl {
- fn sysroot() -> fs::path { self.sysroot }
- fn lib_search_paths() -> [fs::path] {
+ fn sysroot() -> path { self.sysroot }
+ fn lib_search_paths() -> [path] {
self.addl_lib_search_paths
+ [make_target_lib_path(self.sysroot, self.target_triple)]
+ alt get_cargo_lib_path_nearest() {
result::err(p) { [] }
}
}
- fn get_target_lib_path() -> fs::path {
+ fn get_target_lib_path() -> path {
make_target_lib_path(self.sysroot, self.target_triple)
}
- fn get_target_lib_file_path(file: fs::path) -> fs::path {
- fs::connect(self.get_target_lib_path(), file)
+ fn get_target_lib_file_path(file: path) -> path {
+ path::connect(self.get_target_lib_path(), file)
}
}
fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
for lib_search_path in filesearch.lib_search_paths() {
#debug("searching %s", lib_search_path);
- for path in fs::list_dir(lib_search_path) {
+ for path in os::list_dir(lib_search_path) {
#debug("testing %s", path);
let maybe_picked = pick(path);
if option::is_some(maybe_picked) {
ret option::none;
}
-fn relative_target_lib_path(target_triple: str) -> [fs::path] {
+fn relative_target_lib_path(target_triple: str) -> [path] {
[libdir(), "rustc", target_triple, libdir()]
}
-fn make_target_lib_path(sysroot: fs::path,
- target_triple: str) -> fs::path {
+fn make_target_lib_path(sysroot: path,
+ target_triple: str) -> path {
let path = [sysroot] + relative_target_lib_path(target_triple);
- let path = fs::connect_many(path);
+ let path = path::connect_many(path);
ret path;
}
-fn get_default_sysroot() -> fs::path {
- alt os::get_exe_path() {
- option::some(p) { fs::normalize(fs::connect(p, "..")) }
+fn get_default_sysroot() -> path {
+ alt os::self_exe_path() {
+ option::some(p) { path::normalize(path::connect(p, "..")) }
option::none {
fail "can't determine value for sysroot";
}
}
}
-fn get_sysroot(maybe_sysroot: option<fs::path>) -> fs::path {
+fn get_sysroot(maybe_sysroot: option<path>) -> path {
alt maybe_sysroot {
option::some(sr) { sr }
option::none { get_default_sysroot() }
}
}
-fn get_cargo_sysroot() -> result::t<fs::path, str> {
+fn get_cargo_sysroot() -> result::t<path, str> {
let path = [get_default_sysroot(), libdir(), "cargo"];
- result::ok(fs::connect_many(path))
+ result::ok(path::connect_many(path))
}
-fn get_cargo_root() -> result::t<fs::path, str> {
- alt generic_os::getenv("CARGO_ROOT") {
+fn get_cargo_root() -> result::t<path, str> {
+ alt os::getenv("CARGO_ROOT") {
some(_p) { result::ok(_p) }
none {
- alt fs::homedir() {
- some(_q) { result::ok(fs::connect(_q, ".cargo")) }
+ alt os::homedir() {
+ some(_q) { result::ok(path::connect(_q, ".cargo")) }
none { result::err("no CARGO_ROOT or home directory") }
}
}
}
}
-fn get_cargo_root_nearest() -> result::t<fs::path, str> {
+fn get_cargo_root_nearest() -> result::t<path, str> {
result::chain(get_cargo_root()) { |p|
let cwd = os::getcwd();
- let dirname = fs::dirname(cwd);
- let dirpath = fs::split(dirname);
- let cwd_cargo = fs::connect(cwd, ".cargo");
- let par_cargo = fs::connect(dirname, ".cargo");
+ let dirname = path::dirname(cwd);
+ let dirpath = path::split(dirname);
+ let cwd_cargo = path::connect(cwd, ".cargo");
+ let par_cargo = path::connect(dirname, ".cargo");
- if fs::path_is_dir(cwd_cargo) || cwd_cargo == p {
+ if os::path_is_dir(cwd_cargo) || cwd_cargo == p {
ret result::ok(cwd_cargo);
}
while vec::is_not_empty(dirpath) && par_cargo != p {
- if fs::path_is_dir(par_cargo) {
+ if os::path_is_dir(par_cargo) {
ret result::ok(par_cargo);
}
vec::pop(dirpath);
- dirname = fs::dirname(dirname);
- par_cargo = fs::connect(dirname, ".cargo");
+ dirname = path::dirname(dirname);
+ par_cargo = path::connect(dirname, ".cargo");
}
result::ok(cwd_cargo)
}
}
-fn get_cargo_lib_path() -> result::t<fs::path, str> {
+fn get_cargo_lib_path() -> result::t<path, str> {
result::chain(get_cargo_root()) { |p|
- result::ok(fs::connect(p, libdir()))
+ result::ok(path::connect(p, libdir()))
}
}
-fn get_cargo_lib_path_nearest() -> result::t<fs::path, str> {
+fn get_cargo_lib_path_nearest() -> result::t<path, str> {
result::chain(get_cargo_root_nearest()) { |p|
- result::ok(fs::connect(p, libdir()))
+ result::ok(path::connect(p, libdir()))
}
}
}
fn usage() {
- import std::io::println;
+ import io::println;
println("Usage: rustdoc [options] <cratefile>\n");
println("Options:\n");
}
fn parse_config(args: [str]) -> result::t<config, str> {
- parse_config_(args, std::run::program_output)
+ parse_config_(args, run::program_output)
}
fn parse_config_(
];
generic_writer {|markdown|
- import std::run;
- import std::os;
- import std::io;
- import std::io::writer_util;
+ import io::writer_util;
#debug("pandoc cmd: %s", pandoc_cmd);
#debug("pandoc args: %s", str::connect(pandoc_args, " "));
}
}
-fn readclose(fd: ctypes::fd_t) -> str {
- import std::os;
- import std::io;
-
+fn readclose(fd: libc::c_int) -> str {
// Copied from run::program_output
- let file = os::fd_FILE(fd);
+ let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let buf = "";
while !reader.eof() {
page: doc::page
) -> str {
let filename = make_filename(config, page);
- std::fs::connect(config.output_dir, filename)
+ path::connect(config.output_dir, filename)
}
fn make_filename(
}
fn write_file(path: str, s: str) {
- import std::io;
- import std::io::writer_util;
+ import io::writer_util;
alt io::file_writer(path, [io::create, io::truncate]) {
result::ok(writer) {
let config = alt config::parse_config(args) {
result::ok(config) { config }
result::err(err) {
- std::io::println(#fmt("error: %s", err));
+ io::println(#fmt("error: %s", err));
ret;
}
};
import rustc::util::ppaux;
import std::map::{hashmap, map, new_int_hash};
import std::getopts;
-import std::io;
-import std::io::writer_util;
+import io::writer_util;
import driver::build_session_options;
import driver::build_session;
import driver::build_configuration;
// I *think* it's the same, more or less.
use std;
-import std::io::writer;
-import std::io::writer_util;
+import io::writer;
+import io::writer_util;
enum request {
get_count,
let result = comm::recv(from_child);
let end = std::time::precise_time_s();
let elapsed = end - start;
- std::io::stdout().write_str(#fmt("Count is %?\n", result));
- std::io::stdout().write_str(#fmt("Test took %? seconds\n", elapsed));
+ io::stdout().write_str(#fmt("Count is %?\n", result));
+ io::stdout().write_str(#fmt("Test took %? seconds\n", elapsed));
let thruput = ((size / workers * workers) as float) / (elapsed as float);
- std::io::stdout().write_str(#fmt("Throughput=%f per sec\n", thruput));
+ io::stdout().write_str(#fmt("Throughput=%f per sec\n", thruput));
}
fn main(args: [str]) {
} else {
8
};
- std::io::println(#fmt("Ack(3,%d): %d\n", n, ack(3, n)));
+ io::println(#fmt("Ack(3,%d): %d\n", n, ack(3, n)));
}
} else { max_depth = n; }
let stretch_depth = max_depth + 1;
let stretch_tree = bottom_up_tree(0, stretch_depth);
- std::io::println(#fmt("stretch tree of depth %d\t check: %d",
+ io::println(#fmt("stretch tree of depth %d\t check: %d",
stretch_depth,
item_check(stretch_tree)));
let long_lived_tree = bottom_up_tree(0, max_depth);
chk += item_check(temp_tree);
i += 1;
}
- std::io::println(#fmt("%d\t trees of depth %d\t check: %d",
- iterations * 2, depth,
- chk));
+ io::println(#fmt("%d\t trees of depth %d\t check: %d",
+ iterations * 2, depth,
+ chk));
depth += 2;
}
- std::io::println(#fmt("long lived trees of depth %d\t check: %d",
- max_depth,
+ io::println(#fmt("long lived trees of depth %d\t check: %d",
+ max_depth,
item_check(long_lived_tree)));
}
let go = true;
while go {
if r == n {
- std::io::println(#fmt("%d", checksum));
+ io::println(#fmt("%d", checksum));
ret flips;
}
let p0 = perm1[0];
} else {
8
};
- std::io::println(#fmt("Pfannkuchen(%d) = %d", n, fannkuch(n)));
+ io::println(#fmt("Pfannkuchen(%d) = %d", n, fannkuch(n)));
}
} else {
30
};
- std::io::println(#fmt("%d\n", fib(n)));
+ io::println(#fmt("%d\n", fib(n)));
}
// writes pbm image to output path
use std;
-import std::io::writer_util;
+import io::writer_util;
import std::map::hashmap;
type cmplx = {re: f64, im: f64};
type devnull = {dn: int};
-impl of std::io::writer for devnull {
+impl of io::writer for devnull {
fn write(_b: [const u8]) {}
- fn seek(_i: int, _s: std::io::seek_style) {}
+ fn seek(_i: int, _s: io::seek_style) {}
fn tell() -> uint {0_u}
fn flush() -> int {0}
}
let p: comm::port<line> = comm::port();
let ch = comm::chan(p);
comm::send(writech, ch);
- let cout: std::io::writer = alt path {
+ let cout: io::writer = alt path {
"" {
- {dn: 0} as std::io::writer
+ {dn: 0} as io::writer
}
"-" {
- std::io::stdout()
+ io::stdout()
}
_ {
result::get(
- std::io::file_writer(path,
- [std::io::create, std::io::truncate]))
+ io::file_writer(path,
+ [io::create, io::truncate]))
}
};
cout.write_line("P4");
100000
};
let bodies: [Body::props] = NBodySystem::MakeNBodySystem();
- std::io::println(#fmt("%f", NBodySystem::energy(bodies)));
+ io::println(#fmt("%f", NBodySystem::energy(bodies)));
let i: int = 0;
while i < n { NBodySystem::advance(bodies, 0.01); i += 1; }
- std::io::println(#fmt("%f", NBodySystem::energy(bodies)));
+ io::println(#fmt("%f", NBodySystem::energy(bodies)));
}
// Body::props is a record of floats, so
use std;
-import std::{time, io, getopts};
+import std::{time, getopts};
import io::writer_util;
import int::range;
import comm::port;
i += 1u;
}
- std::io::println(#fmt("%0.9f\n", float::sqrt(vBv / vv)));
+ io::println(#fmt("%0.9f\n", float::sqrt(vBv / vv)));
}
while (true) {
alt comm::recv(p) {
1 {
- std::io::println(#fmt("%d\n", id));
+ io::println(#fmt("%d\n", id));
ret;
}
token {
use std;
-import std::{io, bitv};
+import std::bitv;
import io::{writer_util, reader_util};
// Computes a single solution to a given 9x9 sudoku
import option = option;
import option::{some, none};
-import std::{map, io, time};
+import std::{map, time};
import std::map::hashmap;
import io::reader_util;
// error-pattern:non-scalar cast
-use std;
-import std::os;
-
fn main() {
log(debug, { x: 1 } as int);
}
use rustc;
import rustc::*;
-import std::io::*;
+import io::*;
import rustc::driver::diagnostic;
import rustc::syntax::ast;
// error-pattern:unsupported cast
-use std;
-import std::os;
-
fn main() {
- log(debug, 1.0 as os::FILE); // Can't cast float to native.
+ log(debug, 1.0 as *libc::FILE); // Can't cast float to native.
}
-//error-pattern:ctypes::c_int or ctypes::long should be used
+//error-pattern:libc::c_int or libc::c_long should be used
native mod xx {
fn strlen(str: *u8) -> uint;
fn foo(x: int, y: uint);
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
use std;
import str;
-import ctypes::*;
+import libc::*;
#[nolink]
native mod libc {
#[abi = "cdecl"]
native mod rustrt {
- fn rand_new() -> *ctypes::void;
+ fn rand_new() -> *libc::c_void;
}
fn main() { bind rustrt::rand_new(); }
// xfail-fast - check-fast doesn't understand aux-build
// aux-build:cci_impl_lib.rs
-use std;
use cci_impl_lib;
-import std::io;
import cci_impl_lib::helpers;
fn main() {
// xfail-fast - check-fast doesn't understand aux-build
// aux-build:cci_iter_lib.rs
-use std;
use cci_iter_lib;
-import std::io;
-
fn main() {
//let bt0 = sys::rusti::frame_address(1u32);
//#debug["%?", bt0];
// xfail-fast - check-fast doesn't understand aux-build
// aux-build:cci_nested_lib.rs
-use std;
use cci_nested_lib;
-import std::io;
import cci_nested_lib::*;
fn main() {
// xfail-fast - check-fast doesn't understand aux-build
// aux-build:cci_no_inline_lib.rs
-use std;
use cci_no_inline_lib;
import cci_no_inline_lib::iter;
-import std::io;
-
fn main() {
// Check that a cross-crate call function not marked as inline
// does not, in fact, get inlined. Also, perhaps more
// Regression test that f64 exports things properly
-use std;
-import std::io::println;
+import io::println;
fn main() {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
native mod rustrt {
fn rust_dbg_call(cb: *u8,
- data: ctypes::uintptr_t) -> ctypes::uintptr_t;
+ data: libc::uintptr_t) -> libc::uintptr_t;
}
-crust fn cb(data: ctypes::uintptr_t) -> ctypes::uintptr_t {
+crust fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
if data == 1u {
data
} else {
#[abi = "cdecl"]
#[nolink]
native mod libc {
- fn write(fd: int, buf: *u8, count: ctypes::size_t) -> ctypes::ssize_t;
+ fn write(fd: int, buf: *u8,
+ count: core::libc::size_t) -> core::libc::ssize_t;
}
#[abi = "cdecl"]
use rustc;
import rustc::*;
-import std::io::*;
+import io::*;
import rustc::driver::diagnostic;
import rustc::syntax::ast;
fn check_pp<T>(expr: T, f: fn(pprust::ps, T), expect: str) {
let buf = mk_mem_buffer();
- let pp = pprust::rust_printer(buf as std::io::writer);
+ let pp = pprust::rust_printer(buf as io::writer);
f(pp, expr);
pp::eof(pp.s);
let str = mem_buffer_str(buf);
type sched_id = int;
type task_id = int;
-type task = *ctypes::void;
-type closure = *ctypes::void;
+type task = *libc::c_void;
+type closure = *libc::c_void;
native mod rustrt {
fn rust_new_sched(num_threads: uint) -> sched_id;
-use std;
-import std::os;
-
fn main() {
- let f = 1 as os::FILE;
+ let f = 1 as *libc::FILE;
log(debug, f as int);
log(debug, f as uint);
log(debug, f as i8);
log(debug, 1 as uint);
log(debug, 1 as float);
log(debug, 1 as bool);
- log(debug, 1 as os::FILE);
+ log(debug, 1 as *libc::FILE);
log(debug, 1 as i8);
log(debug, 1 as i16);
log(debug, 1 as i32);
log(debug, 1u as uint);
log(debug, 1u as float);
log(debug, 1u as bool);
- log(debug, 1u as os::FILE);
+ log(debug, 1u as *libc::FILE);
log(debug, 1u as i8);
log(debug, 1u as i16);
log(debug, 1u as i32);
log(debug, 1i8 as uint);
log(debug, 1i8 as float);
log(debug, 1i8 as bool);
- log(debug, 1i8 as os::FILE);
+ log(debug, 1i8 as *libc::FILE);
log(debug, 1i8 as i8);
log(debug, 1i8 as i16);
log(debug, 1i8 as i32);
log(debug, 1u8 as uint);
log(debug, 1u8 as float);
log(debug, 1u8 as bool);
- log(debug, 1u8 as os::FILE);
+ log(debug, 1u8 as *libc::FILE);
log(debug, 1u8 as i8);
log(debug, 1u8 as i16);
log(debug, 1u8 as i32);
log(debug, 1i16 as uint);
log(debug, 1i16 as float);
log(debug, 1i16 as bool);
- log(debug, 1i16 as os::FILE);
+ log(debug, 1i16 as *libc::FILE);
log(debug, 1i16 as i8);
log(debug, 1i16 as i16);
log(debug, 1i16 as i32);
log(debug, 1u16 as uint);
log(debug, 1u16 as float);
log(debug, 1u16 as bool);
- log(debug, 1u16 as os::FILE);
+ log(debug, 1u16 as *libc::FILE);
log(debug, 1u16 as i8);
log(debug, 1u16 as i16);
log(debug, 1u16 as i32);
log(debug, 1i32 as uint);
log(debug, 1i32 as float);
log(debug, 1i32 as bool);
- log(debug, 1i32 as os::FILE);
+ log(debug, 1i32 as *libc::FILE);
log(debug, 1i32 as i8);
log(debug, 1i32 as i16);
log(debug, 1i32 as i32);
log(debug, 1u32 as uint);
log(debug, 1u32 as float);
log(debug, 1u32 as bool);
- log(debug, 1u32 as os::FILE);
+ log(debug, 1u32 as *libc::FILE);
log(debug, 1u32 as i8);
log(debug, 1u32 as i16);
log(debug, 1u32 as i32);
log(debug, 1i64 as uint);
log(debug, 1i64 as float);
log(debug, 1i64 as bool);
- log(debug, 1i64 as os::FILE);
+ log(debug, 1i64 as *libc::FILE);
log(debug, 1i64 as i8);
log(debug, 1i64 as i16);
log(debug, 1i64 as i32);
log(debug, 1u64 as uint);
log(debug, 1u64 as float);
log(debug, 1u64 as bool);
- log(debug, 1u64 as os::FILE);
+ log(debug, 1u64 as *libc::FILE);
log(debug, 1u64 as i8);
log(debug, 1u64 as i16);
log(debug, 1u64 as i32);
log(debug, 1u64 as uint);
log(debug, 1u64 as float);
log(debug, 1u64 as bool);
- log(debug, 1u64 as os::FILE);
+ log(debug, 1u64 as *libc::FILE);
log(debug, 1u64 as i8);
log(debug, 1u64 as i16);
log(debug, 1u64 as i32);
log(debug, true as uint);
log(debug, true as float);
log(debug, true as bool);
- log(debug, true as os::FILE);
+ log(debug, true as *libc::FILE);
log(debug, true as i8);
log(debug, true as i16);
log(debug, true as i32);