<commit_before>use crate::common::util::*;

static INPUT: &'static str = "lorem_ipsum.txt";

#[test]
fn test_stdin_default() {
    new_ucmd!()
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_default.expected");
}

#[test]
fn test_stdin_1_line_obsolete() {
    new_ucmd!()
        .args(&["-1"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_1_line() {
    new_ucmd!()
        .args(&["-n", "1"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_negative_23_line() {
    new_ucmd!()
        .args(&["-n", "-23"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_5_chars() {
    new_ucmd!()
        .args(&["-c", "5"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_5_chars.expected");
}

#[test]
fn test_single_default() {
    new_ucmd!()
        .arg(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_default.expected");
}

#[test]
fn test_single_1_line_obsolete() {
    new_ucmd!()
        .args(&["-1", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_single_1_line() {
    new_ucmd!()
        .args(&["-n", "1", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_single_5_chars() {
    new_ucmd!()
        .args(&["-c", "5", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_5_chars.expected");
}

#[test]
fn test_verbose() {
    new_ucmd!()
        .args(&["-v", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_verbose.expected");
}

#[test]
fn test_spams_newline() {
    new_ucmd!().pipe_in("a").succeeds().stdout_is("a\n");
}

#[test]
fn test_unsupported_byte_syntax() {
    new_ucmd!()
        .args(&["-1c"])
        .pipe_in("abc")
        .fails()
        //GNU head returns "a"
        .stdout_is("")
        .stderr_is("head: error: Unrecognized option: \'1\'");
}

#[test]
fn test_unsupported_line_syntax() {
    new_ucmd!()
        .args(&["-n", "2048m"])
        .pipe_in("a\n")
        .fails()
        //.stdout_is("a\n");  What GNU head returns.
        .stdout_is("")
        .stderr_is("head: error: invalid line count \'2048m\': invalid digit found in string");
}

#[test]
fn test_unsupported_zero_terminated_syntax() {
    new_ucmd!()
        .args(&["-z -n 1"])
        .pipe_in("x\0y")
        .fails()
        //GNU Head returns "x\0"
        .stderr_is("head: error: Unrecognized option: \'z\'");
}

#[test]
fn test_unsupported_zero_terminated_syntax_2() {
    new_ucmd!()
        .args(&["-z -n 2"])
        .pipe_in("x\0y")
        .fails()
        //GNU Head returns "x\0y"
        .stderr_is("head: error: Unrecognized option: \'z\'");
}

#[test]
fn test_unsupported_negative_byte_syntax() {
    new_ucmd!()
        .args(&["--bytes=-2"])
        .pipe_in("a\n")
        .fails()
        //GNU Head returns ""
        .stderr_is("head: error: invalid byte count \'-2\': invalid digit found in string");
}

#[test]
fn test_bug_in_negative_zero_lines() {
    new_ucmd!()
        .args(&["--lines=-0"])
        .pipe_in("a\nb\n")
        .succeeds()
        //GNU Head returns "a\nb\n"
        .stdout_is("");
}
<commit_msg>head: Ignore known-failing tests introduced in #1579 (#1586)<commit_after>use crate::common::util::*;

static INPUT: &'static str = "lorem_ipsum.txt";

#[test]
fn test_stdin_default() {
    new_ucmd!()
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_default.expected");
}

#[test]
fn test_stdin_1_line_obsolete() {
    new_ucmd!()
        .args(&["-1"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_1_line() {
    new_ucmd!()
        .args(&["-n", "1"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_negative_23_line() {
    new_ucmd!()
        .args(&["-n", "-23"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_stdin_5_chars() {
    new_ucmd!()
        .args(&["-c", "5"])
        .pipe_in_fixture(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_5_chars.expected");
}

#[test]
fn test_single_default() {
    new_ucmd!()
        .arg(INPUT)
        .run()
        .stdout_is_fixture("lorem_ipsum_default.expected");
}

#[test]
fn test_single_1_line_obsolete() {
    new_ucmd!()
        .args(&["-1", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_single_1_line() {
    new_ucmd!()
        .args(&["-n", "1", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_1_line.expected");
}

#[test]
fn test_single_5_chars() {
    new_ucmd!()
        .args(&["-c", "5", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_5_chars.expected");
}

#[test]
fn test_verbose() {
    new_ucmd!()
        .args(&["-v", INPUT])
        .run()
        .stdout_is_fixture("lorem_ipsum_verbose.expected");
}

#[test]
#[ignore]
fn test_spams_newline() {
    new_ucmd!().pipe_in("a").succeeds().stdout_is("a\n");
}

#[test]
#[ignore]
fn test_unsupported_byte_syntax() {
    new_ucmd!()
        .args(&["-1c"])
        .pipe_in("abc")
        .fails()
        //GNU head returns "a"
        .stdout_is("")
        .stderr_is("head: error: Unrecognized option: \'1\'");
}

#[test]
#[ignore]
fn test_unsupported_line_syntax() {
    new_ucmd!()
        .args(&["-n", "2048m"])
        .pipe_in("a\n")
        .fails()
        //.stdout_is("a\n");  What GNU head returns.
        .stdout_is("")
        .stderr_is("head: error: invalid line count \'2048m\': invalid digit found in string");
}

#[test]
#[ignore]
fn test_unsupported_zero_terminated_syntax() {
    new_ucmd!()
        .args(&["-z -n 1"])
        .pipe_in("x\0y")
        .fails()
        //GNU Head returns "x\0"
        .stderr_is("head: error: Unrecognized option: \'z\'");
}

#[test]
#[ignore]
fn test_unsupported_zero_terminated_syntax_2() {
    new_ucmd!()
        .args(&["-z -n 2"])
        .pipe_in("x\0y")
        .fails()
        //GNU Head returns "x\0y"
        .stderr_is("head: error: Unrecognized option: \'z\'");
}

#[test]
#[ignore]
fn test_unsupported_negative_byte_syntax() {
    new_ucmd!()
        .args(&["--bytes=-2"])
        .pipe_in("a\n")
        .fails()
        //GNU Head returns ""
        .stderr_is("head: error: invalid byte count \'-2\': invalid digit found in string");
}

#[test]
#[ignore]
fn test_bug_in_negative_zero_lines() {
    new_ucmd!()
        .args(&["--lines=-0"])
        .pipe_in("a\nb\n")
        .succeeds()
        //GNU Head returns "a\nb\n"
        .stdout_is("");
}
<|endoftext|>


<commit_before>macro_rules! vk_functions {
    ($($raw_name: expr, $name: ident ($($param_name: ident: $param: ty),*,) -> $ret: ty;)+) => {
        $(
            pub unsafe extern "system" fn $name (
                $($param_name: $param),*
                ) -> $ret {
                use std::mem;

                mem::transmute::<_, $name::FnType>($name::FN_PTR)($($param_name),*)
            }

            pub mod $name {

                use super::super::*;
                #[allow(unused_imports)]
                use super::super::libc_reexports::*;
                pub const RAW_NAME: &'static str = $raw_name;
                pub static mut FN_PTR: *const () = unloaded_function_panic as *const ();
                #[doc(hidden)]
                pub type FnType = unsafe extern "system" fn($($param),*) -> $ret;

                pub fn is_loaded() -> bool {
                    unsafe{ FN_PTR == unloaded_function_panic as *const () }
                }
            }
        )+

        pub fn load_with<F: FnMut(&str) -> *const ()>(mut load_fn: F) -> ::std::result::Result<(), Vec<&'static str>> {unsafe{
            use std::ptr;
            let mut fn_buf: *const ();
            let mut unloaded_fns = Vec::new();

            $(
                fn_buf = load_fn($raw_name);
                if ptr::null() != fn_buf {
                    $name::FN_PTR = fn_buf;
                } else if $name::FN_PTR != unloaded_function_panic as *const () {
                    unloaded_fns.push($raw_name)
                }
            )+

            if 0 == unloaded_fns.len() {
                Ok(())
            } else {
                Err(unloaded_fns)
            }
        }}
    }
}
<commit_msg>Fixed load_with bug in global generator<commit_after>macro_rules! vk_functions {
    ($($raw_name: expr, $name: ident ($($param_name: ident: $param: ty),*,) -> $ret: ty;)+) => {
        $(
            pub unsafe extern "system" fn $name (
                $($param_name: $param),*
                ) -> $ret {
                use std::mem;

                mem::transmute::<_, $name::FnType>($name::FN_PTR)($($param_name),*)
            }

            pub mod $name {

                use super::super::*;
                #[allow(unused_imports)]
                use super::super::libc_reexports::*;
                pub const RAW_NAME: &'static str = $raw_name;
                pub static mut FN_PTR: *const () = unloaded_function_panic as *const ();
                #[doc(hidden)]
                pub type FnType = unsafe extern "system" fn($($param),*) -> $ret;

                pub fn is_loaded() -> bool {
                    unsafe{ FN_PTR == unloaded_function_panic as *const () }
                }
            }
        )+

        pub fn load_with<F: FnMut(&str) -> *const ()>(mut load_fn: F) -> ::std::result::Result<(), Vec<&'static str>> {unsafe{
            use std::ptr;
            let mut fn_buf: *const ();
            let mut unloaded_fns = Vec::new();

            $(
                fn_buf = load_fn($raw_name);
                if ptr::null() != fn_buf {
                    $name::FN_PTR = fn_buf;
                } else if $name::FN_PTR == unloaded_function_panic as *const () {
                    unloaded_fns.push($raw_name)
                }
            )+

            if 0 == unloaded_fns.len() {
                Ok(())
            } else {
                Err(unloaded_fns)
            }
        }}
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::{io, os, str};

use test::{black_box, BenchHarness, TestDesc, TestDescAndFn};
use test::{DynTestName, DynBenchFn, TDynBenchFn};

use html5::tokenizer::{TokenSink, Token, Tokenizer, TokenizerOpts};

struct Sink;

impl TokenSink for Sink {
    fn process_token(&mut self, token: Token) {
        // Don't use the token, but make sure we don't get
        // optimized out entirely.
        black_box(token);
    }
}

// This could almost be the TokenSink too, but it's not
// mut within run().
struct Bench {
    input: ~str,
    clone_only: bool,
    opts: TokenizerOpts,
}

impl Bench {
    fn new(name: &str, size: Option<uint>, clone_only: bool,
           opts: TokenizerOpts) -> Bench {
        let mut path = os::self_exe_path().expect("can't get exe path");
        path.push("../data/bench/");
        path.push(name);
        let mut file = io::File::open(&path).ok().expect("can't open file");
        let file_input = file.read_to_str().ok().expect("can't read file");

        let input = match size {
            None => file_input,
            Some(size) => {
                // Replicate the input in memory up to the desired size.
                let mut input = str::with_capacity(size);
                while input.len() < size {
                    input.push_str(file_input);
                }
                input
            }
        };

        Bench {
            input: input,
            clone_only: clone_only,
            opts: opts,
        }
    }
}

impl TDynBenchFn for Bench {
    fn run(&self, bh: &mut BenchHarness) {
        bh.iter(|| {
            let input = self.input.clone();
            if self.clone_only {
                // Because the tokenizer consumes its buffers, we need
                // to clone inside iter().  We can benchmark this
                // separately and subtract it out.
                black_box(input);
            } else {
                let mut sink = Sink;
                let mut tok = Tokenizer::new(&mut sink, self.opts.clone());
                tok.feed(self.input.clone());
                tok.end();
            }
        });
    }
}

fn make_bench(name: &str, size: Option<uint>, clone_only: bool,
              opts: TokenizerOpts) -> TestDescAndFn {
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName([
                ~"tokenize ",
                name.to_owned(),
                size.map_or(~"", |s| format!(" size {:7u}", s)),
                if clone_only { ~" (clone only)" } else { ~"" },
                if opts.exact_errors { ~" (exact errors)" } else { ~"" },
            ].concat()),
            ignore: false,
            should_fail: false,
        },
        testfn: DynBenchFn(~Bench::new(name, size, clone_only, opts)),
    }
}

pub fn tests() -> ~[TestDescAndFn] {
    let mut tests = ~[
        make_bench("lipsum.html", Some(1024*1024), true, Default::default()),
    ];

    let mut opts_vec = ~[Default::default()];
    if os::getenv("BENCH_EXACT_ERRORS").is_some() {
        opts_vec.push(TokenizerOpts {
            exact_errors: true,
            .. Default::default()
        });
    }

    for opts in opts_vec.iter() {
        for &file in ["lipsum.html", "lipsum-zh.html", "strong.html"].iter() {
            for &sz in [1024, 1024*1024].iter() {
                tests.push(make_bench(file, Some(sz), false, opts.clone()));
            }
        }

        if os::getenv("BENCH_UNCOMMITTED").is_some() {
            // Not checked into the repo, so don't include by default.
            for &file in ["webapps.html", "sina.com.cn.html", "wikipedia.html"].iter() {
                let name: ~str = (~"uncommitted/").append(file);
                tests.push(make_bench(name.as_slice(), None, false, opts.clone()));
            }
        }
    }

    tests
}
<commit_msg>Remove unnecessary clone in tokenizer benchmark<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::{io, os, str};

use test::{black_box, BenchHarness, TestDesc, TestDescAndFn};
use test::{DynTestName, DynBenchFn, TDynBenchFn};

use html5::tokenizer::{TokenSink, Token, Tokenizer, TokenizerOpts};

struct Sink;

impl TokenSink for Sink {
    fn process_token(&mut self, token: Token) {
        // Don't use the token, but make sure we don't get
        // optimized out entirely.
        black_box(token);
    }
}

// This could almost be the TokenSink too, but it's not
// mut within run().
struct Bench {
    input: ~str,
    clone_only: bool,
    opts: TokenizerOpts,
}

impl Bench {
    fn new(name: &str, size: Option<uint>, clone_only: bool,
           opts: TokenizerOpts) -> Bench {
        let mut path = os::self_exe_path().expect("can't get exe path");
        path.push("../data/bench/");
        path.push(name);
        let mut file = io::File::open(&path).ok().expect("can't open file");
        let file_input = file.read_to_str().ok().expect("can't read file");

        let input = match size {
            None => file_input,
            Some(size) => {
                // Replicate the input in memory up to the desired size.
                let mut input = str::with_capacity(size);
                while input.len() < size {
                    input.push_str(file_input);
                }
                input
            }
        };

        Bench {
            input: input,
            clone_only: clone_only,
            opts: opts,
        }
    }
}

impl TDynBenchFn for Bench {
    fn run(&self, bh: &mut BenchHarness) {
        bh.iter(|| {
            let input = self.input.clone();
            if self.clone_only {
                // Because the tokenizer consumes its buffers, we need
                // to clone inside iter().  We can benchmark this
                // separately and subtract it out.
                black_box(input);
            } else {
                let mut sink = Sink;
                let mut tok = Tokenizer::new(&mut sink, self.opts.clone());
                tok.feed(input);
                tok.end();
            }
        });
    }
}

fn make_bench(name: &str, size: Option<uint>, clone_only: bool,
              opts: TokenizerOpts) -> TestDescAndFn {
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName([
                ~"tokenize ",
                name.to_owned(),
                size.map_or(~"", |s| format!(" size {:7u}", s)),
                if clone_only { ~" (clone only)" } else { ~"" },
                if opts.exact_errors { ~" (exact errors)" } else { ~"" },
            ].concat()),
            ignore: false,
            should_fail: false,
        },
        testfn: DynBenchFn(~Bench::new(name, size, clone_only, opts)),
    }
}

pub fn tests() -> ~[TestDescAndFn] {
    let mut tests = ~[
        make_bench("lipsum.html", Some(1024*1024), true, Default::default()),
    ];

    let mut opts_vec = ~[Default::default()];
    if os::getenv("BENCH_EXACT_ERRORS").is_some() {
        opts_vec.push(TokenizerOpts {
            exact_errors: true,
            .. Default::default()
        });
    }

    for opts in opts_vec.iter() {
        for &file in ["lipsum.html", "lipsum-zh.html", "strong.html"].iter() {
            for &sz in [1024, 1024*1024].iter() {
                tests.push(make_bench(file, Some(sz), false, opts.clone()));
            }
        }

        if os::getenv("BENCH_UNCOMMITTED").is_some() {
            // Not checked into the repo, so don't include by default.
            for &file in ["webapps.html", "sina.com.cn.html", "wikipedia.html"].iter() {
                let name: ~str = (~"uncommitted/").append(file);
                tests.push(make_bench(name.as_slice(), None, false, opts.clone()));
            }
        }
    }

    tests
}
<|endoftext|>


<commit_before>use common::types::FnType;
use common::types::StructType;
use common::link::*;

use common::entity::FromEntity;
use common::entity::Entity;
use std::cmp::Ordering;

use std::ops::Deref;

#[derive(Debug, Clone)]
pub struct Node {
    id: i32,
    name: String,
    url: String,
    fn_type: FnType,
    link: Vec<Link>,
    nodes: Vec<Node>,
}

impl Node {
    fn set_children(&self, children: &[Entity]) {

    }
}

impl FromEntity for Node {
    fn from_entity(entity: Entity) -> Self {
        Node {
            id: entity.id,
            name: entity.name,
            url: entity.url,
            fn_type: entity.fn_type,
            link: Vec::new(),
            nodes: Vec::new()
        }
    }

    //TODO entity matcher for nodes
    fn from_entities(mut entites: Vec<Entity>) -> Vec<Self> {
        let mut node_vec: Vec<Node> = Vec::new();
        let mut link_vec: Vec<Link> = Vec::new();

        //let base_length = 2;
        entites.sort_by(|e1, e2| {
            if e1.tree_id.len() < e2.tree_id.len() {
                Ordering::Less
            } else if e1.tree_id.len() > e2.tree_id.len() {
                Ordering::Greater
            } else {
                Ordering::Equal
            }
        });

        println!("{:?}", node_vec);
        node_vec
    }
}
<commit_msg>full vector with non-scalar conversion<commit_after>use common::types::FnType;
use common::types::StructType;
use common::link::*;

use common::entity::FromEntity;
use common::entity::Entity;
use std::cmp::Ordering;

use std::ops::Deref;

#[derive(Debug, Clone)]
pub struct Node {
    id: i32,
    name: String,
    url: String,
    fn_type: FnType,
    link: Vec<Link>,
    nodes: Vec<Node>,
}

impl Node {
    fn set_children(&self, children: &[Entity]) {

    }
}

impl FromEntity for Node {
    fn from_entity(entity: Entity) -> Self {
        Node {
            id: entity.id,
            name: entity.name,
            url: entity.url,
            fn_type: entity.fn_type,
            link: Vec::new(),
            nodes: Vec::new()
        }
    }

    //TODO entity matcher for nodes
    fn from_entities(mut entites: Vec<Entity>) -> Vec<Self> {
        let mut node_vec: Vec<Node> = Vec::new();
        let mut link_vec: Vec<Link> = Vec::new();

        //let base_length = 2;
        entites.sort_by(|e1, e2| {
            if e1.tree_id.len() < e2.tree_id.len() {
                Ordering::Less
            } else if e1.tree_id.len() > e2.tree_id.len() {
                Ordering::Greater
            } else {
                Ordering::Equal
            }
        });

        //remplir les tableau node_vec et link_vec
        for entity in entites{
            if entity.struct_type.into() == "Node"{
                node_vec.push(entity as Node);
            }
            else if entity.struct_type.into() == "Link"{
                link_vec.push(entity as Link);
            }
        }

        println!("{:?}", node_vec);
        node_vec
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

// xfail-fast
#[legacy_modes];

struct Point {
    x: int,
    y: int
}

impl Point : ops::Add<Point,Point> {
    pure fn add(&self, other: &Point) -> Point {
        Point {x: self.x + (*other).x, y: self.y + (*other).y}
    }
}

impl Point : ops::Sub<Point,Point> {
    pure fn sub(&self, other: &Point) -> Point {
        Point {x: self.x - (*other).x, y: self.y - (*other).y}
    }
}

impl Point : ops::Neg<Point> {
    pure fn neg(&self) -> Point {
        Point {x: -self.x, y: -self.y}
    }
}

impl Point : ops::Index<bool,int> {
    pure fn index(&self, +x: bool) -> int {
        if x { self.x } else { self.y }
    }
}

impl Point : cmp::Eq {
    pure fn eq(&self, other: &Point) -> bool {
        (*self).x == (*other).x && (*self).y == (*other).y
    }
    pure fn ne(&self, other: &Point) -> bool { !(*self).eq(other) }
}

fn main() {
    let mut p = Point {x: 10, y: 20};
    p += Point {x: 101, y: 102};
    p = p - Point {x: 100, y: 100};
    assert p + Point {x: 5, y: 5} == Point {x: 16, y: 27};
    assert -p == Point {x: -11, y: -22};
    assert p[true] == 11;
    assert p[false] == 22;
    // Issue #1733
    fn~(_x: int){}(p[true]);
}
<commit_msg>test: add test for overloading logical negation operator<commit_after>// Copyright 2012 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.

// xfail-fast
#[legacy_modes];

struct Point {
    x: int,
    y: int
}

impl Point : ops::Add<Point,Point> {
    pure fn add(&self, other: &Point) -> Point {
        Point {x: self.x + (*other).x, y: self.y + (*other).y}
    }
}

impl Point : ops::Sub<Point,Point> {
    pure fn sub(&self, other: &Point) -> Point {
        Point {x: self.x - (*other).x, y: self.y - (*other).y}
    }
}

impl Point : ops::Neg<Point> {
    pure fn neg(&self) -> Point {
        Point {x: -self.x, y: -self.y}
    }
}

impl Point : ops::Not<Point> {
    pure fn not(&self) -> Point {
        Point {x: !self.x, y: !self.y }
    }
}

impl Point : ops::Index<bool,int> {
    pure fn index(&self, +x: bool) -> int {
        if x { self.x } else { self.y }
    }
}

impl Point : cmp::Eq {
    pure fn eq(&self, other: &Point) -> bool {
        (*self).x == (*other).x && (*self).y == (*other).y
    }
    pure fn ne(&self, other: &Point) -> bool { !(*self).eq(other) }
}

fn main() {
    let mut p = Point {x: 10, y: 20};
    p += Point {x: 101, y: 102};
    p = p - Point {x: 100, y: 100};
    assert p + Point {x: 5, y: 5} == Point {x: 16, y: 27};
    assert -p == Point {x: -11, y: -22};
    assert p[true] == 11;
    assert p[false] == 22;

    let q = !p;
    assert q.x == !(p.x);
    assert q.y == !(p.y);

    // Issue #1733
    fn~(_x: int){}(p[true]);
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::DocumentBinding;
use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, Fallible};
use dom::bindings::utils::{BindingObject, CacheableWrapper, DerivedWrapper};
use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable, null_str_as_empty};
use dom::element::{Element};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::Event;
use dom::htmlcollection::HTMLCollection;
use dom::htmldocument::HTMLDocument;
use dom::htmlelement::HTMLElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId};
use dom::text::Text;
use dom::window::Window;
use dom::windowproxy::WindowProxy;
use dom::htmltitleelement::HTMLTitleElement;
use html::hubbub_html_parser::build_element_from_tag;
use js::jsapi::{JSObject, JSContext, JSVal};
use js::jsapi::{JSTRACE_OBJECT, JSTracer, JS_CallTracer};
use js::glue::RUST_OBJECT_TO_JSVAL;
use servo_util::tree::TreeNodeRef;

use std::cast;
use std::ptr;
use std::str::eq_slice;
use std::libc;
use std::ascii::StrAsciiExt;
use std::unstable::raw::Box;

pub trait WrappableDocument {
    fn init_wrapper(@mut self, cx: *JSContext);
}

#[deriving(Eq)]
pub struct AbstractDocument {
    document: *Document
}

impl AbstractDocument {
    pub fn as_abstract<T: WrappableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument {
        doc.init_wrapper(cx);
        AbstractDocument {
            document: unsafe { cast::transmute(doc) }
        }
    }

    unsafe fn transmute<T, R>(&self, f: &fn(&T) -> R) -> R {
        let box: *Box<T> = cast::transmute(self.document);
        f(&(*box).data)
    }

    unsafe fn transmute_mut<T, R>(&self, f: &fn(&mut T) -> R) -> R {
        let box: *mut Box<T> = cast::transmute(self.document);
        f(&mut (*box).data)
    }

    pub fn with_base<R>(&self, callback: &fn(&Document) -> R) -> R {
        unsafe {
            self.transmute(callback)
        }
    }

    pub fn with_mut_base<R>(&self, callback: &fn(&mut Document) -> R) -> R {
        unsafe {
            self.transmute_mut(callback)
        }
    }

    pub fn with_html<R>(&self, callback: &fn(&HTMLDocument) -> R) -> R {
        match self.with_base(|doc| doc.doctype) {
            HTML => unsafe { self.transmute(callback) },
            _ => fail!("attempt to downcast a non-HTMLDocument to HTMLDocument")
        }
    }

    pub fn set_root(&self, root: AbstractNode<ScriptView>) {
        self.with_mut_base(|document| {
            document.set_root(root);
        });
    }
}

pub enum DocumentType {
    HTML,
    SVG,
    XML
}

pub struct Document {
    root: Option<AbstractNode<ScriptView>>,
    wrapper: WrapperCache,
    window: Option<@mut Window>,
    doctype: DocumentType,
    title: ~str
}

impl Document {
    #[fixed_stack_segment]
    pub fn new(window: Option<@mut Window>, doctype: DocumentType) -> Document {
        Document {
            root: None,
            wrapper: WrapperCache::new(),
            window: window,
            doctype: doctype,
            title: ~""
        }
    }

    pub fn set_root(&mut self, root: AbstractNode<ScriptView>) {
        self.root = Some(root);
    }

    pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> {
        let cx = owner.page.js_info.get_ref().js_compartment.cx.ptr;

        let document = AbstractDocument::as_abstract(cx, @mut Document::new(None, XML));

        let root = @HTMLHtmlElement {
            htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html")
        };
        let root = unsafe { Node::as_abstract_node(cx, root) };
        document.set_root(root);

        Ok(document)
    }
}

impl WrappableDocument for Document {
    fn init_wrapper(@mut self, cx: *JSContext) {
        self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
    }
}

impl CacheableWrapper for AbstractDocument {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        do self.with_mut_base |doc| {
            doc.get_wrappercache()
        }
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        match self.with_base(|doc| doc.doctype) {
            HTML => {
                let doc: @mut HTMLDocument = unsafe { cast::transmute(self.document) };
                doc.wrap_object_shared(cx, scope)
            }
            XML | SVG => {
                fail!("no wrapping for documents that don't exist")
            }
        }
    }
}

impl BindingObject for AbstractDocument {
    fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
        do self.with_mut_base |doc| {
            doc.GetParentObject(cx)
        }
    }
}

impl DerivedWrapper for AbstractDocument {
    #[fixed_stack_segment]
    fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
        let cache = self.get_wrappercache();
        let wrapper = cache.get_wrapper();
        unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
        return 1;
    }

    fn wrap_shared(@mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
        fail!(~"nyi")
    }
}

impl CacheableWrapper for Document {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        unsafe {
            cast::transmute(&self.wrapper)
        }
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        let mut unused = false;
        DocumentBinding::Wrap(cx, scope, self, &mut unused)
    }
}

impl BindingObject for Document {
    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
        match self.window {
            Some(win) => Some(win as @mut CacheableWrapper),
            None => None
        }
    }
}

impl Document {
    pub fn URL(&self) -> DOMString {
        None
    }

    pub fn DocumentURI(&self) -> DOMString {
        None
    }

    pub fn CompatMode(&self) -> DOMString {
        None
    }

    pub fn CharacterSet(&self) -> DOMString {
        None
    }

    pub fn ContentType(&self) -> DOMString {
        None
    }

    pub fn GetDocumentElement(&self) -> Option<AbstractNode<ScriptView>> {
        self.root
    }

    fn get_cx(&self) -> *JSContext {
        let win = self.window.get_ref();
        win.page.js_info.get_ref().js_compartment.cx.ptr
    }

    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let win = self.window.get_ref();
        let cx = win.page.js_info.get_ref().js_compartment.cx.ptr;
        let cache = win.get_wrappercache();
        let scope = cache.get_wrapper();
        (scope, cx)
    }

    pub fn GetElementsByTagName(&self, tag: &DOMString) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, null_str_as_empty(tag)))
    }

    pub fn GetElementsByTagNameNS(&self, _ns: &DOMString, _tag: &DOMString) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn GetElementsByClassName(&self, _class: &DOMString) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn GetElementById(&self, _id: &DOMString) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn CreateElement(&self, local_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> {
        let cx = self.get_cx();
        let local_name = null_str_as_empty(local_name);
        if !is_valid_element_name(local_name) {
            return Err(InvalidCharacter);
        }
        let local_name = local_name.to_ascii_lower();
        Ok(build_element_from_tag(cx, local_name))
    }

    pub fn CreateElementNS(&self, _namespace: &DOMString, _qualified_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> {
        fail!("stub")
    }

    pub fn CreateTextNode(&self, data: &DOMString) -> AbstractNode<ScriptView> {
        let cx = self.get_cx();
        unsafe { Node::as_abstract_node(cx, @Text::new(null_str_as_empty(data))) }
    }

    pub fn CreateEvent(&self, _interface: &DOMString) -> Fallible<@mut Event> {
        fail!("stub")
    }

    pub fn GetInputEncoding(&self) -> DOMString {
        None
    }

    pub fn Referrer(&self) -> DOMString {
        None
    }

    pub fn LastModified(&self) -> DOMString {
        None
    }

    pub fn ReadyState(&self) -> DOMString {
        None
    }

    pub fn Title(&self) -> DOMString {
        let mut title = ~"";
        match self.doctype {
            SVG => {
                fail!("no SVG document yet")
            },
            _ => {
                match self.root {
                    None => {},
                    Some(root) => {
                        for node in root.traverse_preorder() {
                            if node.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) {
                                loop;
                            }
                            for child in node.children() {
                                if child.is_text() {
                                    do child.with_imm_text() |text| {
                                        let s = text.element.Data();
                                        title = title + null_str_as_empty(&s);
                                    }
                                }
                            }
                            break;
                        };
                    }
                }
            }
        }
        let v: ~[&str] = title.word_iter().collect();
        title = v.connect(" ");
        title = title.trim().to_owned();
        Some(title)
    }

    pub fn SetTitle(&self, title: &DOMString) -> ErrorResult {
        match self.doctype {
            SVG => {
                fail!("no SVG document yet")
            },
            _ => {
                let (_scope, cx) = self.get_scope_and_cx();
                match self.root {
                    None => {},
                    Some(root) => {
                        for node in root.traverse_preorder() {
                            if node.type_id() != ElementNodeTypeId(HTMLHeadElementTypeId) {
                                loop;
                            }
                            let mut has_title = false;
                            for child in node.children() {
                                if child.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) {
                                    loop;
                                }
                                has_title = true;
                                for title_child in child.children() {
                                    child.remove_child(title_child);
                                }
                                child.add_child(self.CreateTextNode(title));
                                break;
                            }
                            if !has_title {
                                let new_title = @HTMLTitleElement {
                                    htmlelement: HTMLElement::new(HTMLTitleElementTypeId, ~"title")
                                };
                                let new_title = unsafe {
                                    Node::as_abstract_node(cx, new_title)
                                };
                                new_title.add_child(self.CreateTextNode(title));
                                node.add_child(new_title);
                            }
                            break;
                        };
                    }
                }
            }
        }
        Ok(())
    }

    pub fn Dir(&self) -> DOMString {
        None
    }

    pub fn SetDir(&self, _dir: &DOMString) {
    }

    pub fn GetDefaultView(&self) -> Option<@mut WindowProxy> {
        None
    }

    pub fn GetActiveElement(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn HasFocus(&self) -> Fallible<bool> {
        Ok(false)
    }

    pub fn GetCurrentScript(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn ReleaseCapture(&self) {
    }

    pub fn MozFullScreenEnabled(&self) -> bool {
        false
    }

    pub fn GetMozFullScreenElement(&self) -> Fallible<Option<AbstractNode<ScriptView>>> {
        Ok(None)
    }

    pub fn GetMozPointerLockElement(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn MozExitPointerLock(&self) {
    }

    pub fn Hidden(&self) -> bool {
        false
    }

    pub fn MozHidden(&self) -> bool {
        self.Hidden()
    }

    pub fn VisibilityState(&self) -> DocumentBinding::VisibilityState {
        DocumentBinding::VisibilityStateValues::Visible
    }

    pub fn MozVisibilityState(&self) -> DocumentBinding::VisibilityState {
        self.VisibilityState()
    }

    pub fn GetSelectedStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn SetSelectedStyleSheetSet(&self, _sheet: &DOMString) {
    }

    pub fn GetLastStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn GetPreferredStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn EnableStyleSheetsForSet(&self, _name: &DOMString) {
    }

    pub fn ElementFromPoint(&self, _x: f32, _y: f32) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn QuerySelector(&self, _selectors: &DOMString) -> Fallible<Option<AbstractNode<ScriptView>>> {
        Ok(None)
    }

    pub fn GetElementsByName(&self, name: &DOMString) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem|
            elem.get_attr("name").is_some() && eq_slice(elem.get_attr("name").unwrap(), null_str_as_empty(name)))
    }

    pub fn createHTMLCollection(&self, callback: &fn(elem: &Element) -> bool) -> @mut HTMLCollection {
        let mut elements = ~[];
        match self.root {
            None => {},
            Some(root) => {
                for child in root.traverse_preorder() {
                    if child.is_element() {
                        do child.with_imm_element |elem| {
                            if callback(elem) {
                                elements.push(child);
                            }
                        }
                    }
                };
            }
        }
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(elements, cx, scope)
    }

    pub fn content_changed(&self) {
        for window in self.window.iter() {
            window.content_changed()
        }
    }

    pub fn wait_until_safe_to_modify_dom(&self) {
        for window in self.window.iter() {
            window.wait_until_safe_to_modify_dom();
        }
    }
}

impl Traceable for Document {
    #[fixed_stack_segment]
    fn trace(&self, tracer: *mut JSTracer) {
        match self.root {
            None => {},
            Some(root) => {
                unsafe {
                    (*tracer).debugPrinter = ptr::null();
                    (*tracer).debugPrintIndex = -1;
                    do "root".to_c_str().with_ref |name| {
                        (*tracer).debugPrintArg = name as *libc::c_void;
                        debug!("tracing root node");
                        do root.with_base |node| {
                            JS_CallTracer(tracer as *JSTracer,
                                          node.wrapper.wrapper,
                                          JSTRACE_OBJECT as u32);
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>Remove Document::set_root.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::DocumentBinding;
use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, Fallible};
use dom::bindings::utils::{BindingObject, CacheableWrapper, DerivedWrapper};
use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable, null_str_as_empty};
use dom::element::{Element};
use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::Event;
use dom::htmlcollection::HTMLCollection;
use dom::htmldocument::HTMLDocument;
use dom::htmlelement::HTMLElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId};
use dom::text::Text;
use dom::window::Window;
use dom::windowproxy::WindowProxy;
use dom::htmltitleelement::HTMLTitleElement;
use html::hubbub_html_parser::build_element_from_tag;
use js::jsapi::{JSObject, JSContext, JSVal};
use js::jsapi::{JSTRACE_OBJECT, JSTracer, JS_CallTracer};
use js::glue::RUST_OBJECT_TO_JSVAL;
use servo_util::tree::TreeNodeRef;

use std::cast;
use std::ptr;
use std::str::eq_slice;
use std::libc;
use std::ascii::StrAsciiExt;
use std::unstable::raw::Box;

pub trait WrappableDocument {
    fn init_wrapper(@mut self, cx: *JSContext);
}

#[deriving(Eq)]
pub struct AbstractDocument {
    document: *Document
}

impl AbstractDocument {
    pub fn as_abstract<T: WrappableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument {
        doc.init_wrapper(cx);
        AbstractDocument {
            document: unsafe { cast::transmute(doc) }
        }
    }

    unsafe fn transmute<T, R>(&self, f: &fn(&T) -> R) -> R {
        let box: *Box<T> = cast::transmute(self.document);
        f(&(*box).data)
    }

    unsafe fn transmute_mut<T, R>(&self, f: &fn(&mut T) -> R) -> R {
        let box: *mut Box<T> = cast::transmute(self.document);
        f(&mut (*box).data)
    }

    pub fn with_base<R>(&self, callback: &fn(&Document) -> R) -> R {
        unsafe {
            self.transmute(callback)
        }
    }

    pub fn with_mut_base<R>(&self, callback: &fn(&mut Document) -> R) -> R {
        unsafe {
            self.transmute_mut(callback)
        }
    }

    pub fn with_html<R>(&self, callback: &fn(&HTMLDocument) -> R) -> R {
        match self.with_base(|doc| doc.doctype) {
            HTML => unsafe { self.transmute(callback) },
            _ => fail!("attempt to downcast a non-HTMLDocument to HTMLDocument")
        }
    }

    pub fn set_root(&self, root: AbstractNode<ScriptView>) {
        self.with_mut_base(|document| {
            document.root = Some(root);
        });
    }
}

pub enum DocumentType {
    HTML,
    SVG,
    XML
}

pub struct Document {
    root: Option<AbstractNode<ScriptView>>,
    wrapper: WrapperCache,
    window: Option<@mut Window>,
    doctype: DocumentType,
    title: ~str
}

impl Document {
    #[fixed_stack_segment]
    pub fn new(window: Option<@mut Window>, doctype: DocumentType) -> Document {
        Document {
            root: None,
            wrapper: WrapperCache::new(),
            window: window,
            doctype: doctype,
            title: ~""
        }
    }

    pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> {
        let cx = owner.page.js_info.get_ref().js_compartment.cx.ptr;

        let document = AbstractDocument::as_abstract(cx, @mut Document::new(None, XML));

        let root = @HTMLHtmlElement {
            htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html")
        };
        let root = unsafe { Node::as_abstract_node(cx, root) };
        document.set_root(root);

        Ok(document)
    }
}

impl WrappableDocument for Document {
    fn init_wrapper(@mut self, cx: *JSContext) {
        self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
    }
}

impl CacheableWrapper for AbstractDocument {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        do self.with_mut_base |doc| {
            doc.get_wrappercache()
        }
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        match self.with_base(|doc| doc.doctype) {
            HTML => {
                let doc: @mut HTMLDocument = unsafe { cast::transmute(self.document) };
                doc.wrap_object_shared(cx, scope)
            }
            XML | SVG => {
                fail!("no wrapping for documents that don't exist")
            }
        }
    }
}

impl BindingObject for AbstractDocument {
    fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
        do self.with_mut_base |doc| {
            doc.GetParentObject(cx)
        }
    }
}

impl DerivedWrapper for AbstractDocument {
    #[fixed_stack_segment]
    fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
        let cache = self.get_wrappercache();
        let wrapper = cache.get_wrapper();
        unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
        return 1;
    }

    fn wrap_shared(@mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
        fail!(~"nyi")
    }
}

impl CacheableWrapper for Document {
    fn get_wrappercache(&mut self) -> &mut WrapperCache {
        unsafe {
            cast::transmute(&self.wrapper)
        }
    }

    fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
        let mut unused = false;
        DocumentBinding::Wrap(cx, scope, self, &mut unused)
    }
}

impl BindingObject for Document {
    fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
        match self.window {
            Some(win) => Some(win as @mut CacheableWrapper),
            None => None
        }
    }
}

impl Document {
    pub fn URL(&self) -> DOMString {
        None
    }

    pub fn DocumentURI(&self) -> DOMString {
        None
    }

    pub fn CompatMode(&self) -> DOMString {
        None
    }

    pub fn CharacterSet(&self) -> DOMString {
        None
    }

    pub fn ContentType(&self) -> DOMString {
        None
    }

    pub fn GetDocumentElement(&self) -> Option<AbstractNode<ScriptView>> {
        self.root
    }

    fn get_cx(&self) -> *JSContext {
        let win = self.window.get_ref();
        win.page.js_info.get_ref().js_compartment.cx.ptr
    }

    fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
        let win = self.window.get_ref();
        let cx = win.page.js_info.get_ref().js_compartment.cx.ptr;
        let cache = win.get_wrappercache();
        let scope = cache.get_wrapper();
        (scope, cx)
    }

    pub fn GetElementsByTagName(&self, tag: &DOMString) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem| eq_slice(elem.tag_name, null_str_as_empty(tag)))
    }

    pub fn GetElementsByTagNameNS(&self, _ns: &DOMString, _tag: &DOMString) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn GetElementsByClassName(&self, _class: &DOMString) -> @mut HTMLCollection {
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(~[], cx, scope)
    }

    pub fn GetElementById(&self, _id: &DOMString) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn CreateElement(&self, local_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> {
        let cx = self.get_cx();
        let local_name = null_str_as_empty(local_name);
        if !is_valid_element_name(local_name) {
            return Err(InvalidCharacter);
        }
        let local_name = local_name.to_ascii_lower();
        Ok(build_element_from_tag(cx, local_name))
    }

    pub fn CreateElementNS(&self, _namespace: &DOMString, _qualified_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> {
        fail!("stub")
    }

    pub fn CreateTextNode(&self, data: &DOMString) -> AbstractNode<ScriptView> {
        let cx = self.get_cx();
        unsafe { Node::as_abstract_node(cx, @Text::new(null_str_as_empty(data))) }
    }

    pub fn CreateEvent(&self, _interface: &DOMString) -> Fallible<@mut Event> {
        fail!("stub")
    }

    pub fn GetInputEncoding(&self) -> DOMString {
        None
    }

    pub fn Referrer(&self) -> DOMString {
        None
    }

    pub fn LastModified(&self) -> DOMString {
        None
    }

    pub fn ReadyState(&self) -> DOMString {
        None
    }

    pub fn Title(&self) -> DOMString {
        let mut title = ~"";
        match self.doctype {
            SVG => {
                fail!("no SVG document yet")
            },
            _ => {
                match self.root {
                    None => {},
                    Some(root) => {
                        for node in root.traverse_preorder() {
                            if node.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) {
                                loop;
                            }
                            for child in node.children() {
                                if child.is_text() {
                                    do child.with_imm_text() |text| {
                                        let s = text.element.Data();
                                        title = title + null_str_as_empty(&s);
                                    }
                                }
                            }
                            break;
                        };
                    }
                }
            }
        }
        let v: ~[&str] = title.word_iter().collect();
        title = v.connect(" ");
        title = title.trim().to_owned();
        Some(title)
    }

    pub fn SetTitle(&self, title: &DOMString) -> ErrorResult {
        match self.doctype {
            SVG => {
                fail!("no SVG document yet")
            },
            _ => {
                let (_scope, cx) = self.get_scope_and_cx();
                match self.root {
                    None => {},
                    Some(root) => {
                        for node in root.traverse_preorder() {
                            if node.type_id() != ElementNodeTypeId(HTMLHeadElementTypeId) {
                                loop;
                            }
                            let mut has_title = false;
                            for child in node.children() {
                                if child.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) {
                                    loop;
                                }
                                has_title = true;
                                for title_child in child.children() {
                                    child.remove_child(title_child);
                                }
                                child.add_child(self.CreateTextNode(title));
                                break;
                            }
                            if !has_title {
                                let new_title = @HTMLTitleElement {
                                    htmlelement: HTMLElement::new(HTMLTitleElementTypeId, ~"title")
                                };
                                let new_title = unsafe {
                                    Node::as_abstract_node(cx, new_title)
                                };
                                new_title.add_child(self.CreateTextNode(title));
                                node.add_child(new_title);
                            }
                            break;
                        };
                    }
                }
            }
        }
        Ok(())
    }

    pub fn Dir(&self) -> DOMString {
        None
    }

    pub fn SetDir(&self, _dir: &DOMString) {
    }

    pub fn GetDefaultView(&self) -> Option<@mut WindowProxy> {
        None
    }

    pub fn GetActiveElement(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn HasFocus(&self) -> Fallible<bool> {
        Ok(false)
    }

    pub fn GetCurrentScript(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn ReleaseCapture(&self) {
    }

    pub fn MozFullScreenEnabled(&self) -> bool {
        false
    }

    pub fn GetMozFullScreenElement(&self) -> Fallible<Option<AbstractNode<ScriptView>>> {
        Ok(None)
    }

    pub fn GetMozPointerLockElement(&self) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn MozExitPointerLock(&self) {
    }

    pub fn Hidden(&self) -> bool {
        false
    }

    pub fn MozHidden(&self) -> bool {
        self.Hidden()
    }

    pub fn VisibilityState(&self) -> DocumentBinding::VisibilityState {
        DocumentBinding::VisibilityStateValues::Visible
    }

    pub fn MozVisibilityState(&self) -> DocumentBinding::VisibilityState {
        self.VisibilityState()
    }

    pub fn GetSelectedStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn SetSelectedStyleSheetSet(&self, _sheet: &DOMString) {
    }

    pub fn GetLastStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn GetPreferredStyleSheetSet(&self) -> DOMString {
        None
    }

    pub fn EnableStyleSheetsForSet(&self, _name: &DOMString) {
    }

    pub fn ElementFromPoint(&self, _x: f32, _y: f32) -> Option<AbstractNode<ScriptView>> {
        None
    }

    pub fn QuerySelector(&self, _selectors: &DOMString) -> Fallible<Option<AbstractNode<ScriptView>>> {
        Ok(None)
    }

    pub fn GetElementsByName(&self, name: &DOMString) -> @mut HTMLCollection {
        self.createHTMLCollection(|elem|
            elem.get_attr("name").is_some() && eq_slice(elem.get_attr("name").unwrap(), null_str_as_empty(name)))
    }

    pub fn createHTMLCollection(&self, callback: &fn(elem: &Element) -> bool) -> @mut HTMLCollection {
        let mut elements = ~[];
        match self.root {
            None => {},
            Some(root) => {
                for child in root.traverse_preorder() {
                    if child.is_element() {
                        do child.with_imm_element |elem| {
                            if callback(elem) {
                                elements.push(child);
                            }
                        }
                    }
                };
            }
        }
        let (scope, cx) = self.get_scope_and_cx();
        HTMLCollection::new(elements, cx, scope)
    }

    pub fn content_changed(&self) {
        for window in self.window.iter() {
            window.content_changed()
        }
    }

    pub fn wait_until_safe_to_modify_dom(&self) {
        for window in self.window.iter() {
            window.wait_until_safe_to_modify_dom();
        }
    }
}

impl Traceable for Document {
    #[fixed_stack_segment]
    fn trace(&self, tracer: *mut JSTracer) {
        match self.root {
            None => {},
            Some(root) => {
                unsafe {
                    (*tracer).debugPrinter = ptr::null();
                    (*tracer).debugPrintIndex = -1;
                    do "root".to_c_str().with_ref |name| {
                        (*tracer).debugPrintArg = name as *libc::c_void;
                        debug!("tracing root node");
                        do root.with_base |node| {
                            JS_CallTracer(tracer as *JSTracer,
                                          node.wrapper.wrapper,
                                          JSTRACE_OBJECT as u32);
                        }
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use libc::{c_char, c_int, c_void};
use std::mem;
use std::ptr;

extern {
    fn backtrace(buffer: *mut *mut c_void, size: c_int) -> c_int;
    fn backtrace_symbols(buffer: *mut *const c_void, size: c_int) -> *mut *mut c_char;
    fn backtrace_symbols_fd(buffer: *mut *const c_void, size: c_int, fd: c_int);
}

pub fn stack_height() -> usize {
    let local: u32 = 0;
    let height = &local as *const _ as usize;
    super::main_height() - height
}

pub fn backtrace_return_addresses() -> Vec<*const c_void> {
    let height = stack_height();
    let word_size = mem::size_of::<usize>();
    let rounded_height = (height + (word_size - 1)) / word_size;
    assert!(rounded_height >= 0);
    assert!(rounded_height <= ::std::i32::MAX as usize);
    let mut buffer = vec![ptr::null(); rounded_height];
    let rounded_height = rounded_height as i32;
    unsafe {
        let filled_size = backtrace(buffer.as_mut_ptr() as *mut *mut c_void,
                                    rounded_height);
        assert!(filled_size >= 0);
        buffer.set_len(filled_size as usize);
    }
    buffer
}
<commit_msg>massive additions to the `mod backtrace_hacks`.<commit_after>use libc::{c_char, c_int, c_void};
use std::ffi::CStr;
use std::mem;
use std::ptr;

mod bt {
    use libc::{c_char, c_int, c_void};
    extern {
        pub fn backtrace(buffer: *mut *mut c_void,
                         size: c_int) -> c_int;
        pub fn backtrace_symbols(buffer: *mut *const c_void,
                                 size: c_int) -> *mut *mut c_char;
        pub fn backtrace_symbols_fd(buffer: *mut *const c_void,
                                    size: c_int,
                                    fd: c_int);
    }
}

mod dl {
    use libc::{self, c_char, c_uchar, c_int, c_void};
    #[derive(Debug)]
    #[repr(C)]
    pub struct Dl_info {
        pub dli_fname: *const c_char,
        pub dli_fbase: *mut c_void,
        pub dli_sname: *const c_char,
        pub dli_saddr: *mut c_void,
    }

    extern {
        pub fn dladdr(addr: *mut c_void,
                      info: *mut Dl_info) -> c_int;
        pub fn dladdr1(addr: *mut c_void,
                       info: *mut Dl_info,
                       extra_info: *mut *mut c_void,
                       flags: c_int) -> c_int;
    }

    const RTLD_DL_LINKMAP: i32 = 2;
    const RTLD_DL_SYMENT: i32 = 1;

    pub trait RequestFlags {
        fn flags(&self) -> c_int;
    }

    impl RequestFlags for LinkMap {
        fn flags(&self) -> c_int { RTLD_DL_LINKMAP as c_int }
    }
    impl RequestFlags for SymEnt {
        fn flags(&self) -> c_int { RTLD_DL_SYMENT as c_int }
    }

    #[repr(C)]
    pub struct LinkMap {
        l_addr: libc::size_t,
        l_name: *const char,
        l_ld: ElfDyn,
        l_next: *mut LinkMap,
        l_prev: *mut LinkMap,
    }

    #[repr(C)]
    #[cfg(target_pointer_width = "32")]
    pub struct SymEnt {
        /// Symbol name (starting tbl index)
        st_name: u32,
        /// Symbol value
        st_value: u32,
        /// Symbol size
        st_size: u32,
        /// Symbol type and binding
        st_info: c_uchar,
        /// Symbol visibility
        st_other: c_uchar,
        /// Section index
        st_shndx: u16,
    }

    #[repr(C)]
    #[cfg(target_pointer_width = "64")]
    pub struct SymEnt {
        /// Symbol name (starting tbl index)
        st_name: u64,
        /// Symbol type and binding
        st_info: c_uchar,
        /// Symbol visibility
        st_other: c_uchar,
        /// Section index
        st_shndx: u16,
        /// Symbol value
        st_value: u32,
        /// Symbol size
        st_size: u32,
    }

    #[cfg(target_pointer_width = "32")]
    #[repr(C)]
    pub struct ElfDyn {
        d_tag: i32,
        d_un: u32,
    }

    #[cfg(target_pointer_width = "64")]
    #[repr(C)]
    pub struct ElfDyn {
        d_tag: i64,
        d_un: u64,
    }
}

pub fn stack_height() -> usize {
    let local: u32 = 0;
    let height = &local as *const _ as usize;
    super::main_height() - height
}

#[derive(Copy, Clone, Debug)]
pub struct ReturnAddress(pub *const c_void);

pub fn backtrace_return_addresses() -> Vec<ReturnAddress> {
    let height = stack_height();
    let word_size = mem::size_of::<usize>();
    let rounded_height = (height + (word_size - 1)) / word_size;
    assert!(rounded_height >= 0);
    assert!(rounded_height <= ::std::i32::MAX as usize);
    let mut buffer: Vec<*const c_void> = vec![ptr::null(); rounded_height];
    let rounded_height = rounded_height as i32;
    unsafe {
        let filled_size = bt::backtrace(mem::transmute(buffer.as_mut_ptr()),
                                        rounded_height);
        assert!(filled_size >= 0);
        buffer.set_len(filled_size as usize);
        mem::transmute(buffer)
    }
}

pub fn backtrace_symbols(addresses: &Vec<ReturnAddress>) -> Vec<&'static CStr> {
    let mut symbols = Vec::with_capacity(addresses.len());

    unsafe {
        let strings = bt::backtrace_symbols(mem::transmute(addresses.as_ptr()),
                                            addresses.len() as i32);
        for i in 0..addresses.len() {
            let c_str = unsafe { CStr::from_ptr(*strings.offset(i as isize)) };
            symbols.push(c_str);
        }
    }

    symbols
}

#[derive(Debug)]
pub struct DlInfo {
    fname: String,
    fbase: *mut c_void,
    sname: String,
    saddr: *mut c_void,
}

/// If `addr` is an address is located in a currently-loaded shared
/// object, returns the base address at which that shared object is
/// located. Otherwise returns `None`.
pub fn dlinfo_fbase(addr: *const c_void) -> Option<*const c_void> {
    unsafe {
        let mut info: dl::Dl_info = mem::uninitialized();
        let result = dl::dladdr(addr as *mut _, &mut info as *mut _);
        if 0 != result {
            Some(info.dli_fbase)
        } else {
            None
        }
    }
}

impl DlInfo {
    fn from_dl<'a>(info: &'a dl::Dl_info) -> DlInfo {
        fn to_string(p: *const c_char) -> String {
            if p.is_null() {
                String::new()
            } else {
                unsafe { CStr::from_ptr(p) }.to_str().unwrap().to_string()
            }
        }
        let fname = to_string(info.dli_fname);
        let fbase = info.dli_fbase;
        let sname = to_string(info.dli_sname);
        let saddr = info.dli_saddr;
        DlInfo {
            fname: fname, fbase: fbase, sname: sname, saddr: saddr
        }
    }
}

#[derive(Debug)]
pub struct DlInfoUnmatched(*const c_void);

pub type DlInfoResult = Result<Vec<DlInfo>, (Vec<DlInfo>, Vec<DlInfoUnmatched>)>;

pub fn backtrace_dlinfos(addresses: &[ReturnAddress]) -> DlInfoResult {
    let (ok, err): (Vec<_>, Vec<_>) = addresses.iter()
        .map(|&ReturnAddress(addr)| {
            let mut info: dl::Dl_info = unsafe { mem::uninitialized() };
            let result = unsafe { dl::dladdr(addr as *mut _, &mut info as *mut _) };
            if 0 != result {
                Ok(DlInfo::from_dl(&info))
            } else {
                Err(DlInfoUnmatched(addr))
            }})
        .partition(|x|x.is_ok());

    let okay: Vec<DlInfo> = ok.into_iter().map(|r| r.unwrap()).collect();
    let errs: Vec<DlInfoUnmatched> = err.into_iter().map(|r| r.unwrap_err()).collect();
    if errs.len() == 0 {
        Ok(okay)
    } else {
        Err((okay, errs))
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
extern crate curl;
extern crate http;
extern crate hyper;

extern crate test;

use std::fmt::{mod, Show};
use std::io::net::ip::Ipv4Addr;
use hyper::server::{Incoming, Server};
use hyper::net::HttpAcceptor;

fn listen() -> hyper::server::Listening<HttpAcceptor> {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 0);
    server.listen(handle).unwrap()
}

macro_rules! try_continue(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(..) => continue
        }
    }})

fn handle(mut incoming: Incoming) {
    for (_, res) in incoming {
        let mut res = try_continue!(res.start());
        try_continue!(res.write(b"Benchmarking hyper vs others!"))
        try_continue!(res.end());
    }
}

#[bench]
fn bench_curl(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        curl::http::handle()
            .get(url)
            .header("X-Foo", "Bar")
            .exec()
            .unwrap()
    });
    listening.close().unwrap()
}

struct Foo;

impl hyper::header::Header for Foo {
    fn header_name(_: Option<Foo>) -> &'static str {
        "x-foo"
    }
    fn parse_header(_: &[Vec<u8>]) -> Option<Foo> {
        None
    }
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        "Bar".fmt(fmt)
    }
}

#[bench]
fn bench_hyper(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req = hyper::get(hyper::Url::parse(url).unwrap()).unwrap();
        req.headers.set(Foo);

        req
            .send().unwrap()
            .read_to_string().unwrap()
    });
    listening.close().unwrap()
}

#[bench]
fn bench_http(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req: http::client::RequestWriter = http::client::RequestWriter::new(
            http::method::Get,
            hyper::Url::parse(url).unwrap()
        ).unwrap();
        req.headers.extensions.insert("x-foo".to_string(), "Bar".to_string());
        // cant unwrap because Err contains RequestWriter, which does not implement Show
        let mut res = match req.read_response() {
            Ok(res) => res,
            Err(..) => fail!("http response failed")
        };
        res.read_to_string().unwrap();
    });
    listening.close().unwrap()
}
<commit_msg>Update client benchmarks for new Listening representation.<commit_after>#![feature(macro_rules)]
extern crate curl;
extern crate http;
extern crate hyper;

extern crate test;

use std::fmt::{mod, Show};
use std::io::net::ip::Ipv4Addr;
use hyper::server::{Incoming, Server};
use hyper::net::HttpAcceptor;

fn listen() -> hyper::server::Listening<HttpAcceptor> {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 0);
    server.listen(handle).unwrap()
}

macro_rules! try_continue(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(..) => continue
        }
    }})

fn handle(mut incoming: Incoming) {
    for (_, res) in incoming {
        let mut res = try_continue!(res.start());
        try_continue!(res.write(b"Benchmarking hyper vs others!"))
        try_continue!(res.end());
    }
}

#[bench]
fn bench_curl(b: &mut test::Bencher) {
    let mut listening = listen();
    let s = format!("http://{}/", listening.sockets[0]);
    let url = s.as_slice();
    b.iter(|| {
        curl::http::handle()
            .get(url)
            .header("X-Foo", "Bar")
            .exec()
            .unwrap()
    });
    listening.close().unwrap()
}

struct Foo;

impl hyper::header::Header for Foo {
    fn header_name(_: Option<Foo>) -> &'static str {
        "x-foo"
    }
    fn parse_header(_: &[Vec<u8>]) -> Option<Foo> {
        None
    }
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        "Bar".fmt(fmt)
    }
}

#[bench]
fn bench_hyper(b: &mut test::Bencher) {
    let mut listening = listen();
    let s = format!("http://{}/", listening.sockets[0]);
    let url = s.as_slice();
    b.iter(|| {
        let mut req = hyper::get(hyper::Url::parse(url).unwrap()).unwrap();
        req.headers.set(Foo);

        req
            .send().unwrap()
            .read_to_string().unwrap()
    });
    listening.close().unwrap()
}

#[bench]
fn bench_http(b: &mut test::Bencher) {
    let mut listening = listen();
    let s = format!("http://{}/", listening.sockets[0]);
    let url = s.as_slice();
    b.iter(|| {
        let mut req: http::client::RequestWriter = http::client::RequestWriter::new(
            http::method::Get,
            hyper::Url::parse(url).unwrap()
        ).unwrap();
        req.headers.extensions.insert("x-foo".to_string(), "Bar".to_string());
        // cant unwrap because Err contains RequestWriter, which does not implement Show
        let mut res = match req.read_response() {
            Ok(res) => res,
            Err(..) => fail!("http response failed")
        };
        res.read_to_string().unwrap();
    });
    listening.close().unwrap()
}
<|endoftext|>


<commit_before>use std::mem;

use bytes::Buf;
use criterion::{Benchmark, Criterion, Throughput};
use prost::encoding::{decode_varint, encode_varint, encoded_len_varint};
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};

fn benchmark_varint(criterion: &mut Criterion, name: &str, mut values: Vec<u64>) {
    // Shuffle the values in a stable order.
    values.shuffle(&mut StdRng::seed_from_u64(0));

    let encoded_len = values
        .iter()
        .cloned()
        .map(encoded_len_varint)
        .sum::<usize>() as u64;
    let decoded_len = (values.len() * mem::size_of::<u64>()) as u64;

    let encode_values = values.clone();
    let encode = Benchmark::new("encode", move |b| {
        let mut buf = Vec::<u8>::with_capacity(encode_values.len() * 10);
        b.iter(|| {
            buf.clear();
            for &value in &encode_values {
                encode_varint(value, &mut buf);
            }
            criterion::black_box(&buf);
        })
    })
    .throughput(Throughput::Bytes(encoded_len));

    let decode_values = values.clone();
    let decode = Benchmark::new("decode", move |b| {
        let mut buf = Vec::with_capacity(decode_values.len() * 10);
        for &value in &decode_values {
            encode_varint(value, &mut buf);
        }

        b.iter(|| {
            let mut buf = &mut buf.as_slice();
            while buf.has_remaining() {
                let result = decode_varint(&mut buf);
                debug_assert!(result.is_ok());
                criterion::black_box(&result);
            }
        })
    })
    .throughput(Throughput::Bytes(decoded_len));

    let encoded_len = Benchmark::new("encoded_len", move |b| {
        b.iter(|| {
            let mut sum = 0;
            for &value in &values {
                sum += encoded_len_varint(value);
            }
            criterion::black_box(sum);
        })
    })
    .throughput(Throughput::Bytes(decoded_len));

    let name = format!("varint/{}", name);
    criterion
        .bench(&name, encode)
        .bench(&name, decode)
        .bench(&name, encoded_len);
}

fn main() {
    let mut criterion = Criterion::default().configure_from_args();

    // Benchmark encoding and decoding 100 small (1 byte) varints.
    benchmark_varint(&mut criterion, "small", (0..100).collect());

    // Benchmark encoding and decoding 100 medium (5 byte) varints.
    benchmark_varint(&mut criterion, "medium", (1 << 28..).take(100).collect());

    // Benchmark encoding and decoding 100 large (10 byte) varints.
    benchmark_varint(&mut criterion, "large", (1 << 63..).take(100).collect());

    // Benchmark encoding and decoding 100 varints of mixed width (average 5.5 bytes).
    benchmark_varint(
        &mut criterion,
        "mixed",
        (0..10)
            .flat_map(move |width| {
                let exponent = width * 7;
                (0..10).map(move |offset| offset + (1 << exponent))
            })
            .collect(),
    );

    criterion.final_summary();
}
<commit_msg>Update from deprecated criterion::Benchmark to BenchmarkGroup (#444)<commit_after>use std::mem;

use bytes::Buf;
use criterion::{Criterion, Throughput};
use prost::encoding::{decode_varint, encode_varint, encoded_len_varint};
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};

fn benchmark_varint(criterion: &mut Criterion, name: &str, mut values: Vec<u64>) {
    // Shuffle the values in a stable order.
    values.shuffle(&mut StdRng::seed_from_u64(0));
    let name = format!("varint/{}", name);

    let encoded_len = values
        .iter()
        .cloned()
        .map(encoded_len_varint)
        .sum::<usize>() as u64;
    let decoded_len = (values.len() * mem::size_of::<u64>()) as u64;

    criterion
        .benchmark_group(&name)
        .bench_function("encode", {
            let encode_values = values.clone();
            move |b| {
                let mut buf = Vec::<u8>::with_capacity(encode_values.len() * 10);
                b.iter(|| {
                    buf.clear();
                    for &value in &encode_values {
                        encode_varint(value, &mut buf);
                    }
                    criterion::black_box(&buf);
                })
            }
        })
        .throughput(Throughput::Bytes(encoded_len));

    criterion
        .benchmark_group(&name)
        .bench_function("decode", {
            let decode_values = values.clone();

            move |b| {
                let mut buf = Vec::with_capacity(decode_values.len() * 10);
                for &value in &decode_values {
                    encode_varint(value, &mut buf);
                }

                b.iter(|| {
                    let mut buf = &mut buf.as_slice();
                    while buf.has_remaining() {
                        let result = decode_varint(&mut buf);
                        debug_assert!(result.is_ok());
                        criterion::black_box(&result);
                    }
                })
            }
        })
        .throughput(Throughput::Bytes(decoded_len));

    criterion
        .benchmark_group(&name)
        .bench_function("encoded_len", move |b| {
            b.iter(|| {
                let mut sum = 0;
                for &value in &values {
                    sum += encoded_len_varint(value);
                }
                criterion::black_box(sum);
            })
        })
        .throughput(Throughput::Bytes(decoded_len));
}

fn main() {
    let mut criterion = Criterion::default().configure_from_args();

    // Benchmark encoding and decoding 100 small (1 byte) varints.
    benchmark_varint(&mut criterion, "small", (0..100).collect());

    // Benchmark encoding and decoding 100 medium (5 byte) varints.
    benchmark_varint(&mut criterion, "medium", (1 << 28..).take(100).collect());

    // Benchmark encoding and decoding 100 large (10 byte) varints.
    benchmark_varint(&mut criterion, "large", (1 << 63..).take(100).collect());

    // Benchmark encoding and decoding 100 varints of mixed width (average 5.5 bytes).
    benchmark_varint(
        &mut criterion,
        "mixed",
        (0..10)
            .flat_map(move |width| {
                let exponent = width * 7;
                (0..10).map(move |offset| offset + (1 << exponent))
            })
            .collect(),
    );

    criterion.final_summary();
}
<|endoftext|>


<commit_before>//! Context management
//! https://en.wikipedia.org/wiki/Context_switch
//! https://wiki.osdev.org/Context_Switching
use alloc::boxed::Box;
use core::alloc::{Alloc, GlobalAlloc, Layout};
use core::sync::atomic::Ordering;
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};

pub use self::context::{Context, ContextId, Status, WaitpidKey};
pub use self::list::ContextList;
pub use self::switch::switch;

#[path = "arch/x86_64.rs"]
mod arch;

/// Context struct
mod context;

/// Context list
mod list;

/// Context switch function
mod switch;

/// File struct - defines a scheme and a file number
pub mod file;

/// Memory struct - contains a set of pages for a context
pub mod memory;

/// Signal handling
pub mod signal;

/// Timeout handling
pub mod timeout;

/// Limit on number of contexts
pub const CONTEXT_MAX_CONTEXTS: usize = (isize::max_value() as usize) - 1;

/// Maximum context files
pub const CONTEXT_MAX_FILES: usize = 65_536;

/// Contexts list
static CONTEXTS: Once<RwLock<ContextList>> = Once::new();

#[thread_local]
static CONTEXT_ID: context::AtomicContextId = context::AtomicContextId::default();

pub fn init() {
    let mut contexts = contexts_mut();
    let context_lock = contexts.new_context().expect("could not initialize first context");
    let mut context = context_lock.write();
    let mut fx = unsafe { Box::from_raw(::ALLOCATOR.alloc(Layout::from_size_align_unchecked(512, 16)) as *mut [u8; 512]) };
    for b in fx.iter_mut() {
        *b = 0;
    }

    context.arch.set_fx(fx.as_ptr() as usize);
    context.kfx = Some(fx);
    context.status = Status::Runnable;
    context.running = true;
    context.cpu_id = Some(::cpu_id());
    CONTEXT_ID.store(context.id, Ordering::SeqCst);
}

/// Initialize contexts, called if needed
fn init_contexts() -> RwLock<ContextList> {
    RwLock::new(ContextList::new())
}

/// Get the global schemes list, const
pub fn contexts() -> RwLockReadGuard<'static, ContextList> {
    //call once will init_contexts only once during the kernel's exececution, otherwise it will return the current context via a
    //cache.
    CONTEXTS.call_once(init_contexts).read()
}

/// Get the global schemes list, mutable
pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> {
    CONTEXTS.call_once(init_contexts).write()
}

pub fn context_id() -> ContextId {
    CONTEXT_ID.load(Ordering::SeqCst)
}
<commit_msg>fix small documentation bug<commit_after>//! # Context management
//!
//! For resources on contexts, please consult [wikipedia](https://en.wikipedia.org/wiki/Context_switch) and  [osdev](https://wiki.osdev.org/Context_Switching)
use alloc::boxed::Box;
use core::alloc::{Alloc, GlobalAlloc, Layout};
use core::sync::atomic::Ordering;
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};

pub use self::context::{Context, ContextId, Status, WaitpidKey};
pub use self::list::ContextList;
pub use self::switch::switch;

#[path = "arch/x86_64.rs"]
mod arch;

/// Context struct
mod context;

/// Context list
mod list;

/// Context switch function
mod switch;

/// File struct - defines a scheme and a file number
pub mod file;

/// Memory struct - contains a set of pages for a context
pub mod memory;

/// Signal handling
pub mod signal;

/// Timeout handling
pub mod timeout;

/// Limit on number of contexts
pub const CONTEXT_MAX_CONTEXTS: usize = (isize::max_value() as usize) - 1;

/// Maximum context files
pub const CONTEXT_MAX_FILES: usize = 65_536;

/// Contexts list
static CONTEXTS: Once<RwLock<ContextList>> = Once::new();

#[thread_local]
static CONTEXT_ID: context::AtomicContextId = context::AtomicContextId::default();

pub fn init() {
    let mut contexts = contexts_mut();
    let context_lock = contexts.new_context().expect("could not initialize first context");
    let mut context = context_lock.write();
    let mut fx = unsafe { Box::from_raw(::ALLOCATOR.alloc(Layout::from_size_align_unchecked(512, 16)) as *mut [u8; 512]) };
    for b in fx.iter_mut() {
        *b = 0;
    }

    context.arch.set_fx(fx.as_ptr() as usize);
    context.kfx = Some(fx);
    context.status = Status::Runnable;
    context.running = true;
    context.cpu_id = Some(::cpu_id());
    CONTEXT_ID.store(context.id, Ordering::SeqCst);
}

/// Initialize contexts, called if needed
fn init_contexts() -> RwLock<ContextList> {
    RwLock::new(ContextList::new())
}

/// Get the global schemes list, const
pub fn contexts() -> RwLockReadGuard<'static, ContextList> {
    //call once will init_contexts only once during the kernel's exececution, otherwise it will return the current context via a
    //cache.
    CONTEXTS.call_once(init_contexts).read()
}

/// Get the global schemes list, mutable
pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> {
    CONTEXTS.call_once(init_contexts).write()
}

pub fn context_id() -> ContextId {
    CONTEXT_ID.load(Ordering::SeqCst)
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Create_a_file

extern crate libc;

#[cfg(not(test))]
use std::io::{File, fs};
#[cfg(not(test))]
use libc::S_IRWXU;

#[cfg(not(test))]
fn main () {
    // Create a new file.
    // We get a Result object from File::create. We could check if there is an error
    // by using .is_error() or by using pattern matching. We choose here to ignore
    // the possibility of an error and just unwrap the value contained in the Result object.
    // This means that an error will cause the program to fail at runtime.
    let mut new_file = File::create(&Path::new("output.txt")).unwrap();

    // Write something trivial to the file.
    // Now we are handling a possible error by using pattern matching
    match writeln!(&mut new_file as &mut Writer, "Nothing here...") {
        Ok(()) => (),
        Err(e) => println!("Failed to write to file: {}", e),
    }

    // Create a directory
    // Here we handle a possible error by using the functions provided by result
    // The second argument is an unsigned int that sets the file permissions
    let result = fs::mkdir(&Path::new("docs"), S_IRWXU as u32);
    if result.is_err() {
        println!("Failed to create a directory: {}", result.err().unwrap());
    }
}
<commit_msg>Update create_file to use std::io::FilePermission<commit_after>// Implements http://rosettacode.org/wiki/Create_a_file

extern crate libc;

#[cfg(not(test))]
use std::io::{File, UserRead, UserWrite, UserExecute, fs};

#[cfg(not(test))]
fn main () {
    // Create a new file.
    // We get a Result object from File::create. We could check if there is an error
    // by using .is_error() or by using pattern matching. We choose here to ignore
    // the possibility of an error and just unwrap the value contained in the Result object.
    // This means that an error will cause the program to fail at runtime.
    let mut new_file = File::create(&Path::new("output.txt")).unwrap();

    // Write something trivial to the file.
    // Now we are handling a possible error by using pattern matching
    match writeln!(&mut new_file as &mut Writer, "Nothing here...") {
        Ok(()) => (),
        Err(e) => println!("Failed to write to file: {}", e),
    }

    // Create a directory
    // Here we handle a possible error by using the functions provided by result
    // The second argument sets the file permissions
    let result = fs::mkdir(&Path::new("docs"), UserRead|UserWrite|UserExecute);
    if result.is_err() {
        println!("Failed to create a directory: {}", result.err().unwrap());
    }
}
<|endoftext|>


<commit_before>use crate::common::Config;
use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;

use log::*;

#[cfg(test)]
mod tests;

/// Conversion table from triple OS name to Rust SYSNAME
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
    ("android", "android"),
    ("androideabi", "android"),
    ("cloudabi", "cloudabi"),
    ("cuda", "cuda"),
    ("darwin", "macos"),
    ("dragonfly", "dragonfly"),
    ("emscripten", "emscripten"),
    ("freebsd", "freebsd"),
    ("fuchsia", "fuchsia"),
    ("haiku", "haiku"),
    ("hermit", "hermit"),
    ("ios", "ios"),
    ("l4re", "l4re"),
    ("linux", "linux"),
    ("mingw32", "windows"),
    ("none", "none"),
    ("netbsd", "netbsd"),
    ("openbsd", "openbsd"),
    ("redox", "redox"),
    ("sgx", "sgx"),
    ("solaris", "solaris"),
    ("win32", "windows"),
    ("windows", "windows"),
    ("vxworks", "vxworks"),
];

const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
    ("aarch64", "aarch64"),
    ("amd64", "x86_64"),
    ("arm", "arm"),
    ("arm64", "aarch64"),
    ("armv4t", "arm"),
    ("armv5te", "arm"),
    ("armv7", "arm"),
    ("armv7s", "arm"),
    ("asmjs", "asmjs"),
    ("hexagon", "hexagon"),
    ("i386", "x86"),
    ("i586", "x86"),
    ("i686", "x86"),
    ("mips", "mips"),
    ("mips64", "mips64"),
    ("mips64el", "mips64"),
    ("mipsisa32r6", "mips"),
    ("mipsisa32r6el", "mips"),
    ("mipsisa64r6", "mips64"),
    ("mipsisa64r6el", "mips64"),
    ("mipsel", "mips"),
    ("mipsisa32r6", "mips"),
    ("mipsisa32r6el", "mips"),
    ("mipsisa64r6", "mips64"),
    ("mipsisa64r6el", "mips64"),
    ("msp430", "msp430"),
    ("nvptx64", "nvptx64"),
    ("powerpc", "powerpc"),
    ("powerpc64", "powerpc64"),
    ("powerpc64le", "powerpc64"),
    ("s390x", "s390x"),
    ("sparc", "sparc"),
    ("sparc64", "sparc64"),
    ("sparcv9", "sparc64"),
    ("thumbv6m", "thumb"),
    ("thumbv7em", "thumb"),
    ("thumbv7m", "thumb"),
    ("wasm32", "wasm32"),
    ("x86_64", "x86_64"),
    ("xcore", "xcore"),
];

pub fn matches_os(triple: &str, name: &str) -> bool {
    // For the wasm32 bare target we ignore anything also ignored on emscripten
    // and then we also recognize `wasm32-bare` as the os for the target
    if triple == "wasm32-unknown-unknown" {
        return name == "emscripten" || name == "wasm32-bare";
    }
    let triple: Vec<_> = triple.split('-').collect();
    for &(triple_os, os) in OS_TABLE {
        if triple.contains(&triple_os) {
            return os == name;
        }
    }
    panic!("Cannot determine OS from triple");
}

/// Determine the architecture from `triple`
pub fn get_arch(triple: &str) -> &'static str {
    let triple: Vec<_> = triple.split('-').collect();
    for &(triple_arch, arch) in ARCH_TABLE {
        if triple.contains(&triple_arch) {
            return arch;
        }
    }
    panic!("Cannot determine Architecture from triple");
}

pub fn matches_env(triple: &str, name: &str) -> bool {
    if let Some(env) = triple.split('-').nth(3) { env.starts_with(name) } else { false }
}

pub fn get_pointer_width(triple: &str) -> &'static str {
    if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") {
        "64bit"
    } else {
        "32bit"
    }
}

pub fn make_new_path(path: &str) -> String {
    assert!(cfg!(windows));
    // Windows just uses PATH as the library search path, so we have to
    // maintain the current value while adding our own
    match env::var(lib_path_env_var()) {
        Ok(curr) => format!("{}{}{}", path, path_div(), curr),
        Err(..) => path.to_owned(),
    }
}

pub fn lib_path_env_var() -> &'static str {
    "PATH"
}
fn path_div() -> &'static str {
    ";"
}

pub fn logv(config: &Config, s: String) {
    debug!("{}", s);
    if config.verbose {
        println!("{}", s);
    }
}

pub trait PathBufExt {
    /// Append an extension to the path, even if it already has one.
    fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf;
}

impl PathBufExt for PathBuf {
    fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
        if extension.as_ref().len() == 0 {
            self.clone()
        } else {
            let mut fname = self.file_name().unwrap().to_os_string();
            if !extension.as_ref().to_str().unwrap().starts_with(".") {
                fname.push(".");
            }
            fname.push(extension);
            self.with_file_name(fname)
        }
    }
}
<commit_msg>Rollup merge of #68006 - infinity0:master, r=nikomatsakis<commit_after>use crate::common::Config;
use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;

use log::*;

#[cfg(test)]
mod tests;

/// Conversion table from triple OS name to Rust SYSNAME
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
    ("android", "android"),
    ("androideabi", "android"),
    ("cloudabi", "cloudabi"),
    ("cuda", "cuda"),
    ("darwin", "macos"),
    ("dragonfly", "dragonfly"),
    ("emscripten", "emscripten"),
    ("freebsd", "freebsd"),
    ("fuchsia", "fuchsia"),
    ("haiku", "haiku"),
    ("hermit", "hermit"),
    ("ios", "ios"),
    ("l4re", "l4re"),
    ("linux", "linux"),
    ("mingw32", "windows"),
    ("none", "none"),
    ("netbsd", "netbsd"),
    ("openbsd", "openbsd"),
    ("redox", "redox"),
    ("sgx", "sgx"),
    ("solaris", "solaris"),
    ("win32", "windows"),
    ("windows", "windows"),
    ("vxworks", "vxworks"),
];

const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
    ("aarch64", "aarch64"),
    ("amd64", "x86_64"),
    ("arm", "arm"),
    ("arm64", "aarch64"),
    ("armv4t", "arm"),
    ("armv5te", "arm"),
    ("armv7", "arm"),
    ("armv7s", "arm"),
    ("asmjs", "asmjs"),
    ("hexagon", "hexagon"),
    ("i386", "x86"),
    ("i586", "x86"),
    ("i686", "x86"),
    ("mips", "mips"),
    ("mips64", "mips64"),
    ("mips64el", "mips64"),
    ("mipsisa32r6", "mips"),
    ("mipsisa32r6el", "mips"),
    ("mipsisa64r6", "mips64"),
    ("mipsisa64r6el", "mips64"),
    ("mipsel", "mips"),
    ("mipsisa32r6", "mips"),
    ("mipsisa32r6el", "mips"),
    ("mipsisa64r6", "mips64"),
    ("mipsisa64r6el", "mips64"),
    ("msp430", "msp430"),
    ("nvptx64", "nvptx64"),
    ("powerpc", "powerpc"),
    ("powerpc64", "powerpc64"),
    ("powerpc64le", "powerpc64"),
    ("riscv64gc", "riscv64"),
    ("s390x", "s390x"),
    ("sparc", "sparc"),
    ("sparc64", "sparc64"),
    ("sparcv9", "sparc64"),
    ("thumbv6m", "thumb"),
    ("thumbv7em", "thumb"),
    ("thumbv7m", "thumb"),
    ("wasm32", "wasm32"),
    ("x86_64", "x86_64"),
    ("xcore", "xcore"),
];

pub fn matches_os(triple: &str, name: &str) -> bool {
    // For the wasm32 bare target we ignore anything also ignored on emscripten
    // and then we also recognize `wasm32-bare` as the os for the target
    if triple == "wasm32-unknown-unknown" {
        return name == "emscripten" || name == "wasm32-bare";
    }
    let triple: Vec<_> = triple.split('-').collect();
    for &(triple_os, os) in OS_TABLE {
        if triple.contains(&triple_os) {
            return os == name;
        }
    }
    panic!("Cannot determine OS from triple");
}

/// Determine the architecture from `triple`
pub fn get_arch(triple: &str) -> &'static str {
    let triple: Vec<_> = triple.split('-').collect();
    for &(triple_arch, arch) in ARCH_TABLE {
        if triple.contains(&triple_arch) {
            return arch;
        }
    }
    panic!("Cannot determine Architecture from triple");
}

pub fn matches_env(triple: &str, name: &str) -> bool {
    if let Some(env) = triple.split('-').nth(3) { env.starts_with(name) } else { false }
}

pub fn get_pointer_width(triple: &str) -> &'static str {
    if (triple.contains("64") && !triple.ends_with("gnux32")) || triple.starts_with("s390x") {
        "64bit"
    } else {
        "32bit"
    }
}

pub fn make_new_path(path: &str) -> String {
    assert!(cfg!(windows));
    // Windows just uses PATH as the library search path, so we have to
    // maintain the current value while adding our own
    match env::var(lib_path_env_var()) {
        Ok(curr) => format!("{}{}{}", path, path_div(), curr),
        Err(..) => path.to_owned(),
    }
}

pub fn lib_path_env_var() -> &'static str {
    "PATH"
}
fn path_div() -> &'static str {
    ";"
}

pub fn logv(config: &Config, s: String) {
    debug!("{}", s);
    if config.verbose {
        println!("{}", s);
    }
}

pub trait PathBufExt {
    /// Append an extension to the path, even if it already has one.
    fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf;
}

impl PathBufExt for PathBuf {
    fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
        if extension.as_ref().len() == 0 {
            self.clone()
        } else {
            let mut fname = self.file_name().unwrap().to_os_string();
            if !extension.as_ref().to_str().unwrap().starts_with(".") {
                fname.push(".");
            }
            fname.push(extension);
            self.with_file_name(fname)
        }
    }
}
<|endoftext|>