Merge remote-tracking branch 'original/incoming' into incoming

Conflicts:
	src/libstd/json.rs
	src/libstd/sort.rs
This commit is contained in:
Simon BD 2012-10-03 21:47:09 -05:00
commit efcd2385ea
378 changed files with 11486 additions and 8500 deletions

View file

@ -24,6 +24,8 @@
#[allow(vecs_implicitly_copyable,
non_implicitly_copyable_typarams)];
#[allow(non_camel_case_types)];
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");

View file

@ -11,13 +11,14 @@ use syntax::diagnostic;
use result::{Ok, Err};
use io::WriterUtil;
use send_map::linear::LinearMap;
use std::{map, json, tempfile, term, sort, getopts};
use map::HashMap;
use to_str::to_str;
use getopts::{optflag, optopt, opt_present};
use dvec::DVec;
type package = {
struct Package {
name: ~str,
uuid: ~str,
url: ~str,
@ -26,10 +27,10 @@ type package = {
reference: Option<~str>,
tags: ~[~str],
versions: ~[(~str, ~str)]
};
}
impl package : cmp::Ord {
pure fn lt(other: &package) -> bool {
impl Package : cmp::Ord {
pure fn lt(other: &Package) -> bool {
if self.name.lt(&(*other).name) { return true; }
if (*other).name.lt(&self.name) { return false; }
if self.uuid.lt(&(*other).uuid) { return true; }
@ -45,28 +46,21 @@ impl package : cmp::Ord {
if self.versions.lt(&(*other).versions) { return true; }
return false;
}
pure fn le(other: &package) -> bool { !(*other).lt(&self) }
pure fn ge(other: &package) -> bool { !self.lt(other) }
pure fn gt(other: &package) -> bool { (*other).lt(&self) }
pure fn le(other: &Package) -> bool { !(*other).lt(&self) }
pure fn ge(other: &Package) -> bool { !self.lt(other) }
pure fn gt(other: &Package) -> bool { (*other).lt(&self) }
}
type local_package = {
name: ~str,
metaname: ~str,
version: ~str,
files: ~[~str]
};
type source = @{
struct Source {
name: ~str,
mut url: ~str,
mut method: ~str,
mut key: Option<~str>,
mut keyfp: Option<~str>,
packages: DVec<package>
};
packages: DVec<Package>
}
type cargo = {
struct Cargo {
pgp: bool,
root: Path,
installdir: Path,
@ -74,13 +68,13 @@ type cargo = {
libdir: Path,
workdir: Path,
sourcedir: Path,
sources: map::HashMap<~str, source>,
sources: map::HashMap<~str, @Source>,
mut current_install: ~str,
dep_cache: map::HashMap<~str, bool>,
opts: options
};
opts: Options
}
type crate = {
struct Crate {
name: ~str,
vers: ~str,
uuid: ~str,
@ -88,22 +82,22 @@ type crate = {
sigs: Option<~str>,
crate_type: Option<~str>,
deps: ~[~str]
};
}
type options = {
struct Options {
test: bool,
mode: mode,
mode: Mode,
free: ~[~str],
help: bool,
};
}
enum mode { system_mode, user_mode, local_mode }
enum Mode { SystemMode, UserMode, LocalMode }
impl mode : cmp::Eq {
pure fn eq(other: &mode) -> bool {
impl Mode : cmp::Eq {
pure fn eq(other: &Mode) -> bool {
(self as uint) == ((*other) as uint)
}
pure fn ne(other: &mode) -> bool { !self.eq(other) }
pure fn ne(other: &Mode) -> bool { !self.eq(other) }
}
fn opts() -> ~[getopts::Opt] {
@ -150,7 +144,7 @@ fn is_uuid(id: ~str) -> bool {
if vec::len(parts) == 5u {
let mut correct = 0u;
for vec::eachi(parts) |i, part| {
fn is_hex_digit(ch: char) -> bool {
fn is_hex_digit(+ch: char) -> bool {
('0' <= ch && ch <= '9') ||
('a' <= ch && ch <= 'f') ||
('A' <= ch && ch <= 'F')
@ -270,7 +264,7 @@ fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>,
(name, vers, uuid)
}
fn load_crate(filename: &Path) -> Option<crate> {
fn load_crate(filename: &Path) -> Option<Crate> {
let sess = parse::new_parse_sess(None);
let c = parse::parse_crate_from_crate_file(filename, ~[], sess);
@ -351,7 +345,7 @@ fn load_crate(filename: &Path) -> Option<crate> {
match *ps.interner.get(attr_name) {
~"std" | ~"core" => (),
_ => vec::push(e.deps, query)
_ => e.deps.push(query)
}
}
_ => ()
@ -375,7 +369,7 @@ fn load_crate(filename: &Path) -> Option<crate> {
match (name, vers, uuid) {
(Some(name0), Some(vers0), Some(uuid0)) => {
Some({
Some(Crate {
name: name0,
vers: vers0,
uuid: uuid0,
@ -407,8 +401,8 @@ fn need_dir(s: &Path) {
}
}
fn valid_pkg_name(s: ~str) -> bool {
fn is_valid_digit(c: char) -> bool {
fn valid_pkg_name(s: &str) -> bool {
fn is_valid_digit(+c: char) -> bool {
('0' <= c && c <= '9') ||
('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z') ||
@ -419,33 +413,33 @@ fn valid_pkg_name(s: ~str) -> bool {
s.all(is_valid_digit)
}
fn parse_source(name: ~str, j: json::Json) -> source {
fn parse_source(name: ~str, j: &json::Json) -> @Source {
if !valid_pkg_name(name) {
fail fmt!("'%s' is an invalid source name", name);
}
match j {
json::Dict(j) => {
let mut url = match j.find(~"url") {
Some(json::String(u)) => *u,
match *j {
json::Object(j) => {
let mut url = match j.find(&~"url") {
Some(json::String(u)) => u,
_ => fail ~"needed 'url' field in source"
};
let method = match j.find(~"method") {
Some(json::String(u)) => *u,
let method = match j.find(&~"method") {
Some(json::String(u)) => u,
_ => assume_source_method(url)
};
let key = match j.find(~"key") {
Some(json::String(u)) => Some(*u),
let key = match j.find(&~"key") {
Some(json::String(u)) => Some(u),
_ => None
};
let keyfp = match j.find(~"keyfp") {
Some(json::String(u)) => Some(*u),
let keyfp = match j.find(&~"keyfp") {
Some(json::String(u)) => Some(u),
_ => None
};
if method == ~"file" {
url = os::make_absolute(&Path(url)).to_str();
}
return @{
return @Source {
name: name,
mut url: url,
mut method: method,
@ -457,14 +451,14 @@ fn parse_source(name: ~str, j: json::Json) -> source {
};
}
fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, source>) {
fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, @Source>) {
if !os::path_exists(filename) { return; }
let c = io::read_whole_file_str(filename);
match json::from_str(result::get(c)) {
Ok(json::Dict(j)) => {
for j.each |k, v| {
sources.insert(k, parse_source(k, v));
debug!("source: %s", k);
match json::from_str(c.get()) {
Ok(json::Object(j)) => {
for j.each |k, v| {
sources.insert(copy *k, parse_source(*k, v));
debug!("source: %s", *k);
}
}
Ok(_) => fail ~"malformed sources.json",
@ -472,17 +466,17 @@ fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, source>) {
}
}
fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
let name = match p.find(~"name") {
fn load_one_source_package(src: @Source, p: &json::Object) {
let name = match p.find(&~"name") {
Some(json::String(n)) => {
if !valid_pkg_name(*n) {
if !valid_pkg_name(n) {
warn(~"malformed source json: "
+ src.name + ~", '" + *n + ~"'"+
+ src.name + ~", '" + n + ~"'"+
~" is an invalid name (alphanumeric, underscores and" +
~" dashes only)");
return;
}
*n
n
}
_ => {
warn(~"malformed source json: " + src.name + ~" (missing name)");
@ -490,15 +484,15 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
}
};
let uuid = match p.find(~"uuid") {
let uuid = match p.find(&~"uuid") {
Some(json::String(n)) => {
if !is_uuid(*n) {
if !is_uuid(n) {
warn(~"malformed source json: "
+ src.name + ~", '" + *n + ~"'"+
+ src.name + ~", '" + n + ~"'"+
~" is an invalid uuid");
return;
}
*n
n
}
_ => {
warn(~"malformed source json: " + src.name + ~" (missing uuid)");
@ -506,16 +500,16 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
}
};
let url = match p.find(~"url") {
Some(json::String(n)) => *n,
let url = match p.find(&~"url") {
Some(json::String(n)) => n,
_ => {
warn(~"malformed source json: " + src.name + ~" (missing url)");
return;
}
};
let method = match p.find(~"method") {
Some(json::String(n)) => *n,
let method = match p.find(&~"method") {
Some(json::String(n)) => n,
_ => {
warn(~"malformed source json: "
+ src.name + ~" (missing method)");
@ -523,17 +517,17 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
}
};
let reference = match p.find(~"ref") {
Some(json::String(n)) => Some(*n),
let reference = match p.find(&~"ref") {
Some(json::String(n)) => Some(n),
_ => None
};
let mut tags = ~[];
match p.find(~"tags") {
match p.find(&~"tags") {
Some(json::List(js)) => {
for (*js).each |j| {
for js.each |j| {
match *j {
json::String(j) => vec::grow(tags, 1u, *j),
json::String(ref j) => tags.grow(1u, j),
_ => ()
}
}
@ -541,8 +535,8 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
_ => ()
}
let description = match p.find(~"description") {
Some(json::String(n)) => *n,
let description = match p.find(&~"description") {
Some(json::String(n)) => n,
_ => {
warn(~"malformed source json: " + src.name
+ ~" (missing description)");
@ -550,7 +544,7 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
}
};
let newpkg = {
let newpkg = Package {
name: name,
uuid: uuid,
url: url,
@ -574,14 +568,14 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) {
log(debug, ~" loaded package: " + src.name + ~"/" + name);
}
fn load_source_info(c: &cargo, src: source) {
fn load_source_info(c: &Cargo, src: @Source) {
let dir = c.sourcedir.push(src.name);
let srcfile = dir.push("source.json");
if !os::path_exists(&srcfile) { return; }
let srcstr = io::read_whole_file_str(&srcfile);
match json::from_str(result::get(srcstr)) {
Ok(json::Dict(s)) => {
let o = parse_source(src.name, json::Dict(s));
match json::from_str(srcstr.get()) {
Ok(ref json @ json::Object(_)) => {
let o = parse_source(src.name, json);
src.key = o.key;
src.keyfp = o.keyfp;
@ -595,17 +589,17 @@ fn load_source_info(c: &cargo, src: source) {
}
};
}
fn load_source_packages(c: &cargo, src: source) {
fn load_source_packages(c: &Cargo, src: @Source) {
log(debug, ~"loading source: " + src.name);
let dir = c.sourcedir.push(src.name);
let pkgfile = dir.push("packages.json");
if !os::path_exists(&pkgfile) { return; }
let pkgstr = io::read_whole_file_str(&pkgfile);
match json::from_str(result::get(pkgstr)) {
match json::from_str(pkgstr.get()) {
Ok(json::List(js)) => {
for (*js).each |j| {
for js.each |j| {
match *j {
json::Dict(p) => {
json::Object(p) => {
load_one_source_package(src, p);
}
_ => {
@ -625,7 +619,7 @@ fn load_source_packages(c: &cargo, src: source) {
};
}
fn build_cargo_options(argv: ~[~str]) -> options {
fn build_cargo_options(argv: ~[~str]) -> Options {
let matches = match getopts::getopts(argv, opts()) {
result::Ok(m) => m,
result::Err(f) => {
@ -649,34 +643,34 @@ fn build_cargo_options(argv: ~[~str]) -> options {
}
let mode =
if (!is_install && !is_uninstall) || g { user_mode }
else if G { system_mode }
else { local_mode };
if (!is_install && !is_uninstall) || g { UserMode }
else if G { SystemMode }
else { LocalMode };
{test: test, mode: mode, free: matches.free, help: help}
Options {test: test, mode: mode, free: matches.free, help: help}
}
fn configure(opts: options) -> cargo {
fn configure(opts: Options) -> Cargo {
let home = match get_cargo_root() {
Ok(home) => home,
Err(_err) => result::get(get_cargo_sysroot())
Err(_err) => get_cargo_sysroot().get()
};
let get_cargo_dir = match opts.mode {
system_mode => get_cargo_sysroot,
user_mode => get_cargo_root,
local_mode => get_cargo_root_nearest
SystemMode => get_cargo_sysroot,
UserMode => get_cargo_root,
LocalMode => get_cargo_root_nearest
};
let p = result::get(get_cargo_dir());
let p = get_cargo_dir().get();
let sources = map::HashMap();
let sources = HashMap();
try_parse_sources(&home.push("sources.json"), sources);
try_parse_sources(&home.push("local-sources.json"), sources);
let dep_cache = map::HashMap();
let dep_cache = HashMap();
let mut c = {
let mut c = Cargo {
pgp: pgp::supported(),
root: home,
installdir: p,
@ -714,10 +708,10 @@ fn configure(opts: options) -> cargo {
c
}
fn for_each_package(c: &cargo, b: fn(source, package)) {
fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) {
for c.sources.each_value |v| {
for v.packages.each |p| {
b(v, *p);
b(v, p);
}
}
}
@ -748,7 +742,7 @@ fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path,
Some(buildpath)
}
fn test_one_crate(_c: &cargo, path: &Path, cf: &Path) {
fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) {
let buildpath = match run_in_buildpath(~"testing", path,
&Path("test"),
cf,
@ -759,7 +753,7 @@ fn test_one_crate(_c: &cargo, path: &Path, cf: &Path) {
run_programs(&buildpath);
}
fn install_one_crate(c: &cargo, path: &Path, cf: &Path) {
fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) {
let buildpath = match run_in_buildpath(~"installing", path,
&Path("build"),
cf, ~[]) {
@ -776,7 +770,7 @@ fn install_one_crate(c: &cargo, path: &Path, cf: &Path) {
~"lib")) {
debug!(" bin: %s", ct.to_str());
install_to_dir(*ct, &c.bindir);
if c.opts.mode == system_mode {
if c.opts.mode == SystemMode {
// FIXME (#2662): Put this file in PATH / symlink it so it can
// be used as a generic executable
// `cargo install -G rustray` and `rustray file.obj`
@ -800,14 +794,14 @@ fn rustc_sysroot() -> ~str {
}
}
fn install_source(c: &cargo, path: &Path) {
fn install_source(c: &Cargo, path: &Path) {
debug!("source: %s", path.to_str());
os::change_dir(path);
let mut cratefiles = ~[];
for os::walk_dir(&Path(".")) |p| {
if p.filetype() == Some(~".rc") {
vec::push(cratefiles, *p);
cratefiles.push(*p);
}
}
@ -839,7 +833,7 @@ fn install_source(c: &cargo, path: &Path) {
}
}
fn install_git(c: &cargo, wd: &Path, url: ~str, reference: Option<~str>) {
fn install_git(c: &Cargo, wd: &Path, url: ~str, reference: Option<~str>) {
run::program_output(~"git", ~[~"clone", url, wd.to_str()]);
if reference.is_some() {
let r = reference.get();
@ -850,7 +844,7 @@ fn install_git(c: &cargo, wd: &Path, url: ~str, reference: Option<~str>) {
install_source(c, wd);
}
fn install_curl(c: &cargo, wd: &Path, url: ~str) {
fn install_curl(c: &Cargo, wd: &Path, url: ~str) {
let tarpath = wd.push("pkg.tar");
let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o",
tarpath.to_str(), url]);
@ -863,14 +857,14 @@ fn install_curl(c: &cargo, wd: &Path, url: ~str) {
install_source(c, wd);
}
fn install_file(c: &cargo, wd: &Path, path: &Path) {
fn install_file(c: &Cargo, wd: &Path, path: &Path) {
run::program_output(~"tar", ~[~"-x", ~"--strip-components=1",
~"-C", wd.to_str(),
~"-f", path.to_str()]);
install_source(c, wd);
}
fn install_package(c: &cargo, src: ~str, wd: &Path, pkg: package) {
fn install_package(c: &Cargo, src: ~str, wd: &Path, pkg: Package) {
let url = copy pkg.url;
let method = match pkg.method {
~"git" => ~"git",
@ -883,12 +877,12 @@ fn install_package(c: &cargo, src: ~str, wd: &Path, pkg: package) {
match method {
~"git" => install_git(c, wd, url, copy pkg.reference),
~"file" => install_file(c, wd, &Path(url)),
~"curl" => install_curl(c, wd, copy url),
~"curl" => install_curl(c, wd, url),
_ => ()
}
}
fn cargo_suggestion(c: &cargo, fallback: fn())
fn cargo_suggestion(c: &Cargo, fallback: fn())
{
if c.sources.size() == 0u {
error(~"no sources defined - you may wish to run " +
@ -898,11 +892,11 @@ fn cargo_suggestion(c: &cargo, fallback: fn())
fallback();
}
fn install_uuid(c: &cargo, wd: &Path, uuid: ~str) {
fn install_uuid(c: &Cargo, wd: &Path, uuid: ~str) {
let mut ps = ~[];
for_each_package(c, |s, p| {
if p.uuid == uuid {
vec::grow(ps, 1u, (s.name, copy p));
vec::push(&mut ps, (s.name, copy *p));
}
});
if vec::len(ps) == 1u {
@ -922,11 +916,11 @@ fn install_uuid(c: &cargo, wd: &Path, uuid: ~str) {
}
}
fn install_named(c: &cargo, wd: &Path, name: ~str) {
fn install_named(c: &Cargo, wd: &Path, name: ~str) {
let mut ps = ~[];
for_each_package(c, |s, p| {
if p.name == name {
vec::grow(ps, 1u, (s.name, copy p));
vec::push(&mut ps, (s.name, copy *p));
}
});
if vec::len(ps) == 1u {
@ -946,7 +940,7 @@ fn install_named(c: &cargo, wd: &Path, name: ~str) {
}
}
fn install_uuid_specific(c: &cargo, wd: &Path, src: ~str, uuid: ~str) {
fn install_uuid_specific(c: &Cargo, wd: &Path, src: ~str, uuid: ~str) {
match c.sources.find(src) {
Some(s) => {
for s.packages.each |p| {
@ -961,7 +955,7 @@ fn install_uuid_specific(c: &cargo, wd: &Path, src: ~str, uuid: ~str) {
error(~"can't find package: " + src + ~"/" + uuid);
}
fn install_named_specific(c: &cargo, wd: &Path, src: ~str, name: ~str) {
fn install_named_specific(c: &Cargo, wd: &Path, src: ~str, name: ~str) {
match c.sources.find(src) {
Some(s) => {
for s.packages.each |p| {
@ -976,7 +970,7 @@ fn install_named_specific(c: &cargo, wd: &Path, src: ~str, name: ~str) {
error(~"can't find package: " + src + ~"/" + name);
}
fn cmd_uninstall(c: &cargo) {
fn cmd_uninstall(c: &Cargo) {
if vec::len(c.opts.free) < 3u {
cmd_usage();
return;
@ -1028,7 +1022,7 @@ fn cmd_uninstall(c: &cargo) {
}
}
fn install_query(c: &cargo, wd: &Path, target: ~str) {
fn install_query(c: &Cargo, wd: &Path, target: ~str) {
match c.dep_cache.find(target) {
Some(inst) => {
if inst {
@ -1088,7 +1082,7 @@ fn install_query(c: &cargo, wd: &Path, target: ~str) {
}
}
fn get_temp_workdir(c: &cargo) -> Path {
fn get_temp_workdir(c: &Cargo) -> Path {
match tempfile::mkdtemp(&c.workdir, "cargo") {
Some(wd) => wd,
None => fail fmt!("needed temp dir: %s",
@ -1096,7 +1090,7 @@ fn get_temp_workdir(c: &cargo) -> Path {
}
}
fn cmd_install(c: &cargo) unsafe {
fn cmd_install(c: &Cargo) unsafe {
let wd = get_temp_workdir(c);
if vec::len(c.opts.free) == 2u {
@ -1120,7 +1114,7 @@ fn cmd_install(c: &cargo) unsafe {
install_query(c, &wd, query);
}
fn sync(c: &cargo) {
fn sync(c: &Cargo) {
for c.sources.each_key |k| {
let mut s = c.sources.get(k);
sync_one(c, s);
@ -1128,7 +1122,7 @@ fn sync(c: &cargo) {
}
}
fn sync_one_file(c: &cargo, dir: &Path, src: source) -> bool {
fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool {
let name = src.name;
let srcfile = dir.push("source.json.new");
let destsrcfile = dir.push("source.json");
@ -1206,7 +1200,7 @@ fn sync_one_file(c: &cargo, dir: &Path, src: source) -> bool {
return true;
}
fn sync_one_git(c: &cargo, dir: &Path, src: source) -> bool {
fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool {
let name = src.name;
let srcfile = dir.push("source.json");
let pkgfile = dir.push("packages.json");
@ -1309,7 +1303,7 @@ fn sync_one_git(c: &cargo, dir: &Path, src: source) -> bool {
return true;
}
fn sync_one_curl(c: &cargo, dir: &Path, src: source) -> bool {
fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
let name = src.name;
let srcfile = dir.push("source.json.new");
let destsrcfile = dir.push("source.json");
@ -1425,7 +1419,7 @@ fn sync_one_curl(c: &cargo, dir: &Path, src: source) -> bool {
return true;
}
fn sync_one(c: &cargo, src: source) {
fn sync_one(c: &Cargo, src: @Source) {
let name = src.name;
let dir = c.sourcedir.push(name);
@ -1445,7 +1439,7 @@ fn sync_one(c: &cargo, src: source) {
}
}
fn cmd_init(c: &cargo) {
fn cmd_init(c: &Cargo) {
let srcurl = ~"http://www.rust-lang.org/cargo/sources.json";
let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig";
@ -1484,7 +1478,7 @@ fn cmd_init(c: &cargo) {
info(fmt!("initialized .cargo in %s", c.root.to_str()));
}
fn print_pkg(s: source, p: package) {
fn print_pkg(s: @Source, p: &Package) {
let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")";
if vec::len(p.tags) > 0u {
m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]";
@ -1495,7 +1489,7 @@ fn print_pkg(s: source, p: package) {
}
}
fn print_source(s: source) {
fn print_source(s: @Source) {
info(s.name + ~" (" + s.url + ~")");
let pks = sort::merge_sort(s.packages.get(), sys::shape_lt);
@ -1516,7 +1510,7 @@ fn print_source(s: source) {
}));
}
fn cmd_list(c: &cargo) {
fn cmd_list(c: &Cargo) {
sync(c);
if vec::len(c.opts.free) >= 3u {
@ -1542,7 +1536,7 @@ fn cmd_list(c: &cargo) {
}
}
fn cmd_search(c: &cargo) {
fn cmd_search(c: &Cargo) {
if vec::len(c.opts.free) < 3u {
cmd_usage();
return;
@ -1575,17 +1569,17 @@ fn install_to_dir(srcfile: &Path, destdir: &Path) {
}
}
fn dump_cache(c: &cargo) {
fn dump_cache(c: &Cargo) {
need_dir(&c.root);
let out = c.root.push("cache.json");
let _root = json::Dict(map::HashMap());
let _root = json::Object(~LinearMap());
if os::path_exists(&out) {
copy_warn(&out, &c.root.push("cache.json.old"));
}
}
fn dump_sources(c: &cargo) {
fn dump_sources(c: &Cargo) {
if c.sources.size() < 1u {
return;
}
@ -1600,33 +1594,31 @@ fn dump_sources(c: &cargo) {
match io::buffered_file_writer(&out) {
result::Ok(writer) => {
let hash = map::HashMap();
let root = json::Dict(hash);
let mut hash = ~LinearMap();
for c.sources.each |k, v| {
let chash = map::HashMap();
let child = json::Dict(chash);
for c.sources.each |k, v| {
let mut chash = ~LinearMap();
chash.insert(~"url", json::String(@v.url));
chash.insert(~"method", json::String(@v.method));
chash.insert(~"url", json::String(v.url));
chash.insert(~"method", json::String(v.method));
match copy v.key {
Some(key) => {
chash.insert(~"key", json::String(@key));
chash.insert(~"key", json::String(copy key));
}
_ => ()
}
match copy v.keyfp {
Some(keyfp) => {
chash.insert(~"keyfp", json::String(@keyfp));
chash.insert(~"keyfp", json::String(copy keyfp));
}
_ => ()
}
hash.insert(k, child);
hash.insert(copy k, json::Object(chash));
}
writer.write_str(json::to_str(root));
json::to_writer(writer, &json::Object(hash))
}
result::Err(e) => {
error(fmt!("could not dump sources: %s", e));
@ -1641,7 +1633,7 @@ fn copy_warn(srcfile: &Path, destfile: &Path) {
}
}
fn cmd_sources(c: &cargo) {
fn cmd_sources(c: &Cargo) {
if vec::len(c.opts.free) < 3u {
for c.sources.each_value |v| {
info(fmt!("%s (%s) via %s",
@ -1677,7 +1669,7 @@ fn cmd_sources(c: &cargo) {
if c.sources.contains_key(name) {
error(fmt!("source already exists: %s", name));
} else {
c.sources.insert(name, @{
c.sources.insert(name, @Source {
name: name,
mut url: url,
mut method: assume_source_method(url),

View file

@ -5,6 +5,8 @@
#[allow(vecs_implicitly_copyable)];
#[allow(non_camel_case_types)];
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");

View file

@ -58,7 +58,7 @@ fn parse_config(args: ~[~str]) -> config {
} else { option::None },
logfile: option::map(&getopts::opt_maybe_str(matches,
~"logfile"),
|s| Path(s)),
|s| Path(*s)),
runtool: getopts::opt_maybe_str(matches, ~"runtool"),
rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
jit: getopts::opt_present(matches, ~"jit"),
@ -141,7 +141,7 @@ fn make_tests(config: config) -> ~[test::TestDesc] {
let file = copy *file;
debug!("inspecting file %s", file.to_str());
if is_test(config, file) {
vec::push(tests, make_test(config, file))
tests.push(make_test(config, file))
}
}
return tests;

View file

@ -9,7 +9,7 @@ type expected_error = { line: uint, kind: ~str, msg: ~str };
// Load any test directives embedded in the file
fn load_errors(testfile: &Path) -> ~[expected_error] {
let mut error_patterns = ~[];
let rdr = result::get(io::file_reader(testfile));
let rdr = io::file_reader(testfile).get();
let mut line_num = 1u;
while !rdr.eof() {
let ln = rdr.read_line();

View file

@ -28,7 +28,7 @@ fn load_props(testfile: &Path) -> test_props {
let mut pp_exact = option::None;
for iter_header(testfile) |ln| {
match parse_error_pattern(ln) {
option::Some(ep) => vec::push(error_patterns, ep),
option::Some(ep) => error_patterns.push(ep),
option::None => ()
};
@ -41,11 +41,11 @@ fn load_props(testfile: &Path) -> test_props {
}
do parse_aux_build(ln).iter |ab| {
vec::push(aux_builds, ab);
aux_builds.push(*ab);
}
do parse_exec_env(ln).iter |ee| {
vec::push(exec_env, ee);
exec_env.push(*ee);
}
};
return {
@ -73,7 +73,7 @@ fn is_test_ignored(config: config, testfile: &Path) -> bool {
}
fn iter_header(testfile: &Path, it: fn(~str) -> bool) -> bool {
let rdr = result::get(io::file_reader(testfile));
let rdr = io::file_reader(testfile).get();
while !rdr.eof() {
let ln = rdr.read_line();
@ -103,7 +103,7 @@ fn parse_compile_flags(line: ~str) -> Option<~str> {
fn parse_exec_env(line: ~str) -> Option<(~str, ~str)> {
do parse_name_value_directive(line, ~"exec-env").map |nv| {
// nv is either FOO or FOO=BAR
let strs = str::splitn_char(nv, '=', 1u);
let strs = str::splitn_char(*nv, '=', 1u);
match strs.len() {
1u => (strs[0], ~""),
2u => (strs[0], strs[1]),

View file

@ -14,12 +14,12 @@ fn target_env(lib_path: ~str, prog: ~str) -> ~[(~str,~str)] {
let aux_path = prog.slice(0u, prog.len() - 4u) + ~".libaux";
env = do vec::map(env) |pair| {
let (k,v) = pair;
let (k,v) = *pair;
if k == ~"PATH" { (~"PATH", v + ~";" + lib_path + ~";" + aux_path) }
else { (k,v) }
};
if str::ends_with(prog, ~"rustc.exe") {
vec::push(env, (~"RUST_THREADS", ~"1"));
env.push((~"RUST_THREADS", ~"1"));
}
return env;
}

View file

@ -109,7 +109,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
let rounds =
match props.pp_exact { option::Some(_) => 1, option::None => 2 };
let mut srcs = ~[result::get(io::read_whole_file_str(testfile))];
let mut srcs = ~[io::read_whole_file_str(testfile).get()];
let mut round = 0;
while round < rounds {
@ -121,7 +121,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
procres);
}
vec::push(srcs, procres.stdout);
srcs.push(procres.stdout);
round += 1;
}
@ -129,7 +129,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) {
match props.pp_exact {
option::Some(file) => {
let filepath = testfile.dir_path().push_rel(&file);
result::get(io::read_whole_file_str(&filepath))
io::read_whole_file_str(&filepath).get()
}
option::None => { srcs[vec::len(srcs) - 2u] }
};
@ -503,10 +503,7 @@ fn make_run_args(config: config, _props: test_props, testfile: &Path) ->
fn split_maybe_args(argstr: Option<~str>) -> ~[~str] {
fn rm_whitespace(v: ~[~str]) -> ~[~str] {
fn flt(&&s: ~str) -> Option<~str> {
if !str::is_whitespace(s) { option::Some(s) } else { option::None }
}
vec::filter_map(v, flt)
vec::filter(v, |s| !str::is_whitespace(*s))
}
match argstr {
@ -561,8 +558,8 @@ fn dump_output(config: config, testfile: &Path, out: ~str, err: ~str) {
fn dump_output_file(config: config, testfile: &Path,
out: ~str, extension: ~str) {
let outfile = make_out_name(config, testfile, extension);
let writer = result::get(
io::file_writer(&outfile, ~[io::Create, io::Truncate]));
let writer =
io::file_writer(&outfile, ~[io::Create, io::Truncate]).get();
writer.write_str(out);
}

View file

@ -30,7 +30,7 @@ for t in os.listdir(run_pass):
"xfail-fast" in s or
"xfail-win32" in s):
stage2_tests.append(t)
if "main(args: ~[~str])" in s:
if "fn main(args:" in s or "fn main(++args:" in s:
take_args[t] = True
f.close()
@ -39,11 +39,13 @@ stage2_tests.sort()
c = open("tmp/run_pass_stage2.rc", "w")
i = 0
c.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
c.write("#[legacy_exports];\n")
c.write("#[link(name=\"run_pass_stage2\", vers=\"0.1\")];\n")
for t in stage2_tests:
p = os.path.join(run_pass, t)
p = p.replace("\\", "\\\\")
c.write("#[path = \"%s\"]" % p);
c.write("#[legacy_exports]");
c.write("mod t_%d;\n" % i)
i += 1
c.close()

View file

@ -70,7 +70,7 @@
"let" "log" "loop"
"move" "new"
"pure" "pub" "priv"
"return" "static"
"ref" "return" "static"
"unchecked" "unsafe"
"while"))
(puthash word t table))

View file

@ -62,7 +62,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint)
// Create a graph with no edges
range(0u, vlen) {|_i|
vec::push(v, empty_pointy());
v.push(empty_pointy());
}
// Fill in the graph with random edges, with density k/n
@ -77,7 +77,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint)
// https://github.com/mozilla/rust/issues/1899
if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
if (likelihood(r, k, n)) { vec::push(v[i].n, mut p(choice(r, v))); }
if (likelihood(r, k, n)) { v[i].n.push(mut p(choice(r, v))); }
if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
}

View file

@ -9,6 +9,8 @@
#[allow(vecs_implicitly_copyable)];
#[allow(non_camel_case_types)];
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");

View file

@ -19,7 +19,7 @@ impl test_mode : cmp::Eq {
fn write_file(filename: &Path, content: ~str) {
result::get(
io::file_writer(filename, ~[io::Create, io::Truncate]))
&io::file_writer(filename, ~[io::Create, io::Truncate]))
.write_str(content);
}
@ -30,7 +30,7 @@ fn contains(haystack: ~str, needle: ~str) -> bool {
fn find_rust_files(files: &mut ~[Path], path: &Path) {
if path.filetype() == Some(~".rs") && !contains(path.to_str(), ~"utf8") {
// ignoring "utf8" tests because something is broken
vec::push(*files, *path);
files.push(*path);
} else if os::path_is_dir(path)
&& !contains(path.to_str(), ~"compile-fail")
&& !contains(path.to_str(), ~"build") {
@ -124,7 +124,7 @@ fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool,
e: @ast::ty,
tm: test_mode) {
if c(e, tm) {
vec::push(*es,*e);
es.push(*e);
} else {/* now my indices are wrong :( */ }
}
@ -221,7 +221,7 @@ fn under(n: uint, it: fn(uint)) {
while i < n { it(i); i += 1u; }
}
fn as_str(f: fn@(io::Writer)) -> ~str {
fn as_str(f: fn@(+x: io::Writer)) -> ~str {
io::with_str_writer(f)
}
@ -229,7 +229,7 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
filename: &Path, cx: context) {
let stolen = steal(crate, cx.mode);
let extra_exprs = vec::filter(common_exprs(),
|a| safe_to_use_expr(a, cx.mode) );
|a| safe_to_use_expr(*a, cx.mode) );
check_variants_T(crate, codemap, filename, ~"expr",
extra_exprs + stolen.exprs, pprust::expr_to_str,
replace_expr_in_crate, cx);
@ -243,7 +243,7 @@ fn check_variants_T<T: Copy>(
filename: &Path,
thing_label: ~str,
things: ~[T],
stringifier: fn@(@T, syntax::parse::token::ident_interner) -> ~str,
stringifier: fn@(@T, @syntax::parse::token::ident_interner) -> ~str,
replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate,
cx: context
) {
@ -543,7 +543,7 @@ fn check_convergence(files: &[Path]) {
error!("pp convergence tests: %u files", vec::len(files));
for files.each |file| {
if !file_might_not_converge(file) {
let s = @result::get(io::read_whole_file_str(file));
let s = @result::get(&io::read_whole_file_str(file));
if !content_might_not_converge(*s) {
error!("pp converge: %s", file.to_str());
// Change from 7u to 2u once
@ -563,7 +563,7 @@ fn check_variants(files: &[Path], cx: context) {
loop;
}
let s = @result::get(io::read_whole_file_str(file));
let s = @result::get(&io::read_whole_file_str(file));
if contains(*s, ~"#") {
loop; // Macros are confusing
}

View file

@ -55,11 +55,11 @@ fn vec_edits<T: copy>(v: ~[T], xs: ~[T]) -> ~[~[T]] {
if Lv != 1u {
// When Lv == 1u, this is redundant with omit.
vec::push(edits, ~[]);
edits.push(~[]);
}
if Lv >= 3u {
// When Lv == 2u, this is redundant with swap.
vec::push(edits, vec::reversed(v));
edits.push(vec::reversed(v));
}
ix(0u, 1u, Lv) {|i| edits += ~[vec_omit(v, i)]; }
ix(0u, 1u, Lv) {|i| edits += ~[vec_dup(v, i)]; }
@ -69,10 +69,10 @@ fn vec_edits<T: copy>(v: ~[T], xs: ~[T]) -> ~[~[T]] {
ix(0u, 1u, len(xs)) {|j|
ix(0u, 1u, Lv) {|i|
vec::push(edits, vec_poke(v, i, xs[j]));
edits.push(vec_poke(v, i, xs[j]));
}
ix(0u, 0u, Lv) {|i|
vec::push(edits, vec_insert(v, i, xs[j]));
edits.push(vec_insert(v, i, xs[j]));
}
}

View file

@ -61,7 +61,7 @@ fn weighted_vec<T: copy>(v : ~[weighted<T>]) -> ~[T] {
for {weight: weight, item: item} in v {
let i = 0u;
while i < weight {
vec::push(r, item);
r.push(item);
i += 1u;
}
}

View file

@ -1,14 +1,11 @@
//! Managed vectors
use ptr::addr_of;
// NB: transitionary, de-mode-ing.
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
export init_op;
export capacity;
export build_sized, build, build_sized_opt;
export map;
export from_fn, from_elem;
export raw;
export traits;
use cast::transmute;
use ptr::addr_of;
/// Code for dealing with @-vectors. This is pretty incomplete, and
/// contains a bunch of duplication from the code for ~-vectors.
@ -29,10 +26,10 @@ extern mod rusti {
/// Returns the number of elements the vector can hold without reallocating
#[inline(always)]
pure fn capacity<T>(&&v: @[const T]) -> uint {
pub pure fn capacity<T>(v: @[const T]) -> uint {
unsafe {
let repr: **raw::VecRepr =
::cast::reinterpret_cast(&addr_of(v));
::cast::reinterpret_cast(&addr_of(&v));
(**repr).unboxed.alloc / sys::size_of::<T>()
}
}
@ -50,12 +47,12 @@ pure fn capacity<T>(&&v: @[const T]) -> uint {
* onto the vector being constructed.
*/
#[inline(always)]
pure fn build_sized<A>(size: uint,
builder: fn(push: pure fn(+v: A))) -> @[A] {
let mut vec = @[];
unsafe { raw::reserve(vec, size); }
builder(|+x| unsafe { raw::push(vec, move x) });
return vec;
pub pure fn build_sized<A>(size: uint,
builder: &fn(push: pure fn(v: A))) -> @[A] {
let mut vec: @[const A] = @[];
unsafe { raw::reserve(&mut vec, size); }
builder(|+x| unsafe { raw::push(&mut vec, move x) });
return unsafe { transmute(vec) };
}
/**
@ -69,7 +66,7 @@ pure fn build_sized<A>(size: uint,
* onto the vector being constructed.
*/
#[inline(always)]
pure fn build<A>(builder: fn(push: pure fn(+v: A))) -> @[A] {
pub pure fn build<A>(builder: &fn(push: pure fn(v: A))) -> @[A] {
build_sized(4, builder)
}
@ -86,14 +83,14 @@ pure fn build<A>(builder: fn(push: pure fn(+v: A))) -> @[A] {
* onto the vector being constructed.
*/
#[inline(always)]
pure fn build_sized_opt<A>(size: Option<uint>,
builder: fn(push: pure fn(+v: A))) -> @[A] {
pub pure fn build_sized_opt<A>(size: Option<uint>,
builder: &fn(push: pure fn(v: A))) -> @[A] {
build_sized(size.get_default(4), builder)
}
// Appending
#[inline(always)]
pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
pub pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
do build_sized(lhs.len() + rhs.len()) |push| {
for vec::each(lhs) |x| { push(*x); }
for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
@ -102,10 +99,10 @@ pure fn append<T: Copy>(lhs: @[T], rhs: &[const T]) -> @[T] {
/// Apply a function to each element of a vector and return the results
pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
pub pure fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] {
do build_sized(v.len()) |push| {
for vec::each(v) |elem| {
push(f(*elem));
push(f(elem));
}
}
}
@ -116,7 +113,7 @@ pure fn map<T, U>(v: &[T], f: fn(T) -> U) -> @[U] {
* Creates an immutable vector of size `n_elts` and initializes the elements
* to the value returned by the function `op`.
*/
pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] {
pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] {
do build_sized(n_elts) |push| {
let mut i: uint = 0u;
while i < n_elts { push(op(i)); i += 1u; }
@ -129,17 +126,17 @@ pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] {
* Creates an immutable vector of size `n_elts` and initializes the elements
* to the value `t`.
*/
pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
pub pure fn from_elem<T: Copy>(n_elts: uint, t: T) -> @[T] {
do build_sized(n_elts) |push| {
let mut i: uint = 0u;
while i < n_elts { push(t); i += 1u; }
while i < n_elts { push(copy t); i += 1u; }
}
}
#[cfg(notest)]
mod traits {
pub mod traits {
#[legacy_exports];
impl<T: Copy> @[T] : Add<&[const T],@[T]> {
pub impl<T: Copy> @[T] : Add<&[const T],@[T]> {
#[inline(always)]
pure fn add(rhs: & &[const T]) -> @[T] {
append(self, (*rhs))
@ -148,13 +145,12 @@ mod traits {
}
#[cfg(test)]
mod traits {
pub mod traits {
#[legacy_exports];}
mod raw {
#[legacy_exports];
type VecRepr = vec::raw::VecRepr;
type SliceRepr = vec::raw::SliceRepr;
pub mod raw {
pub type VecRepr = vec::raw::VecRepr;
pub type SliceRepr = vec::raw::SliceRepr;
/**
* Sets the length of a vector
@ -164,14 +160,14 @@ mod raw {
* the vector is actually the specified size.
*/
#[inline(always)]
unsafe fn set_len<T>(&&v: @[const T], new_len: uint) {
let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
pub unsafe fn set_len<T>(v: @[const T], new_len: uint) {
let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(&v));
(**repr).unboxed.fill = new_len * sys::size_of::<T>();
}
#[inline(always)]
unsafe fn push<T>(&v: @[const T], +initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
pub unsafe fn push<T>(v: &mut @[const T], initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc > fill {
push_fast(v, move initval);
@ -182,16 +178,16 @@ mod raw {
}
// This doesn't bother to make sure we have space.
#[inline(always)] // really pretty please
unsafe fn push_fast<T>(&v: @[const T], +initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v));
pub unsafe fn push_fast<T>(v: &mut @[const T], initval: T) {
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::size_of::<T>();
let p = ptr::addr_of((**repr).unboxed.data);
let p = addr_of(&((**repr).unboxed.data));
let p = ptr::offset(p, fill) as *mut T;
rusti::move_val_init(*p, move initval);
}
unsafe fn push_slow<T>(&v: @[const T], +initval: T) {
pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
reserve_at_least(v, v.len() + 1u);
push_fast(v, move initval);
}
@ -207,10 +203,10 @@ mod raw {
* * v - A vector
* * n - The number of elements to reserve space for
*/
unsafe fn reserve<T>(&v: @[const T], n: uint) {
pub unsafe fn reserve<T>(v: &mut @[const T], n: uint) {
// Only make the (slow) call into the runtime if we have to
if capacity(v) < n {
let ptr = addr_of(v) as **VecRepr;
if capacity(*v) < n {
let ptr: **VecRepr = transmute(copy v);
rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
ptr, n as libc::size_t);
}
@ -231,14 +227,14 @@ mod raw {
* * v - A vector
* * n - The number of elements to reserve space for
*/
unsafe fn reserve_at_least<T>(&v: @[const T], n: uint) {
pub unsafe fn reserve_at_least<T>(v: &mut @[const T], n: uint) {
reserve(v, uint::next_power_of_two(n));
}
}
#[test]
fn test() {
pub fn test() {
// Some code that could use that, then:
fn seq_range(lo: uint, hi: uint) -> @[uint] {
do build |push| {
@ -254,7 +250,6 @@ fn test() {
}
#[test]
fn append_test() {
pub fn append_test() {
assert @[1,2,3] + @[4,5,6] == @[1,2,3,4,5,6];
}

View file

@ -8,43 +8,39 @@
use cmp::Eq;
export not, and, or, xor, implies;
export eq, ne, is_true, is_false;
export from_str, to_str, all_values, to_bit;
/// Negation / inverse
pure fn not(v: bool) -> bool { !v }
pub pure fn not(v: bool) -> bool { !v }
/// Conjunction
pure fn and(a: bool, b: bool) -> bool { a && b }
pub pure fn and(a: bool, b: bool) -> bool { a && b }
/// Disjunction
pure fn or(a: bool, b: bool) -> bool { a || b }
pub pure fn or(a: bool, b: bool) -> bool { a || b }
/**
* Exclusive or
*
* Identical to `or(and(a, not(b)), and(not(a), b))`
*/
pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) }
pub pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) }
/// Implication in the logic, i.e. from `a` follows `b`
pure fn implies(a: bool, b: bool) -> bool { !a || b }
pub pure fn implies(a: bool, b: bool) -> bool { !a || b }
/// true if truth values `a` and `b` are indistinguishable in the logic
pure fn eq(a: bool, b: bool) -> bool { a == b }
pub pure fn eq(a: bool, b: bool) -> bool { a == b }
/// true if truth values `a` and `b` are distinguishable in the logic
pure fn ne(a: bool, b: bool) -> bool { a != b }
pub pure fn ne(a: bool, b: bool) -> bool { a != b }
/// true if `v` represents truth in the logic
pure fn is_true(v: bool) -> bool { v }
pub pure fn is_true(v: bool) -> bool { v }
/// true if `v` represents falsehood in the logic
pure fn is_false(v: bool) -> bool { !v }
pub pure fn is_false(v: bool) -> bool { !v }
/// Parse logic value from `s`
pure fn from_str(s: &str) -> Option<bool> {
pub pure fn from_str(s: &str) -> Option<bool> {
if s == "true" {
Some(true)
} else if s == "false" {
@ -55,19 +51,19 @@ pure fn from_str(s: &str) -> Option<bool> {
}
/// Convert `v` into a string
pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } }
pub pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } }
/**
* Iterates over all truth values by passing them to `blk` in an unspecified
* order
*/
fn all_values(blk: fn(v: bool)) {
pub fn all_values(blk: fn(v: bool)) {
blk(true);
blk(false);
}
/// converts truth value to an 8 bit byte
pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
pub pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
impl bool : cmp::Eq {
pure fn eq(other: &bool) -> bool { self == (*other) }
@ -75,20 +71,20 @@ impl bool : cmp::Eq {
}
#[test]
fn test_bool_from_str() {
pub fn test_bool_from_str() {
do all_values |v| {
assert Some(v) == from_str(bool::to_str(v))
}
}
#[test]
fn test_bool_to_str() {
pub fn test_bool_to_str() {
assert to_str(false) == ~"false";
assert to_str(true) == ~"true";
}
#[test]
fn test_bool_to_bit() {
pub fn test_bool_to_bit() {
do all_values |v| {
assert to_bit(v) == if is_true(v) { 1u8 } else { 0u8 };
}

View file

@ -7,28 +7,24 @@
use cmp::{Eq, Ord};
use intrinsic::TyDesc;
export ptr_eq, raw;
mod raw {
#[legacy_exports];
struct BoxHeaderRepr {
pub mod raw {
pub struct BoxHeaderRepr {
ref_count: uint,
type_desc: *TyDesc,
prev: *BoxRepr,
next: *BoxRepr,
}
struct BoxRepr {
pub struct BoxRepr {
header: BoxHeaderRepr,
data: u8
}
}
pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
pub pure fn ptr_eq<T>(a: @T, b: @T) -> bool {
//! Determine if two shared boxes point to the same object
unsafe { ptr::addr_of(*a) == ptr::addr_of(*b) }
unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) }
}
impl<T:Eq> @const T : Eq {

View file

@ -1,21 +1,14 @@
//! Unsafe operations
export reinterpret_cast, forget, bump_box_refcount, transmute;
export transmute_mut, transmute_immut, transmute_region, transmute_mut_region;
export transmute_mut_unsafe, transmute_immut_unsafe;
export copy_lifetime, copy_lifetime_vec;
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn forget<T>(-x: T);
fn reinterpret_cast<T, U>(e: T) -> U;
fn reinterpret_cast<T, U>(&&e: T) -> U;
}
/// Casts the value at `src` to U. The two types must have the same length.
#[inline(always)]
unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
rusti::reinterpret_cast(*src)
}
@ -28,7 +21,7 @@ unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
* reinterpret_cast on managed pointer types.
*/
#[inline(always)]
unsafe fn forget<T>(-thing: T) { rusti::forget(move thing); }
pub unsafe fn forget<T>(thing: T) { rusti::forget(move thing); }
/**
* Force-increment the reference count on a shared box. If used
@ -36,7 +29,7 @@ unsafe fn forget<T>(-thing: T) { rusti::forget(move thing); }
* and/or reinterpret_cast when such calls would otherwise scramble a box's
* reference count
*/
unsafe fn bump_box_refcount<T>(+t: @T) { forget(move t); }
pub unsafe fn bump_box_refcount<T>(t: @T) { forget(move t); }
/**
* Transform a value of one type into a value of another type.
@ -47,7 +40,7 @@ unsafe fn bump_box_refcount<T>(+t: @T) { forget(move t); }
* assert transmute("L") == ~[76u8, 0u8];
*/
#[inline(always)]
unsafe fn transmute<L, G>(-thing: L) -> G {
pub unsafe fn transmute<L, G>(thing: L) -> G {
let newthing: G = reinterpret_cast(&thing);
forget(move thing);
move newthing
@ -55,39 +48,45 @@ unsafe fn transmute<L, G>(-thing: L) -> G {
/// Coerce an immutable reference to be mutable.
#[inline(always)]
unsafe fn transmute_mut<T>(+ptr: &a/T) -> &a/mut T { transmute(move ptr) }
pub unsafe fn transmute_mut<T>(ptr: &a/T) -> &a/mut T { transmute(move ptr) }
/// Coerce a mutable reference to be immutable.
#[inline(always)]
unsafe fn transmute_immut<T>(+ptr: &a/mut T) -> &a/T { transmute(move ptr) }
pub unsafe fn transmute_immut<T>(ptr: &a/mut T) -> &a/T {
transmute(move ptr)
}
/// Coerce a borrowed pointer to have an arbitrary associated region.
#[inline(always)]
unsafe fn transmute_region<T>(+ptr: &a/T) -> &b/T { transmute(move ptr) }
pub unsafe fn transmute_region<T>(ptr: &a/T) -> &b/T { transmute(move ptr) }
/// Coerce an immutable reference to be mutable.
#[inline(always)]
unsafe fn transmute_mut_unsafe<T>(+ptr: *const T) -> *mut T { transmute(ptr) }
pub unsafe fn transmute_mut_unsafe<T>(ptr: *const T) -> *mut T {
transmute(ptr)
}
/// Coerce an immutable reference to be mutable.
#[inline(always)]
unsafe fn transmute_immut_unsafe<T>(+ptr: *const T) -> *T { transmute(ptr) }
pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T {
transmute(ptr)
}
/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
#[inline(always)]
unsafe fn transmute_mut_region<T>(+ptr: &a/mut T) -> &b/mut T {
pub unsafe fn transmute_mut_region<T>(ptr: &a/mut T) -> &b/mut T {
transmute(move ptr)
}
/// Transforms lifetime of the second pointer to match the first.
#[inline(always)]
unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
pub unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
transmute_region(ptr)
}
/// Transforms lifetime of the second pointer to match the first.
#[inline(always)]
unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
pub unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
transmute_region(ptr)
}
@ -97,16 +96,14 @@ unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
****************************************************************************/
#[cfg(test)]
mod tests {
#[legacy_exports];
pub mod tests {
#[test]
fn test_reinterpret_cast() {
pub fn test_reinterpret_cast() {
assert 1u == unsafe { reinterpret_cast(&1) };
}
#[test]
fn test_bump_box_refcount() {
pub fn test_bump_box_refcount() {
unsafe {
let box = @~"box box box"; // refcount 1
bump_box_refcount(box); // refcount 2
@ -121,7 +118,7 @@ mod tests {
}
#[test]
fn test_transmute() {
pub fn test_transmute() {
unsafe {
let x = @1;
let x: *int = transmute(x);
@ -131,7 +128,7 @@ mod tests {
}
#[test]
fn test_transmute2() {
pub fn test_transmute2() {
unsafe {
assert ~[76u8, 0u8] == transmute(~"L");
}

View file

@ -39,24 +39,16 @@ use cmp::Eq;
Cn Unassigned a reserved unassigned code point or a noncharacter
*/
export is_alphabetic,
is_XID_start, is_XID_continue,
is_lowercase, is_uppercase,
is_whitespace, is_alphanumeric,
is_ascii, is_digit,
to_digit, cmp,
escape_default, escape_unicode;
use is_alphabetic = unicode::derived_property::Alphabetic;
use is_XID_start = unicode::derived_property::XID_Start;
use is_XID_continue = unicode::derived_property::XID_Continue;
pub use is_alphabetic = unicode::derived_property::Alphabetic;
pub use is_XID_start = unicode::derived_property::XID_Start;
pub use is_XID_continue = unicode::derived_property::XID_Continue;
/**
* Indicates whether a character is in lower case, defined
* in terms of the Unicode General Category 'Ll'
*/
pure fn is_lowercase(c: char) -> bool {
pub pure fn is_lowercase(c: char) -> bool {
return unicode::general_category::Ll(c);
}
@ -64,7 +56,7 @@ pure fn is_lowercase(c: char) -> bool {
* Indicates whether a character is in upper case, defined
* in terms of the Unicode General Category 'Lu'.
*/
pure fn is_uppercase(c: char) -> bool {
pub pure fn is_uppercase(c: char) -> bool {
return unicode::general_category::Lu(c);
}
@ -73,7 +65,7 @@ pure fn is_uppercase(c: char) -> bool {
* terms of the Unicode General Categories 'Zs', 'Zl', 'Zp'
* additional 'Cc'-category control codes in the range [0x09, 0x0d]
*/
pure fn is_whitespace(c: char) -> bool {
pub pure fn is_whitespace(c: char) -> bool {
return ('\x09' <= c && c <= '\x0d')
|| unicode::general_category::Zs(c)
|| unicode::general_category::Zl(c)
@ -85,7 +77,7 @@ pure fn is_whitespace(c: char) -> bool {
* defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No'
* and the Derived Core Property 'Alphabetic'.
*/
pure fn is_alphanumeric(c: char) -> bool {
pub pure fn is_alphanumeric(c: char) -> bool {
return unicode::derived_property::Alphabetic(c) ||
unicode::general_category::Nd(c) ||
unicode::general_category::Nl(c) ||
@ -93,12 +85,12 @@ pure fn is_alphanumeric(c: char) -> bool {
}
/// Indicates whether the character is an ASCII character
pure fn is_ascii(c: char) -> bool {
pub pure fn is_ascii(c: char) -> bool {
c - ('\x7F' & c) == '\x00'
}
/// Indicates whether the character is numeric (Nd, Nl, or No)
pure fn is_digit(c: char) -> bool {
pub pure fn is_digit(c: char) -> bool {
return unicode::general_category::Nd(c) ||
unicode::general_category::Nl(c) ||
unicode::general_category::No(c);
@ -114,7 +106,7 @@ pure fn is_digit(c: char) -> bool {
* 'b' or 'B', 11, etc. Returns none if the char does not
* refer to a digit in the given radix.
*/
pure fn to_digit(c: char, radix: uint) -> Option<uint> {
pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
let val = match c {
'0' .. '9' => c as uint - ('0' as uint),
'a' .. 'z' => c as uint + 10u - ('a' as uint),
@ -134,7 +126,7 @@ pure fn to_digit(c: char, radix: uint) -> Option<uint> {
* - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN`
* - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN`
*/
fn escape_unicode(c: char) -> ~str {
pub fn escape_unicode(c: char) -> ~str {
let s = u32::to_str(c as u32, 16u);
let (c, pad) = (if c <= '\xff' { ('x', 2u) }
else if c <= '\uffff' { ('u', 4u) }
@ -159,7 +151,7 @@ fn escape_unicode(c: char) -> ~str {
* - Any other chars in the range [0x20,0x7e] are not escaped.
* - Any other chars are given hex unicode escapes; see `escape_unicode`.
*/
fn escape_default(c: char) -> ~str {
pub fn escape_default(c: char) -> ~str {
match c {
'\t' => ~"\\t",
'\r' => ~"\\r",
@ -179,7 +171,7 @@ fn escape_default(c: char) -> ~str {
*
* -1 if a < b, 0 if a == b, +1 if a > b
*/
pure fn cmp(a: char, b: char) -> int {
pub pure fn cmp(a: char, b: char) -> int {
return if b > a { -1 }
else if b < a { 1 }
else { 0 }

View file

@ -10,8 +10,6 @@ use repr::BoxRepr;
use sys::TypeDesc;
use cast::transmute;
export annihilate;
/**
* Runtime structures
*

View file

@ -3,10 +3,6 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// uncomment once #1433 is fixed
// FIXME (#1433): export c_float_math_consts;
// FIXME (#1433): export c_double_math_consts;
use libc::c_int;
use libc::c_float;
use libc::c_double;
@ -193,66 +189,62 @@ pub mod c_double_targ_consts {
FIXME use these once they can be parsed (see Issue #1433)
mod c_float_math_consts {
#[legacy_exports];
const pi: c_float = 0x1.921fb6p+1_f32;
const div_1_pi: c_float = 0x1.45f306p-2_f32;
const div_2_pi: c_float = 0x1.45f306p-1_f32;
const div_pi_2: c_float = 0x1.921fb6p+0_f32;
const div_pi_4: c_float = 0x1.921fb6p-1_f32;
const div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32;
const e: c_float = 0x1.5bf0a8p+1_f32;
const log2_e: c_float = 0x1.715476p+0_f32;
const log10_e: c_float = 0x1.bcb7b2p-2_f32;
const ln_2: c_float = 0x1.62e43p-1_f32;
const ln_10: c_float = 0x1.26bb1cp+1_f32;
const sqrt2: c_float = 0x1.6a09e6p+0_f32;
const div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32;
pub mod c_float_math_consts {
pub const pi: c_float = 0x1.921fb6p+1_f32;
pub const div_1_pi: c_float = 0x1.45f306p-2_f32;
pub const div_2_pi: c_float = 0x1.45f306p-1_f32;
pub const div_pi_2: c_float = 0x1.921fb6p+0_f32;
pub const div_pi_4: c_float = 0x1.921fb6p-1_f32;
pub const div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32;
pub const e: c_float = 0x1.5bf0a8p+1_f32;
pub const log2_e: c_float = 0x1.715476p+0_f32;
pub const log10_e: c_float = 0x1.bcb7b2p-2_f32;
pub const ln_2: c_float = 0x1.62e43p-1_f32;
pub const ln_10: c_float = 0x1.26bb1cp+1_f32;
pub const sqrt2: c_float = 0x1.6a09e6p+0_f32;
pub const div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32;
}
mod c_double_math_consts {
#[legacy_exports];
const pi: c_double = 0x1.921fb54442d18p+1_f64;
const div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64;
const div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64;
const div_pi_2: c_double = 0x1.921fb54442d18p+0_f64;
const div_pi_4: c_double = 0x1.921fb54442d18p-1_f64;
const div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64;
const e: c_double = 0x1.5bf0a8b145769p+1_f64;
const log2_e: c_double = 0x1.71547652b82fep+0_f64;
const log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64;
const ln_2: c_double = 0x1.62e42fefa39efp-1_f64;
const ln_10: c_double = 0x1.26bb1bbb55516p+1_f64;
const sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64;
const div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64;
pub mod c_double_math_consts {
pub const pi: c_double = 0x1.921fb54442d18p+1_f64;
pub const div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64;
pub const div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64;
pub const div_pi_2: c_double = 0x1.921fb54442d18p+0_f64;
pub const div_pi_4: c_double = 0x1.921fb54442d18p-1_f64;
pub const div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64;
pub const e: c_double = 0x1.5bf0a8b145769p+1_f64;
pub const log2_e: c_double = 0x1.71547652b82fep+0_f64;
pub const log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64;
pub const ln_2: c_double = 0x1.62e42fefa39efp-1_f64;
pub const ln_10: c_double = 0x1.26bb1bbb55516p+1_f64;
pub const sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64;
pub const div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64;
}
mod c_float_targ_consts {
#[legacy_exports];
const radix: uint = 2u;
const mantissa_digits: uint = 24u;
const digits: uint = 6u;
const min_exp: int = -125;
const max_exp: int = 128;
const min_10_exp: int = -37;
const max_10_exp: int = 38;
const min_value: c_float = 0x1p-126_f32;
const max_value: c_float = 0x1.fffffep+127_f32;
const epsilon: c_float = 0x1p-23_f32;
pub mod c_float_targ_consts {
pub const radix: uint = 2u;
pub const mantissa_digits: uint = 24u;
pub const digits: uint = 6u;
pub const min_exp: int = -125;
pub const max_exp: int = 128;
pub const min_10_exp: int = -37;
pub const max_10_exp: int = 38;
pub const min_value: c_float = 0x1p-126_f32;
pub const max_value: c_float = 0x1.fffffep+127_f32;
pub const epsilon: c_float = 0x1p-23_f32;
}
mod c_double_targ_consts {
#[legacy_exports];
const radix: uint = 2u;
const mantissa_digits: uint = 53u;
const digits: uint = 15u;
const min_exp: int = -1021;
const max_exp: int = 1024;
const min_10_exp: int = -307;
const max_10_exp: int = 308;
const min_value: c_double = 0x1p-1022_f64;
const max_value: c_double = 0x1.fffffffffffffp+1023_f64;
const epsilon: c_double = 0x1p-52_f64;
pub mod c_double_targ_consts {
pub const radix: uint = 2u;
pub const mantissa_digits: uint = 53u;
pub const digits: uint = 15u;
pub const min_exp: int = -1021;
pub const max_exp: int = 1024;
pub const min_10_exp: int = -307;
pub const max_10_exp: int = 308;
pub const min_value: c_double = 0x1p-1022_f64;
pub const max_value: c_double = 0x1.fffffffffffffp+1023_f64;
pub const epsilon: c_double = 0x1p-52_f64;
}
*/

View file

@ -14,17 +14,14 @@ and `Eq` to overload the `==` and `!=` operators.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use nounittest::*;
use unittest::*;
export Ord;
export Eq;
pub use nounittest::*;
pub use unittest::*;
/// Interfaces used for comparison.
// Awful hack to work around duplicate lang items in core test.
#[cfg(notest)]
mod nounittest {
#[legacy_exports];
/**
* Trait for values that can be compared for a sort-order.
*
@ -33,7 +30,7 @@ mod nounittest {
* default implementations.
*/
#[lang="ord"]
trait Ord {
pub trait Ord {
pure fn lt(other: &self) -> bool;
pure fn le(other: &self) -> bool;
pure fn ge(other: &self) -> bool;
@ -50,7 +47,7 @@ mod nounittest {
* a default implementation.
*/
#[lang="eq"]
trait Eq {
pub trait Eq {
pure fn eq(other: &self) -> bool;
pure fn ne(other: &self) -> bool;
}
@ -63,14 +60,14 @@ mod nounittest {
#[cfg(test)]
mod unittest {
#[legacy_exports];
trait Ord {
pub trait Ord {
pure fn lt(other: &self) -> bool;
pure fn le(other: &self) -> bool;
pure fn ge(other: &self) -> bool;
pure fn gt(other: &self) -> bool;
}
trait Eq {
pub trait Eq {
pure fn eq(other: &self) -> bool;
pure fn ne(other: &self) -> bool;
}
@ -80,27 +77,27 @@ mod unittest {
mod unittest {
#[legacy_exports];}
pure fn lt<T: Ord>(v1: &T, v2: &T) -> bool {
pub pure fn lt<T: Ord>(v1: &T, v2: &T) -> bool {
(*v1).lt(v2)
}
pure fn le<T: Ord Eq>(v1: &T, v2: &T) -> bool {
pub pure fn le<T: Ord Eq>(v1: &T, v2: &T) -> bool {
(*v1).lt(v2) || (*v1).eq(v2)
}
pure fn eq<T: Eq>(v1: &T, v2: &T) -> bool {
pub pure fn eq<T: Eq>(v1: &T, v2: &T) -> bool {
(*v1).eq(v2)
}
pure fn ne<T: Eq>(v1: &T, v2: &T) -> bool {
pub pure fn ne<T: Eq>(v1: &T, v2: &T) -> bool {
(*v1).ne(v2)
}
pure fn ge<T: Ord>(v1: &T, v2: &T) -> bool {
pub pure fn ge<T: Ord>(v1: &T, v2: &T) -> bool {
(*v1).ge(v2)
}
pure fn gt<T: Ord>(v1: &T, v2: &T) -> bool {
pub pure fn gt<T: Ord>(v1: &T, v2: &T) -> bool {
(*v1).gt(v2)
}

View file

@ -32,14 +32,13 @@ will once again be the preferred module for intertask communication.
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// NB: transitionary, de-mode-ing
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use either::Either;
use libc::size_t;
// After snapshot, change p2::addr_of => addr_of
/**
* A communication endpoint that can receive messages
@ -76,7 +75,7 @@ pub fn Port<T: Send>() -> Port<T> {
impl<T: Send> Port<T> {
fn chan() -> Chan<T> { Chan(self) }
fn send(+v: T) { self.chan().send(move v) }
fn send(v: T) { self.chan().send(move v) }
fn recv() -> T { recv(self) }
fn peek() -> bool { peek(self) }
@ -85,7 +84,7 @@ impl<T: Send> Port<T> {
impl<T: Send> Chan<T> {
fn chan() -> Chan<T> { self }
fn send(+v: T) { send(self, move v) }
fn send(v: T) { send(self, move v) }
fn recv() -> T { recv_chan(self) }
fn peek() -> bool { peek_chan(self) }
@ -104,7 +103,7 @@ struct PortPtr<T:Send> {
// Once the port is detached it's guaranteed not to receive further
// messages
let yield = 0;
let yieldp = ptr::addr_of(yield);
let yieldp = ptr::addr_of(&yield);
rustrt::rust_port_begin_detach(self.po, yieldp);
if yield != 0 {
// Need to wait for the port to be detached
@ -167,7 +166,7 @@ fn as_raw_port<T: Send, U>(ch: comm::Chan<T>, f: fn(*rust_port) -> U) -> U {
* Constructs a channel. The channel is bound to the port used to
* construct it.
*/
pub fn Chan<T: Send>(p: Port<T>) -> Chan<T> {
pub fn Chan<T: Send>(&&p: Port<T>) -> Chan<T> {
Chan_(rustrt::get_port_id((**p).po))
}
@ -175,9 +174,9 @@ pub fn Chan<T: Send>(p: Port<T>) -> Chan<T> {
* Sends data over a channel. The sent data is moved into the channel,
* whereupon the caller loses access to it.
*/
pub fn send<T: Send>(ch: Chan<T>, +data: T) {
pub fn send<T: Send>(ch: Chan<T>, data: T) {
let Chan_(p) = ch;
let data_ptr = ptr::addr_of(data) as *();
let data_ptr = ptr::addr_of(&data) as *();
let res = rustrt::rust_port_id_send(p, data_ptr);
if res != 0 unsafe {
// Data sent successfully
@ -207,10 +206,10 @@ fn peek_chan<T: Send>(ch: comm::Chan<T>) -> bool {
/// Receive on a raw port pointer
fn recv_<T: Send>(p: *rust_port) -> T {
let yield = 0;
let yieldp = ptr::addr_of(yield);
let yieldp = ptr::addr_of(&yield);
let mut res;
res = rusti::init::<T>();
rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);
rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp);
if yield != 0 {
// Data isn't available yet, so res has not been initialized.
@ -234,12 +233,12 @@ fn peek_(p: *rust_port) -> bool {
pub fn select2<A: Send, B: Send>(p_a: Port<A>, p_b: Port<B>)
-> Either<A, B> {
let ports = ~[(**p_a).po, (**p_b).po];
let yield = 0, yieldp = ptr::addr_of(yield);
let yield = 0, yieldp = ptr::addr_of(&yield);
let mut resport: *rust_port;
resport = rusti::init::<*rust_port>();
do vec::as_imm_buf(ports) |ports, n_ports| {
rustrt::rust_port_select(ptr::addr_of(resport), ports,
rustrt::rust_port_select(ptr::addr_of(&resport), ports,
n_ports as size_t, yieldp);
}
@ -275,7 +274,6 @@ type port_id = int;
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t;
fn new_port(unit_sz: libc::size_t) -> *rust_port;
@ -298,7 +296,6 @@ extern mod rustrt {
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn init<T>() -> T;
}
@ -459,7 +456,7 @@ fn test_recv_chan_wrong_task() {
let po = Port();
let ch = Chan(po);
send(ch, ~"flower");
assert result::is_err(task::try(||
assert result::is_err(&task::try(||
recv_chan(ch)
))
}

View file

@ -36,7 +36,10 @@ Implicitly, all crates behave as if they included the following prologue:
// Don't link to core. We are core.
#[no_core];
#[legacy_modes];
#[legacy_exports];
#[warn(deprecated_mode)];
#[warn(deprecated_pattern)];
#[warn(vecs_implicitly_copyable)];
#[deny(non_camel_case_types)];
@ -85,242 +88,158 @@ export private;
/// Operations and constants for `int`
#[path = "int-template"]
mod int {
#[legacy_exports];
use inst::{ pow };
export pow;
pub use inst::{ pow };
#[path = "int.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `i8`
#[path = "int-template"]
mod i8 {
#[legacy_exports];
#[path = "i8.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `i16`
#[path = "int-template"]
mod i16 {
#[legacy_exports];
#[path = "i16.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `i32`
#[path = "int-template"]
mod i32 {
#[legacy_exports];
#[path = "i32.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `i64`
#[path = "int-template"]
mod i64 {
#[legacy_exports];
#[path = "i64.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `uint`
#[path = "uint-template"]
mod uint {
#[legacy_exports];
use inst::{
pub use inst::{
div_ceil, div_round, div_floor, iterate,
next_power_of_two
};
export div_ceil, div_round, div_floor, iterate,
next_power_of_two;
#[path = "uint.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `u8`
#[path = "uint-template"]
mod u8 {
#[legacy_exports];
use inst::is_ascii;
export is_ascii;
pub use inst::is_ascii;
#[path = "u8.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `u16`
#[path = "uint-template"]
mod u16 {
#[legacy_exports];
#[path = "u16.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `u32`
#[path = "uint-template"]
mod u32 {
#[legacy_exports];
#[path = "u32.rs"]
#[legacy_exports]
mod inst;
}
/// Operations and constants for `u64`
#[path = "uint-template"]
mod u64 {
#[legacy_exports];
#[path = "u64.rs"]
#[legacy_exports]
mod inst;
}
#[legacy_exports]
mod box;
#[legacy_exports]
mod char;
#[legacy_exports]
mod float;
#[legacy_exports]
mod f32;
#[legacy_exports]
mod f64;
#[legacy_exports]
mod str;
#[legacy_exports]
mod ptr;
#[legacy_exports]
mod vec;
#[legacy_exports]
mod at_vec;
#[legacy_exports]
mod bool;
#[legacy_exports]
mod tuple;
#[legacy_exports]
mod unit;
#[legacy_exports]
mod uniq;
// Ubiquitous-utility-type modules
#[cfg(notest)]
#[legacy_exports]
mod ops;
#[legacy_exports]
mod cmp;
#[legacy_exports]
mod num;
#[legacy_exports]
mod hash;
#[legacy_exports]
mod either;
#[legacy_exports]
mod iter;
#[legacy_exports]
mod logging;
#[legacy_exports]
mod option;
#[path="iter-trait"]
mod option_iter {
#[legacy_exports];
#[path = "option.rs"]
#[legacy_exports]
mod inst;
}
#[legacy_exports]
mod result;
#[legacy_exports]
mod to_str;
#[legacy_exports]
mod to_bytes;
#[legacy_exports]
mod from_str;
#[legacy_exports]
mod util;
// Data structure modules
#[legacy_exports]
mod dvec;
#[path="iter-trait"]
mod dvec_iter {
#[legacy_exports];
#[path = "dvec.rs"]
#[legacy_exports]
mod inst;
}
#[legacy_exports]
mod dlist;
#[path="iter-trait"]
mod dlist_iter {
#[legacy_exports];
#[path ="dlist.rs"]
#[legacy_exports]
mod inst;
}
#[legacy_exports]
mod send_map;
// Concurrency
#[legacy_exports]
mod comm;
#[legacy_exports]
mod task {
#[legacy_exports];
#[legacy_exports]
mod local_data;
#[legacy_exports]
pub mod local_data;
mod local_data_priv;
#[legacy_exports]
mod spawn;
#[legacy_exports]
mod rt;
pub mod spawn;
pub mod rt;
}
#[legacy_exports]
mod future;
#[legacy_exports]
mod pipes;
// Runtime and language-primitive support
#[legacy_exports]
mod gc;
#[legacy_exports]
mod io;
#[legacy_exports]
mod libc;
#[legacy_exports]
mod os;
#[legacy_exports]
mod path;
#[legacy_exports]
mod rand;
#[legacy_exports]
mod run;
#[legacy_exports]
mod sys;
#[legacy_exports]
mod cast;
#[legacy_exports]
mod mutable;
#[legacy_exports]
mod flate;
#[legacy_exports]
mod repr;
#[legacy_exports]
mod cleanup;
#[legacy_exports]
mod reflect;
// Modules supporting compiler-generated code
@ -336,9 +255,7 @@ mod rt;
// For internal use, not exported
#[legacy_exports]
mod unicode;
#[legacy_exports]
mod private;
mod cmath;
mod stackwalk;

View file

@ -2,8 +2,6 @@
// Export various ubiquitous types, constructors, methods.
#[legacy_exports];
use option::{Some, None};
use Option = option::Option;
use result::{Result, Ok, Err};
@ -17,6 +15,7 @@ use tuple::{TupleOps, ExtendedTupleOps};
use str::{StrSlice, UniqueStr};
use vec::{ConstVector, CopyableVector, ImmutableVector};
use vec::{ImmutableEqVector, ImmutableCopyableVector};
use vec::{MutableVector, MutableCopyableVector};
use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
use iter::{CopyableOrderedIter, Times, TimesIx};
use num::Num;
@ -33,6 +32,7 @@ export Num, Times, TimesIx;
export StrSlice, UniqueStr;
export ConstVector, CopyableVector, ImmutableVector;
export ImmutableEqVector, ImmutableCopyableVector, IterTraitExtensions;
export MutableVector, MutableCopyableVector;
export BaseIter, CopyableIter, CopyableOrderedIter, ExtendedIter, EqIter;
export TupleOps, ExtendedTupleOps;
export Ptr;

View file

@ -9,12 +9,9 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
export DList;
export new_dlist, from_elem, from_vec, extensions;
type DListLink<T> = Option<DListNode<T>>;
enum DListNode<T> = @{
@ -24,7 +21,7 @@ enum DListNode<T> = @{
mut next: DListLink<T>
};
enum DList<T> {
pub enum DList<T> {
DList_(@{
mut size: uint,
mut hd: DListLink<T>,
@ -83,7 +80,7 @@ impl<T> DListNode<T> {
}
/// Creates a new dlist node with the given data.
pure fn new_dlist_node<T>(+data: T) -> DListNode<T> {
pure fn new_dlist_node<T>(data: T) -> DListNode<T> {
DListNode(@{data: move data, mut linked: false,
mut prev: None, mut next: None})
}
@ -94,15 +91,15 @@ pure fn DList<T>() -> DList<T> {
}
/// Creates a new dlist with a single element
pure fn from_elem<T>(+data: T) -> DList<T> {
pub pure fn from_elem<T>(data: T) -> DList<T> {
let list = DList();
unsafe { list.push(move data); }
list
}
fn from_vec<T: Copy>(+vec: &[T]) -> DList<T> {
pub fn from_vec<T: Copy>(vec: &[T]) -> DList<T> {
do vec::foldl(DList(), vec) |list,data| {
list.push(data); // Iterating left-to-right -- add newly to the tail.
list.push(*data); // Iterating left-to-right -- add newly to the tail.
list
}
}
@ -118,7 +115,7 @@ fn concat<T>(lists: DList<DList<T>>) -> DList<T> {
}
priv impl<T> DList<T> {
pure fn new_link(-data: T) -> DListLink<T> {
pure fn new_link(data: T) -> DListLink<T> {
Some(DListNode(@{data: move data, mut linked: true,
mut prev: None, mut next: None}))
}
@ -145,7 +142,7 @@ priv impl<T> DList<T> {
// Link two nodes together. If either of them are 'none', also sets
// the head and/or tail pointers appropriately.
#[inline(always)]
fn link(+before: DListLink<T>, +after: DListLink<T>) {
fn link(before: DListLink<T>, after: DListLink<T>) {
match before {
Some(neighbour) => neighbour.next = after,
None => self.hd = after
@ -166,12 +163,12 @@ priv impl<T> DList<T> {
self.size -= 1;
}
fn add_head(+nobe: DListLink<T>) {
fn add_head(nobe: DListLink<T>) {
self.link(nobe, self.hd); // Might set tail too.
self.hd = nobe;
self.size += 1;
}
fn add_tail(+nobe: DListLink<T>) {
fn add_tail(nobe: DListLink<T>) {
self.link(self.tl, nobe); // Might set head too.
self.tl = nobe;
self.size += 1;
@ -201,27 +198,27 @@ impl<T> DList<T> {
pure fn is_not_empty() -> bool { self.len() != 0 }
/// Add data to the head of the list. O(1).
fn push_head(+data: T) {
fn push_head(data: T) {
self.add_head(self.new_link(move data));
}
/**
* Add data to the head of the list, and get the new containing
* node. O(1).
*/
fn push_head_n(+data: T) -> DListNode<T> {
fn push_head_n(data: T) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.add_head(nobe);
option::get(&nobe)
}
/// Add data to the tail of the list. O(1).
fn push(+data: T) {
fn push(data: T) {
self.add_tail(self.new_link(move data));
}
/**
* Add data to the tail of the list, and get the new containing
* node. O(1).
*/
fn push_n(+data: T) -> DListNode<T> {
fn push_n(data: T) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.add_tail(nobe);
option::get(&nobe)
@ -230,7 +227,7 @@ impl<T> DList<T> {
* Insert data into the middle of the list, left of the given node.
* O(1).
*/
fn insert_before(+data: T, neighbour: DListNode<T>) {
fn insert_before(data: T, neighbour: DListNode<T>) {
self.insert_left(self.new_link(move data), neighbour);
}
/**
@ -245,7 +242,7 @@ impl<T> DList<T> {
* Insert data in the middle of the list, left of the given node,
* and get its containing node. O(1).
*/
fn insert_before_n(+data: T, neighbour: DListNode<T>) -> DListNode<T> {
fn insert_before_n(data: T, neighbour: DListNode<T>) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.insert_left(nobe, neighbour);
option::get(&nobe)
@ -254,7 +251,7 @@ impl<T> DList<T> {
* Insert data into the middle of the list, right of the given node.
* O(1).
*/
fn insert_after(+data: T, neighbour: DListNode<T>) {
fn insert_after(data: T, neighbour: DListNode<T>) {
self.insert_right(neighbour, self.new_link(move data));
}
/**
@ -269,7 +266,7 @@ impl<T> DList<T> {
* Insert data in the middle of the list, right of the given node,
* and get its containing node. O(1).
*/
fn insert_after_n(+data: T, neighbour: DListNode<T>) -> DListNode<T> {
fn insert_after_n(data: T, neighbour: DListNode<T>) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.insert_right(neighbour, nobe);
option::get(&nobe)
@ -278,13 +275,13 @@ impl<T> DList<T> {
/// Remove a node from the head of the list. O(1).
fn pop_n() -> Option<DListNode<T>> {
let hd = self.peek_n();
hd.map(|nobe| self.unlink(nobe));
hd.map(|nobe| self.unlink(*nobe));
hd
}
/// Remove a node from the tail of the list. O(1).
fn pop_tail_n() -> Option<DListNode<T>> {
let tl = self.peek_tail_n();
tl.map(|nobe| self.unlink(nobe));
tl.map(|nobe| self.unlink(*nobe));
tl
}
/// Get the node at the list's head. O(1).
@ -678,7 +675,7 @@ mod tests {
#[test]
fn test_dlist_foldl() {
let l = from_vec(vec::from_fn(101, |x|x));
assert iter::foldl(l, 0, |accum,elem| accum+elem) == 5050;
assert iter::foldl(&l, 0, |accum,elem| *accum+*elem) == 5050;
}
#[test]
fn test_dlist_break_early() {

View file

@ -10,18 +10,12 @@ Note that recursive use is not permitted.
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use cast::reinterpret_cast;
use ptr::null;
export DVec;
export from_elem;
export from_vec;
export extensions;
export unwrap;
/**
* A growable, modifiable vector type that accumulates elements into a
* unique vector.
@ -57,27 +51,27 @@ type DVec_<A> = {
mut data: ~[A]
};
enum DVec<A> {
pub enum DVec<A> {
DVec_(DVec_<A>)
}
/// Creates a new, empty dvec
fn DVec<A>() -> DVec<A> {
pub fn DVec<A>() -> DVec<A> {
DVec_({mut data: ~[]})
}
/// Creates a new dvec with a single element
fn from_elem<A>(+e: A) -> DVec<A> {
pub fn from_elem<A>(e: A) -> DVec<A> {
DVec_({mut data: ~[move e]})
}
/// Creates a new dvec with the contents of a vector
fn from_vec<A>(+v: ~[A]) -> DVec<A> {
pub fn from_vec<A>(v: ~[A]) -> DVec<A> {
DVec_({mut data: move v})
}
/// Consumes the vector and returns its contents
fn unwrap<A>(+d: DVec<A>) -> ~[A] {
pub fn unwrap<A>(d: DVec<A>) -> ~[A] {
let DVec_({data: v}) <- d;
move v
}
@ -93,7 +87,7 @@ priv impl<A> DVec<A> {
}
#[inline(always)]
fn check_out<B>(f: fn(-v: ~[A]) -> B) -> B {
fn check_out<B>(f: &fn(v: ~[A]) -> B) -> B {
unsafe {
let mut data = cast::reinterpret_cast(&null::<()>());
data <-> self.data;
@ -104,7 +98,7 @@ priv impl<A> DVec<A> {
}
#[inline(always)]
fn give_back(+data: ~[A]) {
fn give_back(data: ~[A]) {
unsafe {
self.data = move data;
}
@ -126,7 +120,7 @@ impl<A> DVec<A> {
* and return a new vector to replace it with.
*/
#[inline(always)]
fn swap(f: fn(-v: ~[A]) -> ~[A]) {
fn swap(f: &fn(v: ~[A]) -> ~[A]) {
self.check_out(|v| self.give_back(f(move v)))
}
@ -136,7 +130,7 @@ impl<A> DVec<A> {
* and return a new vector to replace it with.
*/
#[inline(always)]
fn swap_mut(f: fn(-v: ~[mut A]) -> ~[mut A]) {
fn swap_mut(f: &fn(v: ~[mut A]) -> ~[mut A]) {
do self.swap |v| {
vec::from_mut(f(vec::to_mut(move v)))
}
@ -154,7 +148,7 @@ impl<A> DVec<A> {
}
/// Overwrite the current contents
fn set(+w: ~[A]) {
fn set(w: ~[A]) {
self.check_not_borrowed();
self.data <- w;
}
@ -163,14 +157,14 @@ impl<A> DVec<A> {
fn pop() -> A {
do self.check_out |v| {
let mut v <- v;
let result = vec::pop(v);
let result = v.pop();
self.give_back(move v);
move result
}
}
/// Insert a single item at the front of the list
fn unshift(-t: A) {
fn unshift(t: A) {
unsafe {
let mut data = cast::reinterpret_cast(&null::<()>());
data <-> self.data;
@ -178,22 +172,22 @@ impl<A> DVec<A> {
if data_ptr.is_null() { fail ~"Recursive use of dvec"; }
log(error, ~"a");
self.data <- ~[move t];
vec::push_all_move(self.data, move data);
self.data.push_all_move(move data);
log(error, ~"b");
}
}
/// Append a single item to the end of the list
fn push(+t: A) {
fn push(t: A) {
self.check_not_borrowed();
vec::push(self.data, move t);
self.data.push(move t);
}
/// Remove and return the first element
fn shift() -> A {
do self.check_out |v| {
let mut v = move v;
let result = vec::shift(v);
let result = v.shift();
self.give_back(move v);
move result
}
@ -246,7 +240,7 @@ impl<A: Copy> DVec<A> {
vec::reserve(&mut v, new_len);
let mut i = from_idx;
while i < to_idx {
vec::push(v, ts[i]);
v.push(ts[i]);
i += 1u;
}
move v
@ -272,7 +266,7 @@ impl<A: Copy> DVec<A> {
}
};
for ts.each |t| { vec::push(v, *t) };
for ts.each |t| { v.push(*t) };
v
}
}
@ -311,10 +305,10 @@ impl<A: Copy> DVec<A> {
* growing the vector if necessary. New elements will be initialized
* with `initval`
*/
fn grow_set_elt(idx: uint, initval: A, val: A) {
fn grow_set_elt(idx: uint, initval: &A, val: A) {
do self.swap |v| {
let mut v = move v;
vec::grow_set(v, idx, initval, val);
v.grow_set(idx, initval, val);
move v
}
}
@ -325,11 +319,11 @@ impl<A: Copy> DVec<A> {
self.check_not_borrowed();
let length = self.len();
if length == 0u {
if length == 0 {
fail ~"attempt to retrieve the last element of an empty vector";
}
return self.data[length - 1u];
return self.data[length - 1];
}
/// Iterates over the elements in reverse order
@ -360,7 +354,7 @@ impl<A: Copy> DVec<A> {
}
impl<A:Copy> DVec<A>: Index<uint,A> {
pure fn index(&&idx: uint) -> A {
pure fn index(idx: uint) -> A {
self.get_elt(idx)
}
}

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
//! A type that represents one of two alternatives
@ -8,13 +8,13 @@ use cmp::Eq;
use result::Result;
/// The either type
enum Either<T, U> {
pub enum Either<T, U> {
Left(T),
Right(U)
}
fn either<T, U, V>(f_left: fn((&T)) -> V,
f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
pub fn either<T, U, V>(f_left: fn((&T)) -> V,
f_right: fn((&U)) -> V, value: &Either<T, U>) -> V {
/*!
* Applies a function based on the given either value
*
@ -29,33 +29,34 @@ fn either<T, U, V>(f_left: fn((&T)) -> V,
}
}
fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
pub fn lefts<T: Copy, U>(eithers: &[Either<T, U>]) -> ~[T] {
//! Extracts from a vector of either all the left values
let mut result: ~[T] = ~[];
for vec::each(eithers) |elt| {
match *elt {
Left(l) => vec::push(result, l),
_ => { /* fallthrough */ }
do vec::build_sized(eithers.len()) |push| {
for vec::each(eithers) |elt| {
match *elt {
Left(ref l) => { push(*l); }
_ => { /* fallthrough */ }
}
}
}
move result
}
fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
//! Extracts from a vector of either all the right values
let mut result: ~[U] = ~[];
for vec::each(eithers) |elt| {
match *elt {
Right(r) => vec::push(result, r),
_ => { /* fallthrough */ }
do vec::build_sized(eithers.len()) |push| {
for vec::each(eithers) |elt| {
match *elt {
Right(ref r) => { push(*r); }
_ => { /* fallthrough */ }
}
}
}
move result
}
fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
// XXX bad copies. take arg by val
pub fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
-> {lefts: ~[T], rights: ~[U]} {
/*!
* Extracts from a vector of either all the left values and right values
@ -68,23 +69,26 @@ fn partition<T: Copy, U: Copy>(eithers: &[Either<T, U>])
let mut rights: ~[U] = ~[];
for vec::each(eithers) |elt| {
match *elt {
Left(l) => vec::push(lefts, l),
Right(r) => vec::push(rights, r)
Left(copy l) => lefts.push(l),
Right(copy r) => rights.push(r)
}
}
return {lefts: move lefts, rights: move rights};
}
pure fn flip<T: Copy, U: Copy>(eith: &Either<T, U>) -> Either<U, T> {
// XXX bad copies
pub pure fn flip<T: Copy, U: Copy>(eith: &Either<T, U>) -> Either<U, T> {
//! Flips between left and right of a given either
match *eith {
Right(r) => Left(r),
Left(l) => Right(l)
Right(copy r) => Left(r),
Left(copy l) => Right(l)
}
}
pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>) -> Result<U, T> {
// XXX bad copies
pub pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>)
-> Result<U, T> {
/*!
* Converts either::t to a result::t
*
@ -93,24 +97,25 @@ pure fn to_result<T: Copy, U: Copy>(eith: &Either<T, U>) -> Result<U, T> {
*/
match *eith {
Right(r) => result::Ok(r),
Left(l) => result::Err(l)
Right(copy r) => result::Ok(r),
Left(copy l) => result::Err(l)
}
}
pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
pub pure fn is_left<T, U>(eith: &Either<T, U>) -> bool {
//! Checks whether the given value is a left
match *eith { Left(_) => true, _ => false }
}
pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
pub pure fn is_right<T, U>(eith: &Either<T, U>) -> bool {
//! Checks whether the given value is a right
match *eith { Right(_) => true, _ => false }
}
pure fn unwrap_left<T,U>(+eith: Either<T,U>) -> T {
// tjc: fix the next two after a snapshot
pub pure fn unwrap_left<T,U>(eith: Either<T,U>) -> T {
//! Retrieves the value in the left branch. Fails if the either is Right.
match move eith {
@ -118,7 +123,7 @@ pure fn unwrap_left<T,U>(+eith: Either<T,U>) -> T {
}
}
pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
pub pure fn unwrap_right<T,U>(eith: Either<T,U>) -> U {
//! Retrieves the value in the right branch. Fails if the either is Left.
match move eith {
@ -129,16 +134,16 @@ pure fn unwrap_right<T,U>(+eith: Either<T,U>) -> U {
impl<T:Eq,U:Eq> Either<T,U> : Eq {
pure fn eq(other: &Either<T,U>) -> bool {
match self {
Left(a) => {
Left(ref a) => {
match (*other) {
Left(ref b) => a.eq(b),
Left(ref b) => (*a).eq(b),
Right(_) => false
}
}
Right(a) => {
Right(ref a) => {
match (*other) {
Left(_) => false,
Right(ref b) => a.eq(b)
Right(ref b) => (*a).eq(b)
}
}
}

View file

@ -81,16 +81,16 @@ mod ct {
// A fragment of the output sequence
enum Piece { PieceString(~str), PieceConv(Conv), }
type ErrorFn = fn@(~str) -> ! ;
type ErrorFn = fn@(&str) -> ! ;
fn parse_fmt_string(s: ~str, error: ErrorFn) -> ~[Piece] {
fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] {
let mut pieces: ~[Piece] = ~[];
let lim = str::len(s);
let mut buf = ~"";
fn flush_buf(+buf: ~str, &pieces: ~[Piece]) -> ~str {
if str::len(buf) > 0 {
fn flush_buf(buf: ~str, pieces: &mut ~[Piece]) -> ~str {
if buf.len() > 0 {
let piece = PieceString(move buf);
vec::push(pieces, move piece);
pieces.push(move piece);
}
return ~"";
}
@ -108,17 +108,17 @@ mod ct {
buf += curr2;
i += 1;
} else {
buf = flush_buf(move buf, pieces);
buf = flush_buf(move buf, &mut pieces);
let rs = parse_conversion(s, i, lim, error);
vec::push(pieces, copy rs.piece);
pieces.push(copy rs.piece);
i = rs.next;
}
} else { buf += curr; i += size; }
}
flush_buf(move buf, pieces);
flush_buf(move buf, &mut pieces);
move pieces
}
fn peek_num(s: ~str, i: uint, lim: uint) ->
fn peek_num(s: &str, i: uint, lim: uint) ->
Option<{num: uint, next: uint}> {
let mut j = i;
let mut accum = 0u;
@ -140,7 +140,7 @@ mod ct {
None
}
}
fn parse_conversion(s: ~str, i: uint, lim: uint, error: ErrorFn) ->
fn parse_conversion(s: &str, i: uint, lim: uint, error: ErrorFn) ->
{piece: Piece, next: uint} {
let parm = parse_parameter(s, i, lim);
let flags = parse_flags(s, parm.next, lim);
@ -155,7 +155,7 @@ mod ct {
ty: ty.ty}),
next: ty.next};
}
fn parse_parameter(s: ~str, i: uint, lim: uint) ->
fn parse_parameter(s: &str, i: uint, lim: uint) ->
{param: Option<int>, next: uint} {
if i >= lim { return {param: None, next: i}; }
let num = peek_num(s, i, lim);
@ -170,12 +170,12 @@ mod ct {
}
};
}
fn parse_flags(s: ~str, i: uint, lim: uint) ->
fn parse_flags(s: &str, i: uint, lim: uint) ->
{flags: ~[Flag], next: uint} {
let noflags: ~[Flag] = ~[];
if i >= lim { return {flags: move noflags, next: i}; }
fn more_(f: Flag, s: ~str, i: uint, lim: uint) ->
fn more(f: Flag, s: &str, i: uint, lim: uint) ->
{flags: ~[Flag], next: uint} {
let next = parse_flags(s, i + 1u, lim);
let rest = copy next.flags;
@ -183,21 +183,22 @@ mod ct {
let curr: ~[Flag] = ~[f];
return {flags: vec::append(move curr, rest), next: j};
}
let more = |x, copy s| more_(x, copy s, i, lim);
// Unfortunate, but because s is borrowed, can't use a closure
// fn more(f: Flag, s: &str) { more_(f, s, i, lim); }
let f = s[i];
return if f == '-' as u8 {
more(FlagLeftJustify)
more(FlagLeftJustify, s, i, lim)
} else if f == '0' as u8 {
more(FlagLeftZeroPad)
more(FlagLeftZeroPad, s, i, lim)
} else if f == ' ' as u8 {
more(FlagSpaceForSign)
more(FlagSpaceForSign, s, i, lim)
} else if f == '+' as u8 {
more(FlagSignAlways)
more(FlagSignAlways, s, i, lim)
} else if f == '#' as u8 {
more(FlagAlternate)
more(FlagAlternate, s, i, lim)
} else { {flags: move noflags, next: i} };
}
fn parse_count(s: ~str, i: uint, lim: uint)
fn parse_count(s: &str, i: uint, lim: uint)
-> {count: Count, next: uint} {
return if i >= lim {
{count: CountImplied, next: i}
@ -219,7 +220,7 @@ mod ct {
}
};
}
fn parse_precision(s: ~str, i: uint, lim: uint) ->
fn parse_precision(s: &str, i: uint, lim: uint) ->
{count: Count, next: uint} {
return if i >= lim {
{count: CountImplied, next: i}
@ -235,7 +236,7 @@ mod ct {
}
} else { {count: CountImplied, next: i} };
}
fn parse_type(s: ~str, i: uint, lim: uint, error: ErrorFn) ->
fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) ->
{ty: Ty, next: uint} {
if i >= lim { error(~"missing type in conversion"); }
let tstr = str::slice(s, i, i+1u);
@ -288,7 +289,7 @@ mod rt {
type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
pure fn conv_int(cv: Conv, i: int) -> ~str {
let radix = 10u;
let radix = 10;
let prec = get_int_precision(cv);
let mut s : ~str = int_to_str_prec(i, radix, prec);
if 0 <= i {
@ -350,8 +351,8 @@ mod rt {
}
return unsafe { pad(cv, s, PadFloat) };
}
pure fn conv_poly<T>(cv: Conv, v: T) -> ~str {
let s = sys::log_str(&v);
pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
let s = sys::log_str(v);
return conv_str(cv, s);
}
@ -404,16 +405,17 @@ mod rt {
pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
}
fn pad(cv: Conv, &s: ~str, mode: PadMode) -> ~str {
fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
let mut s = move s; // sadtimes
let uwidth : uint = match cv.width {
CountImplied => return copy s,
CountImplied => return s,
CountIs(width) => {
// FIXME: width should probably be uint (see Issue #1996)
width as uint
}
};
let strlen = str::char_len(s);
if uwidth <= strlen { return copy s; }
if uwidth <= strlen { return s; }
let mut padchar = ' ';
let diff = uwidth - strlen;
if have_flag(cv.flags, flag_left_justify) {
@ -444,7 +446,7 @@ mod rt {
// zeros. It may make sense to convert zero padding to a precision
// instead.
if signed && zero_padding && str::len(s) > 0u {
if signed && zero_padding && s.len() > 0 {
let head = str::shift_char(&mut s);
if head == '+' || head == '-' || head == ' ' {
let headstr = str::from_chars(vec::from_elem(1u, head));
@ -461,7 +463,12 @@ mod rt {
}
}
// XXX remove after snapshots
// Remove after snapshot
// Functions used by the fmt extension at runtime. For now there are a lot of
// decisions made a runtime. If it proves worthwhile then some of these
// conditions can be evaluated at compile-time. For now though it's cleaner to
// implement it 0this way, I think.
mod rt2 {
#[legacy_exports];
const flag_none : u32 = 0u32;
@ -477,7 +484,7 @@ mod rt2 {
type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
pure fn conv_int(cv: Conv, i: int) -> ~str {
let radix = 10u;
let radix = 10;
let prec = get_int_precision(cv);
let mut s : ~str = int_to_str_prec(i, radix, prec);
if 0 <= i {
@ -539,8 +546,8 @@ mod rt2 {
}
return unsafe { pad(cv, s, PadFloat) };
}
pure fn conv_poly<T>(cv: Conv, v: T) -> ~str {
let s = sys::log_str(&v);
pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
let s = sys::log_str(v);
return conv_str(cv, s);
}
@ -593,16 +600,17 @@ mod rt2 {
pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
}
fn pad(cv: Conv, &s: ~str, mode: PadMode) -> ~str {
fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
let mut s = move s; // sadtimes
let uwidth : uint = match cv.width {
CountImplied => return copy s,
CountImplied => return s,
CountIs(width) => {
// FIXME: width should probably be uint (see Issue #1996)
width as uint
}
};
let strlen = str::char_len(s);
if uwidth <= strlen { return copy s; }
if uwidth <= strlen { return s; }
let mut padchar = ' ';
let diff = uwidth - strlen;
if have_flag(cv.flags, flag_left_justify) {
@ -633,7 +641,7 @@ mod rt2 {
// zeros. It may make sense to convert zero padding to a precision
// instead.
if signed && zero_padding && str::len(s) > 0u {
if signed && zero_padding && s.len() > 0 {
let head = str::shift_char(&mut s);
if head == '+' || head == '-' || head == ' ' {
let headstr = str::from_chars(vec::from_elem(1u, head));

View file

@ -4,68 +4,51 @@
//! Operations and constants for `f32`
// PORT
use cmath::c_float::*;
use cmath::c_float_targ_consts::*;
export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt;
export is_positive, is_negative, is_nonpositive, is_nonnegative;
export is_zero, is_infinite, is_finite;
export NaN, is_NaN, infinity, neg_infinity;
export consts;
export logarithm;
export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor;
export erf, erfc, exp, expm1, exp2, abs, abs_sub;
export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp;
export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix;
export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc;
export signbit;
export num;
pub use cmath::c_float::*;
pub use cmath::c_float_targ_consts::*;
// These are not defined inside consts:: for consistency with
// the integer types
const NaN: f32 = 0.0_f32/0.0_f32;
pub const NaN: f32 = 0.0_f32/0.0_f32;
const infinity: f32 = 1.0_f32/0.0_f32;
pub const infinity: f32 = 1.0_f32/0.0_f32;
const neg_infinity: f32 = -1.0_f32/0.0_f32;
pub const neg_infinity: f32 = -1.0_f32/0.0_f32;
pure fn is_NaN(f: f32) -> bool { f != f }
pub pure fn is_NaN(f: f32) -> bool { f != f }
pure fn add(x: f32, y: f32) -> f32 { return x + y; }
pub pure fn add(x: f32, y: f32) -> f32 { return x + y; }
pure fn sub(x: f32, y: f32) -> f32 { return x - y; }
pub pure fn sub(x: f32, y: f32) -> f32 { return x - y; }
pure fn mul(x: f32, y: f32) -> f32 { return x * y; }
pub pure fn mul(x: f32, y: f32) -> f32 { return x * y; }
pure fn div(x: f32, y: f32) -> f32 { return x / y; }
pub pure fn div(x: f32, y: f32) -> f32 { return x / y; }
pure fn rem(x: f32, y: f32) -> f32 { return x % y; }
pub pure fn rem(x: f32, y: f32) -> f32 { return x % y; }
pure fn lt(x: f32, y: f32) -> bool { return x < y; }
pub pure fn lt(x: f32, y: f32) -> bool { return x < y; }
pure fn le(x: f32, y: f32) -> bool { return x <= y; }
pub pure fn le(x: f32, y: f32) -> bool { return x <= y; }
pure fn eq(x: f32, y: f32) -> bool { return x == y; }
pub pure fn eq(x: f32, y: f32) -> bool { return x == y; }
pure fn ne(x: f32, y: f32) -> bool { return x != y; }
pub pure fn ne(x: f32, y: f32) -> bool { return x != y; }
pure fn ge(x: f32, y: f32) -> bool { return x >= y; }
pub pure fn ge(x: f32, y: f32) -> bool { return x >= y; }
pure fn gt(x: f32, y: f32) -> bool { return x > y; }
pub pure fn gt(x: f32, y: f32) -> bool { return x > y; }
// FIXME (#1999): replace the predicates below with llvm intrinsics or
// calls to the libmath macros in the rust runtime for performance.
/// Returns true if `x` is a positive number, including +0.0f320 and +Infinity
pure fn is_positive(x: f32) -> bool
pub pure fn is_positive(x: f32) -> bool
{ return x > 0.0f32 || (1.0f32/x) == infinity; }
/// Returns true if `x` is a negative number, including -0.0f320 and -Infinity
pure fn is_negative(x: f32) -> bool
pub pure fn is_negative(x: f32) -> bool
{ return x < 0.0f32 || (1.0f32/x) == neg_infinity; }
/**
@ -73,7 +56,7 @@ pure fn is_negative(x: f32) -> bool
*
* This is the same as `f32::is_negative`.
*/
pure fn is_nonpositive(x: f32) -> bool {
pub pure fn is_nonpositive(x: f32) -> bool {
return x < 0.0f32 || (1.0f32/x) == neg_infinity;
}
@ -82,87 +65,85 @@ pure fn is_nonpositive(x: f32) -> bool {
*
* This is the same as `f32::is_positive`.)
*/
pure fn is_nonnegative(x: f32) -> bool {
pub pure fn is_nonnegative(x: f32) -> bool {
return x > 0.0f32 || (1.0f32/x) == infinity;
}
/// Returns true if `x` is a zero number (positive or negative zero)
pure fn is_zero(x: f32) -> bool {
pub pure fn is_zero(x: f32) -> bool {
return x == 0.0f32 || x == -0.0f32;
}
/// Returns true if `x`is an infinite number
pure fn is_infinite(x: f32) -> bool {
pub pure fn is_infinite(x: f32) -> bool {
return x == infinity || x == neg_infinity;
}
/// Returns true if `x`is a finite number
pure fn is_finite(x: f32) -> bool {
pub pure fn is_finite(x: f32) -> bool {
return !(is_NaN(x) || is_infinite(x));
}
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
/* Module: consts */
mod consts {
#[legacy_exports];
pub mod consts {
// FIXME (requires Issue #1433 to fix): replace with mathematical
// constants from cmath.
/// Archimedes' constant
const pi: f32 = 3.14159265358979323846264338327950288_f32;
pub const pi: f32 = 3.14159265358979323846264338327950288_f32;
/// pi/2.0
const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32;
pub const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32;
/// pi/4.0
const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32;
pub const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32;
/// 1.0/pi
const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32;
pub const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32;
/// 2.0/pi
const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32;
pub const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32;
/// 2.0/sqrt(pi)
const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32;
pub const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32;
/// sqrt(2.0)
const sqrt2: f32 = 1.41421356237309504880168872420969808_f32;
pub const sqrt2: f32 = 1.41421356237309504880168872420969808_f32;
/// 1.0/sqrt(2.0)
const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32;
pub const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32;
/// Euler's number
const e: f32 = 2.71828182845904523536028747135266250_f32;
pub const e: f32 = 2.71828182845904523536028747135266250_f32;
/// log2(e)
const log2_e: f32 = 1.44269504088896340735992468100189214_f32;
pub const log2_e: f32 = 1.44269504088896340735992468100189214_f32;
/// log10(e)
const log10_e: f32 = 0.434294481903251827651128918916605082_f32;
pub const log10_e: f32 = 0.434294481903251827651128918916605082_f32;
/// ln(2.0)
const ln_2: f32 = 0.693147180559945309417232121458176568_f32;
pub const ln_2: f32 = 0.693147180559945309417232121458176568_f32;
/// ln(10.0)
const ln_10: f32 = 2.30258509299404568401799145468436421_f32;
pub const ln_10: f32 = 2.30258509299404568401799145468436421_f32;
}
pure fn signbit(x: f32) -> int {
pub pure fn signbit(x: f32) -> int {
if is_negative(x) { return 1; } else { return 0; }
}
pure fn logarithm(n: f32, b: f32) -> f32 {
pub pure fn logarithm(n: f32, b: f32) -> f32 {
return log2(n) / log2(b);
}
impl f32: num::Num {
pure fn add(&&other: f32) -> f32 { return self + other; }
pure fn sub(&&other: f32) -> f32 { return self - other; }
pure fn mul(&&other: f32) -> f32 { return self * other; }
pure fn div(&&other: f32) -> f32 { return self / other; }
pure fn modulo(&&other: f32) -> f32 { return self % other; }
pure fn add(other: &f32) -> f32 { return self + *other; }
pure fn sub(other: &f32) -> f32 { return self - *other; }
pure fn mul(other: &f32) -> f32 { return self * *other; }
pure fn div(other: &f32) -> f32 { return self / *other; }
pure fn modulo(other: &f32) -> f32 { return self % *other; }
pure fn neg() -> f32 { return -self; }
pure fn to_int() -> int { return self as int; }

View file

@ -4,95 +4,70 @@
//! Operations and constants for `f64`
// PORT
pub use cmath::c_double::*;
pub use cmath::c_double_targ_consts::*;
use cmath::c_double::*;
use cmath::c_double_targ_consts::*;
// Even though this module exports everything defined in it,
// because it contains re-exports, we also have to explicitly
// export locally defined things. That's a bit annoying.
export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt;
export is_positive, is_negative, is_nonpositive, is_nonnegative;
export is_zero, is_infinite, is_finite;
export NaN, is_NaN, infinity, neg_infinity;
export consts;
export logarithm;
export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor;
export erf, erfc, exp, expm1, exp2, abs, abs_sub;
export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp;
export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix;
export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc;
export signbit;
export epsilon;
export j0, j1, jn, y0, y1, yn;
export num;
// FIXME (#1433): obtain these in a different way
// These are not defined inside consts:: for consistency with
// the integer types
// PORT check per architecture
pub const radix: uint = 2u;
// FIXME (#1433): obtain these in a different way
pub const mantissa_digits: uint = 53u;
pub const digits: uint = 15u;
const radix: uint = 2u;
pub const epsilon: f64 = 2.2204460492503131e-16_f64;
const mantissa_digits: uint = 53u;
const digits: uint = 15u;
pub const min_value: f64 = 2.2250738585072014e-308_f64;
pub const max_value: f64 = 1.7976931348623157e+308_f64;
const epsilon: f64 = 2.2204460492503131e-16_f64;
pub const min_exp: int = -1021;
pub const max_exp: int = 1024;
const min_value: f64 = 2.2250738585072014e-308_f64;
const max_value: f64 = 1.7976931348623157e+308_f64;
pub const min_10_exp: int = -307;
pub const max_10_exp: int = 308;
const min_exp: int = -1021;
const max_exp: int = 1024;
pub const NaN: f64 = 0.0_f64/0.0_f64;
const min_10_exp: int = -307;
const max_10_exp: int = 308;
pub const infinity: f64 = 1.0_f64/0.0_f64;
const NaN: f64 = 0.0_f64/0.0_f64;
pub const neg_infinity: f64 = -1.0_f64/0.0_f64;
const infinity: f64 = 1.0_f64/0.0_f64;
pub pure fn is_NaN(f: f64) -> bool { f != f }
const neg_infinity: f64 = -1.0_f64/0.0_f64;
pub pure fn add(x: f64, y: f64) -> f64 { return x + y; }
pure fn is_NaN(f: f64) -> bool { f != f }
pub pure fn sub(x: f64, y: f64) -> f64 { return x - y; }
pure fn add(x: f64, y: f64) -> f64 { return x + y; }
pub pure fn mul(x: f64, y: f64) -> f64 { return x * y; }
pure fn sub(x: f64, y: f64) -> f64 { return x - y; }
pub pure fn div(x: f64, y: f64) -> f64 { return x / y; }
pure fn mul(x: f64, y: f64) -> f64 { return x * y; }
pub pure fn rem(x: f64, y: f64) -> f64 { return x % y; }
pure fn div(x: f64, y: f64) -> f64 { return x / y; }
pub pure fn lt(x: f64, y: f64) -> bool { return x < y; }
pure fn rem(x: f64, y: f64) -> f64 { return x % y; }
pub pure fn le(x: f64, y: f64) -> bool { return x <= y; }
pure fn lt(x: f64, y: f64) -> bool { return x < y; }
pub pure fn eq(x: f64, y: f64) -> bool { return x == y; }
pure fn le(x: f64, y: f64) -> bool { return x <= y; }
pub pure fn ne(x: f64, y: f64) -> bool { return x != y; }
pure fn eq(x: f64, y: f64) -> bool { return x == y; }
pub pure fn ge(x: f64, y: f64) -> bool { return x >= y; }
pure fn ne(x: f64, y: f64) -> bool { return x != y; }
pub pure fn gt(x: f64, y: f64) -> bool { return x > y; }
pure fn ge(x: f64, y: f64) -> bool { return x >= y; }
pure fn gt(x: f64, y: f64) -> bool { return x > y; }
pure fn sqrt(x: f64) -> f64 {
pub pure fn sqrt(x: f64) -> f64 {
cmath::c_double::sqrt(x as libc::c_double) as f64
}
/// Returns true if `x` is a positive number, including +0.0f640 and +Infinity
pure fn is_positive(x: f64) -> bool
pub pure fn is_positive(x: f64) -> bool
{ return x > 0.0f64 || (1.0f64/x) == infinity; }
/// Returns true if `x` is a negative number, including -0.0f640 and -Infinity
pure fn is_negative(x: f64) -> bool
pub pure fn is_negative(x: f64) -> bool
{ return x < 0.0f64 || (1.0f64/x) == neg_infinity; }
/**
@ -100,7 +75,7 @@ pure fn is_negative(x: f64) -> bool
*
* This is the same as `f64::is_negative`.
*/
pure fn is_nonpositive(x: f64) -> bool {
pub pure fn is_nonpositive(x: f64) -> bool {
return x < 0.0f64 || (1.0f64/x) == neg_infinity;
}
@ -109,87 +84,85 @@ pure fn is_nonpositive(x: f64) -> bool {
*
* This is the same as `f64::positive`.
*/
pure fn is_nonnegative(x: f64) -> bool {
pub pure fn is_nonnegative(x: f64) -> bool {
return x > 0.0f64 || (1.0f64/x) == infinity;
}
/// Returns true if `x` is a zero number (positive or negative zero)
pure fn is_zero(x: f64) -> bool {
pub pure fn is_zero(x: f64) -> bool {
return x == 0.0f64 || x == -0.0f64;
}
/// Returns true if `x`is an infinite number
pure fn is_infinite(x: f64) -> bool {
pub pure fn is_infinite(x: f64) -> bool {
return x == infinity || x == neg_infinity;
}
/// Returns true if `x`is a finite number
pure fn is_finite(x: f64) -> bool {
pub pure fn is_finite(x: f64) -> bool {
return !(is_NaN(x) || is_infinite(x));
}
// FIXME (#1999): add is_normal, is_subnormal, and fpclassify
/* Module: consts */
mod consts {
#[legacy_exports];
pub mod consts {
// FIXME (requires Issue #1433 to fix): replace with mathematical
// constants from cmath.
/// Archimedes' constant
const pi: f64 = 3.14159265358979323846264338327950288_f64;
pub const pi: f64 = 3.14159265358979323846264338327950288_f64;
/// pi/2.0
const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64;
pub const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64;
/// pi/4.0
const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64;
pub const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64;
/// 1.0/pi
const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64;
pub const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64;
/// 2.0/pi
const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64;
pub const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64;
/// 2.0/sqrt(pi)
const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64;
pub const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64;
/// sqrt(2.0)
const sqrt2: f64 = 1.41421356237309504880168872420969808_f64;
pub const sqrt2: f64 = 1.41421356237309504880168872420969808_f64;
/// 1.0/sqrt(2.0)
const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64;
pub const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64;
/// Euler's number
const e: f64 = 2.71828182845904523536028747135266250_f64;
pub const e: f64 = 2.71828182845904523536028747135266250_f64;
/// log2(e)
const log2_e: f64 = 1.44269504088896340735992468100189214_f64;
pub const log2_e: f64 = 1.44269504088896340735992468100189214_f64;
/// log10(e)
const log10_e: f64 = 0.434294481903251827651128918916605082_f64;
pub const log10_e: f64 = 0.434294481903251827651128918916605082_f64;
/// ln(2.0)
const ln_2: f64 = 0.693147180559945309417232121458176568_f64;
pub const ln_2: f64 = 0.693147180559945309417232121458176568_f64;
/// ln(10.0)
const ln_10: f64 = 2.30258509299404568401799145468436421_f64;
pub const ln_10: f64 = 2.30258509299404568401799145468436421_f64;
}
pure fn signbit(x: f64) -> int {
pub pure fn signbit(x: f64) -> int {
if is_negative(x) { return 1; } else { return 0; }
}
pure fn logarithm(n: f64, b: f64) -> f64 {
pub pure fn logarithm(n: f64, b: f64) -> f64 {
return log2(n) / log2(b);
}
impl f64: num::Num {
pure fn add(&&other: f64) -> f64 { return self + other; }
pure fn sub(&&other: f64) -> f64 { return self - other; }
pure fn mul(&&other: f64) -> f64 { return self * other; }
pure fn div(&&other: f64) -> f64 { return self / other; }
pure fn modulo(&&other: f64) -> f64 { return self % other; }
pure fn add(other: &f64) -> f64 { return self + *other; }
pure fn sub(other: &f64) -> f64 { return self - *other; }
pure fn mul(other: &f64) -> f64 { return self * *other; }
pure fn div(other: &f64) -> f64 { return self / *other; }
pure fn modulo(other: &f64) -> f64 { return self % *other; }
pure fn neg() -> f64 { return -self; }
pure fn to_int() -> int { return self as int; }

View file

@ -11,8 +11,6 @@ Simple compression
use libc::{c_void, size_t, c_int};
extern mod rustrt {
#[legacy_exports];
fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
src_buf_len: size_t,
pout_len: *size_t,
@ -29,14 +27,14 @@ const lz_fast : c_int = 0x1; // LZ with only one probe
const lz_norm : c_int = 0x80; // LZ with 128 probes, "normal"
const lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"
fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
let res =
rustrt::tdefl_compress_mem_to_heap(b as *c_void,
len as size_t,
ptr::addr_of(outsz),
ptr::addr_of(&outsz),
lz_norm);
assert res as int != 0;
let out = vec::raw::from_buf(res as *u8,
@ -47,14 +45,14 @@ fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
}
}
fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
pub fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
let res =
rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
len as size_t,
ptr::addr_of(outsz),
ptr::addr_of(&outsz),
0);
assert res as int != 0;
let out = vec::raw::from_buf(res as *u8,
@ -71,12 +69,12 @@ fn test_flate_round_trip() {
let r = rand::Rng();
let mut words = ~[];
for 20.times {
vec::push(words, r.gen_bytes(r.gen_uint_range(1, 10)));
words.push(r.gen_bytes(r.gen_uint_range(1, 10)));
}
for 20.times {
let mut in = ~[];
for 2000.times {
vec::push_all(in, r.choose(words));
in.push_all(r.choose(words));
}
debug!("de/inflate of %u bytes of random word-sequences",
in.len());

View file

@ -7,26 +7,10 @@
// Even though this module exports everything defined in it,
// because it contains re-exports, we also have to explicitly
// export locally defined things. That's a bit annoying.
export to_str_common, to_str_exact, to_str, from_str;
export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt;
export is_positive, is_negative, is_nonpositive, is_nonnegative;
export is_zero, is_infinite, is_finite;
export NaN, is_NaN, infinity, neg_infinity;
export consts;
export logarithm;
export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor;
export erf, erfc, exp, expm1, exp2, abs, abs_sub;
export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp;
export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix;
export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc;
export signbit;
export pow_with_uint;
export num;
// export when m_float == c_double
export j0, j1, jn, y0, y1, yn;
// PORT this must match in width according to architecture
@ -44,56 +28,54 @@ use f64::{j0, j1, jn, y0, y1, yn};
use cmp::{Eq, Ord};
use num::from_int;
const NaN: float = 0.0/0.0;
pub const NaN: float = 0.0/0.0;
const infinity: float = 1.0/0.0;
pub const infinity: float = 1.0/0.0;
const neg_infinity: float = -1.0/0.0;
pub const neg_infinity: float = -1.0/0.0;
/* Module: consts */
mod consts {
#[legacy_exports];
pub mod consts {
// FIXME (requires Issue #1433 to fix): replace with mathematical
// constants from cmath.
/// Archimedes' constant
const pi: float = 3.14159265358979323846264338327950288;
pub const pi: float = 3.14159265358979323846264338327950288;
/// pi/2.0
const frac_pi_2: float = 1.57079632679489661923132169163975144;
pub const frac_pi_2: float = 1.57079632679489661923132169163975144;
/// pi/4.0
const frac_pi_4: float = 0.785398163397448309615660845819875721;
pub const frac_pi_4: float = 0.785398163397448309615660845819875721;
/// 1.0/pi
const frac_1_pi: float = 0.318309886183790671537767526745028724;
pub const frac_1_pi: float = 0.318309886183790671537767526745028724;
/// 2.0/pi
const frac_2_pi: float = 0.636619772367581343075535053490057448;
pub const frac_2_pi: float = 0.636619772367581343075535053490057448;
/// 2.0/sqrt(pi)
const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
pub const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
/// sqrt(2.0)
const sqrt2: float = 1.41421356237309504880168872420969808;
pub const sqrt2: float = 1.41421356237309504880168872420969808;
/// 1.0/sqrt(2.0)
const frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
pub const frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
/// Euler's number
const e: float = 2.71828182845904523536028747135266250;
pub const e: float = 2.71828182845904523536028747135266250;
/// log2(e)
const log2_e: float = 1.44269504088896340735992468100189214;
pub const log2_e: float = 1.44269504088896340735992468100189214;
/// log10(e)
const log10_e: float = 0.434294481903251827651128918916605082;
pub const log10_e: float = 0.434294481903251827651128918916605082;
/// ln(2.0)
const ln_2: float = 0.693147180559945309417232121458176568;
pub const ln_2: float = 0.693147180559945309417232121458176568;
/// ln(10.0)
const ln_10: float = 2.30258509299404568401799145468436421;
pub const ln_10: float = 2.30258509299404568401799145468436421;
}
/**
@ -109,7 +91,7 @@ mod consts {
* * digits - The number of significant digits
* * exact - Whether to enforce the exact number of significant digits
*/
fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
if is_NaN(num) { return ~"NaN"; }
if num == infinity { return ~"inf"; }
if num == neg_infinity { return ~"-inf"; }
@ -139,11 +121,11 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
// while we still need digits
// build stack of digits
while ii > 0u && (frac >= epsilon_prime || exact) {
while ii > 0 && (frac >= epsilon_prime || exact) {
// store the next digit
frac *= 10.0;
let digit = frac as uint;
vec::push(fractionalParts, digit);
fractionalParts.push(digit);
// calculate the next frac
frac -= digit as float;
@ -153,25 +135,25 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
let mut acc;
let mut racc = ~"";
let mut carry = if frac * 10.0 as uint >= 5u { 1u } else { 0u };
let mut carry = if frac * 10.0 as uint >= 5 { 1 } else { 0 };
// turn digits into string
// using stack of digits
while vec::len(fractionalParts) > 0u {
let mut adjusted_digit = carry + vec::pop(fractionalParts);
while fractionalParts.is_not_empty() {
let mut adjusted_digit = carry + fractionalParts.pop();
if adjusted_digit == 10u {
carry = 1u;
adjusted_digit %= 10u
if adjusted_digit == 10 {
carry = 1;
adjusted_digit %= 10
} else {
carry = 0u
carry = 0;
};
racc = uint::str(adjusted_digit) + racc;
}
// pad decimals with trailing zeroes
while str::len(racc) < digits && exact {
while racc.len() < digits && exact {
racc += ~"0"
}
@ -194,12 +176,12 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
* * num - The float value
* * digits - The number of significant digits
*/
fn to_str_exact(num: float, digits: uint) -> ~str {
pub fn to_str_exact(num: float, digits: uint) -> ~str {
to_str_common(num, digits, true)
}
#[test]
fn test_to_str_exact_do_decimal() {
pub fn test_to_str_exact_do_decimal() {
let s = to_str_exact(5.0, 4u);
assert s == ~"5.0000";
}
@ -214,7 +196,7 @@ fn test_to_str_exact_do_decimal() {
* * num - The float value
* * digits - The number of significant digits
*/
fn to_str(num: float, digits: uint) -> ~str {
pub fn to_str(num: float, digits: uint) -> ~str {
to_str_common(num, digits, false)
}
@ -244,7 +226,7 @@ fn to_str(num: float, digits: uint) -> ~str {
* `none` if the string did not represent a valid number. Otherwise,
* `Some(n)` where `n` is the floating-point number represented by `[num]`.
*/
fn from_str(num: &str) -> Option<float> {
pub fn from_str(num: &str) -> Option<float> {
if num == "inf" {
return Some(infinity as float);
} else if num == "-inf" {
@ -379,7 +361,7 @@ fn from_str(num: &str) -> Option<float> {
*
* `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
*/
fn pow_with_uint(base: uint, pow: uint) -> float {
pub fn pow_with_uint(base: uint, pow: uint) -> float {
if base == 0u {
if pow == 0u {
return NaN as float;
@ -399,40 +381,40 @@ fn pow_with_uint(base: uint, pow: uint) -> float {
return total;
}
pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) }
pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) }
pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) }
pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) }
pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) }
pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
pub pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) }
pub pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) }
pub pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) }
pub pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) }
pub pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) }
pub pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
pub pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) }
pub pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) }
pure fn abs(x: float) -> float { f64::abs(x as f64) as float }
pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float }
pure fn atan(x: float) -> float { f64::atan(x as f64) as float }
pure fn sin(x: float) -> float { f64::sin(x as f64) as float }
pure fn cos(x: float) -> float { f64::cos(x as f64) as float }
pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
pub pure fn abs(x: float) -> float { f64::abs(x as f64) as float }
pub pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float }
pub pure fn atan(x: float) -> float { f64::atan(x as f64) as float }
pub pure fn sin(x: float) -> float { f64::sin(x as f64) as float }
pub pure fn cos(x: float) -> float { f64::cos(x as f64) as float }
pub pure fn tan(x: float) -> float { f64::tan(x as f64) as float }
impl float : Eq {
pure fn eq(other: &float) -> bool { self == (*other) }
pure fn ne(other: &float) -> bool { self != (*other) }
pub pure fn eq(other: &float) -> bool { self == (*other) }
pub pure fn ne(other: &float) -> bool { self != (*other) }
}
impl float : Ord {
pure fn lt(other: &float) -> bool { self < (*other) }
pure fn le(other: &float) -> bool { self <= (*other) }
pure fn ge(other: &float) -> bool { self >= (*other) }
pure fn gt(other: &float) -> bool { self > (*other) }
pub pure fn lt(other: &float) -> bool { self < (*other) }
pub pure fn le(other: &float) -> bool { self <= (*other) }
pub pure fn ge(other: &float) -> bool { self >= (*other) }
pub pure fn gt(other: &float) -> bool { self > (*other) }
}
impl float: num::Num {
pure fn add(&&other: float) -> float { return self + other; }
pure fn sub(&&other: float) -> float { return self - other; }
pure fn mul(&&other: float) -> float { return self * other; }
pure fn div(&&other: float) -> float { return self / other; }
pure fn modulo(&&other: float) -> float { return self % other; }
pub pure fn add(other: &float) -> float { return self + *other; }
pub pure fn sub(other: &float) -> float { return self - *other; }
pub pure fn mul(other: &float) -> float { return self * *other; }
pub pure fn div(other: &float) -> float { return self / *other; }
pure fn modulo(other: &float) -> float { return self % *other; }
pure fn neg() -> float { return -self; }
pure fn to_int() -> int { return self as int; }
@ -440,7 +422,7 @@ impl float: num::Num {
}
#[test]
fn test_from_str() {
pub fn test_from_str() {
assert from_str(~"3") == Some(3.);
assert from_str(~"3") == Some(3.);
assert from_str(~"3.14") == Some(3.14);
@ -483,7 +465,7 @@ fn test_from_str() {
}
#[test]
fn test_positive() {
pub fn test_positive() {
assert(is_positive(infinity));
assert(is_positive(1.));
assert(is_positive(0.));
@ -494,7 +476,7 @@ fn test_positive() {
}
#[test]
fn test_negative() {
pub fn test_negative() {
assert(!is_negative(infinity));
assert(!is_negative(1.));
assert(!is_negative(0.));
@ -505,7 +487,7 @@ fn test_negative() {
}
#[test]
fn test_nonpositive() {
pub fn test_nonpositive() {
assert(!is_nonpositive(infinity));
assert(!is_nonpositive(1.));
assert(!is_nonpositive(0.));
@ -516,7 +498,7 @@ fn test_nonpositive() {
}
#[test]
fn test_nonnegative() {
pub fn test_nonnegative() {
assert(is_nonnegative(infinity));
assert(is_nonnegative(1.));
assert(is_nonnegative(0.));
@ -527,24 +509,24 @@ fn test_nonnegative() {
}
#[test]
fn test_to_str_inf() {
pub fn test_to_str_inf() {
assert to_str(infinity, 10u) == ~"inf";
assert to_str(-infinity, 10u) == ~"-inf";
}
#[test]
fn test_traits() {
pub fn test_traits() {
fn test<U:num::Num cmp::Eq>(ten: &U) {
assert (ten.to_int() == 10);
let two: U = from_int(2);
assert (two.to_int() == 2);
assert (ten.add(two) == from_int(12));
assert (ten.sub(two) == from_int(8));
assert (ten.mul(two) == from_int(20));
assert (ten.div(two) == from_int(5));
assert (ten.modulo(two) == from_int(0));
assert (ten.add(&two) == from_int(12));
assert (ten.sub(&two) == from_int(8));
assert (ten.mul(&two) == from_int(20));
assert (ten.div(&two) == from_int(5));
assert (ten.modulo(&two) == from_int(0));
}
test(&10.0);

View file

@ -6,7 +6,7 @@
use option::Option;
trait FromStr {
pub trait FromStr {
static fn from_str(s: &str) -> Option<self>;
}

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
/*!
@ -19,20 +19,8 @@ use either::Either;
use pipes::recv;
use cast::copy_lifetime;
export Future;
export extensions;
export from_value;
export from_port;
export from_fn;
export get;
export with;
export spawn;
// for task.rs
export future_pipe;
#[doc = "The future type"]
struct Future<A> {
pub struct Future<A> {
/*priv*/ mut state: FutureState<A>,
// FIXME(#2829) -- futures should not be copyable, because they close
@ -67,7 +55,7 @@ impl<A> Future<A> {
}
}
fn from_value<A>(+val: A) -> Future<A> {
pub fn from_value<A>(val: A) -> Future<A> {
/*!
* Create a future from a value
*
@ -78,7 +66,8 @@ fn from_value<A>(+val: A) -> Future<A> {
Future {state: Forced(~(move val))}
}
fn from_port<A:Send>(+port: future_pipe::client::waiting<A>) -> Future<A> {
pub fn from_port<A:Send>(port: future_pipe::client::waiting<A>) ->
Future<A> {
/*!
* Create a future from a port
*
@ -97,7 +86,7 @@ fn from_port<A:Send>(+port: future_pipe::client::waiting<A>) -> Future<A> {
}
}
fn from_fn<A>(+f: ~fn() -> A) -> Future<A> {
pub fn from_fn<A>(+f: ~fn() -> A) -> Future<A> {
/*!
* Create a future from a function.
*
@ -109,7 +98,7 @@ fn from_fn<A>(+f: ~fn() -> A) -> Future<A> {
Future {state: Pending(move f)}
}
fn spawn<A:Send>(+blk: fn~() -> A) -> Future<A> {
pub fn spawn<A:Send>(+blk: fn~() -> A) -> Future<A> {
/*!
* Create a future from a unique closure.
*
@ -122,7 +111,7 @@ fn spawn<A:Send>(+blk: fn~() -> A) -> Future<A> {
}))
}
fn get_ref<A>(future: &r/Future<A>) -> &r/A {
pub fn get_ref<A>(future: &r/Future<A>) -> &r/A {
/*!
* Executes the future's closure and then returns a borrowed
* pointer to the result. The borrowed pointer lasts as long as
@ -160,13 +149,13 @@ fn get_ref<A>(future: &r/Future<A>) -> &r/A {
}
}
fn get<A:Copy>(future: &Future<A>) -> A {
pub fn get<A:Copy>(future: &Future<A>) -> A {
//! Get the value of the future
*get_ref(future)
}
fn with<A,B>(future: &Future<A>, blk: fn((&A)) -> B) -> B {
pub fn with<A,B>(future: &Future<A>, blk: fn((&A)) -> B) -> B {
//! Work with the value without copying it
blk(get_ref(future))
@ -179,16 +168,15 @@ proto! future_pipe (
)
#[allow(non_implicitly_copyable_typarams)]
mod test {
#[legacy_exports];
pub mod test {
#[test]
fn test_from_value() {
pub fn test_from_value() {
let f = from_value(~"snail");
assert get(&f) == ~"snail";
}
#[test]
fn test_from_port() {
pub fn test_from_port() {
let (po, ch) = future_pipe::init();
future_pipe::server::completed(ch, ~"whale");
let f = from_port(po);
@ -196,43 +184,43 @@ mod test {
}
#[test]
fn test_from_fn() {
pub fn test_from_fn() {
let f = from_fn(|| ~"brail");
assert get(&f) == ~"brail";
}
#[test]
fn test_interface_get() {
pub fn test_interface_get() {
let f = from_value(~"fail");
assert f.get() == ~"fail";
}
#[test]
fn test_with() {
pub fn test_with() {
let f = from_value(~"nail");
assert with(&f, |v| copy *v) == ~"nail";
}
#[test]
fn test_get_ref_method() {
pub fn test_get_ref_method() {
let f = from_value(22);
assert *f.get_ref() == 22;
}
#[test]
fn test_get_ref_fn() {
pub fn test_get_ref_fn() {
let f = from_value(22);
assert *get_ref(&f) == 22;
}
#[test]
fn test_interface_with() {
pub fn test_interface_with() {
let f = from_value(~"kale");
assert f.with(|v| copy *v) == ~"kale";
}
#[test]
fn test_spawn() {
pub fn test_spawn() {
let f = spawn(|| ~"bale");
assert get(&f) == ~"bale";
}
@ -240,13 +228,13 @@ mod test {
#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_futurefail() {
pub fn test_futurefail() {
let f = spawn(|| fail);
let _x: ~str = get(&f);
}
#[test]
fn test_sendable_future() {
pub fn test_sendable_future() {
let expected = ~"schlorf";
let f = do spawn |copy expected| { copy expected };
do task::spawn {

View file

@ -29,15 +29,11 @@ with destructors.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use stackwalk::Word;
pub use stackwalk::Word;
use libc::size_t;
use libc::uintptr_t;
use send_map::linear::LinearMap;
export Word;
export gc;
export cleanup_stack_for_failure;
// Mirrors rust_stack.h stk_seg
struct StackSegment {
prev: *StackSegment,
@ -268,7 +264,7 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) {
}
}
fn gc() {
pub fn gc() {
unsafe {
// Abort when GC is disabled.
if get_safe_point_count() == 0 {
@ -301,7 +297,7 @@ fn expect_sentinel() -> bool { false }
// This should only be called from fail, as it will drop the roots
// which are *live* on the stack, rather than dropping those that are
// dead.
fn cleanup_stack_for_failure() {
pub fn cleanup_stack_for_failure() {
unsafe {
// Abort when GC is disabled.
if get_safe_point_count() == 0 {
@ -320,7 +316,7 @@ fn cleanup_stack_for_failure() {
// own stack roots on the stack anyway.
let sentinel_box = ~0;
let sentinel: **Word = if expect_sentinel() {
cast::reinterpret_cast(&ptr::addr_of(sentinel_box))
cast::reinterpret_cast(&ptr::addr_of(&sentinel_box))
} else {
ptr::null()
};

View file

@ -17,9 +17,6 @@ use io::Writer;
use io::WriterUtil;
use to_bytes::IterBytes;
export Streaming, State, Hash, HashUtil;
export default_state;
/**
* Types that can meaningfully be hashed should implement this.
*
@ -32,7 +29,7 @@ export default_state;
* the rest. This is the recommended approach, since constructing
* good keyed hash functions is quite difficult.
*/
trait Hash {
pub trait Hash {
/**
* Compute a "keyed" hash of the value implementing the trait,
* taking `k0` and `k1` as "keying" parameters that randomize or
@ -49,7 +46,7 @@ trait Hash {
}
// When we have default methods, won't need this.
trait HashUtil {
pub trait HashUtil {
pure fn hash() -> u64;
}
@ -59,7 +56,7 @@ impl <A: Hash> A: HashUtil {
}
/// Streaming hash-functions should implement this.
trait Streaming {
pub trait Streaming {
fn input((&[const u8]));
// These can be refactored some when we have default methods.
fn result_bytes() -> ~[u8];
@ -139,15 +136,15 @@ pure fn hash_keyed_5<A: IterBytes,
// Implement State as SipState
type State = SipState;
pub type State = SipState;
#[inline(always)]
fn State(k0: u64, k1: u64) -> State {
pub fn State(k0: u64, k1: u64) -> State {
SipState(k0, k1)
}
#[inline(always)]
fn default_state() -> State {
pub fn default_state() -> State {
State(0,0)
}
@ -361,7 +358,7 @@ impl &SipState : Streaming {
}
#[test]
fn test_siphash() {
pub fn test_siphash() {
let vecs : [[u8]/8]/64 = [
[ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ]/_,
[ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ]/_,
@ -468,26 +465,26 @@ fn test_siphash() {
}
#[test] #[cfg(target_arch = "arm")]
fn test_hash_uint() {
pub fn test_hash_uint() {
let val = 0xdeadbeef_deadbeef_u64;
assert (val as u64).hash() != (val as uint).hash();
assert (val as u32).hash() == (val as uint).hash();
}
#[test] #[cfg(target_arch = "x86_64")]
fn test_hash_uint() {
pub fn test_hash_uint() {
let val = 0xdeadbeef_deadbeef_u64;
assert (val as u64).hash() == (val as uint).hash();
assert (val as u32).hash() != (val as uint).hash();
}
#[test] #[cfg(target_arch = "x86")]
fn test_hash_uint() {
pub fn test_hash_uint() {
let val = 0xdeadbeef_deadbeef_u64;
assert (val as u64).hash() != (val as uint).hash();
assert (val as u32).hash() == (val as uint).hash();
}
#[test]
fn test_hash_idempotent() {
pub fn test_hash_idempotent() {
let val64 = 0xdeadbeef_deadbeef_u64;
val64.hash() == val64.hash();
let val32 = 0xdeadbeef_u32;
@ -495,7 +492,7 @@ fn test_hash_idempotent() {
}
#[test]
fn test_hash_no_bytes_dropped_64() {
pub fn test_hash_no_bytes_dropped_64() {
let val = 0xdeadbeef_deadbeef_u64;
assert val.hash() != zero_byte(val, 0).hash();
@ -514,7 +511,7 @@ fn test_hash_no_bytes_dropped_64() {
}
#[test]
fn test_hash_no_bytes_dropped_32() {
pub fn test_hash_no_bytes_dropped_32() {
let val = 0xdeadbeef_u32;
assert val.hash() != zero_byte(val, 0).hash();

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use T = inst::T;
@ -7,49 +7,36 @@ use cmp::{Eq, Ord};
use from_str::FromStr;
use num::from_int;
export min_value, max_value;
export min, max;
export add, sub, mul, div, rem;
export lt, le, eq, ne, ge, gt;
export is_positive, is_negative;
export is_nonpositive, is_nonnegative;
export range;
export compl;
export abs;
export parse_bytes, from_str, to_str, to_str_bytes, str;
export num, ord, eq, times, timesi;
export bits, bytes;
pub const bits : uint = inst::bits;
pub const bytes : uint = (inst::bits / 8);
const bits : uint = inst::bits;
const bytes : uint = (inst::bits / 8);
pub const min_value: T = (-1 as T) << (bits - 1);
pub const max_value: T = min_value - 1 as T;
const min_value: T = (-1 as T) << (bits - 1);
const max_value: T = min_value - 1 as T;
pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
pub pure fn add(x: T, y: T) -> T { x + y }
pub pure fn sub(x: T, y: T) -> T { x - y }
pub pure fn mul(x: T, y: T) -> T { x * y }
pub pure fn div(x: T, y: T) -> T { x / y }
pub pure fn rem(x: T, y: T) -> T { x % y }
pure fn add(x: T, y: T) -> T { x + y }
pure fn sub(x: T, y: T) -> T { x - y }
pure fn mul(x: T, y: T) -> T { x * y }
pure fn div(x: T, y: T) -> T { x / y }
pure fn rem(x: T, y: T) -> T { x % y }
pub pure fn lt(x: T, y: T) -> bool { x < y }
pub pure fn le(x: T, y: T) -> bool { x <= y }
pub pure fn eq(x: T, y: T) -> bool { x == y }
pub pure fn ne(x: T, y: T) -> bool { x != y }
pub pure fn ge(x: T, y: T) -> bool { x >= y }
pub pure fn gt(x: T, y: T) -> bool { x > y }
pure fn lt(x: T, y: T) -> bool { x < y }
pure fn le(x: T, y: T) -> bool { x <= y }
pure fn eq(x: T, y: T) -> bool { x == y }
pure fn ne(x: T, y: T) -> bool { x != y }
pure fn ge(x: T, y: T) -> bool { x >= y }
pure fn gt(x: T, y: T) -> bool { x > y }
pure fn is_positive(x: T) -> bool { x > 0 as T }
pure fn is_negative(x: T) -> bool { x < 0 as T }
pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
pub pure fn is_positive(x: T) -> bool { x > 0 as T }
pub pure fn is_negative(x: T) -> bool { x < 0 as T }
pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
#[inline(always)]
/// Iterate over the range [`lo`..`hi`)
fn range(lo: T, hi: T, it: fn(T) -> bool) {
pub fn range(lo: T, hi: T, it: fn(T) -> bool) {
let mut i = lo;
while i < hi {
if !it(i) { break }
@ -58,13 +45,13 @@ fn range(lo: T, hi: T, it: fn(T) -> bool) {
}
/// Computes the bitwise complement
pure fn compl(i: T) -> T {
pub pure fn compl(i: T) -> T {
-1 as T ^ i
}
/// Computes the absolute value
// FIXME: abs should return an unsigned int (#2353)
pure fn abs(i: T) -> T {
pub pure fn abs(i: T) -> T {
if is_negative(i) { -i } else { i }
}
@ -81,11 +68,11 @@ impl T : Eq {
}
impl T: num::Num {
pure fn add(&&other: T) -> T { return self + other; }
pure fn sub(&&other: T) -> T { return self - other; }
pure fn mul(&&other: T) -> T { return self * other; }
pure fn div(&&other: T) -> T { return self / other; }
pure fn modulo(&&other: T) -> T { return self % other; }
pure fn add(other: &T) -> T { return self + *other; }
pure fn sub(other: &T) -> T { return self - *other; }
pure fn mul(other: &T) -> T { return self * *other; }
pure fn div(other: &T) -> T { return self / *other; }
pure fn modulo(other: &T) -> T { return self % *other; }
pure fn neg() -> T { return -self; }
pure fn to_int() -> int { return self as int; }
@ -137,7 +124,7 @@ impl T: iter::TimesIx {
* * buf - A byte buffer
* * radix - The base of the number
*/
fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
if vec::len(buf) == 0u { return None; }
let mut i = vec::len(buf) - 1u;
let mut start = 0u;
@ -160,14 +147,14 @@ fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
}
/// Parse a string to an int
fn from_str(s: &str) -> Option<T> { parse_bytes(str::to_bytes(s), 10u) }
pub fn from_str(s: &str) -> Option<T> { parse_bytes(str::to_bytes(s), 10u) }
impl T : FromStr {
static fn from_str(s: &str) -> Option<T> { from_str(s) }
}
/// Convert to a string in a given base
fn to_str(n: T, radix: uint) -> ~str {
pub fn to_str(n: T, radix: uint) -> ~str {
do to_str_bytes(n, radix) |slice| {
do vec::as_imm_buf(slice) |p, len| {
unsafe { str::raw::from_buf_len(p, len) }
@ -175,7 +162,7 @@ fn to_str(n: T, radix: uint) -> ~str {
}
}
fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
pub fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
if n < 0 as T {
uint::to_str_bytes(true, -n as uint, radix, f)
} else {
@ -184,7 +171,7 @@ fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
}
/// Convert to a string
fn str(i: T) -> ~str { return to_str(i, 10u); }
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
#[test]
@ -244,17 +231,17 @@ fn test_to_str() {
#[test]
fn test_interfaces() {
fn test<U:num::Num cmp::Eq>(+ten: U) {
fn test<U:num::Num cmp::Eq>(ten: U) {
assert (ten.to_int() == 10);
let two: U = from_int(2);
assert (two.to_int() == 2);
assert (ten.add(two) == from_int(12));
assert (ten.sub(two) == from_int(8));
assert (ten.mul(two) == from_int(20));
assert (ten.div(two) == from_int(5));
assert (ten.modulo(two) == from_int(0));
assert (ten.add(&two) == from_int(12));
assert (ten.sub(&two) == from_int(8));
assert (ten.mul(&two) == from_int(20));
assert (ten.div(&two) == from_int(5));
assert (ten.modulo(&two) == from_int(0));
assert (ten.neg() == from_int(-10));
}

View file

@ -1,2 +1,2 @@
type T = i16;
const bits: uint = u16::bits;
pub type T = i16;
pub const bits: uint = u16::bits;

View file

@ -1,2 +1,2 @@
type T = i32;
const bits: uint = u32::bits;
pub type T = i32;
pub const bits: uint = u32::bits;

View file

@ -1,2 +1,2 @@
type T = i64;
const bits: uint = u64::bits;
pub type T = i64;
pub const bits: uint = u64::bits;

View file

@ -1,2 +1,2 @@
type T = i8;
const bits: uint = u8::bits;
pub type T = i8;
pub const bits: uint = u8::bits;

View file

@ -1,8 +1,8 @@
type T = int;
const bits: uint = uint::bits;
pub type T = int;
pub const bits: uint = uint::bits;
/// Returns `base` raised to the power of `exponent`
fn pow(base: int, exponent: uint) -> int {
pub fn pow(base: int, exponent: uint) -> int {
if exponent == 0u { return 1; } //Not mathemtically true if ~[base == 0]
if base == 0 { return 0; }
let mut my_pow = exponent;

View file

@ -17,7 +17,6 @@ type fd_t = c_int;
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rust_get_stdin() -> *libc::FILE;
fn rust_get_stdout() -> *libc::FILE;
fn rust_get_stderr() -> *libc::FILE;
@ -27,11 +26,11 @@ extern mod rustrt {
// FIXME (#2004): This is all buffered. We might need an unbuffered variant
// as well
enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
// The raw underlying reader trait. All readers must implement this.
trait Reader {
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
// FIXME (#2982): This should probably return an error.
@ -45,19 +44,30 @@ trait Reader {
// Generic utility functions defined on readers
trait ReaderUtil {
pub trait ReaderUtil {
fn read_bytes(len: uint) -> ~[u8];
fn read_line() -> ~str;
fn read_chars(n: uint) -> ~[char];
fn read_char() -> char;
fn read_c_str() -> ~str;
fn read_le_uint(size: uint) -> uint;
fn read_le_int(size: uint) -> int;
fn read_be_uint(size: uint) -> uint;
fn read_whole_stream() -> ~[u8];
fn each_byte(it: fn(int) -> bool);
fn each_char(it: fn(char) -> bool);
fn each_line(it: fn((&str)) -> bool);
}
impl<T: Reader> T : ReaderUtil {
fn read_bytes(len: uint) -> ~[u8] {
let mut buf = vec::with_capacity(len);
unsafe { vec::raw::set_len(buf, len); }
unsafe { vec::raw::set_len(&mut buf, len); }
let count = self.read(buf, len);
unsafe { vec::raw::set_len(buf, count); }
unsafe { vec::raw::set_len(&mut buf, count); }
move buf
}
fn read_line() -> ~str {
@ -65,78 +75,78 @@ impl<T: Reader> T : ReaderUtil {
loop {
let ch = self.read_byte();
if ch == -1 || ch == 10 { break; }
vec::push(buf, ch as u8);
buf.push(ch as u8);
}
str::from_bytes(buf)
}
}
impl Reader {
fn read_chars(n: uint) -> ~[char] {
// returns the (consumed offset, n_req), appends characters to &chars
fn chars_from_bytes(buf: ~[u8], &chars: ~[char]) -> (uint, uint) {
let mut i = 0u;
while i < vec::len(buf) {
fn chars_from_bytes<T: Reader>(buf: &~[u8], chars: &mut ~[char])
-> (uint, uint) {
let mut i = 0;
let buf_len = buf.len();
while i < buf_len {
let b0 = buf[i];
let w = str::utf8_char_width(b0);
let end = i + w;
i += 1u;
assert (w > 0u);
if w == 1u {
vec::push(chars, b0 as char );
i += 1;
assert (w > 0);
if w == 1 {
chars.push(b0 as char);
loop;
}
// can't satisfy this char with the existing data
if end > vec::len(buf) {
return (i - 1u, end - vec::len(buf));
if end > buf_len {
return (i - 1, end - buf_len);
}
let mut val = 0u;
let mut val = 0;
while i < end {
let next = buf[i] as int;
i += 1u;
i += 1;
assert (next > -1);
assert (next & 192 == 128);
val <<= 6u;
val <<= 6;
val += (next & 63) as uint;
}
// See str::char_at
val += ((b0 << ((w + 1u) as u8)) as uint)
<< (w - 1u) * 6u - w - 1u;
vec::push(chars, val as char );
val += ((b0 << ((w + 1) as u8)) as uint)
<< (w - 1) * 6 - w - 1u;
chars.push(val as char);
}
return (i, 0u);
return (i, 0);
}
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 {
while nbread > 0 {
let data = self.read_bytes(nbread);
if vec::len(data) == 0u {
if data.is_empty() {
// eof - FIXME (#2004): should we do something if
// we're split in a unicode char?
break;
}
vec::push_all(buf, data);
let (offset, nbreq) = chars_from_bytes(buf, chars);
let ncreq = n - vec::len(chars);
buf.push_all(data);
let (offset, nbreq) = chars_from_bytes::<T>(&buf, &mut chars);
let ncreq = n - chars.len();
// 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));
if nbread > 0 {
buf = vec::slice(buf, offset, buf.len());
}
}
move chars
}
fn read_char() -> char {
let c = self.read_chars(1u);
if vec::len(c) == 0u {
let c = self.read_chars(1);
if vec::len(c) == 0 {
return -1 as char; // FIXME will this stay valid? // #2004
}
assert(vec::len(c) == 1u);
assert(vec::len(c) == 1);
return c[0];
}
@ -144,7 +154,7 @@ impl Reader {
let mut buf: ~[u8] = ~[];
loop {
let ch = self.read_byte();
if ch < 1 { break; } else { vec::push(buf, ch as u8); }
if ch < 1 { break; } else { buf.push(ch as u8); }
}
str::from_bytes(buf)
}
@ -179,7 +189,7 @@ impl Reader {
fn read_whole_stream() -> ~[u8] {
let mut buf: ~[u8] = ~[];
while !self.eof() { vec::push_all(buf, self.read_bytes(2048u)); }
while !self.eof() { buf.push_all(self.read_bytes(2048u)); }
move buf
}
@ -195,7 +205,7 @@ impl Reader {
}
}
fn each_line(it: fn(~str) -> bool) {
fn each_line(it: fn(s: &str) -> bool) {
while !self.eof() {
if !it(self.read_line()) { break; }
}
@ -256,7 +266,7 @@ fn FILERes(f: *libc::FILE) -> FILERes {
}
}
fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
if cleanup {
{base: f, cleanup: FILERes(f)} as Reader
} else {
@ -268,9 +278,9 @@ fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
// 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 }
pub fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader }
fn file_reader(path: &Path) -> Result<Reader, ~str> {
pub fn file_reader(path: &Path) -> Result<Reader, ~str> {
let f = os::as_c_charp(path.to_str(), |pathbuf| {
os::as_c_charp("r", |modebuf|
libc::fopen(pathbuf, modebuf)
@ -286,7 +296,7 @@ fn file_reader(path: &Path) -> Result<Reader, ~str> {
// Byte buffer readers
type ByteBuf = {buf: &[const u8], mut pos: uint};
pub type ByteBuf = {buf: &[const u8], mut pos: uint};
impl ByteBuf: Reader {
fn read(buf: &[mut u8], len: uint) -> uint {
@ -315,21 +325,21 @@ impl ByteBuf: Reader {
fn tell() -> uint { self.pos }
}
fn with_bytes_reader<t>(bytes: &[u8], f: fn(Reader) -> t) -> t {
pub fn with_bytes_reader<t>(bytes: &[u8], f: fn(Reader) -> t) -> t {
f({buf: bytes, mut pos: 0u} as Reader)
}
fn with_str_reader<T>(s: &str, f: fn(Reader) -> T) -> T {
pub fn with_str_reader<T>(s: &str, f: fn(Reader) -> T) -> T {
str::byte_slice(s, |bytes| with_bytes_reader(bytes, f))
}
// Writing
enum FileFlag { Append, Create, Truncate, NoFlag, }
pub enum FileFlag { Append, Create, Truncate, NoFlag, }
// What type of writer are we?
enum WriterType { Screen, File }
pub enum WriterType { Screen, File }
impl WriterType : Eq {
pub impl WriterType : Eq {
pure fn eq(other: &WriterType) -> bool {
match (self, (*other)) {
(Screen, Screen) | (File, File) => true,
@ -341,7 +351,7 @@ impl WriterType : Eq {
// FIXME (#2004): Seekable really should be orthogonal.
// FIXME (#2004): eventually u64
trait Writer {
pub trait Writer {
fn write(v: &[const u8]);
fn seek(int, SeekStyle);
fn tell() -> uint;
@ -382,7 +392,7 @@ impl *libc::FILE: Writer {
}
}
fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer {
pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer {
if cleanup {
{base: f, cleanup: FILERes(f)} as Writer
} else {
@ -431,7 +441,7 @@ fn FdRes(fd: fd_t) -> FdRes {
}
}
fn fd_writer(fd: fd_t, cleanup: bool) -> Writer {
pub fn fd_writer(fd: fd_t, cleanup: bool) -> Writer {
if cleanup {
{base: fd, cleanup: FdRes(fd)} as Writer
} else {
@ -440,7 +450,7 @@ fn fd_writer(fd: fd_t, cleanup: bool) -> Writer {
}
fn mk_file_writer(path: &Path, flags: ~[FileFlag])
pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-> Result<Writer, ~str> {
#[cfg(windows)]
@ -470,7 +480,8 @@ fn mk_file_writer(path: &Path, flags: ~[FileFlag])
}
}
fn u64_to_le_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
pub fn u64_to_le_bytes<T>(n: u64, size: uint,
f: fn(v: &[u8]) -> T) -> T {
assert size <= 8u;
match size {
1u => f(&[n as u8]),
@ -492,7 +503,7 @@ fn u64_to_le_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
let mut bytes: ~[u8] = ~[], i = size, n = n;
while i > 0u {
vec::push(bytes, (n & 255_u64) as u8);
bytes.push((n & 255_u64) as u8);
n >>= 8_u64;
i -= 1u;
}
@ -501,7 +512,8 @@ fn u64_to_le_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
}
}
fn u64_to_be_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
pub fn u64_to_be_bytes<T>(n: u64, size: uint,
f: fn(v: &[u8]) -> T) -> T {
assert size <= 8u;
match size {
1u => f(&[n as u8]),
@ -524,7 +536,7 @@ fn u64_to_be_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
let mut i = size;
while i > 0u {
let shift = ((i - 1u) * 8u) as u64;
vec::push(bytes, (n >> shift) as u8);
bytes.push((n >> shift) as u8);
i -= 1u;
}
f(bytes)
@ -532,7 +544,8 @@ fn u64_to_be_bytes<T>(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T {
}
}
fn u64_from_be_bytes(data: &[const u8], start: uint, size: uint) -> u64 {
pub fn u64_from_be_bytes(data: &[const u8],
start: uint, size: uint) -> u64 {
let mut sz = size;
assert (sz <= 8u);
let mut val = 0_u64;
@ -547,7 +560,7 @@ fn u64_from_be_bytes(data: &[const u8], start: uint, size: uint) -> u64 {
// FIXME: #3048 combine trait+impl (or just move these to
// default methods on writer)
trait WriterUtil {
pub trait WriterUtil {
fn write_char(ch: char);
fn write_str(s: &str);
fn write_line(s: &str);
@ -644,13 +657,13 @@ impl<T: Writer> T : WriterUtil {
}
#[allow(non_implicitly_copyable_typarams)]
fn file_writer(path: &Path, flags: ~[FileFlag]) -> Result<Writer, ~str> {
result::chain(mk_file_writer(path, flags), |w| result::Ok(w))
pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<Writer, ~str> {
mk_file_writer(path, flags).chain(|w| result::Ok(w))
}
// FIXME: fileflags // #2004
fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
pub fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
let f = do os::as_c_charp(path.to_str()) |pathbuf| {
do os::as_c_charp("w") |modebuf| {
libc::fopen(pathbuf, modebuf)
@ -664,13 +677,13 @@ fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
// FIXME (#2004) it would be great if this could be a const
// FIXME (#2004) 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) }
pub fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
pub 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); }
pub fn print(s: &str) { stdout().write_str(s); }
pub fn println(s: &str) { stdout().write_line(s); }
struct BytesWriter {
pub struct BytesWriter {
buf: DVec<u8>,
mut pos: uint,
}
@ -684,10 +697,12 @@ impl BytesWriter: Writer {
let count = uint::max(buf_len, self.pos + v_len);
vec::reserve(&mut buf, count);
unsafe { vec::raw::set_len(buf, count); }
unsafe { vec::raw::set_len(&mut buf, count); }
let view = vec::mut_view(buf, self.pos, count);
vec::bytes::memcpy(view, v, v_len);
{
let view = vec::mut_view(buf, self.pos, count);
vec::bytes::memcpy(view, v, v_len);
}
self.pos += v_len;
@ -712,28 +727,28 @@ impl @BytesWriter : Writer {
fn get_type() -> WriterType { (*self).get_type() }
}
fn BytesWriter() -> BytesWriter {
pub fn BytesWriter() -> BytesWriter {
BytesWriter { buf: DVec(), mut pos: 0u }
}
fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
pub fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
let wr = @BytesWriter();
f(wr as Writer);
wr.buf.check_out(|buf| buf)
}
fn with_str_writer(f: fn(Writer)) -> ~str {
pub fn with_str_writer(f: fn(Writer)) -> ~str {
let mut v = with_bytes_writer(f);
// Make sure the vector has a trailing null and is proper utf8.
vec::push(v, 0);
v.push(0);
assert str::is_utf8(v);
unsafe { move ::cast::transmute(v) }
}
// Utility functions
fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
uint {
let mut bpos = pos as int;
let blen = len as int;
@ -747,7 +762,7 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
}
#[allow(non_implicitly_copyable_typarams)]
fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
result::chain(read_whole_file(file), |bytes| {
if str::is_utf8(bytes) {
result::Ok(str::from_bytes(bytes))
@ -760,7 +775,7 @@ fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
// FIXME (#2004): implement this in a low-level way. Going through the
// abstractions is pointless.
#[allow(non_implicitly_copyable_typarams)]
fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
result::chain(file_reader(file), |rdr| {
result::Ok(rdr.read_whole_stream())
})
@ -768,10 +783,9 @@ fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
// fsync related
mod fsync {
#[legacy_exports];
pub mod fsync {
enum Level {
pub enum Level {
// whatever fsync does on that platform
FSync,
@ -786,7 +800,7 @@ mod fsync {
// Artifacts that need to fsync on destruction
struct Res<t> {
pub struct Res<t: Copy> {
arg: Arg<t>,
drop {
match self.arg.opt_level {
@ -799,51 +813,51 @@ mod fsync {
}
}
fn Res<t>(-arg: Arg<t>) -> Res<t>{
pub fn Res<t: Copy>(arg: Arg<t>) -> Res<t>{
Res {
arg: move arg
}
}
type Arg<t> = {
pub type Arg<t> = {
val: t,
opt_level: Option<Level>,
fsync_fn: fn@(t, Level) -> int
fsync_fn: fn@(f: t, Level) -> int
};
// fsync file after executing blk
// FIXME (#2004) find better way to create resources within lifetime of
// outer res
fn FILE_res_sync(&&file: FILERes, opt_level: Option<Level>,
blk: fn(&&v: Res<*libc::FILE>)) {
blk(Res({
pub fn FILE_res_sync(file: &FILERes, opt_level: Option<Level>,
blk: fn(v: Res<*libc::FILE>)) {
blk(move Res({
val: file.f, opt_level: opt_level,
fsync_fn: fn@(&&file: *libc::FILE, l: Level) -> int {
fsync_fn: fn@(file: *libc::FILE, l: Level) -> int {
return os::fsync_fd(libc::fileno(file), l) as int;
}
}));
}
// fsync fd after executing blk
fn fd_res_sync(&&fd: FdRes, opt_level: Option<Level>,
blk: fn(&&v: Res<fd_t>)) {
blk(Res({
pub fn fd_res_sync(fd: &FdRes, opt_level: Option<Level>,
blk: fn(v: Res<fd_t>)) {
blk(move Res({
val: fd.fd, opt_level: opt_level,
fsync_fn: fn@(&&fd: fd_t, l: Level) -> int {
fsync_fn: fn@(fd: fd_t, l: Level) -> int {
return os::fsync_fd(fd, l) as int;
}
}));
}
// Type of objects that may want to fsync
trait FSyncable { fn fsync(l: Level) -> int; }
pub trait FSyncable { fn fsync(l: Level) -> int; }
// Call o.fsync after executing blk
fn obj_sync(&&o: FSyncable, opt_level: Option<Level>,
blk: fn(&&v: Res<FSyncable>)) {
pub fn obj_sync(o: FSyncable, opt_level: Option<Level>,
blk: fn(v: Res<FSyncable>)) {
blk(Res({
val: o, opt_level: opt_level,
fsync_fn: fn@(&&o: FSyncable, l: Level) -> int {
fsync_fn: fn@(o: FSyncable, l: Level) -> int {
return o.fsync(l);
}
}));
@ -852,7 +866,6 @@ mod fsync {
#[cfg(test)]
mod tests {
#[legacy_exports];
#[test]
fn test_simple() {
@ -864,10 +877,10 @@ mod tests {
{
let out: io::Writer =
result::get(
io::file_writer(tmpfile, ~[io::Create, io::Truncate]));
&io::file_writer(tmpfile, ~[io::Create, io::Truncate]));
out.write_str(frood);
}
let inp: io::Reader = result::get(io::file_reader(tmpfile));
let inp: io::Reader = result::get(&io::file_reader(tmpfile));
let frood2: ~str = inp.read_c_str();
log(debug, frood2);
assert frood == frood2;
@ -876,8 +889,8 @@ mod tests {
#[test]
fn test_readchars_empty() {
do io::with_str_reader(~"") |inp| {
let res : ~[char] = inp.read_chars(128u);
assert(vec::len(res) == 0u);
let res : ~[char] = inp.read_chars(128);
assert(vec::len(res) == 0);
}
}
@ -890,7 +903,7 @@ mod tests {
104, 101, 108, 108, 111,
29983, 38152, 30340, 27748,
21273, 20999, 32905, 27748];
fn check_read_ln(len : uint, s: ~str, ivals: ~[int]) {
fn check_read_ln(len : uint, s: &str, ivals: &[int]) {
do io::with_str_reader(s) |inp| {
let res : ~[char] = inp.read_chars(len);
if (len <= vec::len(ivals)) {
@ -900,13 +913,13 @@ mod tests {
vec::map(res, |x| *x as int));
}
}
let mut i = 0u;
while i < 8u {
let mut i = 0;
while i < 8 {
check_read_ln(i, wide_test, ivals);
i += 1u;
i += 1;
}
// check a long read for good measure
check_read_ln(128u, wide_test, ivals);
check_read_ln(128, wide_test, ivals);
}
#[test]
@ -928,7 +941,7 @@ mod tests {
#[test]
fn file_reader_not_exist() {
match io::file_reader(&Path("not a file")) {
result::Err(e) => {
result::Err(copy e) => {
assert e == ~"error opening not a file";
}
result::Ok(_) => fail
@ -938,7 +951,7 @@ mod tests {
#[test]
fn file_writer_bad_name() {
match io::file_writer(&Path("?/?"), ~[]) {
result::Err(e) => {
result::Err(copy e) => {
assert str::starts_with(e, "error opening");
}
result::Ok(_) => fail
@ -948,7 +961,7 @@ mod tests {
#[test]
fn buffered_file_writer_bad_name() {
match io::buffered_file_writer(&Path("?/?")) {
result::Err(e) => {
result::Err(copy e) => {
assert str::starts_with(e, "error opening");
}
result::Ok(_) => fail

View file

@ -2,51 +2,52 @@
// workaround our lack of traits and lack of macros. See core.{rc,rs} for
// how this file is used.
#[warn(deprecated_mode)];
use cmp::{Eq, Ord};
use inst::{IMPL_T, EACH, SIZE_HINT};
export extensions;
impl<A> IMPL_T<A>: iter::BaseIter<A> {
pure fn each(blk: fn(v: &A) -> bool) { EACH(self, blk) }
pure fn size_hint() -> Option<uint> { SIZE_HINT(self) }
pure fn each(blk: fn(v: &A) -> bool) { EACH(&self, blk) }
pure fn size_hint() -> Option<uint> { SIZE_HINT(&self) }
}
impl<A> IMPL_T<A>: iter::ExtendedIter<A> {
pure fn eachi(blk: fn(uint, v: &A) -> bool) { iter::eachi(self, blk) }
pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B {
iter::foldl(self, move b0, blk)
pure fn eachi(blk: fn(uint, v: &A) -> bool) { iter::eachi(&self, blk) }
pure fn all(blk: fn(&A) -> bool) -> bool { iter::all(&self, blk) }
pure fn any(blk: fn(&A) -> bool) -> bool { iter::any(&self, blk) }
pure fn foldl<B>(b0: B, blk: fn(&B, &A) -> B) -> B {
iter::foldl(&self, move b0, blk)
}
pure fn position(f: fn(A) -> bool) -> Option<uint> {
iter::position(self, f)
pure fn position(f: fn(&A) -> bool) -> Option<uint> {
iter::position(&self, f)
}
}
impl<A: Eq> IMPL_T<A>: iter::EqIter<A> {
pure fn contains(x: A) -> bool { iter::contains(self, x) }
pure fn count(x: A) -> uint { iter::count(self, x) }
pure fn contains(x: &A) -> bool { iter::contains(&self, x) }
pure fn count(x: &A) -> uint { iter::count(&self, x) }
}
impl<A: Copy> IMPL_T<A>: iter::CopyableIter<A> {
pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] {
iter::filter_to_vec(self, pred)
pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A] {
iter::filter_to_vec(&self, pred)
}
pure fn map_to_vec<B>(op: fn(v: &A) -> B) -> ~[B] {
iter::map_to_vec(self, op)
pure fn map_to_vec<B>(op: fn(v: A) -> B) -> ~[B] {
iter::map_to_vec(&self, op)
}
pure fn to_vec() -> ~[A] { iter::to_vec(self) }
pure fn to_vec() -> ~[A] { iter::to_vec(&self) }
// FIXME--bug in resolve prevents this from working (#2611)
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> ~[B] {
// iter::flat_map_to_vec(self, op)
// }
pure fn flat_map_to_vec<B:Copy,IB:BaseIter<B>>(op: fn(a: A) -> IB)
-> ~[B] {
iter::flat_map_to_vec(&self, op)
}
pure fn find(p: fn(A) -> bool) -> Option<A> { iter::find(self, p) }
pure fn find(p: fn(a: A) -> bool) -> Option<A> { iter::find(&self, p) }
}
impl<A: Copy Ord> IMPL_T<A>: iter::CopyableOrderedIter<A> {
pure fn min() -> A { iter::min(self) }
pure fn max() -> A { iter::max(self) }
pure fn min() -> A { iter::min(&self) }
pure fn max() -> A { iter::max(&self) }
}

View file

@ -1,5 +1,5 @@
#[allow(non_camel_case_types)]
type IMPL_T<A> = dlist::DList<A>;
pub type IMPL_T<A> = dlist::DList<A>;
/**
* Iterates through the current contents.
@ -8,7 +8,7 @@ type IMPL_T<A> = dlist::DList<A>;
* e.g. breadth-first search with in-place enqueues), but removing the current
* node is forbidden.
*/
pure fn EACH<A>(self: IMPL_T<A>, f: fn(v: &A) -> bool) {
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
let mut link = self.peek_n();
while option::is_some(&link) {
let nobe = option::get(&link);
@ -29,6 +29,6 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(v: &A) -> bool) {
}
}
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> Option<uint> {
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
Some(self.len())
}

View file

@ -1,12 +1,12 @@
#[allow(non_camel_case_types)]
type IMPL_T<A> = dvec::DVec<A>;
pub type IMPL_T<A> = dvec::DVec<A>;
/**
* Iterates through the current contents.
*
* Attempts to access this dvec during iteration will fail.
*/
pure fn EACH<A>(self: IMPL_T<A>, f: fn(v: &A) -> bool) {
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
unsafe {
do self.swap |v| {
v.each(f);
@ -15,6 +15,6 @@ pure fn EACH<A>(self: IMPL_T<A>, f: fn(v: &A) -> bool) {
}
}
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> Option<uint> {
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
Some(self.len())
}

View file

@ -1,16 +1,16 @@
#[allow(non_camel_case_types)]
type IMPL_T<A> = Option<A>;
pub type IMPL_T<A> = Option<A>;
pure fn EACH<A>(self: IMPL_T<A>, f: fn(v: &A) -> bool) {
match self {
pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
match *self {
None => (),
Some(ref a) => { f(a); }
}
}
pure fn SIZE_HINT<A>(self: IMPL_T<A>) -> Option<uint> {
match self {
None => Some(0u),
Some(_) => Some(1u)
pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
match *self {
None => Some(0),
Some(_) => Some(1)
}
}

View file

@ -7,48 +7,49 @@ The iteration traits and common implementation
use cmp::{Eq, Ord};
/// A function used to initialize the elements of a sequence
type InitOp<T> = fn(uint) -> T;
pub type InitOp<T> = &fn(uint) -> T;
trait BaseIter<A> {
pub trait BaseIter<A> {
pure fn each(blk: fn(v: &A) -> bool);
pure fn size_hint() -> Option<uint>;
}
trait ExtendedIter<A> {
pub trait ExtendedIter<A> {
pure fn eachi(blk: fn(uint, v: &A) -> bool);
pure fn all(blk: fn(A) -> bool) -> bool;
pure fn any(blk: fn(A) -> bool) -> bool;
pure fn foldl<B>(+b0: B, blk: fn(B, A) -> B) -> B;
pure fn position(f: fn(A) -> bool) -> Option<uint>;
pure fn all(blk: fn(&A) -> bool) -> bool;
pure fn any(blk: fn(&A) -> bool) -> bool;
pure fn foldl<B>(b0: B, blk: fn(&B, &A) -> B) -> B;
pure fn position(f: fn(&A) -> bool) -> Option<uint>;
}
trait EqIter<A:Eq> {
pure fn contains(x: A) -> bool;
pure fn count(x: A) -> uint;
pub trait EqIter<A:Eq> {
pure fn contains(x: &A) -> bool;
pure fn count(x: &A) -> uint;
}
trait Times {
pub trait Times {
pure fn times(it: fn() -> bool);
}
trait TimesIx{
pub trait TimesIx{
pure fn timesi(it: fn(uint) -> bool);
}
trait CopyableIter<A:Copy> {
pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];
pure fn map_to_vec<B>(op: fn(v: &A) -> B) -> ~[B];
pub trait CopyableIter<A:Copy> {
pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A];
pure fn map_to_vec<B>(op: fn(v: A) -> B) -> ~[B];
pure fn to_vec() -> ~[A];
pure fn find(p: fn(A) -> bool) -> Option<A>;
pure fn find(p: fn(a: A) -> bool) -> Option<A>;
}
trait CopyableOrderedIter<A:Copy Ord> {
pub trait CopyableOrderedIter<A:Copy Ord> {
pure fn min() -> A;
pure fn max() -> A;
}
// A trait for sequences that can be by imperatively pushing elements
// onto them.
trait Buildable<A> {
pub trait Buildable<A> {
/**
* Builds a buildable sequence by calling a provided function with
* an argument function that pushes an element onto the back of
@ -63,33 +64,36 @@ trait Buildable<A> {
* onto the sequence being constructed.
*/
static pure fn build_sized(size: uint,
builder: fn(push: pure fn(+v: A))) -> self;
builder: fn(push: pure fn(v: A))) -> self;
}
pure fn eachi<A,IA:BaseIter<A>>(self: IA, blk: fn(uint, v: &A) -> bool) {
let mut i = 0u;
pub pure fn eachi<A,IA:BaseIter<A>>(self: &IA,
blk: fn(uint, v: &A) -> bool) {
let mut i = 0;
for self.each |a| {
if !blk(i, a) { break; }
i += 1u;
i += 1;
}
}
pure fn all<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
pub pure fn all<A,IA:BaseIter<A>>(self: &IA,
blk: fn(&A) -> bool) -> bool {
for self.each |a| {
if !blk(*a) { return false; }
if !blk(a) { return false; }
}
return true;
}
pure fn any<A,IA:BaseIter<A>>(self: IA, blk: fn(A) -> bool) -> bool {
pub pure fn any<A,IA:BaseIter<A>>(self: &IA,
blk: fn(&A) -> bool) -> bool {
for self.each |a| {
if blk(*a) { return true; }
if blk(a) { return true; }
}
return false;
}
pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: IA,
prd: fn(A) -> bool) -> ~[A] {
pub pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(
self: &IA, prd: fn(a: A) -> bool) -> ~[A] {
do vec::build_sized_opt(self.size_hint()) |push| {
for self.each |a| {
if prd(*a) { push(*a); }
@ -97,18 +101,18 @@ pure fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: IA,
}
}
pure fn map_to_vec<A:Copy,B,IA:BaseIter<A>>(self: IA, op: fn(v: &A) -> B)
pub pure fn map_to_vec<A:Copy,B,IA:BaseIter<A>>(self: &IA,
op: fn(v: A) -> B)
-> ~[B] {
do vec::build_sized_opt(self.size_hint()) |push| {
for self.each |a| {
push(op(a));
push(op(*a));
}
}
}
pure fn flat_map_to_vec<A:Copy,B:Copy,IA:BaseIter<A>,IB:BaseIter<B>>(
self: IA, op: fn(A) -> IB) -> ~[B] {
pub pure fn flat_map_to_vec<A:Copy,B:Copy,IA:BaseIter<A>,IB:BaseIter<B>>(
self: &IA, op: fn(a: A) -> IB) -> ~[B] {
do vec::build |push| {
for self.each |a| {
for op(*a).each |b| {
@ -118,41 +122,43 @@ pure fn flat_map_to_vec<A:Copy,B:Copy,IA:BaseIter<A>,IB:BaseIter<B>>(
}
}
pure fn foldl<A,B,IA:BaseIter<A>>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B {
pub pure fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B,
blk: fn(&B, &A) -> B)
-> B {
let mut b <- b0;
for self.each |a| {
b = blk(b, *a);
b = blk(&b, a);
}
move b
}
pure fn to_vec<A:Copy,IA:BaseIter<A>>(self: IA) -> ~[A] {
foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(copy r, ~[a]))
pub pure fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] {
foldl::<A,~[A],IA>(self, ~[], |r, a| vec::append(copy (*r), ~[*a]))
}
pure fn contains<A:Eq,IA:BaseIter<A>>(self: IA, x: A) -> bool {
pub pure fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool {
for self.each |a| {
if *a == x { return true; }
if *a == *x { return true; }
}
return false;
}
pure fn count<A:Eq,IA:BaseIter<A>>(self: IA, x: A) -> uint {
do foldl(self, 0u) |count, value| {
if value == x {
count + 1u
pub pure fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint {
do foldl(self, 0) |count, value| {
if *value == *x {
*count + 1
} else {
count
*count
}
}
}
pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
pub pure fn position<A,IA:BaseIter<A>>(self: &IA, f: fn(&A) -> bool)
-> Option<uint>
{
let mut i = 0;
for self.each |a| {
if f(*a) { return Some(i); }
if f(a) { return Some(i); }
i += 1;
}
return None;
@ -162,48 +168,44 @@ pure fn position<A,IA:BaseIter<A>>(self: IA, f: fn(A) -> bool)
// iter interface, such as would provide "reach" in addition to "each". as is,
// it would have to be implemented with foldr, which is too inefficient.
pure fn repeat(times: uint, blk: fn() -> bool) {
let mut i = 0u;
pub pure fn repeat(times: uint, blk: fn() -> bool) {
let mut i = 0;
while i < times {
if !blk() { break }
i += 1u;
i += 1;
}
}
pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
pub pure fn min<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
match a {
Some(a_) if a_ < b => {
// FIXME (#2005): Not sure if this is successfully optimized to
// a move
a
&Some(ref a_) if *a_ < *b => {
*(move a)
}
_ => Some(b)
_ => Some(*b)
}
} {
Some(val) => val,
Some(move val) => val,
None => fail ~"min called on empty iterator"
}
}
pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: IA) -> A {
pub pure fn max<A:Copy Ord,IA:BaseIter<A>>(self: &IA) -> A {
match do foldl::<A,Option<A>,IA>(self, None) |a, b| {
match a {
Some(a_) if a_ > b => {
// FIXME (#2005): Not sure if this is successfully optimized to
// a move.
a
&Some(ref a_) if *a_ > *b => {
*(move a)
}
_ => Some(b)
_ => Some(*b)
}
} {
Some(val) => val,
Some(move val) => val,
None => fail ~"max called on empty iterator"
}
}
pure fn find<A: Copy,IA:BaseIter<A>>(self: IA,
p: fn(A) -> bool) -> Option<A> {
pub pure fn find<A: Copy,IA:BaseIter<A>>(self: &IA,
p: fn(a: A) -> bool) -> Option<A> {
for self.each |i| {
if p(*i) { return Some(*i) }
}
@ -223,7 +225,8 @@ pure fn find<A: Copy,IA:BaseIter<A>>(self: IA,
* onto the sequence being constructed.
*/
#[inline(always)]
pure fn build<A,B: Buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
pub pure fn build<A,B: Buildable<A>>(builder: fn(push: pure fn(v: A)))
-> B {
build_sized(4, builder)
}
@ -241,9 +244,9 @@ pure fn build<A,B: Buildable<A>>(builder: fn(push: pure fn(+v: A))) -> B {
* onto the sequence being constructed.
*/
#[inline(always)]
pure fn build_sized_opt<A,B: Buildable<A>>(
pub pure fn build_sized_opt<A,B: Buildable<A>>(
size: Option<uint>,
builder: fn(push: pure fn(+v: A))) -> B {
builder: fn(push: pure fn(v: A))) -> B {
build_sized(size.get_default(4), builder)
}
@ -251,10 +254,11 @@ pure fn build_sized_opt<A,B: Buildable<A>>(
// Functions that combine iteration and building
/// Apply a function to each element of an iterable and return the results
fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: IT, f: fn(T) -> U) -> BU {
pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: fn(&T) -> U)
-> BU {
do build_sized_opt(v.size_hint()) |push| {
for v.each() |elem| {
push(f(*elem));
push(f(elem));
}
}
}
@ -265,7 +269,8 @@ fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: IT, f: fn(T) -> U) -> BU {
* Creates a generic sequence of size `n_elts` and initializes the elements
* to the value returned by the function `op`.
*/
pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
pub pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint,
op: InitOp<T>) -> BT {
do build_sized(n_elts) |push| {
let mut i: uint = 0u;
while i < n_elts { push(op(i)); i += 1u; }
@ -278,19 +283,20 @@ pure fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT {
* Creates an immutable vector of size `n_elts` and initializes the elements
* to the value `t`.
*/
pure fn from_elem<T: Copy,BT: Buildable<T>>(n_elts: uint, t: T) -> BT {
pub pure fn from_elem<T: Copy,BT: Buildable<T>>(n_elts: uint,
t: T) -> BT {
do build_sized(n_elts) |push| {
let mut i: uint = 0u;
while i < n_elts { push(t); i += 1u; }
let mut i: uint = 0;
while i < n_elts { push(t); i += 1; }
}
}
/// Appending two generic sequences
#[inline(always)]
pure fn append<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
lhs: IT, rhs: IT) -> BT {
let size_opt = lhs.size_hint().chain(
|sz1| rhs.size_hint().map(|sz2| sz1+sz2));
pub pure fn append<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
lhs: &IT, rhs: &IT) -> BT {
let size_opt = lhs.size_hint().chain_ref(
|sz1| rhs.size_hint().map(|sz2| *sz1+*sz2));
do build_sized_opt(size_opt) |push| {
for lhs.each |x| { push(*x); }
for rhs.each |x| { push(*x); }
@ -300,8 +306,8 @@ pure fn append<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
/// Copies a generic sequence, possibly converting it to a different
/// type of sequence.
#[inline(always)]
pure fn copy_seq<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
v: IT) -> BT {
pub pure fn copy_seq<T: Copy,IT: BaseIter<T>,BT: Buildable<T>>(
v: &IT) -> BT {
do build_sized_opt(v.size_hint()) |push| {
for v.each |x| { push(*x); }
}

File diff suppressed because it is too large Load diff

View file

@ -6,18 +6,15 @@
use cast::transmute;
export console_on, console_off, log_type;
#[nolink]
extern mod rustrt {
#[legacy_exports];
fn rust_log_console_on();
fn rust_log_console_off();
fn rust_log_str(level: u32, string: *libc::c_char, size: libc::size_t);
}
/// Turns on logging to stdout globally
fn console_on() {
pub fn console_on() {
rustrt::rust_log_console_on();
}
@ -28,7 +25,7 @@ fn console_on() {
* runtime environment's logging spec, e.g. by setting
* the RUST_LOG environment variable
*/
fn console_off() {
pub fn console_off() {
rustrt::rust_log_console_off();
}

View file

@ -8,15 +8,12 @@ dynamic checks: your program will fail if you attempt to perform
mutation when the data structure should be immutable.
*/
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use util::with;
use cast::transmute_immut;
export Mut;
enum Mode { ReadOnly, Mutable, Immutable }
struct Data<T> {
@ -24,18 +21,18 @@ struct Data<T> {
priv mut mode: Mode
}
type Mut<T> = Data<T>;
pub type Mut<T> = Data<T>;
fn Mut<T>(+t: T) -> Mut<T> {
pub fn Mut<T>(t: T) -> Mut<T> {
Data {value: t, mode: ReadOnly}
}
fn unwrap<T>(+m: Mut<T>) -> T {
pub fn unwrap<T>(m: Mut<T>) -> T {
// Borrowck should prevent us from calling unwrap while the value
// is in use, as that would be a move from a borrowed value.
assert (m.mode as uint) == (ReadOnly as uint);
let Data {value, mode: _} <- m;
return move value;
let Data {value: move value, mode: _} = move m;
return value;
}
impl<T> Data<T> {
@ -71,7 +68,7 @@ impl<T> Data<T> {
#[test]
#[ignore(cfg(windows))]
#[should_fail]
fn test_mut_in_imm() {
pub fn test_mut_in_imm() {
let m = @Mut(1);
do m.borrow_imm |_p| {
do m.borrow_mut |_q| {
@ -83,7 +80,7 @@ fn test_mut_in_imm() {
#[test]
#[ignore(cfg(windows))]
#[should_fail]
fn test_imm_in_mut() {
pub fn test_imm_in_mut() {
let m = @Mut(1);
do m.borrow_mut |_p| {
do m.borrow_imm |_q| {
@ -93,7 +90,7 @@ fn test_imm_in_mut() {
}
#[test]
fn test_const_in_mut() {
pub fn test_const_in_mut() {
let m = @Mut(1);
do m.borrow_mut |p| {
do m.borrow_const |q| {
@ -105,7 +102,7 @@ fn test_const_in_mut() {
}
#[test]
fn test_mut_in_const() {
pub fn test_mut_in_const() {
let m = @Mut(1);
do m.borrow_const |p| {
do m.borrow_mut |q| {
@ -117,7 +114,7 @@ fn test_mut_in_const() {
}
#[test]
fn test_imm_in_const() {
pub fn test_imm_in_const() {
let m = @Mut(1);
do m.borrow_const |p| {
do m.borrow_imm |q| {
@ -127,7 +124,7 @@ fn test_imm_in_const() {
}
#[test]
fn test_const_in_imm() {
pub fn test_const_in_imm() {
let m = @Mut(1);
do m.borrow_imm |p| {
do m.borrow_const |q| {
@ -140,7 +137,7 @@ fn test_const_in_imm() {
#[test]
#[ignore(cfg(windows))]
#[should_fail]
fn test_mut_in_imm_in_const() {
pub fn test_mut_in_imm_in_const() {
let m = @Mut(1);
do m.borrow_const |_p| {
do m.borrow_imm |_q| {
@ -149,3 +146,4 @@ fn test_mut_in_imm_in_const() {
}
}
}

View file

@ -1,12 +1,12 @@
//! An interface for numeric types
trait Num {
pub trait Num {
// FIXME: Trait composition. (#2616)
pure fn add(&&other: self) -> self;
pure fn sub(&&other: self) -> self;
pure fn mul(&&other: self) -> self;
pure fn div(&&other: self) -> self;
pure fn modulo(&&other: self) -> self;
pure fn add(other: &self) -> self;
pure fn sub(other: &self) -> self;
pure fn mul(other: &self) -> self;
pure fn div(other: &self) -> self;
pure fn modulo(other: &self) -> self;
pure fn neg() -> self;
pure fn to_int() -> int;

View file

@ -1,82 +1,82 @@
// Core operators and kinds.
#[lang="const"]
trait Const {
pub trait Const {
// Empty.
}
#[lang="copy"]
trait Copy {
pub trait Copy {
// Empty.
}
#[lang="send"]
trait Send {
pub trait Send {
// Empty.
}
#[lang="owned"]
trait Owned {
pub trait Owned {
// Empty.
}
#[lang="add"]
trait Add<RHS,Result> {
pub trait Add<RHS,Result> {
pure fn add(rhs: &RHS) -> Result;
}
#[lang="sub"]
trait Sub<RHS,Result> {
pub trait Sub<RHS,Result> {
pure fn sub(rhs: &RHS) -> Result;
}
#[lang="mul"]
trait Mul<RHS,Result> {
pub trait Mul<RHS,Result> {
pure fn mul(rhs: &RHS) -> Result;
}
#[lang="div"]
trait Div<RHS,Result> {
pub trait Div<RHS,Result> {
pure fn div(rhs: &RHS) -> Result;
}
#[lang="modulo"]
trait Modulo<RHS,Result> {
pub trait Modulo<RHS,Result> {
pure fn modulo(rhs: &RHS) -> Result;
}
#[lang="neg"]
trait Neg<Result> {
pub trait Neg<Result> {
pure fn neg() -> Result;
}
#[lang="bitand"]
trait BitAnd<RHS,Result> {
pub trait BitAnd<RHS,Result> {
pure fn bitand(rhs: &RHS) -> Result;
}
#[lang="bitor"]
trait BitOr<RHS,Result> {
pub trait BitOr<RHS,Result> {
pure fn bitor(rhs: &RHS) -> Result;
}
#[lang="bitxor"]
trait BitXor<RHS,Result> {
pub trait BitXor<RHS,Result> {
pure fn bitxor(rhs: &RHS) -> Result;
}
#[lang="shl"]
trait Shl<RHS,Result> {
pub trait Shl<RHS,Result> {
pure fn shl(rhs: &RHS) -> Result;
}
#[lang="shr"]
trait Shr<RHS,Result> {
pub trait Shr<RHS,Result> {
pure fn shr(rhs: &RHS) -> Result;
}
#[lang="index"]
trait Index<Index,Result> {
pub trait Index<Index,Result> {
pure fn index(index: Index) -> Result;
}

View file

@ -9,18 +9,18 @@
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[warn(deprecated_mode)];
#[forbid(deprecated_pattern)];
use cmp::Eq;
/// The option type
enum Option<T> {
pub enum Option<T> {
None,
Some(T),
}
pure fn get<T: Copy>(opt: &Option<T>) -> T {
pub pure fn get<T: Copy>(opt: &Option<T>) -> T {
/*!
* Gets the value out of an option
*
@ -30,12 +30,12 @@ pure fn get<T: Copy>(opt: &Option<T>) -> T {
*/
match *opt {
Some(x) => return x,
Some(copy x) => return x,
None => fail ~"option::get none"
}
}
pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
/*!
* Gets an immutable reference to the value inside an option.
*
@ -49,7 +49,7 @@ pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
}
}
pure fn expect<T: Copy>(opt: &Option<T>, +reason: ~str) -> T {
pub pure fn expect<T: Copy>(opt: &Option<T>, reason: ~str) -> T {
/*!
* Gets the value out of an option, printing a specified message on
* failure
@ -58,22 +58,17 @@ pure fn expect<T: Copy>(opt: &Option<T>, +reason: ~str) -> T {
*
* Fails if the value equals `none`
*/
match *opt { Some(x) => x, None => fail reason }
match *opt { Some(copy x) => x, None => fail reason }
}
pure fn map<T, U>(opt: &Option<T>, f: fn(T) -> U) -> Option<U> {
//! Maps a `some` value from one type to another
match *opt { Some(x) => Some(f(x)), None => None }
}
pure fn map_ref<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
//! Maps a `some` value by reference from one type to another
match *opt { Some(ref x) => Some(f(x)), None => None }
}
pure fn map_consume<T, U>(+opt: Option<T>, f: fn(+v: T) -> U) -> Option<U> {
pub pure fn map_consume<T, U>(opt: Option<T>,
f: fn(v: T) -> U) -> Option<U> {
/*!
* As `map`, but consumes the option and gives `f` ownership to avoid
* copying.
@ -81,17 +76,23 @@ pure fn map_consume<T, U>(+opt: Option<T>, f: fn(+v: T) -> U) -> Option<U> {
if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None }
}
pure fn chain<T, U>(opt: &Option<T>, f: fn(T) -> Option<U>) -> Option<U> {
pub pure fn chain<T, U>(opt: Option<T>,
f: fn(t: T) -> Option<U>) -> Option<U> {
/*!
* Update an optional value by optionally running its content through a
* function that returns an option.
*/
match *opt { Some(x) => f(x), None => None }
// XXX write with move match
if opt.is_some() {
f(unwrap(opt))
} else {
None
}
}
pure fn chain_ref<T, U>(opt: &Option<T>,
f: fn(x: &T) -> Option<U>) -> Option<U> {
pub pure fn chain_ref<T, U>(opt: &Option<T>,
f: fn(x: &T) -> Option<U>) -> Option<U> {
/*!
* Update an optional value by optionally running its content by reference
* through a function that returns an option.
@ -100,7 +101,7 @@ pure fn chain_ref<T, U>(opt: &Option<T>,
match *opt { Some(ref x) => f(x), None => None }
}
pure fn or<T>(+opta: Option<T>, +optb: Option<T>) -> Option<T> {
pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
/*!
* Returns the leftmost some() value, or none if both are none.
*/
@ -111,7 +112,7 @@ pure fn or<T>(+opta: Option<T>, +optb: Option<T>) -> Option<T> {
}
#[inline(always)]
pure fn while_some<T>(+x: Option<T>, blk: fn(+v: T) -> Option<T>) {
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
//! Applies a function zero or more times until the result is none.
let mut opt <- x;
@ -120,54 +121,38 @@ pure fn while_some<T>(+x: Option<T>, blk: fn(+v: T) -> Option<T>) {
}
}
pure fn is_none<T>(opt: &Option<T>) -> bool {
pub pure fn is_none<T>(opt: &Option<T>) -> bool {
//! Returns true if the option equals `none`
match *opt { None => true, Some(_) => false }
}
pure fn is_some<T>(opt: &Option<T>) -> bool {
pub pure fn is_some<T>(opt: &Option<T>) -> bool {
//! Returns true if the option contains some value
!is_none(opt)
}
pure fn get_default<T: Copy>(opt: &Option<T>, +def: T) -> T {
pub pure fn get_default<T: Copy>(opt: &Option<T>, def: T) -> T {
//! Returns the contained value or a default
match *opt { Some(x) => x, None => def }
match *opt { Some(copy x) => x, None => def }
}
pure fn map_default<T, U>(opt: &Option<T>, +def: U, f: fn(T) -> U) -> U {
//! Applies a function to the contained value or returns a default
match *opt { None => move def, Some(t) => f(t) }
}
// This should replace map_default.
pure fn map_default_ref<T, U>(opt: &Option<T>, +def: U,
pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
f: fn(x: &T) -> U) -> U {
//! Applies a function to the contained value or returns a default
match *opt { None => move def, Some(ref t) => f(t) }
}
// This should change to by-copy mode; use iter_ref below for by reference
pure fn iter<T>(opt: &Option<T>, f: fn(T)) {
//! Performs an operation on the contained value or does nothing
match *opt { None => (), Some(t) => f(t) }
}
pure fn iter_ref<T>(opt: &Option<T>, f: fn(x: &T)) {
pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
//! Performs an operation on the contained value by reference
match *opt { None => (), Some(ref t) => f(t) }
}
// tjc: shouldn't this be - instead of +?
// then could get rid of some superfluous moves
#[inline(always)]
pure fn unwrap<T>(+opt: Option<T>) -> T {
pub pure fn unwrap<T>(opt: Option<T>) -> T {
/*!
* Moves a value out of an option type and returns it.
*
@ -182,12 +167,12 @@ pure fn unwrap<T>(+opt: Option<T>) -> T {
/// The ubiquitous option dance.
#[inline(always)]
fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
if opt.is_none() { fail ~"option::swap_unwrap none" }
unwrap(util::replace(opt, None))
}
pure fn unwrap_expect<T>(+opt: Option<T>, reason: &str) -> T {
pub pure fn unwrap_expect<T>(opt: Option<T>, reason: &str) -> T {
//! As unwrap, but with a specified failure message.
if opt.is_none() { fail reason.to_unique(); }
unwrap(move opt)
@ -195,22 +180,10 @@ pure fn unwrap_expect<T>(+opt: Option<T>, reason: &str) -> T {
// Some of these should change to be &Option<T>, some should not. See below.
impl<T> Option<T> {
/**
* Update an optional value by optionally running its content through a
* function that returns an option.
*/
pure fn chain<U>(f: fn(T) -> Option<U>) -> Option<U> { chain(&self, f) }
/// Applies a function to the contained value or returns a default
pure fn map_default<U>(+def: U, f: fn(T) -> U) -> U
{ map_default(&self, move def, f) }
/// Performs an operation on the contained value or does nothing
pure fn iter(f: fn(T)) { iter(&self, f) }
/// Returns true if the option equals `none`
pure fn is_none() -> bool { is_none(&self) }
/// Returns true if the option contains some value
pure fn is_some() -> bool { is_some(&self) }
/// Maps a `some` value from one type to another
pure fn map<U>(f: fn(T) -> U) -> Option<U> { map(&self, f) }
}
impl<T> &Option<T> {
@ -222,12 +195,12 @@ impl<T> &Option<T> {
chain_ref(self, f)
}
/// Applies a function to the contained value or returns a default
pure fn map_default_ref<U>(+def: U, f: fn(x: &T) -> U) -> U
{ map_default_ref(self, move def, f) }
pure fn map_default<U>(def: U, f: fn(x: &T) -> U) -> U
{ map_default(self, move def, f) }
/// Performs an operation on the contained value by reference
pure fn iter_ref(f: fn(x: &T)) { iter_ref(self, f) }
pure fn iter(f: fn(x: &T)) { iter(self, f) }
/// Maps a `some` value from one type to another by reference
pure fn map_ref<U>(f: fn(x: &T) -> U) -> Option<U> { map_ref(self, f) }
pure fn map<U>(f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
/// Gets an immutable reference to the value inside a `some`.
pure fn get_ref() -> &self/T { get_ref(self) }
}
@ -241,7 +214,7 @@ impl<T: Copy> Option<T> {
* Fails if the value equals `none`
*/
pure fn get() -> T { get(&self) }
pure fn get_default(+def: T) -> T { get_default(&self, def) }
pure fn get_default(def: T) -> T { get_default(&self, def) }
/**
* Gets the value out of an option, printing a specified message on
* failure
@ -250,9 +223,9 @@ impl<T: Copy> Option<T> {
*
* Fails if the value equals `none`
*/
pure fn expect(+reason: ~str) -> T { expect(&self, reason) }
pure fn expect(reason: ~str) -> T { expect(&self, reason) }
/// Applies a function zero or more times until the result is none.
pure fn while_some(blk: fn(+v: T) -> Option<T>) { while_some(self, blk) }
pure fn while_some(blk: fn(v: T) -> Option<T>) { while_some(self, blk) }
}
impl<T: Eq> Option<T> : Eq {
@ -264,11 +237,11 @@ impl<T: Eq> Option<T> : Eq {
Some(_) => false
}
}
Some(self_contents) => {
Some(ref self_contents) => {
match (*other) {
None => false,
Some(ref other_contents) =>
self_contents.eq(other_contents)
(*self_contents).eq(other_contents)
}
}
}
@ -279,20 +252,20 @@ impl<T: Eq> Option<T> : Eq {
#[test]
fn test_unwrap_ptr() {
let x = ~0;
let addr_x = ptr::addr_of(*x);
let addr_x = ptr::p2::addr_of(&(*x));
let opt = Some(x);
let y = unwrap(opt);
let addr_y = ptr::addr_of(*y);
let addr_y = ptr::p2::addr_of(&(*y));
assert addr_x == addr_y;
}
#[test]
fn test_unwrap_str() {
let x = ~"test";
let addr_x = str::as_buf(x, |buf, _len| ptr::addr_of(buf));
let opt = Some(x);
let y = unwrap(opt);
let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf));
let addr_x = str::as_buf(x, |buf, _len| buf);
let opt = Some(move x);
let y = unwrap(move opt);
let addr_y = str::as_buf(y, |buf, _len| buf);
assert addr_x == addr_y;
}

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid
#[forbid(deprecated_pattern)];
/*!
@ -21,34 +21,23 @@
*/
use libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t,
mode_t, pid_t, FILE};
use libc::{close, fclose};
mode_t, pid_t, FILE};
pub use libc::{close, fclose};
use option::{Some, None};
use consts::*;
pub use consts::*;
use task::TaskBuilder;
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, arch, family;
export homedir, tmpdir, list_dir, list_dir_path, path_is_dir, path_exists,
make_absolute, make_dir, remove_dir, change_dir, remove_file,
copy_file;
export last_os_error;
export set_exit_status;
export walk_dir;
// FIXME: move these to str perhaps? #2620
export as_c_charp, fill_charp_buf;
extern mod rustrt {
#[legacy_exports];
fn rust_get_argc() -> c_int;
fn rust_get_argv() -> **c_char;
fn rust_getcwd() -> ~str;
fn rust_path_is_dir(path: *libc::c_char) -> c_int;
fn rust_path_exists(path: *libc::c_char) -> c_int;
fn rust_list_files(path: ~str) -> ~[~str];
fn rust_list_files2(&&path: ~str) -> ~[~str];
fn rust_process_wait(handle: c_int) -> c_int;
fn last_os_error() -> ~str;
fn rust_set_exit_status(code: libc::intptr_t);
@ -57,15 +46,15 @@ extern mod rustrt {
const tmpbuf_sz : uint = 1000u;
fn getcwd() -> Path {
pub fn getcwd() -> Path {
Path(rustrt::rust_getcwd())
}
fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
pub fn as_c_charp<T>(s: &str, f: fn(*c_char) -> T) -> T {
str::as_c_str(s, |b| f(b as *c_char))
}
fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
-> Option<~str> {
let buf = vec::to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char));
do vec::as_mut_buf(buf) |b, sz| {
@ -79,29 +68,23 @@ fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
#[cfg(windows)]
mod win32 {
#[legacy_exports];
use dword = libc::types::os::arch::extra::DWORD;
use libc::DWORD;
fn fill_utf16_buf_and_decode(f: fn(*mut u16, dword) -> dword)
pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD)
-> Option<~str> {
// FIXME: remove these when export globs work properly. #1238
use libc::funcs::extra::kernel32::*;
use libc::consts::os::extra::*;
let mut n = tmpbuf_sz as dword;
let mut n = tmpbuf_sz as DWORD;
let mut res = None;
let mut done = false;
while !done {
let buf = vec::to_mut(vec::from_elem(n as uint, 0u16));
do vec::as_mut_buf(buf) |b, _sz| {
let k : dword = f(b, tmpbuf_sz as dword);
if k == (0 as dword) {
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);
libc::GetLastError() ==
libc::ERROR_INSUFFICIENT_BUFFER as DWORD) {
n *= (2 as DWORD);
} else {
let sub = vec::slice(buf, 0u, k as uint);
res = option::Some(str::from_utf16(sub));
@ -112,7 +95,7 @@ mod win32 {
return res;
}
fn as_utf16_p<T>(s: &str, f: fn(*u16) -> T) -> T {
pub fn as_utf16_p<T>(s: &str, f: fn(*u16) -> T) -> T {
let mut t = str::to_utf16(s);
// Null terminate before passing on.
t += ~[0u16];
@ -120,28 +103,22 @@ mod win32 {
}
}
fn getenv(n: &str) -> Option<~str> {
pub fn getenv(n: &str) -> Option<~str> {
global_env::getenv(n)
}
fn setenv(n: &str, v: &str) {
pub fn setenv(n: &str, v: &str) {
global_env::setenv(n, v)
}
fn env() -> ~[(~str,~str)] {
pub fn env() -> ~[(~str,~str)] {
global_env::env()
}
mod global_env {
#[legacy_exports];
//! Internal module for serializing access to getenv/setenv
export getenv;
export setenv;
export env;
extern mod rustrt {
#[legacy_exports];
fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
}
@ -151,7 +128,7 @@ mod global_env {
MsgEnv(comm::Chan<~[(~str,~str)]>)
}
fn getenv(n: &str) -> Option<~str> {
pub fn getenv(n: &str) -> Option<~str> {
let env_ch = get_global_env_chan();
let po = comm::Port();
comm::send(env_ch, MsgGetEnv(str::from_slice(n),
@ -159,7 +136,7 @@ mod global_env {
comm::recv(po)
}
fn setenv(n: &str, v: &str) {
pub fn setenv(n: &str, v: &str) {
let env_ch = get_global_env_chan();
let po = comm::Port();
comm::send(env_ch, MsgSetEnv(str::from_slice(n),
@ -168,7 +145,7 @@ mod global_env {
comm::recv(po)
}
fn env() -> ~[(~str,~str)] {
pub fn env() -> ~[(~str,~str)] {
let env_ch = get_global_env_chan();
let po = comm::Port();
comm::send(env_ch, MsgEnv(comm::Chan(po)));
@ -191,11 +168,11 @@ mod global_env {
do private::weaken_task |weak_po| {
loop {
match comm::select2(msg_po, weak_po) {
either::Left(MsgGetEnv(n, resp_ch)) => {
comm::send(resp_ch, impl_::getenv(n))
either::Left(MsgGetEnv(ref n, resp_ch)) => {
comm::send(resp_ch, impl_::getenv(*n))
}
either::Left(MsgSetEnv(n, v, resp_ch)) => {
comm::send(resp_ch, impl_::setenv(n, v))
either::Left(MsgSetEnv(ref n, ref v, resp_ch)) => {
comm::send(resp_ch, impl_::setenv(*n, *v))
}
either::Left(MsgEnv(resp_ch)) => {
comm::send(resp_ch, impl_::env())
@ -208,24 +185,22 @@ mod global_env {
}
mod impl_ {
#[legacy_exports];
extern mod rustrt {
#[legacy_exports];
fn rust_env_pairs() -> ~[~str];
}
fn env() -> ~[(~str,~str)] {
pub fn env() -> ~[(~str,~str)] {
let mut pairs = ~[];
for vec::each(rustrt::rust_env_pairs()) |p| {
let vs = str::splitn_char(*p, '=', 1u);
assert vec::len(vs) == 2u;
vec::push(pairs, (copy vs[0], copy vs[1]));
pairs.push((copy vs[0], copy vs[1]));
}
move pairs
}
#[cfg(unix)]
fn getenv(n: &str) -> Option<~str> {
pub fn getenv(n: &str) -> Option<~str> {
unsafe {
let s = str::as_c_str(n, libc::getenv);
return if ptr::null::<u8>() == cast::reinterpret_cast(&s) {
@ -238,39 +213,32 @@ mod global_env {
}
#[cfg(windows)]
fn getenv(n: &str) -> Option<~str> {
use libc::types::os::arch::extra::*;
use libc::funcs::extra::kernel32::*;
pub fn getenv(n: &str) -> Option<~str> {
use win32::*;
do as_utf16_p(n) |u| {
do fill_utf16_buf_and_decode() |buf, sz| {
GetEnvironmentVariableW(u, buf, sz)
libc::GetEnvironmentVariableW(u, buf, sz)
}
}
}
#[cfg(unix)]
fn setenv(n: &str, v: &str) {
// FIXME: remove this when export globs work properly. #1238
use libc::funcs::posix01::unistd::setenv;
pub fn setenv(n: &str, v: &str) {
do str::as_c_str(n) |nbuf| {
do str::as_c_str(v) |vbuf| {
setenv(nbuf, vbuf, 1i32);
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1i32);
}
}
}
#[cfg(windows)]
fn setenv(n: &str, v: &str) {
// FIXME: remove imports when export globs work properly. #1238
use libc::funcs::extra::kernel32::*;
pub fn setenv(n: &str, v: &str) {
use win32::*;
do as_utf16_p(n) |nbuf| {
do as_utf16_p(v) |vbuf| {
SetEnvironmentVariableW(nbuf, vbuf);
libc::SetEnvironmentVariableW(nbuf, vbuf);
}
}
}
@ -278,7 +246,7 @@ mod global_env {
}
}
fn fdopen(fd: c_int) -> *FILE {
pub fn fdopen(fd: c_int) -> *FILE {
return do as_c_charp("r") |modebuf| {
libc::fdopen(fd, modebuf)
};
@ -288,13 +256,13 @@ fn fdopen(fd: c_int) -> *FILE {
// fsync related
#[cfg(windows)]
fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
use libc::funcs::extra::msvcrt::*;
return commit(fd);
}
#[cfg(target_os = "linux")]
fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
use libc::funcs::posix01::unistd::*;
match level {
io::fsync::FSync
@ -304,7 +272,7 @@ fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
}
#[cfg(target_os = "macos")]
fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
use libc::consts::os::extra::*;
use libc::funcs::posix88::fcntl::*;
use libc::funcs::posix01::unistd::*;
@ -321,52 +289,50 @@ fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
}
#[cfg(target_os = "freebsd")]
fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
use libc::funcs::posix01::unistd::*;
return fsync(fd);
}
#[cfg(windows)]
fn waitpid(pid: pid_t) -> c_int {
pub fn waitpid(pid: pid_t) -> c_int {
return rustrt::rust_process_wait(pid);
}
#[cfg(unix)]
fn waitpid(pid: pid_t) -> c_int {
pub fn waitpid(pid: pid_t) -> c_int {
use libc::funcs::posix01::wait::*;
let status = 0 as c_int;
assert (waitpid(pid, ptr::mut_addr_of(status),
assert (waitpid(pid, ptr::mut_addr_of(&status),
0 as c_int) != (-1 as c_int));
return status;
}
#[cfg(unix)]
fn pipe() -> {in: c_int, out: c_int} {
pub fn pipe() -> {in: c_int, out: c_int} {
let fds = {mut in: 0 as c_int,
mut out: 0 as c_int };
assert (libc::pipe(ptr::mut_addr_of(fds.in)) == (0 as c_int));
assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int));
return {in: fds.in, out: fds.out};
}
#[cfg(windows)]
fn pipe() -> {in: c_int, out: c_int} {
// FIXME: remove this when export globs work properly. #1238
use libc::consts::os::extra::*;
pub fn pipe() -> {in: c_int, out: c_int} {
// Windows pipes work subtly differently than unix pipes, and their
// inheritance has to be handled in a different way that I do not 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 = { mut in: 0 as c_int,
mut out: 0 as c_int };
let res = libc::pipe(ptr::mut_addr_of(fds.in),
mut out: 0 as c_int };
let res = libc::pipe(ptr::mut_addr_of(&(fds.in)),
1024 as c_uint,
(O_BINARY | O_NOINHERIT) as c_int);
(libc::O_BINARY | libc::O_NOINHERIT) as c_int);
assert (res == 0 as c_int);
assert (fds.in != -1 as c_int && fds.in != 0 as c_int);
assert (fds.out != -1 as c_int && fds.in != 0 as c_int);
@ -378,7 +344,7 @@ fn dup2(src: c_int, dst: c_int) -> c_int {
}
fn dll_filename(base: &str) -> ~str {
pub fn dll_filename(base: &str) -> ~str {
return pre() + str::from_slice(base) + dll_suffix();
#[cfg(unix)]
@ -389,7 +355,7 @@ fn dll_filename(base: &str) -> ~str {
}
fn self_exe_path() -> Option<Path> {
pub fn self_exe_path() -> Option<Path> {
#[cfg(target_os = "freebsd")]
fn load_self() -> Option<~str> {
@ -401,7 +367,7 @@ fn self_exe_path() -> Option<Path> {
KERN_PROC as c_int,
KERN_PROC_PATHNAME as c_int, -1 as c_int];
sysctl(vec::raw::to_ptr(mib), vec::len(mib) as c_uint,
buf as *mut c_void, ptr::mut_addr_of(sz),
buf as *mut c_void, ptr::mut_addr_of(&sz),
ptr::null(), 0u as size_t) == (0 as c_int)
}
}
@ -419,27 +385,22 @@ fn self_exe_path() -> Option<Path> {
#[cfg(target_os = "macos")]
fn load_self() -> Option<~str> {
// FIXME: remove imports when export globs work properly. #1238
use libc::funcs::extra::*;
do fill_charp_buf() |buf, sz| {
_NSGetExecutablePath(buf, ptr::mut_addr_of(sz as u32))
== (0 as c_int)
libc::funcs::extra::_NSGetExecutablePath(
buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int)
}
}
#[cfg(windows)]
fn load_self() -> Option<~str> {
// FIXME: remove imports when export globs work properly. #1238
use libc::types::os::arch::extra::*;
use libc::funcs::extra::kernel32::*;
use win32::*;
do fill_utf16_buf_and_decode() |buf, sz| {
GetModuleFileNameW(0u as dword, buf, sz)
libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
}
}
do load_self().map |pth| {
Path(pth).dir_path()
Path(*pth).dir_path()
}
}
@ -457,10 +418,10 @@ fn self_exe_path() -> Option<Path> {
*
* Otherwise, homedir returns option::none.
*/
fn homedir() -> Option<Path> {
pub fn homedir() -> Option<Path> {
return match getenv(~"HOME") {
Some(p) => if !str::is_empty(p) {
Some(Path(p))
Some(ref p) => if !str::is_empty(*p) {
Some(Path(*p))
} else {
secondary()
},
@ -474,7 +435,7 @@ fn homedir() -> Option<Path> {
#[cfg(windows)]
fn secondary() -> Option<Path> {
do option::chain(&getenv(~"USERPROFILE")) |p| {
do option::chain(getenv(~"USERPROFILE")) |p| {
if !str::is_empty(p) {
Some(Path(p))
} else {
@ -494,12 +455,12 @@ fn homedir() -> Option<Path> {
* 'USERPROFILE' environment variable if any are set and not the empty
* string. Otherwise, tmpdir returns the path to the Windows directory.
*/
fn tmpdir() -> Path {
pub fn tmpdir() -> Path {
return lookup();
fn getenv_nonempty(v: &str) -> Option<Path> {
match getenv(v) {
Some(x) =>
Some(move x) =>
if str::is_empty(x) {
None
} else {
@ -528,7 +489,7 @@ fn tmpdir() -> Path {
}
}
/// Recursively walk a directory structure
fn walk_dir(p: &Path, f: fn((&Path)) -> bool) {
pub fn walk_dir(p: &Path, f: fn((&Path)) -> bool) {
walk_dir_(p, f);
@ -557,21 +518,19 @@ fn walk_dir(p: &Path, f: fn((&Path)) -> bool) {
}
/// Indicates whether a path represents a directory
fn path_is_dir(p: &Path) -> bool {
pub fn path_is_dir(p: &Path) -> bool {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_is_dir(buf) != 0 as c_int
}
}
/// Indicates whether a path exists
fn path_exists(p: &Path) -> bool {
pub fn path_exists(p: &Path) -> bool {
do str::as_c_str(p.to_str()) |buf| {
rustrt::rust_path_exists(buf) != 0 as c_int
}
}
// FIXME (#2622): under Windows, we should prepend the current drive letter
// to paths that start with a slash.
/**
* Convert a relative path to an absolute path
*
@ -582,7 +541,7 @@ fn path_exists(p: &Path) -> bool {
// NB: this is here rather than in path because it is a form of environment
// querying; what it does depends on the process working directory, not just
// the input paths.
fn make_absolute(p: &Path) -> Path {
pub fn make_absolute(p: &Path) -> Path {
if p.is_absolute {
copy *p
} else {
@ -592,19 +551,18 @@ fn make_absolute(p: &Path) -> Path {
/// Creates a directory at the specified path
fn make_dir(p: &Path, mode: c_int) -> bool {
pub fn make_dir(p: &Path, mode: c_int) -> bool {
return mkdir(p, mode);
#[cfg(windows)]
fn mkdir(p: &Path, _mode: c_int) -> bool {
// FIXME: remove imports when export globs work properly. #1238
use libc::types::os::arch::extra::*;
use libc::funcs::extra::kernel32::*;
use win32::*;
// FIXME: turn mode into something useful? #2623
do as_utf16_p(p.to_str()) |buf| {
CreateDirectoryW(buf, unsafe { cast::reinterpret_cast(&0) })
!= (0 as BOOL)
libc::CreateDirectoryW(buf, unsafe {
cast::reinterpret_cast(&0)
})
!= (0 as libc::BOOL)
}
}
@ -618,7 +576,7 @@ fn make_dir(p: &Path, mode: c_int) -> bool {
/// Lists the contents of a directory
#[allow(non_implicitly_copyable_typarams)]
fn list_dir(p: &Path) -> ~[~str] {
pub fn list_dir(p: &Path) -> ~[~str] {
#[cfg(unix)]
fn star(p: &Path) -> Path { copy *p }
@ -626,8 +584,8 @@ fn list_dir(p: &Path) -> ~[~str] {
#[cfg(windows)]
fn star(p: &Path) -> Path { p.push("*") }
do rustrt::rust_list_files(star(p).to_str()).filter |filename| {
filename != ~"." && filename != ~".."
do rustrt::rust_list_files2(star(p).to_str()).filter |filename| {
*filename != ~"." && *filename != ~".."
}
}
@ -636,22 +594,19 @@ fn list_dir(p: &Path) -> ~[~str] {
*
* This version prepends each entry with the directory.
*/
fn list_dir_path(p: &Path) -> ~[~Path] {
pub fn list_dir_path(p: &Path) -> ~[~Path] {
os::list_dir(p).map(|f| ~p.push(*f))
}
/// Removes a directory at the specified path
fn remove_dir(p: &Path) -> bool {
pub fn remove_dir(p: &Path) -> bool {
return rmdir(p);
#[cfg(windows)]
fn rmdir(p: &Path) -> bool {
// FIXME: remove imports when export globs work properly. #1238
use libc::funcs::extra::kernel32::*;
use libc::types::os::arch::extra::*;
use win32::*;
return do as_utf16_p(p.to_str()) |buf| {
RemoveDirectoryW(buf) != (0 as BOOL)
libc::RemoveDirectoryW(buf) != (0 as libc::BOOL)
};
}
@ -663,17 +618,14 @@ fn remove_dir(p: &Path) -> bool {
}
}
fn change_dir(p: &Path) -> bool {
pub fn change_dir(p: &Path) -> bool {
return chdir(p);
#[cfg(windows)]
fn chdir(p: &Path) -> bool {
// FIXME: remove imports when export globs work properly. #1238
use libc::funcs::extra::kernel32::*;
use libc::types::os::arch::extra::*;
use win32::*;
return do as_utf16_p(p.to_str()) |buf| {
SetCurrentDirectoryW(buf) != (0 as BOOL)
libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL)
};
}
@ -686,18 +638,16 @@ fn change_dir(p: &Path) -> bool {
}
/// Copies a file from one location to another
fn copy_file(from: &Path, to: &Path) -> bool {
pub fn copy_file(from: &Path, to: &Path) -> bool {
return do_copy_file(from, to);
#[cfg(windows)]
fn do_copy_file(from: &Path, to: &Path) -> bool {
// FIXME: remove imports when export globs work properly. #1238
use libc::funcs::extra::kernel32::*;
use libc::types::os::arch::extra::*;
use win32::*;
return do as_utf16_p(from.to_str()) |fromp| {
do as_utf16_p(to.to_str()) |top| {
CopyFileW(fromp, top, (0 as BOOL)) != (0 as BOOL)
libc::CopyFileW(fromp, top, (0 as libc::BOOL)) !=
(0 as libc::BOOL)
}
}
}
@ -748,18 +698,14 @@ fn copy_file(from: &Path, to: &Path) -> bool {
}
/// Deletes an existing file
fn remove_file(p: &Path) -> bool {
pub fn remove_file(p: &Path) -> bool {
return unlink(p);
#[cfg(windows)]
fn unlink(p: &Path) -> bool {
// FIXME (similar to Issue #2006): remove imports when export globs
// work properly.
use libc::funcs::extra::kernel32::*;
use libc::types::os::arch::extra::*;
use win32::*;
return do as_utf16_p(p.to_str()) |buf| {
DeleteFileW(buf) != (0 as BOOL)
libc::DeleteFileW(buf) != (0 as libc::BOOL)
};
}
@ -772,7 +718,7 @@ fn remove_file(p: &Path) -> bool {
}
/// Get a string representing the platform-dependent last error
fn last_os_error() -> ~str {
pub fn last_os_error() -> ~str {
rustrt::last_os_error()
}
@ -784,67 +730,175 @@ fn last_os_error() -> ~str {
* and is supervised by the scheduler then any user-specified exit status is
* ignored and the process exits with the default failure status
*/
fn set_exit_status(code: int) {
pub fn set_exit_status(code: int) {
rustrt::rust_set_exit_status(code as libc::intptr_t);
}
#[cfg(unix)]
fn family() -> ~str { ~"unix" }
unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
let mut args = ~[];
for uint::range(0, argc as uint) |i| {
vec::push(&mut args, str::raw::from_c_str(*argv.offset(i)));
}
return args;
}
/**
* Returns the command line arguments
*
* Returns a list of the command line arguments.
*/
#[cfg(target_os = "macos")]
fn real_args() -> ~[~str] {
unsafe {
let (argc, argv) = (*_NSGetArgc() as c_int,
*_NSGetArgv() as **c_char);
load_argc_and_argv(argc, argv)
}
}
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
fn real_args() -> ~[~str] {
unsafe {
let argc = rustrt::rust_get_argc();
let argv = rustrt::rust_get_argv();
load_argc_and_argv(argc, argv)
}
}
#[cfg(windows)]
fn family() -> ~str { ~"windows" }
fn real_args() -> ~[~str] {
let mut nArgs: c_int = 0;
let lpArgCount = ptr::to_mut_unsafe_ptr(&mut nArgs);
let lpCmdLine = GetCommandLineW();
let szArgList = CommandLineToArgvW(lpCmdLine, lpArgCount);
let mut args = ~[];
for uint::range(0, nArgs as uint) |i| {
unsafe {
// Determine the length of this argument.
let ptr = *szArgList.offset(i);
let mut len = 0;
while *ptr.offset(len) != 0 { len += 1; }
// Push it onto the list.
vec::push(&mut args,
vec::raw::buf_as_slice(ptr, len,
str::from_utf16));
}
}
unsafe {
LocalFree(cast::transmute(szArgList));
}
return args;
}
type LPCWSTR = *u16;
#[cfg(windows)]
#[link_name="kernel32"]
#[abi="stdcall"]
extern {
fn GetCommandLineW() -> LPCWSTR;
fn LocalFree(ptr: *c_void);
}
#[cfg(windows)]
#[link_name="shell32"]
#[abi="stdcall"]
extern {
fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16;
}
struct OverriddenArgs {
val: ~[~str]
}
fn overridden_arg_key(_v: @OverriddenArgs) {}
pub fn args() -> ~[~str] {
unsafe {
match task::local_data::local_data_get(overridden_arg_key) {
None => real_args(),
Some(args) => copy args.val
}
}
}
pub fn set_args(new_args: ~[~str]) {
unsafe {
let overridden_args = @OverriddenArgs { val: copy new_args };
task::local_data::local_data_set(overridden_arg_key, overridden_args);
}
}
#[cfg(target_os = "macos")]
extern {
// These functions are in crt_externs.h.
pub fn _NSGetArgc() -> *c_int;
pub fn _NSGetArgv() -> ***c_char;
}
#[cfg(unix)]
pub fn family() -> ~str { ~"unix" }
#[cfg(windows)]
pub fn family() -> ~str { ~"windows" }
#[cfg(target_os = "macos")]
mod consts {
#[legacy_exports];
fn sysname() -> ~str { ~"macos" }
fn exe_suffix() -> ~str { ~"" }
fn dll_suffix() -> ~str { ~".dylib" }
pub fn sysname() -> ~str { ~"macos" }
pub fn exe_suffix() -> ~str { ~"" }
pub fn dll_suffix() -> ~str { ~".dylib" }
}
#[cfg(target_os = "freebsd")]
mod consts {
#[legacy_exports];
fn sysname() -> ~str { ~"freebsd" }
fn exe_suffix() -> ~str { ~"" }
fn dll_suffix() -> ~str { ~".so" }
pub fn sysname() -> ~str { ~"freebsd" }
pub fn exe_suffix() -> ~str { ~"" }
pub fn dll_suffix() -> ~str { ~".so" }
}
#[cfg(target_os = "linux")]
mod consts {
#[legacy_exports];
fn sysname() -> ~str { ~"linux" }
fn exe_suffix() -> ~str { ~"" }
fn dll_suffix() -> ~str { ~".so" }
pub fn sysname() -> ~str { ~"linux" }
pub fn exe_suffix() -> ~str { ~"" }
pub fn dll_suffix() -> ~str { ~".so" }
}
#[cfg(target_os = "win32")]
mod consts {
#[legacy_exports];
fn sysname() -> ~str { ~"win32" }
fn exe_suffix() -> ~str { ~".exe" }
fn dll_suffix() -> ~str { ~".dll" }
pub fn sysname() -> ~str { ~"win32" }
pub fn exe_suffix() -> ~str { ~".exe" }
pub fn dll_suffix() -> ~str { ~".dll" }
}
#[cfg(target_arch = "x86")]
fn arch() -> ~str { ~"x86" }
pub fn arch() -> ~str { ~"x86" }
#[cfg(target_arch = "x86_64")]
fn arch() -> ~str { ~"x86_64" }
pub fn arch() -> ~str { ~"x86_64" }
#[cfg(target_arch = "arm")]
fn arch() -> str { ~"arm" }
pub fn arch() -> str { ~"arm" }
#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
#[legacy_exports];
#[test]
fn last_os_error() {
pub fn last_os_error() {
log(debug, last_os_error());
}
#[test]
pub fn test_args() {
let a = real_args();
assert a.len() >= 1;
}
fn make_rand_name() -> ~str {
let rng: rand::Rng = rand::Rng();
let n = ~"TEST" + rng.gen_str(10u);
@ -919,10 +973,10 @@ mod tests {
let mut e = env();
setenv(n, ~"VALUE");
assert !vec::contains(e, (copy n, ~"VALUE"));
assert !vec::contains(e, &(copy n, ~"VALUE"));
e = env();
assert vec::contains(e, (n, ~"VALUE"));
assert vec::contains(e, &(n, ~"VALUE"));
}
#[test]
@ -946,7 +1000,7 @@ mod tests {
setenv(~"HOME", ~"");
assert os::homedir().is_none();
oldhome.iter(|s| setenv(~"HOME", s));
oldhome.iter(|s| setenv(~"HOME", *s));
}
#[test]
@ -973,9 +1027,9 @@ mod tests {
setenv(~"USERPROFILE", ~"/home/PaloAlto");
assert os::homedir() == Some(Path("/home/MountainView"));
option::iter(&oldhome, |s| setenv(~"HOME", s));
option::iter(&oldhome, |s| setenv(~"HOME", *s));
option::iter(&olduserprofile,
|s| setenv(~"USERPROFILE", s));
|s| setenv(~"USERPROFILE", *s));
}
#[test]

View file

@ -10,19 +10,19 @@ Cross-platform file path handling
use cmp::Eq;
struct WindowsPath {
pub struct WindowsPath {
host: Option<~str>,
device: Option<~str>,
is_absolute: bool,
components: ~[~str],
}
struct PosixPath {
pub struct PosixPath {
is_absolute: bool,
components: ~[~str],
}
trait GenericPath {
pub trait GenericPath {
static pure fn from_str((&str)) -> self;
@ -45,18 +45,18 @@ trait GenericPath {
}
#[cfg(windows)]
type Path = WindowsPath;
pub type Path = WindowsPath;
#[cfg(windows)]
pure fn Path(s: &str) -> Path {
pub pure fn Path(s: &str) -> Path {
from_str::<WindowsPath>(s)
}
#[cfg(unix)]
type Path = PosixPath;
pub type Path = PosixPath;
#[cfg(unix)]
pure fn Path(s: &str) -> Path {
pub pure fn Path(s: &str) -> Path {
from_str::<PosixPath>(s)
}
@ -167,7 +167,7 @@ impl PosixPath : GenericPath {
if t.len() == 0 {
match self.filestem() {
None => copy self,
Some(s) => self.with_filename(s)
Some(ref s) => self.with_filename(*s)
}
} else {
let t = ~"." + str::from_slice(t);
@ -206,7 +206,7 @@ impl PosixPath : GenericPath {
let mut ss = str::split_nonempty(
*e,
|c| windows::is_sep(c as u8));
unsafe { vec::push_all_move(v, move ss); }
unsafe { v.push_all_move(move ss); }
}
PosixPath { components: move v, ..self }
}
@ -214,14 +214,14 @@ impl PosixPath : GenericPath {
pure fn push(s: &str) -> PosixPath {
let mut v = copy self.components;
let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8));
unsafe { vec::push_all_move(v, move ss); }
unsafe { v.push_all_move(move ss); }
PosixPath { components: move v, ..self }
}
pure fn pop() -> PosixPath {
let mut cs = copy self.components;
if cs.len() != 0 {
unsafe { vec::pop(cs); }
unsafe { cs.pop(); }
}
return PosixPath { components: move cs, ..self }
}
@ -239,11 +239,11 @@ impl WindowsPath : ToStr {
fn to_str() -> ~str {
let mut s = ~"";
match self.host {
Some(h) => { s += "\\\\"; s += h; }
Some(ref h) => { s += "\\\\"; s += *h; }
None => { }
}
match self.device {
Some(d) => { s += d; s += ":"; }
Some(ref d) => { s += *d; s += ":"; }
None => { }
}
if self.is_absolute {
@ -358,7 +358,7 @@ impl WindowsPath : GenericPath {
if t.len() == 0 {
match self.filestem() {
None => copy self,
Some(s) => self.with_filename(s)
Some(ref s) => self.with_filename(*s)
}
} else {
let t = ~"." + str::from_slice(t);
@ -400,7 +400,7 @@ impl WindowsPath : GenericPath {
let mut ss = str::split_nonempty(
*e,
|c| windows::is_sep(c as u8));
unsafe { vec::push_all_move(v, move ss); }
unsafe { v.push_all_move(move ss); }
}
return WindowsPath { components: move v, ..self }
}
@ -408,14 +408,14 @@ impl WindowsPath : GenericPath {
pure fn push(s: &str) -> WindowsPath {
let mut v = copy self.components;
let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8));
unsafe { vec::push_all_move(v, move ss); }
unsafe { v.push_all_move(move ss); }
return WindowsPath { components: move v, ..self }
}
pure fn pop() -> WindowsPath {
let mut cs = copy self.components;
if cs.len() != 0 {
unsafe { vec::pop(cs); }
unsafe { cs.pop(); }
}
return WindowsPath { components: move cs, ..self }
}
@ -429,7 +429,7 @@ impl WindowsPath : GenericPath {
}
pure fn normalize(components: &[~str]) -> ~[~str] {
pub pure fn normalize(components: &[~str]) -> ~[~str] {
let mut cs = ~[];
unsafe {
for components.each |c| {
@ -437,10 +437,10 @@ pure fn normalize(components: &[~str]) -> ~[~str] {
if *c == ~"." && components.len() > 1 { loop; }
if *c == ~"" { loop; }
if *c == ~".." && cs.len() != 0 {
vec::pop(cs);
cs.pop();
loop;
}
vec::push(cs, copy *c);
cs.push(copy *c);
}
}
}
@ -462,7 +462,6 @@ fn test_double_slash_collapsing()
}
mod posix {
#[legacy_exports];
#[cfg(test)]
fn mk(s: &str) -> PosixPath { from_str::<PosixPath>(s) }
@ -553,14 +552,13 @@ mod posix {
// Various windows helpers, and tests for the impl.
mod windows {
#[legacy_exports];
#[inline(always)]
pure fn is_sep(u: u8) -> bool {
pub pure fn is_sep(u: u8) -> bool {
u == '/' as u8 || u == '\\' as u8
}
pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
if (s.len() > 1 &&
s[0] == '\\' as u8 &&
s[1] == '\\' as u8) {
@ -577,7 +575,7 @@ mod windows {
None
}
pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> {
pub pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> {
unsafe {
if (s.len() > 1 &&
libc::isalpha(s[0] as libc::c_int) != 0 &&

View file

@ -73,7 +73,7 @@ bounded and unbounded protocols allows for less code duplication.
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use cmp::Eq;
@ -81,31 +81,11 @@ use cast::{forget, reinterpret_cast, transmute};
use either::{Either, Left, Right};
use option::unwrap;
// Things used by code generated by the pipe compiler.
export entangle, get_buffer, drop_buffer;
export SendPacketBuffered, RecvPacketBuffered;
export Packet, packet, mk_packet, entangle_buffer, HasBuffer, BufferHeader;
// export these so we can find them in the buffer_resource
// destructor. This is probably a symptom of #3005.
export atomic_add_acq, atomic_sub_rel;
// User-level things
export SendPacket, RecvPacket, send, recv, try_recv, peek;
export select, select2, selecti, select2i, selectable;
export spawn_service, spawn_service_recv;
export stream, Port, Chan, SharedChan, PortSet, Channel;
export oneshot, ChanOne, PortOne;
export recv_one, try_recv_one, send_one, try_send_one;
// Functions used by the protocol compiler
export rt;
#[doc(hidden)]
const SPIN_COUNT: uint = 0;
macro_rules! move_it (
{ $x:expr } => { unsafe { let y <- *ptr::addr_of($x); move y } }
{ $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } }
)
#[doc(hidden)]
@ -123,7 +103,7 @@ impl State : Eq {
pure fn ne(other: &State) -> bool { !self.eq(other) }
}
struct BufferHeader {
pub struct BufferHeader {
// Tracks whether this buffer needs to be freed. We can probably
// get away with restricting it to 0 or 1, if we're careful.
mut ref_count: int,
@ -132,7 +112,7 @@ struct BufferHeader {
// thing along.
}
fn BufferHeader() -> BufferHeader{
pub fn BufferHeader() -> BufferHeader{
BufferHeader {
ref_count: 0
}
@ -195,13 +175,13 @@ impl PacketHeader {
}
#[doc(hidden)]
type Packet<T: Send> = {
pub type Packet<T: Send> = {
header: PacketHeader,
mut payload: Option<T>,
};
#[doc(hidden)]
trait HasBuffer {
pub trait HasBuffer {
// XXX This should not have a trailing underscore
fn set_buffer_(b: *libc::c_void);
}
@ -213,7 +193,7 @@ impl<T: Send> Packet<T>: HasBuffer {
}
#[doc(hidden)]
fn mk_packet<T: Send>() -> Packet<T> {
pub fn mk_packet<T: Send>() -> Packet<T> {
{
header: PacketHeader(),
mut payload: None
@ -237,17 +217,17 @@ fn unibuffer<T: Send>() -> ~Buffer<Packet<T>> {
}
#[doc(hidden)]
fn packet<T: Send>() -> *Packet<T> {
pub fn packet<T: Send>() -> *Packet<T> {
let b = unibuffer();
let p = ptr::addr_of(b.data);
let p = ptr::addr_of(&(b.data));
// We'll take over memory management from here.
unsafe { forget(move b) }
p
}
#[doc(hidden)]
fn entangle_buffer<T: Send, Tstart: Send>(
+buffer: ~Buffer<T>,
pub fn entangle_buffer<T: Send, Tstart: Send>(
buffer: ~Buffer<T>,
init: fn(*libc::c_void, x: &T) -> *Packet<Tstart>)
-> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>)
{
@ -256,52 +236,36 @@ fn entangle_buffer<T: Send, Tstart: Send>(
(SendPacketBuffered(p), RecvPacketBuffered(p))
}
#[cfg(stage0)]
#[abi = "rust-intrinsic"]
#[doc(hidden)]
extern mod rusti {
#[legacy_exports];
fn atomic_xchg(dst: &mut int, ++src: int) -> int;
fn atomic_xchg_acq(dst: &mut int, ++src: int) -> int;
fn atomic_xchg_rel(dst: &mut int, ++src: int) -> int;
fn atomic_xchg(dst: &mut int, src: int) -> int;
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
fn atomic_xadd_acq(dst: &mut int, ++src: int) -> int;
fn atomic_xsub_rel(dst: &mut int, ++src: int) -> int;
}
#[cfg(stage1)]
#[cfg(stage2)]
#[abi = "rust-intrinsic"]
#[doc(hidden)]
extern mod rusti {
#[legacy_exports];
fn atomic_xchg(dst: &mut int, +src: int) -> int;
fn atomic_xchg_acq(dst: &mut int, +src: int) -> int;
fn atomic_xchg_rel(dst: &mut int, +src: int) -> int;
fn atomic_xadd_acq(dst: &mut int, +src: int) -> int;
fn atomic_xsub_rel(dst: &mut int, +src: int) -> int;
fn atomic_xadd_acq(dst: &mut int, src: int) -> int;
fn atomic_xsub_rel(dst: &mut int, src: int) -> int;
}
// If I call the rusti versions directly from a polymorphic function,
// I get link errors. This is a bug that needs investigated more.
#[doc(hidden)]
fn atomic_xchng_rel(dst: &mut int, src: int) -> int {
pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int {
rusti::atomic_xchg_rel(dst, src)
}
#[doc(hidden)]
fn atomic_add_acq(dst: &mut int, src: int) -> int {
pub fn atomic_add_acq(dst: &mut int, src: int) -> int {
rusti::atomic_xadd_acq(dst, src)
}
#[doc(hidden)]
fn atomic_sub_rel(dst: &mut int, src: int) -> int {
pub fn atomic_sub_rel(dst: &mut int, src: int) -> int {
rusti::atomic_xsub_rel(dst, src)
}
#[doc(hidden)]
fn swap_task(+dst: &mut *rust_task, src: *rust_task) -> *rust_task {
pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task {
// It might be worth making both acquire and release versions of
// this.
unsafe {
@ -315,7 +279,6 @@ type rust_task = libc::c_void;
#[doc(hidden)]
extern mod rustrt {
#[legacy_exports];
#[rust_stack]
fn rust_get_task() -> *rust_task;
#[rust_stack]
@ -341,21 +304,21 @@ fn wait_event(this: *rust_task) -> *libc::c_void {
}
#[doc(hidden)]
fn swap_state_acq(+dst: &mut State, src: State) -> State {
fn swap_state_acq(dst: &mut State, src: State) -> State {
unsafe {
transmute(rusti::atomic_xchg_acq(transmute(move dst), src as int))
}
}
#[doc(hidden)]
fn swap_state_rel(+dst: &mut State, src: State) -> State {
fn swap_state_rel(dst: &mut State, src: State) -> State {
unsafe {
transmute(rusti::atomic_xchg_rel(transmute(move dst), src as int))
}
}
#[doc(hidden)]
unsafe fn get_buffer<T: Send>(p: *PacketHeader) -> ~Buffer<T> {
pub unsafe fn get_buffer<T: Send>(p: *PacketHeader) -> ~Buffer<T> {
transmute((*p).buf_header())
}
@ -380,7 +343,7 @@ struct BufferResource<T: Send> {
}
}
fn BufferResource<T: Send>(+b: ~Buffer<T>) -> BufferResource<T> {
fn BufferResource<T: Send>(b: ~Buffer<T>) -> BufferResource<T> {
//let p = ptr::addr_of(*b);
//error!("take %?", p);
atomic_add_acq(&mut b.header.ref_count, 1);
@ -391,12 +354,12 @@ fn BufferResource<T: Send>(+b: ~Buffer<T>) -> BufferResource<T> {
}
#[doc(hidden)]
fn send<T: Send, Tbuffer: Send>(+p: SendPacketBuffered<T, Tbuffer>,
+payload: T) -> bool {
pub fn send<T: Send, Tbuffer: Send>(p: SendPacketBuffered<T, Tbuffer>,
payload: T) -> bool {
let header = p.header();
let p_ = p.unwrap();
let p = unsafe { &*p_ };
assert ptr::addr_of(p.header) == header;
assert ptr::addr_of(&(p.header)) == header;
assert p.payload.is_none();
p.payload <- Some(move payload);
let old_state = swap_state_rel(&mut p.header.state, Full);
@ -414,7 +377,7 @@ fn send<T: Send, Tbuffer: Send>(+p: SendPacketBuffered<T, Tbuffer>,
let old_task = swap_task(&mut p.header.blocked_task, ptr::null());
if !old_task.is_null() {
rustrt::task_signal_event(
old_task, ptr::addr_of(p.header) as *libc::c_void);
old_task, ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
}
@ -435,7 +398,7 @@ fn send<T: Send, Tbuffer: Send>(+p: SendPacketBuffered<T, Tbuffer>,
Fails if the sender closes the connection.
*/
fn recv<T: Send, Tbuffer: Send>(+p: RecvPacketBuffered<T, Tbuffer>) -> T {
pub fn recv<T: Send, Tbuffer: Send>(p: RecvPacketBuffered<T, Tbuffer>) -> T {
option::unwrap_expect(try_recv(move p), "connection closed")
}
@ -445,7 +408,7 @@ Returns `none` if the sender has closed the connection without sending
a message, or `Some(T)` if a message was received.
*/
fn try_recv<T: Send, Tbuffer: Send>(+p: RecvPacketBuffered<T, Tbuffer>)
pub fn try_recv<T: Send, Tbuffer: Send>(p: RecvPacketBuffered<T, Tbuffer>)
-> Option<T>
{
let p_ = p.unwrap();
@ -539,7 +502,7 @@ fn try_recv<T: Send, Tbuffer: Send>(+p: RecvPacketBuffered<T, Tbuffer>)
}
/// Returns true if messages are available.
pure fn peek<T: Send, Tb: Send>(p: &RecvPacketBuffered<T, Tb>) -> bool {
pub pure fn peek<T: Send, Tb: Send>(p: &RecvPacketBuffered<T, Tb>) -> bool {
match unsafe {(*p.header()).state} {
Empty => false,
Blocked => fail ~"peeking on blocked packet",
@ -566,7 +529,7 @@ fn sender_terminate<T: Send>(p: *Packet<T>) {
if !old_task.is_null() {
rustrt::task_signal_event(
old_task,
ptr::addr_of(p.header) as *libc::c_void);
ptr::addr_of(&(p.header)) as *libc::c_void);
rustrt::rust_task_deref(old_task);
}
// The receiver will eventually clean up.
@ -691,9 +654,9 @@ Sometimes messages will be available on both endpoints at once. In
this case, `select2` may return either `left` or `right`.
*/
fn select2<A: Send, Ab: Send, B: Send, Bb: Send>(
+a: RecvPacketBuffered<A, Ab>,
+b: RecvPacketBuffered<B, Bb>)
pub fn select2<A: Send, Ab: Send, B: Send, Bb: Send>(
a: RecvPacketBuffered<A, Ab>,
b: RecvPacketBuffered<B, Bb>)
-> Either<(Option<A>, RecvPacketBuffered<B, Bb>),
(RecvPacketBuffered<A, Ab>, Option<B>)>
{
@ -716,12 +679,13 @@ impl *PacketHeader: Selectable {
}
/// Returns the index of an endpoint that is ready to receive.
fn selecti<T: Selectable>(endpoints: &[T]) -> uint {
pub fn selecti<T: Selectable>(endpoints: &[T]) -> uint {
wait_many(endpoints)
}
/// Returns 0 or 1 depending on which endpoint is ready to receive
fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) -> Either<(), ()> {
pub fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) ->
Either<(), ()> {
match wait_many([a.header(), b.header()]/_) {
0 => Left(()),
1 => Right(()),
@ -733,12 +697,12 @@ fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) -> Either<(), ()> {
list of the remaining endpoints.
*/
fn select<T: Send, Tb: Send>(+endpoints: ~[RecvPacketBuffered<T, Tb>])
pub fn select<T: Send, Tb: Send>(endpoints: ~[RecvPacketBuffered<T, Tb>])
-> (uint, Option<T>, ~[RecvPacketBuffered<T, Tb>])
{
let ready = wait_many(endpoints.map(|p| p.header()));
let mut remaining <- endpoints;
let port = vec::swap_remove(remaining, ready);
let port = remaining.swap_remove(ready);
let result = try_recv(move port);
(ready, move result, move remaining)
}
@ -747,14 +711,14 @@ fn select<T: Send, Tb: Send>(+endpoints: ~[RecvPacketBuffered<T, Tb>])
message.
*/
type SendPacket<T: Send> = SendPacketBuffered<T, Packet<T>>;
pub type SendPacket<T: Send> = SendPacketBuffered<T, Packet<T>>;
#[doc(hidden)]
fn SendPacket<T: Send>(p: *Packet<T>) -> SendPacket<T> {
pub fn SendPacket<T: Send>(p: *Packet<T>) -> SendPacket<T> {
SendPacketBuffered(p)
}
struct SendPacketBuffered<T: Send, Tbuffer: Send> {
pub struct SendPacketBuffered<T: Send, Tbuffer: Send> {
mut p: Option<*Packet<T>>,
mut buffer: Option<BufferResource<Tbuffer>>,
drop {
@ -773,14 +737,14 @@ struct SendPacketBuffered<T: Send, Tbuffer: Send> {
}
}
fn SendPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
pub fn SendPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
-> SendPacketBuffered<T, Tbuffer> {
//debug!("take send %?", p);
SendPacketBuffered {
p: Some(p),
buffer: unsafe {
Some(BufferResource(
get_buffer(ptr::addr_of((*p).header))))
get_buffer(ptr::addr_of(&((*p).header)))))
}
}
}
@ -796,7 +760,7 @@ impl<T: Send, Tbuffer: Send> SendPacketBuffered<T, Tbuffer> {
match self.p {
Some(packet) => unsafe {
let packet = &*packet;
let header = ptr::addr_of(packet.header);
let header = ptr::addr_of(&(packet.header));
//forget(packet);
header
},
@ -814,14 +778,14 @@ impl<T: Send, Tbuffer: Send> SendPacketBuffered<T, Tbuffer> {
/// Represents the receive end of a pipe. It can receive exactly one
/// message.
type RecvPacket<T: Send> = RecvPacketBuffered<T, Packet<T>>;
pub type RecvPacket<T: Send> = RecvPacketBuffered<T, Packet<T>>;
#[doc(hidden)]
fn RecvPacket<T: Send>(p: *Packet<T>) -> RecvPacket<T> {
pub fn RecvPacket<T: Send>(p: *Packet<T>) -> RecvPacket<T> {
RecvPacketBuffered(p)
}
struct RecvPacketBuffered<T: Send, Tbuffer: Send> {
pub struct RecvPacketBuffered<T: Send, Tbuffer: Send> {
mut p: Option<*Packet<T>>,
mut buffer: Option<BufferResource<Tbuffer>>,
drop {
@ -851,7 +815,7 @@ impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
match self.p {
Some(packet) => unsafe {
let packet = &*packet;
let header = ptr::addr_of(packet.header);
let header = ptr::addr_of(&(packet.header));
//forget(packet);
header
},
@ -867,20 +831,20 @@ impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
}
}
fn RecvPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
pub fn RecvPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
-> RecvPacketBuffered<T, Tbuffer> {
//debug!("take recv %?", p);
RecvPacketBuffered {
p: Some(p),
buffer: unsafe {
Some(BufferResource(
get_buffer(ptr::addr_of((*p).header))))
get_buffer(ptr::addr_of(&((*p).header)))))
}
}
}
#[doc(hidden)]
fn entangle<T: Send>() -> (SendPacket<T>, RecvPacket<T>) {
pub fn entangle<T: Send>() -> (SendPacket<T>, RecvPacket<T>) {
let p = packet();
(SendPacket(p), RecvPacket(p))
}
@ -892,10 +856,10 @@ endpoint. The send endpoint is returned to the caller and the receive
endpoint is passed to the new task.
*/
fn spawn_service<T: Send, Tb: Send>(
pub fn spawn_service<T: Send, Tb: Send>(
init: extern fn() -> (SendPacketBuffered<T, Tb>,
RecvPacketBuffered<T, Tb>),
+service: fn~(+v: RecvPacketBuffered<T, Tb>))
+service: fn~(v: RecvPacketBuffered<T, Tb>))
-> SendPacketBuffered<T, Tb>
{
let (client, server) = init();
@ -916,10 +880,10 @@ fn spawn_service<T: Send, Tb: Send>(
receive state.
*/
fn spawn_service_recv<T: Send, Tb: Send>(
pub fn spawn_service_recv<T: Send, Tb: Send>(
init: extern fn() -> (RecvPacketBuffered<T, Tb>,
SendPacketBuffered<T, Tb>),
+service: fn~(+v: SendPacketBuffered<T, Tb>))
+service: fn~(v: SendPacketBuffered<T, Tb>))
-> RecvPacketBuffered<T, Tb>
{
let (client, server) = init();
@ -945,19 +909,19 @@ proto! streamp (
)
/// A trait for things that can send multiple messages.
trait Channel<T: Send> {
pub trait Channel<T: Send> {
// It'd be nice to call this send, but it'd conflict with the
// built in send kind.
/// Sends a message.
fn send(+x: T);
fn send(x: T);
/// Sends a message, or report if the receiver has closed the connection.
fn try_send(+x: T) -> bool;
fn try_send(x: T) -> bool;
}
/// A trait for things that can receive multiple messages.
trait Recv<T: Send> {
pub trait Recv<T: Send> {
/// Receives a message, or fails if the connection closes.
fn recv() -> T;
@ -978,7 +942,7 @@ trait Recv<T: Send> {
type Chan_<T:Send> = { mut endp: Option<streamp::client::Open<T>> };
/// An endpoint that can send many messages.
enum Chan<T:Send> {
pub enum Chan<T:Send> {
Chan_(Chan_<T>)
}
@ -986,7 +950,7 @@ enum Chan<T:Send> {
type Port_<T:Send> = { mut endp: Option<streamp::server::Open<T>> };
/// An endpoint that can receive many messages.
enum Port<T:Send> {
pub enum Port<T:Send> {
Port_(Port_<T>)
}
@ -995,21 +959,21 @@ enum Port<T:Send> {
These allow sending or receiving an unlimited number of messages.
*/
fn stream<T:Send>() -> (Chan<T>, Port<T>) {
pub fn stream<T:Send>() -> (Chan<T>, Port<T>) {
let (c, s) = streamp::init();
(Chan_({ mut endp: Some(move c) }), Port_({ mut endp: Some(move s) }))
}
impl<T: Send> Chan<T>: Channel<T> {
fn send(+x: T) {
fn send(x: T) {
let mut endp = None;
endp <-> self.endp;
self.endp = Some(
streamp::client::data(unwrap(move endp), move x))
}
fn try_send(+x: T) -> bool {
fn try_send(x: T) -> bool {
let mut endp = None;
endp <-> self.endp;
match move streamp::client::try_data(unwrap(move endp), move x) {
@ -1047,7 +1011,7 @@ impl<T: Send> Port<T>: Recv<T> {
let mut endp = None;
endp <-> self.endp;
let peek = match endp {
Some(endp) => pipes::peek(&endp),
Some(ref endp) => pipes::peek(endp),
None => fail ~"peeking empty stream"
};
self.endp <-> endp;
@ -1058,18 +1022,18 @@ impl<T: Send> Port<T>: Recv<T> {
impl<T: Send> Port<T>: Selectable {
pure fn header() -> *PacketHeader unsafe {
match self.endp {
Some(endp) => endp.header(),
Some(ref endp) => endp.header(),
None => fail ~"peeking empty stream"
}
}
}
/// Treat many ports as one.
struct PortSet<T: Send> {
pub struct PortSet<T: Send> {
mut ports: ~[pipes::Port<T>],
}
fn PortSet<T: Send>() -> PortSet<T>{
pub fn PortSet<T: Send>() -> PortSet<T>{
PortSet {
ports: ~[]
}
@ -1077,8 +1041,8 @@ fn PortSet<T: Send>() -> PortSet<T>{
impl<T: Send> PortSet<T> : Recv<T> {
fn add(+port: pipes::Port<T>) {
vec::push(self.ports, move port)
fn add(port: pipes::Port<T>) {
self.ports.push(move port)
}
fn chan() -> Chan<T> {
@ -1101,7 +1065,7 @@ impl<T: Send> PortSet<T> : Recv<T> {
}
None => {
// Remove this port.
let _ = vec::swap_remove(ports, i);
let _ = ports.swap_remove(i);
}
}
}
@ -1124,10 +1088,10 @@ impl<T: Send> PortSet<T> : Recv<T> {
}
/// A channel that can be shared between many senders.
type SharedChan<T: Send> = private::Exclusive<Chan<T>>;
pub type SharedChan<T: Send> = private::Exclusive<Chan<T>>;
impl<T: Send> SharedChan<T>: Channel<T> {
fn send(+x: T) {
fn send(x: T) {
let mut xx = Some(move x);
do self.with_imm |chan| {
let mut x = None;
@ -1136,7 +1100,7 @@ impl<T: Send> SharedChan<T>: Channel<T> {
}
}
fn try_send(+x: T) -> bool {
fn try_send(x: T) -> bool {
let mut xx = Some(move x);
do self.with_imm |chan| {
let mut x = None;
@ -1147,12 +1111,12 @@ impl<T: Send> SharedChan<T>: Channel<T> {
}
/// Converts a `chan` into a `shared_chan`.
fn SharedChan<T:Send>(+c: Chan<T>) -> SharedChan<T> {
pub fn SharedChan<T:Send>(c: Chan<T>) -> SharedChan<T> {
private::exclusive(move c)
}
/// Receive a message from one of two endpoints.
trait Select2<T: Send, U: Send> {
pub trait Select2<T: Send, U: Send> {
/// Receive a message or return `none` if a connection closes.
fn try_select() -> Either<Option<T>, Option<U>>;
/// Receive a message or fail if a connection closes.
@ -1164,7 +1128,7 @@ impl<T: Send, U: Send, Left: Selectable Recv<T>, Right: Selectable Recv<U>>
fn select() -> Either<T, U> {
match self {
(lp, rp) => match select2i(&lp, &rp) {
(ref lp, ref rp) => match select2i(lp, rp) {
Left(()) => Left (lp.recv()),
Right(()) => Right(rp.recv())
}
@ -1173,7 +1137,7 @@ impl<T: Send, U: Send, Left: Selectable Recv<T>, Right: Selectable Recv<U>>
fn try_select() -> Either<Option<T>, Option<U>> {
match self {
(lp, rp) => match select2i(&lp, &rp) {
(ref lp, ref rp) => match select2i(lp, rp) {
Left(()) => Left (lp.try_recv()),
Right(()) => Right(rp.try_recv())
}
@ -1188,12 +1152,12 @@ proto! oneshot (
)
/// The send end of a oneshot pipe.
type ChanOne<T: Send> = oneshot::client::Oneshot<T>;
pub type ChanOne<T: Send> = oneshot::client::Oneshot<T>;
/// The receive end of a oneshot pipe.
type PortOne<T: Send> = oneshot::server::Oneshot<T>;
pub type PortOne<T: Send> = oneshot::server::Oneshot<T>;
/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
fn oneshot<T: Send>() -> (ChanOne<T>, PortOne<T>) {
pub fn oneshot<T: Send>() -> (ChanOne<T>, PortOne<T>) {
oneshot::init()
}
@ -1201,13 +1165,13 @@ fn oneshot<T: Send>() -> (ChanOne<T>, PortOne<T>) {
* Receive a message from a oneshot pipe, failing if the connection was
* closed.
*/
fn recv_one<T: Send>(+port: PortOne<T>) -> T {
pub fn recv_one<T: Send>(port: PortOne<T>) -> T {
let oneshot::send(message) = recv(move port);
move message
}
/// Receive a message from a oneshot pipe unless the connection was closed.
fn try_recv_one<T: Send> (+port: PortOne<T>) -> Option<T> {
pub fn try_recv_one<T: Send> (port: PortOne<T>) -> Option<T> {
let message = try_recv(move port);
if message.is_none() { None }
@ -1218,7 +1182,7 @@ fn try_recv_one<T: Send> (+port: PortOne<T>) -> Option<T> {
}
/// Send a message on a oneshot pipe, failing if the connection was closed.
fn send_one<T: Send>(+chan: ChanOne<T>, +data: T) {
pub fn send_one<T: Send>(chan: ChanOne<T>, data: T) {
oneshot::client::send(move chan, move data);
}
@ -1226,24 +1190,22 @@ fn send_one<T: Send>(+chan: ChanOne<T>, +data: T) {
* Send a message on a oneshot pipe, or return false if the connection was
* closed.
*/
fn try_send_one<T: Send>(+chan: ChanOne<T>, +data: T)
pub fn try_send_one<T: Send>(chan: ChanOne<T>, data: T)
-> bool {
oneshot::client::try_send(move chan, move data).is_some()
}
mod rt {
#[legacy_exports];
pub mod rt {
// These are used to hide the option constructors from the
// compiler because their names are changing
fn make_some<T>(+val: T) -> Option<T> { Some(move val) }
fn make_none<T>() -> Option<T> { None }
pub fn make_some<T>(val: T) -> Option<T> { Some(move val) }
pub fn make_none<T>() -> Option<T> { None }
}
#[cfg(test)]
mod test {
#[legacy_exports];
pub mod test {
#[test]
fn test_select2() {
pub fn test_select2() {
let (c1, p1) = pipes::stream();
let (c2, p2) = pipes::stream();
@ -1258,7 +1220,7 @@ mod test {
}
#[test]
fn test_oneshot() {
pub fn test_oneshot() {
let (c, p) = oneshot::init();
oneshot::client::send(c, ());

View file

@ -1,16 +1,9 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
#[doc(hidden)];
export chan_from_global_ptr, weaken_task;
export SharedMutableState, shared_mutable_state, clone_shared_mutable_state;
export get_shared_mutable_state, get_shared_immutable_state;
export unwrap_shared_mutable_state;
export Exclusive, exclusive, unwrap_exclusive;
use compare_and_swap = rustrt::rust_compare_and_swap_ptr;
use task::TaskBuilder;
use task::atomically;
@ -49,7 +42,7 @@ type GlobalPtr = *libc::uintptr_t;
* or, if no channel exists creates and installs a new channel and sets up a
* new task to receive from it.
*/
unsafe fn chan_from_global_ptr<T: Send>(
pub unsafe fn chan_from_global_ptr<T: Send>(
global: GlobalPtr,
task_fn: fn() -> task::TaskBuilder,
+f: fn~(comm::Port<T>)
@ -110,13 +103,13 @@ unsafe fn chan_from_global_ptr<T: Send>(
}
#[test]
fn test_from_global_chan1() {
pub fn test_from_global_chan1() {
// This is unreadable, right?
// The global channel
let globchan = 0u;
let globchanp = ptr::addr_of(globchan);
let globchan = 0;
let globchanp = ptr::p2::addr_of(&globchan);
// Create the global channel, attached to a new task
let ch = unsafe {
@ -147,25 +140,25 @@ fn test_from_global_chan1() {
}
#[test]
fn test_from_global_chan2() {
pub fn test_from_global_chan2() {
for iter::repeat(100u) {
for iter::repeat(100) {
// The global channel
let globchan = 0u;
let globchanp = ptr::addr_of(globchan);
let globchan = 0;
let globchanp = ptr::p2::addr_of(&globchan);
let resultpo = comm::Port();
let resultch = comm::Chan(resultpo);
// Spawn a bunch of tasks that all want to compete to
// create the global channel
for uint::range(0u, 10u) |i| {
for uint::range(0, 10) |i| {
do task::spawn {
let ch = unsafe {
do chan_from_global_ptr(
globchanp, task::task) |po| {
for uint::range(0u, 10u) |_j| {
for uint::range(0, 10) |_j| {
let ch = comm::recv(po);
comm::send(ch, {i});
}
@ -208,7 +201,7 @@ fn test_from_global_chan2() {
* * Weak tasks must not be supervised. A supervised task keeps
* a reference to its parent, so the parent will not die.
*/
unsafe fn weaken_task(f: fn(comm::Port<()>)) {
pub unsafe fn weaken_task(f: fn(comm::Port<()>)) {
let po = comm::Port();
let ch = comm::Chan(po);
unsafe {
@ -232,7 +225,7 @@ unsafe fn weaken_task(f: fn(comm::Port<()>)) {
}
#[test]
fn test_weaken_task_then_unweaken() {
pub fn test_weaken_task_then_unweaken() {
do task::try {
unsafe {
do weaken_task |_po| {
@ -242,7 +235,7 @@ fn test_weaken_task_then_unweaken() {
}
#[test]
fn test_weaken_task_wait() {
pub fn test_weaken_task_wait() {
do task::spawn_unlinked {
unsafe {
do weaken_task |po| {
@ -253,7 +246,7 @@ fn test_weaken_task_wait() {
}
#[test]
fn test_weaken_task_stress() {
pub fn test_weaken_task_stress() {
// Create a bunch of weak tasks
for iter::repeat(100u) {
do task::spawn {
@ -275,7 +268,7 @@ fn test_weaken_task_stress() {
#[test]
#[ignore(cfg(windows))]
fn test_weaken_task_fail() {
pub fn test_weaken_task_fail() {
let res = do task::try {
unsafe {
do weaken_task |_po| {
@ -283,7 +276,7 @@ fn test_weaken_task_fail() {
}
}
};
assert result::is_err(res);
assert result::is_err(&res);
}
/****************************************************************************
@ -347,7 +340,7 @@ fn ArcDestruct<T>(data: *libc::c_void) -> ArcDestruct<T> {
}
}
unsafe fn unwrap_shared_mutable_state<T: Send>(+rc: SharedMutableState<T>)
pub unsafe fn unwrap_shared_mutable_state<T: Send>(rc: SharedMutableState<T>)
-> T {
struct DeathThroes<T> {
mut ptr: Option<~ArcData<T>>,
@ -418,9 +411,10 @@ unsafe fn unwrap_shared_mutable_state<T: Send>(+rc: SharedMutableState<T>)
* Data races between tasks can result in crashes and, with sufficient
* cleverness, arbitrary type coercion.
*/
type SharedMutableState<T: Send> = ArcDestruct<T>;
pub type SharedMutableState<T: Send> = ArcDestruct<T>;
unsafe fn shared_mutable_state<T: Send>(+data: T) -> SharedMutableState<T> {
pub unsafe fn shared_mutable_state<T: Send>(data: T) ->
SharedMutableState<T> {
let data = ~ArcData { count: 1, unwrapper: 0, data: Some(move data) };
unsafe {
let ptr = cast::transmute(move data);
@ -429,7 +423,7 @@ unsafe fn shared_mutable_state<T: Send>(+data: T) -> SharedMutableState<T> {
}
#[inline(always)]
unsafe fn get_shared_mutable_state<T: Send>(rc: &a/SharedMutableState<T>)
pub unsafe fn get_shared_mutable_state<T: Send>(rc: &a/SharedMutableState<T>)
-> &a/mut T {
unsafe {
let ptr: ~ArcData<T> = cast::reinterpret_cast(&(*rc).data);
@ -441,8 +435,8 @@ unsafe fn get_shared_mutable_state<T: Send>(rc: &a/SharedMutableState<T>)
}
}
#[inline(always)]
unsafe fn get_shared_immutable_state<T: Send>(rc: &a/SharedMutableState<T>)
-> &a/T {
pub unsafe fn get_shared_immutable_state<T: Send>(
rc: &a/SharedMutableState<T>) -> &a/T {
unsafe {
let ptr: ~ArcData<T> = cast::reinterpret_cast(&(*rc).data);
assert ptr.count > 0;
@ -453,7 +447,7 @@ unsafe fn get_shared_immutable_state<T: Send>(rc: &a/SharedMutableState<T>)
}
}
unsafe fn clone_shared_mutable_state<T: Send>(rc: &SharedMutableState<T>)
pub unsafe fn clone_shared_mutable_state<T: Send>(rc: &SharedMutableState<T>)
-> SharedMutableState<T> {
unsafe {
let ptr: ~ArcData<T> = cast::reinterpret_cast(&(*rc).data);
@ -506,9 +500,9 @@ struct ExData<T: Send> { lock: LittleLock, mut failed: bool, mut data: T, }
/**
* An arc over mutable data that is protected by a lock. For library use only.
*/
struct Exclusive<T: Send> { x: SharedMutableState<ExData<T>> }
pub struct Exclusive<T: Send> { x: SharedMutableState<ExData<T>> }
fn exclusive<T:Send >(+user_data: T) -> Exclusive<T> {
pub fn exclusive<T:Send >(user_data: T) -> Exclusive<T> {
let data = ExData {
lock: LittleLock(), mut failed: false, mut data: user_data
};
@ -550,7 +544,7 @@ impl<T: Send> Exclusive<T> {
}
// FIXME(#2585) make this a by-move method on the exclusive
fn unwrap_exclusive<T: Send>(+arc: Exclusive<T>) -> T {
pub fn unwrap_exclusive<T: Send>(arc: Exclusive<T>) -> T {
let Exclusive { x: x } <- arc;
let inner = unsafe { unwrap_shared_mutable_state(move x) };
let ExData { data: data, _ } <- inner;
@ -558,11 +552,9 @@ fn unwrap_exclusive<T: Send>(+arc: Exclusive<T>) -> T {
}
#[cfg(test)]
mod tests {
#[legacy_exports];
pub mod tests {
#[test]
fn exclusive_arc() {
pub fn exclusive_arc() {
let mut futures = ~[];
let num_tasks = 10u;
@ -572,7 +564,7 @@ mod tests {
for uint::range(0u, num_tasks) |_i| {
let total = total.clone();
vec::push(futures, future::spawn(|| {
futures.push(future::spawn(|| {
for uint::range(0u, count) |_i| {
do total.with |count| {
**count += 1u;
@ -589,7 +581,7 @@ mod tests {
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn exclusive_poison() {
pub fn exclusive_poison() {
// Tests that if one task fails inside of an exclusive, subsequent
// accesses will also fail.
let x = exclusive(1);
@ -605,13 +597,13 @@ mod tests {
}
#[test]
fn exclusive_unwrap_basic() {
pub fn exclusive_unwrap_basic() {
let x = exclusive(~~"hello");
assert unwrap_exclusive(x) == ~~"hello";
}
#[test]
fn exclusive_unwrap_contended() {
pub fn exclusive_unwrap_contended() {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
do task::spawn {
@ -636,7 +628,7 @@ mod tests {
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn exclusive_unwrap_conflict() {
pub fn exclusive_unwrap_conflict() {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
let mut res = None;
@ -650,7 +642,7 @@ mod tests {
}
#[test] #[ignore(cfg(windows))]
fn exclusive_unwrap_deadlock() {
pub fn exclusive_unwrap_deadlock() {
// This is not guaranteed to get to the deadlock before being killed,
// but it will show up sometimes, and if the deadlock were not there,
// the test would nondeterministically fail.

View file

@ -1,33 +1,11 @@
//! Unsafe pointer utility functions
export addr_of;
export to_unsafe_ptr;
export to_const_unsafe_ptr;
export to_mut_unsafe_ptr;
export mut_addr_of;
export offset;
export const_offset;
export mut_offset;
export null;
export mut_null;
export is_null;
export is_not_null;
export memcpy;
export memmove;
export memset;
export to_uint;
export ref_eq;
export buf_len;
export position;
export Ptr;
use cmp::{Eq, Ord};
use libc::{c_void, size_t};
#[nolink]
#[abi = "cdecl"]
extern mod libc_ {
#[legacy_exports];
#[rust_stack]
fn memcpy(dest: *mut c_void, src: *const c_void,
n: libc::size_t) -> *c_void;
@ -43,25 +21,30 @@ extern mod libc_ {
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn addr_of<T>(val: T) -> *T;
fn addr_of<T>(&&val: T) -> *T;
}
/// Get an unsafe pointer to a value
#[inline(always)]
pure fn addr_of<T>(val: T) -> *T { unsafe { rusti::addr_of(val) } }
pub pure fn addr_of<T>(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
pub mod p2 {
/// Get an unsafe pointer to a value
#[inline(always)]
pub pure fn addr_of<T>(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
}
/// Get an unsafe mut pointer to a value
#[inline(always)]
pure fn mut_addr_of<T>(val: T) -> *mut T {
pub pure fn mut_addr_of<T>(val: &T) -> *mut T {
unsafe {
cast::reinterpret_cast(&rusti::addr_of(val))
cast::reinterpret_cast(&rusti::addr_of(*val))
}
}
/// Calculate the offset from a pointer
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T {
pub pure fn offset<T>(ptr: *T, count: uint) -> *T {
unsafe {
(ptr as uint + count * sys::size_of::<T>()) as *T
}
@ -69,7 +52,7 @@ fn offset<T>(ptr: *T, count: uint) -> *T {
/// Calculate the offset from a const pointer
#[inline(always)]
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
pub pure fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
unsafe {
(ptr as uint + count * sys::size_of::<T>()) as *T
}
@ -77,39 +60,39 @@ fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
/// Calculate the offset from a mut pointer
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
pub pure fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
(ptr as uint + count * sys::size_of::<T>()) as *mut T
}
/// Return the offset of the first null pointer in `buf`.
#[inline(always)]
unsafe fn buf_len<T>(buf: **T) -> uint {
position(buf, |i| i == null())
pub unsafe fn buf_len<T>(buf: **T) -> uint {
position(buf, |i| *i == null())
}
/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline(always)]
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
let mut i = 0u;
pub unsafe fn position<T>(buf: *T, f: fn(&T) -> bool) -> uint {
let mut i = 0;
loop {
if f(*offset(buf, i)) { return i; }
else { i += 1u; }
if f(&(*offset(buf, i))) { return i; }
else { i += 1; }
}
}
/// Create an unsafe null pointer
#[inline(always)]
pure fn null<T>() -> *T { unsafe { cast::reinterpret_cast(&0u) } }
pub pure fn null<T>() -> *T { unsafe { cast::reinterpret_cast(&0u) } }
/// Create an unsafe mutable null pointer
#[inline(always)]
pure fn mut_null<T>() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } }
pub pure fn mut_null<T>() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } }
/// Returns true if the pointer is equal to the null pointer.
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
pub pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }
/// Returns true if the pointer is not equal to the null pointer.
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
pub pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
/**
* Copies data from one location to another
@ -118,7 +101,7 @@ pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
* and destination may not overlap.
*/
#[inline(always)]
unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
pub unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
let n = count * sys::size_of::<T>();
libc_::memcpy(dst as *mut c_void, src as *c_void, n as size_t);
}
@ -130,13 +113,13 @@ unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
* and destination may overlap.
*/
#[inline(always)]
unsafe fn memmove<T>(dst: *mut T, src: *const T, count: uint) {
pub unsafe fn memmove<T>(dst: *mut T, src: *const T, count: uint) {
let n = count * sys::size_of::<T>();
libc_::memmove(dst as *mut c_void, src as *c_void, n as size_t);
}
#[inline(always)]
unsafe fn memset<T>(dst: *mut T, c: int, count: uint) {
pub unsafe fn memset<T>(dst: *mut T, c: int, count: uint) {
let n = count * sys::size_of::<T>();
libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t);
}
@ -148,7 +131,7 @@ unsafe fn memset<T>(dst: *mut T, c: int, count: uint) {
reinterpret_cast.
*/
#[inline(always)]
fn to_unsafe_ptr<T>(thing: &T) -> *T {
pub pure fn to_unsafe_ptr<T>(thing: &T) -> *T {
unsafe { cast::reinterpret_cast(&thing) }
}
@ -158,7 +141,7 @@ fn to_unsafe_ptr<T>(thing: &T) -> *T {
reinterpret_cast.
*/
#[inline(always)]
fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
pub pure fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
unsafe { cast::reinterpret_cast(&thing) }
}
@ -168,7 +151,7 @@ fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
reinterpret_cast.
*/
#[inline(always)]
fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
pub pure fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
unsafe { cast::reinterpret_cast(&thing) }
}
@ -180,28 +163,35 @@ fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
(I couldn't think of a cutesy name for this one.)
*/
#[inline(always)]
fn to_uint<T>(thing: &T) -> uint unsafe {
pub fn to_uint<T>(thing: &T) -> uint unsafe {
cast::reinterpret_cast(&thing)
}
/// Determine if two borrowed pointers point to the same thing.
#[inline(always)]
fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
pub fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
to_uint(thing) == to_uint(other)
}
trait Ptr {
pub trait Ptr<T> {
pure fn is_null() -> bool;
pure fn is_not_null() -> bool;
pure fn offset(count: uint) -> self;
}
/// Extension methods for pointers
impl<T> *T: Ptr {
impl<T> *T: Ptr<T> {
/// Returns true if the pointer is equal to the null pointer.
#[inline(always)]
pure fn is_null() -> bool { is_null(self) }
/// Returns true if the pointer is not equal to the null pointer.
#[inline(always)]
pure fn is_not_null() -> bool { is_not_null(self) }
/// Calculates the offset from a pointer.
#[inline(always)]
pure fn offset(count: uint) -> *T { offset(self, count) }
}
// Equality for pointers
@ -253,11 +243,11 @@ impl<T:Ord> &const T : Ord {
}
#[test]
fn test() {
pub fn test() {
unsafe {
type Pair = {mut fst: int, mut snd: int};
let p = {mut fst: 10, mut snd: 20};
let pptr: *mut Pair = mut_addr_of(p);
let pptr: *mut Pair = mut_addr_of(&p);
let iptr: *mut int = cast::reinterpret_cast(&pptr);
assert (*iptr == 10);;
*iptr = 30;
@ -285,20 +275,20 @@ fn test() {
}
#[test]
fn test_position() {
pub fn test_position() {
use str::as_c_str;
use libc::c_char;
let s = ~"hello";
unsafe {
assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char));
assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char));
assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char));
assert 2u == as_c_str(s, |p| position(p, |c| *c == 'l' as c_char));
assert 4u == as_c_str(s, |p| position(p, |c| *c == 'o' as c_char));
assert 5u == as_c_str(s, |p| position(p, |c| *c == 0 as c_char));
}
}
#[test]
fn test_buf_len() {
pub fn test_buf_len() {
let s0 = ~"hello";
let s1 = ~"there";
let s2 = ~"thing";
@ -316,7 +306,7 @@ fn test_buf_len() {
}
#[test]
fn test_is_null() {
pub fn test_is_null() {
let p: *int = ptr::null();
assert p.is_null();
assert !p.is_not_null();

View file

@ -1,29 +1,29 @@
//! Random number generation
export Rng, seed, seeded_rng, Weighted, extensions;
export xorshift, seeded_xorshift;
// NB: transitional, de-mode-ing.
#[warn(deprecated_mode)];
#[forbid(deprecated_pattern)];
#[allow(non_camel_case_types)] // runtime type
enum rctx {}
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rand_seed() -> ~[u8];
fn rand_new() -> *rctx;
fn rand_new_seeded(seed: ~[u8]) -> *rctx;
fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx;
fn rand_next(c: *rctx) -> u32;
fn rand_free(c: *rctx);
}
/// A random number generator
trait Rng {
pub trait Rng {
/// Return the next random integer
fn next() -> u32;
}
/// A value with a particular weight compared to other values
type Weighted<T> = { weight: uint, item: T };
pub type Weighted<T> = { weight: uint, item: T };
/// Extension methods for random number generators
impl Rng {
@ -123,7 +123,7 @@ impl Rng {
/**
* Return a char randomly chosen from chars, failing if chars is empty
*/
fn gen_char_from(chars: ~str) -> char {
fn gen_char_from(chars: &str) -> char {
assert !chars.is_empty();
self.choose(str::chars(chars))
}
@ -218,7 +218,7 @@ impl Rng {
let mut r = ~[];
for v.each |item| {
for uint::range(0u, item.weight) |_i| {
vec::push(r, item.item);
r.push(item.item);
}
}
move r
@ -260,12 +260,12 @@ impl @RandRes: Rng {
}
/// Create a new random seed for seeded_rng
fn seed() -> ~[u8] {
pub fn seed() -> ~[u8] {
rustrt::rand_seed()
}
/// Create a random number generator with a system specified seed
fn Rng() -> Rng {
pub fn Rng() -> Rng {
@RandRes(rustrt::rand_new()) as Rng
}
@ -275,8 +275,8 @@ fn Rng() -> Rng {
* all other generators constructed with the same seed. The seed may be any
* length.
*/
fn seeded_rng(seed: ~[u8]) -> Rng {
@RandRes(rustrt::rand_new_seeded(seed)) as Rng
pub fn seeded_rng(seed: &~[u8]) -> Rng {
@RandRes(rustrt::rand_new_seeded2(*seed)) as Rng
}
type XorShiftState = {
@ -299,40 +299,72 @@ impl XorShiftState: Rng {
}
}
fn xorshift() -> Rng {
pub fn xorshift() -> Rng {
// constants taken from http://en.wikipedia.org/wiki/Xorshift
seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32)
}
fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
{mut x: x, mut y: y, mut z: z, mut w: w} as Rng
}
#[cfg(test)]
mod tests {
#[legacy_exports];
// used to make space in TLS for a random number generator
fn tls_rng_state(+_v: @RandRes) {}
/**
* Gives back a lazily initialized task-local random number generator,
* seeded by the system. Intended to be used in method chaining style, ie
* task_rng().gen_int().
*/
pub fn task_rng() -> Rng {
let r : Option<@RandRes>;
unsafe {
r = task::local_data::local_data_get(tls_rng_state);
}
match r {
None => {
let rng = @RandRes(rustrt::rand_new());
unsafe {
task::local_data::local_data_set(tls_rng_state, rng);
}
rng as Rng
}
Some(rng) => rng as Rng
}
}
/**
* Returns a random uint, using the task's based random number generator.
*/
pub fn random() -> uint {
task_rng().gen_uint()
}
#[cfg(test)]
pub mod tests {
#[test]
fn rng_seeded() {
pub fn rng_seeded() {
let seed = rand::seed();
let ra = rand::seeded_rng(seed);
let rb = rand::seeded_rng(seed);
let ra = rand::seeded_rng(&seed);
let rb = rand::seeded_rng(&seed);
assert ra.gen_str(100u) == rb.gen_str(100u);
}
#[test]
fn rng_seeded_custom_seed() {
pub fn rng_seeded_custom_seed() {
// much shorter than generated seeds which are 1024 bytes
let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
let ra = rand::seeded_rng(seed);
let rb = rand::seeded_rng(seed);
let ra = rand::seeded_rng(&seed);
let rb = rand::seeded_rng(&seed);
assert ra.gen_str(100u) == rb.gen_str(100u);
}
#[test]
fn rng_seeded_custom_seed2() {
pub fn rng_seeded_custom_seed2() {
let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8];
let ra = rand::seeded_rng(seed);
let ra = rand::seeded_rng(&seed);
// Regression test that isaac is actually using the above vector
let r = ra.next();
error!("%?", r);
@ -341,7 +373,7 @@ mod tests {
}
#[test]
fn gen_int_range() {
pub fn gen_int_range() {
let r = rand::Rng();
let a = r.gen_int_range(-3, 42);
assert a >= -3 && a < 42;
@ -352,12 +384,12 @@ mod tests {
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn gen_int_from_fail() {
pub fn gen_int_from_fail() {
rand::Rng().gen_int_range(5, -2);
}
#[test]
fn gen_uint_range() {
pub fn gen_uint_range() {
let r = rand::Rng();
let a = r.gen_uint_range(3u, 42u);
assert a >= 3u && a < 42u;
@ -368,12 +400,12 @@ mod tests {
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn gen_uint_range_fail() {
pub fn gen_uint_range_fail() {
rand::Rng().gen_uint_range(5u, 2u);
}
#[test]
fn gen_float() {
pub fn gen_float() {
let r = rand::Rng();
let a = r.gen_float();
let b = r.gen_float();
@ -381,14 +413,14 @@ mod tests {
}
#[test]
fn gen_weighted_bool() {
pub fn gen_weighted_bool() {
let r = rand::Rng();
assert r.gen_weighted_bool(0u) == true;
assert r.gen_weighted_bool(1u) == true;
}
#[test]
fn gen_str() {
pub fn gen_str() {
let r = rand::Rng();
log(debug, r.gen_str(10u));
log(debug, r.gen_str(10u));
@ -399,7 +431,7 @@ mod tests {
}
#[test]
fn gen_bytes() {
pub fn gen_bytes() {
let r = rand::Rng();
assert r.gen_bytes(0u).len() == 0u;
assert r.gen_bytes(10u).len() == 10u;
@ -407,13 +439,13 @@ mod tests {
}
#[test]
fn choose() {
pub fn choose() {
let r = rand::Rng();
assert r.choose([1, 1, 1]) == 1;
}
#[test]
fn choose_option() {
pub fn choose_option() {
let r = rand::Rng();
let x: Option<int> = r.choose_option([]);
assert x.is_none();
@ -421,7 +453,7 @@ mod tests {
}
#[test]
fn choose_weighted() {
pub fn choose_weighted() {
let r = rand::Rng();
assert r.choose_weighted(~[{weight: 1u, item: 42}]) == 42;
assert r.choose_weighted(~[
@ -431,7 +463,7 @@ mod tests {
}
#[test]
fn choose_weighted_option() {
pub fn choose_weighted_option() {
let r = rand::Rng();
assert r.choose_weighted_option(~[{weight: 1u, item: 42}]) ==
Some(42);
@ -444,7 +476,7 @@ mod tests {
}
#[test]
fn weighted_vec() {
pub fn weighted_vec() {
let r = rand::Rng();
let empty: ~[int] = ~[];
assert r.weighted_vec(~[]) == empty;
@ -456,12 +488,26 @@ mod tests {
}
#[test]
fn shuffle() {
pub fn shuffle() {
let r = rand::Rng();
let empty: ~[int] = ~[];
assert r.shuffle(~[]) == empty;
assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1];
}
#[test]
pub fn task_rng() {
let r = rand::task_rng();
r.gen_int();
assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1];
assert r.gen_uint_range(0u, 1u) == 0u;
}
#[test]
pub fn random() {
// not sure how to test this aside from just getting a number
let _n : uint = rand::random();
}
}

View file

@ -13,7 +13,7 @@ use libc::c_void;
* data structure, and implement both `MovePtr` for it as well as `TyVisitor`;
* then build a MovePtrAdaptor wrapped around your struct.
*/
trait MovePtr {
pub trait MovePtr {
fn move_ptr(adjustment: fn(*c_void) -> *c_void);
}
@ -27,7 +27,7 @@ fn align(size: uint, align: uint) -> uint {
struct MovePtrAdaptor<V: TyVisitor MovePtr> {
inner: V
}
pub fn MovePtrAdaptor<V: TyVisitor MovePtr>(+v: V) -> MovePtrAdaptor<V> {
pub fn MovePtrAdaptor<V: TyVisitor MovePtr>(v: V) -> MovePtrAdaptor<V> {
MovePtrAdaptor { inner: move v }
}

View file

@ -13,7 +13,8 @@ use cast::transmute;
use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
use reflect::{MovePtr, MovePtrAdaptor};
use vec::raw::{VecRepr, UnboxedVecRepr, SliceRepr};
use box::raw::{BoxRepr, BoxHeaderRepr};
pub use box::raw::BoxRepr;
use box::raw::BoxHeaderRepr;
/// Helpers

View file

@ -1,10 +1,14 @@
//! A type representing either success or failure
// NB: transitionary, de-mode-ing.
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use cmp::Eq;
use either::Either;
/// The result type
enum Result<T, U> {
pub enum Result<T, U> {
/// Contains the successful result value
Ok(T),
/// Contains the error value
@ -18,11 +22,11 @@ enum Result<T, U> {
*
* If the result is an error
*/
pure fn get<T: Copy, U>(res: Result<T, U>) -> T {
match res {
Ok(t) => t,
Err(the_err) => unsafe {
fail fmt!("get called on error result: %?", the_err)
pub pure fn get<T: Copy, U>(res: &Result<T, U>) -> T {
match *res {
Ok(copy t) => t,
Err(ref the_err) => unsafe {
fail fmt!("get called on error result: %?", *the_err)
}
}
}
@ -34,11 +38,11 @@ pure fn get<T: Copy, U>(res: Result<T, U>) -> T {
*
* If the result is an error
*/
pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
pub pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
match *res {
Ok(ref t) => t,
Err(ref the_err) => unsafe {
fail fmt!("get_ref called on error result: %?", the_err)
fail fmt!("get_ref called on error result: %?", *the_err)
}
}
}
@ -50,23 +54,23 @@ pure fn get_ref<T, U>(res: &a/Result<T, U>) -> &a/T {
*
* If the result is not an error
*/
pure fn get_err<T, U: Copy>(res: Result<T, U>) -> U {
match res {
Err(u) => u,
pub pure fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
match *res {
Err(copy u) => u,
Ok(_) => fail ~"get_err called on ok result"
}
}
/// Returns true if the result is `ok`
pure fn is_ok<T, U>(res: Result<T, U>) -> bool {
match res {
pub pure fn is_ok<T, U>(res: &Result<T, U>) -> bool {
match *res {
Ok(_) => true,
Err(_) => false
}
}
/// Returns true if the result is `err`
pure fn is_err<T, U>(res: Result<T, U>) -> bool {
pub pure fn is_err<T, U>(res: &Result<T, U>) -> bool {
!is_ok(res)
}
@ -76,10 +80,11 @@ pure fn is_err<T, U>(res: Result<T, U>) -> bool {
* `ok` result variants are converted to `either::right` variants, `err`
* result variants are converted to `either::left`.
*/
pure fn to_either<T: Copy, U: Copy>(res: Result<U, T>) -> Either<T, U> {
match res {
Ok(res) => either::Right(res),
Err(fail_) => either::Left(fail_)
pub pure fn to_either<T: Copy, U: Copy>(res: &Result<U, T>)
-> Either<T, U> {
match *res {
Ok(copy res) => either::Right(res),
Err(copy fail_) => either::Left(fail_)
}
}
@ -97,11 +102,13 @@ pure fn to_either<T: Copy, U: Copy>(res: Result<U, T>) -> Either<T, U> {
* ok(parse_bytes(buf))
* }
*/
fn chain<T, U: Copy, V: Copy>(res: Result<T, V>, op: fn(T) -> Result<U, V>)
-> Result<U, V> {
match res {
Ok(t) => op(t),
Err(e) => Err(e)
pub fn chain<T, U: Copy, V: Copy>(res: Result<T, V>, op: fn(t: T)
-> Result<U, V>) -> Result<U, V> {
// XXX: Should be writable with move + match
if res.is_ok() {
op(unwrap(res))
} else {
Err(unwrap_err(res))
}
}
@ -113,13 +120,13 @@ fn chain<T, U: Copy, V: Copy>(res: Result<T, V>, op: fn(T) -> Result<U, V>)
* immediately returned. This function can be used to pass through a
* successful result while handling an error.
*/
fn chain_err<T: Copy, U: Copy, V: Copy>(
pub fn chain_err<T: Copy, U: Copy, V: Copy>(
res: Result<T, V>,
op: fn(V) -> Result<T, U>)
op: fn(t: V) -> Result<T, U>)
-> Result<T, U> {
match res {
Ok(t) => Ok(t),
Err(v) => op(v)
match move res {
Ok(move t) => Ok(t),
Err(move v) => op(v)
}
}
@ -137,9 +144,9 @@ fn chain_err<T: Copy, U: Copy, V: Copy>(
* print_buf(buf)
* }
*/
fn iter<T, E>(res: Result<T, E>, f: fn(T)) {
match res {
Ok(t) => f(t),
pub fn iter<T, E>(res: &Result<T, E>, f: fn((&T))) {
match *res {
Ok(ref t) => f(t),
Err(_) => ()
}
}
@ -152,10 +159,10 @@ fn iter<T, E>(res: Result<T, E>, f: fn(T)) {
* This function can be used to pass through a successful result while
* handling an error.
*/
fn iter_err<T, E>(res: Result<T, E>, f: fn(E)) {
match res {
pub fn iter_err<T, E>(res: &Result<T, E>, f: fn((&E))) {
match *res {
Ok(_) => (),
Err(e) => f(e)
Err(ref e) => f(e)
}
}
@ -173,11 +180,11 @@ fn iter_err<T, E>(res: Result<T, E>, f: fn(E)) {
* parse_bytes(buf)
* }
*/
fn map<T, E: Copy, U: Copy>(res: Result<T, E>, op: fn(T) -> U)
pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: fn((&T)) -> U)
-> Result<U, E> {
match res {
Ok(t) => Ok(op(t)),
Err(e) => Err(e)
match *res {
Ok(ref t) => Ok(op(t)),
Err(copy e) => Err(e)
}
}
@ -189,63 +196,65 @@ fn map<T, E: Copy, U: Copy>(res: Result<T, E>, op: fn(T) -> U)
* is immediately returned. This function can be used to pass through a
* successful result while handling an error.
*/
fn map_err<T: Copy, E, F: Copy>(res: Result<T, E>, op: fn(E) -> F)
pub fn map_err<T: Copy, E, F: Copy>(res: &Result<T, E>, op: fn((&E)) -> F)
-> Result<T, F> {
match res {
Ok(t) => Ok(t),
Err(e) => Err(op(e))
match *res {
Ok(copy t) => Ok(t),
Err(ref e) => Err(op(e))
}
}
impl<T, E> Result<T, E> {
fn is_ok() -> bool { is_ok(self) }
fn is_ok() -> bool { is_ok(&self) }
fn is_err() -> bool { is_err(self) }
fn is_err() -> bool { is_err(&self) }
fn iter(f: fn(T)) {
fn iter(f: fn((&T))) {
match self {
Ok(t) => f(t),
Ok(ref t) => f(t),
Err(_) => ()
}
}
fn iter_err(f: fn(E)) {
fn iter_err(f: fn((&E))) {
match self {
Ok(_) => (),
Err(e) => f(e)
Err(ref e) => f(e)
}
}
}
impl<T: Copy, E> Result<T, E> {
fn get() -> T { get(self) }
fn get() -> T { get(&self) }
fn map_err<F:Copy>(op: fn(E) -> F) -> Result<T,F> {
fn map_err<F:Copy>(op: fn((&E)) -> F) -> Result<T,F> {
match self {
Ok(t) => Ok(t),
Err(e) => Err(op(e))
Ok(copy t) => Ok(t),
Err(ref e) => Err(op(e))
}
}
}
impl<T, E: Copy> Result<T, E> {
fn get_err() -> E { get_err(self) }
fn get_err() -> E { get_err(&self) }
fn map<U:Copy>(op: fn(T) -> U) -> Result<U,E> {
fn map<U:Copy>(op: fn((&T)) -> U) -> Result<U,E> {
match self {
Ok(t) => Ok(op(t)),
Err(e) => Err(e)
Ok(ref t) => Ok(op(t)),
Err(copy e) => Err(e)
}
}
}
impl<T: Copy, E: Copy> Result<T, E> {
fn chain<U:Copy>(op: fn(T) -> Result<U,E>) -> Result<U,E> {
chain(self, op)
fn chain<U:Copy>(op: fn(t: T) -> Result<U,E>) -> Result<U,E> {
// XXX: Bad copy
chain(copy self, op)
}
fn chain_err<F:Copy>(op: fn(E) -> Result<T,F>) -> Result<T,F> {
chain_err(self, op)
fn chain_err<F:Copy>(op: fn(t: E) -> Result<T,F>) -> Result<T,F> {
// XXX: Bad copy
chain_err(copy self, op)
}
}
@ -266,27 +275,27 @@ impl<T: Copy, E: Copy> Result<T, E> {
* assert incd == ~[2u, 3u, 4u];
* }
*/
fn map_vec<T,U:Copy,V:Copy>(
pub fn map_vec<T,U:Copy,V:Copy>(
ts: &[T], op: fn((&T)) -> Result<V,U>) -> Result<~[V],U> {
let mut vs: ~[V] = vec::with_capacity(vec::len(ts));
for vec::each(ts) |t| {
match op(t) {
Ok(v) => vec::push(vs, v),
Err(u) => return Err(u)
Ok(copy v) => vs.push(v),
Err(copy u) => return Err(u)
}
}
return Ok(move vs);
}
fn map_opt<T,U:Copy,V:Copy>(
o_t: Option<T>, op: fn(T) -> Result<V,U>) -> Result<Option<V>,U> {
pub fn map_opt<T,U:Copy,V:Copy>(
o_t: &Option<T>, op: fn((&T)) -> Result<V,U>) -> Result<Option<V>,U> {
match o_t {
match *o_t {
None => Ok(None),
Some(t) => match op(t) {
Ok(v) => Ok(Some(v)),
Err(e) => Err(e)
Some(ref t) => match op(t) {
Ok(copy v) => Ok(Some(v)),
Err(copy e) => Err(e)
}
}
}
@ -300,17 +309,17 @@ fn map_opt<T,U:Copy,V:Copy>(
* used in 'careful' code contexts where it is both appropriate and easy
* to accommodate an error like the vectors being of different lengths.
*/
fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
op: fn(S,T) -> Result<V,U>) -> Result<~[V],U> {
pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
op: fn((&S),(&T)) -> Result<V,U>) -> Result<~[V],U> {
assert vec::same_length(ss, ts);
let n = vec::len(ts);
let mut vs = vec::with_capacity(n);
let mut i = 0u;
while i < n {
match op(ss[i],ts[i]) {
Ok(v) => vec::push(vs, v),
Err(u) => return Err(u)
match op(&ss[i],&ts[i]) {
Ok(copy v) => vs.push(v),
Err(copy u) => return Err(u)
}
i += 1u;
}
@ -322,16 +331,16 @@ fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
* error. This could be implemented using `map2()` but it is more efficient
* on its own as no result vector is built.
*/
fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
op: fn(S,T) -> Result<(),U>) -> Result<(),U> {
pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
op: fn((&S),(&T)) -> Result<(),U>) -> Result<(),U> {
assert vec::same_length(ss, ts);
let n = vec::len(ts);
let mut i = 0u;
while i < n {
match op(ss[i],ts[i]) {
match op(&ss[i],&ts[i]) {
Ok(()) => (),
Err(u) => return Err(u)
Err(copy u) => return Err(u)
}
i += 1u;
}
@ -339,7 +348,7 @@ fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
}
/// Unwraps a result, assuming it is an `ok(T)`
fn unwrap<T, U>(+res: Result<T, U>) -> T {
pub fn unwrap<T, U>(res: Result<T, U>) -> T {
match move res {
Ok(move t) => move t,
Err(_) => fail ~"unwrap called on an err result"
@ -347,7 +356,7 @@ fn unwrap<T, U>(+res: Result<T, U>) -> T {
}
/// Unwraps a result, assuming it is an `err(U)`
fn unwrap_err<T, U>(+res: Result<T, U>) -> U {
pub fn unwrap_err<T, U>(res: Result<T, U>) -> U {
match move res {
Err(move u) => move u,
Ok(_) => fail ~"unwrap called on an ok result"
@ -357,15 +366,15 @@ fn unwrap_err<T, U>(+res: Result<T, U>) -> U {
impl<T:Eq,U:Eq> Result<T,U> : Eq {
pure fn eq(other: &Result<T,U>) -> bool {
match self {
Ok(e0a) => {
Ok(ref e0a) => {
match (*other) {
Ok(e0b) => e0a == e0b,
Ok(ref e0b) => *e0a == *e0b,
_ => false
}
}
Err(e0a) => {
Err(ref e0a) => {
match (*other) {
Err(e0b) => e0a == e0b,
Err(ref e0b) => *e0a == *e0b,
_ => false
}
}
@ -380,7 +389,7 @@ mod tests {
#[legacy_exports];
fn op1() -> result::Result<int, ~str> { result::Ok(666) }
fn op2(&&i: int) -> result::Result<uint, ~str> {
fn op2(i: int) -> result::Result<uint, ~str> {
result::Ok(i as uint + 1u)
}
@ -388,12 +397,12 @@ mod tests {
#[test]
fn chain_success() {
assert get(chain(op1(), op2)) == 667u;
assert get(&chain(op1(), op2)) == 667u;
}
#[test]
fn chain_failure() {
assert get_err(chain(op3(), op2)) == ~"sadface";
assert get_err(&chain(op3(), op2)) == ~"sadface";
}
#[test]

View file

@ -11,10 +11,9 @@ use libc::uintptr_t;
use gc::{cleanup_stack_for_failure, gc, Word};
#[allow(non_camel_case_types)]
type rust_task = c_void;
pub type rust_task = c_void;
extern mod rustrt {
#[legacy_exports];
#[rust_stack]
fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t);
@ -35,13 +34,23 @@ extern mod rustrt {
// 'rt_', otherwise the compiler won't find it. To fix this, see
// gather_rust_rtcalls.
#[rt(fail_)]
fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) {
pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) {
cleanup_stack_for_failure();
rustrt::rust_upcall_fail(expr, file, line);
}
#[rt(fail_bounds_check)]
pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
index: size_t, len: size_t) {
let msg = fmt!("index out of bounds: the len is %d but the index is %d",
len as int, index as int);
do str::as_buf(msg) |p, _len| {
rt_fail_(p as *c_char, file, line);
}
}
#[rt(exchange_malloc)]
fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_exchange_malloc(td, size);
}
@ -49,12 +58,12 @@ fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
// inside a landing pad may corrupt the state of the exception handler. If a
// problem occurs, call exit instead.
#[rt(exchange_free)]
fn rt_exchange_free(ptr: *c_char) {
pub fn rt_exchange_free(ptr: *c_char) {
rustrt::rust_upcall_exchange_free(ptr);
}
#[rt(malloc)]
fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_malloc(td, size);
}
@ -62,7 +71,7 @@ fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
// inside a landing pad may corrupt the state of the exception handler. If a
// problem occurs, call exit instead.
#[rt(free)]
fn rt_free(ptr: *c_char) {
pub fn rt_free(ptr: *c_char) {
rustrt::rust_upcall_free(ptr);
}

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
//! Process spawning
@ -7,16 +7,8 @@ use option::{Some, None};
use libc::{pid_t, c_void, c_int};
use io::ReaderUtil;
export Program;
export run_program;
export start_program;
export program_output;
export spawn_process;
export waitpid;
#[abi = "cdecl"]
extern mod rustrt {
#[legacy_exports];
fn rust_run_program(argv: **libc::c_char, envp: *c_void,
dir: *libc::c_char,
in_fd: c_int, out_fd: c_int, err_fd: c_int)
@ -24,7 +16,7 @@ extern mod rustrt {
}
/// A value representing a child process
trait Program {
pub trait Program {
/// Returns the process id of the program
fn get_id() -> pid_t;
@ -68,7 +60,7 @@ trait Program {
*
* The process id of the spawned process
*/
fn spawn_process(prog: &str, args: &[~str],
pub 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)
@ -89,10 +81,10 @@ fn with_argv<T>(prog: &str, args: &[~str],
let mut tmps = ~[];
for vec::each(args) |arg| {
let t = @copy *arg;
vec::push(tmps, t);
vec::push_all(argptrs, str::as_c_str(*t, |b| ~[b]));
tmps.push(t);
argptrs.push_all(str::as_c_str(*t, |b| ~[b]));
}
vec::push(argptrs, ptr::null());
argptrs.push(ptr::null());
vec::as_imm_buf(argptrs, |buf, _len| cb(buf))
}
@ -102,17 +94,17 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>,
// On posixy systems we can pass a char** for envp, which is
// a null-terminated array of "k=v\n" strings.
match *env {
Some(es) if !vec::is_empty(es) => {
Some(ref es) if !vec::is_empty(*es) => {
let mut tmps = ~[];
let mut ptrs = ~[];
for vec::each(es) |e| {
for vec::each(*es) |e| {
let (k,v) = copy *e;
let t = @(fmt!("%s=%s", k, v));
vec::push(tmps, t);
vec::push_all(ptrs, str::as_c_str(*t, |b| ~[b]));
tmps.push(t);
ptrs.push_all(str::as_c_str(*t, |b| ~[b]));
}
vec::push(ptrs, ptr::null());
ptrs.push(ptr::null());
vec::as_imm_buf(ptrs, |p, _len|
unsafe { cb(::cast::reinterpret_cast(&p)) }
)
@ -149,7 +141,7 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>,
fn with_dirp<T>(d: &Option<~str>,
cb: fn(*libc::c_char) -> T) -> T {
match *d {
Some(dir) => str::as_c_str(dir, cb),
Some(ref dir) => str::as_c_str(*dir, cb),
None => cb(ptr::null())
}
}
@ -166,7 +158,7 @@ fn with_dirp<T>(d: &Option<~str>,
*
* The process id
*/
fn run_program(prog: &str, args: &[~str]) -> int {
pub fn run_program(prog: &str, args: &[~str]) -> int {
let pid = spawn_process(prog, args, &None, &None,
0i32, 0i32, 0i32);
if pid == -1 as pid_t { fail; }
@ -189,7 +181,7 @@ fn run_program(prog: &str, args: &[~str]) -> int {
*
* A class with a <program> field
*/
fn start_program(prog: &str, args: &[~str]) -> Program {
pub fn start_program(prog: &str, args: &[~str]) -> Program {
let pipe_input = os::pipe();
let pipe_output = os::pipe();
let pipe_err = os::pipe();
@ -232,7 +224,7 @@ fn start_program(prog: &str, args: &[~str]) -> Program {
drop { destroy_repr(&self.r); }
}
fn ProgRes(+r: ProgRepr) -> ProgRes {
fn ProgRes(r: ProgRepr) -> ProgRes {
ProgRes {
r: r
}
@ -278,7 +270,7 @@ fn read_all(rd: io::Reader) -> ~str {
* 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]) ->
pub fn program_output(prog: &str, args: &[~str]) ->
{status: int, out: ~str, err: ~str} {
let pipe_in = os::pipe();
@ -320,11 +312,11 @@ fn program_output(prog: &str, args: &[~str]) ->
while count > 0 {
let stream = comm::recv(p);
match stream {
(1, s) => {
outs = copy s;
(1, copy s) => {
outs = s;
}
(2, s) => {
errs = copy s;
(2, copy s) => {
errs = s;
}
(n, _) => {
fail(fmt!("program_output received an unexpected file \
@ -336,7 +328,7 @@ fn program_output(prog: &str, args: &[~str]) ->
return {status: status, out: move outs, err: move errs};
}
fn writeclose(fd: c_int, s: &str) {
fn writeclose(fd: c_int, s: ~str) {
use io::WriterUtil;
error!("writeclose %d, %s", fd as int, s);
@ -359,7 +351,7 @@ fn readclose(fd: c_int) -> ~str {
}
/// Waits for a process to exit and returns the exit code
fn waitpid(pid: pid_t) -> int {
pub fn waitpid(pid: pid_t) -> int {
return waitpid_os(pid);
#[cfg(windows)]
@ -402,20 +394,19 @@ fn waitpid(pid: pid_t) -> int {
#[cfg(test)]
mod tests {
#[legacy_exports];
use io::WriterUtil;
// Regression test for memory leaks
#[ignore(cfg(windows))] // FIXME (#2626)
fn test_leaks() {
pub fn test_leaks() {
run::run_program("echo", []);
run::start_program("echo", []);
run::program_output("echo", []);
}
#[test]
fn test_pipes() {
#[allow(non_implicitly_copyable_typarams)]
pub fn test_pipes() {
let pipe_in = os::pipe();
let pipe_out = os::pipe();
let pipe_err = os::pipe();
@ -430,7 +421,7 @@ mod tests {
if pid == -1i32 { fail; }
let expected = ~"test";
writeclose(pipe_in.out, expected);
writeclose(pipe_in.out, copy expected);
let actual = readclose(pipe_out.in);
readclose(pipe_err.in);
os::waitpid(pid);
@ -441,7 +432,7 @@ mod tests {
}
#[test]
fn waitpid() {
pub fn waitpid() {
let pid = run::spawn_process("false", [],
&None, &None,
0i32, 0i32, 0i32);

View file

@ -12,10 +12,10 @@ use cmp::Eq;
use hash::Hash;
use to_bytes::IterBytes;
trait SendMap<K:Eq Hash, V: Copy> {
pub trait SendMap<K:Eq Hash, V: Copy> {
// FIXME(#3148) ^^^^ once find_ref() works, we can drop V:copy
fn insert(&mut self, +k: K, +v: V) -> bool;
fn insert(&mut self, k: K, +v: V) -> bool;
fn remove(&mut self, k: &K) -> bool;
fn clear(&mut self);
pure fn len(&const self) -> uint;
@ -31,17 +31,15 @@ trait SendMap<K:Eq Hash, V: Copy> {
}
/// Open addressing with linear probing.
mod linear {
#[legacy_exports];
export LinearMap, linear_map, linear_map_with_capacity, public_methods;
pub mod linear {
const initial_capacity: uint = 32u; // 2^5
struct Bucket<K:Eq Hash,V> {
hash: uint,
key: K,
value: V,
}
struct LinearMap<K:Eq Hash,V> {
pub struct LinearMap<K:Eq Hash,V> {
k0: u64,
k1: u64,
resize_at: uint,
@ -60,11 +58,11 @@ mod linear {
((capacity as float) * 3. / 4.) as uint
}
fn LinearMap<K:Eq Hash,V>() -> LinearMap<K,V> {
pub fn LinearMap<K:Eq Hash,V>() -> LinearMap<K,V> {
linear_map_with_capacity(32)
}
fn linear_map_with_capacity<K:Eq Hash,V>(
pub fn linear_map_with_capacity<K:Eq Hash,V>(
initial_capacity: uint) -> LinearMap<K,V> {
let r = rand::Rng();
linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(),
@ -137,7 +135,7 @@ mod linear {
k: &K) -> SearchResult {
let _ = for self.bucket_sequence(hash) |i| {
match buckets[i] {
Some(bkt) => if bkt.hash == hash && *k == bkt.key {
Some(ref bkt) => if bkt.hash == hash && *k == bkt.key {
return FoundEntry(i);
},
None => return FoundHole(i)
@ -163,7 +161,7 @@ mod linear {
}
}
fn insert_opt_bucket(&mut self, +bucket: Option<Bucket<K,V>>) {
fn insert_opt_bucket(&mut self, bucket: Option<Bucket<K,V>>) {
match move bucket {
Some(Bucket {hash: move hash,
key: move key,
@ -177,7 +175,7 @@ mod linear {
/// Inserts the key value pair into the buckets.
/// Assumes that there will be a bucket.
/// True if there was no previous entry with that key
fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
fn insert_internal(&mut self, hash: uint, k: K, v: V) -> bool {
match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
TableFull => { fail ~"Internal logic error"; }
FoundHole(idx) => {
@ -208,7 +206,7 @@ mod linear {
}
impl<K:Hash IterBytes Eq,V> LinearMap<K,V> {
fn insert(&mut self, +k: K, +v: V) -> bool {
fn insert(&mut self, k: K, v: V) -> bool {
if self.size >= self.resize_at {
// n.b.: We could also do this after searching, so
// that we do not resize if this call to insert is
@ -285,18 +283,9 @@ mod linear {
FoundEntry(idx) => {
match self.buckets[idx] {
Some(ref bkt) => {
let ptr = unsafe {
// FIXME(#3148)--region inference
// fails to capture needed deps.
// Here, the bucket value is known to
// live as long as self, because self
// is immutable. But the region
// inference stupidly infers a
// lifetime for `ref bkt` that is
// shorter than it needs to be.
cast::copy_lifetime(self, &bkt.value)
};
Some(ptr)
// FIXME(#3148)---should be inferred
let bkt: &self/Bucket<K,V> = bkt;
Some(&bkt.value)
}
None => {
fail ~"LinearMap::find: internal logic error"
@ -344,7 +333,7 @@ mod linear {
// FIXME (#3148): Once we rewrite found_entry, this
// failure case won't be necessary
match self.buckets[idx] {
Some(bkt) => {Some(copy bkt.value)}
Some(Bucket {value: copy value, _}) => {Some(value)}
None => fail ~"LinearMap::find: internal logic error"
}
}
@ -366,13 +355,11 @@ mod linear {
}
#[test]
mod test {
#[legacy_exports];
pub mod test {
use linear::LinearMap;
#[test]
fn inserts() {
pub fn inserts() {
let mut m = ~LinearMap();
assert m.insert(1, 2);
assert m.insert(2, 4);
@ -381,7 +368,7 @@ mod test {
}
#[test]
fn overwrite() {
pub fn overwrite() {
let mut m = ~LinearMap();
assert m.insert(1, 2);
assert m.get(&1) == 2;
@ -390,7 +377,7 @@ mod test {
}
#[test]
fn conflicts() {
pub fn conflicts() {
let mut m = linear::linear_map_with_capacity(4);
assert m.insert(1, 2);
assert m.insert(5, 3);
@ -401,7 +388,7 @@ mod test {
}
#[test]
fn conflict_remove() {
pub fn conflict_remove() {
let mut m = linear::linear_map_with_capacity(4);
assert m.insert(1, 2);
assert m.insert(5, 3);
@ -412,7 +399,7 @@ mod test {
}
#[test]
fn empty() {
pub fn empty() {
let mut m = linear::linear_map_with_capacity(4);
assert m.insert(1, 2);
assert !m.is_empty();
@ -421,7 +408,7 @@ mod test {
}
#[test]
fn iterate() {
pub fn iterate() {
let mut m = linear::linear_map_with_capacity(4);
for uint::range(0, 32) |i| {
assert m.insert(i, i*2);
@ -435,7 +422,7 @@ mod test {
}
#[test]
fn find_ref() {
pub fn find_ref() {
let mut m = ~LinearMap();
assert m.find_ref(&1).is_none();
m.insert(1, 2);

View file

@ -1,7 +1,10 @@
#[doc(hidden)]; // FIXME #3538
#[legacy_modes]; // tjc: remove after snapshot
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// XXX: Can't do this because frame_address needs a deprecated mode.
//#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use cast::reinterpret_cast;
@ -74,7 +77,7 @@ fn breakpoint() {
rustrt::rust_dbg_breakpoint()
}
fn frame_address(f: fn(*u8)) {
fn frame_address(f: fn(++x: *u8)) {
rusti::frame_address(f)
}
@ -86,5 +89,5 @@ extern mod rustrt {
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn frame_address(f: fn(*u8));
fn frame_address(f: fn(++x: *u8));
}

File diff suppressed because it is too large Load diff

View file

@ -7,21 +7,10 @@
use cmp::{Eq, Ord};
use libc::c_void;
export FreeGlue;
export TypeDesc;
export Closure;
export get_type_desc;
export size_of;
export min_align_of;
export pref_align_of;
export refcount;
export log_str;
export shape_eq, shape_lt, shape_le;
type FreeGlue = fn(*TypeDesc, *c_void);
pub type FreeGlue = fn(*TypeDesc, *c_void);
// Corresponds to runtime type_desc type
enum TypeDesc = {
pub enum TypeDesc = {
size: uint,
align: uint,
take_glue: uint,
@ -31,14 +20,13 @@ enum TypeDesc = {
};
/// The representation of a Rust closure
struct Closure {
pub struct Closure {
code: *(),
env: *(),
}
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn get_tydesc<T>() -> *();
fn size_of<T>() -> uint;
fn pref_align_of<T>() -> uint;
@ -47,15 +35,15 @@ extern mod rusti {
/// Compares contents of two pointers using the default method.
/// Equivalent to `*x1 == *x2`. Useful for hashtables.
pure fn shape_eq<T:Eq>(x1: &T, x2: &T) -> bool {
pub pure fn shape_eq<T:Eq>(x1: &T, x2: &T) -> bool {
*x1 == *x2
}
pure fn shape_lt<T:Ord>(x1: &T, x2: &T) -> bool {
pub pure fn shape_lt<T:Ord>(x1: &T, x2: &T) -> bool {
*x1 < *x2
}
pure fn shape_le<T:Ord>(x1: &T, x2: &T) -> bool {
pub pure fn shape_le<T:Ord>(x1: &T, x2: &T) -> bool {
*x1 <= *x2
}
@ -66,13 +54,13 @@ pure fn shape_le<T:Ord>(x1: &T, x2: &T) -> bool {
* performing dark magick.
*/
#[inline(always)]
pure fn get_type_desc<T>() -> *TypeDesc {
pub pure fn get_type_desc<T>() -> *TypeDesc {
unsafe { rusti::get_tydesc::<T>() as *TypeDesc }
}
/// Returns the size of a type
#[inline(always)]
pure fn size_of<T>() -> uint {
pub pure fn size_of<T>() -> uint {
unsafe { rusti::size_of::<T>() }
}
@ -83,26 +71,26 @@ pure fn size_of<T>() -> uint {
* than the preferred alignment.
*/
#[inline(always)]
pure fn min_align_of<T>() -> uint {
pub pure fn min_align_of<T>() -> uint {
unsafe { rusti::min_align_of::<T>() }
}
/// Returns the preferred alignment of a type
#[inline(always)]
pure fn pref_align_of<T>() -> uint {
pub pure fn pref_align_of<T>() -> uint {
unsafe { rusti::pref_align_of::<T>() }
}
/// Returns the refcount of a shared box (as just before calling this)
#[inline(always)]
pure fn refcount<T>(+t: @T) -> uint {
pub pure fn refcount<T>(t: @T) -> uint {
unsafe {
let ref_ptr: *uint = cast::reinterpret_cast(&t);
*ref_ptr - 1
}
}
pure fn log_str<T>(t: &T) -> ~str {
pub pure fn log_str<T>(t: &T) -> ~str {
unsafe {
do io::with_str_writer |wr| {
repr::write_repr(wr, t)
@ -111,11 +99,10 @@ pure fn log_str<T>(t: &T) -> ~str {
}
#[cfg(test)]
mod tests {
#[legacy_exports];
pub mod tests {
#[test]
fn size_of_basic() {
pub fn size_of_basic() {
assert size_of::<u8>() == 1u;
assert size_of::<u16>() == 2u;
assert size_of::<u32>() == 4u;
@ -125,20 +112,20 @@ mod tests {
#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
fn size_of_32() {
pub fn size_of_32() {
assert size_of::<uint>() == 4u;
assert size_of::<*uint>() == 4u;
}
#[test]
#[cfg(target_arch = "x86_64")]
fn size_of_64() {
pub fn size_of_64() {
assert size_of::<uint>() == 8u;
assert size_of::<*uint>() == 8u;
}
#[test]
fn align_of_basic() {
pub fn align_of_basic() {
assert pref_align_of::<u8>() == 1u;
assert pref_align_of::<u16>() == 2u;
assert pref_align_of::<u32>() == 4u;
@ -147,20 +134,20 @@ mod tests {
#[test]
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
fn align_of_32() {
pub fn align_of_32() {
assert pref_align_of::<uint>() == 4u;
assert pref_align_of::<*uint>() == 4u;
}
#[test]
#[cfg(target_arch = "x86_64")]
fn align_of_64() {
pub fn align_of_64() {
assert pref_align_of::<uint>() == 8u;
assert pref_align_of::<*uint>() == 8u;
}
#[test]
fn synthesize_closure() unsafe {
pub fn synthesize_closure() unsafe {
let x = 10;
let f: fn(int) -> int = |y| x + y;

View file

@ -1,5 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
/*!
@ -32,54 +32,11 @@ use result::Result;
use pipes::{stream, Chan, Port};
use local_data_priv::{local_get, local_set};
export Task;
export TaskResult;
export Notification;
export SchedMode;
export SchedOpts;
export TaskOpts;
export TaskBuilder;
export task;
export default_task_opts;
export get_opts;
export set_opts;
export set_sched_mode;
export add_wrapper;
export run;
export future_result;
export run_listener;
export run_with;
export spawn;
export spawn_unlinked;
export spawn_supervised;
export spawn_with;
export spawn_listener;
export spawn_conversation;
export spawn_sched;
export try;
export yield;
export failing;
export get_task;
export unkillable, rekillable;
export atomically;
export local_data;
export SingleThreaded;
export ThreadPerCore;
export ThreadPerTask;
export ManualThreads;
export PlatformThread;
use rt::task_id;
use rt::rust_task;
/// A handle to a task
enum Task {
pub enum Task {
TaskHandle(task_id)
}
@ -99,7 +56,7 @@ impl Task : cmp::Eq {
* If you wish for this result's delivery to block until all linked and/or
* children tasks complete, recommend using a result future.
*/
enum TaskResult {
pub enum TaskResult {
Success,
Failure,
}
@ -115,7 +72,7 @@ impl TaskResult : Eq {
}
/// A message type for notifying of task lifecycle events
enum Notification {
pub enum Notification {
/// Sent when a task exits with the task handle and result
Exit(Task, TaskResult)
}
@ -134,7 +91,7 @@ impl Notification : cmp::Eq {
}
/// Scheduler modes
enum SchedMode {
pub enum SchedMode {
/// All tasks run in the same OS thread
SingleThreaded,
/// Tasks are distributed among available CPUs
@ -207,7 +164,7 @@ impl SchedMode : cmp::Eq {
* default these foreign stacks have unspecified size, but with this
* option their size can be precisely specified.
*/
type SchedOpts = {
pub type SchedOpts = {
mode: SchedMode,
foreign_stack_size: Option<uint>
};
@ -239,7 +196,7 @@ type SchedOpts = {
* into foreign code that blocks. Without doing so in a different
* scheduler other tasks will be impeded or even blocked indefinitely.
*/
type TaskOpts = {
pub type TaskOpts = {
linked: bool,
supervised: bool,
mut notify_chan: Option<Chan<Notification>>,
@ -260,7 +217,7 @@ type TaskOpts = {
// the run function move them in.
// FIXME (#2585): Replace the 'consumed' bit with move mode on self
enum TaskBuilder = {
pub enum TaskBuilder = {
opts: TaskOpts,
gen_body: fn@(+v: fn~()) -> fn~(),
can_not_copy: Option<util::NonCopyable>,
@ -272,10 +229,10 @@ enum TaskBuilder = {
* configuration methods can be chained.
* For example, task().unlinked().spawn is equivalent to spawn_unlinked.
*/
fn task() -> TaskBuilder {
pub fn task() -> TaskBuilder {
TaskBuilder({
opts: default_task_opts(),
gen_body: |body| move body, // Identity function
gen_body: |+body| move body, // Identity function
can_not_copy: None,
mut consumed: false,
})
@ -390,7 +347,7 @@ impl TaskBuilder {
* # Failure
* Fails if a future_result was already set for this task.
*/
fn future_result(blk: fn(+v: future::Future<TaskResult>)) -> TaskBuilder {
fn future_result(blk: fn(v: future::Future<TaskResult>)) -> TaskBuilder {
// FIXME (#1087, #1857): Once linked failure and notification are
// handled in the library, I can imagine implementing this by just
// registering an arbitrary number of task::on_exit handlers and
@ -473,7 +430,7 @@ impl TaskBuilder {
}
/**
* Creates and exucutes a new child task
* Creates and executes a new child task
*
* Sets up a new task with its own call stack and schedules it to run
* the provided unique closure. The task has the properties and behavior
@ -502,9 +459,9 @@ impl TaskBuilder {
spawn::spawn_raw(move opts, x.gen_body(move f));
}
/// Runs a task, while transfering ownership of one argument to the child.
fn spawn_with<A: Send>(+arg: A, +f: fn~(+v: A)) {
fn spawn_with<A: Send>(arg: A, +f: fn~(+v: A)) {
let arg = ~mut Some(move arg);
do self.spawn |move arg, move f|{
do self.spawn |move arg, move f| {
f(option::swap_unwrap(arg))
}
}
@ -516,7 +473,7 @@ impl TaskBuilder {
* child task, passes the port to child's body, and returns a channel
* linked to the port to the parent.
*
* This encapsulates Some boilerplate handshaking logic that would
* This encapsulates some boilerplate handshaking logic that would
* otherwise be required to establish communication from the parent
* to the child.
*/
@ -580,7 +537,7 @@ impl TaskBuilder {
/* Task construction */
fn default_task_opts() -> TaskOpts {
pub fn default_task_opts() -> TaskOpts {
/*!
* The default task options
*
@ -598,7 +555,7 @@ fn default_task_opts() -> TaskOpts {
/* Spawn convenience functions */
fn spawn(+f: fn~()) {
pub fn spawn(+f: fn~()) {
/*!
* Creates and executes a new child task
*
@ -611,7 +568,7 @@ fn spawn(+f: fn~()) {
task().spawn(move f)
}
fn spawn_unlinked(+f: fn~()) {
pub fn spawn_unlinked(+f: fn~()) {
/*!
* Creates a child task unlinked from the current one. If either this
* task or the child task fails, the other will not be killed.
@ -620,7 +577,7 @@ fn spawn_unlinked(+f: fn~()) {
task().unlinked().spawn(move f)
}
fn spawn_supervised(+f: fn~()) {
pub fn spawn_supervised(+f: fn~()) {
/*!
* Creates a child task unlinked from the current one. If either this
* task or the child task fails, the other will not be killed.
@ -629,7 +586,7 @@ fn spawn_supervised(+f: fn~()) {
task().supervised().spawn(move f)
}
fn spawn_with<A:Send>(+arg: A, +f: fn~(+v: A)) {
pub fn spawn_with<A:Send>(+arg: A, +f: fn~(+v: A)) {
/*!
* Runs a task, while transfering ownership of one argument to the
* child.
@ -643,7 +600,7 @@ fn spawn_with<A:Send>(+arg: A, +f: fn~(+v: A)) {
task().spawn_with(move arg, move f)
}
fn spawn_listener<A:Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
pub fn spawn_listener<A:Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
/*!
* Runs a new task while providing a channel from the parent to the child
*
@ -653,7 +610,7 @@ fn spawn_listener<A:Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
task().spawn_listener(move f)
}
fn spawn_conversation<A: Send, B: Send>
pub fn spawn_conversation<A: Send, B: Send>
(+f: fn~(comm::Port<A>, comm::Chan<B>))
-> (comm::Port<B>, comm::Chan<A>) {
/*!
@ -665,7 +622,7 @@ fn spawn_conversation<A: Send, B: Send>
task().spawn_conversation(move f)
}
fn spawn_sched(mode: SchedMode, +f: fn~()) {
pub fn spawn_sched(mode: SchedMode, +f: fn~()) {
/*!
* Creates a new scheduler and executes a task on it
*
@ -682,7 +639,7 @@ fn spawn_sched(mode: SchedMode, +f: fn~()) {
task().sched_mode(mode).spawn(move f)
}
fn try<T:Send>(+f: fn~() -> T) -> Result<T,()> {
pub fn try<T:Send>(+f: fn~() -> T) -> Result<T,()> {
/*!
* Execute a function in another task and return either the return value
* of the function or result::err.
@ -696,7 +653,7 @@ fn try<T:Send>(+f: fn~() -> T) -> Result<T,()> {
/* Lifecycle functions */
fn yield() {
pub fn yield() {
//! Yield control to the task scheduler
let task_ = rt::rust_get_task();
@ -706,13 +663,13 @@ fn yield() {
}
}
fn failing() -> bool {
pub fn failing() -> bool {
//! True if the running task has failed
rt::rust_task_is_unwinding(rt::rust_get_task())
}
fn get_task() -> Task {
pub fn get_task() -> Task {
//! Get a handle to the running task
TaskHandle(rt::get_task_id())
@ -733,7 +690,7 @@ fn get_task() -> Task {
* }
* ~~~
*/
unsafe fn unkillable<U>(f: fn() -> U) -> U {
pub unsafe fn unkillable<U>(f: fn() -> U) -> U {
struct AllowFailure {
t: *rust_task,
drop { rt::rust_task_allow_kill(self.t); }
@ -752,7 +709,7 @@ unsafe fn unkillable<U>(f: fn() -> U) -> U {
}
/// The inverse of unkillable. Only ever to be used nested in unkillable().
unsafe fn rekillable<U>(f: fn() -> U) -> U {
pub unsafe fn rekillable<U>(f: fn() -> U) -> U {
struct DisallowFailure {
t: *rust_task,
drop { rt::rust_task_inhibit_kill(self.t); }
@ -774,7 +731,7 @@ unsafe fn rekillable<U>(f: fn() -> U) -> U {
* A stronger version of unkillable that also inhibits scheduling operations.
* For use with exclusive ARCs, which use pthread mutexes directly.
*/
unsafe fn atomically<U>(f: fn() -> U) -> U {
pub unsafe fn atomically<U>(f: fn() -> U) -> U {
struct DeferInterrupts {
t: *rust_task,
drop {
@ -1102,7 +1059,6 @@ fn test_spawn_sched_childs_on_same_sched() {
#[nolink]
#[cfg(test)]
extern mod testrt {
#[legacy_exports];
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);
@ -1175,10 +1131,10 @@ fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) {
let ch = comm::Chan(p);
let x = ~1;
let x_in_parent = ptr::addr_of(*x) as uint;
let x_in_parent = ptr::p2::addr_of(&(*x)) as uint;
do spawnfn {
let x_in_child = ptr::addr_of(*x) as uint;
let x_in_child = ptr::p2::addr_of(&(*x)) as uint;
comm::send(ch, x_in_child);
}
@ -1193,7 +1149,7 @@ fn test_avoid_copying_the_body_spawn() {
#[test]
fn test_avoid_copying_the_body_spawn_listener() {
do avoid_copying_the_body |f| {
do avoid_copying_the_body |+f| {
spawn_listener(fn~(move f, _po: comm::Port<int>) {
f();
});
@ -1211,7 +1167,7 @@ fn test_avoid_copying_the_body_task_spawn() {
#[test]
fn test_avoid_copying_the_body_spawn_listener_1() {
do avoid_copying_the_body |f| {
do avoid_copying_the_body |+f| {
task().spawn_listener(fn~(move f, _po: comm::Port<int>) {
f();
});

View file

@ -16,12 +16,6 @@ magic.
*/
export LocalDataKey;
export local_data_pop;
export local_data_get;
export local_data_set;
export local_data_modify;
use local_data_priv::{
local_pop,
local_get,
@ -43,13 +37,13 @@ use local_data_priv::{
*
* These two cases aside, the interface is safe.
*/
type LocalDataKey<T: Owned> = &fn(+v: @T);
pub type LocalDataKey<T: Owned> = &fn(v: @T);
/**
* Remove a task-local data value from the table, returning the
* reference that was originally created to insert it.
*/
unsafe fn local_data_pop<T: Owned>(
pub unsafe fn local_data_pop<T: Owned>(
key: LocalDataKey<T>) -> Option<@T> {
local_pop(rt::rust_get_task(), key)
@ -58,7 +52,7 @@ unsafe fn local_data_pop<T: Owned>(
* Retrieve a task-local data value. It will also be kept alive in the
* table until explicitly removed.
*/
unsafe fn local_data_get<T: Owned>(
pub unsafe fn local_data_get<T: Owned>(
key: LocalDataKey<T>) -> Option<@T> {
local_get(rt::rust_get_task(), key)
@ -67,8 +61,8 @@ unsafe fn local_data_get<T: Owned>(
* Store a value in task-local data. If this key already has a value,
* that value is overwritten (and its destructor is run).
*/
unsafe fn local_data_set<T: Owned>(
key: LocalDataKey<T>, +data: @T) {
pub unsafe fn local_data_set<T: Owned>(
key: LocalDataKey<T>, data: @T) {
local_set(rt::rust_get_task(), key, data)
}
@ -76,7 +70,7 @@ unsafe fn local_data_set<T: Owned>(
* Modify a task-local data value. If the function returns 'None', the
* data is removed (and its reference dropped).
*/
unsafe fn local_data_modify<T: Owned>(
pub unsafe fn local_data_modify<T: Owned>(
key: LocalDataKey<T>,
modify_fn: fn(Option<@T>) -> Option<@T>) {
@ -84,8 +78,8 @@ unsafe fn local_data_modify<T: Owned>(
}
#[test]
fn test_tls_multitask() unsafe {
fn my_key(+_x: @~str) { }
pub fn test_tls_multitask() unsafe {
fn my_key(_x: @~str) { }
local_data_set(my_key, @~"parent data");
do task::spawn unsafe {
assert local_data_get(my_key).is_none(); // TLS shouldn't carry over.
@ -100,16 +94,16 @@ fn test_tls_multitask() unsafe {
}
#[test]
fn test_tls_overwrite() unsafe {
fn my_key(+_x: @~str) { }
pub fn test_tls_overwrite() unsafe {
fn my_key(_x: @~str) { }
local_data_set(my_key, @~"first data");
local_data_set(my_key, @~"next data"); // Shouldn't leak.
assert *(local_data_get(my_key).get()) == ~"next data";
}
#[test]
fn test_tls_pop() unsafe {
fn my_key(+_x: @~str) { }
pub fn test_tls_pop() unsafe {
fn my_key(_x: @~str) { }
local_data_set(my_key, @~"weasel");
assert *(local_data_pop(my_key).get()) == ~"weasel";
// Pop must remove the data from the map.
@ -117,18 +111,18 @@ fn test_tls_pop() unsafe {
}
#[test]
fn test_tls_modify() unsafe {
fn my_key(+_x: @~str) { }
pub fn test_tls_modify() unsafe {
fn my_key(_x: @~str) { }
local_data_modify(my_key, |data| {
match data {
Some(@val) => fail ~"unwelcome value: " + val,
Some(@ref val) => fail ~"unwelcome value: " + *val,
None => Some(@~"first data")
}
});
local_data_modify(my_key, |data| {
match data {
Some(@~"first data") => Some(@~"next data"),
Some(@val) => fail ~"wrong value: " + val,
Some(@ref val) => fail ~"wrong value: " + *val,
None => fail ~"missing value"
}
});
@ -136,23 +130,23 @@ fn test_tls_modify() unsafe {
}
#[test]
fn test_tls_crust_automorestack_memorial_bug() unsafe {
pub fn test_tls_crust_automorestack_memorial_bug() unsafe {
// This might result in a stack-canary clobber if the runtime fails to set
// sp_limit to 0 when calling the cleanup extern - it might automatically
// jump over to the rust stack, which causes next_c_sp to get recorded as
// Something within a rust stack segment. Then a subsequent upcall (esp.
// for logging, think vsnprintf) would run on a stack smaller than 1 MB.
fn my_key(+_x: @~str) { }
fn my_key(_x: @~str) { }
do task::spawn {
unsafe { local_data_set(my_key, @~"hax"); }
}
}
#[test]
fn test_tls_multiple_types() unsafe {
fn str_key(+_x: @~str) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
pub fn test_tls_multiple_types() unsafe {
fn str_key(_x: @~str) { }
fn box_key(_x: @@()) { }
fn int_key(_x: @int) { }
do task::spawn unsafe {
local_data_set(str_key, @~"string data");
local_data_set(box_key, @@());
@ -161,10 +155,10 @@ fn test_tls_multiple_types() unsafe {
}
#[test]
fn test_tls_overwrite_multiple_types() {
fn str_key(+_x: @~str) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
pub fn test_tls_overwrite_multiple_types() {
fn str_key(_x: @~str) { }
fn box_key(_x: @@()) { }
fn int_key(_x: @int) { }
do task::spawn unsafe {
local_data_set(str_key, @~"string data");
local_data_set(int_key, @42);
@ -177,10 +171,10 @@ fn test_tls_overwrite_multiple_types() {
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn test_tls_cleanup_on_failure() unsafe {
fn str_key(+_x: @~str) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
pub fn test_tls_cleanup_on_failure() unsafe {
fn str_key(_x: @~str) { }
fn box_key(_x: @@()) { }
fn int_key(_x: @int) { }
local_data_set(str_key, @~"parent data");
local_data_set(box_key, @@());
do task::spawn unsafe { // spawn_linked

View file

@ -3,7 +3,7 @@
use local_data::LocalDataKey;
use rt::rust_task;
trait LocalData { }
pub trait LocalData { }
impl<T: Owned> @T: LocalData { }
impl LocalData: Eq {
@ -17,11 +17,11 @@ impl LocalData: Eq {
// We use dvec because it's the best data structure in core. If TLS is used
// heavily in future, this could be made more efficient with a proper map.
type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
pub type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
// Has to be a pointer at outermost layer; the foreign call returns void *.
type TaskLocalMap = @dvec::DVec<Option<TaskLocalElement>>;
pub type TaskLocalMap = @dvec::DVec<Option<TaskLocalElement>>;
extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
assert !map_ptr.is_null();
// Get and keep the single reference that was created at the beginning.
let _map: TaskLocalMap = cast::reinterpret_cast(&map_ptr);
@ -29,7 +29,7 @@ extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
}
// Gets the map from the runtime. Lazily initialises if not done so already.
unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
// Relies on the runtime initialising the pointer to null.
// NOTE: The map's box lives in TLS invisibly referenced once. Each time
@ -52,7 +52,7 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
}
}
unsafe fn key_to_key_value<T: Owned>(
pub unsafe fn key_to_key_value<T: Owned>(
key: LocalDataKey<T>) -> *libc::c_void {
// Keys are closures, which are (fnptr,envptr) pairs. Use fnptr.
@ -62,25 +62,25 @@ unsafe fn key_to_key_value<T: Owned>(
}
// If returning Some(..), returns with @T with the map's reference. Careful!
unsafe fn local_data_lookup<T: Owned>(
pub unsafe fn local_data_lookup<T: Owned>(
map: TaskLocalMap, key: LocalDataKey<T>)
-> Option<(uint, *libc::c_void)> {
let key_value = key_to_key_value(key);
let map_pos = (*map).position(|entry|
match entry {
match *entry {
Some((k,_,_)) => k == key_value,
None => false
}
);
do map_pos.map |index| {
// .get() is guaranteed because of "None { false }" above.
let (_, data_ptr, _) = (*map)[index].get();
(index, data_ptr)
let (_, data_ptr, _) = (*map)[*index].get();
(*index, data_ptr)
}
}
unsafe fn local_get_helper<T: Owned>(
pub unsafe fn local_get_helper<T: Owned>(
task: *rust_task, key: LocalDataKey<T>,
do_pop: bool) -> Option<@T> {
@ -91,7 +91,7 @@ unsafe fn local_get_helper<T: Owned>(
// was referenced in the local_data box, though, not here, so before
// overwriting the local_data_box we need to give an extra reference.
// We must also give an extra reference when not removing.
let (index, data_ptr) = result;
let (index, data_ptr) = *result;
let data: @T = cast::transmute(move data_ptr);
cast::bump_box_refcount(data);
if do_pop {
@ -102,22 +102,22 @@ unsafe fn local_get_helper<T: Owned>(
}
unsafe fn local_pop<T: Owned>(
pub unsafe fn local_pop<T: Owned>(
task: *rust_task,
key: LocalDataKey<T>) -> Option<@T> {
local_get_helper(task, key, true)
}
unsafe fn local_get<T: Owned>(
pub unsafe fn local_get<T: Owned>(
task: *rust_task,
key: LocalDataKey<T>) -> Option<@T> {
local_get_helper(task, key, false)
}
unsafe fn local_set<T: Owned>(
task: *rust_task, key: LocalDataKey<T>, +data: @T) {
pub unsafe fn local_set<T: Owned>(
task: *rust_task, key: LocalDataKey<T>, data: @T) {
let map = get_task_local_map(task);
// Store key+data as *voids. Data is invisibly referenced once; key isn't.
@ -148,7 +148,7 @@ unsafe fn local_set<T: Owned>(
}
}
unsafe fn local_modify<T: Owned>(
pub unsafe fn local_modify<T: Owned>(
task: *rust_task, key: LocalDataKey<T>,
modify_fn: fn(Option<@T>) -> Option<@T>) {

View file

@ -7,16 +7,16 @@ The task interface to the runtime
#[doc(hidden)]; // FIXME #3538
#[allow(non_camel_case_types)] // runtime type
type sched_id = int;
pub type sched_id = int;
#[allow(non_camel_case_types)] // runtime type
type task_id = int;
pub type task_id = int;
// These are both opaque runtime/compiler types that we don't know the
// structure of and should only deal with via unsafe pointer
#[allow(non_camel_case_types)] // runtime type
type rust_task = libc::c_void;
pub type rust_task = libc::c_void;
#[allow(non_camel_case_types)] // runtime type
type rust_closure = libc::c_void;
pub type rust_closure = libc::c_void;
extern {
#[rust_stack]

View file

@ -66,28 +66,28 @@ use rt::rust_task;
use rt::rust_closure;
macro_rules! move_it (
{ $x:expr } => { unsafe { let y <- *ptr::addr_of($x); move y } }
{ $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } }
)
type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
pub type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
fn new_taskset() -> TaskSet {
pub fn new_taskset() -> TaskSet {
send_map::linear::LinearMap()
}
fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
pub fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
let didnt_overwrite = tasks.insert(task, ());
assert didnt_overwrite;
}
fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
pub fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
let was_present = tasks.remove(&task);
assert was_present;
}
fn taskset_each(tasks: &TaskSet, blk: fn(+v: *rust_task) -> bool) {
pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) {
tasks.each_key(|k| blk(*k))
}
// One of these per group of linked-failure tasks.
type TaskGroupData = {
pub type TaskGroupData = {
// All tasks which might kill this group. When this is empty, the group
// can be "GC"ed (i.e., its link in the ancestor list can be removed).
mut members: TaskSet,
@ -95,12 +95,12 @@ type TaskGroupData = {
// tasks in this group.
mut descendants: TaskSet,
};
type TaskGroupArc = private::Exclusive<Option<TaskGroupData>>;
pub type TaskGroupArc = private::Exclusive<Option<TaskGroupData>>;
type TaskGroupInner = &mut Option<TaskGroupData>;
pub type TaskGroupInner = &mut Option<TaskGroupData>;
// A taskgroup is 'dead' when nothing can cause it to fail; only members can.
pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
(&tg.members).is_empty()
}
@ -111,7 +111,7 @@ pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
// taskgroup which was spawned-unlinked. Tasks from intermediate generations
// have references to the middle of the list; when intermediate generations
// die, their node in the list will be collected at a descendant's spawn-time.
type AncestorNode = {
pub type AncestorNode = {
// Since the ancestor list is recursive, we end up with references to
// exclusives within other exclusives. This is dangerous business (if
// circular references arise, deadlock and memory leaks are imminent).
@ -124,16 +124,16 @@ type AncestorNode = {
// Recursive rest of the list.
mut ancestors: AncestorList,
};
enum AncestorList = Option<private::Exclusive<AncestorNode>>;
pub enum AncestorList = Option<private::Exclusive<AncestorNode>>;
// Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
#[inline(always)]
fn access_group<U>(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
pub fn access_group<U>(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
unsafe { x.with(blk) }
}
#[inline(always)]
fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
pub fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
blk: fn(x: &mut AncestorNode) -> U) -> U {
unsafe { x.with(blk) }
}
@ -146,9 +146,9 @@ fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
// (3) As a bonus, coalesces away all 'dead' taskgroup nodes in the list.
// FIXME(#2190): Change Option<fn@(...)> to Option<fn&(...)>, to save on
// allocations. Once that bug is fixed, changing the sigil should suffice.
fn each_ancestor(list: &mut AncestorList,
bail_opt: Option<fn@(TaskGroupInner)>,
forward_blk: fn(TaskGroupInner) -> bool)
pub fn each_ancestor(list: &mut AncestorList,
bail_opt: Option<fn@(TaskGroupInner)>,
forward_blk: fn(TaskGroupInner) -> bool)
-> bool {
// "Kickoff" call - there was no last generation.
return !coalesce(list, bail_opt, forward_blk, uint::max_value);
@ -200,7 +200,7 @@ fn each_ancestor(list: &mut AncestorList,
// the end of the list, which doesn't make sense to coalesce.
return do (**ancestors).map_default((None,false)) |ancestor_arc| {
// NB: Takes a lock! (this ancestor node)
do access_ancestors(&ancestor_arc) |nobe| {
do access_ancestors(ancestor_arc) |nobe| {
// Check monotonicity
assert last_generation > nobe.generation;
/*##########################################################*
@ -240,7 +240,7 @@ fn each_ancestor(list: &mut AncestorList,
if need_unwind && !nobe_is_dead {
do bail_opt.iter |bail_blk| {
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
bail_blk(tg_opt)
(*bail_blk)(tg_opt)
}
}
}
@ -271,7 +271,7 @@ fn each_ancestor(list: &mut AncestorList,
}
// One of these per task.
struct TCB {
pub struct TCB {
me: *rust_task,
// List of tasks with whose fates this one's is intertwined.
tasks: TaskGroupArc, // 'none' means the group has failed.
@ -303,8 +303,8 @@ struct TCB {
}
}
fn TCB(me: *rust_task, +tasks: TaskGroupArc, +ancestors: AncestorList,
is_main: bool, +notifier: Option<AutoNotify>) -> TCB {
pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
is_main: bool, notifier: Option<AutoNotify>) -> TCB {
let notifier = move notifier;
notifier.iter(|x| { x.failed = false; });
@ -318,7 +318,7 @@ fn TCB(me: *rust_task, +tasks: TaskGroupArc, +ancestors: AncestorList,
}
}
struct AutoNotify {
pub struct AutoNotify {
notify_chan: Chan<Notification>,
mut failed: bool,
drop {
@ -327,15 +327,15 @@ struct AutoNotify {
}
}
fn AutoNotify(+chan: Chan<Notification>) -> AutoNotify {
pub fn AutoNotify(chan: Chan<Notification>) -> AutoNotify {
AutoNotify {
notify_chan: chan,
failed: true // Un-set above when taskgroup successfully made.
}
}
fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
is_member: bool) -> bool {
pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
is_member: bool) -> bool {
let newstate = util::replace(state, None);
// If 'None', the group was failing. Can't enlist.
if newstate.is_some() {
@ -350,7 +350,8 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
}
// NB: Runs in destructor/post-exit context. Can't 'fail'.
fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) {
pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
is_member: bool) {
let newstate = util::replace(state, None);
// If 'None', already failing and we've already gotten a kill signal.
if newstate.is_some() {
@ -362,7 +363,7 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) {
}
// NB: Runs in destructor/post-exit context. Can't 'fail'.
fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
pub fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
// NB: We could do the killing iteration outside of the group arc, by
// having "let mut newstate" here, swapping inside, and iterating after.
// But that would let other exiting tasks fall-through and exit while we
@ -377,13 +378,13 @@ fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
// see 'None' if Somebody already failed and we got a kill signal.)
if newstate.is_some() {
let group = option::unwrap(move newstate);
for taskset_each(&group.members) |+sibling| {
for taskset_each(&group.members) |sibling| {
// Skip self - killing ourself won't do much good.
if sibling != me {
rt::rust_task_kill_other(sibling);
}
}
for taskset_each(&group.descendants) |+child| {
for taskset_each(&group.descendants) |child| {
assert child != me;
rt::rust_task_kill_other(child);
}
@ -404,8 +405,8 @@ macro_rules! taskgroup_key (
() => (cast::transmute((-2 as uint, 0u)))
)
fn gen_child_taskgroup(linked: bool, supervised: bool)
-> (TaskGroupArc, AncestorList, bool) {
pub fn gen_child_taskgroup(linked: bool, supervised: bool)
-> (TaskGroupArc, AncestorList, bool) {
let spawner = rt::rust_get_task();
/*######################################################################*
* Step 1. Get spawner's taskgroup info.
@ -451,7 +452,9 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
// it should be enabled only in debug builds.
let new_generation =
match *old_ancestors {
Some(arc) => access_ancestors(&arc, |a| a.generation+1),
Some(ref arc) => {
access_ancestors(arc, |a| a.generation+1)
}
None => 0 // the actual value doesn't really matter.
};
assert new_generation < uint::max_value;
@ -484,7 +487,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
}
}
fn spawn_raw(+opts: TaskOpts, +f: fn~()) {
pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
let (child_tg, ancestors, is_main) =
gen_child_taskgroup(opts.linked, opts.supervised);
@ -509,8 +512,8 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) {
let child_wrapper = make_child_wrapper(new_task, move child_tg,
move ancestors, is_main, move notify_chan, move f);
let fptr = ptr::addr_of(child_wrapper);
let closure: *rust_closure = cast::reinterpret_cast(&fptr);
let closure = cast::transmute(&child_wrapper);
// Getting killed between these two calls would free the child's
// closure. (Reordering them wouldn't help - then getting killed
@ -526,9 +529,9 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) {
// (3a) If any of those fails, it leaves all groups, and does nothing.
// (3b) Otherwise it builds a task control structure and puts it in TLS,
// (4) ...and runs the provided body function.
fn make_child_wrapper(child: *rust_task, +child_arc: TaskGroupArc,
+ancestors: AncestorList, is_main: bool,
+notify_chan: Option<Chan<Notification>>,
fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
ancestors: AncestorList, is_main: bool,
notify_chan: Option<Chan<Notification>>,
+f: fn~()) -> fn~() {
let child_data = ~mut Some((move child_arc, move ancestors));
return fn~(move notify_chan, move child_data, move f) {
@ -541,8 +544,8 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) {
//let mut notifier = None;//notify_chan.map(|c| AutoNotify(c));
let notifier = match notify_chan {
Some(notify_chan_value) => {
let moved_ncv = move_it!(notify_chan_value);
Some(ref notify_chan_value) => {
let moved_ncv = move_it!(*notify_chan_value);
Some(AutoNotify(move moved_ncv))
}
_ => None

View file

@ -10,7 +10,7 @@ The `ToBytes` and `IterBytes` traits
use io::Writer;
type Cb = fn(buf: &[const u8]) -> bool;
pub type Cb = fn(buf: &[const u8]) -> bool;
/**
* A trait to implement in order to make a type hashable;
@ -19,7 +19,7 @@ type Cb = fn(buf: &[const u8]) -> bool;
* modified when default methods and trait inheritence are
* completed.
*/
trait IterBytes {
pub trait IterBytes {
/**
* Call the provided callback `f` one or more times with
* byte-slices that should be used when computing a hash
@ -211,7 +211,7 @@ impl<A: IterBytes> @[A]: IterBytes {
}
}
pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
pub pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
lsb0: bool, z: Cb) {
let mut flag = true;
a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
@ -219,7 +219,7 @@ pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}
pure fn iter_bytes_3<A: IterBytes,
pub pure fn iter_bytes_3<A: IterBytes,
B: IterBytes,
C: IterBytes>(a: &A, b: &B, c: &C,
lsb0: bool, z: Cb) {
@ -231,7 +231,7 @@ pure fn iter_bytes_3<A: IterBytes,
c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}
pure fn iter_bytes_4<A: IterBytes,
pub pure fn iter_bytes_4<A: IterBytes,
B: IterBytes,
C: IterBytes,
D: IterBytes>(a: &A, b: &B, c: &C,
@ -247,7 +247,7 @@ pure fn iter_bytes_4<A: IterBytes,
d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}
pure fn iter_bytes_5<A: IterBytes,
pub pure fn iter_bytes_5<A: IterBytes,
B: IterBytes,
C: IterBytes,
D: IterBytes,
@ -266,7 +266,7 @@ pure fn iter_bytes_5<A: IterBytes,
e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}
pure fn iter_bytes_6<A: IterBytes,
pub pure fn iter_bytes_6<A: IterBytes,
B: IterBytes,
C: IterBytes,
D: IterBytes,
@ -288,7 +288,7 @@ pure fn iter_bytes_6<A: IterBytes,
f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}
pure fn iter_bytes_7<A: IterBytes,
pub pure fn iter_bytes_7<A: IterBytes,
B: IterBytes,
C: IterBytes,
D: IterBytes,
@ -345,7 +345,7 @@ impl<A: IterBytes> Option<A>: IterBytes {
#[inline(always)]
pure fn iter_bytes(lsb0: bool, f: Cb) {
match self {
Some(a) => iter_bytes_2(&0u8, &a, lsb0, f),
Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f),
None => 1u8.iter_bytes(lsb0, f)
}
}

View file

@ -8,7 +8,7 @@ The `ToStr` trait for converting to strings
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
trait ToStr { fn to_str() -> ~str; }
pub trait ToStr { fn to_str() -> ~str; }
impl int: ToStr {
fn to_str() -> ~str { int::str(self) }
@ -101,7 +101,6 @@ impl<A: ToStr> ~A: ToStr {
#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
#[legacy_exports];
#[test]
fn test_simple_types() {
assert 1.to_str() == ~"1";

View file

@ -6,7 +6,7 @@
use cmp::{Eq, Ord};
trait TupleOps<T,U> {
pub trait TupleOps<T,U> {
pure fn first() -> T;
pure fn second() -> U;
pure fn swap() -> (U, T);
@ -34,49 +34,54 @@ impl<T: Copy, U: Copy> (T, U): TupleOps<T,U> {
}
trait ExtendedTupleOps<A,B> {
fn zip() -> ~[(A, B)];
fn map<C>(f: fn(A, B) -> C) -> ~[C];
pub trait ExtendedTupleOps<A,B> {
fn zip(&self) -> ~[(A, B)];
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
}
impl<A: Copy, B: Copy> (&[A], &[B]): ExtendedTupleOps<A,B> {
fn zip() -> ~[(A, B)] {
let (a, b) = self;
vec::zip_slice(a, b)
fn zip(&self) -> ~[(A, B)] {
match *self {
(ref a, ref b) => {
vec::zip_slice(*a, *b)
}
}
}
fn map<C>(f: fn(A, B) -> C) -> ~[C] {
let (a, b) = self;
vec::map2(a, b, f)
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
match *self {
(ref a, ref b) => {
vec::map2(*a, *b, f)
}
}
}
}
impl<A: Copy, B: Copy> (~[A], ~[B]): ExtendedTupleOps<A,B> {
fn zip() -> ~[(A, B)] {
// FIXME #2543: Bad copy
let (a, b) = copy self;
vec::zip(move a, move b)
fn zip(&self) -> ~[(A, B)] {
match *self {
(ref a, ref b) => {
vec::zip_slice(*a, *b)
}
}
}
fn map<C>(f: fn(A, B) -> C) -> ~[C] {
// FIXME #2543: Bad copy
let (a, b) = copy self;
vec::map2(a, b, f)
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
match *self {
(ref a, ref b) => {
vec::map2(*a, *b, f)
}
}
}
}
impl<A: Eq, B: Eq> (A, B) : Eq {
pure fn eq(other: &(A, B)) -> bool {
// XXX: This would be a lot less wordy with ref bindings, but I don't
// trust that they work yet.
match self {
(self_a, self_b) => {
match (*other) {
(ref other_a, ref other_b) => {
self_a.eq(other_a) && self_b.eq(other_b)
}
(ref self_a, ref self_b) => match other {
&(ref other_a, ref other_b) => {
(*self_a).eq(other_a) && (*self_b).eq(other_b)
}
}
}
@ -106,16 +111,11 @@ impl<A: Ord, B: Ord> (A, B) : Ord {
impl<A: Eq, B: Eq, C: Eq> (A, B, C) : Eq {
pure fn eq(other: &(A, B, C)) -> bool {
// XXX: This would be a lot less wordy with ref bindings, but I don't
// trust that they work yet.
match self {
(self_a, self_b, self_c) => {
match (*other) {
(ref other_a, ref other_b, ref other_c) => {
self_a.eq(other_a) &&
self_b.eq(other_b) &&
self_c.eq(other_c)
}
(ref self_a, ref self_b, ref self_c) => match other {
&(ref other_a, ref other_b, ref other_c) => {
(*self_a).eq(other_a) && (*self_b).eq(other_b)
&& (*self_c).eq(other_c)
}
}
}

View file

@ -6,49 +6,36 @@ use T = inst::T;
use cmp::{Eq, Ord};
use from_str::FromStr;
export min_value, max_value;
export min, max;
export add, sub, mul, div, rem;
export lt, le, eq, ne, ge, gt;
export is_positive, is_negative;
export is_nonpositive, is_nonnegative;
export range;
export compl;
export to_str, to_str_bytes;
export from_str, from_str_radix, str, parse_bytes;
export num, ord, eq, times, timesi;
export bits, bytes;
pub const bits : uint = inst::bits;
pub const bytes : uint = (inst::bits / 8);
const bits : uint = inst::bits;
const bytes : uint = (inst::bits / 8);
pub const min_value: T = 0 as T;
pub const max_value: T = 0 as T - 1 as T;
const min_value: T = 0 as T;
const max_value: T = 0 as T - 1 as T;
pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }
pub pure fn add(x: T, y: T) -> T { x + y }
pub pure fn sub(x: T, y: T) -> T { x - y }
pub pure fn mul(x: T, y: T) -> T { x * y }
pub pure fn div(x: T, y: T) -> T { x / y }
pub pure fn rem(x: T, y: T) -> T { x % y }
pure fn add(x: T, y: T) -> T { x + y }
pure fn sub(x: T, y: T) -> T { x - y }
pure fn mul(x: T, y: T) -> T { x * y }
pure fn div(x: T, y: T) -> T { x / y }
pure fn rem(x: T, y: T) -> T { x % y }
pub pure fn lt(x: T, y: T) -> bool { x < y }
pub pure fn le(x: T, y: T) -> bool { x <= y }
pub pure fn eq(x: T, y: T) -> bool { x == y }
pub pure fn ne(x: T, y: T) -> bool { x != y }
pub pure fn ge(x: T, y: T) -> bool { x >= y }
pub pure fn gt(x: T, y: T) -> bool { x > y }
pure fn lt(x: T, y: T) -> bool { x < y }
pure fn le(x: T, y: T) -> bool { x <= y }
pure fn eq(x: T, y: T) -> bool { x == y }
pure fn ne(x: T, y: T) -> bool { x != y }
pure fn ge(x: T, y: T) -> bool { x >= y }
pure fn gt(x: T, y: T) -> bool { x > y }
pure fn is_positive(x: T) -> bool { x > 0 as T }
pure fn is_negative(x: T) -> bool { x < 0 as T }
pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
pub pure fn is_positive(x: T) -> bool { x > 0 as T }
pub pure fn is_negative(x: T) -> bool { x < 0 as T }
pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
#[inline(always)]
/// Iterate over the range [`lo`..`hi`)
pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
let mut i = lo;
while i < hi {
if !it(i) { break }
@ -57,7 +44,7 @@ pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
}
/// Computes the bitwise complement
pure fn compl(i: T) -> T {
pub pure fn compl(i: T) -> T {
max_value ^ i
}
@ -74,11 +61,11 @@ impl T : Eq {
}
impl T: num::Num {
pure fn add(&&other: T) -> T { return self + other; }
pure fn sub(&&other: T) -> T { return self - other; }
pure fn mul(&&other: T) -> T { return self * other; }
pure fn div(&&other: T) -> T { return self / other; }
pure fn modulo(&&other: T) -> T { return self % other; }
pure fn add(other: &T) -> T { return self + *other; }
pure fn sub(other: &T) -> T { return self - *other; }
pure fn mul(other: &T) -> T { return self * *other; }
pure fn div(other: &T) -> T { return self / *other; }
pure fn modulo(other: &T) -> T { return self % *other; }
pure fn neg() -> T { return -self; }
pure fn to_int() -> int { return self as int; }
@ -126,7 +113,7 @@ impl T: iter::TimesIx {
*
* `buf` must not be empty
*/
fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
pub fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
if vec::len(buf) == 0u { return None; }
let mut i = vec::len(buf) - 1u;
let mut power = 1u as T;
@ -143,14 +130,14 @@ fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
}
/// Parse a string to an int
fn from_str(s: &str) -> Option<T> { parse_bytes(str::to_bytes(s), 10u) }
pub fn from_str(s: &str) -> Option<T> { parse_bytes(str::to_bytes(s), 10u) }
impl T : FromStr {
static fn from_str(s: &str) -> Option<T> { from_str(s) }
}
/// Parse a string as an unsigned integer.
fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
if str::len(buf) == 0u { return None; }
let mut i = str::len(buf) - 1u;
let mut power = 1u64, n = 0u64;
@ -172,7 +159,7 @@ fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
*
* Fails if `radix` < 2 or `radix` > 16
*/
pure fn to_str(num: T, radix: uint) -> ~str {
pub pure fn to_str(num: T, radix: uint) -> ~str {
do to_str_bytes(false, num, radix) |slice| {
do vec::as_imm_buf(slice) |p, len| {
unsafe { str::raw::from_buf_len(p, len) }
@ -181,7 +168,7 @@ pure fn to_str(num: T, radix: uint) -> ~str {
}
/// Low-level helper routine for string conversion.
pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
f: fn(v: &[u8]) -> U) -> U {
#[inline(always)]
@ -239,17 +226,16 @@ pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
*ptr::mut_offset(mp, i) = '-' as u8;
}
vec::raw::form_slice(ptr::offset(p, i),
len - i, f)
vec::raw::buf_as_slice(ptr::offset(p, i), len - i, f)
}
}
}
/// Convert to a string
fn str(i: T) -> ~str { return to_str(i, 10u); }
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
#[test]
fn test_to_str() {
pub fn test_to_str() {
assert to_str(0 as T, 10u) == ~"0";
assert to_str(1 as T, 10u) == ~"1";
assert to_str(2 as T, 10u) == ~"2";
@ -261,7 +247,7 @@ fn test_to_str() {
#[test]
#[ignore]
fn test_from_str() {
pub fn test_from_str() {
assert from_str(~"0") == Some(0u as T);
assert from_str(~"3") == Some(3u as T);
assert from_str(~"10") == Some(10u as T);
@ -275,7 +261,7 @@ fn test_from_str() {
#[test]
#[ignore]
fn test_parse_bytes() {
pub fn test_parse_bytes() {
use str::to_bytes;
assert parse_bytes(to_bytes(~"123"), 10u) == Some(123u as T);
assert parse_bytes(to_bytes(~"1001"), 2u) == Some(9u as T);
@ -291,19 +277,19 @@ fn test_parse_bytes() {
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn to_str_radix1() {
pub fn to_str_radix1() {
uint::to_str(100u, 1u);
}
#[test]
#[should_fail]
#[ignore(cfg(windows))]
fn to_str_radix17() {
pub fn to_str_radix17() {
uint::to_str(100u, 17u);
}
#[test]
fn test_times() {
pub fn test_times() {
use iter::Times;
let ten = 10 as T;
let mut accum = 0;

View file

@ -1,2 +1,2 @@
type T = u16;
const bits: uint = 16;
pub type T = u16;
pub const bits: uint = 16;

View file

@ -1,2 +1,2 @@
type T = u32;
const bits: uint = 32;
pub type T = u32;
pub const bits: uint = 32;

View file

@ -1,2 +1,2 @@
type T = u64;
const bits: uint = 64;
pub type T = u64;
pub const bits: uint = 64;

View file

@ -1,7 +1,7 @@
type T = u8;
const bits: uint = 8;
pub type T = u8;
pub const bits: uint = 8;
// Type-specific functions here. These must be reexported by the
// parent module so that they appear in core::u8 and not core::u8::u8;
pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; }
pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; }

View file

@ -1,11 +1,11 @@
type T = uint;
pub type T = uint;
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
const bits: uint = 32;
pub const bits: uint = 32;
#[cfg(target_arch = "x86_64")]
const bits: uint = 64;
pub const bits: uint = 64;
/**
* Divide two numbers, return the result, rounded up.
@ -19,7 +19,7 @@ const bits: uint = 64;
*
* The smallest integer `q` such that `x/y <= q`.
*/
pure fn div_ceil(x: uint, y: uint) -> uint {
pub pure fn div_ceil(x: uint, y: uint) -> uint {
let div = x / y;
if x % y == 0u { div }
else { div + 1u }
@ -37,7 +37,7 @@ pure fn div_ceil(x: uint, y: uint) -> uint {
*
* The integer `q` closest to `x/y`.
*/
pure fn div_round(x: uint, y: uint) -> uint {
pub pure fn div_round(x: uint, y: uint) -> uint {
let div = x / y;
if x % y * 2u < y { div }
else { div + 1u }
@ -58,7 +58,7 @@ pure fn div_round(x: uint, y: uint) -> uint {
* The smallest integer `q` such that `x/y <= q`. This
* is either `x/y` or `x/y + 1`.
*/
pure fn div_floor(x: uint, y: uint) -> uint { return x / y; }
pub pure fn div_floor(x: uint, y: uint) -> uint { return x / y; }
/**
* Iterate over the range [`lo`..`hi`), or stop when requested
@ -75,7 +75,7 @@ pure fn div_floor(x: uint, y: uint) -> uint { return x / y; }
* `true` If execution proceeded correctly, `false` if it was interrupted,
* that is if `it` returned `false` at any point.
*/
pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
pub pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
let mut i = lo;
while i < hi {
if (!it(i)) { return false; }
@ -86,7 +86,7 @@ pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
/// Returns the smallest power of 2 greater than or equal to `n`
#[inline(always)]
fn next_power_of_two(n: uint) -> uint {
pub fn next_power_of_two(n: uint) -> uint {
let halfbits: uint = sys::size_of::<uint>() * 4u;
let mut tmp: uint = n - 1u;
let mut shift: uint = 1u;

View file

@ -3,9 +3,8 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
mod general_category {
#[legacy_exports];
pure fn Cc(c: char) -> bool {
pub mod general_category {
pub pure fn Cc(c: char) -> bool {
return match c {
'\x00' .. '\x1f'
| '\x7f' .. '\x9f' => true,
@ -13,7 +12,7 @@ mod general_category {
};
}
pure fn Cf(c: char) -> bool {
pub pure fn Cf(c: char) -> bool {
return match c {
'\xad'
| '\u0600' .. '\u0603'
@ -32,21 +31,21 @@ mod general_category {
};
}
pure fn Co(c: char) -> bool {
pub pure fn Co(c: char) -> bool {
return match c {
'\ue000' .. '\uf8ff' => true,
_ => false
};
}
pure fn Cs(c: char) -> bool {
pub pure fn Cs(c: char) -> bool {
return match c {
'\ud800' .. '\udfff' => true,
_ => false
};
}
pure fn Ll(c: char) -> bool {
pub pure fn Ll(c: char) -> bool {
return match c {
'\x61' .. '\x7a'
| '\xaa'
@ -651,7 +650,7 @@ mod general_category {
};
}
pure fn Lm(c: char) -> bool {
pub pure fn Lm(c: char) -> bool {
return match c {
'\u02b0' .. '\u02c1'
| '\u02c6' .. '\u02d1'
@ -707,7 +706,7 @@ mod general_category {
};
}
pure fn Lo(c: char) -> bool {
pub pure fn Lo(c: char) -> bool {
return match c {
'\u01bb'
| '\u01c0' .. '\u01c3'
@ -893,7 +892,7 @@ mod general_category {
};
}
pure fn Lt(c: char) -> bool {
pub pure fn Lt(c: char) -> bool {
return match c {
'\u01c5'
| '\u01c8'
@ -910,7 +909,7 @@ mod general_category {
};
}
pure fn Lu(c: char) -> bool {
pub pure fn Lu(c: char) -> bool {
return match c {
'\x41' .. '\x5a'
| '\xc0' .. '\xd6'
@ -1502,7 +1501,7 @@ mod general_category {
};
}
pure fn Mc(c: char) -> bool {
pub pure fn Mc(c: char) -> bool {
return match c {
'\u0903'
| '\u093b'
@ -1613,7 +1612,7 @@ mod general_category {
};
}
pure fn Me(c: char) -> bool {
pub pure fn Me(c: char) -> bool {
return match c {
'\u0488' .. '\u0489'
| '\u20dd' .. '\u20e0'
@ -1624,7 +1623,7 @@ mod general_category {
};
}
pure fn Mn(c: char) -> bool {
pub pure fn Mn(c: char) -> bool {
return match c {
'\u0300' .. '\u036f'
| '\u0483' .. '\u0487'
@ -1817,7 +1816,7 @@ mod general_category {
};
}
pure fn Nd(c: char) -> bool {
pub pure fn Nd(c: char) -> bool {
return match c {
'\x30' .. '\x39'
| '\u0660' .. '\u0669'
@ -1861,7 +1860,7 @@ mod general_category {
};
}
pure fn Nl(c: char) -> bool {
pub pure fn Nl(c: char) -> bool {
return match c {
'\u16ee' .. '\u16f0'
| '\u2160' .. '\u2182'
@ -1880,7 +1879,7 @@ mod general_category {
};
}
pure fn No(c: char) -> bool {
pub pure fn No(c: char) -> bool {
return match c {
'\xb2' .. '\xb3'
| '\xb9'
@ -1928,7 +1927,7 @@ mod general_category {
};
}
pure fn Pc(c: char) -> bool {
pub pure fn Pc(c: char) -> bool {
return match c {
'\x5f'
| '\u203f' .. '\u2040'
@ -1941,7 +1940,7 @@ mod general_category {
};
}
pure fn Pd(c: char) -> bool {
pub pure fn Pd(c: char) -> bool {
return match c {
'\x2d'
| '\u058a'
@ -1963,7 +1962,7 @@ mod general_category {
};
}
pure fn Pe(c: char) -> bool {
pub pure fn Pe(c: char) -> bool {
return match c {
'\x29'
| '\x5d'
@ -2040,7 +2039,7 @@ mod general_category {
};
}
pure fn Pf(c: char) -> bool {
pub pure fn Pf(c: char) -> bool {
return match c {
'\xbb'
| '\u2019'
@ -2057,7 +2056,7 @@ mod general_category {
};
}
pure fn Pi(c: char) -> bool {
pub pure fn Pi(c: char) -> bool {
return match c {
'\xab'
| '\u2018'
@ -2075,7 +2074,7 @@ mod general_category {
};
}
pure fn Po(c: char) -> bool {
pub pure fn Po(c: char) -> bool {
return match c {
'\x21' .. '\x23'
| '\x25' .. '\x27'
@ -2208,7 +2207,7 @@ mod general_category {
};
}
pure fn Ps(c: char) -> bool {
pub pure fn Ps(c: char) -> bool {
return match c {
'\x28'
| '\x5b'
@ -2287,7 +2286,7 @@ mod general_category {
};
}
pure fn Sc(c: char) -> bool {
pub pure fn Sc(c: char) -> bool {
return match c {
'\x24'
| '\xa2' .. '\xa5'
@ -2310,7 +2309,7 @@ mod general_category {
};
}
pure fn Sk(c: char) -> bool {
pub pure fn Sk(c: char) -> bool {
return match c {
'\x5e'
| '\x60'
@ -2344,7 +2343,7 @@ mod general_category {
};
}
pure fn Sm(c: char) -> bool {
pub pure fn Sm(c: char) -> bool {
return match c {
'\x2b'
| '\x3c' .. '\x3e'
@ -2415,7 +2414,7 @@ mod general_category {
};
}
pure fn So(c: char) -> bool {
pub pure fn So(c: char) -> bool {
return match c {
'\xa6' .. '\xa7'
| '\xa9'
@ -2534,21 +2533,21 @@ mod general_category {
};
}
pure fn Zl(c: char) -> bool {
pub pure fn Zl(c: char) -> bool {
return match c {
'\u2028' => true,
_ => false
};
}
pure fn Zp(c: char) -> bool {
pub pure fn Zp(c: char) -> bool {
return match c {
'\u2029' => true,
_ => false
};
}
pure fn Zs(c: char) -> bool {
pub pure fn Zs(c: char) -> bool {
return match c {
'\x20'
| '\xa0'
@ -2567,7 +2566,7 @@ mod general_category {
mod derived_property {
#[legacy_exports];
/// Check if a character has the alphabetic unicode property
pure fn Alphabetic(c: char) -> bool {
pub pure fn Alphabetic(c: char) -> bool {
return match c {
'\x41' .. '\x5a'
| '\x61' .. '\x7a'
@ -3305,7 +3304,7 @@ mod derived_property {
};
}
pure fn XID_Continue(c: char) -> bool {
pub pure fn XID_Continue(c: char) -> bool {
return match c {
'\x30' .. '\x39'
| '\x41' .. '\x5a'
@ -4176,7 +4175,7 @@ mod derived_property {
};
}
pure fn XID_Start(c: char) -> bool {
pub pure fn XID_Start(c: char) -> bool {
return match c {
'\x41' .. '\x5a'
| '\x61' .. '\x7a'

View file

@ -5,25 +5,25 @@ Miscellaneous helpers for common patterns.
*/
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
// tjc: re-forbid deprecated modes after snapshot
#[forbid(deprecated_pattern)];
use cmp::Eq;
/// The identity function.
#[inline(always)]
pure fn id<T>(+x: T) -> T { move x }
pub pure fn id<T>(x: T) -> T { move x }
/// Ignores a value.
#[inline(always)]
pure fn ignore<T>(+_x: T) { }
pub pure fn ignore<T>(_x: T) { }
/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
/// original value of `*ptr`.
#[inline(always)]
fn with<T: Copy, R>(
pub fn with<T: Copy, R>(
ptr: &mut T,
+new_value: T,
new_value: T,
op: &fn() -> R) -> R
{
// NDM: if swap operator were defined somewhat differently,
@ -41,7 +41,7 @@ fn with<T: Copy, R>(
* deinitialising or copying either one.
*/
#[inline(always)]
fn swap<T>(x: &mut T, y: &mut T) {
pub fn swap<T>(x: &mut T, y: &mut T) {
*x <-> *y;
}
@ -50,19 +50,19 @@ fn swap<T>(x: &mut T, y: &mut T) {
* value, without deinitialising or copying either one.
*/
#[inline(always)]
fn replace<T>(dest: &mut T, +src: T) -> T {
pub fn replace<T>(dest: &mut T, src: T) -> T {
let mut tmp <- src;
swap(dest, &mut tmp);
move tmp
}
/// A non-copyable dummy type.
struct NonCopyable {
pub struct NonCopyable {
i: (),
drop { }
}
fn NonCopyable() -> NonCopyable { NonCopyable { i: () } }
pub fn NonCopyable() -> NonCopyable { NonCopyable { i: () } }
/**
A utility function for indicating unreachable code. It will fail if
@ -88,7 +88,7 @@ fn choose_weighted_item(v: &[Item]) -> Item {
~~~
*/
fn unreachable() -> ! {
pub fn unreachable() -> ! {
fail ~"internal error: entered unreachable code";
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,5 @@
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// tjc: forbid deprecated modes again after snap
/**
* Concurrency-enabled mechanisms for sharing mutable and/or immutable state
* between tasks.
@ -12,14 +11,9 @@ use private::{SharedMutableState, shared_mutable_state,
use sync::{Mutex, mutex_with_condvars,
RWlock, rwlock_with_condvars};
export ARC, clone, get;
export Condvar;
export MutexARC, mutex_arc_with_condvars, unwrap_mutex_arc;
export RWARC, rw_arc_with_condvars, RWWriteMode, RWReadMode;
export unwrap_rw_arc;
/// As sync::condvar, a mechanism for unlock-and-descheduling and signalling.
struct Condvar { is_mutex: bool, failed: &mut bool, cond: &sync::Condvar }
pub struct Condvar { is_mutex: bool, failed: &mut bool, cond: &sync::Condvar }
impl &Condvar {
/// Atomically exit the associated ARC and block until a signal is sent.
@ -72,7 +66,7 @@ impl &Condvar {
struct ARC<T: Const Send> { x: SharedMutableState<T> }
/// Create an atomically reference counted wrapper.
fn ARC<T: Const Send>(+data: T) -> ARC<T> {
pub fn ARC<T: Const Send>(data: T) -> ARC<T> {
ARC { x: unsafe { shared_mutable_state(move data) } }
}
@ -80,7 +74,7 @@ fn ARC<T: Const Send>(+data: T) -> ARC<T> {
* Access the underlying data in an atomically reference counted
* wrapper.
*/
fn get<T: Const Send>(rc: &a/ARC<T>) -> &a/T {
pub fn get<T: Const Send>(rc: &a/ARC<T>) -> &a/T {
unsafe { get_shared_immutable_state(&rc.x) }
}
@ -91,7 +85,7 @@ fn get<T: Const Send>(rc: &a/ARC<T>) -> &a/T {
* object. However, one of the `arc` objects can be sent to another task,
* allowing them to share the underlying data.
*/
fn clone<T: Const Send>(rc: &ARC<T>) -> ARC<T> {
pub fn clone<T: Const Send>(rc: &ARC<T>) -> ARC<T> {
ARC { x: unsafe { clone_shared_mutable_state(&rc.x) } }
}
@ -104,7 +98,7 @@ fn clone<T: Const Send>(rc: &ARC<T>) -> ARC<T> {
* unwrap from a task that holds another reference to the same ARC; it is
* guaranteed to deadlock.
*/
fn unwrap<T: Const Send>(+rc: ARC<T>) -> T {
fn unwrap<T: Const Send>(rc: ARC<T>) -> T {
let ARC { x: x } <- rc;
unsafe { unwrap_shared_mutable_state(move x) }
}
@ -119,14 +113,14 @@ struct MutexARCInner<T: Send> { lock: Mutex, failed: bool, data: T }
struct MutexARC<T: Send> { x: SharedMutableState<MutexARCInner<T>> }
/// Create a mutex-protected ARC with the supplied data.
fn MutexARC<T: Send>(+user_data: T) -> MutexARC<T> {
pub fn MutexARC<T: Send>(user_data: T) -> MutexARC<T> {
mutex_arc_with_condvars(move user_data, 1)
}
/**
* Create a mutex-protected ARC with the supplied data and a specified number
* of condvars (as sync::mutex_with_condvars).
*/
fn mutex_arc_with_condvars<T: Send>(+user_data: T,
pub fn mutex_arc_with_condvars<T: Send>(user_data: T,
num_condvars: uint) -> MutexARC<T> {
let data =
MutexARCInner { lock: mutex_with_condvars(num_condvars),
@ -197,7 +191,7 @@ impl<T: Send> &MutexARC<T> {
* Will additionally fail if another task has failed while accessing the arc.
*/
// FIXME(#2585) make this a by-move method on the arc
fn unwrap_mutex_arc<T: Send>(+arc: MutexARC<T>) -> T {
pub fn unwrap_mutex_arc<T: Send>(arc: MutexARC<T>) -> T {
let MutexARC { x: x } <- arc;
let inner = unsafe { unwrap_shared_mutable_state(move x) };
let MutexARCInner { failed: failed, data: data, _ } <- inner;
@ -253,14 +247,14 @@ struct RWARC<T: Const Send> {
}
/// Create a reader/writer ARC with the supplied data.
fn RWARC<T: Const Send>(+user_data: T) -> RWARC<T> {
pub fn RWARC<T: Const Send>(user_data: T) -> RWARC<T> {
rw_arc_with_condvars(move user_data, 1)
}
/**
* Create a reader/writer ARC with the supplied data and a specified number
* of condvars (as sync::rwlock_with_condvars).
*/
fn rw_arc_with_condvars<T: Const Send>(+user_data: T,
pub fn rw_arc_with_condvars<T: Const Send>(user_data: T,
num_condvars: uint) -> RWARC<T> {
let data =
RWARCInner { lock: rwlock_with_condvars(num_condvars),
@ -340,7 +334,7 @@ impl<T: Const Send> &RWARC<T> {
* }
* ~~~
*/
fn write_downgrade<U>(blk: fn(+v: RWWriteMode<T>) -> U) -> U {
fn write_downgrade<U>(blk: fn(v: RWWriteMode<T>) -> U) -> U {
let state = unsafe { get_shared_mutable_state(&self.x) };
do borrow_rwlock(state).write_downgrade |write_mode| {
check_poison(false, state.failed);
@ -350,7 +344,7 @@ impl<T: Const Send> &RWARC<T> {
}
/// To be called inside of the write_downgrade block.
fn downgrade(+token: RWWriteMode/&a<T>) -> RWReadMode/&a<T> {
fn downgrade(token: RWWriteMode/&a<T>) -> RWReadMode/&a<T> {
// The rwlock should assert that the token belongs to us for us.
let state = unsafe { get_shared_immutable_state(&self.x) };
let RWWriteMode((data, t, _poison)) <- token;
@ -375,7 +369,7 @@ impl<T: Const Send> &RWARC<T> {
* in write mode.
*/
// FIXME(#2585) make this a by-move method on the arc
fn unwrap_rw_arc<T: Const Send>(+arc: RWARC<T>) -> T {
pub fn unwrap_rw_arc<T: Const Send>(arc: RWARC<T>) -> T {
let RWARC { x: x, _ } <- arc;
let inner = unsafe { unwrap_shared_mutable_state(move x) };
let RWARCInner { failed: failed, data: data, _ } <- inner;
@ -396,10 +390,10 @@ fn borrow_rwlock<T: Const Send>(state: &r/mut RWARCInner<T>) -> &r/RWlock {
// FIXME (#3154) ice with struct/&<T> prevents these from being structs.
/// The "write permission" token used for RWARC.write_downgrade().
enum RWWriteMode<T: Const Send> =
pub enum RWWriteMode<T: Const Send> =
(&mut T, sync::RWlockWriteMode, PoisonOnFail);
/// The "read permission" token used for RWARC.write_downgrade().
enum RWReadMode<T:Const Send> = (&T, sync::RWlockReadMode);
pub enum RWReadMode<T:Const Send> = (&T, sync::RWlockReadMode);
impl<T: Const Send> &RWWriteMode<T> {
/// Access the pre-downgrade RWARC in write mode.
@ -648,7 +642,7 @@ mod tests {
let mut children = ~[];
for 5.times {
let arc3 = ~arc.clone();
do task::task().future_result(|+r| vec::push(children, r)).spawn {
do task::task().future_result(|+r| children.push(r)).spawn {
do arc3.read |num| {
assert *num >= 0;
}
@ -676,7 +670,7 @@ mod tests {
let mut reader_convos = ~[];
for 10.times {
let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream());
vec::push(reader_convos, (rc1,rp2));
reader_convos.push((rc1,rp2));
let arcn = ~arc.clone();
do task::spawn {
rp1.recv(); // wait for downgrader to give go-ahead
@ -719,7 +713,7 @@ mod tests {
// send to other readers
for vec::each(reader_convos) |x| {
match *x {
(rc, _) => rc.send(()),
(ref rc, _) => rc.send(()),
}
}
}
@ -728,7 +722,7 @@ mod tests {
// complete handshake with other readers
for vec::each(reader_convos) |x| {
match *x {
(_, rp) => rp.recv(),
(_, ref rp) => rp.recv(),
}
}
wc1.send(()); // tell writer to try again

View file

@ -23,9 +23,6 @@
// to waste time running the destructors of POD.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
export Arena, arena_with_size;
use list::{List, Cons, Nil};
use cast::reinterpret_cast;
@ -34,12 +31,10 @@ use libc::size_t;
#[abi = "rust-intrinsic"]
extern mod rusti {
#[legacy_exports];
fn move_val_init<T>(&dst: T, -src: T);
fn needs_drop<T>() -> bool;
}
extern mod rustrt {
#[legacy_exports];
#[rust_stack]
fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
}
@ -52,7 +47,7 @@ const tydesc_drop_glue_index: size_t = 3 as size_t;
// will always stay at 0.
type Chunk = {data: @[u8], mut fill: uint, is_pod: bool};
struct Arena {
pub struct Arena {
// The head is seperated out from the list as a unbenchmarked
// microoptimization, to avoid needing to case on the list to
// access the head.
@ -63,25 +58,25 @@ struct Arena {
unsafe {
destroy_chunk(&self.head);
for list::each(self.chunks) |chunk| {
if !chunk.is_pod { destroy_chunk(&chunk); }
if !chunk.is_pod { destroy_chunk(chunk); }
}
}
}
}
fn chunk(size: uint, is_pod: bool) -> Chunk {
let mut v = @[];
unsafe { at_vec::raw::reserve(v, size); }
{ data: v, mut fill: 0u, is_pod: is_pod }
let mut v: @[const u8] = @[];
unsafe { at_vec::raw::reserve(&mut v, size); }
{ data: unsafe { cast::transmute(v) }, mut fill: 0u, is_pod: is_pod }
}
fn arena_with_size(initial_size: uint) -> Arena {
pub fn arena_with_size(initial_size: uint) -> Arena {
return Arena {mut head: chunk(initial_size, false),
mut pod_head: chunk(initial_size, true),
mut chunks: @Nil};
}
fn Arena() -> Arena {
pub fn Arena() -> Arena {
arena_with_size(32u)
}

View file

@ -1,8 +1,7 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use io::Reader;
trait ToBase64 {
pub trait ToBase64 {
fn to_base64() -> ~str;
}
@ -63,7 +62,7 @@ impl &str: ToBase64 {
}
}
trait FromBase64 {
pub trait FromBase64 {
fn from_base64() -> ~[u8];
}
@ -102,12 +101,12 @@ impl ~[u8]: FromBase64 {
} else if ch == '=' {
match len - i {
1u => {
vec::push(r, ((n >> 16u) & 0xFFu) as u8);
vec::push(r, ((n >> 8u ) & 0xFFu) as u8);
r.push(((n >> 16u) & 0xFFu) as u8);
r.push(((n >> 8u ) & 0xFFu) as u8);
return copy r;
}
2u => {
vec::push(r, ((n >> 10u) & 0xFFu) as u8);
r.push(((n >> 10u) & 0xFFu) as u8);
return copy r;
}
_ => fail ~"invalid base64 padding"
@ -119,9 +118,9 @@ impl ~[u8]: FromBase64 {
i += 1u;
};
vec::push(r, ((n >> 16u) & 0xFFu) as u8);
vec::push(r, ((n >> 8u ) & 0xFFu) as u8);
vec::push(r, ((n ) & 0xFFu) as u8);
r.push(((n >> 16u) & 0xFFu) as u8);
r.push(((n >> 8u ) & 0xFFu) as u8);
r.push(((n ) & 0xFFu) as u8);
}
r

View file

@ -1,10 +1,7 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// tjc: forbid deprecated modes again after snap
use vec::{to_mut, from_elem};
export Bitv, from_bytes, from_bools, from_fn;
struct SmallBitv {
/// only the lowest nbits of this value are used. the rest is undefined.
mut bits: u32
@ -98,7 +95,7 @@ struct BigBitv {
mut storage: ~[mut uint]
}
fn BigBitv(+storage: ~[mut uint]) -> BigBitv {
fn BigBitv(storage: ~[mut uint]) -> BigBitv {
BigBitv {storage: storage}
}
@ -140,17 +137,17 @@ impl BigBitv {
}
#[inline(always)]
fn each_storage(op: fn(&v: uint) -> bool) {
fn each_storage(op: fn(v: &mut uint) -> bool) {
for uint::range(0, self.storage.len()) |i| {
let mut w = self.storage[i];
let b = !op(w);
let b = !op(&mut w);
self.storage[i] = w;
if !b { break; }
}
}
#[inline(always)]
fn invert() { for self.each_storage() |w| { w = !w } }
fn invert() { for self.each_storage() |w| { *w = !*w } }
#[inline(always)]
fn union(b: &BigBitv, nbits: uint) -> bool {
@ -210,12 +207,12 @@ enum BitvVariant { Big(~BigBitv), Small(~SmallBitv) }
enum Op {Union, Intersect, Assign, Difference}
// The bitvector type
struct Bitv {
pub struct Bitv {
rep: BitvVariant,
nbits: uint
}
fn Bitv (nbits: uint, init: bool) -> Bitv {
pub fn Bitv (nbits: uint, init: bool) -> Bitv {
let rep = if nbits <= 32 {
Small(~SmallBitv(if init {!0} else {0}))
}
@ -241,22 +238,22 @@ priv impl Bitv {
self.die();
}
match self.rep {
Small(s) => match other.rep {
Small(s1) => match op {
Union => s.union(s1, self.nbits),
Intersect => s.intersect(s1, self.nbits),
Assign => s.become(s1, self.nbits),
Difference => s.difference(s1, self.nbits)
Small(ref s) => match other.rep {
Small(ref s1) => match op {
Union => s.union(*s1, self.nbits),
Intersect => s.intersect(*s1, self.nbits),
Assign => s.become(*s1, self.nbits),
Difference => s.difference(*s1, self.nbits)
},
Big(_) => self.die()
},
Big(s) => match other.rep {
Big(ref s) => match other.rep {
Small(_) => self.die(),
Big(s1) => match op {
Union => s.union(s1, self.nbits),
Intersect => s.intersect(s1, self.nbits),
Assign => s.become(s1, self.nbits),
Difference => s.difference(s1, self.nbits)
Big(ref s1) => match op {
Union => s.union(*s1, self.nbits),
Intersect => s.intersect(*s1, self.nbits),
Assign => s.become(*s1, self.nbits),
Difference => s.difference(*s1, self.nbits)
}
}
}
@ -297,10 +294,10 @@ impl Bitv {
#[inline(always)]
fn clone() -> ~Bitv {
~match self.rep {
Small(b) => {
Small(ref b) => {
Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})}
}
Big(b) => {
Big(ref b) => {
let st = to_mut(from_elem(self.nbits / uint_bits + 1, 0));
let len = st.len();
for uint::range(0, len) |i| { st[i] = b.storage[i]; };
@ -314,8 +311,8 @@ impl Bitv {
pure fn get(i: uint) -> bool {
assert (i < self.nbits);
match self.rep {
Big(b) => b.get(i),
Small(s) => s.get(i)
Big(ref b) => b.get(i),
Small(ref s) => s.get(i)
}
}
@ -328,8 +325,8 @@ impl Bitv {
fn set(i: uint, x: bool) {
assert (i < self.nbits);
match self.rep {
Big(b) => b.set(i, x),
Small(s) => s.set(i, x)
Big(ref b) => b.set(i, x),
Small(ref s) => s.set(i, x)
}
}
@ -340,15 +337,15 @@ impl Bitv {
* bitvectors contain identical elements.
*/
#[inline(always)]
fn equal(v1: Bitv) -> bool {
fn equal(v1: &Bitv) -> bool {
if self.nbits != v1.nbits { return false; }
match self.rep {
Small(b) => match v1.rep {
Small(b1) => b.equals(b1, self.nbits),
Small(ref b) => match v1.rep {
Small(ref b1) => b.equals(*b1, self.nbits),
_ => false
},
Big(s) => match v1.rep {
Big(s1) => s.equals(s1, self.nbits),
Big(ref s) => match v1.rep {
Big(ref s1) => s.equals(*s1, self.nbits),
Small(_) => return false
}
}
@ -358,8 +355,8 @@ impl Bitv {
#[inline(always)]
fn clear() {
match self.rep {
Small(b) => b.clear(),
Big(s) => for s.each_storage() |w| { w = 0u }
Small(ref b) => b.clear(),
Big(ref s) => for s.each_storage() |w| { *w = 0u }
}
}
@ -367,16 +364,16 @@ impl Bitv {
#[inline(always)]
fn set_all() {
match self.rep {
Small(b) => b.set_all(),
Big(s) => for s.each_storage() |w| { w = !0u } }
Small(ref b) => b.set_all(),
Big(ref s) => for s.each_storage() |w| { *w = !0u } }
}
/// Invert all bits
#[inline(always)]
fn invert() {
match self.rep {
Small(b) => b.invert(),
Big(s) => for s.each_storage() |w| { w = !w } }
Small(ref b) => b.invert(),
Big(ref s) => for s.each_storage() |w| { *w = !*w } }
}
/**
@ -389,13 +386,13 @@ impl Bitv {
* Returns `true` if `v0` was changed.
*/
#[inline(always)]
fn difference(v: ~Bitv) -> bool { self.do_op(Difference, v) }
fn difference(v: &Bitv) -> bool { self.do_op(Difference, v) }
/// Returns true if all bits are 1
#[inline(always)]
fn is_true() -> bool {
match self.rep {
Small(b) => b.is_true(self.nbits),
Small(ref b) => b.is_true(self.nbits),
_ => {
for self.each() |i| { if !i { return false; } }
true
@ -415,7 +412,7 @@ impl Bitv {
/// Returns true if all bits are 0
fn is_false() -> bool {
match self.rep {
Small(b) => b.is_false(self.nbits),
Small(ref b) => b.is_false(self.nbits),
Big(_) => {
for self.each() |i| { if i { return false; } }
true
@ -520,7 +517,7 @@ impl Bitv {
* with the most significant bits of each byte coming first. Each
* bit becomes true if equal to 1 or false if equal to 0.
*/
fn from_bytes(bytes: &[u8]) -> Bitv {
pub fn from_bytes(bytes: &[u8]) -> Bitv {
from_fn(bytes.len() * 8, |i| {
let b = bytes[i / 8] as uint;
let offset = i % 8;
@ -531,7 +528,7 @@ fn from_bytes(bytes: &[u8]) -> Bitv {
/**
* Transform a [bool] into a bitv by converting each bool into a bit.
*/
fn from_bools(bools: &[bool]) -> Bitv {
pub fn from_bools(bools: &[bool]) -> Bitv {
from_fn(bools.len(), |i| bools[i])
}
@ -539,7 +536,7 @@ fn from_bools(bools: &[bool]) -> Bitv {
* Create a bitv of the specified length where the value at each
* index is f(index).
*/
fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv {
pub fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv {
let bitv = Bitv(len, false);
for uint::range(0, len) |i| {
bitv.set(i, f(i));
@ -556,7 +553,7 @@ pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; }
pure fn right(_w0: uint, w1: uint) -> uint { return w1; }
impl Bitv: ops::Index<uint,bool> {
pure fn index(&&i: uint) -> bool {
pure fn index(+i: uint) -> bool {
self.get(i)
}
}
@ -866,14 +863,14 @@ mod tests {
fn test_equal_differing_sizes() {
let v0 = Bitv(10u, false);
let v1 = Bitv(11u, false);
assert !v0.equal(v1);
assert !v0.equal(&v1);
}
#[test]
fn test_equal_greatly_differing_sizes() {
let v0 = Bitv(10u, false);
let v1 = Bitv(110u, false);
assert !v0.equal(v1);
assert !v0.equal(&v1);
}
#[test]
@ -884,7 +881,7 @@ mod tests {
let b = bitv::Bitv(1, true);
b.set(0, true);
assert a.equal(b);
assert a.equal(&b);
}
#[test]
@ -899,7 +896,7 @@ mod tests {
b.set(i, true);
}
assert a.equal(b);
assert a.equal(&b);
}
#[test]

View file

@ -26,19 +26,13 @@
* still held if needed.
*/
export CVec;
export CVec, c_vec_with_dtor;
export get, set;
export len;
export ptr;
/**
* The type representing a foreign chunk of memory
*
* Wrapped in a enum for opacity; FIXME #818 when it is possible to have
* truly opaque types, this should be revisited.
*/
enum CVec<T> {
pub enum CVec<T> {
CVecCtor({ base: *mut T, len: uint, rsrc: @DtorRes})
}
@ -70,7 +64,7 @@ fn DtorRes(dtor: Option<fn@()>) -> DtorRes {
* * base - A foreign pointer to a buffer
* * len - The number of elements in the buffer
*/
unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
return CVecCtor({
base: base,
len: len,
@ -89,7 +83,7 @@ unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
* * dtor - A function to run when the value is destructed, useful
* for freeing the buffer, etc.
*/
unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: fn@())
pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: fn@())
-> CVec<T> {
return CVecCtor({
base: base,
@ -107,7 +101,7 @@ unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: fn@())
*
* Fails if `ofs` is greater or equal to the length of the vector
*/
fn get<T: Copy>(t: CVec<T>, ofs: uint) -> T {
pub fn get<T: Copy>(t: CVec<T>, ofs: uint) -> T {
assert ofs < len(t);
return unsafe { *ptr::mut_offset((*t).base, ofs) };
}
@ -117,7 +111,7 @@ fn get<T: Copy>(t: CVec<T>, ofs: uint) -> T {
*
* Fails if `ofs` is greater or equal to the length of the vector
*/
fn set<T: Copy>(t: CVec<T>, ofs: uint, v: T) {
pub fn set<T: Copy>(t: CVec<T>, ofs: uint, +v: T) {
assert ofs < len(t);
unsafe { *ptr::mut_offset((*t).base, ofs) = v };
}
@ -127,18 +121,17 @@ fn set<T: Copy>(t: CVec<T>, ofs: uint, v: T) {
*/
/// Returns the length of the vector
fn len<T>(t: CVec<T>) -> uint {
pub fn len<T>(t: CVec<T>) -> uint {
return (*t).len;
}
/// Returns a pointer to the first element of the vector
unsafe fn ptr<T>(t: CVec<T>) -> *mut T {
pub unsafe fn ptr<T>(t: CVec<T>) -> *mut T {
return (*t).base;
}
#[cfg(test)]
mod tests {
#[legacy_exports];
use libc::*;
fn malloc(n: size_t) -> CVec<u8> {

View file

@ -1,19 +1,18 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// tjc: forbid deprecated modes again after snap
/// A dynamic, mutable location.
///
/// Similar to a mutable option type, but friendlier.
struct Cell<T> {
pub struct Cell<T> {
mut value: Option<T>
}
/// Creates a new full cell with the given value.
fn Cell<T>(+value: T) -> Cell<T> {
pub fn Cell<T>(value: T) -> Cell<T> {
Cell { value: Some(move value) }
}
fn empty_cell<T>() -> Cell<T> {
pub fn empty_cell<T>() -> Cell<T> {
Cell { value: None }
}
@ -30,7 +29,7 @@ impl<T> Cell<T> {
}
/// Returns the value, failing if the cell is full.
fn put_back(+value: T) {
fn put_back(value: T) {
if !self.is_empty() {
fail ~"attempt to put a value back into a full cell";
}

View file

@ -1,10 +1,9 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
/// Additional general-purpose comparison functionality.
const fuzzy_epsilon: float = 1.0e-6;
trait FuzzyEq {
pub trait FuzzyEq {
pure fn fuzzy_eq(other: &self) -> bool;
}

View file

@ -6,14 +6,11 @@ Higher level communication abstractions.
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use pipes::{Channel, Recv, Chan, Port, Selectable};
export DuplexStream;
/// An extension of `pipes::stream` that allows both sending and receiving.
struct DuplexStream<T: Send, U: Send> {
pub struct DuplexStream<T: Send, U: Send> {
priv chan: Chan<T>,
priv port: Port <U>,
}
@ -49,7 +46,7 @@ impl<T: Send, U: Send> DuplexStream<T, U> : Selectable {
}
/// Creates a bidirectional stream.
fn DuplexStream<T: Send, U: Send>()
pub fn DuplexStream<T: Send, U: Send>()
-> (DuplexStream<T, U>, DuplexStream<U, T>)
{
let (c2, p1) = pipes::stream();

View file

@ -1,16 +1,8 @@
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// tjc: forbid deprecated modes again after snap
//! Unsafe debugging functions for inspecting values.
use cast::reinterpret_cast;
export debug_tydesc;
export debug_opaque;
export debug_box;
export debug_tag;
export debug_fn;
export ptr_cast;
export breakpoint;
#[abi = "cdecl"]
extern mod rustrt {
@ -24,34 +16,34 @@ extern mod rustrt {
fn rust_dbg_breakpoint();
}
fn debug_tydesc<T>() {
pub fn debug_tydesc<T>() {
rustrt::debug_tydesc(sys::get_type_desc::<T>());
}
fn debug_opaque<T>(+x: T) {
rustrt::debug_opaque(sys::get_type_desc::<T>(), ptr::addr_of(x) as *());
pub fn debug_opaque<T>(x: T) {
rustrt::debug_opaque(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
}
fn debug_box<T>(x: @T) {
rustrt::debug_box(sys::get_type_desc::<T>(), ptr::addr_of(x) as *());
pub fn debug_box<T>(x: @T) {
rustrt::debug_box(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
}
fn debug_tag<T>(+x: T) {
rustrt::debug_tag(sys::get_type_desc::<T>(), ptr::addr_of(x) as *());
pub fn debug_tag<T>(x: T) {
rustrt::debug_tag(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
}
fn debug_fn<T>(+x: T) {
rustrt::debug_fn(sys::get_type_desc::<T>(), ptr::addr_of(x) as *());
pub fn debug_fn<T>(x: T) {
rustrt::debug_fn(sys::get_type_desc::<T>(), ptr::addr_of(&x) as *());
}
unsafe fn ptr_cast<T, U>(x: @T) -> @U {
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
reinterpret_cast(
&rustrt::debug_ptrcast(sys::get_type_desc::<T>(),
reinterpret_cast(&x)))
}
/// Triggers a debugger breakpoint
fn breakpoint() {
pub fn breakpoint() {
rustrt::rust_dbg_breakpoint();
}

View file

@ -1,16 +1,15 @@
//! A deque. Untested as of yet. Likely buggy
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
// tjc: forbid deprecated modes again after snap
#[forbid(non_camel_case_types)];
use option::{Some, None};
use dvec::DVec;
use core::cmp::{Eq};
trait Deque<T> {
pub trait Deque<T> {
fn size() -> uint;
fn add_front(T);
fn add_back(T);
fn add_front(v: T);
fn add_back(v: T);
fn pop_front() -> T;
fn pop_back() -> T;
fn peek_front() -> T;
@ -20,7 +19,7 @@ trait Deque<T> {
// FIXME (#2343) eventually, a proper datatype plus an exported impl would
// be preferrable.
fn create<T: Copy>() -> Deque<T> {
pub fn create<T: Copy>() -> Deque<T> {
type Cell<T> = Option<T>;
let initial_capacity: uint = 32u; // 2^5
@ -28,7 +27,7 @@ fn create<T: Copy>() -> Deque<T> {
* Grow is only called on full elts, so nelts is also len(elts), unlike
* elsewhere.
*/
fn grow<T: Copy>(nelts: uint, lo: uint, +elts: ~[Cell<T>])
fn grow<T: Copy>(nelts: uint, lo: uint, elts: ~[Cell<T>])
-> ~[Cell<T>] {
let mut elts = move elts;
assert (nelts == vec::len(elts));
@ -38,15 +37,15 @@ fn create<T: Copy>() -> Deque<T> {
let nalloc = uint::next_power_of_two(nelts + 1u);
while i < nalloc {
if i < nelts {
vec::push(rv, elts[(lo + i) % nelts]);
} else { vec::push(rv, None); }
rv.push(elts[(lo + i) % nelts]);
} else { rv.push(None); }
i += 1u;
}
move rv
}
fn get<T: Copy>(elts: &DVec<Cell<T>>, i: uint) -> T {
match (*elts).get_elt(i) { Some(t) => t, _ => fail }
match (*elts).get_elt(i) { Some(move t) => t, _ => fail }
}
type Repr<T> = {mut nelts: uint,
@ -120,7 +119,6 @@ fn create<T: Copy>() -> Deque<T> {
#[cfg(test)]
mod tests {
#[legacy_exports];
#[test]
fn test_simple() {
let d: deque::Deque<int> = deque::create::<int>();
@ -202,7 +200,7 @@ mod tests {
assert (deq.get(3) == d);
}
fn test_parameterized<T: Copy Eq Owned>(+a: T, +b: T, +c: T, +d: T) {
fn test_parameterized<T: Copy Eq Owned>(a: T, +b: T, +c: T, +d: T) {
let deq: deque::Deque<T> = deque::create::<T>();
assert (deq.size() == 0u);
deq.add_front(a);

View file

@ -4,31 +4,6 @@
use core::Option;
use option::{Some, None};
export Doc;
export doc_at;
export maybe_get_doc;
export get_doc;
export docs;
export tagged_docs;
export doc_data;
export doc_as_str;
export doc_as_u8;
export doc_as_u16;
export doc_as_u32;
export doc_as_u64;
export doc_as_i8;
export doc_as_i16;
export doc_as_i32;
export doc_as_i64;
export Writer;
export serializer;
export ebml_deserializer;
export EbmlDeserializer;
export deserializer;
export with_doc_data;
export get_doc;
export extensions;
type EbmlTag = {id: uint, size: uint};
type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint};
@ -37,12 +12,12 @@ type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint};
// separate modules within this file.
// ebml reading
type Doc = {data: @~[u8], start: uint, end: uint};
pub type Doc = {data: @~[u8], start: uint, end: uint};
type TaggedDoc = {tag: uint, doc: Doc};
impl Doc: ops::Index<uint,Doc> {
pure fn index(&&tag: uint) -> Doc {
pure fn index(+tag: uint) -> Doc {
unsafe {
get_doc(self, tag)
}
@ -72,11 +47,11 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
} else { error!("vint too big"); fail; }
}
fn Doc(data: @~[u8]) -> Doc {
pub fn Doc(data: @~[u8]) -> Doc {
return {data: data, start: 0u, end: vec::len::<u8>(*data)};
}
fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
let elt_tag = vuint_at(*data, start);
let elt_size = vuint_at(*data, elt_tag.next);
let end = elt_size.next + elt_size.val;
@ -84,7 +59,7 @@ fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
doc: {data: data, start: elt_size.next, end: end}};
}
fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
@ -101,7 +76,7 @@ fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
return None::<Doc>;
}
fn get_doc(d: Doc, tg: uint) -> Doc {
pub fn get_doc(d: Doc, tg: uint) -> Doc {
match maybe_get_doc(d, tg) {
Some(d) => return d,
None => {
@ -111,7 +86,7 @@ fn get_doc(d: Doc, tg: uint) -> Doc {
}
}
fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
@ -123,7 +98,7 @@ fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
}
}
fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
@ -137,43 +112,43 @@ fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
}
}
fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
return f(vec::view(*d.data, d.start, d.end));
}
fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); }
pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); }
fn doc_as_u8(d: Doc) -> u8 {
pub fn doc_as_u8(d: Doc) -> u8 {
assert d.end == d.start + 1u;
return (*d.data)[d.start];
}
fn doc_as_u16(d: Doc) -> u16 {
pub fn doc_as_u16(d: Doc) -> u16 {
assert d.end == d.start + 2u;
return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16;
}
fn doc_as_u32(d: Doc) -> u32 {
pub fn doc_as_u32(d: Doc) -> u32 {
assert d.end == d.start + 4u;
return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32;
}
fn doc_as_u64(d: Doc) -> u64 {
pub fn doc_as_u64(d: Doc) -> u64 {
assert d.end == d.start + 8u;
return io::u64_from_be_bytes(*d.data, d.start, 8u);
}
fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
// ebml writing
type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]};
enum Writer {
pub enum Writer {
Writer_(Writer_)
}
@ -197,7 +172,7 @@ fn write_vuint(w: io::Writer, n: uint) {
fail fmt!("vint to write too big: %?", n);
}
fn Writer(w: io::Writer) -> Writer {
pub fn Writer(w: io::Writer) -> Writer {
let size_positions: ~[uint] = ~[];
return Writer_({writer: w, mut size_positions: size_positions});
}
@ -211,13 +186,13 @@ impl Writer {
write_vuint(self.writer, tag_id);
// Write a placeholder four-byte size.
vec::push(self.size_positions, self.writer.tell());
self.size_positions.push(self.writer.tell());
let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
self.writer.write(zeroes);
}
fn end_tag() {
let last_size_pos = vec::pop::<uint>(self.size_positions);
let last_size_pos = self.size_positions.pop();
let cur_pos = self.writer.tell();
self.writer.seek(last_size_pos as int, io::SeekSet);
let size = (cur_pos - last_size_pos - 4u);
@ -292,7 +267,7 @@ impl Writer {
self.writer.write(b);
}
fn wr_str(s: ~str) {
fn wr_str(s: &str) {
debug!("Write str: %?", s);
self.writer.write(str::to_bytes(s));
}
@ -409,16 +384,16 @@ impl ebml::Writer: serialization::Serializer {
type EbmlDeserializer_ = {mut parent: ebml::Doc,
mut pos: uint};
enum EbmlDeserializer {
pub enum EbmlDeserializer {
EbmlDeserializer_(EbmlDeserializer_)
}
fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer {
pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer {
EbmlDeserializer_({mut parent: d, mut pos: d.start})
}
priv impl EbmlDeserializer {
fn _check_label(lbl: ~str) {
fn _check_label(lbl: &str) {
if self.pos < self.parent.end {
let {tag: r_tag, doc: r_doc} =
ebml::doc_at(self.parent.data, self.pos);
@ -516,7 +491,7 @@ impl EbmlDeserializer: serialization::Deserializer {
fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) }
// Compound types:
fn read_enum<T>(name: ~str, f: fn() -> T) -> T {
fn read_enum<T>(name: &str, f: fn() -> T) -> T {
debug!("read_enum(%s)", name);
self._check_label(name);
self.push_doc(self.next_doc(EsEnum), f)
@ -565,7 +540,7 @@ impl EbmlDeserializer: serialization::Deserializer {
f()
}
fn read_rec_field<T>(f_name: ~str, f_idx: uint, f: fn() -> T) -> T {
fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T {
debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
self._check_label(f_name);
f()
@ -588,11 +563,11 @@ impl EbmlDeserializer: serialization::Deserializer {
#[test]
fn test_option_int() {
fn serialize_1<S: serialization::Serializer>(s: S, v: int) {
fn serialize_1<S: serialization::Serializer>(&&s: S, v: int) {
s.emit_i64(v as i64);
}
fn serialize_0<S: serialization::Serializer>(s: S, v: Option<int>) {
fn serialize_0<S: serialization::Serializer>(&&s: S, v: Option<int>) {
do s.emit_enum(~"core::option::t") {
match v {
None => s.emit_enum_variant(
@ -606,11 +581,11 @@ fn test_option_int() {
}
}
fn deserialize_1<S: serialization::Deserializer>(s: S) -> int {
fn deserialize_1<S: serialization::Deserializer>(&&s: S) -> int {
s.read_i64() as int
}
fn deserialize_0<S: serialization::Deserializer>(s: S) -> Option<int> {
fn deserialize_0<S: serialization::Deserializer>(&&s: S) -> Option<int> {
do s.read_enum(~"core::option::t") {
do s.read_enum_variant |i| {
match i {

643
src/libstd/ebml2.rs Normal file
View file

@ -0,0 +1,643 @@
use serialization2;
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
// cursor model. See the specification here:
// http://www.matroska.org/technical/specs/rfc/index.html
struct EbmlTag {
id: uint,
size: uint,
}
struct EbmlState {
ebml_tag: EbmlTag,
tag_pos: uint,
data_pos: uint,
}
// FIXME (#2739): When we have module renaming, make "reader" and "writer"
// separate modules within this file.
// ebml reading
struct Doc {
data: @~[u8],
start: uint,
end: uint,
}
struct TaggedDoc {
tag: uint,
doc: Doc,
}
impl Doc: ops::Index<uint,Doc> {
pure fn index(+tag: uint) -> Doc {
unsafe {
get_doc(self, tag)
}
}
}
fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
let a = data[start];
if a & 0x80u8 != 0u8 {
return {val: (a & 0x7fu8) as uint, next: start + 1u};
}
if a & 0x40u8 != 0u8 {
return {val: ((a & 0x3fu8) as uint) << 8u |
(data[start + 1u] as uint),
next: start + 2u};
} else if a & 0x20u8 != 0u8 {
return {val: ((a & 0x1fu8) as uint) << 16u |
(data[start + 1u] as uint) << 8u |
(data[start + 2u] as uint),
next: start + 3u};
} else if a & 0x10u8 != 0u8 {
return {val: ((a & 0x0fu8) as uint) << 24u |
(data[start + 1u] as uint) << 16u |
(data[start + 2u] as uint) << 8u |
(data[start + 3u] as uint),
next: start + 4u};
} else { error!("vint too big"); fail; }
}
pub fn Doc(data: @~[u8]) -> Doc {
Doc { data: data, start: 0u, end: vec::len::<u8>(*data) }
}
pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
let elt_tag = vuint_at(*data, start);
let elt_size = vuint_at(*data, elt_tag.next);
let end = elt_size.next + elt_size.val;
TaggedDoc {
tag: elt_tag.val,
doc: Doc { data: data, start: elt_size.next, end: end }
}
}
pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
let elt_size = vuint_at(*d.data, elt_tag.next);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
return Some(Doc { data: d.data, start: elt_size.next, end: pos });
}
}
None
}
pub fn get_doc(d: Doc, tg: uint) -> Doc {
match maybe_get_doc(d, tg) {
Some(d) => d,
None => {
error!("failed to find block with tag %u", tg);
fail;
}
}
}
pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
let elt_size = vuint_at(*d.data, elt_tag.next);
pos = elt_size.next + elt_size.val;
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(elt_tag.val, doc) {
break;
}
}
}
pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
let mut pos = d.start;
while pos < d.end {
let elt_tag = vuint_at(*d.data, pos);
let elt_size = vuint_at(*d.data, elt_tag.next);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(doc) {
break;
}
}
}
}
pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) }
pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T {
f(vec::view(*d.data, d.start, d.end))
}
pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) }
pub fn doc_as_u8(d: Doc) -> u8 {
assert d.end == d.start + 1u;
(*d.data)[d.start]
}
pub fn doc_as_u16(d: Doc) -> u16 {
assert d.end == d.start + 2u;
io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
}
pub fn doc_as_u32(d: Doc) -> u32 {
assert d.end == d.start + 4u;
io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
}
pub fn doc_as_u64(d: Doc) -> u64 {
assert d.end == d.start + 8u;
io::u64_from_be_bytes(*d.data, d.start, 8u)
}
pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
// ebml writing
struct Serializer {
writer: io::Writer,
priv mut size_positions: ~[uint],
}
fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
match size {
1u => w.write(&[0x80u8 | (n as u8)]),
2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
n as u8]),
4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
(n >> 8_u) as u8, n as u8]),
_ => fail fmt!("vint to write too big: %?", n)
};
}
fn write_vuint(w: io::Writer, n: uint) {
if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
fail fmt!("vint to write too big: %?", n);
}
pub fn Serializer(w: io::Writer) -> Serializer {
let size_positions: ~[uint] = ~[];
Serializer { writer: w, mut size_positions: size_positions }
}
// FIXME (#2741): Provide a function to write the standard ebml header.
impl Serializer {
fn start_tag(tag_id: uint) {
debug!("Start tag %u", tag_id);
// Write the enum ID:
write_vuint(self.writer, tag_id);
// Write a placeholder four-byte size.
self.size_positions.push(self.writer.tell());
let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
self.writer.write(zeroes);
}
fn end_tag() {
let last_size_pos = self.size_positions.pop();
let cur_pos = self.writer.tell();
self.writer.seek(last_size_pos as int, io::SeekSet);
let size = (cur_pos - last_size_pos - 4u);
write_sized_vuint(self.writer, size, 4u);
self.writer.seek(cur_pos as int, io::SeekSet);
debug!("End tag (size = %u)", size);
}
fn wr_tag(tag_id: uint, blk: fn()) {
self.start_tag(tag_id);
blk();
self.end_tag();
}
fn wr_tagged_bytes(tag_id: uint, b: &[u8]) {
write_vuint(self.writer, tag_id);
write_vuint(self.writer, vec::len(b));
self.writer.write(b);
}
fn wr_tagged_u64(tag_id: uint, v: u64) {
do io::u64_to_be_bytes(v, 8u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_u32(tag_id: uint, v: u32) {
do io::u64_to_be_bytes(v as u64, 4u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_u16(tag_id: uint, v: u16) {
do io::u64_to_be_bytes(v as u64, 2u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_u8(tag_id: uint, v: u8) {
self.wr_tagged_bytes(tag_id, &[v]);
}
fn wr_tagged_i64(tag_id: uint, v: i64) {
do io::u64_to_be_bytes(v as u64, 8u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_i32(tag_id: uint, v: i32) {
do io::u64_to_be_bytes(v as u64, 4u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_i16(tag_id: uint, v: i16) {
do io::u64_to_be_bytes(v as u64, 2u) |v| {
self.wr_tagged_bytes(tag_id, v);
}
}
fn wr_tagged_i8(tag_id: uint, v: i8) {
self.wr_tagged_bytes(tag_id, &[v as u8]);
}
fn wr_tagged_str(tag_id: uint, v: &str) {
str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b));
}
fn wr_bytes(b: &[u8]) {
debug!("Write %u bytes", vec::len(b));
self.writer.write(b);
}
fn wr_str(s: &str) {
debug!("Write str: %?", s);
self.writer.write(str::to_bytes(s));
}
}
// FIXME (#2743): optionally perform "relaxations" on end_tag to more
// efficiently encode sizes; this is a fixed point iteration
// Set to true to generate more debugging in EBML serialization.
// Totally lame approach.
const debug: bool = false;
enum EbmlSerializerTag {
EsUint, EsU64, EsU32, EsU16, EsU8,
EsInt, EsI64, EsI32, EsI16, EsI8,
EsBool,
EsStr,
EsF64, EsF32, EsFloat,
EsEnum, EsEnumVid, EsEnumBody,
EsVec, EsVecLen, EsVecElt,
EsOpaque,
EsLabel // Used only when debugging
}
priv impl Serializer {
// used internally to emit things like the vector length and so on
fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) {
assert v <= 0xFFFF_FFFF_u;
self.wr_tagged_u32(t as uint, v as u32);
}
fn _emit_label(label: &str) {
// There are various strings that we have access to, such as
// the name of a record field, which do not actually appear in
// the serialized EBML (normally). This is just for
// efficiency. When debugging, though, we can emit such
// labels and then they will be checked by deserializer to
// try and check failures more quickly.
if debug { self.wr_tagged_str(EsLabel as uint, label) }
}
}
impl Serializer {
fn emit_opaque(&self, f: fn()) {
do self.wr_tag(EsOpaque as uint) {
f()
}
}
}
impl Serializer: serialization2::Serializer {
fn emit_nil(&self) {}
fn emit_uint(&self, v: uint) {
self.wr_tagged_u64(EsUint as uint, v as u64);
}
fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); }
fn emit_int(&self, v: int) {
self.wr_tagged_i64(EsInt as uint, v as i64);
}
fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); }
fn emit_bool(&self, v: bool) {
self.wr_tagged_u8(EsBool as uint, v as u8)
}
// FIXME (#2742): implement these
fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; }
fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; }
fn emit_float(&self, _v: float) {
fail ~"Unimplemented: serializing a float";
}
fn emit_char(&self, _v: char) {
fail ~"Unimplemented: serializing a char";
}
fn emit_borrowed_str(&self, v: &str) {
self.wr_tagged_str(EsStr as uint, v)
}
fn emit_owned_str(&self, v: &str) {
self.emit_borrowed_str(v)
}
fn emit_managed_str(&self, v: &str) {
self.emit_borrowed_str(v)
}
fn emit_borrowed(&self, f: fn()) { f() }
fn emit_owned(&self, f: fn()) { f() }
fn emit_managed(&self, f: fn()) { f() }
fn emit_enum(&self, name: &str, f: fn()) {
self._emit_label(name);
self.wr_tag(EsEnum as uint, f)
}
fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint,
f: fn()) {
self._emit_tagged_uint(EsEnumVid, v_id);
self.wr_tag(EsEnumBody as uint, f)
}
fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
fn emit_borrowed_vec(&self, len: uint, f: fn()) {
do self.wr_tag(EsVec as uint) {
self._emit_tagged_uint(EsVecLen, len);
f()
}
}
fn emit_owned_vec(&self, len: uint, f: fn()) {
self.emit_borrowed_vec(len, f)
}
fn emit_managed_vec(&self, len: uint, f: fn()) {
self.emit_borrowed_vec(len, f)
}
fn emit_vec_elt(&self, _idx: uint, f: fn()) {
self.wr_tag(EsVecElt as uint, f)
}
fn emit_rec(&self, f: fn()) { f() }
fn emit_struct(&self, _name: &str, f: fn()) { f() }
fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
self._emit_label(name);
f()
}
fn emit_tup(&self, _len: uint, f: fn()) { f() }
fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
}
struct Deserializer {
priv mut parent: Doc,
priv mut pos: uint,
}
pub fn Deserializer(d: Doc) -> Deserializer {
Deserializer { mut parent: d, mut pos: d.start }
}
priv impl Deserializer {
fn _check_label(lbl: &str) {
if self.pos < self.parent.end {
let TaggedDoc { tag: r_tag, doc: r_doc } =
doc_at(self.parent.data, self.pos);
if r_tag == (EsLabel as uint) {
self.pos = r_doc.end;
let str = doc_as_str(r_doc);
if lbl != str {
fail fmt!("Expected label %s but found %s", lbl, str);
}
}
}
}
fn next_doc(exp_tag: EbmlSerializerTag) -> Doc {
debug!(". next_doc(exp_tag=%?)", exp_tag);
if self.pos >= self.parent.end {
fail ~"no more documents in current node!";
}
let TaggedDoc { tag: r_tag, doc: r_doc } =
doc_at(self.parent.data, self.pos);
debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
copy self.parent.start, copy self.parent.end,
copy self.pos, r_tag, r_doc.start, r_doc.end);
if r_tag != (exp_tag as uint) {
fail fmt!("expected EMBL doc with tag %? but found tag %?",
exp_tag, r_tag);
}
if r_doc.end > self.parent.end {
fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x",
r_doc.end, self.parent.end);
}
self.pos = r_doc.end;
r_doc
}
fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
let old_parent = self.parent;
let old_pos = self.pos;
self.parent = d;
self.pos = d.start;
let r = f();
self.parent = old_parent;
self.pos = old_pos;
move r
}
fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
let r = doc_as_u32(self.next_doc(exp_tag));
debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
r as uint
}
}
impl Deserializer {
fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R {
do self.push_doc(self.next_doc(EsOpaque)) {
op(copy self.parent)
}
}
}
impl Deserializer: serialization2::Deserializer {
fn read_nil(&self) -> () { () }
fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
fn read_uint(&self) -> uint {
let v = doc_as_u64(self.next_doc(EsUint));
if v > (core::uint::max_value as u64) {
fail fmt!("uint %? too large for this architecture", v);
}
v as uint
}
fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 }
fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 }
fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 }
fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 }
fn read_int(&self) -> int {
let v = doc_as_u64(self.next_doc(EsInt)) as i64;
if v > (int::max_value as i64) || v < (int::min_value as i64) {
fail fmt!("int %? out of range for this architecture", v);
}
v as int
}
fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
fn read_f64(&self) -> f64 { fail ~"read_f64()"; }
fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
fn read_float(&self) -> float { fail ~"read_float()"; }
fn read_char(&self) -> char { fail ~"read_char()"; }
fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
// Compound types:
fn read_owned<T>(&self, f: fn() -> T) -> T {
debug!("read_owned()");
f()
}
fn read_managed<T>(&self, f: fn() -> T) -> T {
debug!("read_managed()");
f()
}
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
debug!("read_enum(%s)", name);
self._check_label(name);
self.push_doc(self.next_doc(EsEnum), f)
}
fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
debug!("read_enum_variant()");
let idx = self._next_uint(EsEnumVid);
debug!(" idx=%u", idx);
do self.push_doc(self.next_doc(EsEnumBody)) {
f(idx)
}
}
fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
debug!("read_enum_variant_arg(idx=%u)", idx);
f()
}
fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
debug!("read_owned_vec()");
do self.push_doc(self.next_doc(EsVec)) {
let len = self._next_uint(EsVecLen);
debug!(" len=%u", len);
f(len)
}
}
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
debug!("read_managed_vec()");
do self.push_doc(self.next_doc(EsVec)) {
let len = self._next_uint(EsVecLen);
debug!(" len=%u", len);
f(len)
}
}
fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
debug!("read_vec_elt(idx=%u)", idx);
self.push_doc(self.next_doc(EsVecElt), f)
}
fn read_rec<T>(&self, f: fn() -> T) -> T {
debug!("read_rec()");
f()
}
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
debug!("read_struct(name=%s)", name);
f()
}
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
debug!("read_field(name=%s, idx=%u)", name, idx);
self._check_label(name);
f()
}
fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
debug!("read_tup(len=%u)", len);
f()
}
fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
debug!("read_tup_elt(idx=%u)", idx);
f()
}
}
// ___________________________________________________________________________
// Testing
#[cfg(test)]
mod tests {
#[test]
fn test_option_int() {
fn test_v(v: Option<int>) {
debug!("v == %?", v);
let bytes = do io::with_bytes_writer |wr| {
let ebml_w = Serializer(wr);
v.serialize(&ebml_w)
};
let ebml_doc = Doc(@bytes);
let deser = Deserializer(ebml_doc);
let v1 = serialization2::deserialize(&deser);
debug!("v1 == %?", v1);
assert v == v1;
}
test_v(Some(22));
test_v(None);
test_v(Some(3));
}
}

Some files were not shown because too many files have changed in this diff Show more