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

This commit is contained in:
Simon BD 2012-10-22 18:33:41 -05:00
commit cc0f2c6bb2
401 changed files with 11020 additions and 10248 deletions

View file

@ -10,7 +10,7 @@
// End:
#[link(name = "cargo",
vers = "0.4",
vers = "0.5",
uuid = "9ff87a04-8fed-4295-9ff8-f99bb802650b",
url = "https://github.com/mozilla/rust/tree/master/src/cargo")];
@ -27,10 +27,10 @@
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");
extern mod rustc(vers = "0.4");
extern mod syntax(vers = "0.4");
extern mod core(vers = "0.5");
extern mod std(vers = "0.5");
extern mod rustc(vers = "0.5");
extern mod syntax(vers = "0.5");
use core::*;

View file

@ -705,7 +705,7 @@ fn configure(opts: Options) -> Cargo {
~" or package manager to get it to work correctly");
}
c
move c
}
fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) {
@ -1162,20 +1162,20 @@ fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool {
}
match (src.key, src.keyfp) {
(Some(_), Some(f)) => {
let r = pgp::verify(&c.root, &pkgfile, &sigfile, f);
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
if !r {
error(fmt!("signature verification failed for source %s",
name));
error(fmt!("signature verification failed for source %s with \
key %s", name, f));
return false;
}
if has_src_file {
let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f);
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
if !e {
error(fmt!("signature verification failed for source %s",
name));
error(fmt!("signature verification failed for source %s \
with key %s", name, f));
return false;
}
}
@ -1273,21 +1273,21 @@ fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool {
}
match (src.key, src.keyfp) {
(Some(_), Some(f)) => {
let r = pgp::verify(&c.root, &pkgfile, &sigfile, f);
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
if !r {
error(fmt!("signature verification failed for source %s",
name));
error(fmt!("signature verification failed for source %s with \
key %s", name, f));
rollback(name, dir, false);
return false;
}
if has_src_file {
let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f);
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
if !e {
error(fmt!("signature verification failed for source %s",
name));
error(fmt!("signature verification failed for source %s \
with key %s", name, f));
rollback(name, dir, false);
return false;
}
@ -1370,11 +1370,11 @@ fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
return false;
}
let r = pgp::verify(&c.root, &pkgfile, &sigfile, f);
let r = pgp::verify(&c.root, &pkgfile, &sigfile);
if !r {
error(fmt!("signature verification failed for source %s",
name));
error(fmt!("signature verification failed for source %s with \
key %s", name, f));
return false;
}
@ -1390,11 +1390,11 @@ fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool {
return false;
}
let e = pgp::verify(&c.root, &srcfile, &srcsigfile, f);
let e = pgp::verify(&c.root, &srcfile, &srcsigfile);
if !e {
error(~"signature verification failed for " +
~"source " + name);
~"source " + name + ~" with key " + f);
return false;
}
}
@ -1463,8 +1463,7 @@ fn cmd_init(c: &Cargo) {
return;
}
let r = pgp::verify(&c.root, &srcfile, &sigfile,
pgp::signing_key_fp());
let r = pgp::verify(&c.root, &srcfile, &sigfile);
if !r {
error(fmt!("signature verification failed for '%s'",
srcfile.to_str()));
@ -1615,10 +1614,10 @@ fn dump_sources(c: &Cargo) {
_ => ()
}
hash.insert(copy k, json::Object(chash));
hash.insert(copy k, json::Object(move chash));
}
json::to_writer(writer, &json::Object(hash))
json::to_writer(writer, &json::Object(move hash))
}
result::Err(e) => {
error(fmt!("could not dump sources: %s", e));

View file

@ -1,5 +1,5 @@
fn gpg(args: ~[~str]) -> { status: int, out: ~str, err: ~str } {
return run::program_output(~"gpg", args);
fn gpgv(args: ~[~str]) -> { status: int, out: ~str, err: ~str } {
return run::program_output(~"gpgv", args);
}
fn signing_key() -> ~str {
@ -59,7 +59,7 @@ fn signing_key_fp() -> ~str {
}
fn supported() -> bool {
let r = gpg(~[~"--version"]);
let r = gpgv(~[~"--version"]);
r.status == 0
}
@ -88,15 +88,14 @@ fn add(root: &Path, key: &Path) {
}
}
fn verify(root: &Path, data: &Path, sig: &Path, keyfp: ~str) -> bool {
fn verify(root: &Path, data: &Path, sig: &Path) -> bool {
let path = root.push("gpg");
let p = gpg(~[~"--homedir", path.to_str(),
~"--with-fingerprint",
~"--verify", sig.to_str(),
data.to_str()]);
let res = ~"Primary key fingerprint: " + keyfp;
for str::split_char_each(p.err, '\n') |line| {
if line == res { return true; }
let res = gpgv(~[~"--homedir", path.to_str(),
~"--keyring", ~"pubring.gpg",
~"--verbose",
sig.to_str(), data.to_str()]);
if res.status != 0 {
return false;
}
return false;
return true;
}

View file

@ -8,8 +8,8 @@
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");
extern mod core(vers = "0.5");
extern mod std(vers = "0.5");
use core::*;

View file

@ -145,7 +145,7 @@ fn make_tests(config: config) -> ~[test::TestDesc] {
tests.push(make_test(config, file))
}
}
return tests;
move tests
}
fn is_test(config: config, testfile: &Path) -> bool {

View file

@ -60,12 +60,12 @@ fn run(lib_path: ~str,
writeclose(pipe_in.out, input);
let p = pipes::PortSet();
let ch = p.chan();
do task::spawn_sched(task::SingleThreaded) {
do task::spawn_sched(task::SingleThreaded) |move ch| {
let errput = readclose(pipe_err.in);
ch.send((2, errput));
}
let ch = p.chan();
do task::spawn_sched(task::SingleThreaded) {
do task::spawn_sched(task::SingleThreaded) |move ch| {
let output = readclose(pipe_out.in);
ch.send((1, output));
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language name="Rust" version="0.3.1" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
<language name="Rust" version="0.4.0" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
<highlighting>
<list name="fn">
<item> fn </item>
@ -9,59 +9,39 @@
<item> type </item>
</list>
<list name="keywords">
<item> alt </item>
<item> again </item>
<item> as </item>
<item> assert </item>
<item> break </item>
<item> check </item>
<item> claim </item>
<item> const </item>
<item> copy </item>
<item> do </item>
<item> drop </item>
<item> else </item>
<item> enum </item>
<item> export </item>
<item> extern </item>
<item> f16 </item>
<item> f80 </item>
<item> f128 </item>
<item> fail </item>
<item> for </item>
<item> if </item>
<item> impl </item>
<item> import </item>
<item> in </item>
<item> let </item>
<item> log </item>
<item> loop </item>
<item> m32 </item>
<item> m64 </item>
<item> m128 </item>
<item> match </item>
<item> mod </item>
<item> module </item>
<item> move </item>
<item> mut </item>
<item> new </item>
<item> of </item>
<item> owned </item>
<item> priv </item>
<item> pub </item>
<item> pure </item>
<item> ret </item>
<item> ref </item>
<item> return </item>
<item> to </item>
<item> unchecked </item>
<item> static </item>
<item> struct </item>
<item> trait </item>
<item> unsafe </item>
<item> use </item>
<item> while </item>
<item> with </item>
<item> mod </item>
<item> trait </item>
<item> class </item>
<item> struct </item>
<item> enum </item>
</list>
<list name="types">
<item> bool </item>
@ -80,8 +60,9 @@
<item> float </item>
<item> char </item>
<item> str </item>
<item> option </item>
<item> either </item>
<item> Either </item>
<item> Option </item>
<item> Result </item>
</list>
<list name="ctypes">
<item> c_float </item>
@ -121,16 +102,16 @@
<list name="constants">
<item> true </item>
<item> false </item>
<item> some </item>
<item> none </item>
<item> left </item>
<item> right </item>
<item> ok </item>
<item> err </item>
<item> success </item>
<item> failure </item>
<item> cons </item>
<item> nil </item>
<item> Some </item>
<item> None </item>
<item> Left </item>
<item> Right </item>
<item> Ok </item>
<item> Err </item>
<item> Success </item>
<item> Failure </item>
<item> Cons </item>
<item> Nil </item>
</list>
<list name="cconstants">
<item> EXIT_FAILURE </item>

View file

@ -68,7 +68,7 @@ def parse_line(n, line):
match = re.match(r"([ST]) (\d{4}-\d{2}-\d{2}) ([a-fA-F\d]+)\s*$", line);
if (not match):
raise Exception("%s:%d:E syntax error" % (snapshotfile, n))
raise Exception("%s:%d:E syntax error: " % (snapshotfile, n))
return {"type": "snapshot",
"date": match.group(2),
"rev": match.group(3)}

View file

@ -12,9 +12,9 @@
#[allow(deprecated_mode)];
#[allow(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod std(vers = "0.4");
extern mod syntax(vers = "0.4");
extern mod core(vers = "0.5");
extern mod std(vers = "0.5");
extern mod syntax(vers = "0.5");
use core::*;

View file

@ -104,7 +104,7 @@ pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool {
}
}
fn safe_to_steal_ty(t: @ast::ty, tm: test_mode) -> bool {
fn safe_to_steal_ty(t: @ast::Ty, tm: test_mode) -> bool {
// Restrictions happen to be the same.
safe_to_replace_ty(t.node, tm)
}
@ -119,16 +119,16 @@ fn stash_expr_if(c: fn@(@ast::expr, test_mode)->bool,
} else {/* now my indices are wrong :( */ }
}
fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool,
es: @mut ~[ast::ty],
e: @ast::ty,
fn stash_ty_if(c: fn@(@ast::Ty, test_mode)->bool,
es: @mut ~[ast::Ty],
e: @ast::Ty,
tm: test_mode) {
if c(e, tm) {
es.push(*e);
} else {/* now my indices are wrong :( */ }
}
type stolen_stuff = {exprs: ~[ast::expr], tys: ~[ast::ty]};
type stolen_stuff = {exprs: ~[ast::expr], tys: ~[ast::Ty]};
fn steal(crate: ast::crate, tm: test_mode) -> stolen_stuff {
let exprs = @mut ~[];
@ -195,7 +195,7 @@ fn replace_expr_in_crate(crate: ast::crate, i: uint,
// Replace the |i|th ty (in fold order) of |crate| with |newty|.
fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::ty,
fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty,
tm: test_mode) -> ast::crate {
let j: @mut uint = @mut 0u;
fn fold_ty_rep(j_: @mut uint, i_: uint, newty_: ast::ty_,
@ -225,7 +225,7 @@ fn as_str(f: fn@(+x: io::Writer)) -> ~str {
io::with_str_writer(f)
}
fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
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(),
@ -239,7 +239,7 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap,
fn check_variants_T<T: Copy>(
crate: ast::crate,
codemap: codemap::codemap,
codemap: codemap::CodeMap,
filename: &Path,
thing_label: ~str,
things: ~[T],
@ -296,7 +296,7 @@ fn check_variants_T<T: Copy>(
}
fn last_part(filename: ~str) -> ~str {
let ix = option::get(&str::rfind_char(filename, '/'));
let ix = option::get(str::rfind_char(filename, '/'));
str::slice(filename, ix + 1u, str::len(filename) - 3u)
}
@ -444,7 +444,7 @@ fn parse_and_print(code: @~str) -> ~str {
fn has_raw_pointers(c: ast::crate) -> bool {
let has_rp = @mut false;
fn visit_ty(flag: @mut bool, t: @ast::ty) {
fn visit_ty(flag: @mut bool, t: @ast::Ty) {
match t.node {
ast::ty_ptr(_) => { *flag = true; }
_ => { }

View file

@ -122,9 +122,9 @@ pub mod tests {
pub fn test_transmute() {
unsafe {
let x = @1;
let x: *int = transmute(x);
let x: *int = transmute(move x);
assert *x == 1;
let _x: @int = transmute(x);
let _x: @int = transmute(move x);
}
}

View file

@ -142,7 +142,7 @@ pub unsafe fn annihilate() {
assert (*box).header.prev == null();
debug!("freeing box: %x", box as uint);
rt_free(transmute(box));
rt_free(transmute(move box));
}
}

View file

@ -12,7 +12,7 @@ use libc::c_double;
#[link_name = "m"]
#[abi = "cdecl"]
pub extern mod c_double {
pub extern mod c_double_utils {
// Alpabetically sorted by link_name
@ -87,7 +87,7 @@ pub extern mod c_double {
#[link_name = "m"]
#[abi = "cdecl"]
pub extern mod c_float {
pub extern mod c_float_utils {
// Alpabetically sorted by link_name

300
src/libcore/condition.rs Normal file
View file

@ -0,0 +1,300 @@
// helper for transmutation, shown below.
type RustClosure = (int,int);
struct Condition<T, U:Copy> {
key: task::local_data::LocalDataKey<Handler<T,U>>
}
struct Handler<T, U:Copy> {
handle: RustClosure
}
struct ProtectBlock<T, U:Copy> {
cond: &Condition<T, U>,
inner: RustClosure
}
struct Guard<T, U:Copy> {
cond: &Condition<T,U>,
prev: Option<@Handler<T, U>>,
drop {
match self.prev {
None => (),
Some(p) =>
unsafe {
debug!("Guard: popping handler from TLS");
task::local_data::local_data_set(self.cond.key, p)
}
}
}
}
struct HandleBlock<T, U:Copy> {
pb: &ProtectBlock<T,U>,
prev: Option<@Handler<T,U>>,
handler: @Handler<T,U>,
drop {
unsafe {
debug!("HandleBlock: pushing handler to TLS");
let _g = Guard { cond: self.pb.cond,
prev: self.prev };
task::local_data::local_data_set(self.pb.cond.key,
self.handler);
// transmutation to avoid copying non-copyable, should
// be fixable by tracking closure pointees in regionck.
let f : &fn() = ::cast::transmute(self.pb.inner);
debug!("HandleBlock: invoking protected code");
f();
debug!("HandleBlock: returned from protected code");
}
}
}
struct Trap<T, U:Copy> {
cond: &Condition<T,U>,
handler: @Handler<T, U>
}
impl<T, U: Copy> ProtectBlock<T,U> {
fn handle(&self, h: &self/fn(&T) ->U) -> HandleBlock/&self<T,U> {
unsafe {
debug!("ProtectBlock.handle: setting up handler block");
let p : *RustClosure = ::cast::transmute(&h);
let prev = task::local_data::local_data_get(self.cond.key);
HandleBlock { pb: self,
prev: prev,
handler: @Handler{handle: *p} }
}
}
}
impl<T, U: Copy> Trap<T,U> {
fn in<V: Copy>(&self, inner: &self/fn() -> V) -> V {
unsafe {
let prev = task::local_data::local_data_get(self.cond.key);
let _g = Guard { cond: self.cond,
prev: prev };
debug!("Trap: pushing handler to TLS");
task::local_data::local_data_set(self.cond.key, self.handler);
inner()
}
}
}
impl<T, U: Copy> Condition<T,U> {
fn guard(&self, h: &self/fn(&T) ->U) -> Guard/&self<T,U> {
unsafe {
let prev = task::local_data::local_data_get(self.key);
let g = Guard { cond: self, prev: prev };
debug!("Guard: pushing handler to TLS");
let p : *RustClosure = ::cast::transmute(&h);
let h = @Handler{handle: *p};
task::local_data::local_data_set(self.key, h);
move g
}
}
fn trap(&self, h: &self/fn(&T) ->U) -> Trap/&self<T,U> {
unsafe {
let p : *RustClosure = ::cast::transmute(&h);
let h = @Handler{handle: *p};
move Trap { cond: self, handler: h }
}
}
fn protect(&self, inner: &self/fn()) -> ProtectBlock/&self<T,U> {
unsafe {
// transmutation to avoid copying non-copyable, should
// be fixable by tracking closure pointees in regionck.
debug!("Condition.protect: setting up protected block");
let p : *RustClosure = ::cast::transmute(&inner);
ProtectBlock { cond: self,
inner: *p }
}
}
fn raise(t:&T) -> U {
unsafe {
match task::local_data::local_data_get(self.key) {
None => {
debug!("Condition.raise: found no handler");
fail
}
Some(handler) => {
debug!("Condition.raise: found handler");
let f : &fn(&T) -> U = ::cast::transmute(handler.handle);
f(t)
}
}
}
}
}
#[cfg(test)]
fn sadness_key(_x: @Handler<int,int>) { }
#[cfg(test)]
fn trouble(i: int) {
// Condition should work as a const, just limitations in consts.
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
debug!("trouble: raising conition");
let j = sadness_condition.raise(&i);
debug!("trouble: handler recovered with %d", j);
}
#[test]
fn test1() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut i = 10;
let b = do sadness_condition.protect {
debug!("test1: in protected block");
trouble(1);
trouble(2);
trouble(3);
};
do b.handle |j| {
debug!("test1: in handler");
i += *j;
i
};
assert i == 16;
}
#[cfg(test)]
fn nested_test_inner() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut inner_trapped = false;
let b = do sadness_condition.protect {
debug!("nested_test_inner: in protected block");
trouble(1);
};
do b.handle |_j| {
debug!("nested_test_inner: in handler");
inner_trapped = true;
0
};
assert inner_trapped;
}
#[test]
fn nested_test_outer() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut outer_trapped = false;
let b = do sadness_condition.protect {
debug!("nested_test_outer: in protected block");
nested_test_inner();
trouble(1);
};
do b.handle |_j| {
debug!("nested_test_outer: in handler");
outer_trapped = true;
0
};
assert outer_trapped;
}
#[cfg(test)]
fn nested_guard_test_inner() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut inner_trapped = false;
let _g = do sadness_condition.guard |_j| {
debug!("nested_guard_test_inner: in handler");
inner_trapped = true;
0
};
debug!("nested_guard_test_inner: in protected block");
trouble(1);
assert inner_trapped;
}
#[test]
fn nested_guard_test_outer() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut outer_trapped = false;
let _g = do sadness_condition.guard |_j| {
debug!("nested_guard_test_outer: in handler");
outer_trapped = true;
0
};
debug!("nested_guard_test_outer: in protected block");
nested_guard_test_inner();
trouble(1);
assert outer_trapped;
}
#[cfg(test)]
fn nested_trap_test_inner() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut inner_trapped = false;
do sadness_condition.trap(|_j| {
debug!("nested_trap_test_inner: in handler");
inner_trapped = true;
0
}).in {
debug!("nested_trap_test_inner: in protected block");
trouble(1);
}
assert inner_trapped;
}
#[test]
fn nested_trap_test_outer() {
let sadness_condition : Condition<int,int> =
Condition { key: sadness_key };
let mut outer_trapped = false;
do sadness_condition.trap(|_j| {
debug!("nested_trap_test_outer: in handler");
outer_trapped = true; 0
}).in {
debug!("nested_guard_test_outer: in protected block");
nested_trap_test_inner();
trouble(1);
}
assert outer_trapped;
}

View file

@ -25,7 +25,7 @@ Implicitly, all crates behave as if they included the following prologue:
*/
#[link(name = "core",
vers = "0.4",
vers = "0.5",
uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
url = "https://github.com/mozilla/rust/tree/master/src/libcore")];
@ -200,6 +200,7 @@ pub mod flate;
pub mod repr;
pub mod cleanup;
pub mod reflect;
pub mod condition;
// Modules supporting compiler-generated code
// Exported but not part of the public interface

View file

@ -11,8 +11,8 @@ pub use GenericPath = path::GenericPath;
pub use WindowsPath = path::WindowsPath;
pub use PosixPath = path::PosixPath;
pub use tuple::{TupleOps, ExtendedTupleOps};
pub use str::{StrSlice, UniqueStr};
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
pub use str::{StrSlice, Trimmable};
pub use vec::{ConstVector, CopyableVector, ImmutableVector};
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
pub use vec::{MutableVector, MutableCopyableVector};
@ -33,7 +33,7 @@ pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
pub use ops::{Shl, Shr, Index};
#[cfg(test)]
extern mod coreops(name = "core", vers = "0.4");
extern mod coreops(name = "core", vers = "0.5");
#[cfg(test)]
pub use coreops::ops::{Const, Copy, Send, Owned};
@ -72,6 +72,6 @@ mod core {
// Similar to above. Some magic to make core testable.
#[cfg(test)]
mod std {
extern mod std(vers = "0.4");
extern mod std(vers = "0.5");
pub use std::test;
}

View file

@ -208,7 +208,7 @@ impl<T> DList<T> {
fn push_head_n(data: T) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.add_head(nobe);
option::get(&nobe)
option::get(nobe)
}
/// Add data to the tail of the list. O(1).
fn push(data: T) {
@ -221,7 +221,7 @@ impl<T> DList<T> {
fn push_n(data: T) -> DListNode<T> {
let mut nobe = self.new_link(move data);
self.add_tail(nobe);
option::get(&nobe)
option::get(nobe)
}
/**
* Insert data into the middle of the list, left of the given node.
@ -245,7 +245,7 @@ impl<T> DList<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)
option::get(nobe)
}
/**
* Insert data into the middle of the list, right of the given node.
@ -269,7 +269,7 @@ impl<T> DList<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)
option::get(nobe)
}
/// Remove a node from the head of the list. O(1).
@ -385,17 +385,17 @@ impl<T> DList<T> {
let mut link = self.peek_n();
let mut rabbit = link;
while option::is_some(&link) {
let nobe = option::get(&link);
let nobe = option::get(link);
assert nobe.linked;
// check cycle
if option::is_some(&rabbit) {
rabbit = option::get(&rabbit).next;
rabbit = option::get(rabbit).next;
}
if option::is_some(&rabbit) {
rabbit = option::get(&rabbit).next;
rabbit = option::get(rabbit).next;
}
if option::is_some(&rabbit) {
assert !box::ptr_eq(*option::get(&rabbit), *nobe);
assert !box::ptr_eq(*option::get(rabbit), *nobe);
}
// advance
link = nobe.next_link();
@ -406,17 +406,17 @@ impl<T> DList<T> {
link = self.peek_tail_n();
rabbit = link;
while option::is_some(&link) {
let nobe = option::get(&link);
let nobe = option::get(link);
assert nobe.linked;
// check cycle
if option::is_some(&rabbit) {
rabbit = option::get(&rabbit).prev;
rabbit = option::get(rabbit).prev;
}
if option::is_some(&rabbit) {
rabbit = option::get(&rabbit).prev;
rabbit = option::get(rabbit).prev;
}
if option::is_some(&rabbit) {
assert !box::ptr_eq(*option::get(&rabbit), *nobe);
assert !box::ptr_eq(*option::get(rabbit), *nobe);
}
// advance
link = nobe.prev_link();

View file

@ -56,7 +56,7 @@ pub enum DVec<A> {
}
/// Creates a new, empty dvec
pub fn DVec<A>() -> DVec<A> {
pub pure fn DVec<A>() -> DVec<A> {
DVec_({mut data: ~[]})
}

View file

@ -301,7 +301,7 @@ pub mod rt {
unsafe { str::unshift_char(&mut s, ' ') };
}
}
return unsafe { pad(cv, s, PadSigned) };
return unsafe { pad(cv, move s, PadSigned) };
}
pub pure fn conv_uint(cv: Conv, u: uint) -> ~str {
let prec = get_int_precision(cv);
@ -313,7 +313,7 @@ pub mod rt {
TyBits => uint_to_str_prec(u, 2u, prec),
TyOctal => uint_to_str_prec(u, 8u, prec)
};
return unsafe { pad(cv, rs, PadUnsigned) };
return unsafe { pad(cv, move rs, PadUnsigned) };
}
pub pure fn conv_bool(cv: Conv, b: bool) -> ~str {
let s = if b { ~"true" } else { ~"false" };
@ -323,20 +323,20 @@ pub mod rt {
}
pub pure fn conv_char(cv: Conv, c: char) -> ~str {
let mut s = str::from_char(c);
return unsafe { pad(cv, s, PadNozero) };
return unsafe { pad(cv, move s, PadNozero) };
}
pub pure fn conv_str(cv: Conv, s: &str) -> ~str {
// For strings, precision is the maximum characters
// displayed
let mut unpadded = match cv.precision {
CountImplied => s.to_unique(),
CountImplied => s.to_owned(),
CountIs(max) => if max as uint < str::char_len(s) {
str::substr(s, 0u, max as uint)
} else {
s.to_unique()
s.to_owned()
}
};
return unsafe { pad(cv, unpadded, PadNozero) };
return unsafe { pad(cv, move unpadded, PadNozero) };
}
pub pure fn conv_float(cv: Conv, f: float) -> ~str {
let (to_str, digits) = match cv.precision {
@ -351,7 +351,7 @@ pub mod rt {
s = ~" " + s;
}
}
return unsafe { pad(cv, s, PadFloat) };
return unsafe { pad(cv, move s, PadFloat) };
}
pub pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
let s = sys::log_str(v);
@ -411,14 +411,14 @@ pub mod rt {
pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
let mut s = move s; // sadtimes
let uwidth : uint = match cv.width {
CountImplied => return s,
CountImplied => return (move 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 s; }
if uwidth <= strlen { return (move s); }
let mut padchar = ' ';
let diff = uwidth - strlen;
if have_flag(cv.flags, flag_left_justify) {

View file

@ -4,7 +4,7 @@
//! Operations and constants for `f32`
pub use cmath::c_float::*;
pub use cmath::c_float_utils::*;
pub use cmath::c_float_targ_consts::*;
// These are not defined inside consts:: for consistency with

View file

@ -4,7 +4,7 @@
//! Operations and constants for `f64`
pub use cmath::c_double::*;
pub use cmath::c_double_utils::*;
pub use cmath::c_double_targ_consts::*;
// FIXME (#1433): obtain these in a different way
@ -59,7 +59,7 @@ pub pure fn ge(x: f64, y: f64) -> bool { return x >= y; }
pub pure fn gt(x: f64, y: f64) -> bool { return x > y; }
pub pure fn sqrt(x: f64) -> f64 {
cmath::c_double::sqrt(x as libc::c_double) as f64
cmath::c_double_utils::sqrt(x as libc::c_double) as f64
}
/// Returns true if `x` is a positive number, including +0.0f640 and +Infinity

View file

@ -37,7 +37,7 @@ pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] {
ptr::addr_of(&outsz),
lz_norm);
assert res as int != 0;
let out = vec::raw::from_buf(res as *u8,
let out = vec::raw::from_buf_raw(res as *u8,
outsz as uint);
libc::free(res);
move out
@ -55,7 +55,7 @@ pub fn inflate_bytes(bytes: &[const u8]) -> ~[u8] {
ptr::addr_of(&outsz),
0);
assert res as int != 0;
let out = vec::raw::from_buf(res as *u8,
let out = vec::raw::from_buf_raw(res as *u8,
outsz as uint);
libc::free(res);
move out

View file

@ -91,7 +91,7 @@ pub mod consts {
* * digits - The number of significant digits
* * exact - Whether to enforce the exact number of significant digits
*/
pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
pub pure 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"; }
@ -125,7 +125,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
// store the next digit
frac *= 10.0;
let digit = frac as uint;
fractionalParts.push(digit);
// Bleh: not really unsafe.
unsafe { fractionalParts.push(digit); }
// calculate the next frac
frac -= digit as float;
@ -140,7 +141,8 @@ pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str {
// turn digits into string
// using stack of digits
while fractionalParts.is_not_empty() {
let mut adjusted_digit = carry + fractionalParts.pop();
// Bleh; shouldn't need to be unsafe
let mut adjusted_digit = carry + unsafe { fractionalParts.pop() };
if adjusted_digit == 10 {
carry = 1;
@ -196,7 +198,7 @@ pub fn test_to_str_exact_do_decimal() {
* * num - The float value
* * digits - The number of significant digits
*/
pub fn to_str(num: float, digits: uint) -> ~str {
pub pure fn to_str(num: float, digits: uint) -> ~str {
to_str_common(num, digits, false)
}
@ -361,7 +363,7 @@ pub fn from_str(num: &str) -> Option<float> {
*
* `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
*/
pub fn pow_with_uint(base: uint, pow: uint) -> float {
pub pure fn pow_with_uint(base: uint, pow: uint) -> float {
if base == 0u {
if pow == 0u {
return NaN as float;

View file

@ -179,8 +179,8 @@ pub mod test {
#[test]
pub fn test_from_port() {
let (po, ch) = future_pipe::init();
future_pipe::server::completed(ch, ~"whale");
let f = from_port(po);
future_pipe::server::completed(move ch, ~"whale");
let f = from_port(move po);
assert get(&f) == ~"whale";
}
@ -238,7 +238,7 @@ pub mod test {
pub fn test_sendable_future() {
let expected = ~"schlorf";
let f = do spawn |copy expected| { copy expected };
do task::spawn {
do task::spawn |move f, move expected| {
let actual = get(&f);
assert actual == expected;
}

View file

@ -156,7 +156,7 @@ struct SipState {
mut v1: u64,
mut v2: u64,
mut v3: u64,
tail: [mut u8]/8, // unprocessed bytes
tail: [mut u8 * 8], // unprocessed bytes
mut ntail: uint, // how many bytes in tail are valid
}
@ -359,72 +359,72 @@ impl &SipState : Streaming {
#[test]
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, ]/_,
[ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ]/_,
[ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ]/_,
[ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ]/_,
[ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ]/_,
[ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ]/_,
[ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ]/_,
[ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ]/_,
[ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ]/_,
[ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ]/_,
[ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ]/_,
[ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ]/_,
[ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ]/_,
[ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ]/_,
[ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ]/_,
[ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ]/_,
[ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ]/_,
[ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ]/_,
[ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ]/_,
[ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ]/_,
[ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ]/_,
[ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ]/_,
[ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ]/_,
[ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ]/_,
[ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ]/_,
[ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ]/_,
[ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ]/_,
[ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ]/_,
[ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ]/_,
[ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ]/_,
[ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ]/_,
[ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ]/_,
[ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ]/_,
[ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ]/_,
[ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ]/_,
[ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ]/_,
[ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ]/_,
[ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ]/_,
[ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ]/_,
[ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ]/_,
[ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ]/_,
[ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ]/_,
[ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ]/_,
[ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ]/_,
[ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ]/_,
[ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ]/_,
[ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ]/_,
[ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ]/_,
[ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ]/_,
[ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ]/_,
[ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ]/_,
[ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ]/_,
[ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ]/_,
[ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ]/_,
[ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ]/_,
[ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ]/_,
[ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ]/_,
[ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ]/_,
[ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ]/_,
[ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ]/_,
[ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ]/_,
[ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ]/_,
[ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]/_
]/_;
let vecs : [[u8 * 8] * 64] = [
[ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
[ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
[ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
[ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
[ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
[ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
[ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
[ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
[ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
[ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
[ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
[ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
[ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
[ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
[ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
[ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
[ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
[ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
[ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
[ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
[ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
[ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
[ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
[ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
[ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
[ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
[ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
[ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
[ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
[ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
[ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
[ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
[ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
[ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
[ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
[ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
[ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
[ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
[ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
[ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
[ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
[ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
[ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
[ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
[ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
[ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
[ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
[ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
[ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
[ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
[ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
[ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
[ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
[ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
[ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
[ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
[ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
[ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
[ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
[ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
[ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
[ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
[ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
[ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
];
let k0 = 0x_07_06_05_04_03_02_01_00_u64;
let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
@ -433,12 +433,12 @@ pub fn test_siphash() {
let stream_inc = &State(k0,k1);
let stream_full = &State(k0,k1);
fn to_hex_str(r: &[u8]/8) -> ~str {
fn to_hex_str(r: &[u8 * 8]) -> ~str {
let mut s = ~"";
for vec::each(*r) |b| {
s += uint::to_str(*b as uint, 16u);
}
return s;
move s
}
while t < 64 {

View file

@ -50,7 +50,6 @@ pub pure fn compl(i: T) -> T {
}
/// Computes the absolute value
// FIXME: abs should return an unsigned int (#2353)
pub pure fn abs(i: T) -> T {
if is_negative(i) { -i } else { i }
}
@ -154,7 +153,7 @@ impl T : FromStr {
}
/// Convert to a string in a given base
pub fn to_str(n: T, radix: uint) -> ~str {
pub pure 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) }
@ -162,7 +161,7 @@ pub fn to_str(n: T, radix: uint) -> ~str {
}
}
pub fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
pub pure 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 {
@ -171,7 +170,7 @@ pub fn to_str_bytes<U>(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U {
}
/// Convert to a string
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
#[test]

View file

@ -37,7 +37,7 @@ pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
// FIXME (#2982): This should probably return an error.
fn read(buf: &[mut u8], len: uint) -> uint;
fn read(bytes: &[mut u8], len: uint) -> uint;
fn read_byte() -> int;
fn unread_byte(int);
fn eof() -> bool;
@ -65,32 +65,32 @@ pub trait ReaderUtil {
impl<T: Reader> T : ReaderUtil {
fn read_bytes(len: uint) -> ~[u8] {
let mut buf = vec::with_capacity(len);
unsafe { vec::raw::set_len(&mut buf, len); }
let mut bytes = vec::with_capacity(len);
unsafe { vec::raw::set_len(&mut bytes, len); }
let count = self.read(buf, len);
let count = self.read(bytes, len);
unsafe { vec::raw::set_len(&mut buf, count); }
move buf
unsafe { vec::raw::set_len(&mut bytes, count); }
move bytes
}
fn read_line() -> ~str {
let mut buf = ~[];
let mut bytes = ~[];
loop {
let ch = self.read_byte();
if ch == -1 || ch == 10 { break; }
buf.push(ch as u8);
bytes.push(ch as u8);
}
str::from_bytes(buf)
str::from_bytes(bytes)
}
fn read_chars(n: uint) -> ~[char] {
// returns the (consumed offset, n_req), appends characters to &chars
fn chars_from_bytes<T: Reader>(buf: &~[u8], chars: &mut ~[char])
fn chars_from_bytes<T: Reader>(bytes: &~[u8], chars: &mut ~[char])
-> (uint, uint) {
let mut i = 0;
let buf_len = buf.len();
while i < buf_len {
let b0 = buf[i];
let bytes_len = bytes.len();
while i < bytes_len {
let b0 = bytes[i];
let w = str::utf8_char_width(b0);
let end = i + w;
i += 1;
@ -100,12 +100,12 @@ impl<T: Reader> T : ReaderUtil {
loop;
}
// can't satisfy this char with the existing data
if end > buf_len {
return (i - 1, end - buf_len);
if end > bytes_len {
return (i - 1, end - bytes_len);
}
let mut val = 0;
while i < end {
let next = buf[i] as int;
let next = bytes[i] as int;
i += 1;
assert (next > -1);
assert (next & 192 == 128);
@ -119,8 +119,8 @@ impl<T: Reader> T : ReaderUtil {
}
return (i, 0);
}
let mut buf: ~[u8] = ~[];
let mut chars: ~[char] = ~[];
let mut bytes = ~[];
let mut chars = ~[];
// might need more bytes, but reading n will never over-read
let mut nbread = n;
while nbread > 0 {
@ -130,15 +130,15 @@ impl<T: Reader> T : ReaderUtil {
// we're split in a unicode char?
break;
}
buf.push_all(data);
let (offset, nbreq) = chars_from_bytes::<T>(&buf, &mut chars);
bytes.push_all(data);
let (offset, nbreq) = chars_from_bytes::<T>(&bytes, &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 > 0 {
buf = vec::slice(buf, offset, buf.len());
bytes = vec::slice(bytes, offset, bytes.len());
}
}
move chars
@ -154,12 +154,12 @@ impl<T: Reader> T : ReaderUtil {
}
fn read_c_str() -> ~str {
let mut buf: ~[u8] = ~[];
let mut bytes: ~[u8] = ~[];
loop {
let ch = self.read_byte();
if ch < 1 { break; } else { buf.push(ch as u8); }
if ch < 1 { break; } else { bytes.push(ch as u8); }
}
str::from_bytes(buf)
str::from_bytes(bytes)
}
// FIXME deal with eof? // #2004
@ -191,9 +191,9 @@ impl<T: Reader> T : ReaderUtil {
}
fn read_whole_stream() -> ~[u8] {
let mut buf: ~[u8] = ~[];
while !self.eof() { buf.push_all(self.read_bytes(2048u)); }
move buf
let mut bytes: ~[u8] = ~[];
while !self.eof() { bytes.push_all(self.read_bytes(2048u)); }
move bytes
}
fn each_byte(it: fn(int) -> bool) {
@ -226,8 +226,8 @@ fn convert_whence(whence: SeekStyle) -> i32 {
}
impl *libc::FILE: Reader {
fn read(buf: &[mut u8], len: uint) -> uint {
do vec::as_mut_buf(buf) |buf_p, buf_len| {
fn read(bytes: &[mut u8], len: uint) -> uint {
do vec::as_mut_buf(bytes) |buf_p, buf_len| {
assert buf_len <= len;
let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
@ -250,7 +250,9 @@ impl *libc::FILE: Reader {
// duration of its lifetime.
// FIXME there really should be a better way to do this // #2004
impl<T: Reader, C> {base: T, cleanup: C}: Reader {
fn read(buf: &[mut u8], len: uint) -> uint { self.base.read(buf, len) }
fn read(bytes: &[mut u8], len: uint) -> uint {
self.base.read(bytes, len)
}
fn read_byte() -> int { self.base.read_byte() }
fn unread_byte(byte: int) { self.base.unread_byte(byte); }
fn eof() -> bool { self.base.eof() }
@ -297,39 +299,41 @@ pub fn file_reader(path: &Path) -> Result<Reader, ~str> {
}
// Byte buffer readers
// Byte readers
pub struct BytesReader {
bytes: &[u8],
mut pos: uint
}
pub type ByteBuf = {buf: &[const u8], mut pos: uint};
impl BytesReader: Reader {
fn read(bytes: &[mut u8], len: uint) -> uint {
let count = uint::min(len, self.bytes.len() - self.pos);
impl ByteBuf: Reader {
fn read(buf: &[mut u8], len: uint) -> uint {
let count = uint::min(len, self.buf.len() - self.pos);
let view = vec::const_view(self.buf, self.pos, self.buf.len());
vec::bytes::memcpy(buf, view, count);
let view = vec::view(self.bytes, self.pos, self.bytes.len());
vec::bytes::memcpy(bytes, view, count);
self.pos += count;
count
}
fn read_byte() -> int {
if self.pos == self.buf.len() { return -1; }
let b = self.buf[self.pos];
if self.pos == self.bytes.len() { return -1; }
let b = self.bytes[self.pos];
self.pos += 1u;
return b as int;
}
// FIXME (#2738): implement this
fn unread_byte(_byte: int) { error!("Unimplemented: unread_byte"); fail; }
fn eof() -> bool { self.pos == self.buf.len() }
fn eof() -> bool { self.pos == self.bytes.len() }
fn seek(offset: int, whence: SeekStyle) {
let pos = self.pos;
self.pos = seek_in_buf(offset, pos, self.buf.len(), whence);
self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
}
fn tell() -> uint { self.pos }
}
pub fn with_bytes_reader<t>(bytes: &[u8], f: fn(Reader) -> t) -> t {
f({buf: bytes, mut pos: 0u} as Reader)
pub pure fn with_bytes_reader<t>(bytes: &[u8], f: fn(Reader) -> t) -> t {
f(BytesReader { bytes: bytes, pos: 0u } as Reader)
}
pub fn with_str_reader<T>(s: &str, f: fn(Reader) -> T) -> T {
@ -602,10 +606,10 @@ impl<T: Writer> T : WriterUtil {
self.write_str(&"\n");
}
fn write_int(n: int) {
int::to_str_bytes(n, 10u, |buf| self.write(buf))
int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
}
fn write_uint(n: uint) {
uint::to_str_bytes(false, n, 10u, |buf| self.write(buf))
uint::to_str_bytes(false, n, 10u, |bytes| self.write(bytes))
}
fn write_le_uint(n: uint) {
u64_to_le_bytes(n as u64, uint::bytes, |v| self.write(v))
@ -687,34 +691,34 @@ pub fn print(s: &str) { stdout().write_str(s); }
pub fn println(s: &str) { stdout().write_line(s); }
pub struct BytesWriter {
buf: DVec<u8>,
bytes: DVec<u8>,
mut pos: uint,
}
impl BytesWriter: Writer {
fn write(v: &[const u8]) {
do self.buf.swap |buf| {
let mut buf <- buf;
do self.bytes.swap |bytes| {
let mut bytes <- bytes;
let v_len = v.len();
let buf_len = buf.len();
let bytes_len = bytes.len();
let count = uint::max(buf_len, self.pos + v_len);
vec::reserve(&mut buf, count);
unsafe { vec::raw::set_len(&mut buf, count); }
let count = uint::max(bytes_len, self.pos + v_len);
vec::reserve(&mut bytes, count);
unsafe { vec::raw::set_len(&mut bytes, count); }
{
let view = vec::mut_view(buf, self.pos, count);
let view = vec::mut_view(bytes, self.pos, count);
vec::bytes::memcpy(view, v, v_len);
}
self.pos += v_len;
move buf
move bytes
}
}
fn seek(offset: int, whence: SeekStyle) {
let pos = self.pos;
let len = self.buf.len();
let len = self.bytes.len();
self.pos = seek_in_buf(offset, pos, len, whence);
}
fn tell() -> uint { self.pos }
@ -730,24 +734,28 @@ impl @BytesWriter : Writer {
fn get_type() -> WriterType { (*self).get_type() }
}
pub fn BytesWriter() -> BytesWriter {
BytesWriter { buf: DVec(), mut pos: 0u }
pub pure fn BytesWriter() -> BytesWriter {
BytesWriter { bytes: DVec(), mut pos: 0u }
}
pub fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
pub pure fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
let wr = @BytesWriter();
f(wr as Writer);
wr.buf.check_out(|buf| buf)
// FIXME (#3758): This should not be needed.
unsafe { wr.bytes.check_out(|bytes| move bytes) }
}
pub fn with_str_writer(f: fn(Writer)) -> ~str {
pub pure 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.
v.push(0);
// FIXME (#3758): This should not be needed.
unsafe {
// Make sure the vector has a trailing null and is proper utf8.
v.push(0);
}
assert str::is_utf8(v);
unsafe { move ::cast::transmute(v) }
unsafe { move ::cast::transmute(move v) }
}
// Utility functions
@ -975,15 +983,17 @@ mod tests {
fn bytes_buffer_overwrite() {
let wr = BytesWriter();
wr.write(~[0u8, 1u8, 2u8, 3u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 1u8, 2u8, 3u8]);
assert wr.bytes.borrow(|bytes| bytes == ~[0u8, 1u8, 2u8, 3u8]);
wr.seek(-2, SeekCur);
wr.write(~[4u8, 5u8, 6u8, 7u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
assert wr.bytes.borrow(|bytes| bytes ==
~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
wr.seek(-2, SeekEnd);
wr.write(~[8u8]);
wr.seek(1, SeekSet);
wr.write(~[9u8]);
assert wr.buf.borrow(|buf| buf == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
assert wr.bytes.borrow(|bytes| bytes ==
~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
}
}

View file

@ -11,7 +11,7 @@ pub type IMPL_T<A> = dlist::DList<A>;
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);
let nobe = option::get(link);
assert nobe.linked;
if !f(&nobe.data) { break; }
// Check (weakly) that the user didn't do a remove.

View file

@ -42,8 +42,6 @@
// Initial glob-exports mean that all the contents of all the modules
// wind up exported, if you're interested in writing platform-specific code.
// FIXME (#2006): change these to glob-exports when sufficiently supported.
pub use types::common::c95::*;
pub use types::common::c99::*;
pub use types::common::posix88::*;
@ -89,7 +87,7 @@ pub use funcs::extra::*;
pub use size_t;
pub use c_float, c_double, c_void, FILE, fpos_t;
pub use DIR, dirent;
pub use DIR, dirent_t;
pub use c_char, c_schar, c_uchar;
pub use c_short, c_ushort, c_int, c_uint, c_long, c_ulong;
pub use size_t, ptrdiff_t, clock_t, time_t;
@ -149,7 +147,7 @@ mod types {
}
pub mod posix88 {
pub enum DIR {}
pub enum dirent {}
pub enum dirent_t {}
}
pub mod posix01 {}
pub mod posix08 {}
@ -1021,7 +1019,7 @@ pub mod funcs {
pub extern mod dirent {
fn opendir(dirname: *c_char) -> *DIR;
fn closedir(dirp: *DIR) -> c_int;
fn readdir(dirp: *DIR) -> *dirent;
fn readdir(dirp: *DIR) -> *dirent_t;
fn rewinddir(dirp: *DIR);
fn seekdir(dirp: *DIR, loc: c_long);
fn telldir(dirp: *DIR) -> c_long;

View file

@ -32,7 +32,7 @@ pub fn console_off() {
#[cfg(notest)]
#[lang="log_type"]
pub fn log_type<T>(level: u32, object: &T) {
let bytes = do io::with_bytes_writer() |writer| {
let bytes = do io::with_bytes_writer |writer| {
repr::write_repr(writer, object);
};
unsafe {

View file

@ -24,7 +24,7 @@ struct Data<T> {
pub type Mut<T> = Data<T>;
pub fn Mut<T>(t: T) -> Mut<T> {
Data {value: t, mode: ReadOnly}
Data {value: move t, mode: ReadOnly}
}
pub fn unwrap<T>(m: Mut<T>) -> T {
@ -32,7 +32,7 @@ pub fn unwrap<T>(m: Mut<T>) -> T {
// is in use, as that would be a move from a borrowed value.
assert (m.mode as uint) == (ReadOnly as uint);
let Data {value: move value, mode: _} = move m;
return value;
move value
}
impl<T> Data<T> {

View file

@ -42,7 +42,7 @@ pub enum Option<T> {
Some(T),
}
pub 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
@ -58,7 +58,7 @@ pub pure fn get<T: Copy>(opt: &Option<T>) -> T {
case explicitly.
*/
match *opt {
match opt {
Some(copy x) => return x,
None => fail ~"option::get none"
}
@ -85,7 +85,7 @@ pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
}
}
pub 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
@ -94,7 +94,7 @@ pub pure fn expect<T: Copy>(opt: &Option<T>, reason: ~str) -> T {
*
* Fails if the value equals `none`
*/
match *opt { Some(copy x) => x, None => fail reason }
match opt { Some(copy x) => x, None => fail reason }
}
pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
@ -119,11 +119,9 @@ pub pure fn chain<T, U>(opt: Option<T>,
* function that returns an option.
*/
// XXX write with move match
if opt.is_some() {
f(unwrap(opt))
} else {
None
match move opt {
Some(move t) => f(move t),
None => None
}
}
@ -169,10 +167,10 @@ pub pure fn is_some<T>(opt: &Option<T>) -> bool {
!is_none(opt)
}
pub 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(copy x) => x, None => def }
match opt { Some(copy x) => x, None => def }
}
pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
@ -227,7 +225,7 @@ pub fn swap_unwrap<T>(opt: &mut Option<T>) -> 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(); }
if opt.is_none() { fail reason.to_owned(); }
unwrap(move opt)
}
@ -286,8 +284,8 @@ impl<T: Copy> Option<T> {
Instead, prefer to use pattern matching and handle the `None`
case explicitly.
*/
pure fn get() -> T { get(&self) }
pure fn get_default(def: T) -> T { get_default(&self, def) }
pure fn get() -> T { get(self) }
pure fn get_default(def: T) -> T { get_default(self, def) }
/**
* Gets the value out of an option, printing a specified message on
* failure
@ -296,7 +294,7 @@ 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, move 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) }
}
@ -326,8 +324,8 @@ impl<T: Eq> Option<T> : Eq {
fn test_unwrap_ptr() {
let x = ~0;
let addr_x = ptr::addr_of(&(*x));
let opt = Some(x);
let y = unwrap(opt);
let opt = Some(move x);
let y = unwrap(move opt);
let addr_y = ptr::addr_of(&(*y));
assert addr_x == addr_y;
}
@ -358,8 +356,8 @@ fn test_unwrap_resource() {
let i = @mut 0;
{
let x = R(i);
let opt = Some(x);
let _y = unwrap(opt);
let opt = Some(move x);
let _y = unwrap(move opt);
}
assert *i == 1;
}

View file

@ -473,7 +473,7 @@ pub fn tmpdir() -> Path {
#[cfg(unix)]
#[allow(non_implicitly_copyable_typarams)]
fn lookup() -> Path {
option::get_default(&getenv_nonempty("TMPDIR"),
option::get_default(getenv_nonempty("TMPDIR"),
Path("/tmp"))
}
@ -481,7 +481,7 @@ pub fn tmpdir() -> Path {
#[allow(non_implicitly_copyable_typarams)]
fn lookup() -> Path {
option::get_default(
&option::or(getenv_nonempty("TMP"),
option::or(getenv_nonempty("TMP"),
option::or(getenv_nonempty("TEMP"),
option::or(getenv_nonempty("USERPROFILE"),
getenv_nonempty("WINDIR")))),
@ -739,7 +739,7 @@ unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {
for uint::range(0, argc as uint) |i| {
vec::push(&mut args, str::raw::from_c_str(*argv.offset(i)));
}
return args;
move args
}
/**
@ -903,7 +903,7 @@ mod tests {
let rng: rand::Rng = rand::Rng();
let n = ~"TEST" + rng.gen_str(10u);
assert getenv(n).is_none();
n
move n
}
#[test]
@ -937,7 +937,7 @@ mod tests {
let n = make_rand_name();
setenv(n, s);
log(debug, s);
assert getenv(n) == option::Some(s);
assert getenv(n) == option::Some(move s);
}
#[test]
@ -963,7 +963,7 @@ mod tests {
// MingW seems to set some funky environment variables like
// "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
// from env() but not visible from getenv().
assert v2.is_none() || v2 == option::Some(v);
assert v2.is_none() || v2 == option::Some(move v);
}
}
@ -976,7 +976,7 @@ mod tests {
assert !vec::contains(e, &(copy n, ~"VALUE"));
e = env();
assert vec::contains(e, &(n, ~"VALUE"));
assert vec::contains(e, &(move n, ~"VALUE"));
}
#[test]

View file

@ -61,7 +61,7 @@ pub pure fn Path(s: &str) -> Path {
}
impl PosixPath : ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
let mut s = ~"";
if self.is_absolute {
s += "/";
@ -96,7 +96,7 @@ impl PosixPath : GenericPath {
let mut components = str::split_nonempty(s, |c| c == '/');
let is_absolute = (s.len() != 0 && s[0] == '/' as u8);
return PosixPath { is_absolute: is_absolute,
components: components }
components: move components }
}
pure fn dirname() -> ~str {
@ -192,7 +192,7 @@ impl PosixPath : GenericPath {
Some(ref f) => ~[copy *f]
};
return PosixPath { is_absolute: false,
components: cs }
components: move cs }
}
pure fn push_rel(other: &PosixPath) -> PosixPath {
@ -208,7 +208,8 @@ impl PosixPath : GenericPath {
|c| windows::is_sep(c as u8));
unsafe { v.push_all_move(move ss); }
}
PosixPath { components: move v, ..self }
PosixPath { is_absolute: self.is_absolute,
components: move v }
}
pure fn push(s: &str) -> PosixPath {
@ -223,20 +224,25 @@ impl PosixPath : GenericPath {
if cs.len() != 0 {
unsafe { cs.pop(); }
}
return PosixPath { components: move cs, ..self }
return PosixPath {
is_absolute: self.is_absolute,
components: move cs
}
//..self }
}
pure fn normalize() -> PosixPath {
return PosixPath {
components: normalize(self.components),
..self
is_absolute: self.is_absolute,
components: normalize(self.components)
// ..self
}
}
}
impl WindowsPath : ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
let mut s = ~"";
match self.host {
Some(ref h) => { s += "\\\\"; s += *h; }
@ -286,10 +292,10 @@ impl WindowsPath : GenericPath {
let mut components =
str::split_nonempty(rest, |c| windows::is_sep(c as u8));
let is_absolute = (rest.len() != 0 && windows::is_sep(rest[0]));
return WindowsPath { host: host,
device: device,
return WindowsPath { host: move host,
device: move device,
is_absolute: is_absolute,
components: components }
components: move components }
}
pure fn dirname() -> ~str {
@ -386,7 +392,7 @@ impl WindowsPath : GenericPath {
return WindowsPath { host: None,
device: None,
is_absolute: false,
components: cs }
components: move cs }
}
pure fn push_rel(other: &WindowsPath) -> WindowsPath {
@ -402,7 +408,13 @@ impl WindowsPath : GenericPath {
|c| windows::is_sep(c as u8));
unsafe { v.push_all_move(move ss); }
}
return WindowsPath { components: move v, ..self }
// tedious, but as-is, we can't use ..self
return WindowsPath {
host: copy self.host,
device: copy self.device,
is_absolute: self.is_absolute,
components: move v
}
}
pure fn push(s: &str) -> WindowsPath {
@ -417,13 +429,20 @@ impl WindowsPath : GenericPath {
if cs.len() != 0 {
unsafe { cs.pop(); }
}
return WindowsPath { components: move cs, ..self }
return WindowsPath {
host: copy self.host,
device: copy self.device,
is_absolute: self.is_absolute,
components: move cs
}
}
pure fn normalize() -> WindowsPath {
return WindowsPath {
components: normalize(self.components),
..self
host: copy self.host,
device: copy self.device,
is_absolute: self.is_absolute,
components: normalize(self.components)
}
}
}

View file

@ -350,7 +350,8 @@ fn BufferResource<T: Send>(b: ~Buffer<T>) -> BufferResource<T> {
atomic_add_acq(&mut b.header.ref_count, 1);
BufferResource {
buffer: b
// tjc: ????
buffer: move b
}
}
@ -448,7 +449,12 @@ pub fn try_recv<T: Send, Tbuffer: Send>(p: RecvPacketBuffered<T, Tbuffer>)
let this = rustrt::rust_get_task();
rustrt::task_clear_event_reject(this);
rustrt::rust_task_ref(this);
debug!("blocked = %x this = %x", p.header.blocked_task as uint,
this as uint);
let old_task = swap_task(&mut p.header.blocked_task, this);
debug!("blocked = %x this = %x old_task = %x",
p.header.blocked_task as uint,
this as uint, old_task as uint);
assert old_task.is_null();
let mut first = true;
let mut count = SPIN_COUNT;
@ -661,7 +667,7 @@ pub fn select2<A: Send, Ab: Send, B: Send, Bb: Send>(
-> Either<(Option<A>, RecvPacketBuffered<B, Bb>),
(RecvPacketBuffered<A, Ab>, Option<B>)>
{
let i = wait_many([a.header(), b.header()]/_);
let i = wait_many([a.header(), b.header()]);
match i {
0 => Left((try_recv(move a), move b)),
@ -687,7 +693,7 @@ pub fn selecti<T: Selectable>(endpoints: &[T]) -> uint {
/// Returns 0 or 1 depending on which endpoint is ready to receive
pub fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) ->
Either<(), ()> {
match wait_many([a.header(), b.header()]/_) {
match wait_many([a.header(), b.header()]) {
0 => Left(()),
1 => Right(()),
_ => fail ~"wait returned unexpected index"
@ -1212,7 +1218,7 @@ pub mod test {
c1.send(~"abc");
match (p1, p2).select() {
match (move p1, move p2).select() {
Right(_) => fail,
_ => ()
}
@ -1224,8 +1230,8 @@ pub mod test {
pub fn test_oneshot() {
let (c, p) = oneshot::init();
oneshot::client::send(c, ());
oneshot::client::send(move c, ());
recv_one(p)
recv_one(move p)
}
}

View file

@ -374,7 +374,7 @@ pub unsafe fn unwrap_shared_mutable_state<T: Send>(rc: SharedMutableState<T>)
rc.data = ptr::null();
// Step 1 - drop our own reference.
let new_count = rustrt::rust_atomic_decrement(&mut ptr.count);
assert new_count >= 0;
// assert new_count >= 0;
if new_count == 0 {
// We were the last owner. Can unwrap immediately.
// Also we have to free the server endpoints.
@ -505,7 +505,7 @@ pub struct Exclusive<T: Send> { x: SharedMutableState<ExData<T>> }
pub fn exclusive<T:Send >(user_data: T) -> Exclusive<T> {
let data = ExData {
lock: LittleLock(), mut failed: false, mut data: user_data
lock: LittleLock(), mut failed: false, mut data: move user_data
};
Exclusive { x: unsafe { shared_mutable_state(move data) } }
}
@ -544,7 +544,7 @@ impl<T: Send> Exclusive<T> {
}
}
// FIXME(#2585) make this a by-move method on the exclusive
// FIXME(#3724) make this a by-move method on the exclusive
pub fn unwrap_exclusive<T: Send>(arc: Exclusive<T>) -> T {
let Exclusive { x: x } <- arc;
let inner = unsafe { unwrap_shared_mutable_state(move x) };
@ -558,17 +558,17 @@ pub mod tests {
pub fn exclusive_arc() {
let mut futures = ~[];
let num_tasks = 10u;
let count = 10u;
let num_tasks = 10;
let count = 10;
let total = exclusive(~mut 0u);
let total = exclusive(~mut 0);
for uint::range(0u, num_tasks) |_i| {
for uint::range(0, num_tasks) |_i| {
let total = total.clone();
futures.push(future::spawn(|| {
for uint::range(0u, count) |_i| {
futures.push(future::spawn(|move total| {
for uint::range(0, count) |_i| {
do total.with |count| {
**count += 1u;
**count += 1;
}
}
}));
@ -587,7 +587,7 @@ pub mod tests {
// accesses will also fail.
let x = exclusive(1);
let x2 = x.clone();
do task::try {
do task::try |move x2| {
do x2.with |one| {
assert *one == 2;
}
@ -600,27 +600,28 @@ pub mod tests {
#[test]
pub fn exclusive_unwrap_basic() {
let x = exclusive(~~"hello");
assert unwrap_exclusive(x) == ~~"hello";
assert unwrap_exclusive(move x) == ~~"hello";
}
#[test]
pub fn exclusive_unwrap_contended() {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
do task::spawn {
do task::spawn |move x2| {
let x2 = option::swap_unwrap(x2);
do x2.with |_hello| { }
task::yield();
}
assert unwrap_exclusive(x) == ~~"hello";
assert unwrap_exclusive(move x) == ~~"hello";
// Now try the same thing, but with the child task blocking.
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
let mut res = None;
do task::task().future_result(|+r| res = Some(r)).spawn {
do task::task().future_result(|+r| res = Some(move r)).spawn
|move x2| {
let x2 = option::swap_unwrap(x2);
assert unwrap_exclusive(x2) == ~~"hello";
assert unwrap_exclusive(move x2) == ~~"hello";
}
// Have to get rid of our reference before blocking.
{ let _x = move x; } // FIXME(#3161) util::ignore doesn't work here
@ -633,11 +634,12 @@ pub mod tests {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
let mut res = None;
do task::task().future_result(|+r| res = Some(r)).spawn {
do task::task().future_result(|+r| res = Some(move r)).spawn
|move x2| {
let x2 = option::swap_unwrap(x2);
assert unwrap_exclusive(x2) == ~~"hello";
assert unwrap_exclusive(move x2) == ~~"hello";
}
assert unwrap_exclusive(x) == ~~"hello";
assert unwrap_exclusive(move x) == ~~"hello";
let res = option::swap_unwrap(&mut res);
future::get(&res);
}
@ -656,7 +658,7 @@ pub mod tests {
for 10.times { task::yield(); } // try to let the unwrapper go
fail; // punt it awake from its deadlock
}
let _z = unwrap_exclusive(x);
let _z = unwrap_exclusive(move x);
do x2.with |_hello| { }
};
assert result.is_err();

View file

@ -246,7 +246,7 @@ impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
}
fn visit_unboxed_vec(mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<vec::raw::UnboxedVecRepr>();
self.align_to::<vec::UnboxedVecRepr>();
if ! self.inner.visit_vec(mtbl, inner) { return false; }
true
}

View file

@ -15,7 +15,8 @@ use to_str::ToStr;
use cast::transmute;
use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
use reflect::{MovePtr, MovePtrAdaptor};
use vec::raw::{VecRepr, UnboxedVecRepr, SliceRepr};
use vec::UnboxedVecRepr;
use vec::raw::{VecRepr, SliceRepr};
pub use box::raw::BoxRepr;
use box::raw::BoxHeaderRepr;
@ -155,7 +156,7 @@ impl ReprVisitor {
fn visit_ptr_inner(ptr: *c_void, inner: *TyDesc) -> bool {
let mut u = ReprVisitor(ptr, self.writer);
let v = reflect::MovePtrAdaptor(move u);
visit_tydesc(inner, v as @TyVisitor);
visit_tydesc(inner, (move v) as @TyVisitor);
true
}
@ -303,7 +304,7 @@ impl ReprVisitor : TyVisitor {
fn visit_unboxed_vec(mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<vec::raw::UnboxedVecRepr> |b| {
do self.get::<vec::UnboxedVecRepr> |b| {
self.write_unboxed_vec_repr(mtbl, b, inner);
}
}
@ -452,7 +453,7 @@ pub fn write_repr2<T>(writer: @Writer, object: &T) {
let tydesc = intrinsic::get_tydesc::<T>();
let mut u = ReprVisitor(ptr, writer);
let v = reflect::MovePtrAdaptor(move u);
visit_tydesc(tydesc, v as @TyVisitor)
visit_tydesc(tydesc, (move v) as @TyVisitor)
}
#[test]
@ -558,7 +559,7 @@ impl ReprPrinter {
unsafe {
self.align(sys::min_align_of::<T>());
let value_addr: &T = transmute(copy self.ptr);
(*value_addr).write_repr(self.writer);
value_addr.write_repr(self.writer);
self.bump(sys::size_of::<T>());
true
}
@ -991,7 +992,7 @@ pub fn write_repr<T>(writer: @Writer, object: &T) {
unsafe {
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
let tydesc = sys::get_type_desc::<T>();
let tydesc = cast::transmute(tydesc);
let tydesc = cast::transmute(move tydesc);
let repr_printer = @ReprPrinter {
ptr: ptr,

View file

@ -105,11 +105,9 @@ pub pure fn to_either<T: Copy, U: Copy>(res: &Result<U, T>)
*/
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))
match move res {
Ok(move t) => op(move t),
Err(move e) => Err(e)
}
}

View file

@ -226,7 +226,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> Program {
fn ProgRes(r: ProgRepr) -> ProgRes {
ProgRes {
r: r
r: move r
}
}
@ -248,12 +248,14 @@ pub fn start_program(prog: &str, args: &[~str]) -> Program {
}
fn read_all(rd: io::Reader) -> ~str {
let mut buf = ~"";
while !rd.eof() {
let bytes = rd.read_bytes(4096u);
buf += str::from_bytes(bytes);
}
move buf
let buf = io::with_bytes_writer(|wr| {
let mut bytes = [mut 0, ..4096];
while !rd.eof() {
let nread = rd.read(bytes, bytes.len());
wr.write(bytes.view(0, nread));
}
});
str::from_bytes(buf)
}
/**
@ -313,10 +315,10 @@ pub fn program_output(prog: &str, args: &[~str]) ->
let stream = comm::recv(p);
match stream {
(1, copy s) => {
outs = s;
outs = move s;
}
(2, copy s) => {
errs = s;
errs = move s;
}
(n, _) => {
fail(fmt!("program_output received an unexpected file \
@ -341,13 +343,15 @@ fn writeclose(fd: c_int, s: ~str) {
fn readclose(fd: c_int) -> ~str {
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let mut buf = ~"";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
buf += str::from_bytes(bytes);
}
let buf = io::with_bytes_writer(|writer| {
let mut bytes = [mut 0, ..4096];
while !reader.eof() {
let nread = reader.read(bytes, bytes.len());
writer.write(bytes.view(0, nread));
}
});
os::fclose(file);
move buf
str::from_bytes(buf)
}
/// Waits for a process to exit and returns the exit code

View file

@ -17,6 +17,9 @@ pub trait SendMap<K:Eq Hash, V: Copy> {
fn insert(&mut self, k: K, +v: V) -> bool;
fn remove(&mut self, k: &K) -> bool;
fn pop(&mut self, k: &K) -> Option<V>;
fn swap(&mut self, k: K, +v: V) -> Option<V>;
fn consume(&mut self, f: fn(K, V));
fn clear(&mut self);
pure fn len(&const self) -> uint;
pure fn is_empty(&const self) -> bool;
@ -182,8 +185,8 @@ pub mod linear {
debug!("insert fresh (%?->%?) at idx %?, hash %?",
k, v, idx, hash);
self.buckets[idx] = Some(Bucket {hash: hash,
key: k,
value: v});
key: move k,
value: move v});
self.size += 1;
true
}
@ -191,13 +194,59 @@ pub mod linear {
debug!("insert overwrite (%?->%?) at idx %?, hash %?",
k, v, idx, hash);
self.buckets[idx] = Some(Bucket {hash: hash,
key: k,
value: v});
key: move k,
value: move v});
false
}
}
}
fn pop_internal(&mut self, hash: uint, k: &K) -> Option<V> {
// Removing from an open-addressed hashtable
// is, well, painful. The problem is that
// the entry may lie on the probe path for other
// entries, so removing it would make you think that
// those probe paths are empty.
//
// To address this we basically have to keep walking,
// re-inserting entries we find until we reach an empty
// bucket. We know we will eventually reach one because
// we insert one ourselves at the beginning (the removed
// entry).
//
// I found this explanation elucidating:
// http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf
let mut idx = match self.bucket_for_key_with_hash(self.buckets,
hash, k) {
TableFull | FoundHole(_) => return None,
FoundEntry(idx) => idx
};
let len_buckets = self.buckets.len();
let mut bucket = None;
self.buckets[idx] <-> bucket;
let value = match move bucket {
None => None,
Some(move bucket) => {
let Bucket { value: move value, _ } = move bucket;
Some(move value)
},
};
idx = self.next_bucket(idx, len_buckets);
while self.buckets[idx].is_some() {
let mut bucket = None;
bucket <-> self.buckets[idx];
self.insert_opt_bucket(move bucket);
idx = self.next_bucket(idx, len_buckets);
}
self.size -= 1;
move value
}
fn search(&self,
hash: uint,
op: fn(x: &Option<Bucket<K,V>>) -> bool) {
@ -222,37 +271,55 @@ pub mod linear {
}
fn remove(&mut self, k: &K) -> bool {
// Removing from an open-addressed hashtable
// is, well, painful. The problem is that
// the entry may lie on the probe path for other
// entries, so removing it would make you think that
// those probe paths are empty.
//
// To address this we basically have to keep walking,
// re-inserting entries we find until we reach an empty
// bucket. We know we will eventually reach one because
// we insert one ourselves at the beginning (the removed
// entry).
//
// I found this explanation elucidating:
// http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf
let mut idx = match self.bucket_for_key(self.buckets, k) {
TableFull | FoundHole(_) => return false,
FoundEntry(idx) => idx
};
let len_buckets = self.buckets.len();
self.buckets[idx] = None;
idx = self.next_bucket(idx, len_buckets);
while self.buckets[idx].is_some() {
let mut bucket = None;
bucket <-> self.buckets[idx];
self.insert_opt_bucket(move bucket);
idx = self.next_bucket(idx, len_buckets);
match self.pop(k) {
Some(_) => true,
None => false,
}
}
fn pop(&mut self, k: &K) -> Option<V> {
let hash = k.hash_keyed(self.k0, self.k1) as uint;
self.pop_internal(hash, k)
}
fn swap(&mut self, k: K, v: V) -> Option<V> {
// this could be faster.
let hash = k.hash_keyed(self.k0, self.k1) as uint;
let old_value = self.pop_internal(hash, &k);
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
// simply going to update a key in place. My sense
// though is that it's worse to have to search through
// buckets to find the right spot twice than to just
// resize in this corner case.
self.expand();
}
self.insert_internal(hash, move k, move v);
move old_value
}
fn consume(&mut self, f: fn(K, V)) {
let mut buckets = ~[];
self.buckets <-> buckets;
self.size = 0;
do vec::consume(move buckets) |_i, bucket| {
match move bucket {
None => { },
Some(move bucket) => {
let Bucket {
key: move key,
value: move value,
_
} = move bucket;
f(move key, move value)
}
}
}
self.size -= 1;
return true;
}
fn clear(&mut self) {
@ -350,7 +417,6 @@ pub mod linear {
}
option::unwrap(move value)
}
}
}
@ -407,6 +473,37 @@ pub mod test {
assert m.is_empty();
}
#[test]
pub fn pops() {
let mut m = ~LinearMap();
m.insert(1, 2);
assert m.pop(&1) == Some(2);
assert m.pop(&1) == None;
}
#[test]
pub fn swaps() {
let mut m = ~LinearMap();
assert m.swap(1, 2) == None;
assert m.swap(1, 3) == Some(2);
assert m.swap(1, 4) == Some(3);
}
#[test]
pub fn consumes() {
let mut m = ~LinearMap();
assert m.insert(1, 2);
assert m.insert(2, 3);
let mut m2 = ~LinearMap();
do m.consume |k, v| {
m2.insert(k, v);
}
assert m.len() == 0;
assert m2.len() == 2;
assert m2.find(&1) == Some(2);
assert m2.find(&2) == Some(3);
}
#[test]
pub fn iterate() {
let mut m = linear::linear_map_with_capacity(4);

View file

@ -49,7 +49,7 @@ pub pure fn from_byte(b: u8) -> ~str {
}
/// Appends a character at the end of a string
pub fn push_char(s: &const ~str, ch: char) {
pub fn push_char(s: &mut ~str, ch: char) {
unsafe {
let code = ch as uint;
let nb = if code < max_one_b { 1u }
@ -140,7 +140,7 @@ pub pure fn from_chars(chs: &[char]) -> ~str {
/// Appends a string slice to the back of a string, without overallocating
#[inline(always)]
pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) {
pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) {
unsafe {
let llen = lhs.len();
let rlen = rhs.len();
@ -157,7 +157,7 @@ pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) {
}
/// Appends a string slice to the back of a string
#[inline(always)]
pub fn push_str(lhs: &const ~str, rhs: &str) {
pub fn push_str(lhs: &mut ~str, rhs: &str) {
unsafe {
let llen = lhs.len();
let rlen = rhs.len();
@ -203,6 +203,13 @@ pub pure fn connect(v: &[~str], sep: &str) -> ~str {
move s
}
/// Given a string, make a new string with repeated copies of it
pub fn repeat(ss: &str, nn: uint) -> ~str {
let mut acc = ~"";
for nn.times { acc += ss; }
move acc
}
/*
Section: Adding to and removing from a string
*/
@ -214,7 +221,7 @@ Section: Adding to and removing from a string
*
* If the string does not contain any characters
*/
pub fn pop_char(s: &const ~str) -> char {
pub fn pop_char(s: &mut ~str) -> char {
let end = len(*s);
assert end > 0u;
let {ch, prev} = char_range_at_reverse(*s, end);
@ -573,6 +580,40 @@ pub pure fn words(s: &str) -> ~[~str] {
split_nonempty(s, |c| char::is_whitespace(c))
}
/** Split a string into a vector of substrings,
* each of which is less than a limit
*/
pub fn split_within(ss: &str, lim: uint) -> ~[~str] {
let words = str::words(ss);
// empty?
if words == ~[] { return ~[]; }
let mut rows : ~[~str] = ~[];
let mut row : ~str = ~"";
for words.each |wptr| {
let word = copy *wptr;
// if adding this word to the row would go over the limit,
// then start a new row
if row.len() + word.len() + 1 > lim {
rows.push(copy row); // save previous row
row = move word; // start a new one
} else {
if row.len() > 0 { row += ~" " } // separate words
row += word; // append to this row
}
}
// save the last row
if row != ~"" { rows.push(move row); }
move rows
}
/// Convert a string to lowercase. ASCII only
pub pure fn to_lower(s: &str) -> ~str {
map(s,
@ -1361,7 +1402,7 @@ pub pure fn is_whitespace(s: &str) -> bool {
*
* Alphanumeric characters are determined by `char::is_alphanumeric`
*/
fn is_alphanumeric(s: &str) -> bool {
pure fn is_alphanumeric(s: &str) -> bool {
return all(s, char::is_alphanumeric);
}
@ -1473,6 +1514,11 @@ pub pure fn from_utf16(v: &[u16]) -> ~str {
move buf
}
pub pure fn with_capacity(capacity: uint) -> ~str {
let mut buf = ~"";
unsafe { reserve(&mut buf, capacity); }
move buf
}
/**
* As char_len but for a slice of a string
@ -1802,9 +1848,9 @@ pub pure fn as_buf<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
* * s - A string
* * n - The number of bytes to reserve space for
*/
pub fn reserve(s: &const ~str, n: uint) {
pub fn reserve(s: &mut ~str, n: uint) {
unsafe {
let v: *mut ~[u8] = cast::transmute(copy s);
let v: *mut ~[u8] = cast::transmute(s);
vec::reserve(&mut *v, n + 1);
}
}
@ -1829,7 +1875,7 @@ pub fn reserve(s: &const ~str, n: uint) {
* * s - A string
* * n - The number of bytes to reserve space for
*/
pub fn reserve_at_least(s: &const ~str, n: uint) {
pub fn reserve_at_least(s: &mut ~str, n: uint) {
reserve(s, uint::next_power_of_two(n + 1u) - 1u)
}
@ -1906,7 +1952,7 @@ pub mod raw {
}
/// Converts a vector of bytes to a string.
pub pub unsafe fn from_bytes(v: &[const u8]) -> ~str {
pub unsafe fn from_bytes(v: &[const u8]) -> ~str {
do vec::as_const_buf(v) |buf, len| {
from_buf_len(buf, len)
}
@ -1974,7 +2020,7 @@ pub mod raw {
}
/// Appends a byte to a string. (Not UTF-8 safe).
pub unsafe fn push_byte(s: &const ~str, b: u8) {
pub unsafe fn push_byte(s: &mut ~str, b: u8) {
reserve_at_least(s, s.len() + 1);
do as_buf(*s) |buf, len| {
let buf: *mut u8 = ::cast::reinterpret_cast(&buf);
@ -1984,13 +2030,13 @@ pub mod raw {
}
/// Appends a vector of bytes to a string. (Not UTF-8 safe).
unsafe fn push_bytes(s: &const ~str, bytes: &[u8]) {
unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
reserve_at_least(s, s.len() + bytes.len());
for vec::each(bytes) |byte| { push_byte(s, *byte); }
}
/// Removes the last byte from a string and returns it. (Not UTF-8 safe).
pub unsafe fn pop_byte(s: &const ~str) -> u8 {
pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
let len = len(*s);
assert (len > 0u);
let b = s[len - 1u];
@ -2008,7 +2054,7 @@ pub mod raw {
}
/// Sets the length of the string and adds the null terminator
pub unsafe fn set_len(v: &const ~str, new_len: uint) {
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
let v: **vec::raw::VecRepr = cast::transmute(copy v);
let repr: *vec::raw::VecRepr = *v;
(*repr).unboxed.fill = new_len + 1u;
@ -2029,23 +2075,23 @@ pub mod raw {
}
pub trait UniqueStr {
fn trim() -> self;
fn trim_left() -> self;
fn trim_right() -> self;
pub trait Trimmable {
pure fn trim() -> self;
pure fn trim_left() -> self;
pure fn trim_right() -> self;
}
/// Extension methods for strings
impl ~str: UniqueStr {
impl ~str: Trimmable {
/// Returns a string with leading and trailing whitespace removed
#[inline]
fn trim() -> ~str { trim(self) }
pure fn trim() -> ~str { trim(self) }
/// Returns a string with leading whitespace removed
#[inline]
fn trim_left() -> ~str { trim_left(self) }
pure fn trim_left() -> ~str { trim_left(self) }
/// Returns a string with trailing whitespace removed
#[inline]
fn trim_right() -> ~str { trim_right(self) }
pure fn trim_right() -> ~str { trim_right(self) }
}
#[cfg(notest)]
@ -2062,31 +2108,35 @@ pub mod traits {
pub mod traits {}
pub trait StrSlice {
fn all(it: fn(char) -> bool) -> bool;
fn any(it: fn(char) -> bool) -> bool;
fn contains(needle: &a/str) -> bool;
fn contains_char(needle: char) -> bool;
fn each(it: fn(u8) -> bool);
fn eachi(it: fn(uint, u8) -> bool);
fn each_char(it: fn(char) -> bool);
fn each_chari(it: fn(uint, char) -> bool);
fn ends_with(needle: &str) -> bool;
fn is_empty() -> bool;
fn is_not_empty() -> bool;
fn is_whitespace() -> bool;
fn is_alphanumeric() -> bool;
pure fn all(it: fn(char) -> bool) -> bool;
pure fn any(it: fn(char) -> bool) -> bool;
pure fn contains(needle: &a/str) -> bool;
pure fn contains_char(needle: char) -> bool;
pure fn each(it: fn(u8) -> bool);
pure fn eachi(it: fn(uint, u8) -> bool);
pure fn each_char(it: fn(char) -> bool);
pure fn each_chari(it: fn(uint, char) -> bool);
pure fn ends_with(needle: &str) -> bool;
pure fn is_empty() -> bool;
pure fn is_not_empty() -> bool;
pure fn is_whitespace() -> bool;
pure fn is_alphanumeric() -> bool;
pure fn len() -> uint;
pure fn slice(begin: uint, end: uint) -> ~str;
fn split(sepfn: fn(char) -> bool) -> ~[~str];
fn split_char(sep: char) -> ~[~str];
fn split_str(sep: &a/str) -> ~[~str];
fn starts_with(needle: &a/str) -> bool;
fn substr(begin: uint, n: uint) -> ~str;
pure fn split(sepfn: fn(char) -> bool) -> ~[~str];
pure fn split_char(sep: char) -> ~[~str];
pure fn split_str(sep: &a/str) -> ~[~str];
pure fn starts_with(needle: &a/str) -> bool;
pure fn substr(begin: uint, n: uint) -> ~str;
pure fn to_lower() -> ~str;
pure fn to_upper() -> ~str;
fn escape_default() -> ~str;
fn escape_unicode() -> ~str;
pure fn to_unique() -> ~str;
pure fn escape_default() -> ~str;
pure fn escape_unicode() -> ~str;
pure fn trim() -> ~str;
pure fn trim_left() -> ~str;
pure fn trim_right() -> ~str;
pure fn to_owned() -> ~str;
pure fn to_managed() -> @str;
pure fn char_at(i: uint) -> char;
}
@ -2097,54 +2147,56 @@ impl &str: StrSlice {
* contains no characters
*/
#[inline]
fn all(it: fn(char) -> bool) -> bool { all(self, it) }
pure fn all(it: fn(char) -> bool) -> bool { all(self, it) }
/**
* Return true if a predicate matches any character (and false if it
* matches none or there are no characters)
*/
#[inline]
fn any(it: fn(char) -> bool) -> bool { any(self, it) }
pure fn any(it: fn(char) -> bool) -> bool { any(self, it) }
/// Returns true if one string contains another
#[inline]
fn contains(needle: &a/str) -> bool { contains(self, needle) }
pure fn contains(needle: &a/str) -> bool { contains(self, needle) }
/// Returns true if a string contains a char
#[inline]
fn contains_char(needle: char) -> bool { contains_char(self, needle) }
pure fn contains_char(needle: char) -> bool {
contains_char(self, needle)
}
/// Iterate over the bytes in a string
#[inline]
fn each(it: fn(u8) -> bool) { each(self, it) }
pure fn each(it: fn(u8) -> bool) { each(self, it) }
/// Iterate over the bytes in a string, with indices
#[inline]
fn eachi(it: fn(uint, u8) -> bool) { eachi(self, it) }
pure fn eachi(it: fn(uint, u8) -> bool) { eachi(self, it) }
/// Iterate over the chars in a string
#[inline]
fn each_char(it: fn(char) -> bool) { each_char(self, it) }
pure fn each_char(it: fn(char) -> bool) { each_char(self, it) }
/// Iterate over the chars in a string, with indices
#[inline]
fn each_chari(it: fn(uint, char) -> bool) { each_chari(self, it) }
pure fn each_chari(it: fn(uint, char) -> bool) { each_chari(self, it) }
/// Returns true if one string ends with another
#[inline]
fn ends_with(needle: &str) -> bool { ends_with(self, needle) }
pure fn ends_with(needle: &str) -> bool { ends_with(self, needle) }
/// Returns true if the string has length 0
#[inline]
fn is_empty() -> bool { is_empty(self) }
pure fn is_empty() -> bool { is_empty(self) }
/// Returns true if the string has length greater than 0
#[inline]
fn is_not_empty() -> bool { is_not_empty(self) }
pure fn is_not_empty() -> bool { is_not_empty(self) }
/**
* Returns true if the string contains only whitespace
*
* Whitespace characters are determined by `char::is_whitespace`
*/
#[inline]
fn is_whitespace() -> bool { is_whitespace(self) }
pure fn is_whitespace() -> bool { is_whitespace(self) }
/**
* Returns true if the string contains only alphanumerics
*
* Alphanumeric characters are determined by `char::is_alphanumeric`
*/
#[inline]
fn is_alphanumeric() -> bool { is_alphanumeric(self) }
pure fn is_alphanumeric() -> bool { is_alphanumeric(self) }
#[inline]
/// Returns the size in bytes not counting the null terminator
pure fn len() -> uint { len(self) }
@ -2159,21 +2211,21 @@ impl &str: StrSlice {
pure fn slice(begin: uint, end: uint) -> ~str { slice(self, begin, end) }
/// Splits a string into substrings using a character function
#[inline]
fn split(sepfn: fn(char) -> bool) -> ~[~str] { split(self, sepfn) }
pure fn split(sepfn: fn(char) -> bool) -> ~[~str] { split(self, sepfn) }
/**
* Splits a string into substrings at each occurrence of a given character
*/
#[inline]
fn split_char(sep: char) -> ~[~str] { split_char(self, sep) }
pure fn split_char(sep: char) -> ~[~str] { split_char(self, sep) }
/**
* Splits a string into a vector of the substrings separated by a given
* string
*/
#[inline]
fn split_str(sep: &a/str) -> ~[~str] { split_str(self, sep) }
pure fn split_str(sep: &a/str) -> ~[~str] { split_str(self, sep) }
/// Returns true if one string starts with another
#[inline]
fn starts_with(needle: &a/str) -> bool { starts_with(self, needle) }
pure fn starts_with(needle: &a/str) -> bool { starts_with(self, needle) }
/**
* Take a substring of another.
*
@ -2181,7 +2233,7 @@ impl &str: StrSlice {
* `begin`.
*/
#[inline]
fn substr(begin: uint, n: uint) -> ~str { substr(self, begin, n) }
pure fn substr(begin: uint, n: uint) -> ~str { substr(self, begin, n) }
/// Convert a string to lowercase
#[inline]
pure fn to_lower() -> ~str { to_lower(self) }
@ -2190,13 +2242,31 @@ impl &str: StrSlice {
pure fn to_upper() -> ~str { to_upper(self) }
/// Escape each char in `s` with char::escape_default.
#[inline]
fn escape_default() -> ~str { escape_default(self) }
pure fn escape_default() -> ~str { escape_default(self) }
/// Escape each char in `s` with char::escape_unicode.
#[inline]
fn escape_unicode() -> ~str { escape_unicode(self) }
pure fn escape_unicode() -> ~str { escape_unicode(self) }
/// Returns a string with leading and trailing whitespace removed
#[inline]
pure fn trim() -> ~str { trim(self) }
/// Returns a string with leading whitespace removed
#[inline]
pure fn trim_left() -> ~str { trim_left(self) }
/// Returns a string with trailing whitespace removed
#[inline]
pure fn trim_right() -> ~str { trim_right(self) }
#[inline]
pure fn to_unique() -> ~str { self.slice(0, self.len()) }
pure fn to_owned() -> ~str { self.slice(0, self.len()) }
#[inline]
pure fn to_managed() -> @str {
let v = at_vec::from_fn(self.len() + 1, |i| {
if i == self.len() { 0 } else { self[i] }
});
unsafe { ::cast::transmute(v) }
}
#[inline]
pure fn char_at(i: uint) -> char { char_at(self, i) }
@ -2450,6 +2520,19 @@ mod tests {
assert ~[] == words(~"");
}
#[test]
fn test_split_within() {
assert split_within(~"", 0) == ~[];
assert split_within(~"", 15) == ~[];
assert split_within(~"hello", 15) == ~[~"hello"];
let data = ~"\nMary had a little lamb\nLittle lamb\n";
error!("~~~~ %?", split_within(data, 15));
assert split_within(data, 15) == ~[~"Mary had a",
~"little lamb",
~"Little lamb"];
}
#[test]
fn test_find_str() {
// byte positions
@ -2525,6 +2608,15 @@ mod tests {
t(~[~"hi"], ~" ", ~"hi");
}
#[test]
fn test_repeat() {
assert repeat(~"x", 4) == ~"xxxx";
assert repeat(~"hi", 4) == ~"hihihihi";
assert repeat(~"ไท华", 3) == ~"ไท华ไท华ไท华";
assert repeat(~"", 4) == ~"";
assert repeat(~"hi", 0) == ~"";
}
#[test]
fn test_to_upper() {
// libc::toupper, and hence str::to_upper
@ -2547,23 +2639,23 @@ mod tests {
#[test]
fn test_unsafe_slice() {
unsafe {
assert ~"ab" == raw::slice_bytes(~"abc", 0u, 2u);
assert ~"bc" == raw::slice_bytes(~"abc", 1u, 3u);
assert ~"" == raw::slice_bytes(~"abc", 1u, 1u);
assert ~"ab" == raw::slice_bytes(~"abc", 0, 2);
assert ~"bc" == raw::slice_bytes(~"abc", 1, 3);
assert ~"" == raw::slice_bytes(~"abc", 1, 1);
fn a_million_letter_a() -> ~str {
let mut i = 0;
let mut rs = ~"";
while i < 100000 { push_str(&mut rs, ~"aaaaaaaaaa"); i += 1; }
return rs;
move rs
}
fn half_a_million_letter_a() -> ~str {
let mut i = 0;
let mut rs = ~"";
while i < 100000 { push_str(&mut rs, ~"aaaaa"); i += 1; }
return rs;
move rs
}
assert half_a_million_letter_a() ==
raw::slice_bytes(a_million_letter_a(), 0u, 500000u);
raw::slice_bytes(a_million_letter_a(), 0u, 500000);
}
}
@ -2649,16 +2741,16 @@ mod tests {
#[test]
fn test_slice() {
assert ~"ab" == slice(~"abc", 0u, 2u);
assert ~"bc" == slice(~"abc", 1u, 3u);
assert ~"" == slice(~"abc", 1u, 1u);
assert ~"\u65e5" == slice(~"\u65e5\u672c", 0u, 3u);
assert ~"ab" == slice(~"abc", 0, 2);
assert ~"bc" == slice(~"abc", 1, 3);
assert ~"" == slice(~"abc", 1, 1);
assert ~"\u65e5" == slice(~"\u65e5\u672c", 0, 3);
let data = ~"ประเทศไทย中华";
assert ~"" == slice(data, 0u, 3u);
assert ~"" == slice(data, 3u, 6u);
assert ~"" == slice(data, 3u, 3u);
assert ~"" == slice(data, 30u, 33u);
assert ~"" == slice(data, 0, 3);
assert ~"" == slice(data, 3, 6);
assert ~"" == slice(data, 3, 3);
assert ~"" == slice(data, 30, 33);
fn a_million_letter_X() -> ~str {
let mut i = 0;
@ -2667,13 +2759,13 @@ mod tests {
push_str(&mut rs, ~"华华华华华华华华华华");
i += 1;
}
return rs;
move rs
}
fn half_a_million_letter_X() -> ~str {
let mut i = 0;
let mut rs = ~"";
while i < 100000 { push_str(&mut rs, ~"华华华华华"); i += 1; }
return rs;
move rs
}
assert half_a_million_letter_X() ==
slice(a_million_letter_X(), 0u, 3u * 500000u);
@ -3175,4 +3267,10 @@ mod tests {
assert escape_default(~"\U0001d4ea\r") == ~"\\U0001d4ea\\r";
}
#[test]
fn test_to_managed() {
assert (~"abc").to_managed() == @"abc";
assert view("abcdef", 1, 5).to_managed() == @"bcde";
}
}

View file

@ -153,7 +153,7 @@ pub mod tests {
assert f(20) == 30;
let original_closure: Closure = cast::transmute(f);
let original_closure: Closure = cast::transmute(move f);
let actual_function_pointer = original_closure.code;
let environment = original_closure.env;
@ -163,7 +163,7 @@ pub mod tests {
env: environment
};
let new_f: fn(int) -> int = cast::transmute(new_closure);
let new_f: fn(int) -> int = cast::transmute(move new_closure);
assert new_f(20) == 30;
}
}

View file

@ -217,7 +217,7 @@ pub type TaskOpts = {
// sidestep that whole issue by making builders uncopyable and making
// the run function move them in.
// FIXME (#2585): Replace the 'consumed' bit with move mode on self
// FIXME (#3724): Replace the 'consumed' bit with move mode on self
pub enum TaskBuilder = {
opts: TaskOpts,
gen_body: fn@(v: fn~()) -> fn~(),
@ -349,7 +349,7 @@ impl TaskBuilder {
* Fails if a future_result was already set for this task.
*/
fn future_result(blk: fn(v: future::Future<TaskResult>)) -> TaskBuilder {
// FIXME (#1087, #1857): Once linked failure and notification are
// FIXME (#3725): 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
// sending out messages.
@ -424,7 +424,11 @@ impl TaskBuilder {
mut notify_chan: move notify_chan,
sched: self.opts.sched
},
gen_body: |body| { wrapper(prev_gen_body(move body)) },
// tjc: I think this is the line that gets miscompiled
// w/ last-use off, if we leave out the move prev_gen_body?
// that makes no sense, though...
gen_body: |move prev_gen_body,
body| { wrapper(prev_gen_body(move body)) },
can_not_copy: None,
.. *self.consume()
})
@ -758,9 +762,9 @@ pub unsafe fn atomically<U>(f: fn() -> U) -> U {
fn test_cant_dup_task_builder() {
let b = task().unlinked();
do b.spawn { }
// FIXME(#2585): For now, this is a -runtime- failure, because we haven't
// got modes on self. When 2585 is fixed, this test should fail to compile
// instead, and should go in tests/compile-fail.
// FIXME(#3724): For now, this is a -runtime- failure, because we haven't
// got move mode on self. When 3724 is fixed, this test should fail to
// compile instead, and should go in tests/compile-fail.
do b.spawn { } // b should have been consumed by the previous call
}
@ -931,7 +935,7 @@ fn test_add_wrapper() {
let ch = comm::Chan(&po);
let b0 = task();
let b1 = do b0.add_wrapper |body| {
fn~() {
fn~(move body) {
body();
comm::send(ch, ());
}
@ -944,14 +948,15 @@ fn test_add_wrapper() {
#[ignore(cfg(windows))]
fn test_future_result() {
let mut result = None;
do task().future_result(|+r| { result = Some(r); }).spawn { }
assert future::get(&option::unwrap(result)) == Success;
do task().future_result(|+r| { result = Some(move r); }).spawn { }
assert future::get(&option::unwrap(move result)) == Success;
result = None;
do task().future_result(|+r| { result = Some(r); }).unlinked().spawn {
do task().future_result(|+r|
{ result = Some(move r); }).unlinked().spawn {
fail;
}
assert future::get(&option::unwrap(result)) == Failure;
assert future::get(&option::unwrap(move result)) == Failure;
}
#[test] #[should_fail] #[ignore(cfg(windows))]
@ -981,7 +986,7 @@ fn test_spawn_conversation() {
let (recv_str, send_int) = do spawn_conversation |recv_int, send_str| {
let input = comm::recv(recv_int);
let output = int::str(input);
comm::send(send_str, output);
comm::send(send_str, move output);
};
comm::send(send_int, 1);
assert comm::recv(recv_str) == ~"1";
@ -1134,7 +1139,7 @@ fn avoid_copying_the_body(spawnfn: fn(v: fn~())) {
let x = ~1;
let x_in_parent = ptr::addr_of(&(*x)) as uint;
do spawnfn {
do spawnfn |move x| {
let x_in_child = ptr::addr_of(&(*x)) as uint;
comm::send(ch, x_in_child);
}
@ -1160,7 +1165,7 @@ fn test_avoid_copying_the_body_spawn_listener() {
#[test]
fn test_avoid_copying_the_body_task_spawn() {
do avoid_copying_the_body |f| {
do task().spawn {
do task().spawn |move f| {
f();
}
}
@ -1178,7 +1183,7 @@ fn test_avoid_copying_the_body_spawn_listener_1() {
#[test]
fn test_avoid_copying_the_body_try() {
do avoid_copying_the_body |f| {
do try {
do try |move f| {
f()
};
}
@ -1187,7 +1192,7 @@ fn test_avoid_copying_the_body_try() {
#[test]
fn test_avoid_copying_the_body_unlinked() {
do avoid_copying_the_body |f| {
do spawn_unlinked {
do spawn_unlinked |move f| {
f();
}
}
@ -1212,7 +1217,7 @@ fn test_unkillable() {
// We want to do this after failing
do spawn_unlinked {
for iter::repeat(10u) { yield() }
for iter::repeat(10) { yield() }
ch.send(());
}
@ -1226,12 +1231,12 @@ fn test_unkillable() {
unsafe {
do unkillable {
let p = ~0;
let pp: *uint = cast::transmute(p);
let pp: *uint = cast::transmute(move p);
// If we are killed here then the box will leak
po.recv();
let _p: ~int = cast::transmute(pp);
let _p: ~int = cast::transmute(move pp);
}
}
@ -1246,8 +1251,8 @@ fn test_unkillable_nested() {
let (ch, po) = pipes::stream();
// We want to do this after failing
do spawn_unlinked {
for iter::repeat(10u) { yield() }
do spawn_unlinked |move ch| {
for iter::repeat(10) { yield() }
ch.send(());
}
@ -1262,12 +1267,12 @@ fn test_unkillable_nested() {
do unkillable {
do unkillable {} // Here's the difference from the previous test.
let p = ~0;
let pp: *uint = cast::transmute(p);
let pp: *uint = cast::transmute(move p);
// If we are killed here then the box will leak
po.recv();
let _p: ~int = cast::transmute(pp);
let _p: ~int = cast::transmute(move pp);
}
}
@ -1311,7 +1316,7 @@ fn test_child_doesnt_ref_parent() {
fn test_sched_thread_per_core() {
let (chan, port) = pipes::stream();
do spawn_sched(ThreadPerCore) {
do spawn_sched(ThreadPerCore) |move chan| {
let cores = rt::rust_num_threads();
let reported_threads = rt::rust_sched_threads();
assert(cores as uint == reported_threads as uint);
@ -1325,7 +1330,7 @@ fn test_sched_thread_per_core() {
fn test_spawn_thread_on_demand() {
let (chan, port) = pipes::stream();
do spawn_sched(ManualThreads(2)) {
do spawn_sched(ManualThreads(2)) |move chan| {
let max_threads = rt::rust_sched_threads();
assert(max_threads as int == 2);
let running_threads = rt::rust_sched_current_nonlazy_threads();
@ -1333,7 +1338,7 @@ fn test_spawn_thread_on_demand() {
let (chan2, port2) = pipes::stream();
do spawn() {
do spawn() |move chan2| {
chan2.send(());
}

View file

@ -312,8 +312,8 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
TCB {
me: me,
tasks: tasks,
ancestors: ancestors,
tasks: move tasks,
ancestors: move ancestors,
is_main: is_main,
notifier: move notifier
}
@ -330,7 +330,7 @@ struct AutoNotify {
fn AutoNotify(chan: Chan<Notification>) -> AutoNotify {
AutoNotify {
notify_chan: chan,
notify_chan: move chan,
failed: true // Un-set above when taskgroup successfully made.
}
}
@ -652,7 +652,7 @@ fn test_spawn_raw_unsupervise() {
mut notify_chan: None,
.. default_task_opts()
};
do spawn_raw(opts) {
do spawn_raw(move opts) {
fail;
}
}
@ -667,7 +667,7 @@ fn test_spawn_raw_notify_success() {
notify_chan: Some(move notify_ch),
.. default_task_opts()
};
do spawn_raw(opts) |move task_ch| {
do spawn_raw(move opts) |move task_ch| {
task_ch.send(get_task());
}
let task_ = task_po.recv();
@ -683,10 +683,10 @@ fn test_spawn_raw_notify_failure() {
let opts = {
linked: false,
notify_chan: Some(notify_ch),
notify_chan: Some(move notify_ch),
.. default_task_opts()
};
do spawn_raw(opts) {
do spawn_raw(move opts) |move task_ch| {
task_ch.send(get_task());
fail;
}

View file

@ -8,80 +8,82 @@ The `ToStr` trait for converting to strings
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
pub trait ToStr { fn to_str() -> ~str; }
pub trait ToStr { pure fn to_str() -> ~str; }
impl int: ToStr {
fn to_str() -> ~str { int::str(self) }
pure fn to_str() -> ~str { int::str(self) }
}
impl i8: ToStr {
fn to_str() -> ~str { i8::str(self) }
pure fn to_str() -> ~str { i8::str(self) }
}
impl i16: ToStr {
fn to_str() -> ~str { i16::str(self) }
pure fn to_str() -> ~str { i16::str(self) }
}
impl i32: ToStr {
fn to_str() -> ~str { i32::str(self) }
pure fn to_str() -> ~str { i32::str(self) }
}
impl i64: ToStr {
fn to_str() -> ~str { i64::str(self) }
pure fn to_str() -> ~str { i64::str(self) }
}
impl uint: ToStr {
fn to_str() -> ~str { uint::str(self) }
pure fn to_str() -> ~str { uint::str(self) }
}
impl u8: ToStr {
fn to_str() -> ~str { u8::str(self) }
pure fn to_str() -> ~str { u8::str(self) }
}
impl u16: ToStr {
fn to_str() -> ~str { u16::str(self) }
pure fn to_str() -> ~str { u16::str(self) }
}
impl u32: ToStr {
fn to_str() -> ~str { u32::str(self) }
pure fn to_str() -> ~str { u32::str(self) }
}
impl u64: ToStr {
fn to_str() -> ~str { u64::str(self) }
pure fn to_str() -> ~str { u64::str(self) }
}
impl float: ToStr {
fn to_str() -> ~str { float::to_str(self, 4u) }
pure fn to_str() -> ~str { float::to_str(self, 4u) }
}
impl f32: ToStr {
fn to_str() -> ~str { float::to_str(self as float, 4u) }
pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
}
impl f64: ToStr {
fn to_str() -> ~str { float::to_str(self as float, 4u) }
pure fn to_str() -> ~str { float::to_str(self as float, 4u) }
}
impl bool: ToStr {
fn to_str() -> ~str { bool::to_str(self) }
pure fn to_str() -> ~str { bool::to_str(self) }
}
impl (): ToStr {
fn to_str() -> ~str { ~"()" }
pure fn to_str() -> ~str { ~"()" }
}
impl ~str: ToStr {
fn to_str() -> ~str { copy self }
pure fn to_str() -> ~str { copy self }
}
impl &str: ToStr {
fn to_str() -> ~str { str::from_slice(self) }
pure fn to_str() -> ~str { str::from_slice(self) }
}
impl @str: ToStr {
fn to_str() -> ~str { str::from_slice(self) }
pure fn to_str() -> ~str { str::from_slice(self) }
}
impl<A: ToStr Copy, B: ToStr Copy> (A, B): ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
let (a, b) = self;
~"(" + a.to_str() + ~", " + b.to_str() + ~")"
}
}
impl<A: ToStr Copy, B: ToStr Copy, C: ToStr Copy> (A, B, C): ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
let (a, b, c) = self;
~"(" + a.to_str() + ~", " + b.to_str() + ~", " + c.to_str() + ~")"
}
}
impl<A: ToStr> ~[A]: ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str unsafe {
// Bleh -- not really unsafe
// push_str and push_char
let mut acc = ~"[", first = true;
for vec::each(self) |elt| {
for vec::each(self) |elt| unsafe {
if first { first = false; }
else { str::push_str(&mut acc, ~", "); }
str::push_str(&mut acc, elt.to_str());
@ -92,10 +94,10 @@ impl<A: ToStr> ~[A]: ToStr {
}
impl<A: ToStr> @A: ToStr {
fn to_str() -> ~str { ~"@" + (*self).to_str() }
pure fn to_str() -> ~str { ~"@" + (*self).to_str() }
}
impl<A: ToStr> ~A: ToStr {
fn to_str() -> ~str { ~"~" + (*self).to_str() }
pure fn to_str() -> ~str { ~"~" + (*self).to_str() }
}
#[cfg(test)]

View file

@ -6,13 +6,13 @@
use cmp::{Eq, Ord};
pub trait TupleOps<T,U> {
pub trait CopyableTuple<T, U> {
pure fn first() -> T;
pure fn second() -> U;
pure fn swap() -> (U, T);
}
impl<T: Copy, U: Copy> (T, U): TupleOps<T,U> {
impl<T: Copy, U: Copy> (T, U): CopyableTuple<T, U> {
/// Return the first element of self
pure fn first() -> T {
@ -34,6 +34,24 @@ impl<T: Copy, U: Copy> (T, U): TupleOps<T,U> {
}
pub trait ImmutableTuple<T, U> {
pure fn first_ref(&self) -> &self/T;
pure fn second_ref(&self) -> &self/U;
}
impl<T, U> (T, U): ImmutableTuple<T, U> {
pure fn first_ref(&self) -> &self/T {
match *self {
(ref t, _) => t,
}
}
pure fn second_ref(&self) -> &self/U {
match *self {
(_, ref u) => u,
}
}
}
pub trait ExtendedTupleOps<A,B> {
fn zip(&self) -> ~[(A, B)];
fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
@ -145,6 +163,13 @@ impl<A: Ord, B: Ord, C: Ord> (A, B, C) : Ord {
pure fn gt(other: &(A, B, C)) -> bool { (*other).lt(&self) }
}
#[test]
fn test_tuple_ref() {
let x = (~"foo", ~"bar");
assert x.first_ref() == &~"foo";
assert x.second_ref() == &~"bar";
}
#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_tuple() {

View file

@ -187,19 +187,7 @@ pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
// Enough room to hold any number in any radix.
// Worst case: 64-bit number, binary-radix, with
// a leading negative sign = 65 bytes.
let buf : [mut u8]/65 =
[mut
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,
0u8,0u8,0u8,0u8,0u8
]/65;
let buf : [mut u8 * 65] = [mut 0u8, ..65];
// FIXME (#2649): post-snapshot, you can do this without the raw
// pointers and unsafe bits, and the codegen will prove it's all
@ -232,7 +220,7 @@ pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
}
/// Convert to a string
pub fn str(i: T) -> ~str { return to_str(i, 10u); }
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }
#[test]
pub fn test_to_str() {

View file

@ -100,7 +100,7 @@ mod tests {
let x = ~[(5, false)];
//FIXME #3387 assert x.eq(id(copy x));
let y = copy x;
assert x.eq(&id(y));
assert x.eq(&id(move y));
}
#[test]
fn test_swap() {

View file

@ -340,15 +340,15 @@ pub fn splitn<T: Copy>(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] {
*/
pub fn rsplit<T: Copy>(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] {
let ln = len(v);
if (ln == 0u) { return ~[] }
if (ln == 0) { return ~[] }
let mut end = ln;
let mut result = ~[];
while end > 0u {
match rposition_between(v, 0u, end, f) {
while end > 0 {
match rposition_between(v, 0, end, f) {
None => break,
Some(i) => {
result.push(slice(v, i + 1u, end));
result.push(slice(v, i + 1, end));
end = i;
}
}
@ -416,7 +416,7 @@ pub fn shift<T>(v: &mut ~[T]) -> T {
pub fn unshift<T>(v: &mut ~[T], x: T) {
let mut vv = ~[move x];
*v <-> vv;
v.push_all_move(vv);
v.push_all_move(move vv);
}
pub fn consume<T>(v: ~[T], f: fn(uint, v: T)) unsafe {
@ -433,7 +433,7 @@ pub fn consume<T>(v: ~[T], f: fn(uint, v: T)) unsafe {
}
pub fn consume_mut<T>(v: ~[mut T], f: fn(uint, v: T)) {
consume(vec::from_mut(v), f)
consume(vec::from_mut(move v), f)
}
/// Remove the last element from a vector and return it
@ -591,7 +591,7 @@ pub pure fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
#[inline(always)]
pure fn append_mut<T: Copy>(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] {
to_mut(append(from_mut(lhs), rhs))
to_mut(append(from_mut(move lhs), rhs))
}
/**
@ -1621,7 +1621,7 @@ impl<T> ~[T]: MutableVector<T> {
}
fn unshift(&mut self, x: T) {
unshift(self, x)
unshift(self, move x)
}
fn swap_remove(&mut self, index: uint) -> T {
@ -1657,9 +1657,29 @@ impl<T: Eq> ~[T]: MutableEqVector<T> {
}
}
/**
* Constructs a vector from an unsafe pointer to a buffer
*
* # Arguments
*
* * ptr - An unsafe pointer to a buffer of `T`
* * elts - The number of elements in the buffer
*/
// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
raw::from_buf_raw(ptr, elts)
}
/// The internal 'unboxed' representation of a vector
pub struct UnboxedVecRepr {
mut fill: uint,
mut alloc: uint,
data: u8
}
/// Unsafe operations
pub mod raw {
// FIXME: This should have crate visibility (#1893 blocks that)
mod raw {
/// The internal representation of a (boxed) vector
pub struct VecRepr {
@ -1667,34 +1687,11 @@ pub mod raw {
unboxed: UnboxedVecRepr
}
/// The internal 'unboxed' representation of a vector
pub struct UnboxedVecRepr {
mut fill: uint,
mut alloc: uint,
data: u8
}
pub type SliceRepr = {
mut data: *u8,
mut len: uint
};
/**
* Constructs a vector from an unsafe pointer to a buffer
*
* # Arguments
*
* * ptr - An unsafe pointer to a buffer of `T`
* * elts - The number of elements in the buffer
*/
#[inline(always)]
pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
let mut dst = with_capacity(elts);
set_len(&mut dst, elts);
as_mut_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts));
move dst
}
/**
* Sets the length of a vector
*
@ -1775,6 +1772,23 @@ pub mod raw {
}
}
/**
* Constructs a vector from an unsafe pointer to a buffer
*
* # Arguments
*
* * ptr - An unsafe pointer to a buffer of `T`
* * elts - The number of elements in the buffer
*/
// Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
#[inline(always)]
pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
let mut dst = with_capacity(elts);
set_len(&mut dst, elts);
as_mut_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts));
move dst
}
/**
* Copies data from one vector to another.
*
@ -1959,7 +1973,7 @@ mod tests {
// Test on-stack copy-from-buf.
let a = ~[1, 2, 3];
let mut ptr = raw::to_ptr(a);
let b = raw::from_buf(ptr, 3u);
let b = from_buf(ptr, 3u);
assert (len(b) == 3u);
assert (b[0] == 1);
assert (b[1] == 2);
@ -1968,7 +1982,7 @@ mod tests {
// Test on-heap copy-from-buf.
let c = ~[1, 2, 3, 4, 5];
ptr = raw::to_ptr(c);
let d = raw::from_buf(ptr, 5u);
let d = from_buf(ptr, 5u);
assert (len(d) == 5u);
assert (d[0] == 1);
assert (d[1] == 2);
@ -2194,7 +2208,7 @@ mod tests {
#[test]
fn test_dedup() {
fn case(a: ~[uint], b: ~[uint]) {
let mut v = a;
let mut v = move a;
v.dedup();
assert(v == b);
}
@ -2450,13 +2464,13 @@ mod tests {
let v1 = ~[1, 2, 3];
let v2 = ~[4, 5, 6];
let z1 = zip(v1, v2);
let z1 = zip(move v1, move v2);
assert ((1, 4) == z1[0]);
assert ((2, 5) == z1[1]);
assert ((3, 6) == z1[2]);
let (left, right) = unzip(z1);
let (left, right) = unzip(move z1);
assert ((1, 4) == (left[0], right[0]));
assert ((2, 5) == (left[1], right[1]));
@ -2754,7 +2768,7 @@ mod tests {
unsafe {
let x = ~[1, 2, 3];
let addr = raw::to_ptr(x);
let x_mut = to_mut(x);
let x_mut = to_mut(move x);
let addr_mut = raw::to_ptr(x_mut);
assert addr == addr_mut;
}
@ -2765,7 +2779,7 @@ mod tests {
unsafe {
let x = ~[mut 1, 2, 3];
let addr = raw::to_ptr(x);
let x_imm = from_mut(x);
let x_imm = from_mut(move x);
let addr_imm = raw::to_ptr(x_imm);
assert addr == addr_imm;
}
@ -2963,7 +2977,7 @@ mod tests {
fn test_consume_fail() {
let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
let mut i = 0;
do consume(v) |_i, _elt| {
do consume(move v) |_i, _elt| {
if i == 2 {
fail
}
@ -2977,7 +2991,7 @@ mod tests {
fn test_consume_mut_fail() {
let v = ~[mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)];
let mut i = 0;
do consume_mut(v) |_i, _elt| {
do consume_mut(move v) |_i, _elt| {
if i == 2 {
fail
}
@ -3020,7 +3034,7 @@ mod tests {
fn test_map_consume_fail() {
let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)];
let mut i = 0;
do map_consume(v) |_elt| {
do map_consume(move v) |_elt| {
if i == 2 {
fail
}

View file

@ -124,7 +124,7 @@ 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),
failed: false, data: user_data };
failed: false, data: move user_data };
MutexARC { x: unsafe { shared_mutable_state(move data) } }
}
@ -190,7 +190,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
// FIXME(#3724) make this a by-move method on the arc
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) };
@ -258,7 +258,7 @@ 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),
failed: false, data: user_data };
failed: false, data: move user_data };
RWARC { x: unsafe { shared_mutable_state(move data) }, cant_nest: () }
}
@ -368,7 +368,7 @@ impl<T: Const Send> &RWARC<T> {
* Will additionally fail if another task has failed while accessing the arc
* in write mode.
*/
// FIXME(#2585) make this a by-move method on the arc
// FIXME(#3724) make this a by-move method on the arc
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) };
@ -448,7 +448,7 @@ mod tests {
let (c, p) = pipes::stream();
do task::spawn() {
do task::spawn() |move c| {
let p = pipes::PortSet();
c.send(p.chan());
@ -471,8 +471,8 @@ mod tests {
let arc = ~MutexARC(false);
let arc2 = ~arc.clone();
let (c,p) = pipes::oneshot();
let (c,p) = (~mut Some(c), ~mut Some(p));
do task::spawn {
let (c,p) = (~mut Some(move c), ~mut Some(move p));
do task::spawn |move arc2, move p| {
// wait until parent gets in
pipes::recv_one(option::swap_unwrap(p));
do arc2.access_cond |state, cond| {
@ -494,7 +494,7 @@ mod tests {
let arc2 = ~arc.clone();
let (c,p) = pipes::stream();
do task::spawn_unlinked {
do task::spawn_unlinked |move arc2, move p| {
let _ = p.recv();
do arc2.access_cond |one, cond| {
cond.signal();
@ -513,7 +513,7 @@ mod tests {
fn test_mutex_arc_poison() {
let arc = ~MutexARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.access |one| {
assert *one == 2;
}
@ -527,21 +527,21 @@ mod tests {
let arc = MutexARC(1);
let arc2 = ~(&arc).clone();
let (c,p) = pipes::stream();
do task::spawn {
do task::spawn |move c, move arc2| {
do arc2.access |one| {
c.send(());
assert *one == 2;
}
}
let _ = p.recv();
let one = unwrap_mutex_arc(arc);
let one = unwrap_mutex_arc(move arc);
assert one == 1;
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_rw_arc_poison_wr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.write |one| {
assert *one == 2;
}
@ -554,7 +554,7 @@ mod tests {
fn test_rw_arc_poison_ww() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.write |one| {
assert *one == 2;
}
@ -567,7 +567,7 @@ mod tests {
fn test_rw_arc_poison_dw() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.write_downgrade |write_mode| {
do (&write_mode).write |one| {
assert *one == 2;
@ -582,7 +582,7 @@ mod tests {
fn test_rw_arc_no_poison_rr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.read |one| {
assert *one == 2;
}
@ -595,7 +595,7 @@ mod tests {
fn test_rw_arc_no_poison_rw() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.read |one| {
assert *one == 2;
}
@ -608,9 +608,9 @@ mod tests {
fn test_rw_arc_no_poison_dr() {
let arc = ~RWARC(1);
let arc2 = ~arc.clone();
do task::try {
do task::try |move arc2| {
do arc2.write_downgrade |write_mode| {
let read_mode = arc2.downgrade(write_mode);
let read_mode = arc2.downgrade(move write_mode);
do (&read_mode).read |one| {
assert *one == 2;
}
@ -626,7 +626,7 @@ mod tests {
let arc2 = ~arc.clone();
let (c,p) = pipes::stream();
do task::spawn {
do task::spawn |move arc2, move c| {
do arc2.write |num| {
for 10.times {
let tmp = *num;
@ -642,7 +642,8 @@ mod tests {
let mut children = ~[];
for 5.times {
let arc3 = ~arc.clone();
do task::task().future_result(|+r| children.push(r)).spawn {
do task::task().future_result(|+r| children.push(move r)).spawn
|move arc3| {
do arc3.read |num| {
assert *num >= 0;
}
@ -670,9 +671,9 @@ mod tests {
let mut reader_convos = ~[];
for 10.times {
let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream());
reader_convos.push((rc1,rp2));
reader_convos.push((move rc1, move rp2));
let arcn = ~arc.clone();
do task::spawn {
do task::spawn |move rp1, move rc2, move arcn| {
rp1.recv(); // wait for downgrader to give go-ahead
do arcn.read |state| {
assert *state == 31337;
@ -684,7 +685,7 @@ mod tests {
// Writer task
let arc2 = ~arc.clone();
let ((wc1,wp1),(wc2,wp2)) = (pipes::stream(),pipes::stream());
do task::spawn {
do task::spawn |move arc2, move wc2, move wp1| {
wp1.recv();
do arc2.write_cond |state, cond| {
assert *state == 0;
@ -717,7 +718,7 @@ mod tests {
}
}
}
let read_mode = arc.downgrade(write_mode);
let read_mode = arc.downgrade(move write_mode);
do (&read_mode).read |state| {
// complete handshake with other readers
for vec::each(reader_convos) |x| {

View file

@ -244,7 +244,7 @@ fn test_arena_destructors() {
do arena.alloc { @i };
// Allocate something with funny size and alignment, to keep
// things interesting.
do arena.alloc { [0u8, 1u8, 2u8]/3 };
do arena.alloc { [0u8, 1u8, 2u8] };
}
}
@ -258,7 +258,7 @@ fn test_arena_destructors_fail() {
do arena.alloc { @i };
// Allocate something with funny size and alignment, to keep
// things interesting.
do arena.alloc { [0u8, 1u8, 2u8]/3 };
do arena.alloc { [0u8, 1u8, 2u8] };
}
// Now, fail while allocating
do arena.alloc::<@int> {

View file

@ -96,7 +96,7 @@ struct BigBitv {
}
fn BigBitv(storage: ~[mut uint]) -> BigBitv {
BigBitv {storage: storage}
BigBitv {storage: move storage}
}
/**
@ -223,7 +223,7 @@ pub fn Bitv (nbits: uint, init: bool) -> Bitv {
let s = to_mut(from_elem(nelems, elem));
Big(~BigBitv(move s))
};
Bitv {rep: rep, nbits: nbits}
Bitv {rep: move rep, nbits: nbits}
}
priv impl Bitv {
@ -301,7 +301,7 @@ impl Bitv {
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]; };
Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})}
Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: move st})}
}
}
}

View file

@ -57,7 +57,7 @@ fn test_basic() {
let value = value_cell.take();
assert value == ~10;
assert value_cell.is_empty();
value_cell.put_back(value);
value_cell.put_back(move value);
assert !value_cell.is_empty();
}

View file

@ -52,12 +52,12 @@ pub fn DuplexStream<T: Send, U: Send>()
let (c2, p1) = pipes::stream();
let (c1, p2) = pipes::stream();
(DuplexStream {
chan: c1,
port: p1
chan: move c1,
port: move p1
},
DuplexStream {
chan: c2,
port: p2
chan: move c2,
port: move p2
})
}

View file

@ -1,21 +1,35 @@
#[forbid(deprecated_mode)];
use serialization;
// 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
use core::Option;
use option::{Some, None};
type EbmlTag = {id: uint, size: uint};
struct EbmlTag {
id: uint,
size: uint,
}
type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: 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
pub type Doc = {data: @~[u8], start: uint, end: uint};
struct Doc {
data: @~[u8],
start: uint,
end: uint,
}
type TaggedDoc = {tag: uint, doc: Doc};
struct TaggedDoc {
tag: uint,
doc: Doc,
}
impl Doc: ops::Index<uint,Doc> {
pure fn index(tag: uint) -> Doc {
@ -49,15 +63,17 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} {
}
pub fn Doc(data: @~[u8]) -> Doc {
return {data: data, start: 0u, end: vec::len::<u8>(*data)};
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;
return {tag: elt_tag.val,
doc: {data: data, start: elt_size.next, end: end}};
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> {
@ -67,19 +83,15 @@ pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
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
});
return Some(Doc { data: d.data, start: elt_size.next, end: pos });
}
}
return None::<Doc>;
None
}
pub fn get_doc(d: Doc, tg: uint) -> Doc {
match maybe_get_doc(d, tg) {
Some(d) => return d,
Some(d) => d,
None => {
error!("failed to find block with tag %u", tg);
fail;
@ -93,7 +105,8 @@ pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) {
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 !it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos}) {
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(elt_tag.val, doc) {
break;
}
}
@ -106,7 +119,8 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
let elt_size = vuint_at(*d.data, elt_tag.next);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
if !it({data: d.data, start: elt_size.next, end: pos}) {
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(doc) {
break;
}
}
@ -116,29 +130,29 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) {
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 {
return f(vec::view(*d.data, d.start, d.end));
f(vec::view(*d.data, d.start, d.end))
}
pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); }
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;
return (*d.data)[d.start];
(*d.data)[d.start]
}
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;
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;
return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32;
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;
return io::u64_from_be_bytes(*d.data, 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 }
@ -147,10 +161,9 @@ 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]};
pub enum Writer {
Writer_(Writer_)
struct Serializer {
writer: io::Writer,
priv mut size_positions: ~[uint],
}
fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
@ -173,13 +186,13 @@ fn write_vuint(w: io::Writer, n: uint) {
fail fmt!("vint to write too big: %?", n);
}
pub fn Writer(w: io::Writer) -> Writer {
pub fn Serializer(w: io::Writer) -> Serializer {
let size_positions: ~[uint] = ~[];
return Writer_({writer: w, mut size_positions: size_positions});
Serializer { writer: w, mut size_positions: size_positions }
}
// FIXME (#2741): Provide a function to write the standard ebml header.
impl Writer {
impl Serializer {
fn start_tag(tag_id: uint) {
debug!("Start tag %u", tag_id);
@ -295,12 +308,7 @@ enum EbmlSerializerTag {
EsLabel // Used only when debugging
}
trait SerializerPriv {
fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint);
fn _emit_label(label: &str);
}
impl ebml::Writer: SerializerPriv {
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;
@ -318,89 +326,123 @@ impl ebml::Writer: SerializerPriv {
}
}
impl ebml::Writer {
fn emit_opaque(f: fn()) {
impl Serializer {
fn emit_opaque(&self, f: fn()) {
do self.wr_tag(EsOpaque as uint) {
f()
}
}
}
impl ebml::Writer: serialization::Serializer {
fn emit_nil() {}
impl Serializer: serialization::Serializer {
fn emit_nil(&self) {}
fn emit_uint(v: uint) { self.wr_tagged_u64(EsUint as uint, v as u64); }
fn emit_u64(v: u64) { self.wr_tagged_u64(EsU64 as uint, v); }
fn emit_u32(v: u32) { self.wr_tagged_u32(EsU32 as uint, v); }
fn emit_u16(v: u16) { self.wr_tagged_u16(EsU16 as uint, v); }
fn emit_u8(v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); }
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(v: int) { self.wr_tagged_i64(EsInt as uint, v as i64); }
fn emit_i64(v: i64) { self.wr_tagged_i64(EsI64 as uint, v); }
fn emit_i32(v: i32) { self.wr_tagged_i32(EsI32 as uint, v); }
fn emit_i16(v: i16) { self.wr_tagged_i16(EsI16 as uint, v); }
fn emit_i8(v: i8) { self.wr_tagged_i8 (EsI8 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(v: bool) { self.wr_tagged_u8(EsBool as uint, v as u8) }
fn emit_bool(&self, v: bool) {
self.wr_tagged_u8(EsBool as uint, v as u8)
}
// FIXME (#2742): implement these
fn emit_f64(_v: f64) { fail ~"Unimplemented: serializing an f64"; }
fn emit_f32(_v: f32) { fail ~"Unimplemented: serializing an f32"; }
fn emit_float(_v: float) { fail ~"Unimplemented: serializing a float"; }
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_str(v: &str) { self.wr_tagged_str(EsStr as uint, v) }
fn emit_char(&self, _v: char) {
fail ~"Unimplemented: serializing a char";
}
fn emit_enum(name: &str, f: fn()) {
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(_v_name: &str, v_id: uint, _cnt: uint, f: fn()) {
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(_idx: uint, f: fn()) { f() }
fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
fn emit_vec(len: uint, f: fn()) {
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_vec_elt(_idx: uint, f: fn()) {
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_box(f: fn()) { f() }
fn emit_uniq(f: fn()) { f() }
fn emit_rec(f: fn()) { f() }
fn emit_rec_field(f_name: &str, _f_idx: uint, f: fn()) {
self._emit_label(f_name);
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(_sz: uint, f: fn()) { f() }
fn emit_tup_elt(_idx: uint, f: fn()) { f() }
fn emit_tup(&self, _len: uint, f: fn()) { f() }
fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
}
type EbmlDeserializer_ = {mut parent: ebml::Doc,
mut pos: uint};
pub enum EbmlDeserializer {
EbmlDeserializer_(EbmlDeserializer_)
struct Deserializer {
priv mut parent: Doc,
priv mut pos: uint,
}
pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer {
EbmlDeserializer_({mut parent: d, mut pos: d.start})
pub fn Deserializer(d: Doc) -> Deserializer {
Deserializer { mut parent: d, mut pos: d.start }
}
priv impl EbmlDeserializer {
priv impl Deserializer {
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);
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 = ebml::doc_as_str(r_doc);
let str = doc_as_str(r_doc);
if lbl != str {
fail fmt!("Expected label %s but found %s", lbl, str);
}
@ -408,13 +450,13 @@ priv impl EbmlDeserializer {
}
}
fn next_doc(exp_tag: EbmlSerializerTag) -> ebml::Doc {
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 {tag: r_tag, doc: r_doc} =
ebml::doc_at(self.parent.data, self.pos);
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);
@ -427,10 +469,10 @@ priv impl EbmlDeserializer {
r_doc.end, self.parent.end);
}
self.pos = r_doc.end;
return r_doc;
r_doc
}
fn push_doc<T>(d: ebml::Doc, f: fn() -> T) -> T{
fn push_doc<T>(d: Doc, f: fn() -> T) -> T{
let old_parent = self.parent;
let old_pos = self.pos;
self.parent = d;
@ -442,63 +484,76 @@ priv impl EbmlDeserializer {
}
fn _next_uint(exp_tag: EbmlSerializerTag) -> uint {
let r = ebml::doc_as_u32(self.next_doc(exp_tag));
let r = doc_as_u32(self.next_doc(exp_tag));
debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
return r as uint;
r as uint
}
}
impl EbmlDeserializer {
fn read_opaque<R>(op: fn(ebml::Doc) -> R) -> R {
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 EbmlDeserializer: serialization::Deserializer {
fn read_nil() -> () { () }
impl Deserializer: serialization::Deserializer {
fn read_nil(&self) -> () { () }
fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(EsU64)) }
fn read_u32() -> u32 { ebml::doc_as_u32(self.next_doc(EsU32)) }
fn read_u16() -> u16 { ebml::doc_as_u16(self.next_doc(EsU16)) }
fn read_u8 () -> u8 { ebml::doc_as_u8 (self.next_doc(EsU8 )) }
fn read_uint() -> uint {
let v = ebml::doc_as_u64(self.next_doc(EsUint));
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);
}
return v as uint;
v as uint
}
fn read_i64() -> i64 { ebml::doc_as_u64(self.next_doc(EsI64)) as i64 }
fn read_i32() -> i32 { ebml::doc_as_u32(self.next_doc(EsI32)) as i32 }
fn read_i16() -> i16 { ebml::doc_as_u16(self.next_doc(EsI16)) as i16 }
fn read_i8 () -> i8 { ebml::doc_as_u8 (self.next_doc(EsI8 )) as i8 }
fn read_int() -> int {
let v = ebml::doc_as_u64(self.next_doc(EsInt)) as i64;
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);
}
return v as int;
v as int
}
fn read_bool() -> bool { ebml::doc_as_u8(self.next_doc(EsBool)) as bool }
fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool }
fn read_f64() -> f64 { fail ~"read_f64()"; }
fn read_f32() -> f32 { fail ~"read_f32()"; }
fn read_float() -> float { fail ~"read_float()"; }
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_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) }
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_enum<T>(name: &str, f: fn() -> T) -> T {
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>(f: fn(uint) -> T) -> T {
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);
@ -507,13 +562,13 @@ impl EbmlDeserializer: serialization::Deserializer {
}
}
fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T {
fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
debug!("read_enum_variant_arg(idx=%u)", idx);
f()
}
fn read_vec<T>(f: fn(uint) -> T) -> T {
debug!("read_vec()");
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);
@ -521,104 +576,69 @@ impl EbmlDeserializer: serialization::Deserializer {
}
}
fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T {
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_box<T>(f: fn() -> T) -> T {
debug!("read_box()");
f()
}
fn read_uniq<T>(f: fn() -> T) -> T {
debug!("read_uniq()");
f()
}
fn read_rec<T>(f: fn() -> T) -> T {
fn read_rec<T>(&self, f: fn() -> T) -> T {
debug!("read_rec()");
f()
}
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);
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
debug!("read_struct(name=%s)", name);
f()
}
fn read_tup<T>(sz: uint, f: fn() -> T) -> T {
debug!("read_tup(sz=%u)", sz);
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_elt<T>(idx: uint, f: fn() -> T) -> T {
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
#[test]
fn test_option_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>) {
do s.emit_enum(~"core::option::t") {
match v {
None => s.emit_enum_variant(
~"core::option::None", 0u, 0u, || { } ),
Some(v0) => {
do s.emit_enum_variant(~"core::option::some", 1u, 1u) {
s.emit_enum_variant_arg(0u, || serialize_1(s, v0));
}
}
}
#[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 = serialization::deserialize(&deser);
debug!("v1 == %?", v1);
assert v == v1;
}
}
fn deserialize_1<S: serialization::Deserializer>(s: &S) -> int {
s.read_i64() as int
test_v(Some(22));
test_v(None);
test_v(Some(3));
}
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 {
0 => None,
1 => {
let v0 = do s.read_enum_variant_arg(0u) {
deserialize_1(s)
};
Some(v0)
}
_ => {
fail #fmt("deserialize_0: unexpected variant %u", i);
}
}
}
}
}
fn test_v(v: Option<int>) {
debug!("v == %?", v);
let bytes = do io::with_bytes_writer |wr| {
let ebml_w = ebml::Writer(wr);
serialize_0(&ebml_w, v);
};
let ebml_doc = ebml::Doc(@bytes);
let deser = ebml_deserializer(ebml_doc);
let v1 = deserialize_0(&deser);
debug!("v1 == %?", v1);
assert v == v1;
}
test_v(Some(22));
test_v(None);
test_v(Some(3));
}

View file

@ -1,644 +0,0 @@
#[forbid(deprecated_mode)];
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));
}
}

View file

@ -82,7 +82,7 @@ pub type Opt = {name: Name, hasarg: HasArg, occur: Occur};
fn mkname(nm: &str) -> Name {
let unm = str::from_slice(nm);
return if str::len(nm) == 1u {
return if nm.len() == 1u {
Short(str::char_at(unm, 0u))
} else { Long(unm) };
}
@ -114,6 +114,22 @@ impl Occur : Eq {
pure fn ne(other: &Occur) -> bool { !self.eq(other) }
}
impl HasArg : Eq {
pure fn eq(other: &HasArg) -> bool {
(self as uint) == ((*other) as uint)
}
pure fn ne(other: &HasArg) -> bool { !self.eq(other) }
}
impl Opt : Eq {
pure fn eq(other: &Opt) -> bool {
self.name == (*other).name &&
self.hasarg == (*other).hasarg &&
self.occur == (*other).occur
}
pure fn ne(other: &Opt) -> bool { !self.eq(other) }
}
/// Create an option that is required and takes an argument
pub fn reqopt(name: &str) -> Opt {
return {name: mkname(name), hasarg: Yes, occur: Req};
@ -150,8 +166,29 @@ enum Optval { Val(~str), Given, }
*/
pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]};
impl Optval : Eq {
pure fn eq(other: &Optval) -> bool {
match self {
Val(ref s) => match *other { Val (ref os) => s == os,
Given => false },
Given => match *other { Val(_) => false,
Given => true }
}
}
pure fn ne(other: &Optval) -> bool { !self.eq(other) }
}
impl Matches : Eq {
pure fn eq(other: &Matches) -> bool {
self.opts == (*other).opts &&
self.vals == (*other).vals &&
self.free == (*other).free
}
pure fn ne(other: &Matches) -> bool { !self.eq(other) }
}
fn is_arg(arg: &str) -> bool {
return str::len(arg) > 1u && arg[0] == '-' as u8;
return arg.len() > 1u && arg[0] == '-' as u8;
}
fn name_str(nm: &Name) -> ~str {
@ -177,6 +214,35 @@ pub enum Fail_ {
UnexpectedArgument(~str),
}
impl Fail_ : Eq {
// this whole thing should be easy to infer...
pure fn eq(other: &Fail_) -> bool {
match self {
ArgumentMissing(ref s) => {
match *other { ArgumentMissing(ref so) => s == so,
_ => false }
}
UnrecognizedOption(ref s) => {
match *other { UnrecognizedOption(ref so) => s == so,
_ => false }
}
OptionMissing(ref s) => {
match *other { OptionMissing(ref so) => s == so,
_ => false }
}
OptionDuplicated(ref s) => {
match *other { OptionDuplicated(ref so) => s == so,
_ => false }
}
UnexpectedArgument(ref s) => {
match *other { UnexpectedArgument(ref so) => s == so,
_ => false }
}
}
}
pure fn ne(other: &Fail_) -> bool { !self.eq(other) }
}
/// Convert a `fail_` enum into an error string
pub fn fail_str(f: Fail_) -> ~str {
return match f {
@ -220,7 +286,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe {
let mut i = 0u;
while i < l {
let cur = args[i];
let curlen = str::len(cur);
let curlen = cur.len();
if !is_arg(cur) {
free.push(cur);
} else if cur == ~"--" {
@ -444,6 +510,194 @@ impl FailType : Eq {
pure fn ne(other: &FailType) -> bool { !self.eq(other) }
}
/** A module which provides a way to specify descriptions and
* groups of short and long option names, together.
*/
pub mod groups {
/** one group of options, e.g., both -h and --help, along with
* their shared description and properties
*/
pub type OptGroup = {
short_name: ~str,
long_name: ~str,
hint: ~str,
desc: ~str,
hasarg: HasArg,
occur: Occur
};
impl OptGroup : Eq {
pure fn eq(other: &OptGroup) -> bool {
self.short_name == (*other).short_name &&
self.long_name == (*other).long_name &&
self.hint == (*other).hint &&
self.desc == (*other).desc &&
self.hasarg == (*other).hasarg &&
self.occur == (*other).occur
}
pure fn ne(other: &OptGroup) -> bool { !self.eq(other) }
}
/// Create a long option that is required and takes an argument
pub fn reqopt(short_name: &str, long_name: &str,
desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert len == 1 || len == 0;
return {short_name: str::from_slice(short_name),
long_name: str::from_slice(long_name),
hint: str::from_slice(hint),
desc: str::from_slice(desc),
hasarg: Yes,
occur: Req};
}
/// Create a long option that is optional and takes an argument
pub fn optopt(short_name: &str, long_name: &str,
desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert len == 1 || len == 0;
return {short_name: str::from_slice(short_name),
long_name: str::from_slice(long_name),
hint: str::from_slice(hint),
desc: str::from_slice(desc),
hasarg: Yes,
occur: Optional};
}
/// Create a long option that is optional and does not take an argument
pub fn optflag(short_name: &str, long_name: &str,
desc: &str) -> OptGroup {
let len = short_name.len();
assert len == 1 || len == 0;
return {short_name: str::from_slice(short_name),
long_name: str::from_slice(long_name),
hint: ~"",
desc: str::from_slice(desc),
hasarg: No,
occur: Optional};
}
/// Create a long option that is optional and takes an optional argument
pub fn optflagopt(short_name: &str, long_name: &str,
desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert len == 1 || len == 0;
return {short_name: str::from_slice(short_name),
long_name: str::from_slice(long_name),
hint: str::from_slice(hint),
desc: str::from_slice(desc),
hasarg: Maybe,
occur: Optional};
}
/**
* Create a long option that is optional, takes an argument, and may occur
* multiple times
*/
pub fn optmulti(short_name: &str, long_name: &str,
desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert len == 1 || len == 0;
return {short_name: str::from_slice(short_name),
long_name: str::from_slice(long_name),
hint: str::from_slice(hint),
desc: str::from_slice(desc),
hasarg: Yes,
occur: Multi};
}
// translate OptGroup into Opt
// (both short and long names correspond to different Opts)
pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] {
match ((*lopt).short_name.len(),
(*lopt).long_name.len()) {
(0,0) => fail ~"this long-format option was given no name",
(0,_) => ~[{name: Long(((*lopt).long_name)),
hasarg: (*lopt).hasarg,
occur: (*lopt).occur}],
(1,0) => ~[{name: Short(str::char_at((*lopt).short_name, 0)),
hasarg: (*lopt).hasarg,
occur: (*lopt).occur}],
(1,_) => ~[{name: Short(str::char_at((*lopt).short_name, 0)),
hasarg: (*lopt).hasarg,
occur: (*lopt).occur},
{name: Long(((*lopt).long_name)),
hasarg: (*lopt).hasarg,
occur: (*lopt).occur}],
(_,_) => fail ~"something is wrong with the long-form opt"
}
}
/*
* Parse command line args with the provided long format options
*/
pub fn getopts(args: &[~str], opts: &[OptGroup]) -> Result {
::getopts::getopts(args, vec::flat_map(opts, long_to_short))
}
/**
* Derive a usage message from a set of long options
*/
pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
let desc_sep = ~"\n" + str::repeat(~" ", 24);
let rows = vec::map(opts, |optref| {
let short_name = (*optref).short_name;
let long_name = (*optref).long_name;
let hint = (*optref).hint;
let desc = (*optref).desc;
let hasarg = (*optref).hasarg;
let mut row = str::repeat(~" ", 4);
// short option
row += match short_name.len() {
0 => ~"",
1 => ~"-" + short_name + " ",
_ => fail ~"the short name should only be 1 char long",
};
// long option
row += match long_name.len() {
0 => ~"",
_ => ~"--" + long_name + " ",
};
// arg
row += match hasarg {
No => ~"",
Yes => hint,
Maybe => ~"[" + hint + ~"]",
};
// here we just need to indent the start of the description
let rowlen = row.len();
row += if rowlen < 24 {
str::repeat(~" ", 24 - rowlen)
} else {
desc_sep
};
// wrapped description
row += str::connect(str::split_within(desc, 54), desc_sep);
row
});
return str::from_slice(brief) +
~"\n\nOptions:\n" +
str::connect(rows, ~"\n") +
~"\n\n";
}
} // end groups module
#[cfg(test)]
mod tests {
#[legacy_exports];
@ -943,6 +1197,158 @@ mod tests {
assert opts_present(matches, ~[~"L"]);
assert opts_str(matches, ~[~"L"]) == ~"foo";
}
#[test]
fn test_groups_reqopt() {
let opt = groups::reqopt(~"b", ~"banana", ~"some bananas", ~"VAL");
assert opt == { short_name: ~"b",
long_name: ~"banana",
hint: ~"VAL",
desc: ~"some bananas",
hasarg: Yes,
occur: Req }
}
#[test]
fn test_groups_optopt() {
let opt = groups::optopt(~"a", ~"apple", ~"some apples", ~"VAL");
assert opt == { short_name: ~"a",
long_name: ~"apple",
hint: ~"VAL",
desc: ~"some apples",
hasarg: Yes,
occur: Optional }
}
#[test]
fn test_groups_optflag() {
let opt = groups::optflag(~"k", ~"kiwi", ~"some kiwis");
assert opt == { short_name: ~"k",
long_name: ~"kiwi",
hint: ~"",
desc: ~"some kiwis",
hasarg: No,
occur: Optional }
}
#[test]
fn test_groups_optflagopt() {
let opt = groups::optflagopt(~"p", ~"pineapple",
~"some pineapples", ~"VAL");
assert opt == { short_name: ~"p",
long_name: ~"pineapple",
hint: ~"VAL",
desc: ~"some pineapples",
hasarg: Maybe,
occur: Optional }
}
#[test]
fn test_groups_optmulti() {
let opt = groups::optmulti(~"l", ~"lime",
~"some limes", ~"VAL");
assert opt == { short_name: ~"l",
long_name: ~"lime",
hint: ~"VAL",
desc: ~"some limes",
hasarg: Yes,
occur: Multi }
}
#[test]
fn test_groups_long_to_short() {
let short = ~[reqopt(~"b"), reqopt(~"banana")];
let verbose = groups::reqopt(~"b", ~"banana",
~"some bananas", ~"VAL");
assert groups::long_to_short(&verbose) == short;
}
#[test]
fn test_groups_getopts() {
let short = ~[
reqopt(~"b"), reqopt(~"banana"),
optopt(~"a"), optopt(~"apple"),
optflag(~"k"), optflagopt(~"kiwi"),
optflagopt(~"p"),
optmulti(~"l")
];
let verbose = ~[
groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
groups::optopt(~"a", ~"apple", ~"Desc", ~"VAL"),
groups::optflag(~"k", ~"kiwi", ~"Desc"),
groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
];
let sample_args = ~[~"-k", ~"15", ~"--apple", ~"1", ~"k",
~"-p", ~"16", ~"l", ~"35"];
// NOTE: we should sort before comparing
assert getopts(sample_args, short)
== groups::getopts(sample_args, verbose);
}
#[test]
fn test_groups_usage() {
let optgroups = ~[
groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
groups::optopt(~"a", ~"012345678901234567890123456789",
~"Desc", ~"VAL"),
groups::optflag(~"k", ~"kiwi", ~"Desc"),
groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
];
let expected =
~"Usage: fruits
Options:
-b --banana VAL Desc
-a --012345678901234567890123456789 VAL
Desc
-k --kiwi Desc
-p [VAL] Desc
-l VAL Desc
";
let generated_usage = groups::usage(~"Usage: fruits", optgroups);
debug!("expected: <<%s>>", expected);
debug!("generated: <<%s>>", generated_usage);
assert generated_usage == expected;
}
#[test]
fn test_groups_usage_description_wrapping() {
// indentation should be 24 spaces
// lines wrap after 78: or rather descriptions wrap after 54
let optgroups = ~[
groups::optflag(~"k", ~"kiwi",
~"This is a long description which won't be wrapped..+.."), // 54
groups::optflag(~"a", ~"apple",
~"This is a long description which _will_ be wrapped..+.."), // 55
];
let expected =
~"Usage: fruits
Options:
-k --kiwi This is a long description which won't be wrapped..+..
-a --apple This is a long description which _will_ be
wrapped..+..
";
let usage = groups::usage(~"Usage: fruits", optgroups);
debug!("expected: <<%s>>", expected);
debug!("generated: <<%s>>", usage);
assert usage == expected
}
}
// Local Variables:

View file

@ -51,7 +51,7 @@ fn escape_str(s: &str) -> ~str {
fn spaces(n: uint) -> ~str {
let mut ss = ~"";
for n.times { str::push_str(&ss, " "); }
for n.times { str::push_str(&mut ss, " "); }
return ss;
}
@ -63,7 +63,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
Serializer { wr: wr }
}
pub impl Serializer: serialization2::Serializer {
pub impl Serializer: serialization::Serializer {
fn emit_nil(&self) { self.wr.write_str("null") }
fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@ -167,7 +167,7 @@ pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer {
PrettySerializer { wr: wr, indent: 0 }
}
pub impl PrettySerializer: serialization2::Serializer {
pub impl PrettySerializer: serialization::Serializer {
fn emit_nil(&self) { self.wr.write_str("null") }
fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
@ -273,8 +273,36 @@ pub impl PrettySerializer: serialization2::Serializer {
}
}
pub impl Json: serialization2::Serializable {
fn serialize<S: serialization2::Serializer>(&self, s: &S) {
#[cfg(stage0)]
pub impl Json: serialization::Serializable {
fn serialize<S: serialization::Serializer>(&self, s: &S) {
match *self {
Number(v) => v.serialize(s),
String(ref v) => v.serialize(s),
Boolean(v) => v.serialize(s),
List(v) => v.serialize(s),
Object(ref v) => {
do s.emit_rec || {
let mut idx = 0;
for v.each |key, value| {
do s.emit_field(*key, idx) {
value.serialize(s);
}
idx += 1;
}
}
},
Null => s.emit_nil(),
}
}
}
#[cfg(stage1)]
#[cfg(stage2)]
pub impl<
S: serialization::Serializer
> Json: serialization::Serializable<S> {
fn serialize(&self, s: &S) {
match *self {
Number(v) => v.serialize(s),
String(ref v) => v.serialize(s),
@ -302,7 +330,8 @@ pub fn to_writer(wr: io::Writer, json: &Json) {
}
/// Serializes a json value into a string
pub fn to_str(json: &Json) -> ~str {
pub pure fn to_str(json: &Json) -> ~str unsafe {
// ugh, should be safe
io::with_str_writer(|wr| to_writer(wr, json))
}
@ -328,8 +357,8 @@ pub fn Parser(rdr: io::Reader) -> Parser {
Parser {
rdr: rdr,
ch: rdr.read_char(),
line: 1u,
col: 1u,
line: 1,
col: 1,
}
}
@ -341,7 +370,7 @@ pub impl Parser {
self.parse_whitespace();
// Make sure there is no trailing characters.
if self.eof() {
Ok(value)
Ok(move value)
} else {
self.error(~"trailing characters")
}
@ -546,14 +575,14 @@ priv impl Parser {
if (escape) {
match self.ch {
'"' => str::push_char(&res, '"'),
'\\' => str::push_char(&res, '\\'),
'/' => str::push_char(&res, '/'),
'b' => str::push_char(&res, '\x08'),
'f' => str::push_char(&res, '\x0c'),
'n' => str::push_char(&res, '\n'),
'r' => str::push_char(&res, '\r'),
't' => str::push_char(&res, '\t'),
'"' => str::push_char(&mut res, '"'),
'\\' => str::push_char(&mut res, '\\'),
'/' => str::push_char(&mut res, '/'),
'b' => str::push_char(&mut res, '\x08'),
'f' => str::push_char(&mut res, '\x0c'),
'n' => str::push_char(&mut res, '\n'),
'r' => str::push_char(&mut res, '\r'),
't' => str::push_char(&mut res, '\t'),
'u' => {
// Parse \u1234.
let mut i = 0u;
@ -582,7 +611,7 @@ priv impl Parser {
~"invalid \\u escape (not four digits)");
}
str::push_char(&res, n as char);
str::push_char(&mut res, n as char);
}
_ => return self.error(~"invalid escape")
}
@ -594,7 +623,7 @@ priv impl Parser {
self.bump();
return Ok(res);
}
str::push_char(&res, self.ch);
str::push_char(&mut res, self.ch);
}
}
@ -609,12 +638,12 @@ priv impl Parser {
if self.ch == ']' {
self.bump();
return Ok(List(values));
return Ok(List(move values));
}
loop {
match move self.parse_value() {
Ok(move v) => values.push(v),
Ok(move v) => values.push(move v),
Err(move e) => return Err(e)
}
@ -625,7 +654,7 @@ priv impl Parser {
match self.ch {
',' => self.bump(),
']' => { self.bump(); return Ok(List(values)); }
']' => { self.bump(); return Ok(List(move values)); }
_ => return self.error(~"expected `,` or `]`")
}
};
@ -639,7 +668,7 @@ priv impl Parser {
if self.ch == '}' {
self.bump();
return Ok(Object(values));
return Ok(Object(move values));
}
while !self.eof() {
@ -663,14 +692,14 @@ priv impl Parser {
self.bump();
match move self.parse_value() {
Ok(move value) => { values.insert(key, value); }
Ok(move value) => { values.insert(key, move value); }
Err(move e) => return Err(e)
}
self.parse_whitespace();
match self.ch {
',' => self.bump(),
'}' => { self.bump(); return Ok(Object(values)); }
'}' => { self.bump(); return Ok(Object(move values)); }
_ => {
if self.eof() { break; }
return self.error(~"expected `,` or `}`");
@ -702,7 +731,7 @@ pub struct Deserializer {
pub fn Deserializer(rdr: io::Reader) -> Result<Deserializer, Error> {
match move from_reader(rdr) {
Ok(move json) => {
let des = Deserializer { json: json, stack: ~[] };
let des = Deserializer { json: move json, stack: ~[] };
Ok(move des)
}
Err(move e) => Err(e)
@ -721,7 +750,7 @@ priv impl Deserializer {
}
}
pub impl Deserializer: serialization2::Deserializer {
pub impl Deserializer: serialization::Deserializer {
fn read_nil(&self) -> () {
debug!("read_nil");
match *self.pop() {
@ -818,7 +847,7 @@ pub impl Deserializer: serialization2::Deserializer {
};
let res = f(len);
self.pop();
res
move res
}
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
@ -829,7 +858,7 @@ pub impl Deserializer: serialization2::Deserializer {
};
let res = f(len);
self.pop();
res
move res
}
fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
@ -850,14 +879,14 @@ pub impl Deserializer: serialization2::Deserializer {
debug!("read_rec()");
let value = f();
self.pop();
value
move value
}
fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
debug!("read_struct()");
let value = f();
self.pop();
value
move value
}
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
@ -868,7 +897,7 @@ pub impl Deserializer: serialization2::Deserializer {
// FIXME(#3148) This hint should not be necessary.
let obj: &self/~Object = obj;
match obj.find_ref(&name.to_unique()) {
match obj.find_ref(&name.to_owned()) {
None => fail fmt!("no such field: %s", name),
Some(json) => {
self.stack.push(json);
@ -890,7 +919,7 @@ pub impl Deserializer: serialization2::Deserializer {
debug!("read_tup(len=%u)", len);
let value = f();
self.pop();
value
move value
}
fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
@ -1166,11 +1195,11 @@ impl <A: ToJson> Option<A>: ToJson {
}
impl Json: to_str::ToStr {
fn to_str() -> ~str { to_str(&self) }
pure fn to_str() -> ~str { to_str(&self) }
}
impl Error: to_str::ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
fmt!("%u:%u: %s", self.line, self.col, *self.msg)
}
}
@ -1182,11 +1211,11 @@ mod tests {
for items.each |item| {
match *item {
(copy key, copy value) => { d.insert(key, value); },
(copy key, copy value) => { d.insert(key, move value); },
}
};
Object(d)
Object(move d)
}
#[test]

View file

@ -341,7 +341,8 @@ pub mod chained {
wr.write_str(~" }");
}
fn to_str() -> ~str {
pure fn to_str() -> ~str unsafe {
// Meh -- this should be safe
do io::with_str_writer |wr| { self.to_writer(wr) }
}
}
@ -722,7 +723,7 @@ mod tests {
let map = map::HashMap::<~str, ~str>();
assert (option::is_none(&map.find(key)));
map.insert(key, ~"val");
assert (option::get(&map.find(key)) == ~"val");
assert (option::get(map.find(key)) == ~"val");
}
#[test]

View file

@ -10,8 +10,10 @@ use addrinfo = uv::ll::addrinfo;
use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t;
use uv_ip4_addr = uv::ll::ip4_addr;
use uv_ip4_name = uv::ll::ip4_name;
use uv_ip4_port = uv::ll::ip4_port;
use uv_ip6_addr = uv::ll::ip6_addr;
use uv_ip6_name = uv::ll::ip6_name;
use uv_ip6_port = uv::ll::ip6_port;
use uv_getaddrinfo = uv::ll::getaddrinfo;
use uv_freeaddrinfo = uv::ll::freeaddrinfo;
use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t;
@ -33,11 +35,11 @@ type ParseAddrErr = {
};
/**
* Convert a `ip_addr` to a str
* Convert a `IpAddr` to a str
*
* # Arguments
*
* * ip - a `std::net::ip::ip_addr`
* * ip - a `std::net::ip::IpAddr`
*/
pub fn format_addr(ip: &IpAddr) -> ~str {
match *ip {
@ -58,6 +60,23 @@ pub fn format_addr(ip: &IpAddr) -> ~str {
}
}
/**
* Get the associated port
*
* # Arguments
* * ip - a `std::net::ip::IpAddr`
*/
pub fn get_port(ip: &IpAddr) -> uint {
match *ip {
Ipv4(ref addr) => unsafe {
uv_ip4_port(addr)
},
Ipv6(ref addr) => unsafe {
uv_ip6_port(addr)
}
}
}
/// Represents errors returned from `net::ip::get_addr()`
enum IpGetAddrErr {
GetAddrUnknownError
@ -128,7 +147,7 @@ pub mod v4 {
*/
pub fn parse_addr(ip: &str) -> IpAddr {
match try_parse_addr(ip) {
result::Ok(copy addr) => addr,
result::Ok(move addr) => move addr,
result::Err(ref err_data) => fail err_data.err_msg
}
}
@ -214,7 +233,7 @@ pub mod v6 {
*/
pub fn parse_addr(ip: &str) -> IpAddr {
match try_parse_addr(ip) {
result::Ok(copy addr) => addr,
result::Ok(move addr) => move addr,
result::Err(copy err_data) => fail err_data.err_msg
}
}
@ -353,7 +372,7 @@ mod test {
}
// note really sure how to realiably test/assert
// this.. mostly just wanting to see it work, atm.
let results = result::unwrap(ga_result);
let results = result::unwrap(move ga_result);
log(debug, fmt!("test_get_addr: Number of results for %s: %?",
localhost_name, vec::len(results)));
for vec::each(results) |r| {
@ -366,7 +385,7 @@ mod test {
}
// at least one result.. this is going to vary from system
// to system, based on stuff like the contents of /etc/hosts
assert vec::len(results) > 0;
assert !results.is_empty();
}
#[test]
#[ignore(reason = "valgrind says it's leaky")]

View file

@ -6,9 +6,7 @@ use ip = net_ip;
use uv::iotask;
use uv::iotask::IoTask;
use future_spawn = future::spawn;
// FIXME #1935
// should be able to, but can't atm, replace w/ result::{result, extensions};
use result::*;
use result::{Result};
use libc::size_t;
use io::{Reader, ReaderUtil, Writer};
use comm = core::comm;
@ -136,6 +134,10 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
stream_handle_ptr: stream_handle_ptr,
connect_req: uv::ll::connect_t(),
write_req: uv::ll::write_t(),
ipv6: match input_ip {
ip::Ipv4(_) => { false }
ip::Ipv6(_) => { true }
},
iotask: iotask
};
let socket_data_ptr = ptr::addr_of(&(*socket_data));
@ -477,6 +479,7 @@ pub fn accept(new_conn: TcpNewConnection)
stream_handle_ptr : stream_handle_ptr,
connect_req : uv::ll::connect_t(),
write_req : uv::ll::write_t(),
ipv6: (*server_data_ptr).ipv6,
iotask : iotask
};
let client_socket_data_ptr = ptr::addr_of(&(*client_socket_data));
@ -564,7 +567,8 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
new_connect_cb: fn~(TcpNewConnection,
comm::Chan<Option<TcpErrData>>))
-> result::Result<(), TcpListenErrData> unsafe {
do listen_common(move host_ip, port, backlog, iotask, on_establish_cb)
do listen_common(move host_ip, port, backlog, iotask,
move on_establish_cb)
// on_connect_cb
|move new_connect_cb, handle| unsafe {
let server_data_ptr = uv::ll::get_data_for_uv_handle(handle)
@ -591,6 +595,10 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
kill_ch: kill_ch,
on_connect_cb: move on_connect_cb,
iotask: iotask,
ipv6: match host_ip {
ip::Ipv4(_) => { false }
ip::Ipv6(_) => { true }
},
mut active: true
};
let server_data_ptr = ptr::addr_of(&server_data);
@ -747,6 +755,21 @@ impl TcpSocket {
-> future::Future<result::Result<(), TcpErrData>> {
write_future(&self, raw_write_data)
}
pub fn get_peer_addr() -> ip::IpAddr {
unsafe {
if self.socket_data.ipv6 {
let addr = uv::ll::ip6_addr("", 0);
uv::ll::tcp_getpeername6(self.socket_data.stream_handle_ptr,
ptr::addr_of(&addr));
ip::Ipv6(move addr)
} else {
let addr = uv::ll::ip4_addr("", 0);
uv::ll::tcp_getpeername(self.socket_data.stream_handle_ptr,
ptr::addr_of(&addr));
ip::Ipv4(move addr)
}
}
}
}
/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
@ -1004,6 +1027,7 @@ type TcpListenFcData = {
kill_ch: comm::Chan<Option<TcpErrData>>,
on_connect_cb: fn~(*uv::ll::uv_tcp_t),
iotask: IoTask,
ipv6: bool,
mut active: bool
};
@ -1093,7 +1117,7 @@ extern fn on_tcp_read_cb(stream: *uv::ll::uv_stream_t,
log(debug, fmt!("tcp on_read_cb nread: %d", nread as int));
let reader_ch = (*socket_data_ptr).reader_ch;
let buf_base = uv::ll::get_base_from_buf(buf);
let new_bytes = vec::raw::from_buf(buf_base, nread as uint);
let new_bytes = vec::from_buf(buf_base, nread as uint);
core::comm::send(reader_ch, result::Ok(new_bytes));
}
}
@ -1202,6 +1226,7 @@ type TcpSocketData = {
stream_handle_ptr: *uv::ll::uv_tcp_t,
connect_req: uv::ll::uv_connect_t,
write_req: uv::ll::uv_write_t,
ipv6: bool,
iotask: IoTask
};
@ -1224,6 +1249,10 @@ mod test {
impl_gl_tcp_ipv4_server_and_client();
}
#[test]
fn test_gl_tcp_get_peer_addr() unsafe {
impl_gl_tcp_ipv4_get_peer_addr();
}
#[test]
fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe {
impl_gl_tcp_ipv4_client_error_connection_refused();
}
@ -1250,6 +1279,11 @@ mod test {
}
#[test]
#[ignore(cfg(target_os = "linux"))]
fn test_gl_tcp_get_peer_addr() unsafe {
impl_gl_tcp_ipv4_get_peer_addr();
}
#[test]
#[ignore(cfg(target_os = "linux"))]
fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe {
impl_gl_tcp_ipv4_client_error_connection_refused();
}
@ -1317,6 +1351,53 @@ mod test {
assert str::contains(actual_req, expected_req);
assert str::contains(actual_resp, expected_resp);
}
fn impl_gl_tcp_ipv4_get_peer_addr() {
let hl_loop = uv::global_loop::get();
let server_ip = ~"127.0.0.1";
let server_port = 8887u;
let expected_resp = ~"pong";
let server_result_po = core::comm::Port::<~str>();
let server_result_ch = core::comm::Chan(&server_result_po);
let cont_po = core::comm::Port::<()>();
let cont_ch = core::comm::Chan(&cont_po);
// server
do task::spawn_sched(task::ManualThreads(1u)) {
let actual_req = do comm::listen |server_ch| {
run_tcp_test_server(
server_ip,
server_port,
expected_resp,
server_ch,
cont_ch,
hl_loop)
};
server_result_ch.send(actual_req);
};
core::comm::recv(cont_po);
// client
log(debug, ~"server started, firing up client..");
do core::comm::listen |client_ch| {
let server_ip_addr = ip::v4::parse_addr(server_ip);
let iotask = uv::global_loop::get();
let connect_result = connect(move server_ip_addr, server_port,
iotask);
let sock = result::unwrap(move connect_result);
// This is what we are actually testing!
assert net::ip::format_addr(&sock.get_peer_addr()) ==
~"127.0.0.1";
assert net::ip::get_port(&sock.get_peer_addr()) == 8887;
// Fulfill the protocol the test server expects
let resp_bytes = str::to_bytes(~"ping");
tcp_write_single(&sock, resp_bytes);
let read_result = sock.read(0u);
client_ch.send(str::from_bytes(read_result.get()));
};
}
fn impl_gl_tcp_ipv4_client_error_connection_refused() {
let hl_loop = uv::global_loop::get();
let server_ip = ~"127.0.0.1";
@ -1512,8 +1593,11 @@ mod test {
~"SERVER/WORKER: send on cont ch");
cont_ch.send(());
let sock = result::unwrap(move accept_result);
let peer_addr = sock.get_peer_addr();
log(debug, ~"SERVER: successfully accepted"+
~"connection!");
fmt!(" connection from %s:%u",
ip::format_addr(&peer_addr),
ip::get_port(&peer_addr)));
let received_req_bytes = read(&sock, 0u);
match move received_req_bytes {
result::Ok(move data) => {

View file

@ -65,10 +65,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
str::push_char(&mut out, ch);
}
_ => out += #fmt("%%%X", ch as uint)
_ => out += fmt!("%%%X", ch as uint)
}
} else {
out += #fmt("%%%X", ch as uint);
out += fmt!("%%%X", ch as uint);
}
}
}
@ -94,6 +94,7 @@ pub fn encode(s: &str) -> ~str {
*
* This function is compliant with RFC 3986.
*/
pub fn encode_component(s: &str) -> ~str {
encode_inner(s, false)
}
@ -163,7 +164,7 @@ fn encode_plus(s: &str) -> ~str {
str::push_char(&mut out, ch);
}
' ' => str::push_char(&mut out, '+'),
_ => out += #fmt("%%%X", ch as uint)
_ => out += fmt!("%%%X", ch as uint)
}
}
@ -189,7 +190,7 @@ pub fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str {
first = false;
}
out += #fmt("%s=%s", key, encode_plus(**value));
out += fmt!("%s=%s", key, encode_plus(**value));
}
}
@ -297,7 +298,7 @@ fn userinfo_from_str(uinfo: &str) -> UserInfo {
return UserInfo(user, pass);
}
fn userinfo_to_str(userinfo: UserInfo) -> ~str {
pure fn userinfo_to_str(userinfo: UserInfo) -> ~str {
if option::is_some(&userinfo.pass) {
return str::concat(~[copy userinfo.user, ~":",
option::unwrap(copy userinfo.pass),
@ -325,11 +326,15 @@ fn query_from_str(rawquery: &str) -> Query {
return query;
}
pub fn query_to_str(query: Query) -> ~str {
pub pure fn query_to_str(query: Query) -> ~str {
let mut strvec = ~[];
for query.each |kv| {
let (k, v) = copy *kv;
strvec += ~[#fmt("%s=%s", encode_component(k), encode_component(v))];
// This is really safe...
unsafe {
strvec += ~[fmt!("%s=%s",
encode_component(k), encode_component(v))];
}
};
return str::connect(strvec, ~"&");
}
@ -672,7 +677,7 @@ impl Url : FromStr {
* result in just "http://somehost.com".
*
*/
pub fn to_str(url: Url) -> ~str {
pub pure fn to_str(url: Url) -> ~str {
let user = if url.user.is_some() {
userinfo_to_str(option::unwrap(copy url.user))
} else {
@ -688,7 +693,8 @@ pub fn to_str(url: Url) -> ~str {
} else {
str::concat(~[~"?", query_to_str(url.query)])
};
let fragment = if url.fragment.is_some() {
// ugh, this really is safe
let fragment = if url.fragment.is_some() unsafe {
str::concat(~[~"#", encode_component(
option::unwrap(copy url.fragment))])
} else {
@ -704,7 +710,7 @@ pub fn to_str(url: Url) -> ~str {
}
impl Url: to_str::ToStr {
pub fn to_str() -> ~str {
pub pure fn to_str() -> ~str {
to_str(self)
}
}
@ -844,7 +850,7 @@ mod tests {
fn test_url_parse_host_slash() {
let urlstr = ~"http://0.42.42.42/";
let url = from_str(urlstr).get();
#debug("url: %?", url);
debug!("url: %?", url);
assert url.host == ~"0.42.42.42";
assert url.path == ~"/";
}
@ -853,7 +859,7 @@ mod tests {
fn test_url_with_underscores() {
let urlstr = ~"http://dotcom.com/file_name.html";
let url = from_str(urlstr).get();
#debug("url: %?", url);
debug!("url: %?", url);
assert url.path == ~"/file_name.html";
}
@ -861,7 +867,7 @@ mod tests {
fn test_url_with_dashes() {
let urlstr = ~"http://dotcom.com/file-name.html";
let url = from_str(urlstr).get();
#debug("url: %?", url);
debug!("url: %?", url);
assert url.path == ~"/file-name.html";
}

View file

@ -2,131 +2,175 @@
use io::Writer;
use io::WriterUtil;
use serialization::Serializer;
use serialization;
impl Writer: Serializer {
fn emit_nil() {
self.write_str(~"()")
pub struct Serializer {
wr: io::Writer,
}
pub fn Serializer(wr: io::Writer) -> Serializer {
Serializer { wr: wr }
}
pub impl Serializer: serialization::Serializer {
fn emit_nil(&self) {
self.wr.write_str(~"()")
}
fn emit_uint(v: uint) {
self.write_str(fmt!("%?u", v));
fn emit_uint(&self, v: uint) {
self.wr.write_str(fmt!("%?u", v));
}
fn emit_u64(v: u64) {
self.write_str(fmt!("%?_u64", v));
fn emit_u64(&self, v: u64) {
self.wr.write_str(fmt!("%?_u64", v));
}
fn emit_u32(v: u32) {
self.write_str(fmt!("%?_u32", v));
fn emit_u32(&self, v: u32) {
self.wr.write_str(fmt!("%?_u32", v));
}
fn emit_u16(v: u16) {
self.write_str(fmt!("%?_u16", v));
fn emit_u16(&self, v: u16) {
self.wr.write_str(fmt!("%?_u16", v));
}
fn emit_u8(v: u8) {
self.write_str(fmt!("%?_u8", v));
fn emit_u8(&self, v: u8) {
self.wr.write_str(fmt!("%?_u8", v));
}
fn emit_int(v: int) {
self.write_str(fmt!("%?", v));
fn emit_int(&self, v: int) {
self.wr.write_str(fmt!("%?", v));
}
fn emit_i64(v: i64) {
self.write_str(fmt!("%?_i64", v));
fn emit_i64(&self, v: i64) {
self.wr.write_str(fmt!("%?_i64", v));
}
fn emit_i32(v: i32) {
self.write_str(fmt!("%?_i32", v));
fn emit_i32(&self, v: i32) {
self.wr.write_str(fmt!("%?_i32", v));
}
fn emit_i16(v: i16) {
self.write_str(fmt!("%?_i16", v));
fn emit_i16(&self, v: i16) {
self.wr.write_str(fmt!("%?_i16", v));
}
fn emit_i8(v: i8) {
self.write_str(fmt!("%?_i8", v));
fn emit_i8(&self, v: i8) {
self.wr.write_str(fmt!("%?_i8", v));
}
fn emit_bool(v: bool) {
self.write_str(fmt!("%b", v));
fn emit_bool(&self, v: bool) {
self.wr.write_str(fmt!("%b", v));
}
fn emit_float(v: float) {
self.write_str(fmt!("%?_f", v));
fn emit_float(&self, v: float) {
self.wr.write_str(fmt!("%?_f", v));
}
fn emit_f64(v: f64) {
self.write_str(fmt!("%?_f64", v));
fn emit_f64(&self, v: f64) {
self.wr.write_str(fmt!("%?_f64", v));
}
fn emit_f32(v: f32) {
self.write_str(fmt!("%?_f32", v));
fn emit_f32(&self, v: f32) {
self.wr.write_str(fmt!("%?_f32", v));
}
fn emit_str(v: &str) {
self.write_str(fmt!("%?", v));
fn emit_char(&self, v: char) {
self.wr.write_str(fmt!("%?", v));
}
fn emit_enum(_name: &str, f: fn()) {
fn emit_borrowed_str(&self, v: &str) {
self.wr.write_str(fmt!("&%?", v));
}
fn emit_owned_str(&self, v: &str) {
self.wr.write_str(fmt!("~%?", v));
}
fn emit_managed_str(&self, v: &str) {
self.wr.write_str(fmt!("@%?", v));
}
fn emit_borrowed(&self, f: fn()) {
self.wr.write_str(~"&");
f();
}
fn emit_enum_variant(v_name: &str, _v_id: uint, sz: uint, f: fn()) {
self.write_str(v_name);
if sz > 0u { self.write_str(~"("); }
f();
if sz > 0u { self.write_str(~")"); }
}
fn emit_enum_variant_arg(idx: uint, f: fn()) {
if idx > 0u { self.write_str(~", "); }
fn emit_owned(&self, f: fn()) {
self.wr.write_str(~"~");
f();
}
fn emit_vec(_len: uint, f: fn()) {
self.write_str(~"[");
f();
self.write_str(~"]");
}
fn emit_vec_elt(idx: uint, f: fn()) {
if idx > 0u { self.write_str(~", "); }
fn emit_managed(&self, f: fn()) {
self.wr.write_str(~"@");
f();
}
fn emit_box(f: fn()) {
self.write_str(~"@");
fn emit_enum(&self, _name: &str, f: fn()) {
f();
}
fn emit_uniq(f: fn()) {
self.write_str(~"~");
fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
f: fn()) {
self.wr.write_str(v_name);
if sz > 0u { self.wr.write_str(~"("); }
f();
if sz > 0u { self.wr.write_str(~")"); }
}
fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
fn emit_rec(f: fn()) {
self.write_str(~"{");
fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"&[");
f();
self.write_str(~"}");
self.wr.write_str(~"]");
}
fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()) {
if f_idx > 0u { self.write_str(~", "); }
self.write_str(f_name);
self.write_str(~": ");
fn emit_owned_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"~[");
f();
self.wr.write_str(~"]");
}
fn emit_managed_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"@[");
f();
self.wr.write_str(~"]");
}
fn emit_vec_elt(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
fn emit_tup(_sz: uint, f: fn()) {
self.write_str(~"(");
fn emit_rec(&self, f: fn()) {
self.wr.write_str(~"{");
f();
self.write_str(~")");
self.wr.write_str(~"}");
}
fn emit_tup_elt(idx: uint, f: fn()) {
if idx > 0u { self.write_str(~", "); }
fn emit_struct(&self, name: &str, f: fn()) {
self.wr.write_str(fmt!("%s {", name));
f();
self.wr.write_str(~"}");
}
fn emit_field(&self, name: &str, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
self.wr.write_str(name);
self.wr.write_str(~": ");
f();
}
fn emit_tup(&self, _len: uint, f: fn()) {
self.wr.write_str(~"(");
f();
self.wr.write_str(~")");
}
fn emit_tup_elt(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
}

View file

@ -1,176 +0,0 @@
#[forbid(deprecated_mode)];
use io::Writer;
use io::WriterUtil;
use serialization2;
pub struct Serializer {
wr: io::Writer,
}
pub fn Serializer(wr: io::Writer) -> Serializer {
Serializer { wr: wr }
}
pub impl Serializer: serialization2::Serializer {
fn emit_nil(&self) {
self.wr.write_str(~"()")
}
fn emit_uint(&self, v: uint) {
self.wr.write_str(fmt!("%?u", v));
}
fn emit_u64(&self, v: u64) {
self.wr.write_str(fmt!("%?_u64", v));
}
fn emit_u32(&self, v: u32) {
self.wr.write_str(fmt!("%?_u32", v));
}
fn emit_u16(&self, v: u16) {
self.wr.write_str(fmt!("%?_u16", v));
}
fn emit_u8(&self, v: u8) {
self.wr.write_str(fmt!("%?_u8", v));
}
fn emit_int(&self, v: int) {
self.wr.write_str(fmt!("%?", v));
}
fn emit_i64(&self, v: i64) {
self.wr.write_str(fmt!("%?_i64", v));
}
fn emit_i32(&self, v: i32) {
self.wr.write_str(fmt!("%?_i32", v));
}
fn emit_i16(&self, v: i16) {
self.wr.write_str(fmt!("%?_i16", v));
}
fn emit_i8(&self, v: i8) {
self.wr.write_str(fmt!("%?_i8", v));
}
fn emit_bool(&self, v: bool) {
self.wr.write_str(fmt!("%b", v));
}
fn emit_float(&self, v: float) {
self.wr.write_str(fmt!("%?_f", v));
}
fn emit_f64(&self, v: f64) {
self.wr.write_str(fmt!("%?_f64", v));
}
fn emit_f32(&self, v: f32) {
self.wr.write_str(fmt!("%?_f32", v));
}
fn emit_char(&self, v: char) {
self.wr.write_str(fmt!("%?", v));
}
fn emit_borrowed_str(&self, v: &str) {
self.wr.write_str(fmt!("&%?", v));
}
fn emit_owned_str(&self, v: &str) {
self.wr.write_str(fmt!("~%?", v));
}
fn emit_managed_str(&self, v: &str) {
self.wr.write_str(fmt!("@%?", v));
}
fn emit_borrowed(&self, f: fn()) {
self.wr.write_str(~"&");
f();
}
fn emit_owned(&self, f: fn()) {
self.wr.write_str(~"~");
f();
}
fn emit_managed(&self, f: fn()) {
self.wr.write_str(~"@");
f();
}
fn emit_enum(&self, _name: &str, f: fn()) {
f();
}
fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint,
f: fn()) {
self.wr.write_str(v_name);
if sz > 0u { self.wr.write_str(~"("); }
f();
if sz > 0u { self.wr.write_str(~")"); }
}
fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"&[");
f();
self.wr.write_str(~"]");
}
fn emit_owned_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"~[");
f();
self.wr.write_str(~"]");
}
fn emit_managed_vec(&self, _len: uint, f: fn()) {
self.wr.write_str(~"@[");
f();
self.wr.write_str(~"]");
}
fn emit_vec_elt(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
fn emit_rec(&self, f: fn()) {
self.wr.write_str(~"{");
f();
self.wr.write_str(~"}");
}
fn emit_struct(&self, name: &str, f: fn()) {
self.wr.write_str(fmt!("%s {", name));
f();
self.wr.write_str(~"}");
}
fn emit_field(&self, name: &str, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
self.wr.write_str(name);
self.wr.write_str(~": ");
f();
}
fn emit_tup(&self, _len: uint, f: fn()) {
self.wr.write_str(~"(");
f();
self.wr.write_str(~")");
}
fn emit_tup_elt(&self, idx: uint, f: fn()) {
if idx > 0u { self.wr.write_str(~", "); }
f();
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,563 +0,0 @@
//! Support code for serialization.
/*
Core serialization interfaces.
*/
#[forbid(deprecated_mode)];
#[forbid(non_camel_case_types)];
pub trait Serializer {
// Primitive types:
fn emit_nil(&self);
fn emit_uint(&self, v: uint);
fn emit_u64(&self, v: u64);
fn emit_u32(&self, v: u32);
fn emit_u16(&self, v: u16);
fn emit_u8(&self, v: u8);
fn emit_int(&self, v: int);
fn emit_i64(&self, v: i64);
fn emit_i32(&self, v: i32);
fn emit_i16(&self, v: i16);
fn emit_i8(&self, v: i8);
fn emit_bool(&self, v: bool);
fn emit_float(&self, v: float);
fn emit_f64(&self, v: f64);
fn emit_f32(&self, v: f32);
fn emit_char(&self, v: char);
fn emit_borrowed_str(&self, v: &str);
fn emit_owned_str(&self, v: &str);
fn emit_managed_str(&self, v: &str);
// Compound types:
fn emit_borrowed(&self, f: fn());
fn emit_owned(&self, f: fn());
fn emit_managed(&self, f: fn());
fn emit_enum(&self, name: &str, f: fn());
fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
fn emit_enum_variant_arg(&self, idx: uint, f: fn());
fn emit_borrowed_vec(&self, len: uint, f: fn());
fn emit_owned_vec(&self, len: uint, f: fn());
fn emit_managed_vec(&self, len: uint, f: fn());
fn emit_vec_elt(&self, idx: uint, f: fn());
fn emit_rec(&self, f: fn());
fn emit_struct(&self, name: &str, f: fn());
fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
fn emit_tup(&self, len: uint, f: fn());
fn emit_tup_elt(&self, idx: uint, f: fn());
}
pub trait Deserializer {
// Primitive types:
fn read_nil(&self) -> ();
fn read_uint(&self) -> uint;
fn read_u64(&self) -> u64;
fn read_u32(&self) -> u32;
fn read_u16(&self) -> u16;
fn read_u8(&self) -> u8;
fn read_int(&self) -> int;
fn read_i64(&self) -> i64;
fn read_i32(&self) -> i32;
fn read_i16(&self) -> i16;
fn read_i8(&self) -> i8;
fn read_bool(&self) -> bool;
fn read_f64(&self) -> f64;
fn read_f32(&self) -> f32;
fn read_float(&self) -> float;
fn read_char(&self) -> char;
fn read_owned_str(&self) -> ~str;
fn read_managed_str(&self) -> @str;
// Compound types:
fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
fn read_owned<T>(&self, f: fn() -> T) -> T;
fn read_managed<T>(&self, f: fn() -> T) -> T;
fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
fn read_rec<T>(&self, f: fn() -> T) -> T;
fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
}
pub trait Serializable {
fn serialize<S: Serializer>(&self, s: &S);
}
pub trait Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
}
pub impl uint: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
}
pub impl uint: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
d.read_uint()
}
}
pub impl u8: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
}
pub impl u8: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
d.read_u8()
}
}
pub impl u16: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
}
pub impl u16: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
d.read_u16()
}
}
pub impl u32: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
}
pub impl u32: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
d.read_u32()
}
}
pub impl u64: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
}
pub impl u64: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
d.read_u64()
}
}
pub impl int: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
}
pub impl int: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
d.read_int()
}
}
pub impl i8: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
}
pub impl i8: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
d.read_i8()
}
}
pub impl i16: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
}
pub impl i16: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
d.read_i16()
}
}
pub impl i32: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
}
pub impl i32: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
d.read_i32()
}
}
pub impl i64: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
}
pub impl i64: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
d.read_i64()
}
}
pub impl &str: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
}
pub impl ~str: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
}
pub impl ~str: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
d.read_owned_str()
}
}
pub impl @str: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
}
pub impl @str: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
d.read_managed_str()
}
}
pub impl float: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
}
pub impl float: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
d.read_float()
}
}
pub impl f32: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
}
pub impl f32: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
d.read_f32() }
}
pub impl f64: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
}
pub impl f64: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
d.read_f64()
}
}
pub impl bool: Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
}
pub impl bool: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
d.read_bool()
}
}
pub impl (): Serializable {
fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
}
pub impl (): Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
d.read_nil()
}
}
pub impl<T: Serializable> &T: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
s.emit_borrowed(|| (**self).serialize(s))
}
}
pub impl<T: Serializable> ~T: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
s.emit_owned(|| (**self).serialize(s))
}
}
pub impl<T: Deserializable> ~T: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
d.read_owned(|| ~deserialize(d))
}
}
pub impl<T: Serializable> @T: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
s.emit_managed(|| (**self).serialize(s))
}
}
pub impl<T: Deserializable> @T: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
d.read_managed(|| @deserialize(d))
}
}
pub impl<T: Serializable> &[T]: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
do s.emit_borrowed_vec(self.len()) {
for self.eachi |i, e| {
s.emit_vec_elt(i, || e.serialize(s))
}
}
}
}
pub impl<T: Serializable> ~[T]: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
do s.emit_owned_vec(self.len()) {
for self.eachi |i, e| {
s.emit_vec_elt(i, || e.serialize(s))
}
}
}
}
pub impl<T: Deserializable> ~[T]: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
do d.read_owned_vec |len| {
do vec::from_fn(len) |i| {
d.read_vec_elt(i, || deserialize(d))
}
}
}
}
pub impl<T: Serializable> @[T]: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
do s.emit_managed_vec(self.len()) {
for self.eachi |i, e| {
s.emit_vec_elt(i, || e.serialize(s))
}
}
}
}
pub impl<T: Deserializable> @[T]: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
do d.read_managed_vec |len| {
do at_vec::from_fn(len) |i| {
d.read_vec_elt(i, || deserialize(d))
}
}
}
}
pub impl<T: Serializable> Option<T>: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
do s.emit_enum(~"option") {
match *self {
None => do s.emit_enum_variant(~"none", 0u, 0u) {
},
Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) {
s.emit_enum_variant_arg(0u, || v.serialize(s))
}
}
}
}
}
pub impl<T: Deserializable> Option<T>: Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
do d.read_enum(~"option") {
do d.read_enum_variant |i| {
match i {
0 => None,
1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))),
_ => fail(#fmt("Bad variant for option: %u", i))
}
}
}
}
}
pub impl<
T0: Serializable,
T1: Serializable
> (T0, T1): Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
match *self {
(ref t0, ref t1) => {
do s.emit_tup(2) {
s.emit_tup_elt(0, || t0.serialize(s));
s.emit_tup_elt(1, || t1.serialize(s));
}
}
}
}
}
pub impl<
T0: Deserializable,
T1: Deserializable
> (T0, T1): Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
do d.read_tup(2) {
(
d.read_tup_elt(0, || deserialize(d)),
d.read_tup_elt(1, || deserialize(d))
)
}
}
}
pub impl<
T0: Serializable,
T1: Serializable,
T2: Serializable
> (T0, T1, T2): Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
match *self {
(ref t0, ref t1, ref t2) => {
do s.emit_tup(3) {
s.emit_tup_elt(0, || t0.serialize(s));
s.emit_tup_elt(1, || t1.serialize(s));
s.emit_tup_elt(2, || t2.serialize(s));
}
}
}
}
}
pub impl<
T0: Deserializable,
T1: Deserializable,
T2: Deserializable
> (T0, T1, T2): Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
do d.read_tup(3) {
(
d.read_tup_elt(0, || deserialize(d)),
d.read_tup_elt(1, || deserialize(d)),
d.read_tup_elt(2, || deserialize(d))
)
}
}
}
pub impl<
T0: Serializable,
T1: Serializable,
T2: Serializable,
T3: Serializable
> (T0, T1, T2, T3): Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
match *self {
(ref t0, ref t1, ref t2, ref t3) => {
do s.emit_tup(4) {
s.emit_tup_elt(0, || t0.serialize(s));
s.emit_tup_elt(1, || t1.serialize(s));
s.emit_tup_elt(2, || t2.serialize(s));
s.emit_tup_elt(3, || t3.serialize(s));
}
}
}
}
}
pub impl<
T0: Deserializable,
T1: Deserializable,
T2: Deserializable,
T3: Deserializable
> (T0, T1, T2, T3): Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
do d.read_tup(4) {
(
d.read_tup_elt(0, || deserialize(d)),
d.read_tup_elt(1, || deserialize(d)),
d.read_tup_elt(2, || deserialize(d)),
d.read_tup_elt(3, || deserialize(d))
)
}
}
}
pub impl<
T0: Serializable,
T1: Serializable,
T2: Serializable,
T3: Serializable,
T4: Serializable
> (T0, T1, T2, T3, T4): Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
match *self {
(ref t0, ref t1, ref t2, ref t3, ref t4) => {
do s.emit_tup(5) {
s.emit_tup_elt(0, || t0.serialize(s));
s.emit_tup_elt(1, || t1.serialize(s));
s.emit_tup_elt(2, || t2.serialize(s));
s.emit_tup_elt(3, || t3.serialize(s));
s.emit_tup_elt(4, || t4.serialize(s));
}
}
}
}
}
pub impl<
T0: Deserializable,
T1: Deserializable,
T2: Deserializable,
T3: Deserializable,
T4: Deserializable
> (T0, T1, T2, T3, T4): Deserializable {
static fn deserialize<D: Deserializer>(&self, d: &D)
-> (T0, T1, T2, T3, T4) {
do d.read_tup(5) {
(
d.read_tup_elt(0, || deserialize(d)),
d.read_tup_elt(1, || deserialize(d)),
d.read_tup_elt(2, || deserialize(d)),
d.read_tup_elt(3, || deserialize(d)),
d.read_tup_elt(4, || deserialize(d))
)
}
}
}
// ___________________________________________________________________________
// Helper routines
//
// In some cases, these should eventually be coded as traits.
pub trait SerializerHelpers {
fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
}
pub impl<S: Serializer> S: SerializerHelpers {
fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
do self.emit_owned_vec(v.len()) {
for v.eachi |i, e| {
do self.emit_vec_elt(i) {
f(e)
}
}
}
}
}
pub trait DeserializerHelpers {
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T];
}
pub impl<D: Deserializer> D: DeserializerHelpers {
fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
do self.read_owned_vec |len| {
do vec::from_fn(len) |i| {
self.read_vec_elt(i, || f())
}
}
}
}

View file

@ -899,7 +899,7 @@ mod test_qsort {
do sort::quick_sort(names) |x, y| { int::le(*x, *y) };
let immut_names = vec::from_mut(names);
let immut_names = vec::from_mut(move names);
let pairs = vec::zip(expected, immut_names);
for vec::each(pairs) |p| {

View file

@ -8,7 +8,7 @@ not required in or otherwise suitable for the core library.
*/
#[link(name = "std",
vers = "0.4",
vers = "0.5",
uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
@ -25,7 +25,7 @@ not required in or otherwise suitable for the core library.
#[allow(deprecated_mode)];
#[forbid(deprecated_pattern)];
extern mod core(vers = "0.4");
extern mod core(vers = "0.5");
use core::*;
// General io and system-services modules
@ -69,7 +69,6 @@ pub mod treemap;
// And ... other stuff
pub mod ebml;
pub mod ebml2;
pub mod dbg;
pub mod getopts;
pub mod json;
@ -79,7 +78,6 @@ pub mod tempfile;
pub mod term;
pub mod time;
pub mod prettyprint;
pub mod prettyprint2;
pub mod arena;
pub mod par;
pub mod cmp;
@ -93,7 +91,6 @@ mod unicode;
pub mod test;
pub mod serialization;
pub mod serialization2;
// Local Variables:
// mode: rust;

View file

@ -25,7 +25,7 @@ struct Waitqueue { head: pipes::Port<SignalEnd>,
fn new_waitqueue() -> Waitqueue {
let (block_tail, block_head) = pipes::stream();
Waitqueue { head: block_head, tail: block_tail }
Waitqueue { head: move block_head, tail: move block_tail }
}
// Signals one live task from the queue.
@ -71,7 +71,7 @@ enum Sem<Q: Send> = Exclusive<SemInner<Q>>;
#[doc(hidden)]
fn new_sem<Q: Send>(count: int, q: Q) -> Sem<Q> {
Sem(exclusive(SemInner {
mut count: count, waiters: new_waitqueue(), blocked: q }))
mut count: count, waiters: new_waitqueue(), blocked: move q }))
}
#[doc(hidden)]
fn new_sem_and_signal(count: int, num_condvars: uint)
@ -146,7 +146,7 @@ impl &Sem<~[mut Waitqueue]> {
}
}
// FIXME(#3136) should go inside of access()
// FIXME(#3588) should go inside of access()
#[doc(hidden)]
struct SemRelease {
sem: &Sem<()>,
@ -577,7 +577,7 @@ impl &RWlock {
}
}
// FIXME(#3136) should go inside of read()
// FIXME(#3588) should go inside of read()
#[doc(hidden)]
struct RWlockReleaseRead {
lock: &RWlock,
@ -606,7 +606,7 @@ fn RWlockReleaseRead(lock: &r/RWlock) -> RWlockReleaseRead/&r {
}
}
// FIXME(#3136) should go inside of downgrade()
// FIXME(#3588) should go inside of downgrade()
#[doc(hidden)]
struct RWlockReleaseDowngrade {
lock: &RWlock,
@ -686,7 +686,7 @@ mod tests {
fn test_sem_as_mutex() {
let s = ~semaphore(1);
let s2 = ~s.clone();
do task::spawn {
do task::spawn |move s2| {
do s2.access {
for 5.times { task::yield(); }
}
@ -701,7 +701,7 @@ mod tests {
let (c,p) = pipes::stream();
let s = ~semaphore(0);
let s2 = ~s.clone();
do task::spawn {
do task::spawn |move s2, move c| {
s2.acquire();
c.send(());
}
@ -713,7 +713,7 @@ mod tests {
let (c,p) = pipes::stream();
let s = ~semaphore(0);
let s2 = ~s.clone();
do task::spawn {
do task::spawn |move s2, move p| {
for 5.times { task::yield(); }
s2.release();
let _ = p.recv();
@ -729,7 +729,7 @@ mod tests {
let s2 = ~s.clone();
let (c1,p1) = pipes::stream();
let (c2,p2) = pipes::stream();
do task::spawn {
do task::spawn |move s2, move c1, move p2| {
do s2.access {
let _ = p2.recv();
c1.send(());
@ -748,10 +748,10 @@ mod tests {
let s = ~semaphore(1);
let s2 = ~s.clone();
let (c,p) = pipes::stream();
let child_data = ~mut Some((s2,c));
let child_data = ~mut Some((move s2, move c));
do s.access {
let (s2,c) = option::swap_unwrap(child_data);
do task::spawn {
do task::spawn |move c, move s2| {
c.send(());
do s2.access { }
c.send(());
@ -774,7 +774,7 @@ mod tests {
let m2 = ~m.clone();
let mut sharedstate = ~0;
let ptr = ptr::addr_of(&(*sharedstate));
do task::spawn {
do task::spawn |move m2, move c| {
let sharedstate: &mut int =
unsafe { cast::reinterpret_cast(&ptr) };
access_shared(sharedstate, m2, 10);
@ -803,7 +803,7 @@ mod tests {
// Child wakes up parent
do m.lock_cond |cond| {
let m2 = ~m.clone();
do task::spawn {
do task::spawn |move m2| {
do m2.lock_cond |cond| {
let woken = cond.signal();
assert woken;
@ -814,7 +814,7 @@ mod tests {
// Parent wakes up child
let (chan,port) = pipes::stream();
let m3 = ~m.clone();
do task::spawn {
do task::spawn |move chan, move m3| {
do m3.lock_cond |cond| {
chan.send(());
cond.wait();
@ -836,8 +836,8 @@ mod tests {
for num_waiters.times {
let mi = ~m.clone();
let (chan, port) = pipes::stream();
ports.push(port);
do task::spawn {
ports.push(move port);
do task::spawn |move chan, move mi| {
do mi.lock_cond |cond| {
chan.send(());
cond.wait();
@ -867,7 +867,7 @@ mod tests {
fn test_mutex_cond_no_waiter() {
let m = ~Mutex();
let m2 = ~m.clone();
do task::try {
do task::try |move m| {
do m.lock_cond |_x| { }
};
do m2.lock_cond |cond| {
@ -880,7 +880,7 @@ mod tests {
let m = ~Mutex();
let m2 = ~m.clone();
let result: result::Result<(),()> = do task::try {
let result: result::Result<(),()> = do task::try |move m2| {
do m2.lock {
fail;
}
@ -896,9 +896,9 @@ mod tests {
let m = ~Mutex();
let m2 = ~m.clone();
let result: result::Result<(),()> = do task::try {
let result: result::Result<(),()> = do task::try |move m2| {
let (c,p) = pipes::stream();
do task::spawn { // linked
do task::spawn |move p| { // linked
let _ = p.recv(); // wait for sibling to get in the mutex
task::yield();
fail;
@ -921,19 +921,19 @@ mod tests {
let m2 = ~m.clone();
let (c,p) = pipes::stream();
let result: result::Result<(),()> = do task::try {
let result: result::Result<(),()> = do task::try |move c, move m2| {
let mut sibling_convos = ~[];
for 2.times {
let (c,p) = pipes::stream();
let c = ~mut Some(c);
sibling_convos.push(p);
let c = ~mut Some(move c);
sibling_convos.push(move p);
let mi = ~m2.clone();
// spawn sibling task
do task::spawn { // linked
do task::spawn |move mi, move c| { // linked
do mi.lock_cond |cond| {
let c = option::swap_unwrap(c);
c.send(()); // tell sibling to go ahead
let _z = SendOnFailure(c);
let _z = SendOnFailure(move c);
cond.wait(); // block forever
}
}
@ -942,7 +942,7 @@ mod tests {
let _ = p.recv(); // wait for sibling to get in the mutex
}
do m2.lock { }
c.send(sibling_convos); // let parent wait on all children
c.send(move sibling_convos); // let parent wait on all children
fail;
};
assert result.is_err();
@ -959,7 +959,7 @@ mod tests {
fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure {
SendOnFailure {
c: c
c: move c
}
}
}
@ -969,7 +969,7 @@ mod tests {
let m = ~Mutex();
do m.lock_cond |cond| {
let m2 = ~m.clone();
do task::spawn {
do task::spawn |move m2| {
do m2.lock_cond |cond| {
cond.signal_on(0);
}
@ -983,7 +983,7 @@ mod tests {
let m = ~mutex_with_condvars(2);
let m2 = ~m.clone();
let (c,p) = pipes::stream();
do task::spawn {
do task::spawn |move m2, move c| {
do m2.lock_cond |cond| {
c.send(());
cond.wait_on(1);
@ -1032,7 +1032,7 @@ mod tests {
},
DowngradeRead =>
do x.write_downgrade |mode| {
let mode = x.downgrade(mode);
let mode = x.downgrade(move mode);
(&mode).read(blk);
},
}
@ -1046,7 +1046,7 @@ mod tests {
let x2 = ~x.clone();
let mut sharedstate = ~0;
let ptr = ptr::addr_of(&(*sharedstate));
do task::spawn {
do task::spawn |move c, move x2| {
let sharedstate: &mut int =
unsafe { cast::reinterpret_cast(&ptr) };
access_shared(sharedstate, x2, mode1, 10);
@ -1089,7 +1089,7 @@ mod tests {
let x2 = ~x.clone();
let (c1,p1) = pipes::stream();
let (c2,p2) = pipes::stream();
do task::spawn {
do task::spawn |move c1, move x2, move p2| {
if !make_mode2_go_first {
let _ = p2.recv(); // parent sends to us once it locks, or ...
}
@ -1126,10 +1126,10 @@ mod tests {
// Tests that downgrade can unlock the lock in both modes
let x = ~RWlock();
do lock_rwlock_in_mode(x, Downgrade) { }
test_rwlock_handshake(x, Read, Read, false);
test_rwlock_handshake(move x, Read, Read, false);
let y = ~RWlock();
do lock_rwlock_in_mode(y, DowngradeRead) { }
test_rwlock_exclusion(y, Write, Write);
test_rwlock_exclusion(move y, Write, Write);
}
#[test]
fn test_rwlock_read_recursive() {
@ -1144,7 +1144,7 @@ mod tests {
// Child wakes up parent
do x.write_cond |cond| {
let x2 = ~x.clone();
do task::spawn {
do task::spawn |move x2| {
do x2.write_cond |cond| {
let woken = cond.signal();
assert woken;
@ -1155,7 +1155,7 @@ mod tests {
// Parent wakes up child
let (chan,port) = pipes::stream();
let x3 = ~x.clone();
do task::spawn {
do task::spawn |move x3, move chan| {
do x3.write_cond |cond| {
chan.send(());
cond.wait();
@ -1190,8 +1190,8 @@ mod tests {
for num_waiters.times {
let xi = ~x.clone();
let (chan, port) = pipes::stream();
ports.push(port);
do task::spawn {
ports.push(move port);
do task::spawn |move chan, move xi| {
do lock_cond(xi, dg1) |cond| {
chan.send(());
cond.wait();
@ -1226,7 +1226,7 @@ mod tests {
let x = ~RWlock();
let x2 = ~x.clone();
let result: result::Result<(),()> = do task::try {
let result: result::Result<(),()> = do task::try |move x2| {
do lock_rwlock_in_mode(x2, mode1) {
fail;
}
@ -1264,7 +1264,7 @@ mod tests {
let x = ~RWlock();
let y = ~RWlock();
do x.write_downgrade |xwrite| {
let mut xopt = Some(xwrite);
let mut xopt = Some(move xwrite);
do y.write_downgrade |_ywrite| {
y.downgrade(option::swap_unwrap(&mut xopt));
error!("oops, y.downgrade(x) should have failed!");

View file

@ -130,7 +130,7 @@ pub fn run_tests_console(opts: &TestOpts,
st.failed += 1u;
write_failed(st.out, st.use_color);
st.out.write_line(~"");
st.failures.push(test);
st.failures.push(move test);
}
TrIgnored => {
st.ignored += 1u;
@ -249,7 +249,7 @@ fn should_sort_failures_before_printing_them() {
mut passed: 0u,
mut failed: 0u,
mut ignored: 0u,
mut failures: ~[test_b, test_a]};
mut failures: ~[move test_b, move test_a]};
print_failures(st);
};
@ -534,9 +534,9 @@ mod tests {
for vec::each(names) |name| {
let test = {name: *name, testfn: copy testfn, ignore: false,
should_fail: false};
tests.push(test);
tests.push(move test);
}
tests
move tests
};
let filtered = filter_tests(&opts, tests);
@ -549,7 +549,7 @@ mod tests {
~"test::parse_ignored_flag",
~"test::sort_tests"];
let pairs = vec::zip(expected, filtered);
let pairs = vec::zip(expected, move filtered);
for vec::each(pairs) |p| {
match *p {

View file

@ -595,8 +595,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
fn strftime(format: &str, tm: Tm) -> ~str {
fn parse_type(ch: char, tm: &Tm) -> ~str {
//FIXME (#2350): Implement missing types.
let die = || #fmt("strftime: can't understand this format %c ",
ch);
let die = || fmt!("strftime: can't understand this format %c ", ch);
match ch {
'A' => match tm.tm_wday as int {
0 => ~"Sunday",

View file

@ -23,7 +23,7 @@ use comm = core::comm;
* * ch - a channel of type T to send a `val` on
* * val - a value of type T to send over the provided `ch`
*/
pub fn delayed_send<T: Copy Send>(iotask: IoTask,
pub fn delayed_send<T: Send>(iotask: IoTask,
msecs: uint, ch: comm::Chan<T>, val: T) {
unsafe {
let timer_done_po = core::comm::Port::<()>();
@ -55,7 +55,7 @@ pub fn delayed_send<T: Copy Send>(iotask: IoTask,
// delayed_send_cb has been processed by libuv
core::comm::recv(timer_done_po);
// notify the caller immediately
core::comm::send(ch, copy(val));
core::comm::send(ch, move(val));
// uv_close for this timer has been processed
core::comm::recv(timer_done_po);
};

View file

@ -11,28 +11,28 @@ use core::cmp::{Eq, Ord};
use core::option::{Some, None};
use Option = core::Option;
pub type TreeMap<K, V> = @mut TreeEdge<K, V>;
pub type TreeMap<K: Copy Eq Ord, V: Copy> = @mut TreeEdge<K, V>;
type TreeEdge<K, V> = Option<@TreeNode<K, V>>;
type TreeEdge<K: Copy Eq Ord, V: Copy> = Option<@TreeNode<K, V>>;
enum TreeNode<K, V> = {
struct TreeNode<K: Copy Eq Ord, V: Copy> {
key: K,
mut value: V,
mut left: TreeEdge<K, V>,
mut right: TreeEdge<K, V>
};
}
/// Create a treemap
pub fn TreeMap<K, V>() -> TreeMap<K, V> { @mut None }
pub fn TreeMap<K: Copy Eq Ord, V: Copy>() -> TreeMap<K, V> { @mut None }
/// Insert a value into the map
pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, k: K, v: V) {
match copy *m {
None => {
*m = Some(@TreeNode({key: k,
mut value: v,
mut left: None,
mut right: None}));
*m = Some(@TreeNode {key: k,
mut value: v,
mut left: None,
mut right: None});
return;
}
Some(node) => {
@ -67,7 +67,8 @@ pub fn find<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, k: K)
}
/// Visit all pairs in the map in order.
pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) {
pub fn traverse<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>,
f: fn((&K), (&V))) {
match copy *m {
None => (),
Some(node) => {
@ -79,6 +80,19 @@ pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) {
}
}
/// Compare two treemaps and return true iff
/// they contain same keys and values
pub fn equals<K: Copy Eq Ord, V: Copy Eq>(t1: &const TreeEdge<K, V>,
t2: &const TreeEdge<K, V>)
-> bool {
let mut v1 = ~[];
let mut v2 = ~[];
traverse(t1, |k,v| { v1.push((copy *k, copy *v)) });
traverse(t2, |k,v| { v2.push((copy *k, copy *v)) });
return v1 == v2;
}
#[cfg(test)]
mod tests {
#[legacy_exports];
@ -127,6 +141,28 @@ mod tests {
traverse(m, |x,y| t(n, *x, *y));
}
#[test]
fn equality() {
let m1 = TreeMap();
insert(m1, 3, ());
insert(m1, 0, ());
insert(m1, 4, ());
insert(m1, 2, ());
insert(m1, 1, ());
let m2 = TreeMap();
insert(m2, 2, ());
insert(m2, 1, ());
insert(m2, 3, ());
insert(m2, 0, ());
insert(m2, 4, ());
assert equals(m1, m2);
let m3 = TreeMap();
assert !equals(m1,m3);
}
#[test]
fn u8_map() {
let m = TreeMap();

View file

@ -590,6 +590,8 @@ extern mod rustrt {
-> libc::c_int;
fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t)
-> libc::c_int;
fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint;
fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint;
// FIXME ref #2064
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
tcp_handle_ptr: *uv_tcp_t,
@ -606,6 +608,10 @@ extern mod rustrt {
// FIXME ref #2064
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
++addr: *sockaddr_in6) -> libc::c_int;
fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in) -> libc::c_int;
fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
++name: *sockaddr_in6) ->libc::c_int;
fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
cb: *u8) -> libc::c_int;
fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
@ -736,6 +742,16 @@ pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t,
addr_ptr);
}
pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
name: *sockaddr_in) -> libc::c_int {
return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name);
}
pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
name: *sockaddr_in6) ->libc::c_int {
return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
}
pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int,
cb: *u8) -> libc::c_int {
return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb);
@ -857,6 +873,12 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
}
}
}
pub unsafe fn ip4_port(src: &sockaddr_in) -> uint {
rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint
}
pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint {
rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint
}
pub unsafe fn timer_init(loop_ptr: *libc::c_void,
timer_ptr: *uv_timer_t) -> libc::c_int {
@ -1048,7 +1070,7 @@ pub mod test {
as *request_wrapper;
let buf_base = get_base_from_buf(buf);
let buf_len = get_len_from_buf(buf);
let bytes = vec::raw::from_buf(buf_base, buf_len as uint);
let bytes = vec::from_buf(buf_base, buf_len as uint);
let read_chan = *((*client_data).read_chan);
let msg_from_server = str::from_bytes(bytes);
core::comm::send(read_chan, msg_from_server);
@ -1223,7 +1245,7 @@ pub mod test {
buf_base as uint,
buf_len as uint,
nread));
let bytes = vec::raw::from_buf(buf_base, buf_len);
let bytes = vec::from_buf(buf_base, buf_len);
let request_str = str::from_bytes(bytes);
let client_data = get_data_for_uv_handle(
@ -1462,7 +1484,7 @@ pub mod test {
fn impl_uv_tcp_server_and_request() unsafe {
let bind_ip = ~"0.0.0.0";
let request_ip = ~"127.0.0.1";
let port = 8887;
let port = 8886;
let kill_server_msg = ~"does a dog have buddha nature?";
let server_resp_msg = ~"mu!";
let client_port = core::comm::Port::<~str>();

View file

@ -1,33 +1,14 @@
// The Rust abstract syntax tree.
use std::serialization::{Serializable,
Deserializable,
Serializer,
Deserializer};
use codemap::{span, filename};
use std::serialization::{Serializer,
Deserializer,
serialize_Option,
deserialize_Option,
serialize_uint,
deserialize_uint,
serialize_int,
deserialize_int,
serialize_i64,
deserialize_i64,
serialize_u64,
deserialize_u64,
serialize_str,
deserialize_str,
serialize_bool,
deserialize_bool};
use parse::token;
/* Note #1972 -- spans are serialized but not deserialized */
fn serialize_span<S>(_s: S, _v: span) {
}
fn deserialize_span<D>(_d: D) -> span {
ast_util::dummy_sp()
}
#[auto_serialize]
#[auto_deserialize]
type spanned<T> = {node: T, span: span};
@ -42,25 +23,62 @@ macro_rules! interner_key (
// implemented.
struct ident { repr: uint }
fn serialize_ident<S: Serializer>(s: S, i: ident) {
let intr = match unsafe{
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"serialization: TLS interner not set up",
Some(intr) => intr
};
#[cfg(stage0)]
impl ident: Serializable {
fn serialize<S: Serializer>(&self, s: &S) {
let intr = match unsafe {
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"serialization: TLS interner not set up",
Some(intr) => intr
};
s.emit_str(*(*intr).get(i));
s.emit_owned_str(*(*intr).get(*self));
}
}
fn deserialize_ident<D: Deserializer>(d: D) -> ident {
let intr = match unsafe{
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"deserialization: TLS interner not set up",
Some(intr) => intr
};
(*intr).intern(@d.read_str())
#[cfg(stage0)]
impl ident: Deserializable {
static fn deserialize<D: Deserializer>(d: &D) -> ident {
let intr = match unsafe {
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"deserialization: TLS interner not set up",
Some(intr) => intr
};
(*intr).intern(@d.read_owned_str())
}
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<S: Serializer> ident: Serializable<S> {
fn serialize(&self, s: &S) {
let intr = match unsafe {
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"serialization: TLS interner not set up",
Some(intr) => intr
};
s.emit_owned_str(*(*intr).get(*self));
}
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<D: Deserializer> ident: Deserializable<D> {
static fn deserialize(d: &D) -> ident {
let intr = match unsafe {
task::local_data::local_data_get(interner_key!())
} {
None => fail ~"deserialization: TLS interner not set up",
Some(intr) => intr
};
(*intr).intern(@d.read_owned_str())
}
}
impl ident: cmp::Eq {
@ -75,23 +93,22 @@ impl ident: to_bytes::IterBytes {
}
// Functions may or may not have names.
#[auto_serialize]
type fn_ident = Option<ident>;
#[auto_serialize]
#[auto_deserialize]
type path = {span: span,
global: bool,
idents: ~[ident],
rp: Option<@region>,
types: ~[@ty]};
types: ~[@Ty]};
#[auto_serialize]
type crate_num = int;
#[auto_serialize]
type node_id = int;
#[auto_serialize]
#[auto_deserialize]
type def_id = {crate: crate_num, node: node_id};
impl def_id : cmp::Eq {
@ -105,21 +122,24 @@ const local_crate: crate_num = 0;
const crate_node_id: node_id = 0;
#[auto_serialize]
enum ty_param_bound {
bound_copy,
bound_send,
bound_const,
bound_owned,
bound_trait(@ty),
}
#[auto_deserialize]
// The AST represents all type param bounds as types.
// typeck::collect::compute_bounds matches these against
// the "special" built-in traits (see middle::lang_items) and
// detects Copy, Send, Owned, and Const.
enum ty_param_bound = @Ty;
#[auto_serialize]
#[auto_deserialize]
type ty_param = {ident: ident, id: node_id, bounds: @~[ty_param_bound]};
#[auto_serialize]
#[auto_deserialize]
enum def {
def_fn(def_id, purity),
def_static_method(def_id, purity),
def_static_method(/* method */ def_id,
/* trait */ Option<def_id>,
purity),
def_self(node_id),
def_mod(def_id),
def_foreign_mod(def_id),
@ -136,7 +156,7 @@ enum def {
@def, // closed over def
node_id, // expr node that creates the closure
node_id), // id for the block/body of the closure expr
def_class(def_id, bool /* has constructor */),
def_class(def_id),
def_typaram_binder(node_id), /* class, impl or trait that has ty params */
def_region(node_id),
def_label(node_id)
@ -151,9 +171,10 @@ impl def : cmp::Eq {
_ => false
}
}
def_static_method(e0a, e1a) => {
def_static_method(e0a, e1a, e2a) => {
match (*other) {
def_static_method(e0b, e1b) => e0a == e0b && e1a == e1b,
def_static_method(e0b, e1b, e2b) =>
e0a == e0b && e1a == e1b && e2a == e2b,
_ => false
}
}
@ -236,9 +257,9 @@ impl def : cmp::Eq {
_ => false
}
}
def_class(e0a, e1a) => {
def_class(e0a) => {
match (*other) {
def_class(e0b, e1b) => e0a == e0b && e1a == e1b,
def_class(e0b) => e0a == e0b,
_ => false
}
}
@ -293,20 +314,20 @@ enum crate_directive_ {
type crate_directive = spanned<crate_directive_>;
#[auto_serialize]
type meta_item = spanned<meta_item_>;
#[auto_serialize]
#[auto_deserialize]
enum meta_item_ {
meta_word(~str),
meta_list(~str, ~[@meta_item]),
meta_name_value(~str, lit),
}
#[auto_serialize]
type blk = spanned<blk_>;
#[auto_serialize]
#[auto_deserialize]
type blk_ = {view_items: ~[@view_item],
stmts: ~[@stmt],
expr: Option<@expr>,
@ -314,12 +335,15 @@ type blk_ = {view_items: ~[@view_item],
rules: blk_check_mode};
#[auto_serialize]
#[auto_deserialize]
type pat = {id: node_id, node: pat_, span: span};
#[auto_serialize]
#[auto_deserialize]
type field_pat = {ident: ident, pat: @pat};
#[auto_serialize]
#[auto_deserialize]
enum binding_mode {
bind_by_value,
bind_by_move,
@ -376,6 +400,7 @@ impl binding_mode : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum pat_ {
pat_wild,
// A pat_ident may either be a new bound variable,
@ -399,6 +424,7 @@ enum pat_ {
}
#[auto_serialize]
#[auto_deserialize]
enum mutability { m_mutbl, m_imm, m_const, }
impl mutability : to_bytes::IterBytes {
@ -415,6 +441,7 @@ impl mutability : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum proto {
proto_bare, // foreign fn
proto_uniq, // fn~
@ -430,18 +457,20 @@ impl proto : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum vstore {
// FIXME (#2112): Change uint to @expr (actually only constant exprs)
vstore_fixed(Option<uint>), // [1,2,3,4]/_ or 4
// FIXME (#3469): Change uint to @expr (actually only constant exprs)
vstore_fixed(Option<uint>), // [1,2,3,4]
vstore_uniq, // ~[1,2,3,4]
vstore_box, // @[1,2,3,4]
vstore_slice(@region) // &[1,2,3,4](foo)?
}
#[auto_serialize]
#[auto_deserialize]
enum expr_vstore {
// FIXME (#2112): Change uint to @expr (actually only constant exprs)
expr_vstore_fixed(Option<uint>), // [1,2,3,4]/_ or 4
// FIXME (#3469): Change uint to @expr (actually only constant exprs)
expr_vstore_fixed(Option<uint>), // [1,2,3,4]
expr_vstore_uniq, // ~[1,2,3,4]
expr_vstore_box, // @[1,2,3,4]
expr_vstore_slice // &[1,2,3,4]
@ -455,6 +484,7 @@ pure fn is_blockish(p: ast::proto) -> bool {
}
#[auto_serialize]
#[auto_deserialize]
enum binop {
add,
subtract,
@ -484,6 +514,7 @@ impl binop : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum unop {
box(mutability),
uniq(mutability),
@ -535,6 +566,7 @@ impl unop : cmp::Eq {
// Generally, after typeck you can get the inferred value
// using ty::resolved_T(...).
#[auto_serialize]
#[auto_deserialize]
enum inferable<T> {
expl(T),
infer(node_id)
@ -574,6 +606,7 @@ impl<T:cmp::Eq> inferable<T> : cmp::Eq {
// "resolved" mode: the real modes.
#[auto_serialize]
#[auto_deserialize]
enum rmode { by_ref, by_val, by_move, by_copy }
impl rmode : to_bytes::IterBytes {
@ -591,13 +624,12 @@ impl rmode : cmp::Eq {
}
// inferable mode.
#[auto_serialize]
type mode = inferable<rmode>;
#[auto_serialize]
type stmt = spanned<stmt_>;
#[auto_serialize]
#[auto_deserialize]
enum stmt_ {
stmt_decl(@decl, node_id),
@ -609,6 +641,7 @@ enum stmt_ {
}
#[auto_serialize]
#[auto_deserialize]
enum init_op { init_assign, init_move, }
impl init_op : cmp::Eq {
@ -632,33 +665,36 @@ impl init_op : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
type initializer = {op: init_op, expr: @expr};
// FIXME (pending discussion of #1697, #2178...): local should really be
// a refinement on pat.
#[auto_serialize]
type local_ = {is_mutbl: bool, ty: @ty, pat: @pat,
#[auto_deserialize]
type local_ = {is_mutbl: bool, ty: @Ty, pat: @pat,
init: Option<initializer>, id: node_id};
#[auto_serialize]
type local = spanned<local_>;
#[auto_serialize]
type decl = spanned<decl_>;
#[auto_serialize]
#[auto_deserialize]
enum decl_ { decl_local(~[@local]), decl_item(@item), }
#[auto_serialize]
#[auto_deserialize]
type arm = {pats: ~[@pat], guard: Option<@expr>, body: blk};
#[auto_serialize]
#[auto_deserialize]
type field_ = {mutbl: mutability, ident: ident, expr: @expr};
#[auto_serialize]
type field = spanned<field_>;
#[auto_serialize]
#[auto_deserialize]
enum blk_check_mode { default_blk, unsafe_blk, }
impl blk_check_mode : cmp::Eq {
@ -674,17 +710,17 @@ impl blk_check_mode : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
type expr = {id: node_id, callee_id: node_id, node: expr_, span: span};
// Extra node ID is only used for index, assign_op, unary, binary
#[auto_serialize]
#[auto_deserialize]
enum log_level { error, debug, other }
// 0 = error, 1 = debug, 2 = other
#[auto_serialize]
enum alt_mode { alt_check, alt_exhaustive, }
#[auto_serialize]
#[auto_deserialize]
enum expr_ {
expr_vstore(@expr, expr_vstore),
expr_vec(~[@expr], mutability),
@ -694,7 +730,7 @@ enum expr_ {
expr_binary(binop, @expr, @expr),
expr_unary(unop, @expr),
expr_lit(@lit),
expr_cast(@expr, @ty),
expr_cast(@expr, @Ty),
expr_if(@expr, blk, Option<@expr>),
expr_while(@expr, blk),
/* Conditionless loop (can be exited with break, cont, ret, or fail)
@ -718,7 +754,7 @@ enum expr_ {
expr_assign(@expr, @expr),
expr_swap(@expr, @expr),
expr_assign_op(binop, @expr, @expr),
expr_field(@expr, ident, ~[@ty]),
expr_field(@expr, ident, ~[@Ty]),
expr_index(@expr, @expr),
expr_path(@path),
expr_addr_of(mutability, @expr),
@ -741,14 +777,16 @@ enum expr_ {
}
#[auto_serialize]
type capture_item = @{
#[auto_deserialize]
type capture_item_ = {
id: int,
is_move: bool,
name: ident, // Currently, can only capture a local var.
span: span
};
#[auto_serialize]
type capture_item = @capture_item_;
type capture_clause = @~[capture_item];
//
@ -768,12 +806,13 @@ type capture_clause = @~[capture_item];
// error.
//
#[auto_serialize]
#[auto_deserialize]
#[doc="For macro invocations; parsing is delegated to the macro"]
enum token_tree {
tt_tok(span, token::token),
tt_tok(span, token::Token),
tt_delim(~[token_tree]),
// These only make sense for right-hand-sides of MBE macros
tt_seq(span, ~[token_tree], Option<token::token>, bool),
tt_seq(span, ~[token_tree], Option<token::Token>, bool),
tt_nonterminal(span, ident)
}
@ -829,33 +868,32 @@ enum token_tree {
// If you understand that, you have closed to loop and understand the whole
// macro system. Congratulations.
//
#[auto_serialize]
type matcher = spanned<matcher_>;
#[auto_serialize]
#[auto_deserialize]
enum matcher_ {
// match one token
match_tok(token::token),
match_tok(token::Token),
// match repetitions of a sequence: body, separator, zero ok?,
// lo, hi position-in-match-array used:
match_seq(~[matcher], Option<token::token>, bool, uint, uint),
match_seq(~[matcher], Option<token::Token>, bool, uint, uint),
// parse a Rust NT: name to bind, name of NT, position in match array:
match_nonterminal(ident, ident, uint)
}
#[auto_serialize]
type mac = spanned<mac_>;
#[auto_serialize]
type mac_arg = Option<@expr>;
#[auto_serialize]
#[auto_deserialize]
type mac_body_ = {span: span};
#[auto_serialize]
type mac_body = Option<mac_body_>;
#[auto_serialize]
#[auto_deserialize]
enum mac_ {
mac_invoc(@path, mac_arg, mac_body), // old macro-invocation
mac_invoc_tt(@path,~[token_tree]), // new macro-invocation
@ -866,10 +904,10 @@ enum mac_ {
mac_var(uint)
}
#[auto_serialize]
type lit = spanned<lit_>;
#[auto_serialize]
#[auto_deserialize]
enum lit_ {
lit_str(@~str),
lit_int(i64, int_ty),
@ -911,20 +949,23 @@ impl ast::lit_: cmp::Eq {
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[auto_serialize]
type mt = {ty: @ty, mutbl: mutability};
#[auto_deserialize]
type mt = {ty: @Ty, mutbl: mutability};
#[auto_serialize]
#[auto_deserialize]
type ty_field_ = {ident: ident, mt: mt};
#[auto_serialize]
type ty_field = spanned<ty_field_>;
#[auto_serialize]
#[auto_deserialize]
type ty_method = {ident: ident, attrs: ~[attribute], purity: purity,
decl: fn_decl, tps: ~[ty_param], self_ty: self_ty,
id: node_id, span: span};
#[auto_serialize]
#[auto_deserialize]
// A trait method is either required (meaning it doesn't have an
// implementation, just a signature) or provided (meaning it has a default
// implementation).
@ -934,6 +975,7 @@ enum trait_method {
}
#[auto_serialize]
#[auto_deserialize]
enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
impl int_ty : to_bytes::IterBytes {
@ -963,6 +1005,7 @@ impl int_ty : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
impl uint_ty : to_bytes::IterBytes {
@ -990,6 +1033,7 @@ impl uint_ty : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum float_ty { ty_f, ty_f32, ty_f64, }
impl float_ty : to_bytes::IterBytes {
@ -1008,10 +1052,12 @@ impl float_ty : cmp::Eq {
}
#[auto_serialize]
type ty = {id: node_id, node: ty_, span: span};
#[auto_deserialize]
type Ty = {id: node_id, node: ty_, span: span};
// Not represented directly in the AST, referred to by name through a ty_path.
#[auto_serialize]
#[auto_deserialize]
enum prim_ty {
ty_int(int_ty),
ty_uint(uint_ty),
@ -1059,9 +1105,11 @@ impl prim_ty : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
type region = {id: node_id, node: region_};
#[auto_serialize]
#[auto_deserialize]
enum region_ {
re_anon,
re_static,
@ -1070,6 +1118,7 @@ enum region_ {
}
#[auto_serialize]
#[auto_deserialize]
enum ty_ {
ty_nil,
ty_bot, /* bottom type */
@ -1080,9 +1129,9 @@ enum ty_ {
ty_rptr(@region, mt),
ty_rec(~[ty_field]),
ty_fn(proto, purity, @~[ty_param_bound], fn_decl),
ty_tup(~[@ty]),
ty_tup(~[@Ty]),
ty_path(@path, node_id),
ty_fixed_length(@ty, Option<uint>),
ty_fixed_length(@Ty, Option<uint>),
ty_mac(mac),
// ty_infer means the type should be inferred instead of it having been
// specified. This should only appear at the "top level" of a type and not
@ -1092,16 +1141,16 @@ enum ty_ {
// Equality and byte-iter (hashing) can be quite approximate for AST types.
// since we only care about this for normalizing them to "real" types.
impl ty : cmp::Eq {
pure fn eq(other: &ty) -> bool {
impl Ty : cmp::Eq {
pure fn eq(other: &Ty) -> bool {
ptr::addr_of(&self) == ptr::addr_of(&(*other))
}
pure fn ne(other: &ty) -> bool {
pure fn ne(other: &Ty) -> bool {
ptr::addr_of(&self) != ptr::addr_of(&(*other))
}
}
impl ty : to_bytes::IterBytes {
impl Ty : to_bytes::IterBytes {
pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f);
}
@ -1109,15 +1158,18 @@ impl ty : to_bytes::IterBytes {
#[auto_serialize]
type arg = {mode: mode, ty: @ty, ident: ident, id: node_id};
#[auto_deserialize]
type arg = {mode: mode, ty: @Ty, ident: ident, id: node_id};
#[auto_serialize]
#[auto_deserialize]
type fn_decl =
{inputs: ~[arg],
output: @ty,
output: @Ty,
cf: ret_style};
#[auto_serialize]
#[auto_deserialize]
enum purity {
pure_fn, // declared with "pure fn"
unsafe_fn, // declared with "unsafe fn"
@ -1139,6 +1191,7 @@ impl purity : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum ret_style {
noreturn, // functions with return type _|_ that always
// raise an error or exit (i.e. never return to the caller)
@ -1164,6 +1217,7 @@ impl ret_style : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
enum self_ty_ {
sty_static, // no self: static method
sty_by_ref, // old by-reference self: ``
@ -1217,10 +1271,10 @@ impl self_ty_ : cmp::Eq {
pure fn ne(other: &self_ty_) -> bool { !self.eq(other) }
}
#[auto_serialize]
type self_ty = spanned<self_ty_>;
#[auto_serialize]
#[auto_deserialize]
type method = {ident: ident, attrs: ~[attribute],
tps: ~[ty_param], self_ty: self_ty,
purity: purity, decl: fn_decl, body: blk,
@ -1228,9 +1282,11 @@ type method = {ident: ident, attrs: ~[attribute],
vis: visibility};
#[auto_serialize]
#[auto_deserialize]
type _mod = {view_items: ~[@view_item], items: ~[@item]};
#[auto_serialize]
#[auto_deserialize]
enum foreign_abi {
foreign_abi_rust_intrinsic,
foreign_abi_cdecl,
@ -1239,6 +1295,7 @@ enum foreign_abi {
// Foreign mods can be named or anonymous
#[auto_serialize]
#[auto_deserialize]
enum foreign_mod_sort { named, anonymous }
impl foreign_mod_sort : cmp::Eq {
@ -1263,15 +1320,18 @@ impl foreign_abi : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
type foreign_mod =
{sort: foreign_mod_sort,
view_items: ~[@view_item],
items: ~[@foreign_item]};
#[auto_serialize]
type variant_arg = {ty: @ty, id: node_id};
#[auto_deserialize]
type variant_arg = {ty: @Ty, id: node_id};
#[auto_serialize]
#[auto_deserialize]
enum variant_kind {
tuple_variant_kind(~[variant_arg]),
struct_variant_kind(@struct_def),
@ -1279,22 +1339,28 @@ enum variant_kind {
}
#[auto_serialize]
enum enum_def = { variants: ~[variant], common: Option<@struct_def> };
#[auto_deserialize]
type enum_def_ = { variants: ~[variant], common: Option<@struct_def> };
#[auto_serialize]
#[auto_deserialize]
enum enum_def = enum_def_;
#[auto_serialize]
#[auto_deserialize]
type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
id: node_id, disr_expr: Option<@expr>, vis: visibility};
#[auto_serialize]
type variant = spanned<variant_>;
#[auto_serialize]
#[auto_deserialize]
type path_list_ident_ = {name: ident, id: node_id};
#[auto_serialize]
type path_list_ident = spanned<path_list_ident_>;
#[auto_serialize]
#[auto_deserialize]
enum namespace { module_ns, type_value_ns }
impl namespace : cmp::Eq {
@ -1304,10 +1370,10 @@ impl namespace : cmp::Eq {
pure fn ne(other: &namespace) -> bool { !self.eq(other) }
}
#[auto_serialize]
type view_path = spanned<view_path_>;
#[auto_serialize]
#[auto_deserialize]
enum view_path_ {
// quux = foo::bar::baz
@ -1325,10 +1391,12 @@ enum view_path_ {
}
#[auto_serialize]
#[auto_deserialize]
type view_item = {node: view_item_, attrs: ~[attribute],
vis: visibility, span: span};
#[auto_serialize]
#[auto_deserialize]
enum view_item_ {
view_item_use(ident, ~[@meta_item], node_id),
view_item_import(~[@view_path]),
@ -1336,13 +1404,13 @@ enum view_item_ {
}
// Meta-data associated with an item
#[auto_serialize]
type attribute = spanned<attribute_>;
// Distinguishes between attributes that decorate items and attributes that
// are contained as statements within items. These two cases need to be
// distinguished for pretty-printing.
#[auto_serialize]
#[auto_deserialize]
enum attr_style { attr_outer, attr_inner, }
impl attr_style : cmp::Eq {
@ -1354,6 +1422,7 @@ impl attr_style : cmp::Eq {
// doc-comments are promoted to attributes that have is_sugared_doc = true
#[auto_serialize]
#[auto_deserialize]
type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
/*
@ -1366,9 +1435,11 @@ type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
trait)
*/
#[auto_serialize]
#[auto_deserialize]
type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id};
#[auto_serialize]
#[auto_deserialize]
enum visibility { public, private, inherited }
impl visibility : cmp::Eq {
@ -1386,29 +1457,29 @@ impl visibility : cmp::Eq {
}
#[auto_serialize]
#[auto_deserialize]
type struct_field_ = {
kind: struct_field_kind,
id: node_id,
ty: @ty
ty: @Ty
};
#[auto_serialize]
type struct_field = spanned<struct_field_>;
#[auto_serialize]
#[auto_deserialize]
enum struct_field_kind {
named_field(ident, class_mutability, visibility),
unnamed_field // element of a tuple-like struct
}
#[auto_serialize]
#[auto_deserialize]
type struct_def = {
traits: ~[@trait_ref], /* traits this struct implements */
fields: ~[@struct_field], /* fields */
methods: ~[@method], /* methods */
/* (not including ctor or dtor) */
/* ctor is optional, and will soon go away */
ctor: Option<class_ctor>,
/* dtor is optional */
dtor: Option<class_dtor>
};
@ -1418,28 +1489,31 @@ type struct_def = {
we just use dummy names for anon items.
*/
#[auto_serialize]
#[auto_deserialize]
type item = {ident: ident, attrs: ~[attribute],
id: node_id, node: item_,
vis: visibility, span: span};
#[auto_serialize]
#[auto_deserialize]
enum item_ {
item_const(@ty, @expr),
item_const(@Ty, @expr),
item_fn(fn_decl, purity, ~[ty_param], blk),
item_mod(_mod),
item_foreign_mod(foreign_mod),
item_ty(@ty, ~[ty_param]),
item_ty(@Ty, ~[ty_param]),
item_enum(enum_def, ~[ty_param]),
item_class(@struct_def, ~[ty_param]),
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
item_impl(~[ty_param],
Option<@trait_ref>, /* (optional) trait this impl implements */
@ty, /* self */
@Ty, /* self */
~[@method]),
item_mac(mac),
}
#[auto_serialize]
#[auto_deserialize]
enum class_mutability { class_mutable, class_immutable }
impl class_mutability : to_bytes::IterBytes {
@ -1460,26 +1534,27 @@ impl class_mutability : cmp::Eq {
pure fn ne(other: &class_mutability) -> bool { !self.eq(other) }
}
#[auto_serialize]
type class_ctor = spanned<class_ctor_>;
#[auto_serialize]
#[auto_deserialize]
type class_ctor_ = {id: node_id,
attrs: ~[attribute],
self_id: node_id,
dec: fn_decl,
body: blk};
#[auto_serialize]
type class_dtor = spanned<class_dtor_>;
#[auto_serialize]
#[auto_deserialize]
type class_dtor_ = {id: node_id,
attrs: ~[attribute],
self_id: node_id,
body: blk};
#[auto_serialize]
#[auto_deserialize]
type foreign_item =
{ident: ident,
attrs: ~[attribute],
@ -1489,20 +1564,21 @@ type foreign_item =
vis: visibility};
#[auto_serialize]
#[auto_deserialize]
enum foreign_item_ {
foreign_item_fn(fn_decl, purity, ~[ty_param]),
foreign_item_const(@ty)
foreign_item_const(@Ty)
}
// The data we save and restore about an inlined item or method. This is not
// part of the AST that we parse from a file, but it becomes part of the tree
// that we trans.
#[auto_serialize]
#[auto_deserialize]
enum inlined_item {
ii_item(@item),
ii_method(def_id /* impl id */, @method),
ii_foreign(@foreign_item),
ii_ctor(class_ctor, ident, ~[ty_param], def_id /* parent id */),
ii_dtor(class_dtor, ident, ~[ty_param], def_id /* parent id */)
}

View file

@ -71,9 +71,6 @@ enum ast_node {
// order they are introduced.
node_arg(arg, uint),
node_local(uint),
// Constructor for a class
// def_id is parent id
node_ctor(ident, ~[ty_param], @class_ctor, def_id, @path),
// Destructor for a class
node_dtor(~[ty_param], @class_dtor, def_id, @path),
node_block(blk),
@ -132,7 +129,7 @@ fn map_decoded_item(diag: span_handler,
// don't decode and instantiate the impl, but just the method, we have to
// add it to the table now:
match ii {
ii_item(*) | ii_ctor(*) | ii_dtor(*) => { /* fallthrough */ }
ii_item(*) | ii_dtor(*) => { /* fallthrough */ }
ii_foreign(i) => {
cx.map.insert(i.id, node_foreign_item(i, foreign_abi_rust_intrinsic,
@path));
@ -155,18 +152,6 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
cx.local_id += 1u;
}
match fk {
visit::fk_ctor(nm, attrs, tps, self_id, parent_id) => {
let ct = @{node: {id: id,
attrs: attrs,
self_id: self_id,
dec: /* FIXME (#2543) */ copy decl,
body: /* FIXME (#2543) */ copy body},
span: sp};
cx.map.insert(id, node_ctor(/* FIXME (#2543) */ copy nm,
/* FIXME (#2543) */ copy tps,
ct, parent_id,
@/* FIXME (#2543) */ copy cx.path));
}
visit::fk_dtor(tps, attrs, self_id, parent_id) => {
let dt = @{node: {id: id, attrs: attrs, self_id: self_id,
body: /* FIXME (#2543) */ copy body}, span: sp};
@ -382,9 +367,6 @@ fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str {
Some(node_local(_)) => { // add more info here
fmt!("local (id=%?)", id)
}
Some(node_ctor(*)) => { // add more info here
fmt!("node_ctor (id=%?)", id)
}
Some(node_dtor(*)) => { // add more info here
fmt!("node_dtor (id=%?)", id)
}

View file

@ -54,10 +54,10 @@ fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} {
pure fn def_id_of_def(d: def) -> def_id {
match d {
def_fn(id, _) | def_static_method(id, _) | def_mod(id) |
def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) |
def_foreign_mod(id) | def_const(id) |
def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
def_use(id) | def_class(id, _) => {
def_use(id) | def_class(id) => {
id
}
def_arg(id, _) | def_local(id, _) | def_self(id) |
@ -233,7 +233,6 @@ fn is_exported(i: ident, m: _mod) -> bool {
}
}
// FIXME: glob-exports aren't supported yet. (#2006)
_ => ()
}
}
@ -339,7 +338,6 @@ impl inlined_item: inlined_item_utils {
ii_item(i) => /* FIXME (#2543) */ copy i.ident,
ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
ii_ctor(_, nm, _, _) => /* FIXME (#2543) */ copy nm,
ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
}
}
@ -349,7 +347,6 @@ impl inlined_item: inlined_item_utils {
ii_item(i) => i.id,
ii_foreign(i) => i.id,
ii_method(_, m) => m.id,
ii_ctor(ctor, _, _, _) => ctor.node.id,
ii_dtor(dtor, _, _, _) => dtor.node.id
}
}
@ -359,9 +356,6 @@ impl inlined_item: inlined_item_utils {
ii_item(i) => v.visit_item(i, e, v),
ii_foreign(i) => v.visit_foreign_item(i, e, v),
ii_method(_, m) => visit::visit_method_helper(m, e, v),
ii_ctor(ctor, nm, tps, parent_id) => {
visit::visit_class_ctor_helper(ctor, nm, tps, parent_id, e, v);
}
ii_dtor(dtor, _, tps, parent_id) => {
visit::visit_class_dtor_helper(dtor, tps, parent_id, e, v);
}
@ -407,6 +401,7 @@ fn dtor_dec() -> fn_decl {
// Enumerating the IDs which appear in an AST
#[auto_serialize]
#[auto_deserialize]
type id_range = {min: node_id, max: node_id};
fn empty(range: id_range) -> bool {
@ -476,7 +471,7 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
visit_expr_post: fn@(_e: @expr) {
},
visit_ty: fn@(t: @ty) {
visit_ty: fn@(t: @Ty) {
match t.node {
ty_path(_, id) => vfn(id),
_ => { /* fall through */ }
@ -494,12 +489,6 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
vfn(id);
match fk {
visit::fk_ctor(_, _, tps, self_id, parent_id) => {
for vec::each(tps) |tp| { vfn(tp.id); }
vfn(id);
vfn(self_id);
vfn(parent_id.node);
}
visit::fk_dtor(tps, _, self_id, parent_id) => {
for vec::each(tps) |tp| { vfn(tp.id); }
vfn(id);

View file

@ -90,9 +90,7 @@ fn attr_meta(attr: ast::attribute) -> @ast::meta_item { @attr.node.value }
// Get the meta_items from inside a vector of attributes
fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
let mut mitems = ~[];
for attrs.each |a| { mitems.push(attr_meta(*a)); }
return mitems;
do attrs.map |a| { attr_meta(*a) }
}
fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute {

View file

@ -1,4 +1,8 @@
use dvec::DVec;
use std::serialization::{Serializable,
Deserializable,
Serializer,
Deserializer};
export filename;
export filemap;
@ -7,7 +11,7 @@ export file_substr;
export fss_none;
export fss_internal;
export fss_external;
export codemap;
export CodeMap;
export expn_info;
export expn_info_;
export expanded_from;
@ -55,11 +59,11 @@ type filemap =
@{name: filename, substr: file_substr, src: @~str,
start_pos: file_pos, mut lines: ~[file_pos]};
type codemap = @{files: DVec<filemap>};
type CodeMap = @{files: DVec<filemap>};
type loc = {file: filemap, line: uint, col: uint};
fn new_codemap() -> codemap { @{files: DVec()} }
fn new_codemap() -> CodeMap { @{files: DVec()} }
fn new_filemap_w_substr(+filename: filename, +substr: file_substr,
src: @~str,
@ -77,7 +81,7 @@ fn new_filemap(+filename: filename, src: @~str,
start_pos_ch, start_pos_byte);
}
fn mk_substr_filename(cm: codemap, sp: span) -> ~str
fn mk_substr_filename(cm: CodeMap, sp: span) -> ~str
{
let pos = lookup_char_pos(cm, sp.lo);
return fmt!("<%s:%u:%u>", pos.file.name, pos.line, pos.col);
@ -89,7 +93,7 @@ fn next_line(file: filemap, chpos: uint, byte_pos: uint) {
type lookup_fn = pure fn(file_pos) -> uint;
fn lookup_line(map: codemap, pos: uint, lookup: lookup_fn)
fn lookup_line(map: CodeMap, pos: uint, lookup: lookup_fn)
-> {fm: filemap, line: uint}
{
let len = map.files.len();
@ -112,22 +116,22 @@ fn lookup_line(map: codemap, pos: uint, lookup: lookup_fn)
return {fm: f, line: a};
}
fn lookup_pos(map: codemap, pos: uint, lookup: lookup_fn) -> loc {
fn lookup_pos(map: CodeMap, pos: uint, lookup: lookup_fn) -> loc {
let {fm: f, line: a} = lookup_line(map, pos, lookup);
return {file: f, line: a + 1u, col: pos - lookup(f.lines[a])};
}
fn lookup_char_pos(map: codemap, pos: uint) -> loc {
fn lookup_char_pos(map: CodeMap, pos: uint) -> loc {
pure fn lookup(pos: file_pos) -> uint { return pos.ch; }
return lookup_pos(map, pos, lookup);
}
fn lookup_byte_pos(map: codemap, pos: uint) -> loc {
fn lookup_byte_pos(map: CodeMap, pos: uint) -> loc {
pure fn lookup(pos: file_pos) -> uint { return pos.byte; }
return lookup_pos(map, pos, lookup);
}
fn lookup_char_pos_adj(map: codemap, pos: uint)
fn lookup_char_pos_adj(map: CodeMap, pos: uint)
-> {filename: ~str, line: uint, col: uint, file: Option<filemap>}
{
let loc = lookup_char_pos(map, pos);
@ -150,7 +154,7 @@ fn lookup_char_pos_adj(map: codemap, pos: uint)
}
}
fn adjust_span(map: codemap, sp: span) -> span {
fn adjust_span(map: CodeMap, sp: span) -> span {
pure fn lookup(pos: file_pos) -> uint { return pos.ch; }
let line = lookup_line(map, sp.lo, lookup);
match (line.fm.substr) {
@ -178,14 +182,42 @@ impl span : cmp::Eq {
pure fn ne(other: &span) -> bool { !self.eq(other) }
}
fn span_to_str_no_adj(sp: span, cm: codemap) -> ~str {
#[cfg(stage0)]
impl span: Serializable {
/* Note #1972 -- spans are serialized but not deserialized */
fn serialize<S: Serializer>(&self, _s: &S) { }
}
#[cfg(stage0)]
impl span: Deserializable {
static fn deserialize<D: Deserializer>(_d: &D) -> span {
ast_util::dummy_sp()
}
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<S: Serializer> span: Serializable<S> {
/* Note #1972 -- spans are serialized but not deserialized */
fn serialize(&self, _s: &S) { }
}
#[cfg(stage1)]
#[cfg(stage2)]
impl<D: Deserializer> span: Deserializable<D> {
static fn deserialize(_d: &D) -> span {
ast_util::dummy_sp()
}
}
fn span_to_str_no_adj(sp: span, cm: CodeMap) -> ~str {
let lo = lookup_char_pos(cm, sp.lo);
let hi = lookup_char_pos(cm, sp.hi);
return fmt!("%s:%u:%u: %u:%u", lo.file.name,
lo.line, lo.col, hi.line, hi.col)
}
fn span_to_str(sp: span, cm: codemap) -> ~str {
fn span_to_str(sp: span, cm: CodeMap) -> ~str {
let lo = lookup_char_pos_adj(cm, sp.lo);
let hi = lookup_char_pos_adj(cm, sp.hi);
return fmt!("%s:%u:%u: %u:%u", lo.filename,
@ -194,12 +226,12 @@ fn span_to_str(sp: span, cm: codemap) -> ~str {
type file_lines = {file: filemap, lines: ~[uint]};
fn span_to_filename(sp: span, cm: codemap::codemap) -> filename {
fn span_to_filename(sp: span, cm: codemap::CodeMap) -> filename {
let lo = lookup_char_pos(cm, sp.lo);
return /* FIXME (#2543) */ copy lo.file.name;
}
fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
fn span_to_lines(sp: span, cm: codemap::CodeMap) -> @file_lines {
let lo = lookup_char_pos(cm, sp.lo);
let hi = lookup_char_pos(cm, sp.hi);
let mut lines = ~[];
@ -218,7 +250,7 @@ fn get_line(fm: filemap, line: int) -> ~str unsafe {
str::slice(*fm.src, begin, end)
}
fn lookup_byte_offset(cm: codemap::codemap, chpos: uint)
fn lookup_byte_offset(cm: codemap::CodeMap, chpos: uint)
-> {fm: filemap, pos: uint} {
pure fn lookup(pos: file_pos) -> uint { return pos.ch; }
let {fm, line} = lookup_line(cm, chpos, lookup);
@ -228,20 +260,20 @@ fn lookup_byte_offset(cm: codemap::codemap, chpos: uint)
{fm: fm, pos: line_offset + col_offset}
}
fn span_to_snippet(sp: span, cm: codemap::codemap) -> ~str {
fn span_to_snippet(sp: span, cm: codemap::CodeMap) -> ~str {
let begin = lookup_byte_offset(cm, sp.lo);
let end = lookup_byte_offset(cm, sp.hi);
assert begin.fm.start_pos == end.fm.start_pos;
return str::slice(*begin.fm.src, begin.pos, end.pos);
}
fn get_snippet(cm: codemap::codemap, fidx: uint, lo: uint, hi: uint) -> ~str
fn get_snippet(cm: codemap::CodeMap, fidx: uint, lo: uint, hi: uint) -> ~str
{
let fm = cm.files[fidx];
return str::slice(*fm.src, lo, hi)
}
fn get_filemap(cm: codemap, filename: ~str) -> filemap {
fn get_filemap(cm: CodeMap, filename: ~str) -> filemap {
for cm.files.each |fm| { if fm.name == filename { return *fm; } }
//XXjdm the following triggers a mismatched type bug
// (or expected function, found _|_)

View file

@ -9,7 +9,7 @@ export codemap_span_handler, codemap_handler;
export ice_msg;
export expect;
type emitter = fn@(cmsp: Option<(codemap::codemap, span)>,
type emitter = fn@(cmsp: Option<(codemap::CodeMap, span)>,
msg: &str, lvl: level);
@ -33,7 +33,7 @@ trait handler {
fn note(msg: &str);
fn bug(msg: &str) -> !;
fn unimpl(msg: &str) -> !;
fn emit(cmsp: Option<(codemap::codemap, span)>, msg: &str, lvl: level);
fn emit(cmsp: Option<(codemap::CodeMap, span)>, msg: &str, lvl: level);
}
type handler_t = @{
@ -43,7 +43,7 @@ type handler_t = @{
type codemap_t = @{
handler: handler,
cm: codemap::codemap
cm: codemap::CodeMap
};
impl codemap_t: span_handler {
@ -107,7 +107,7 @@ impl handler_t: handler {
self.fatal(ice_msg(msg));
}
fn unimpl(msg: &str) -> ! { self.bug(~"unimplemented " + msg); }
fn emit(cmsp: Option<(codemap::codemap, span)>, msg: &str, lvl: level) {
fn emit(cmsp: Option<(codemap::CodeMap, span)>, msg: &str, lvl: level) {
self.emit(cmsp, msg, lvl);
}
}
@ -116,7 +116,7 @@ fn ice_msg(msg: &str) -> ~str {
fmt!("internal compiler error: %s", msg)
}
fn mk_span_handler(handler: handler, cm: codemap::codemap) -> span_handler {
fn mk_span_handler(handler: handler, cm: codemap::CodeMap) -> span_handler {
@{ handler: handler, cm: cm } as span_handler
}
@ -125,7 +125,7 @@ fn mk_handler(emitter: Option<emitter>) -> handler {
let emit = match emitter {
Some(e) => e,
None => {
let f = fn@(cmsp: Option<(codemap::codemap, span)>,
let f = fn@(cmsp: Option<(codemap::CodeMap, span)>,
msg: &str, t: level) {
emit(cmsp, msg, t);
};
@ -189,8 +189,7 @@ fn print_diagnostic(topic: ~str, lvl: level, msg: &str) {
io::stderr().write_str(fmt!(" %s\n", msg));
}
fn emit(cmsp: Option<(codemap::codemap, span)>,
msg: &str, lvl: level) {
fn emit(cmsp: Option<(codemap::CodeMap, span)>, msg: &str, lvl: level) {
match cmsp {
Some((cm, sp)) => {
let sp = codemap::adjust_span(cm,sp);
@ -206,7 +205,7 @@ fn emit(cmsp: Option<(codemap::codemap, span)>,
}
}
fn highlight_lines(cm: codemap::codemap, sp: span,
fn highlight_lines(cm: codemap::CodeMap, sp: span,
lines: @codemap::file_lines) {
let fm = lines.file;
@ -261,12 +260,12 @@ fn highlight_lines(cm: codemap::codemap, sp: span,
}
}
fn print_macro_backtrace(cm: codemap::codemap, sp: span) {
fn print_macro_backtrace(cm: codemap::CodeMap, sp: span) {
do option::iter(&sp.expn_info) |ei| {
let ss = option::map_default(&ei.callie.span, @~"",
|span| @codemap::span_to_str(*span, cm));
print_diagnostic(*ss, note,
fmt!("in expansion of #%s", ei.callie.name));
fmt!("in expansion of %s!", ei.callie.name));
let ss = codemap::span_to_str(ei.call_site, cm);
print_diagnostic(ss, note, ~"expansion site");
print_macro_backtrace(cm, ei.call_site);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
use std::map::HashMap;
use parse::parser;
use diagnostic::span_handler;
use codemap::{codemap, span, expn_info, expanded_from};
use codemap::{CodeMap, span, expn_info, expanded_from};
// obsolete old-style #macro code:
//
@ -80,14 +80,12 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
builtin_item_tt(
ext::tt::macro_rules::add_new_extension));
syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext));
syntax_expanders.insert(~"auto_serialize",
item_decorator(ext::auto_serialize::expand));
syntax_expanders.insert(
~"auto_serialize2",
item_decorator(ext::auto_serialize2::expand_auto_serialize));
~"auto_serialize",
item_decorator(ext::auto_serialize::expand_auto_serialize));
syntax_expanders.insert(
~"auto_deserialize2",
item_decorator(ext::auto_serialize2::expand_auto_deserialize));
~"auto_deserialize",
item_decorator(ext::auto_serialize::expand_auto_deserialize));
syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext));
syntax_expanders.insert(~"concat_idents",
builtin(ext::concat_idents::expand_syntax_ext));
@ -122,12 +120,11 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
return syntax_expanders;
}
// One of these is made during expansion and incrementally updated as we go;
// when a macro expansion occurs, the resulting nodes have the backtrace()
// -> expn_info of their expansion context stored into their span.
trait ext_ctxt {
fn codemap() -> codemap;
fn codemap() -> CodeMap;
fn parse_sess() -> parse::parse_sess;
fn cfg() -> ast::crate_cfg;
fn print_backtrace();
@ -159,7 +156,7 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
mut mod_path: ~[ast::ident],
mut trace_mac: bool};
impl ctxt_repr: ext_ctxt {
fn codemap() -> codemap { self.parse_sess.cm }
fn codemap() -> CodeMap { self.parse_sess.cm }
fn parse_sess() -> parse::parse_sess { self.parse_sess }
fn cfg() -> ast::crate_cfg { self.cfg }
fn print_backtrace() { }
@ -234,7 +231,7 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
mut mod_path: ~[],
mut trace_mac: false
};
move (imp as ext_ctxt)
move ((move imp) as ext_ctxt)
}
fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, error: ~str) -> ~str {
@ -272,21 +269,21 @@ fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
match max {
Some(max) if ! (min <= elts_len && elts_len <= max) => {
cx.span_fatal(sp,
fmt!("#%s takes between %u and %u arguments.",
fmt!("%s! takes between %u and %u arguments.",
name, min, max));
}
None if ! (min <= elts_len) => {
cx.span_fatal(sp, fmt!("#%s needs at least %u arguments.",
cx.span_fatal(sp, fmt!("%s! needs at least %u arguments.",
name, min));
}
_ => return elts /* we are good */
}
}
_ => {
cx.span_fatal(sp, fmt!("#%s: malformed invocation", name))
cx.span_fatal(sp, fmt!("%s!: malformed invocation", name))
}
},
None => cx.span_fatal(sp, fmt!("#%s: missing arguments", name))
None => cx.span_fatal(sp, fmt!("%s!: missing arguments", name))
}
}

View file

@ -1,6 +1,6 @@
/*
* The compiler code necessary to support the #env extension. Eventually this
* The compiler code necessary to support the env! extension. Eventually this
* should all get sucked into either the compiler syntax extension plugin
* interface.
*/
@ -15,7 +15,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
// FIXME (#2248): if this was more thorough it would manufacture an
// Option<str> rather than just an maybe-empty string.
let var = expr_to_str(cx, args[0], ~"#env requires a string");
let var = expr_to_str(cx, args[0], ~"env! requires a string");
match os::getenv(var) {
option::None => return mk_uniq_str(cx, sp, ~""),
option::Some(s) => return mk_uniq_str(cx, sp, s)

View file

@ -1,7 +1,7 @@
/*
* The compiler code necessary to support the #fmt extension. Eventually this
* The compiler code necessary to support the fmt! extension. Eventually this
* should all get sucked into either the standard library extfmt module or the
* compiler syntax extension plugin interface.
*/
@ -16,7 +16,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
let args = get_mac_args_no_max(cx, sp, arg, 1u, ~"fmt");
let fmt =
expr_to_str(cx, args[0],
~"first argument to #fmt must be a string literal.");
~"first argument to fmt! must be a string literal.");
let fmtspan = args[0].span;
debug!("Format string:");
log(debug, fmt);
@ -76,7 +76,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
let count_is_args = ~[count_lit];
return mk_call(cx, sp, count_is_path, count_is_args);
}
_ => cx.span_unimpl(sp, ~"unimplemented #fmt conversion")
_ => cx.span_unimpl(sp, ~"unimplemented fmt! conversion")
}
}
fn make_ty(cx: ext_ctxt, sp: span, t: Ty) -> @ast::expr {
@ -133,7 +133,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
_ => return false
}
}
let unsupported = ~"conversion not supported in #fmt string";
let unsupported = ~"conversion not supported in fmt! string";
match cnv.param {
option::None => (),
_ => cx.span_unimpl(sp, unsupported)
@ -145,14 +145,14 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
if !is_signed_type(cnv) {
cx.span_fatal(sp,
~"+ flag only valid in " +
~"signed #fmt conversion");
~"signed fmt! conversion");
}
}
FlagSpaceForSign => {
if !is_signed_type(cnv) {
cx.span_fatal(sp,
~"space flag only valid in " +
~"signed #fmt conversions");
~"signed fmt! conversions");
}
}
FlagLeftZeroPad => (),
@ -252,7 +252,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
n += 1u;
if n >= nargs {
cx.span_fatal(sp,
~"not enough arguments to #fmt " +
~"not enough arguments to fmt! " +
~"for the given format string");
}
debug!("Building conversion:");
@ -267,7 +267,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
if expected_nargs < nargs {
cx.span_fatal
(sp, fmt!("too many arguments to #fmt. found %u, expected %u",
(sp, fmt!("too many arguments to fmt!. found %u, expected %u",
nargs, expected_nargs));
}

View file

@ -37,7 +37,7 @@ use codemap::span;
use ext::base::ext_ctxt;
use ast::tt_delim;
use parse::lexer::{new_tt_reader, reader};
use parse::parser::{parser, SOURCE_FILE};
use parse::parser::{Parser, SOURCE_FILE};
use parse::common::parser_common;
use pipes::parse_proto::proto_parser;
@ -52,7 +52,7 @@ fn expand_proto(cx: ext_ctxt, _sp: span, id: ast::ident,
let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
cx.parse_sess().interner, None, tt);
let rdr = tt_rdr as reader;
let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let proto = rust_parser.parse_proto(cx.str_of(id));

View file

@ -28,17 +28,17 @@ fn empty_span() -> span {
}
trait append_types {
fn add_ty(ty: @ast::ty) -> @ast::path;
fn add_tys(+tys: ~[@ast::ty]) -> @ast::path;
fn add_ty(ty: @ast::Ty) -> @ast::path;
fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path;
}
impl @ast::path: append_types {
fn add_ty(ty: @ast::ty) -> @ast::path {
fn add_ty(ty: @ast::Ty) -> @ast::path {
@{types: vec::append_one(self.types, ty),
.. *self}
}
fn add_tys(+tys: ~[@ast::ty]) -> @ast::path {
fn add_tys(+tys: ~[@ast::Ty]) -> @ast::path {
@{types: vec::append(self.types, tys),
.. *self}
}
@ -47,18 +47,18 @@ impl @ast::path: append_types {
trait ext_ctxt_ast_builder {
fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
-> ast::ty_param;
fn arg(name: ident, ty: @ast::ty) -> ast::arg;
fn arg(name: ident, ty: @ast::Ty) -> ast::arg;
fn expr_block(e: @ast::expr) -> ast::blk;
fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
fn fn_decl(+inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
fn item(name: ident, span: span, +node: ast::item_) -> @ast::item;
fn item_fn_poly(name: ident,
+inputs: ~[ast::arg],
output: @ast::ty,
output: @ast::Ty,
+ty_params: ~[ast::ty_param],
+body: ast::blk) -> @ast::item;
fn item_fn(name: ident,
+inputs: ~[ast::arg],
output: @ast::ty,
output: @ast::Ty,
+body: ast::blk) -> @ast::item;
fn item_enum_poly(name: ident,
span: span,
@ -66,17 +66,17 @@ trait ext_ctxt_ast_builder {
+ty_params: ~[ast::ty_param]) -> @ast::item;
fn item_enum(name: ident, span: span,
+enum_definition: ast::enum_def) -> @ast::item;
fn variant(name: ident, span: span, +tys: ~[@ast::ty]) -> ast::variant;
fn variant(name: ident, span: span, +tys: ~[@ast::Ty]) -> ast::variant;
fn item_mod(name: ident, span: span, +items: ~[@ast::item]) -> @ast::item;
fn ty_path_ast_builder(path: @ast::path) -> @ast::ty;
fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty;
fn item_ty_poly(name: ident,
span: span,
ty: @ast::ty,
ty: @ast::Ty,
+params: ~[ast::ty_param]) -> @ast::item;
fn item_ty(name: ident, span: span, ty: @ast::ty) -> @ast::item;
fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty];
fn ty_field_imm(name: ident, ty: @ast::ty) -> ast::ty_field;
fn ty_rec(+v: ~[ast::ty_field]) -> @ast::ty;
fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item;
fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty];
fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field;
fn ty_rec(+v: ~[ast::ty_field]) -> @ast::Ty;
fn field_imm(name: ident, e: @ast::expr) -> ast::field;
fn rec(+v: ~[ast::field]) -> @ast::expr;
fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk;
@ -84,11 +84,11 @@ trait ext_ctxt_ast_builder {
fn stmt_expr(e: @ast::expr) -> @ast::stmt;
fn block_expr(b: ast::blk) -> @ast::expr;
fn empty_span() -> span;
fn ty_option(ty: @ast::ty) -> @ast::ty;
fn ty_option(ty: @ast::Ty) -> @ast::Ty;
}
impl ext_ctxt: ext_ctxt_ast_builder {
fn ty_option(ty: @ast::ty) -> @ast::ty {
fn ty_option(ty: @ast::Ty) -> @ast::Ty {
self.ty_path_ast_builder(path(~[self.ident_of(~"Option")],
self.empty_span())
.add_ty(ty))
@ -146,18 +146,18 @@ impl ext_ctxt: ext_ctxt_ast_builder {
span: self.empty_span()}
}
fn ty_field_imm(name: ident, ty: @ast::ty) -> ast::ty_field {
fn ty_field_imm(name: ident, ty: @ast::Ty) -> ast::ty_field {
{node: {ident: name, mt: { ty: ty, mutbl: ast::m_imm } },
span: self.empty_span()}
}
fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::ty {
fn ty_rec(+fields: ~[ast::ty_field]) -> @ast::Ty {
@{id: self.next_id(),
node: ast::ty_rec(fields),
span: self.empty_span()}
}
fn ty_infer() -> @ast::ty {
fn ty_infer() -> @ast::Ty {
@{id: self.next_id(),
node: ast::ty_infer,
span: self.empty_span()}
@ -169,7 +169,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
{ident: id, id: self.next_id(), bounds: @bounds}
}
fn arg(name: ident, ty: @ast::ty) -> ast::arg {
fn arg(name: ident, ty: @ast::Ty) -> ast::arg {
{mode: ast::infer(self.next_id()),
ty: ty,
ident: name,
@ -192,7 +192,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
}
fn fn_decl(+inputs: ~[ast::arg],
output: @ast::ty) -> ast::fn_decl {
output: @ast::Ty) -> ast::fn_decl {
{inputs: inputs,
output: output,
cf: ast::return_val}
@ -224,7 +224,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
fn item_fn_poly(name: ident,
+inputs: ~[ast::arg],
output: @ast::ty,
output: @ast::Ty,
+ty_params: ~[ast::ty_param],
+body: ast::blk) -> @ast::item {
self.item(name,
@ -237,7 +237,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
fn item_fn(name: ident,
+inputs: ~[ast::arg],
output: @ast::ty,
output: @ast::Ty,
+body: ast::blk) -> @ast::item {
self.item_fn_poly(name, inputs, output, ~[], body)
}
@ -256,7 +256,7 @@ impl ext_ctxt: ext_ctxt_ast_builder {
fn variant(name: ident,
span: span,
+tys: ~[@ast::ty]) -> ast::variant {
+tys: ~[@ast::Ty]) -> ast::variant {
let args = tys.map(|ty| {ty: *ty, id: self.next_id()});
{node: {name: name,
@ -278,13 +278,13 @@ impl ext_ctxt: ext_ctxt_ast_builder {
items: items}))
}
fn ty_path_ast_builder(path: @ast::path) -> @ast::ty {
fn ty_path_ast_builder(path: @ast::path) -> @ast::Ty {
@{id: self.next_id(),
node: ast::ty_path(path, self.next_id()),
span: path.span}
}
fn ty_nil_ast_builder() -> @ast::ty {
fn ty_nil_ast_builder() -> @ast::Ty {
@{id: self.next_id(),
node: ast::ty_nil,
span: self.empty_span()}
@ -292,16 +292,16 @@ impl ext_ctxt: ext_ctxt_ast_builder {
fn item_ty_poly(name: ident,
span: span,
ty: @ast::ty,
ty: @ast::Ty,
+params: ~[ast::ty_param]) -> @ast::item {
self.item(name, span, ast::item_ty(ty, params))
}
fn item_ty(name: ident, span: span, ty: @ast::ty) -> @ast::item {
fn item_ty(name: ident, span: span, ty: @ast::Ty) -> @ast::item {
self.item_ty_poly(name, span, ty, ~[])
}
fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::Ty] {
ty_params.map(|p| self.ty_path_ast_builder(
path(~[p.ident], self.empty_span())))
}

View file

@ -38,7 +38,7 @@ impl ext_ctxt: proto::visitor<(), (), ()> {
}
}
fn visit_message(name: ~str, _span: span, _tys: &[@ast::ty],
fn visit_message(name: ~str, _span: span, _tys: &[@ast::Ty],
this: state, next: next_state) {
match next {
Some({state: next, tys: next_tys}) => {
@ -68,4 +68,4 @@ impl ext_ctxt: proto::visitor<(), (), ()> {
None => ()
}
}
}
}

View file

@ -10,7 +10,7 @@ trait proto_parser {
fn parse_state(proto: protocol);
}
impl parser: proto_parser {
impl parser::Parser: proto_parser {
fn parse_proto(id: ~str) -> protocol {
let proto = protocol(id, self.span);

View file

@ -181,7 +181,7 @@ impl message: gen_send {
}
}
fn to_ty(cx: ext_ctxt) -> @ast::ty {
fn to_ty(cx: ext_ctxt) -> @ast::Ty {
cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
.add_tys(cx.ty_vars(self.get_params())))
}
@ -360,7 +360,7 @@ impl protocol: gen_init {
}}
}
fn buffer_ty_path(cx: ext_ctxt) -> @ast::ty {
fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty {
let mut params: ~[ast::ty_param] = ~[];
for (copy self.states).each |s| {
for s.ty_params.each |tp| {
@ -444,13 +444,13 @@ impl ~[@ast::item]: to_source {
}
}
impl @ast::ty: to_source {
impl @ast::Ty: to_source {
fn to_source(cx: ext_ctxt) -> ~str {
ty_to_str(self, cx.parse_sess().interner)
}
}
impl ~[@ast::ty]: to_source {
impl ~[@ast::Ty]: to_source {
fn to_source(cx: ext_ctxt) -> ~str {
str::connect(self.map(|i| i.to_source(cx)), ~", ")
}

View file

@ -18,7 +18,7 @@ impl direction : cmp::Eq {
}
impl direction: ToStr {
fn to_str() -> ~str {
pure fn to_str() -> ~str {
match self {
send => ~"Send",
recv => ~"Recv"
@ -35,11 +35,11 @@ impl direction {
}
}
type next_state = Option<{state: ~str, tys: ~[@ast::ty]}>;
type next_state = Option<{state: ~str, tys: ~[@ast::Ty]}>;
enum message {
// name, span, data, current state, next state
message(~str, span, ~[@ast::ty], state, next_state)
message(~str, span, ~[@ast::Ty], state, next_state)
}
impl message {
@ -78,7 +78,7 @@ enum state {
impl state {
fn add_message(name: ~str, span: span,
+data: ~[@ast::ty], next: next_state) {
+data: ~[@ast::Ty], next: next_state) {
self.messages.push(message(name, span, data, self,
next));
}
@ -92,7 +92,7 @@ impl state {
}
/// Returns the type that is used for the messages.
fn to_ty(cx: ext_ctxt) -> @ast::ty {
fn to_ty(cx: ext_ctxt) -> @ast::Ty {
cx.ty_path_ast_builder
(path(~[cx.ident_of(self.name)],self.span).add_tys(
cx.ty_vars(self.ty_params)))
@ -200,7 +200,7 @@ impl protocol {
trait visitor<Tproto, Tstate, Tmessage> {
fn visit_proto(proto: protocol, st: &[Tstate]) -> Tproto;
fn visit_state(state: state, m: &[Tmessage]) -> Tstate;
fn visit_message(name: ~str, spane: span, tys: &[@ast::ty],
fn visit_message(name: ~str, spane: span, tys: &[@ast::Ty],
this: state, next: next_state) -> Tmessage;
}

View file

@ -1,7 +1,7 @@
use ast::{crate, expr_, mac_invoc,
mac_aq, mac_var};
use parse::parser;
use parse::parser::parse_from_source_str;
use parse::parser::{Parser, parse_from_source_str};
use dvec::DVec;
use parse::token::ident_interner;
@ -24,7 +24,7 @@ struct gather_item {
type aq_ctxt = @{lo: uint, gather: DVec<gather_item>};
enum fragment {
from_expr(@ast::expr),
from_ty(@ast::ty)
from_ty(@ast::Ty)
}
fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
@ -68,7 +68,7 @@ impl @ast::expr: qq_helper {
}
fn get_fold_fn() -> ~str {~"fold_expr"}
}
impl @ast::ty: qq_helper {
impl @ast::Ty: qq_helper {
fn span() -> span {self.span}
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
fn extract_mac() -> Option<ast::mac_> {
@ -186,13 +186,13 @@ fn expand_ast(ecx: ext_ctxt, _sp: span,
};
}
fn parse_crate(p: parser) -> @ast::crate { p.parse_crate_mod(~[]) }
fn parse_ty(p: parser) -> @ast::ty { p.parse_ty(false) }
fn parse_stmt(p: parser) -> @ast::stmt { p.parse_stmt(~[]) }
fn parse_expr(p: parser) -> @ast::expr { p.parse_expr() }
fn parse_pat(p: parser) -> @ast::pat { p.parse_pat(true) }
fn parse_crate(p: Parser) -> @ast::crate { p.parse_crate_mod(~[]) }
fn parse_ty(p: Parser) -> @ast::Ty { p.parse_ty(false) }
fn parse_stmt(p: Parser) -> @ast::stmt { p.parse_stmt(~[]) }
fn parse_expr(p: Parser) -> @ast::expr { p.parse_expr() }
fn parse_pat(p: Parser) -> @ast::pat { p.parse_pat(true) }
fn parse_item(p: parser) -> @ast::item {
fn parse_item(p: Parser) -> @ast::item {
match p.parse_item(~[]) {
Some(item) => item,
None => fail ~"parse_item: parsing an item failed"
@ -200,7 +200,7 @@ fn parse_item(p: parser) -> @ast::item {
}
fn finish<T: qq_helper>
(ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
(ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: Parser) -> T)
-> @ast::expr
{
let cm = ecx.codemap();
@ -309,7 +309,7 @@ fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
@f.fold_crate(*n)
}
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
fn fold_ty(f: ast_fold, &&n: @ast::Ty) -> @ast::Ty {f.fold_ty(n)}
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {
f.fold_item(n).get() //HACK: we know we don't drop items
}

View file

@ -6,7 +6,7 @@ use base::*;
use fold::*;
use ast_util::respan;
use ast::{ident, path, ty, blk_, expr, expr_path,
use ast::{ident, path, Ty, blk_, expr, expr_path,
expr_vec, expr_mac, mac_invoc, node_id, expr_index};
export add_new_extension;
@ -29,7 +29,7 @@ enum matchable {
match_expr(@expr),
match_path(@path),
match_ident(ast::spanned<ident>),
match_ty(@ty),
match_ty(@Ty),
match_block(ast::blk),
match_exact, /* don't bind anything, just verify the AST traversal */
}

View file

@ -2,7 +2,7 @@ use codemap::span;
use ext::base::ext_ctxt;
use ast::tt_delim;
use parse::lexer::{new_tt_reader, reader};
use parse::parser::{parser, SOURCE_FILE};
use parse::parser::{Parser, SOURCE_FILE};
use parse::common::parser_common;
fn expand_trace_macros(cx: ext_ctxt, sp: span,
@ -13,7 +13,7 @@ fn expand_trace_macros(cx: ext_ctxt, sp: span,
let tt_rdr = new_tt_reader(cx.parse_sess().span_diagnostic,
cx.parse_sess().interner, None, tt);
let rdr = tt_rdr as reader;
let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let arg = cx.str_of(rust_parser.parse_ident());
match arg {
@ -21,7 +21,7 @@ fn expand_trace_macros(cx: ext_ctxt, sp: span,
~"false" => cx.set_trace_macros(false),
_ => cx.span_fatal(sp, ~"trace_macros! only accepts `true` or `false`")
}
let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let result = rust_parser.parse_expr();
base::mr_expr(result)
}

View file

@ -1,9 +1,9 @@
// Earley-like parser for macros.
use parse::token;
use parse::token::{token, EOF, to_str, nonterminal};
use parse::token::{Token, EOF, to_str, nonterminal};
use parse::lexer::*; //resolve bug?
//import parse::lexer::{reader, tt_reader, tt_reader_as_reader};
use parse::parser::{parser,SOURCE_FILE};
use parse::parser::{Parser, SOURCE_FILE};
//import parse::common::parser_common;
use parse::common::*; //resolve bug?
use parse::parse_sess;
@ -97,7 +97,7 @@ fn is_some(&&mpu: matcher_pos_up) -> bool {
type matcher_pos = ~{
elts: ~[ast::matcher], // maybe should be /&? Need to understand regions.
sep: Option<token>,
sep: Option<Token>,
mut idx: uint,
mut up: matcher_pos_up, // mutable for swapping only
matches: ~[DVec<@named_match>],
@ -122,7 +122,7 @@ fn count_names(ms: &[matcher]) -> uint {
}
#[allow(non_implicitly_copyable_typarams)]
fn initial_matcher_pos(ms: ~[matcher], sep: Option<token>, lo: uint)
fn initial_matcher_pos(ms: ~[matcher], sep: Option<Token>, lo: uint)
-> matcher_pos {
let mut match_idx_hi = 0u;
for ms.each() |elt| {
@ -345,7 +345,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
built-in NTs %s or %u other options.",
nts, next_eis.len()));
} else if (bb_eis.len() == 0u && next_eis.len() == 0u) {
return failure(sp, ~"No rules expected the token "
return failure(sp, ~"No rules expected the token: "
+ to_str(rdr.interner(), tok));
} else if (next_eis.len() > 0u) {
/* Now process the next token */
@ -354,7 +354,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
}
rdr.next_token();
} else /* bb_eis.len() == 1 */ {
let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let rust_parser = Parser(sess, cfg, rdr.dup(), SOURCE_FILE);
let ei = bb_eis.pop();
match ei.elts[ei.idx].node {
@ -381,7 +381,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
}
}
fn parse_nt(p: parser, name: ~str) -> nonterminal {
fn parse_nt(p: Parser, name: ~str) -> nonterminal {
match name {
~"item" => match p.parse_item(~[]) {
Some(i) => token::nt_item(i),

View file

@ -4,7 +4,7 @@ use ast::{ident, matcher_, matcher, match_tok,
match_nonterminal, match_seq, tt_delim};
use parse::lexer::{new_tt_reader, reader};
use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt};
use parse::parser::{parser, SOURCE_FILE};
use parse::parser::{Parser, SOURCE_FILE};
use macro_parser::{parse, parse_or_else, success, failure, named_match,
matched_seq, matched_nonterminal, error};
use std::map::HashMap;
@ -86,7 +86,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
// rhs has holes ( `$id` and `$(...)` that need filled)
let trncbr = new_tt_reader(s_d, itr, Some(named_matches),
~[rhs]);
let p = parser(cx.parse_sess(), cx.cfg(),
let p = Parser(cx.parse_sess(), cx.cfg(),
trncbr as reader, SOURCE_FILE);
let e = p.parse_expr();
return mr_expr(e);
@ -111,4 +111,4 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
name: *cx.parse_sess().interner.get(name),
ext: expr_tt({expander: exp, span: Some(sp)})
});
}
}

View file

@ -2,8 +2,7 @@ use diagnostic::span_handler;
use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
use macro_parser::{named_match, matched_seq, matched_nonterminal};
use codemap::span;
use parse::token::{EOF, INTERPOLATED, IDENT, token, nt_ident,
ident_interner};
use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
use std::map::HashMap;
export tt_reader, new_tt_reader, dup_tt_reader, tt_next_token;
@ -19,7 +18,7 @@ type tt_frame = @{
readme: ~[ast::token_tree],
mut idx: uint,
dotdotdoted: bool,
sep: Option<token>,
sep: Option<Token>,
up: tt_frame_up,
};
@ -32,7 +31,7 @@ type tt_reader = @{
mut repeat_idx: ~[uint],
mut repeat_len: ~[uint],
/* cached: */
mut cur_tok: token,
mut cur_tok: Token,
mut cur_span: span
};
@ -134,7 +133,7 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis {
}
fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
fn tt_next_token(&&r: tt_reader) -> {tok: Token, sp: span} {
let ret_val = { tok: r.cur_tok, sp: r.cur_span };
while r.cur.idx >= r.cur.readme.len() {
/* done with this set; pop or repeat? */

View file

@ -33,7 +33,7 @@ trait ast_fold {
fn fold_pat(&&v: @pat) -> @pat;
fn fold_decl(&&v: @decl) -> @decl;
fn fold_expr(&&v: @expr) -> @expr;
fn fold_ty(&&v: @ty) -> @ty;
fn fold_ty(&&v: @Ty) -> @Ty;
fn fold_mod(_mod) -> _mod;
fn fold_foreign_mod(foreign_mod) -> foreign_mod;
fn fold_variant(variant) -> variant;
@ -131,10 +131,7 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
}
fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
match tpb {
bound_copy | bound_send | bound_const | bound_owned => tpb,
bound_trait(ty) => bound_trait(fld.fold_ty(ty))
}
ty_param_bound(fld.fold_ty(*tpb))
}
fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param {
@ -271,23 +268,6 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
-> @ast::struct_def {
let resulting_optional_constructor;
match struct_def.ctor {
None => {
resulting_optional_constructor = None;
}
Some(constructor) => {
resulting_optional_constructor = Some({
node: {
body: fld.fold_block(constructor.node.body),
dec: fold_fn_decl(constructor.node.dec, fld),
id: fld.new_id(constructor.node.id),
.. constructor.node
},
.. constructor
});
}
}
let dtor = do option::map(&struct_def.dtor) |dtor| {
let dtor_body = fld.fold_block(dtor.node.body);
let dtor_id = fld.new_id(dtor.node.id);
@ -298,7 +278,6 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
traits: vec::map(struct_def.traits, |p| fold_trait_ref(*p, fld)),
fields: vec::map(struct_def.fields, |f| fold_struct_field(*f, fld)),
methods: vec::map(struct_def.methods, |m| fld.fold_method(*m)),
ctor: resulting_optional_constructor,
dtor: dtor
};
}
@ -585,7 +564,6 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|f| fld.fold_struct_field(*f)),
methods: vec::map(struct_def.methods,
|m| fld.fold_method(*m)),
ctor: None,
dtor: dtor
})
}
@ -747,7 +725,7 @@ impl ast_fold_precursor: ast_fold {
node: n,
span: self.new_span(s)};
}
fn fold_ty(&&x: @ty) -> @ty {
fn fold_ty(&&x: @Ty) -> @Ty {
let (n, s) = self.fold_ty(x.node, x.span, self as ast_fold);
return @{id: self.new_id(x.id), node: n, span: self.new_span(s)};
}

View file

@ -12,7 +12,7 @@ export parse_expr_from_source_str, parse_item_from_source_str;
export parse_stmt_from_source_str;
export parse_from_source_str;
use parser::parser;
use parser::Parser;
use attr::parser_attr;
use common::parser_common;
use ast::node_id;
@ -22,7 +22,7 @@ use lexer::{reader, string_reader};
use parse::token::{ident_interner, mk_ident_interner};
type parse_sess = @{
cm: codemap::codemap,
cm: codemap::CodeMap,
mut next_id: node_id,
span_diagnostic: span_handler,
interner: @ident_interner,
@ -40,7 +40,7 @@ fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
mut chpos: 0u, mut byte_pos: 0u};
}
fn new_parse_sess_special_handler(sh: span_handler, cm: codemap::codemap)
fn new_parse_sess_special_handler(sh: span_handler, cm: codemap::CodeMap)
-> parse_sess {
return @{cm: cm,
mut next_id: 1,
@ -142,7 +142,7 @@ fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
return r;
}
fn parse_from_source_str<T>(f: fn (p: parser) -> T,
fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
name: ~str, ss: codemap::file_substr,
source: @~str, cfg: ast::crate_cfg,
sess: parse_sess)
@ -170,19 +170,19 @@ fn next_node_id(sess: parse_sess) -> node_id {
fn new_parser_etc_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
+name: ~str, +ss: codemap::file_substr,
source: @~str) -> (parser, string_reader) {
source: @~str) -> (Parser, string_reader) {
let ftype = parser::SOURCE_FILE;
let filemap = codemap::new_filemap_w_substr
(name, ss, source, sess.chpos, sess.byte_pos);
sess.cm.files.push(filemap);
let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
sess.interner);
return (parser(sess, cfg, srdr as reader, ftype), srdr);
return (Parser(sess, cfg, srdr as reader, ftype), srdr);
}
fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
+name: ~str, +ss: codemap::file_substr,
source: @~str) -> parser {
source: @~str) -> Parser {
let (p, _) = new_parser_etc_from_source_str(sess, cfg, name, ss, source);
move p
}
@ -190,7 +190,7 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
fn new_parser_etc_from_file(sess: parse_sess, cfg: ast::crate_cfg,
path: &Path, ftype: parser::file_type) ->
(parser, string_reader) {
(Parser, string_reader) {
let res = io::read_whole_file_str(path);
match res {
result::Ok(_) => { /* Continue. */ }
@ -202,18 +202,18 @@ fn new_parser_etc_from_file(sess: parse_sess, cfg: ast::crate_cfg,
sess.cm.files.push(filemap);
let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
sess.interner);
return (parser(sess, cfg, srdr as reader, ftype), srdr);
return (Parser(sess, cfg, srdr as reader, ftype), srdr);
}
fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: &Path,
ftype: parser::file_type) -> parser {
ftype: parser::file_type) -> Parser {
let (p, _) = new_parser_etc_from_file(sess, cfg, path, ftype);
move p
}
fn new_parser_from_tt(sess: parse_sess, cfg: ast::crate_cfg,
tt: ~[ast::token_tree]) -> parser {
tt: ~[ast::token_tree]) -> Parser {
let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner,
None, tt);
return parser(sess, cfg, trdr as reader, parser::SOURCE_FILE)
return Parser(sess, cfg, trdr as reader, parser::SOURCE_FILE)
}

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