<commit_before>use constant::{IGNORE_FILE_NAME, MAIN_DIR};
use lib::io::*;
use lib::fs::*;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{Error as IoError, Read};
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub struct Ignore {
    entries: BTreeSet<String>,
}

impl Ignore {
    fn path() -> PathBuf {
        path_buf![super::working_dir(), IGNORE_FILE_NAME]
    }

    pub fn exist() -> bool {
        Self::path().is_file()
    }

    fn to_string(entries: BTreeSet<String>) -> String {
        entries
            .iter()
            .fold(String::new(), |contents, entry| contents + entry + "\n")
    }

    pub fn create(self) -> Result<(), IoError> {
        print_with_tag(Tag::Info, format!("Create \"{}\" file", IGNORE_FILE_NAME));

        let (dirs, files) = self.dirs_and_files();

        let files = files
            .into_iter()
            .filter(|f| !dirs.iter().any(|d| f.starts_with(d)))
            .collect::<BTreeSet<String>>();

        super::create_setting_file(Self::path(), Self::to_string(dirs) + &Self::to_string(files))
    }

    fn _new(entries: BTreeSet<String>) -> Self {
        Ignore { entries: entries }
    }

    pub fn new() -> Self {
        Self::_new(BTreeSet::new())
    }

    pub fn default() -> Self {
        let current_entries = walk_dir(MAIN_DIR);

        Self::_new(current_entries)
    }

    pub fn read() -> Result<Self, IoError> {
        print_with_tag(Tag::Info, format!("Read \"{}\" file", IGNORE_FILE_NAME));

        let mut f = try!(File::open(Self::path()));

        let mut contents = String::new();
        try!(f.read_to_string(&mut contents));

        let entries = contents
            .lines()
            .map(|l| l.trim().to_string())
            .collect::<BTreeSet<String>>();

        Ok(Self::_new(entries))
    }

    pub fn dirs_and_files(self) -> (BTreeSet<String>, BTreeSet<String>) {
        self.entries
            .into_iter()
            .partition(|s| Path::new(s).is_dir())
    }

    pub fn add(mut self, paths: &Vec<String>) -> Self {
        let paths_to_be_added = paths
            .iter()
            .filter(|p| Path::new(p).exists())
            .map(supply_current_dir_prefix)
            .map(supply_dir_suffix)
            .collect::<BTreeSet<String>>();

        self.entries = self.entries
            .union(&paths_to_be_added)
            .cloned()
            .collect::<BTreeSet<String>>();

        self
    }

    pub fn remove(mut self, paths: &Vec<String>) -> Self {
        let paths_to_be_removed = paths
            .iter()
            .map(supply_current_dir_prefix)
            .map(supply_dir_suffix)
            .collect::<BTreeSet<String>>();

        self.entries = self.entries
            .difference(&paths_to_be_removed)
            .cloned()
            .collect::<BTreeSet<String>>();

        self
    }
}

#[test]
fn remove_should_remove_specified_entries() {
    let e1 = "./a"  .to_string();
    let e2 = "./b"  .to_string();
    let e3 = "./c/d".to_string();
    let e4 = "./c/e".to_string();

    let mut entries = BTreeSet::new();
    entries.insert(e1.clone());
    entries.insert(e2.clone());
    entries.insert(e3.clone());
    entries.insert(e4.clone());

    let ignore = Ignore::_new(entries.clone());

    entries.remove(&e1);
    let ignore = ignore.remove(&vec![e1]);
    assert_eq!(&entries, ignore.entries());

    entries.remove(&e3);
    entries.remove(&e4);
    let ignore = ignore.remove(&vec![e3, e4]);
    assert_eq!(&entries, ignore.entries());
}
<commit_msg>[Test] Fix error<commit_after>use constant::{IGNORE_FILE_NAME, MAIN_DIR};
use lib::io::*;
use lib::fs::*;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{Error as IoError, Read};
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub struct Ignore {
    entries: BTreeSet<String>,
}

impl Ignore {
    fn path() -> PathBuf {
        path_buf![super::working_dir(), IGNORE_FILE_NAME]
    }

    pub fn exist() -> bool {
        Self::path().is_file()
    }

    fn to_string(entries: BTreeSet<String>) -> String {
        entries
            .iter()
            .fold(String::new(), |contents, entry| contents + entry + "\n")
    }

    pub fn create(self) -> Result<(), IoError> {
        print_with_tag(Tag::Info, format!("Create \"{}\" file", IGNORE_FILE_NAME));

        let (dirs, files) = self.dirs_and_files();

        let files = files
            .into_iter()
            .filter(|f| !dirs.iter().any(|d| f.starts_with(d)))
            .collect::<BTreeSet<String>>();

        super::create_setting_file(Self::path(), Self::to_string(dirs) + &Self::to_string(files))
    }

    fn _new(entries: BTreeSet<String>) -> Self {
        Ignore { entries: entries }
    }

    pub fn new() -> Self {
        Self::_new(BTreeSet::new())
    }

    pub fn default() -> Self {
        let current_entries = walk_dir(MAIN_DIR);

        Self::_new(current_entries)
    }

    pub fn read() -> Result<Self, IoError> {
        print_with_tag(Tag::Info, format!("Read \"{}\" file", IGNORE_FILE_NAME));

        let mut f = try!(File::open(Self::path()));

        let mut contents = String::new();
        try!(f.read_to_string(&mut contents));

        let entries = contents
            .lines()
            .map(|l| l.trim().to_string())
            .collect::<BTreeSet<String>>();

        Ok(Self::_new(entries))
    }

    pub fn dirs_and_files(self) -> (BTreeSet<String>, BTreeSet<String>) {
        self.entries
            .into_iter()
            .partition(|s| Path::new(s).is_dir())
    }

    pub fn add(mut self, paths: &Vec<String>) -> Self {
        let paths_to_be_added = paths
            .iter()
            .filter(|p| Path::new(p).exists())
            .map(supply_current_dir_prefix)
            .map(supply_dir_suffix)
            .collect::<BTreeSet<String>>();

        self.entries = self.entries
            .union(&paths_to_be_added)
            .cloned()
            .collect::<BTreeSet<String>>();

        self
    }

    pub fn remove(mut self, paths: &Vec<String>) -> Self {
        let paths_to_be_removed = paths
            .iter()
            .map(supply_current_dir_prefix)
            .map(supply_dir_suffix)
            .collect::<BTreeSet<String>>();

        self.entries = self.entries
            .difference(&paths_to_be_removed)
            .cloned()
            .collect::<BTreeSet<String>>();

        self
    }
}

#[test]
fn remove_should_remove_specified_entries() {
    let e1 = "./a"  .to_string();
    let e2 = "./b"  .to_string();
    let e3 = "./c/d".to_string();
    let e4 = "./c/e".to_string();

    let mut entries = BTreeSet::new();
    entries.insert(e1.clone());
    entries.insert(e2.clone());
    entries.insert(e3.clone());
    entries.insert(e4.clone());

    let ignore = Ignore::_new(entries.clone());

    entries.remove(&e1);
    let ignore = ignore.remove(&vec![e1]);
    assert_eq!(&entries, &ignore.entries);

    entries.remove(&e3);
    entries.remove(&e4);
    let ignore = ignore.remove(&vec![e3, e4]);
    assert_eq!(&entries, &ignore.entries);
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use super::cluster::{Cluster, Simulator};
use super::node::new_node_cluster;
use super::server::new_server_cluster;
use super::util::*;
use tikv::pd::PdClient;

fn test_simple_store_stats<T: Simulator>(cluster: &mut Cluster<T>) {
    let pd_client = cluster.pd_client.clone();

    cluster.cfg.store_cfg.pd_store_heartbeat_tick_interval = 20;
    cluster.bootstrap_region().expect("");
    cluster.start();

    // wait store reports stats.
    for _ in 0..100 {
        sleep_ms(20);

        if pd_client.get_store_stats(1).is_some() {
            break;
        }
    }

    let engine = cluster.get_engine(1);
    engine.flush(true).unwrap();
    let last_stats = pd_client.get_store_stats(1).unwrap();
    assert_eq!(last_stats.get_region_count(), 1);

    cluster.must_put(b"a1", b"v1");
    cluster.must_put(b"a3", b"v3");

    let region = pd_client.get_region(b"").unwrap();
    cluster.must_split(&region, b"a2");
    engine.flush(true).unwrap();

    // wait report region count after split
    for _ in 0..100 {
        sleep_ms(20);

        let stats = pd_client.get_store_stats(1).unwrap();
        if stats.get_region_count() == 2 {
            break;
        }
    }

    let stats = pd_client.get_store_stats(1).unwrap();
    assert_eq!(stats.get_region_count(), 2);
    // We must use some space, so available must reduce.
    assert!(stats.get_available() < last_stats.get_available());
}

#[test]
fn test_node_simple_store_stats() {
    let mut cluster = new_node_cluster(0, 1);
    test_simple_store_stats(&mut cluster);
}

#[test]
fn test_server_simple_store_stats() {
    let mut cluster = new_server_cluster(0, 1);
    test_simple_store_stats(&mut cluster);
}
<commit_msg>raftstrore: fix available check.<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

use super::cluster::{Cluster, Simulator};
use super::node::new_node_cluster;
use super::server::new_server_cluster;
use super::util::*;
use tikv::pd::PdClient;

fn check_available<T: Simulator>(cluster: &mut Cluster<T>) {
    let pd_client = cluster.pd_client.clone();
    let engine = cluster.get_engine(1);

    let stats = pd_client.get_store_stats(1).unwrap();
    assert_eq!(stats.get_region_count(), 2);

    let value = vec![0;1024];
    for i in 0..1000 {
        let last_available = stats.get_available();
        cluster.must_put(format!("a{}", i).as_bytes(), &value);
        engine.flush(true).unwrap();
        sleep_ms(20);

        let stats = pd_client.get_store_stats(1).unwrap();
        // Because the available is for disk size, even we add data
        // other process may reduce data too. so here we try to
        // check available size changed.
        if stats.get_available() != last_available {
            return;
        }
    }

    panic!("available not changed")
}

fn test_simple_store_stats<T: Simulator>(cluster: &mut Cluster<T>) {
    let pd_client = cluster.pd_client.clone();

    cluster.cfg.store_cfg.pd_store_heartbeat_tick_interval = 20;
    cluster.bootstrap_region().expect("");
    cluster.start();

    // wait store reports stats.
    for _ in 0..100 {
        sleep_ms(20);

        if pd_client.get_store_stats(1).is_some() {
            break;
        }
    }

    let engine = cluster.get_engine(1);
    engine.flush(true).unwrap();
    let last_stats = pd_client.get_store_stats(1).unwrap();
    assert_eq!(last_stats.get_region_count(), 1);

    cluster.must_put(b"a1", b"v1");
    cluster.must_put(b"a3", b"v3");

    let region = pd_client.get_region(b"").unwrap();
    cluster.must_split(&region, b"a2");
    engine.flush(true).unwrap();

    // wait report region count after split
    for _ in 0..100 {
        sleep_ms(20);

        let stats = pd_client.get_store_stats(1).unwrap();
        if stats.get_region_count() == 2 {
            break;
        }
    }

    let stats = pd_client.get_store_stats(1).unwrap();
    assert_eq!(stats.get_region_count(), 2);

    check_available(cluster);
}

#[test]
fn test_node_simple_store_stats() {
    let mut cluster = new_node_cluster(0, 1);
    test_simple_store_stats(&mut cluster);
}

#[test]
fn test_server_simple_store_stats() {
    let mut cluster = new_server_cluster(0, 1);
    test_simple_store_stats(&mut cluster);
}
<|endoftext|>


<commit_before>use std::fs::{self, File};
use std::io::prelude::*;

use support::{project, execs, path2url};
use support::COMPILING;
use support::paths::CargoPathExt;
use hamcrest::{assert_that, existing_file};

fn setup() {}

test!(modifying_and_moving {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"
        "#)
        .file("src/main.rs", r#"
            mod a; fn main() {}
        "#)
        .file("src/a.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));

    assert_that(p.cargo("build"),
                execs().with_status(0).with_stdout(""));
    p.root().move_into_the_past().unwrap();
    p.root().join("target").move_into_the_past().unwrap();

    File::create(&p.root().join("src/a.rs")).unwrap()
         .write_all(b"fn main() {}").unwrap();
    assert_that(p.cargo("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));

    fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap();
    assert_that(p.cargo("build"),
                execs().with_status(101));
});

test!(modify_only_some_files {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"
        "#)
        .file("src/lib.rs", "mod a;")
        .file("src/a.rs", "")
        .file("src/main.rs", r#"
            mod b;
            fn main() {}
        "#)
        .file("src/b.rs", "")
        .file("tests/test.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));
    assert_that(p.cargo("test"),
                execs().with_status(0));

    assert_that(&p.bin("foo"), existing_file());

    let lib = p.root().join("src/lib.rs");
    let bin = p.root().join("src/b.rs");

    File::create(&lib).unwrap().write_all(b"invalid rust code").unwrap();
    lib.move_into_the_past().unwrap();
    p.root().move_into_the_past().unwrap();

    File::create(&bin).unwrap().write_all(b"fn foo() {}").unwrap();
    // p.root().move_into_the_past().unwrap();
    // p.root().join("target").move_into_the_past().unwrap();

    // Make sure the binary is rebuilt, not the lib
    assert_that(p.cargo("build")
                 .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));
    assert_that(&p.bin("foo"), existing_file());
});

test!(rebuild_sub_package_then_while_package {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"

            [dependencies.a]
            path = "a"
            [dependencies.b]
            path = "b"
        "#)
        .file("src/lib.rs", "extern crate a; extern crate b;")
        .file("a/Cargo.toml", r#"
            [package]
            name = "a"
            authors = []
            version = "0.0.1"
            [dependencies.b]
            path = "../b"
        "#)
        .file("a/src/lib.rs", "extern crate b;")
        .file("b/Cargo.toml", r#"
            [package]
            name = "b"
            authors = []
            version = "0.0.1"
        "#)
        .file("b/src/lib.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0));

    File::create(&p.root().join("b/src/lib.rs")).unwrap().write_all(br#"
        pub fn b() {}
    "#).unwrap();

    assert_that(p.cargo("build").arg("-pb"),
                execs().with_status(0));

    File::create(&p.root().join("src/lib.rs")).unwrap().write_all(br#"
        extern crate a;
        extern crate b;
        pub fn toplevel() {}
    "#).unwrap();

    assert_that(p.cargo("build"),
                execs().with_status(0));
});

test!(changing_features_is_ok {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"

            [features]
            foo = []
        "#)
        .file("src/lib.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build").arg("--features").arg("foo"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build"),
                execs().with_status(0)
                       .with_stdout(""));
});

test!(rebuild_tests_if_lib_changes {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            version = "0.0.1"
            authors = []
        "#)
        .file("src/lib.rs", "pub fn foo() {}")
        .file("tests/foo.rs", r#"
            extern crate foo;
            #[test]
            fn test() { foo::foo(); }
        "#);

    assert_that(p.cargo_process("build"),
                execs().with_status(0));
    assert_that(p.cargo("test"),
                execs().with_status(0));

    File::create(&p.root().join("src/lib.rs")).unwrap();
    p.root().move_into_the_past().unwrap();
    p.root().join("target").move_into_the_past().unwrap();

    assert_that(p.cargo("build"),
                execs().with_status(0));
    assert_that(p.cargo("test").arg("-v"),
                execs().with_status(101));
});
<commit_msg>Make a freshness test more robust on OSX<commit_after>use std::fs::{self, File};
use std::io::prelude::*;
use std::thread;

use support::{project, execs, path2url};
use support::COMPILING;
use support::paths::CargoPathExt;
use hamcrest::{assert_that, existing_file};

fn setup() {}

test!(modifying_and_moving {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"
        "#)
        .file("src/main.rs", r#"
            mod a; fn main() {}
        "#)
        .file("src/a.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));

    assert_that(p.cargo("build"),
                execs().with_status(0).with_stdout(""));
    p.root().move_into_the_past().unwrap();
    p.root().join("target").move_into_the_past().unwrap();

    File::create(&p.root().join("src/a.rs")).unwrap()
         .write_all(b"fn main() {}").unwrap();
    assert_that(p.cargo("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));

    fs::rename(&p.root().join("src/a.rs"), &p.root().join("src/b.rs")).unwrap();
    assert_that(p.cargo("build"),
                execs().with_status(101));
});

test!(modify_only_some_files {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"
        "#)
        .file("src/lib.rs", "mod a;")
        .file("src/a.rs", "")
        .file("src/main.rs", r#"
            mod b;
            fn main() {}
        "#)
        .file("src/b.rs", "")
        .file("tests/test.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));
    assert_that(p.cargo("test"),
                execs().with_status(0));
    thread::sleep_ms(1000);

    assert_that(&p.bin("foo"), existing_file());

    let lib = p.root().join("src/lib.rs");
    let bin = p.root().join("src/b.rs");

    File::create(&lib).unwrap().write_all(b"invalid rust code").unwrap();
    File::create(&bin).unwrap().write_all(b"fn foo() {}").unwrap();
    lib.move_into_the_past().unwrap();

    // Make sure the binary is rebuilt, not the lib
    assert_that(p.cargo("build")
                 .env("RUST_LOG", "cargo::ops::cargo_rustc::fingerprint"),
                execs().with_status(0).with_stdout(format!("\
{compiling} foo v0.0.1 ({dir})
", compiling = COMPILING, dir = path2url(p.root()))));
    assert_that(&p.bin("foo"), existing_file());
});

test!(rebuild_sub_package_then_while_package {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"

            [dependencies.a]
            path = "a"
            [dependencies.b]
            path = "b"
        "#)
        .file("src/lib.rs", "extern crate a; extern crate b;")
        .file("a/Cargo.toml", r#"
            [package]
            name = "a"
            authors = []
            version = "0.0.1"
            [dependencies.b]
            path = "../b"
        "#)
        .file("a/src/lib.rs", "extern crate b;")
        .file("b/Cargo.toml", r#"
            [package]
            name = "b"
            authors = []
            version = "0.0.1"
        "#)
        .file("b/src/lib.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0));

    File::create(&p.root().join("b/src/lib.rs")).unwrap().write_all(br#"
        pub fn b() {}
    "#).unwrap();

    assert_that(p.cargo("build").arg("-pb"),
                execs().with_status(0));

    File::create(&p.root().join("src/lib.rs")).unwrap().write_all(br#"
        extern crate a;
        extern crate b;
        pub fn toplevel() {}
    "#).unwrap();

    assert_that(p.cargo("build"),
                execs().with_status(0));
});

test!(changing_features_is_ok {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            authors = []
            version = "0.0.1"

            [features]
            foo = []
        "#)
        .file("src/lib.rs", "");

    assert_that(p.cargo_process("build"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build").arg("--features").arg("foo"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build"),
                execs().with_status(0)
                       .with_stdout("\
[..]Compiling foo v0.0.1 ([..])
"));

    assert_that(p.cargo("build"),
                execs().with_status(0)
                       .with_stdout(""));
});

test!(rebuild_tests_if_lib_changes {
    let p = project("foo")
        .file("Cargo.toml", r#"
            [package]
            name = "foo"
            version = "0.0.1"
            authors = []
        "#)
        .file("src/lib.rs", "pub fn foo() {}")
        .file("tests/foo.rs", r#"
            extern crate foo;
            #[test]
            fn test() { foo::foo(); }
        "#);

    assert_that(p.cargo_process("build"),
                execs().with_status(0));
    assert_that(p.cargo("test"),
                execs().with_status(0));

    File::create(&p.root().join("src/lib.rs")).unwrap();
    p.root().move_into_the_past().unwrap();
    p.root().join("target").move_into_the_past().unwrap();

    assert_that(p.cargo("build"),
                execs().with_status(0));
    assert_that(p.cargo("test").arg("-v"),
                execs().with_status(101));
});
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Rust Prelude
//!
//! Because `std` is required by most serious Rust software, it is
//! imported at the topmost level of every crate by default, as if
//! each crate contains the following:
//!
//! ```ignore
//! extern crate std;
//! ```
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`,
//! etc.
//!
//! Additionally, `std` contains a versioned *prelude* that reexports many of the
//! most common traits, types, and functions. *The contents of the prelude are
//! imported into every module by default*.  Implicitly, all modules behave as if
//! they contained the following [`use` statement][book-use]:
//!
//! [book-use]: ../../book/crates-and-modules.html#importing-modules-with-use
//!
//! ```ignore
//! use std::prelude::v1::*;
//! ```
//!
//! The prelude is primarily concerned with exporting *traits* that
//! are so pervasive that they would be onerous to import for every use,
//! particularly those that are commonly mentioned in [generic type
//! bounds][book-traits].
//!
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`](v1/index.html), and reexports the following.
//!
//! * `std::marker::`{
//!     [`Copy`](../marker/trait.Copy.html),
//!     [`Send`](../marker/trait.Send.html),
//!     [`Sized`](../marker/trait.Sized.html),
//!     [`Sync`](../marker/trait.Sync.html)
//!   }.
//!   The marker traits indicate fundamental properties of types.
//! * `std::ops::`{
//!     [`Drop`](../ops/trait.Drop.html),
//!     [`Fn`](../ops/trait.Fn.html),
//!     [`FnMut`](../ops/trait.FnMut.html),
//!     [`FnOnce`](../ops/trait.FnOnce.html)
//!   }.
//!   The [destructor][book-dtor] trait and the
//!   [closure][book-closures] traits, reexported from the same
//!   [module that also defines overloaded
//!   operators](../ops/index.html).
//! * `std::mem::`[`drop`](../mem/fn.drop.html).
//!   A convenience function for explicitly dropping a value.
//! * `std::boxed::`[`Box`](../boxed/struct.Box.html).
//!   The owned heap pointer.
//! * `std::borrow::`[`ToOwned`](../borrow/trait.ToOwned.html).
//!   The conversion trait that defines `to_owned`, the generic method
//!   for creating an owned type from a borrowed type.
//! * `std::clone::`[`Clone`](../clone/trait.Clone.html).
//!   The ubiquitous trait that defines `clone`, the method for
//!   producing copies of values that are consider expensive to copy.
//! * `std::cmp::`{
//!     [`PartialEq`](../cmp/trait.PartialEq.html),
//!     [`PartialOrd`](../cmp/trait.PartialOrd.html),
//!     [`Eq`](../cmp/trait.Eq.html),
//!     [`Ord`](../cmp/trait.Ord.html)
//!   }.
//!   The comparision traits, which implement the comparison operators
//!   and are often seen in trait bounds.
//! * `std::convert::`{
//!     [`AsRef`](../convert/trait.AsRef.html),
//!     [`AsMut`](../convert/trait.AsMut.html),
//!     [`Into`](../convert/trait.Into.html),
//!     [`From`](../convert/trait.From.html)
//!   }.
//!   Generic conversions, used by savvy API authors to create
//!   overloaded methods.
//! * `std::default::`[`Default`](../default/trait.Default).
//!   Types that have default values.
//! * `std::iter::`{
//!     [`Iterator`](../iter/trait.Iterator.html),
//!     [`Extend`](../iter/trait.Extend.html),
//!     [`IntoIterator`](../iter/trait.IntoIterator.html),
//!     [`DoubleEndedIterator`](../iter/trait.DoubleEndedIterator.html),
//!     [`ExactSizeIterator`](../iter/trait.ExactSizeIterator.html)
//!   }.
//!   [Iterators][book-iter].
//! * `std::option::Option::`{
//!     [`self`](../option/enum.Option.html),
//!     [`Some`](../option/enum.Option.html),
//!     [`None`](../option/enum.Option.html)
//!   }.
//!   The ubiquitous `Option` type and its two [variants][book-enums],
//!   `Some` and `None`.
//! * `std::result::Result::`{
//!     [`self`](../result/enum.Result.html),
//!     [`Some`](../result/enum.Result.html),
//!     [`None`](../result/enum.Result.html)
//!   }.
//!   The ubiquitous `Result` type and its two [variants][book-enums],
//!   `Ok` and `Err`.
//! * `std::slice::`[`SliceConcatExt`](../slice/trait.SliceConcatExt.html).
//!   An unstable extension to slices that shouldn't have to exist.
//! * `std::string::`{
//!     [`String`](../string/struct.String.html),
//!     [`ToString`](../string/trait.ToString.html)
//!   }.
//!   Heap allocated strings.
//! * `std::vec::`[`Vec`](../vec/struct.Vec.html).
//!   Heap allocated vectors.
//!
//! [book-traits]: ../../book/traits.html
//! [book-closures]: ../../book/closures.html
//! [book-dtor]: ../../book/drop.html
//! [book-iter]: ../../book/iterators.html
//! [book-enums]: ../../book/enums.html

#![stable(feature = "rust1", since = "1.0.0")]

pub mod v1;
<commit_msg>Fix typo in prelude docs<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Rust Prelude
//!
//! Because `std` is required by most serious Rust software, it is
//! imported at the topmost level of every crate by default, as if
//! each crate contains the following:
//!
//! ```ignore
//! extern crate std;
//! ```
//!
//! This means that the contents of std can be accessed from any context
//! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`,
//! etc.
//!
//! Additionally, `std` contains a versioned *prelude* that reexports many of the
//! most common traits, types, and functions. *The contents of the prelude are
//! imported into every module by default*.  Implicitly, all modules behave as if
//! they contained the following [`use` statement][book-use]:
//!
//! [book-use]: ../../book/crates-and-modules.html#importing-modules-with-use
//!
//! ```ignore
//! use std::prelude::v1::*;
//! ```
//!
//! The prelude is primarily concerned with exporting *traits* that
//! are so pervasive that they would be onerous to import for every use,
//! particularly those that are commonly mentioned in [generic type
//! bounds][book-traits].
//!
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`](v1/index.html), and reexports the following.
//!
//! * `std::marker::`{
//!     [`Copy`](../marker/trait.Copy.html),
//!     [`Send`](../marker/trait.Send.html),
//!     [`Sized`](../marker/trait.Sized.html),
//!     [`Sync`](../marker/trait.Sync.html)
//!   }.
//!   The marker traits indicate fundamental properties of types.
//! * `std::ops::`{
//!     [`Drop`](../ops/trait.Drop.html),
//!     [`Fn`](../ops/trait.Fn.html),
//!     [`FnMut`](../ops/trait.FnMut.html),
//!     [`FnOnce`](../ops/trait.FnOnce.html)
//!   }.
//!   The [destructor][book-dtor] trait and the
//!   [closure][book-closures] traits, reexported from the same
//!   [module that also defines overloaded
//!   operators](../ops/index.html).
//! * `std::mem::`[`drop`](../mem/fn.drop.html).
//!   A convenience function for explicitly dropping a value.
//! * `std::boxed::`[`Box`](../boxed/struct.Box.html).
//!   The owned heap pointer.
//! * `std::borrow::`[`ToOwned`](../borrow/trait.ToOwned.html).
//!   The conversion trait that defines `to_owned`, the generic method
//!   for creating an owned type from a borrowed type.
//! * `std::clone::`[`Clone`](../clone/trait.Clone.html).
//!   The ubiquitous trait that defines `clone`, the method for
//!   producing copies of values that are consider expensive to copy.
//! * `std::cmp::`{
//!     [`PartialEq`](../cmp/trait.PartialEq.html),
//!     [`PartialOrd`](../cmp/trait.PartialOrd.html),
//!     [`Eq`](../cmp/trait.Eq.html),
//!     [`Ord`](../cmp/trait.Ord.html)
//!   }.
//!   The comparision traits, which implement the comparison operators
//!   and are often seen in trait bounds.
//! * `std::convert::`{
//!     [`AsRef`](../convert/trait.AsRef.html),
//!     [`AsMut`](../convert/trait.AsMut.html),
//!     [`Into`](../convert/trait.Into.html),
//!     [`From`](../convert/trait.From.html)
//!   }.
//!   Generic conversions, used by savvy API authors to create
//!   overloaded methods.
//! * `std::default::`[`Default`](../default/trait.Default).
//!   Types that have default values.
//! * `std::iter::`{
//!     [`Iterator`](../iter/trait.Iterator.html),
//!     [`Extend`](../iter/trait.Extend.html),
//!     [`IntoIterator`](../iter/trait.IntoIterator.html),
//!     [`DoubleEndedIterator`](../iter/trait.DoubleEndedIterator.html),
//!     [`ExactSizeIterator`](../iter/trait.ExactSizeIterator.html)
//!   }.
//!   [Iterators][book-iter].
//! * `std::option::Option::`{
//!     [`self`](../option/enum.Option.html),
//!     [`Some`](../option/enum.Option.html),
//!     [`None`](../option/enum.Option.html)
//!   }.
//!   The ubiquitous `Option` type and its two [variants][book-enums],
//!   `Some` and `None`.
//! * `std::result::Result::`{
//!     [`self`](../result/enum.Result.html),
//!     [`Ok`](../result/enum.Result.html),
//!     [`Err`](../result/enum.Result.html)
//!   }.
//!   The ubiquitous `Result` type and its two [variants][book-enums],
//!   `Ok` and `Err`.
//! * `std::slice::`[`SliceConcatExt`](../slice/trait.SliceConcatExt.html).
//!   An unstable extension to slices that shouldn't have to exist.
//! * `std::string::`{
//!     [`String`](../string/struct.String.html),
//!     [`ToString`](../string/trait.ToString.html)
//!   }.
//!   Heap allocated strings.
//! * `std::vec::`[`Vec`](../vec/struct.Vec.html).
//!   Heap allocated vectors.
//!
//! [book-traits]: ../../book/traits.html
//! [book-closures]: ../../book/closures.html
//! [book-dtor]: ../../book/drop.html
//! [book-iter]: ../../book/iterators.html
//! [book-enums]: ../../book/enums.html

#![stable(feature = "rust1", since = "1.0.0")]

pub mod v1;
<|endoftext|>


<commit_before>use crate::any::Any;
use crate::error::Error as StdError;
use crate::ffi::{OsString, OsStr, CString, CStr};
use crate::fmt;
use crate::io;
use crate::marker::PhantomData;
use crate::os::wasi::prelude::*;
use crate::path::{self, PathBuf};
use crate::ptr;
use crate::str;
use crate::sys::memchr;
use crate::sys::{cvt, unsupported, Void};
use crate::vec;

use wasi::wasi_unstable as wasi;

#[cfg(not(target_feature = "atomics"))]
pub unsafe fn env_lock() -> impl Any {
    // No need for a lock if we're single-threaded, but this function will need
    // to get implemented for multi-threaded scenarios
}

pub fn errno() -> i32 {
    0
}

pub fn error_string(errno: i32) -> String {
    wasi::error_string(errno).to_string()
}

pub fn getcwd() -> io::Result<PathBuf> {
    unsupported()
}

pub fn chdir(_: &path::Path) -> io::Result<()> {
    unsupported()
}

pub struct SplitPaths<'a>(&'a Void);

pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
    panic!("unsupported")
}

impl<'a> Iterator for SplitPaths<'a> {
    type Item = PathBuf;
    fn next(&mut self) -> Option<PathBuf> {
        match *self.0 {}
    }
}

#[derive(Debug)]
pub struct JoinPathsError;

pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
    where I: Iterator<Item=T>, T: AsRef<OsStr>
{
    Err(JoinPathsError)
}

impl fmt::Display for JoinPathsError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        "not supported on wasm yet".fmt(f)
    }
}

impl StdError for JoinPathsError {
    fn description(&self) -> &str {
        "not supported on wasm yet"
    }
}

pub fn current_exe() -> io::Result<PathBuf> {
    unsupported()
}

pub struct Env {
    iter: vec::IntoIter<(OsString, OsString)>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Iterator for Env {
    type Item = (OsString, OsString);
    fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

pub fn env() -> Env {
    unsafe {
        let _guard = env_lock();
        // FIXME: replace with wasi::environ_get
        let mut environ = libc::environ;
        let mut result = Vec::new();
        while environ != ptr::null_mut() && *environ != ptr::null_mut() {
            if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
                result.push(key_value);
            }
            environ = environ.offset(1);
        }
        return Env {
            iter: result.into_iter(),
            _dont_send_or_sync_me: PhantomData,
        }
    }

    // See src/libstd/sys/unix/os.rs, same as that
    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
        if input.is_empty() {
            return None;
        }
        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
        pos.map(|p| (
            OsStringExt::from_vec(input[..p].to_vec()),
            OsStringExt::from_vec(input[p+1..].to_vec()),
        ))
    }
}

pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
    let k = CString::new(k.as_bytes())?;
    unsafe {
        let _guard = env_lock();
        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
        let ret = if s.is_null() {
            None
        } else {
            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
        };
        Ok(ret)
    }
}

pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
    let k = CString::new(k.as_bytes())?;
    let v = CString::new(v.as_bytes())?;

    unsafe {
        let _guard = env_lock();
        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
    }
}

pub fn unsetenv(n: &OsStr) -> io::Result<()> {
    let nbuf = CString::new(n.as_bytes())?;

    unsafe {
        let _guard = env_lock();
        cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
    }
}

pub fn temp_dir() -> PathBuf {
    panic!("no filesystem on wasm")
}

pub fn home_dir() -> Option<PathBuf> {
    None
}

pub fn exit(code: i32) -> ! {
    unsafe { wasi::proc_exit(code as u32) }
}

pub fn getpid() -> u32 {
    panic!("unsupported");
}
<commit_msg>remove to_string<commit_after>use crate::any::Any;
use crate::error::Error as StdError;
use crate::ffi::{OsString, OsStr, CString, CStr};
use crate::fmt;
use crate::io;
use crate::marker::PhantomData;
use crate::os::wasi::prelude::*;
use crate::path::{self, PathBuf};
use crate::ptr;
use crate::str;
use crate::sys::memchr;
use crate::sys::{cvt, unsupported, Void};
use crate::vec;

use wasi::wasi_unstable as wasi;

#[cfg(not(target_feature = "atomics"))]
pub unsafe fn env_lock() -> impl Any {
    // No need for a lock if we're single-threaded, but this function will need
    // to get implemented for multi-threaded scenarios
}

pub fn errno() -> i32 {
    0
}

pub fn error_string(errno: i32) -> String {
    wasi::error_string(errno)
}

pub fn getcwd() -> io::Result<PathBuf> {
    unsupported()
}

pub fn chdir(_: &path::Path) -> io::Result<()> {
    unsupported()
}

pub struct SplitPaths<'a>(&'a Void);

pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
    panic!("unsupported")
}

impl<'a> Iterator for SplitPaths<'a> {
    type Item = PathBuf;
    fn next(&mut self) -> Option<PathBuf> {
        match *self.0 {}
    }
}

#[derive(Debug)]
pub struct JoinPathsError;

pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
    where I: Iterator<Item=T>, T: AsRef<OsStr>
{
    Err(JoinPathsError)
}

impl fmt::Display for JoinPathsError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        "not supported on wasm yet".fmt(f)
    }
}

impl StdError for JoinPathsError {
    fn description(&self) -> &str {
        "not supported on wasm yet"
    }
}

pub fn current_exe() -> io::Result<PathBuf> {
    unsupported()
}

pub struct Env {
    iter: vec::IntoIter<(OsString, OsString)>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Iterator for Env {
    type Item = (OsString, OsString);
    fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

pub fn env() -> Env {
    unsafe {
        let _guard = env_lock();
        // FIXME: replace with wasi::environ_get
        let mut environ = libc::environ;
        let mut result = Vec::new();
        while environ != ptr::null_mut() && *environ != ptr::null_mut() {
            if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
                result.push(key_value);
            }
            environ = environ.offset(1);
        }
        return Env {
            iter: result.into_iter(),
            _dont_send_or_sync_me: PhantomData,
        }
    }

    // See src/libstd/sys/unix/os.rs, same as that
    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
        if input.is_empty() {
            return None;
        }
        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
        pos.map(|p| (
            OsStringExt::from_vec(input[..p].to_vec()),
            OsStringExt::from_vec(input[p+1..].to_vec()),
        ))
    }
}

pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
    let k = CString::new(k.as_bytes())?;
    unsafe {
        let _guard = env_lock();
        let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
        let ret = if s.is_null() {
            None
        } else {
            Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
        };
        Ok(ret)
    }
}

pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
    let k = CString::new(k.as_bytes())?;
    let v = CString::new(v.as_bytes())?;

    unsafe {
        let _guard = env_lock();
        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
    }
}

pub fn unsetenv(n: &OsStr) -> io::Result<()> {
    let nbuf = CString::new(n.as_bytes())?;

    unsafe {
        let _guard = env_lock();
        cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
    }
}

pub fn temp_dir() -> PathBuf {
    panic!("no filesystem on wasm")
}

pub fn home_dir() -> Option<PathBuf> {
    None
}

pub fn exit(code: i32) -> ! {
    unsafe { wasi::proc_exit(code as u32) }
}

pub fn getpid() -> u32 {
    panic!("unsupported");
}
<|endoftext|>


<commit_before>use storage_by_ints::*;
use common::R;

#[test]
fn test_StorageByInts2_constr_from_fn() {
  let t = StorageByInts2::from_fn(3,4, |i,j| 1000.*(i as R) + 100.*(j as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      assert_eq!(t.get(i,j), 1000.*(i as R) + 100.*(j as R));
    }
  }
}

#[test]
fn test_StorageByInts2_set() {
  let mut t = StorageByInts2::from_fn(3,4, |i,j| 1000.*(i as R) + 100.*(j as R));
  t.set(1,1, -99.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      if i == 1 && j == 1 {
        assert_eq!(t.get(i,j), -99.);
      } else {
        assert_eq!(t.get(i,j), 1000.*(i as R) + 100.*(j as R));
      }
    }
  }
}

#[test]
fn test_StorageByInts2_constr_from_elem() {
  let mut t = StorageByInts2::from_elem(3,4, 99.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      assert_eq!(t.get(i,j), .99);
    }
  }
}

#[test]
fn test_StorageByInts3_constr_from_fn() {
  let t = StorageByInts3::from_fn(3,4,5, |i,j,k| 1000.*(i as R) + 100.*(j as R) + (k as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        assert_eq!(t.get(i,j,k), 1000.*(i as R) + 100.*(j as R) + (k as R));
      }
    }
  }
}

#[test]
fn test_StorageByInts4_constr_from_fn() {
  let t = StorageByInts4::from_fn(3,4,5,6, |i,j,k,l| 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        for l in range(0u,6) {
          assert_eq!(t.get(i,j,k,l), 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R));
        }
      }
    }
  }
}

#[test]
fn test_StorageByInts5_constr_from_fn() {
  let t = StorageByInts5::from_fn(3,4,5,6,7, |i,j,k,l,m| 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R) + (m as R)/10.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        for l in range(0u,6) {
          for m in range(0u,7) {
            assert_eq!(t.get(i,j,k,l,m), 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R) + (m as R)/10.);
          }
        }
      }
    }
  }
}

<commit_msg>Fix syntax error in new test.<commit_after>use storage_by_ints::*;
use common::R;

#[test]
fn test_StorageByInts2_constr_from_fn() {
  let t = StorageByInts2::from_fn(3,4, |i,j| 1000.*(i as R) + 100.*(j as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      assert_eq!(t.get(i,j), 1000.*(i as R) + 100.*(j as R));
    }
  }
}

#[test]
fn test_StorageByInts2_set() {
  let mut t = StorageByInts2::from_fn(3,4, |i,j| 1000.*(i as R) + 100.*(j as R));
  t.set(1,1, -99.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      if i == 1 && j == 1 {
        assert_eq!(t.get(i,j), -99.);
      } else {
        assert_eq!(t.get(i,j), 1000.*(i as R) + 100.*(j as R));
      }
    }
  }
}

#[test]
fn test_StorageByInts2_constr_from_elem() {
  let mut t = StorageByInts2::from_elem(3,4, 99.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      assert_eq!(t.get(i,j), 99.);
    }
  }
}

#[test]
fn test_StorageByInts3_constr_from_fn() {
  let t = StorageByInts3::from_fn(3,4,5, |i,j,k| 1000.*(i as R) + 100.*(j as R) + (k as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        assert_eq!(t.get(i,j,k), 1000.*(i as R) + 100.*(j as R) + (k as R));
      }
    }
  }
}

#[test]
fn test_StorageByInts4_constr_from_fn() {
  let t = StorageByInts4::from_fn(3,4,5,6, |i,j,k,l| 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R));
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        for l in range(0u,6) {
          assert_eq!(t.get(i,j,k,l), 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R));
        }
      }
    }
  }
}

#[test]
fn test_StorageByInts5_constr_from_fn() {
  let t = StorageByInts5::from_fn(3,4,5,6,7, |i,j,k,l,m| 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R) + (m as R)/10.);
  for i in range(0u,3) {
    for j in range(0u,4) {
      for k in range(0u,5) {
        for l in range(0u,6) {
          for m in range(0u,7) {
            assert_eq!(t.get(i,j,k,l,m), 1000.*(i as R) + 100.*(j as R) + 10.*(k as R) + (l as R) + (m as R)/10.);
          }
        }
      }
    }
  }
}

<|endoftext|>


<commit_before>//! Tokenizes input strings.

use super::{SExpr, Cons, Nil, DataType, Operator, Literal, car, cdr};
use super::basictype::{BasicType, Boolean, Character, Number, String, Symbol};
use super::operator::OperatorType;

pub enum Token {
    LParen,
    RParen,
    Operator(OperatorType),
    Literal(BasicType)
}

pub fn tokenize(expr: &str) -> Result<Vec<Token>>, StrBuf> {
    let mut tokens = Vec::new();

    let mut i = 0;
    let len = expr.len();

    while i < len {
        let slice = expr.slice_from(i);

        if slice.chars().next().unwrap().is_whitespace() {
            i += 1;
            continue;
        }

        //Parentheses
        let token = match slice.chars().next().unwrap() {
            '(' => Some(LParen),
            ')' => Some(RParen),
            _   => None
        };
        if token.is_some() {
            tokens.push(token.unwrap());
            i += 1;
            continue;
        }

        //operators
        //there's at least one word, so it's safe to unwrap
        let word = slice.words().next().unwrap();

        //Discard dangling parens
        let word = word.slice(0, word.find(|c: char| c == ')').unwrap_or(word.len()));

        match operator::From_str(word) {
            Some(op_type)   => {
                tokens.push(Operator(op_type));
                i += word.len();
                continue;
            }
            _               => { } //do nothing
        };

        //Booleans
        match word {
            "true"  => {
                tokens.push(Literal(Boolean(true)));
                i += word.len();
                continue;
            },
            "false" => {
                tokens.push(Literal(Boolean(false)));
                i += word.len();
                continue;
            },
            _       => { } // do nothing
        }

        //Character literals
        if word.len() == 3 && word.starts_with("'") && word.ends_with("'") {
            tokens.push(Literal(Character(word.chars().next().next().unwrap())));
        }
<commit_msg>fixed character literals. Obv nothing is operational yet.''<commit_after>//! Tokenizes input strings.

use super::{SExpr, Cons, Nil, DataType, Operator, Literal, car, cdr};
use super::basictype::{BasicType, Boolean, Character, Number, String, Symbol};
use super::operator::OperatorType;

pub enum Token {
    LParen,
    RParen,
    Operator(OperatorType),
    Literal(BasicType)
}

pub fn tokenize(expr: &str) -> Result<Vec<Token>>, StrBuf> {
    let mut tokens = Vec::new();

    let mut i = 0;
    let len = expr.len();

    while i < len {
        let slice = expr.slice_from(i);

        if slice.chars().next().unwrap().is_whitespace() {
            i += 1;
            continue;
        }

        //Parentheses
        let token = match slice.chars().next().unwrap() {
            '(' => Some(LParen),
            ')' => Some(RParen),
            _   => None
        };
        if token.is_some() {
            tokens.push(token.unwrap());
            i += 1;
            continue;
        }

        //operators
        //there's at least one word, so it's safe to unwrap
        let word = slice.words().next().unwrap();

        //Discard dangling parens
        let word = word.slice(0, word.find(|c: char| c == ')').unwrap_or(word.len()));

        match operator::From_str(word) {
            Some(op_type)   => {
                tokens.push(Operator(op_type));
                i += word.len();
                continue;
            }
            _               => { } //do nothing
        };

        //Booleans
        match word {
            "true"  => {
                tokens.push(Literal(Boolean(true)));
                i += word.len();
                continue;
            },
            "false" => {
                tokens.push(Literal(Boolean(false)));
                i += word.len();
                continue;
            },
            _       => { } // do nothing
        }

        //Character literals
        if word.len() == 3 && word.starts_with("'") && word.ends_with("'") {
            tokens.push(Literal(Character(word.chars().nth(1).unwrap())));
        }
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::sync::atomic::*;
use core::sync::atomic::Ordering::SeqCst;

#[test]
fn bool_() {
    let a = AtomicBool::new(false);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), true);

    a.store(false, SeqCst);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
}

#[test]
fn bool_and() {
    let a = AtomicBool::new(true);
    assert_eq!(a.fetch_and(false, SeqCst), true);
    assert_eq!(a.load(SeqCst),false);
}

#[test]
fn bool_nand() {
    let a = AtomicBool::new(false);
    assert_eq!(a.fetch_nand(false, SeqCst), false);
    assert_eq!(a.load(SeqCst), true);
    assert_eq!(a.fetch_nand(false, SeqCst), true);
    assert_eq!(a.load(SeqCst), true);
    assert_eq!(a.fetch_nand(true, SeqCst), true);
    assert_eq!(a.load(SeqCst), false);
    assert_eq!(a.fetch_nand(true, SeqCst), false);
    assert_eq!(a.load(SeqCst), true);
}

#[test]
fn uint_and() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn uint_nand() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn uint_or() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
}

#[test]
fn uint_xor() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
}

#[test]
fn int_and() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn int_nand() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn int_or() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
}

#[test]
fn int_xor() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
}

static S_FALSE: AtomicBool = AtomicBool::new(false);
static S_TRUE: AtomicBool = AtomicBool::new(true);
static S_INT: AtomicIsize  = AtomicIsize::new(0);
static S_UINT: AtomicUsize = AtomicUsize::new(0);

#[test]
fn static_init() {
    assert!(!S_FALSE.load(SeqCst));
    assert!(S_TRUE.load(SeqCst));
    assert!(S_INT.load(SeqCst) == 0);
    assert!(S_UINT.load(SeqCst) == 0);
}
<commit_msg>std: Be sure to modify atomics in tests<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::sync::atomic::*;
use core::sync::atomic::Ordering::SeqCst;

#[test]
fn bool_() {
    let a = AtomicBool::new(false);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), true);

    a.store(false, SeqCst);
    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
}

#[test]
fn bool_and() {
    let a = AtomicBool::new(true);
    assert_eq!(a.fetch_and(false, SeqCst), true);
    assert_eq!(a.load(SeqCst),false);
}

#[test]
fn bool_nand() {
    let a = AtomicBool::new(false);
    assert_eq!(a.fetch_nand(false, SeqCst), false);
    assert_eq!(a.load(SeqCst), true);
    assert_eq!(a.fetch_nand(false, SeqCst), true);
    assert_eq!(a.load(SeqCst), true);
    assert_eq!(a.fetch_nand(true, SeqCst), true);
    assert_eq!(a.load(SeqCst), false);
    assert_eq!(a.fetch_nand(true, SeqCst), false);
    assert_eq!(a.load(SeqCst), true);
}

#[test]
fn uint_and() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn uint_nand() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn uint_or() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
}

#[test]
fn uint_xor() {
    let x = AtomicUsize::new(0xf731);
    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
}

#[test]
fn int_and() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
}

#[test]
fn int_nand() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f));
}

#[test]
fn int_or() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
}

#[test]
fn int_xor() {
    let x = AtomicIsize::new(0xf731);
    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
}

static S_FALSE: AtomicBool = AtomicBool::new(false);
static S_TRUE: AtomicBool = AtomicBool::new(true);
static S_INT: AtomicIsize  = AtomicIsize::new(0);
static S_UINT: AtomicUsize = AtomicUsize::new(0);

#[test]
fn static_init() {
    // Note that we're not really testing the mutability here but it's important
    // on Android at the moment (#49775)
    assert!(!S_FALSE.swap(true, SeqCst));
    assert!(S_TRUE.swap(false, SeqCst));
    assert!(S_INT.fetch_add(1, SeqCst) == 0);
    assert!(S_UINT.fetch_add(1, SeqCst) == 0);
}
<|endoftext|>


<commit_before>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::cmp::{min, max};
use std::num::SignedInt;

#[derive(PartialEq, Eq, Show, Copy, Clone)]
pub struct Interval {
  lb: int,
  ub: int
}

impl Interval
{
  pub fn new(lb: int, ub: int) -> Interval {
    Interval { lb: lb, ub: ub }
  }

  pub fn empty() -> Interval {
    Interval::new(1, 0)
  }

  pub fn singleton(x: int) -> Interval {
    Interval::new(x, x)
  }

  pub fn is_singleton(self) -> bool {
    self.lb == self.ub
  }

  pub fn size(self) -> uint {
    if self.is_empty() { 0 }
    else { (self.ub - self.lb + 1).abs() as uint }
  }

  pub fn is_empty(self) -> bool {
    self.lb > self.ub
  }

  pub fn member(self, x: int) -> bool {
    x >= self.lb && x <= self.ub
  }

  pub fn is_subset_of(self, i: Interval) -> bool {
    if self.is_empty() { true }
    else {
      self.lb >= i.lb && self.ub <= i.ub
    }
  }

  pub fn intersection(self, i: Interval) -> Interval {
    Interval::new(
      max(self.lb, i.lb),
      min(self.ub, i.ub)
    )
  }

  pub fn hull(self, i: Interval) -> Interval {
    if self.is_empty() { i }
    else if i.is_empty() { self }
    else {
      Interval::new(
        min(self.lb, i.lb),
        max(self.ub, i.ub)
      )
    }
  }

  fn disjoint(self, i: Interval) -> bool {
    self.lb > i.ub || i.lb > self.ub
  }
}

pub trait ToInterval {
  fn to_interval(self) -> Interval;
}

impl ToInterval for Interval {
  fn to_interval(self) -> Interval { self }
}

impl ToInterval for (int, int) {
  fn to_interval(self) -> Interval {
    let (a, b) = self;
    Interval::new(a, b)
  }
}

impl ToInterval for () {
  fn to_interval(self) -> Interval {
    Interval::empty()
  }
}

impl ToInterval for int {
  fn to_interval(self) -> Interval {
    Interval::singleton(self)
  }
}

#[allow(non_upper_case_globals)]
#[cfg(test)]
mod tests {
  use super::*;

  const empty: Interval = Interval {lb: 1, ub: 0};
  const invalid: Interval = Interval {lb: 10, ub: -10};
  const zero: Interval = Interval {lb: 0, ub: 0};
  const one: Interval = Interval {lb: 1, ub: 1};

  const i1_2: Interval = Interval {lb: 1, ub: 2};
  const i0_10: Interval = Interval {lb: 0, ub: 10};
  const i5_10: Interval = Interval {lb: 5, ub: 10};
  const i0_5: Interval = Interval {lb: 0, ub: 5};
  const i20_30: Interval = Interval {lb: 20, ub: 30};
  const im30_m20: Interval = Interval {lb: -30, ub: -20};

  #[test]
  fn to_interval_id_test() {
    let id = i1_2.clone().to_interval();
    assert!(i1_2 == id);
    assert!(i1_2 == Interval::new(1, 2));
  }

  #[test]
  fn size_test() {
    assert!(zero.size() == 1);
    assert!(one.size() == 1);
    assert!(empty.size() == 0);
    assert!(invalid.size() == 0);

    assert!(i1_2.size() == 2);
    assert!(i0_10.size() == 11);
    assert!(im30_m20.size() == 11);
  }
}<commit_msg>Test the subset operation.<commit_after>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::cmp::{min, max};
use std::num::SignedInt;

#[derive(PartialEq, Eq, Show, Copy, Clone)]
pub struct Interval {
  lb: int,
  ub: int
}

impl Interval
{
  pub fn new(lb: int, ub: int) -> Interval {
    Interval { lb: lb, ub: ub }
  }

  pub fn empty() -> Interval {
    Interval::new(1, 0)
  }

  pub fn singleton(x: int) -> Interval {
    Interval::new(x, x)
  }

  pub fn is_singleton(self) -> bool {
    self.lb == self.ub
  }

  pub fn size(self) -> uint {
    if self.is_empty() { 0 }
    else { (self.ub - self.lb + 1).abs() as uint }
  }

  pub fn is_empty(self) -> bool {
    self.lb > self.ub
  }

  pub fn has_member(self, x: int) -> bool {
    x >= self.lb && x <= self.ub
  }

  pub fn is_subset_of(self, i: Interval) -> bool {
    if self.is_empty() { true }
    else {
      self.lb >= i.lb && self.ub <= i.ub
    }
  }

  pub fn intersection(self, i: Interval) -> Interval {
    Interval::new(
      max(self.lb, i.lb),
      min(self.ub, i.ub)
    )
  }

  pub fn hull(self, i: Interval) -> Interval {
    if self.is_empty() { i }
    else if i.is_empty() { self }
    else {
      Interval::new(
        min(self.lb, i.lb),
        max(self.ub, i.ub)
      )
    }
  }

  fn disjoint(self, i: Interval) -> bool {
    self.lb > i.ub || i.lb > self.ub
  }
}

pub trait ToInterval {
  fn to_interval(self) -> Interval;
}

impl ToInterval for Interval {
  fn to_interval(self) -> Interval { self }
}

impl ToInterval for (int, int) {
  fn to_interval(self) -> Interval {
    let (a, b) = self;
    Interval::new(a, b)
  }
}

impl ToInterval for () {
  fn to_interval(self) -> Interval {
    Interval::empty()
  }
}

impl ToInterval for int {
  fn to_interval(self) -> Interval {
    Interval::singleton(self)
  }
}

#[allow(non_upper_case_globals)]
#[cfg(test)]
mod tests {
  use super::*;

  const empty: Interval = Interval {lb: 1, ub: 0};
  const invalid: Interval = Interval {lb: 10, ub: -10};
  const zero: Interval = Interval {lb: 0, ub: 0};
  const one: Interval = Interval {lb: 1, ub: 1};

  const i1_2: Interval = Interval {lb: 1, ub: 2};
  const i0_10: Interval = Interval {lb: 0, ub: 10};
  const i0_15: Interval = Interval {lb: 0, ub: 15};
  const im5_10: Interval = Interval {lb: -5, ub: 10};
  const i5_10: Interval = Interval {lb: 5, ub: 10};
  const i0_5: Interval = Interval {lb: 0, ub: 5};
  const i0_4: Interval = Interval {lb: 0, ub: 4};
  const im5_5: Interval = Interval {lb: -5, ub: 5};
  const i20_30: Interval = Interval {lb: 20, ub: 30};
  const im30_m20: Interval = Interval {lb: -30, ub: -20};

  #[test]
  fn to_interval_id_test() {
    let id = i1_2.clone().to_interval();
    assert!(i1_2 == id);
    assert!(i1_2 == Interval::new(1, 2));
  }

  #[test]
  fn size_test() {
    assert!(zero.size() == 1);
    assert!(one.size() == 1);
    assert!(empty.size() == 0);
    assert!(invalid.size() == 0);

    assert!(i1_2.size() == 2);
    assert!(i0_10.size() == 11);
    assert!(im30_m20.size() == 11);
  }

  #[test]
  fn member_test() {
    assert!(i1_2.has_member(1));
    assert!(i1_2.has_member(2));
    assert!(!i1_2.has_member(0));
    assert!(!i1_2.has_member(3));

    assert!(zero.has_member(0));
    assert!(!zero.has_member(1));

    assert!(!empty.has_member(0));
    assert!(!empty.has_member(1));
    assert!(!empty.has_member(5));
    assert!(!empty.has_member(-5));

    assert!(!invalid.has_member(0));
    assert!(!invalid.has_member(-11));
    assert!(!invalid.has_member(11));
  }

  #[test]
  fn is_subset_of_test() {
    let cases = vec![
      (zero, zero,          true),
      (i1_2, i1_2,          true),
      (empty, empty,        true),
      (invalid, invalid,    true)
    ];

    // For each cases (x, y, res)
    // * x and y are the values
    // * res is a tuple (r, sym) where
    //    * r is true if x is a subset of y
    //    * sym is true if y is a subset of x
    let sym_cases = vec![
      // ||
      // |-|
      (empty, zero,         (true, false)),
      (invalid, zero,       (true, false)),
      (empty, invalid,      (true, true)),
      // ||
      //|--|
      (empty, i1_2,         (true, false)),
      (invalid, i1_2,       (true, false)),
      //  |--|
      // |----|
      (i1_2, i0_10,         (true, false)),
      // |--|
      //     |--|
      (i0_4, i5_10,         (false, false)),
      // |--|
      //    |--|
      (i0_5, i5_10,         (false, false)),
      // |---|
      //   |---|
      (im5_5, i0_10,        (false, false)),
      // |--|
      //         |--|
      (i0_10, i20_30,       (false, false)),
      // |--|
      // |---|
      (i0_10, i0_15,        (true, false)),
      // |---|
      //  |--|
      (im5_10, i0_10,       (false, true))
    ];

    for (x,y,r) in cases.into_iter() {
      assert!(x.is_subset_of(y) == r, "{} is subset of {} is not equal to {}", x, y, r);
    }

    for (x,y,(r1,r2)) in sym_cases.into_iter() {
      assert!(x.is_subset_of(y) == r1, "{} is subset of {} is not equal to {}", x, y, r1);
      assert!(y.is_subset_of(x) == r2, "{} is subset of {} is not equal to {}", y, x, r2);
    }
  }
}<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io;
use libc::{self, c_int};
use mem;
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
use sys::fd::FileDesc;
use sys::{cvt, cvt_r};

////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
////////////////////////////////////////////////////////////////////////////////

pub struct AnonPipe(FileDesc);

pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
    weak! { fn pipe2(*mut c_int, c_int) -> c_int }
    static INVALID: AtomicBool = ATOMIC_BOOL_INIT;

    let mut fds = [0; 2];

    // Unfortunately the only known way right now to create atomically set the
    // CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
    // 2.6.27, however, and because we support 2.6.18 we must detect this
    // support dynamically.
    if cfg!(any(target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "linux",
                target_os = "netbsd",
                target_os = "openbsd")) &&
       !INVALID.load(Ordering::SeqCst)
    {

        if let Some(pipe) = pipe2.get() {
            // Note that despite calling a glibc function here we may still
            // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
            // emulate on older kernels, so if you happen to be running on
            // an older kernel you may see `pipe2` as a symbol but still not
            // see the syscall.
            match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
                Ok(_) => {
                    return Ok((AnonPipe(FileDesc::new(fds[0])),
                               AnonPipe(FileDesc::new(fds[1]))));
                }
                Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
                    INVALID.store(true, Ordering::SeqCst);
                }
                Err(e) => return Err(e),
            }
        }
    }
    cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;

    let fd0 = FileDesc::new(fds[0]);
    let fd1 = FileDesc::new(fds[1]);
    fd0.set_cloexec()?;
    fd1.set_cloexec()?;
    Ok((AnonPipe(fd0), AnonPipe(fd1)))
}

impl AnonPipe {
    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn fd(&self) -> &FileDesc { &self.0 }
    pub fn into_fd(self) -> FileDesc { self.0 }
}

pub fn read2(p1: AnonPipe,
             v1: &mut Vec<u8>,
             p2: AnonPipe,
             v2: &mut Vec<u8>) -> io::Result<()> {

    // Set both pipes into nonblocking mode as we're gonna be reading from both
    // in the `select` loop below, and we wouldn't want one to block the other!
    let p1 = p1.into_fd();
    let p2 = p2.into_fd();
    p1.set_nonblocking(true)?;
    p2.set_nonblocking(true)?;

    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
    fds[0].fd = p1.raw();
    fds[0].events = libc::POLLIN;
    fds[1].fd = p2.raw();
    fds[1].events = libc::POLLIN;
    loop {
        // wait for either pipe to become readable using `poll`
        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;

        // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
        // EAGAIN. If we hit EOF, then this will happen because the underlying
        // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
        // this case we flip the other fd back into blocking mode and read
        // whatever's leftover on that file descriptor.
        let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
            match fd.read_to_end(dst) {
                Ok(_) => Ok(true),
                Err(e) => {
                    if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
                       e.raw_os_error() == Some(libc::EAGAIN) {
                        Ok(false)
                    } else {
                        Err(e)
                    }
                }
            }
        };
        if fds[0].revents != 0 && read(&p1, v1)? {
            p2.set_nonblocking(false)?;
            return p2.read_to_end(v2).map(|_| ());
        }
        if fds[1].revents != 0 && read(&p2, v2)? {
            p1.set_nonblocking(false)?;
            return p1.read_to_end(v1).map(|_| ());
        }
    }
}
<commit_msg>read2: Use inner function instead of closure<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io;
use libc::{self, c_int};
use mem;
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
use sys::fd::FileDesc;
use sys::{cvt, cvt_r};

////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
////////////////////////////////////////////////////////////////////////////////

pub struct AnonPipe(FileDesc);

pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
    weak! { fn pipe2(*mut c_int, c_int) -> c_int }
    static INVALID: AtomicBool = ATOMIC_BOOL_INIT;

    let mut fds = [0; 2];

    // Unfortunately the only known way right now to create atomically set the
    // CLOEXEC flag is to use the `pipe2` syscall on Linux. This was added in
    // 2.6.27, however, and because we support 2.6.18 we must detect this
    // support dynamically.
    if cfg!(any(target_os = "dragonfly",
                target_os = "freebsd",
                target_os = "linux",
                target_os = "netbsd",
                target_os = "openbsd")) &&
       !INVALID.load(Ordering::SeqCst)
    {

        if let Some(pipe) = pipe2.get() {
            // Note that despite calling a glibc function here we may still
            // get ENOSYS. Glibc has `pipe2` since 2.9 and doesn't try to
            // emulate on older kernels, so if you happen to be running on
            // an older kernel you may see `pipe2` as a symbol but still not
            // see the syscall.
            match cvt(unsafe { pipe(fds.as_mut_ptr(), libc::O_CLOEXEC) }) {
                Ok(_) => {
                    return Ok((AnonPipe(FileDesc::new(fds[0])),
                               AnonPipe(FileDesc::new(fds[1]))));
                }
                Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {
                    INVALID.store(true, Ordering::SeqCst);
                }
                Err(e) => return Err(e),
            }
        }
    }
    cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;

    let fd0 = FileDesc::new(fds[0]);
    let fd1 = FileDesc::new(fds[1]);
    fd0.set_cloexec()?;
    fd1.set_cloexec()?;
    Ok((AnonPipe(fd0), AnonPipe(fd1)))
}

impl AnonPipe {
    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn fd(&self) -> &FileDesc { &self.0 }
    pub fn into_fd(self) -> FileDesc { self.0 }
}

pub fn read2(p1: AnonPipe,
             v1: &mut Vec<u8>,
             p2: AnonPipe,
             v2: &mut Vec<u8>) -> io::Result<()> {

    // Set both pipes into nonblocking mode as we're gonna be reading from both
    // in the `select` loop below, and we wouldn't want one to block the other!
    let p1 = p1.into_fd();
    let p2 = p2.into_fd();
    p1.set_nonblocking(true)?;
    p2.set_nonblocking(true)?;

    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
    fds[0].fd = p1.raw();
    fds[0].events = libc::POLLIN;
    fds[1].fd = p2.raw();
    fds[1].events = libc::POLLIN;
    loop {
        // wait for either pipe to become readable using `poll`
        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;

        if fds[0].revents != 0 && read(&p1, v1)? {
            p2.set_nonblocking(false)?;
            return p2.read_to_end(v2).map(|_| ());
        }
        if fds[1].revents != 0 && read(&p2, v2)? {
            p1.set_nonblocking(false)?;
            return p1.read_to_end(v1).map(|_| ());
        }
    }

    // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
    // EAGAIN. If we hit EOF, then this will happen because the underlying
    // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
    // this case we flip the other fd back into blocking mode and read
    // whatever's leftover on that file descriptor.
    fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {
        match fd.read_to_end(dst) {
            Ok(_) => Ok(true),
            Err(e) => {
                if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
                   e.raw_os_error() == Some(libc::EAGAIN) {
                    Ok(false)
                } else {
                    Err(e)
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// This should fail even without validation
// compile-flags: -Zmir-emit-validate=0

fn main() {
    #[cfg(target_pointer_width="64")]
    let bad = unsafe {
        std::mem::transmute::<&[u8], u128>(&[1u8])
    };
    #[cfg(target_pointer_width="32")]
    let bad = unsafe {
        std::mem::transmute::<&[u8], u64>(&[1u8])
    };
    let _ = bad + 1; //~ ERROR constant evaluation error
    //~^ NOTE a raw memory access tried to access part of a pointer value as raw bytes
}
<commit_msg>try using types with lower alignment, maybe that helps for Windows<commit_after>// This should fail even without validation
// compile-flags: -Zmir-emit-validate=0

fn main() {
    #[cfg(target_pointer_width="64")]
    let bad = unsafe {
        std::mem::transmute::<&[u8], [u8; 16]>(&[1u8])
    };
    #[cfg(target_pointer_width="32")]
    let bad = unsafe {
        std::mem::transmute::<&[u8], [u8; 8]>(&[1u8])
    };
    let _ = bad[0] + bad[bad.len()-1]; //~ ERROR constant evaluation error
    //~^ NOTE a raw memory access tried to access part of a pointer value as raw bytes
}
<|endoftext|>