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

//! Utilities related to FFI bindings.
//!
//! This module provides utilities to handle data across non-Rust
//! interfaces, like other programming languages and the underlying
//! operating system. It is mainly of use for FFI (Foreign Function
//! Interface) bindings and code that needs to exchange C-like strings
//! with other languages.
//!
//! # Overview
//!
//! Rust represents owned strings with the [`String`] type, and
//! borrowed slices of strings with the [`str`] primitive. Both are
//! always in UTF-8 encoding, and may contain nul bytes in the middle,
//! i.e. if you look at the bytes that make up the string, there may
//! be a `\0` among them. Both `String` and `str` store their length
//! explicitly; there are no nul terminators at the end of strings
//! like in C.
//!
//! C strings are different from Rust strings:
//!
//! * **Encodings** - Rust strings are UTF-8, but C strings may use
//! other encodings. If you are using a string from C, you should
//! check its encoding explicitly, rather than just assuming that it
//! is UTF-8 like you can do in Rust.
//!
//! * **Character size** - C strings may use `char` or `wchar_t`-sized
//! characters; please **note** that C's `char` is different from Rust's.
//! The C standard leaves the actual sizes of those types open to
//! interpretation, but defines different APIs for strings made up of
//! each character type. Rust strings are always UTF-8, so different
//! Unicode characters will be encoded in a variable number of bytes
//! each. The Rust type [`char`] represents a '[Unicode scalar
//! value]', which is similar to, but not the same as, a '[Unicode
//! code point]'.
//!
//! * **Nul terminators and implicit string lengths** - Often, C
//! strings are nul-terminated, i.e. they have a `\0` character at the
//! end. The length of a string buffer is not stored, but has to be
//! calculated; to compute the length of a string, C code must
//! manually call a function like `strlen()` for `char`-based strings,
//! or `wcslen()` for `wchar_t`-based ones. Those functions return
//! the number of characters in the string excluding the nul
//! terminator, so the buffer length is really `len+1` characters.
//! Rust strings don't have a nul terminator; their length is always
//! stored and does not need to be calculated. While in Rust
//! accessing a string's length is a O(1) operation (because the
//! length is stored); in C it is an O(length) operation because the
//! length needs to be computed by scanning the string for the nul
//! terminator.
//!
//! * **Internal nul characters** - When C strings have a nul
//! terminator character, this usually means that they cannot have nul
//! characters in the middle — a nul character would essentially
//! truncate the string. Rust strings *can* have nul characters in
//! the middle, because nul does not have to mark the end of the
//! string in Rust.
//!
//! # Representations of non-Rust strings
//!
//! [`CString`] and [`CStr`] are useful when you need to transfer
//! UTF-8 strings to and from languages with a C ABI, like Python.
//!
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
//! string: it is nul-terminated, and has no internal nul characters.
//! Rust code can create a `CString` out of a normal string (provided
//! that the string doesn't have nul characters in the middle), and
//! then use a variety of methods to obtain a raw `*mut u8` that can
//! then be passed as an argument to functions which use the C
//! conventions for strings.
//!
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
//! is what you would use to wrap a raw `*const u8` that you got from
//! a C function. A `CStr` is guaranteed to be a nul-terminated array
//! of bytes. Once you have a `CStr`, you can convert it to a Rust
//! `&str` if it's valid UTF-8, or lossily convert it by adding
//! replacement characters.
//!
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
//! strings to and from the operating system itself, or when capturing
//! the output of external commands. Conversions between `OsString`,
//! `OsStr` and Rust strings work similarly to those for [`CString`]
//! and [`CStr`].
//!
//! * [`OsString`] represents an owned string in whatever
//! representation the operating system prefers. In the Rust standard
//! library, various APIs that transfer strings to/from the operating
//! system use `OsString` instead of plain strings. For example,
//! [`env::var_os()`] is used to query environment variables; it
//! returns an `Option<OsString>`. If the environment variable exists
//! you will get a `Some(os_string)`, which you can *then* try to
//! convert to a Rust string. This yields a [`Result<>`], so that
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
//! * [`OsStr`] represents a borrowed reference to a string in a
//! format that can be passed to the operating system. It can be
//! converted into an UTF-8 Rust string slice in a similar way to
//! `OsString`.
//!
//! # Conversions
//!
//! ## On Unix
//!
//! On Unix, [`OsStr`] implements the
//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
//! These do inexpensive conversions from and to UTF-8 byte slices.
//!
//! Additionally, on Unix [`OsString`] implements the
//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! which provides [`from_vec`] and [`into_vec`] methods that consume
//! their arguments, and take or produce vectors of [`u8`].
//!
//! ## On Windows
//!
//! On Windows, [`OsStr`] implements the
//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
//! which provides an [`encode_wide`] method. This provides an
//! iterator that can be [`collect`]ed into a vector of [`u16`].
//!
//! Additionally, on Windows [`OsString`] implements the
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
//! trait, which provides a [`from_wide`] method. The result of this
//! method is an `OsString` which can be round-tripped to a Windows
//! string losslessly.
//!
//! [`String`]: ../string/struct.String.html
//! [`str`]: ../primitive.str.html
//! [`char`]: ../primitive.char.html
//! [`u8`]: ../primitive.u8.html
//! [`u16`]: ../primitive.u16.html
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
//! [`CString`]: struct.CString.html
//! [`CStr`]: struct.CStr.html
//! [`OsString`]: struct.OsString.html
//! [`OsStr`]: struct.OsStr.html
//! [`env::set_var()`]: ../env/fn.set_var.html
//! [`env::var_os()`]: ../env/fn.var_os.html
//! [`Result<>`]: ../result/enum.Result.html
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide

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

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub use self::c_str::{FromBytesWithNulError};

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsString, OsStr};

#[stable(feature = "raw_os", since = "1.1.0")]
pub use core::ffi::c_void;

#[cfg(not(stage0))]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
pub use core::ffi::VaList;

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

//! Utilities related to FFI bindings.
//!
//! This module provides utilities to handle data across non-Rust
//! interfaces, like other programming languages and the underlying
//! operating system. It is mainly of use for FFI (Foreign Function
//! Interface) bindings and code that needs to exchange C-like strings
//! with other languages.
//!
//! # Overview
//!
//! Rust represents owned strings with the [`String`] type, and
//! borrowed slices of strings with the [`str`] primitive. Both are
//! always in UTF-8 encoding, and may contain nul bytes in the middle,
//! i.e. if you look at the bytes that make up the string, there may
//! be a `\0` among them. Both `String` and `str` store their length
//! explicitly; there are no nul terminators at the end of strings
//! like in C.
//!
//! C strings are different from Rust strings:
//!
//! * **Encodings** - Rust strings are UTF-8, but C strings may use
//! other encodings. If you are using a string from C, you should
//! check its encoding explicitly, rather than just assuming that it
//! is UTF-8 like you can do in Rust.
//!
//! * **Character size** - C strings may use `char` or `wchar_t`-sized
//! characters; please **note** that C's `char` is different from Rust's.
//! The C standard leaves the actual sizes of those types open to
//! interpretation, but defines different APIs for strings made up of
//! each character type. Rust strings are always UTF-8, so different
//! Unicode characters will be encoded in a variable number of bytes
//! each. The Rust type [`char`] represents a '[Unicode scalar
//! value]', which is similar to, but not the same as, a '[Unicode
//! code point]'.
//!
//! * **Nul terminators and implicit string lengths** - Often, C
//! strings are nul-terminated, i.e. they have a `\0` character at the
//! end. The length of a string buffer is not stored, but has to be
//! calculated; to compute the length of a string, C code must
//! manually call a function like `strlen()` for `char`-based strings,
//! or `wcslen()` for `wchar_t`-based ones. Those functions return
//! the number of characters in the string excluding the nul
//! terminator, so the buffer length is really `len+1` characters.
//! Rust strings don't have a nul terminator; their length is always
//! stored and does not need to be calculated. While in Rust
//! accessing a string's length is a O(1) operation (because the
//! length is stored); in C it is an O(length) operation because the
//! length needs to be computed by scanning the string for the nul
//! terminator.
//!
//! * **Internal nul characters** - When C strings have a nul
//! terminator character, this usually means that they cannot have nul
//! characters in the middle — a nul character would essentially
//! truncate the string. Rust strings *can* have nul characters in
//! the middle, because nul does not have to mark the end of the
//! string in Rust.
//!
//! # Representations of non-Rust strings
//!
//! [`CString`] and [`CStr`] are useful when you need to transfer
//! UTF-8 strings to and from languages with a C ABI, like Python.
//!
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
//! string: it is nul-terminated, and has no internal nul characters.
//! Rust code can create a [`CString`] out of a normal string (provided
//! that the string doesn't have nul characters in the middle), and
//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
//! then be passed as an argument to functions which use the C
//! conventions for strings.
//!
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
//! is what you would use to wrap a raw `*const `[`u8`] that you got from
//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
//! replacement characters.
//!
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
//! strings to and from the operating system itself, or when capturing
//! the output of external commands. Conversions between [`OsString`],
//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
//! and [`CStr`].
//!
//! * [`OsString`] represents an owned string in whatever
//! representation the operating system prefers. In the Rust standard
//! library, various APIs that transfer strings to/from the operating
//! system use [`OsString`] instead of plain strings. For example,
//! [`env::var_os()`] is used to query environment variables; it
//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
//! convert to a Rust string. This yields a [`Result<>`], so that
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
//! * [`OsStr`] represents a borrowed reference to a string in a
//! format that can be passed to the operating system. It can be
//! converted into an UTF-8 Rust string slice in a similar way to
//! [`OsString`].
//!
//! # Conversions
//!
//! ## On Unix
//!
//! On Unix, [`OsStr`] implements the
//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
//! These do inexpensive conversions from and to UTF-8 byte slices.
//!
//! Additionally, on Unix [`OsString`] implements the
//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! which provides [`from_vec`] and [`into_vec`] methods that consume
//! their arguments, and take or produce vectors of [`u8`].
//!
//! ## On Windows
//!
//! On Windows, [`OsStr`] implements the
//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
//! which provides an [`encode_wide`] method. This provides an
//! iterator that can be [`collect`]ed into a vector of [`u16`].
//!
//! Additionally, on Windows [`OsString`] implements the
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
//! trait, which provides a [`from_wide`] method. The result of this
//! method is an [`OsString`] which can be round-tripped to a Windows
//! string losslessly.
//!
//! [`String`]: ../string/struct.String.html
//! [`str`]: ../primitive.str.html
//! [`char`]: ../primitive.char.html
//! [`u8`]: ../primitive.u8.html
//! [`u16`]: ../primitive.u16.html
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
//! [`CString`]: struct.CString.html
//! [`CStr`]: struct.CStr.html
//! [`OsString`]: struct.OsString.html
//! [`OsStr`]: struct.OsStr.html
//! [`env::set_var()`]: ../env/fn.set_var.html
//! [`env::var_os()`]: ../env/fn.var_os.html
//! [`Result<>`]: ../result/enum.Result.html
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
//! [`Option`]: ../option/enum.Option.html
//! [`Some`]: ../option/enum.Option.html#variant.Some

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

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::c_str::{CString, CStr, NulError, IntoStringError};
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub use self::c_str::{FromBytesWithNulError};

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsString, OsStr};

#[stable(feature = "raw_os", since = "1.1.0")]
pub use core::ffi::c_void;

#[cfg(not(stage0))]
#[unstable(feature = "c_variadic",
           reason = "the `c_variadic` feature has not been properly tested on \
                     all supported platforms",
           issue = "27745")]
pub use core::ffi::VaList;

mod c_str;
mod os_str;
<|endoftext|>


<commit_before><commit_msg>Problem 03<commit_after>enum List<T> {
    Cons(T, ~List<T>),
    Nil
}

fn kth<'a, T>(k: uint, list: &'a List<T>) -> Option<&'a T> {
    match *list {
        Nil => None,
        Cons(ref elem, _) if k == 1 => Some(elem),
        Cons(_, ~ref rest) => kth(k-1, rest)
    }
}

fn main() {
    let list: List<char> = Cons('a', ~Cons('b', ~Cons('c', ~Cons('d', ~Nil))));
    println!("{:?}", kth(3, &list));
    println!("{:?}", kth(7, &list));
}
<|endoftext|>


<commit_before><commit_msg>Add some XML character predicates<commit_after>use super::{Document,Root,RootChild};

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Benchmark creation vs. modification of `WeightedIndex`<commit_after>// Copyright 2019 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(test)]

extern crate test;

const RAND_BENCH_N: u64 = 1000;

use test::Bencher;
use rand::Rng;
use rand::distributions::WeightedIndex;

#[bench]
fn weighted_index_creation(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| {
        let weights = [1u32, 2, 4, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 7];
        let distr = WeightedIndex::new(weights.to_vec()).unwrap();
        rng.sample(distr)
    })
}

#[bench]
fn weighted_index_modification(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    let weights = [1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7];
    let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
    b.iter(|| {
        distr.update_weights(&[(2, &4), (5, &1)]).unwrap();
        rng.sample(&distr)
    })
}
<|endoftext|>


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

// ignore-tidy-linelength

#![crate_name = "foo"]

#![feature(staged_api)]

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

#[stable(since="1.1.1", feature="rust1")]
pub struct SomeStruct;

impl SomeStruct {
    // @has 'foo/struct.SomeStruct.html' '//*[@id="SOME_CONST.v"]//div[@class="since"]' '1.1.2'
    #[stable(since="1.1.2", feature="rust2")]
    pub const SOME_CONST: usize = 0;
}
<|endoftext|>


<commit_before><commit_msg>empty message<commit_after><|endoftext|>


<commit_before><commit_msg>parser: add more docs and props verification<commit_after><|endoftext|>


<commit_before><commit_msg>Add dxgi_structures mod<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Structures provided by DXGI. Structures are from DXGI 1.0, 1.1, and 1.2

use winapi::{ WCHAR, UINT, SIZE_T, LUID, LARGE_INTEGER,
	BOOL, FLOAT, RECT, HMONITOR, POINT, HANDLE };
use libc::{ c_char, c_float };

use dxgi_constants::*;

#[repr(C)] pub struct DXGI_ADAPTER_DESC {
	Description: [WCHAR; 128],
	VendorId: UINT,
	DeviceId: UINT,
	SubSysId: UINT,
	Revision: UINT,
	DedicatedVideoMemory: SIZE_T,
	DedicatedSystemMemory: SIZE_T,
	SharedSystemMemory: SIZE_T,
	AdapterLuid: LUID,
}

#[repr(C)] pub struct DXGI_ADAPTER_DESC1 {
	Description: [WCHAR; 128],
	VendorId: UINT,
	DeviceId: UINT,
	SubSysId: UINT,
	Revision: UINT,
	DedicatedVideoMemory: SIZE_T,
	DedicatedSystemMemory: SIZE_T,
	SharedSystemMemory: SIZE_T,
	AdapterLuid: LUID,
	Flags: UINT,
}

#[repr(C)] pub struct DXGI_ADAPTER_DESC2 {
	Description: [WCHAR; 128],
	VendorId: UINT,
	DeviceId: UINT,
	SubSysId: UINT,
	Revision: UINT,
	DedicatedVideoMemory: SIZE_T,
	DedicatedSystemMemory: SIZE_T,
	SharedSystemMemory: SIZE_T,
	AdapterLuid: LUID,
	Flags: UINT,
	GraphicsPreemptionGranularity: DXGI_GRAPHICS_PREEMPTION_GRANULARITY,
	ComputePreemptionGranularity: DXGI_COMPUTE_PREEMPTION_GRANULARITY,
}

#[repr(C)] pub struct DXGI_DECODE_SWAP_CHAIN_DESC {
	Flags: UINT,
}

#[repr(C)] pub struct DXGI_FRAME_STATISTICS {
	PresentCount: UINT,
	PresentRefreshCount: UINT,
	SyncRefreshCount: UINT,
	SyncQPCTime: LARGE_INTEGER,
	SyncGPUTime: LARGE_INTEGER,
}

#[repr(C)] pub struct DXGI_GAMMA_CONTROL {
	Scale: DXGI_RGB,
	Offset: DXGI_RGB,
	GammaCurve: [DXGI_RGB; 1025],
}

#[repr(C)] pub struct DXGI_GAMMA_CONTROL_CAPABILITIES {
	ScaleAndOffsetSupported: BOOL,
	MaxConvertedValue: c_float,
	MinConvertedValue: c_float,
	NumGammaControlPoints: UINT,
	ControlPointPositions: [c_float; 1025],
}

#[repr(C)] pub struct DXGI_INFO_QUEUE_FILTER {
	AllowList: DXGI_INFO_QUEUE_FILTER_DESC,
	DenyList: DXGI_INFO_QUEUE_FILTER_DESC,
}

#[repr(C)] pub struct DXGI_INFO_QUEUE_FILTER_DESC {
	NumCategories: UINT,
	pCategoryList: DXGI_INFO_QUEUE_MESSAGE_CATEGORY,
	NumSeverities: UINT,
	pSeverityList: DXGI_INFO_QUEUE_MESSAGE_SEVERITY,
	NumIDs: UINT,
	pIDList: DXGI_INFO_QUEUE_MESSAGE_ID,
}

#[repr(C)] pub struct DXGI_INFO_QUEUE_MESSAGE {
	Producer: DXGI_DEBUG_ID,
	Category: DXGI_INFO_QUEUE_MESSAGE_CATEGORY,
	Severity: DXGI_INFO_QUEUE_MESSAGE_SEVERITY,
	ID: DXGI_INFO_QUEUE_MESSAGE_ID,
	pDescription: *const c_char,
	DescriptionByteLength: SIZE_T,
}

#[repr(C)] pub struct _DXGI_MATRIX_3X2_F {
	_11: FLOAT,
	_12: FLOAT,
	_21: FLOAT,
	_22: FLOAT,
	_31: FLOAT,
	_32: FLOAT,
}

#[repr(C)] pub struct DXGI_MAPPED_RECT {
	Pitch: INT,
	pBits: BYTE,
}

#[repr(C)] pub struct DXGI_MODE_DESC {
	Width: UINT,
	Height: UINT,
	RefreshRate: DXGI_RATIONAL,
	Format: DXGI_FORMAT,
	ScanlineOrdering: DXGI_MODE_SCANLINE_ORDER,
	Scaling: DXGI_MODE_SCALING,
}

#[repr(C)] pub struct _DXGI_MODE_DESC1 {
	Width: UINT,
	Height: UINT,
	RefreshRate: DXGI_RATIONAL,
	Format: DXGI_FORMAT,
	ScanlineOrdering: DXGI_MODE_SCANLINE_ORDER,
	Scaling: DXGI_MODE_SCALING,
	Stereo: BOOL,
}

#[repr(C)] pub struct DXGI_OUTPUT_DESC {
	DeviceName: [WCHAR; 32],
	DesktopCoordinates: RECT,
	AttachedToDesktop: BOOL,
	Rotation: DXGI_MODE_ROTATION,
	Monitor: HMONITOR,
}

#[repr(C)] pub struct _DXGI_OUTDUPL_DESC {
	ModeDesc: DXGI_MODE_DESC,
	Rotation: DXGI_MODE_ROTATION,
	DesktopImageInSystemMemory: BOOL,
}

#[repr(C)] pub struct _DXGI_OUTDUPL_FRAME_INFO {
	LastPresentTime: LARGE_INTEGER,
	LastMouseUpdateTime: LARGE_INTEGER,
	AccumulatedFrames: UINT,
	RectsCoalesced: BOOL,
	ProtectedContentMaskedOut: BOOL,
	PointerPosition: DXGI_OUTDUPL_POINTER_POSITION,
	TotalMetadataBufferSize: UINT,
	PointerShapeBufferSize: UINT,
}

#[repr(C)] pub struct _DXGI_OUTDUPL_MOVE_RECT {
	SourcePoint: POINT,
	DestinationRect: RECT,
}

#[repr(C)] pub struct _DXGI_OUTDUPL_POINTER_POSITION {
	Position: POINT,
	Visible: BOOL,
}

#[repr(C)] pub struct _DXGI_OUTDUPL_POINTER_SHAPE_INFO {
	Type: UINT,
	Width: UINT,
	Height: UINT,
	Pitch: UINT,
	HotSpot: POINT,
}

#[repr(C)] pub struct DXGI_PRESENT_PARAMETERS {
	DirtyRectsCount: UINT,
	pDirtyRects: RECT,
	pScrollRect: RECT,
	pScrollOffset: POINT,
}

#[repr(C)] pub struct DXGI_RATIONAL {
	Numerator: UINT,
	Denominator: UINT,
}

#[repr(C)] pub struct DXGI_RGB {
	Red: c_float,
	Green: c_float,
	Blue: c_float,
}

#[repr(C)] pub struct DXGI_RGBA {
	r: c_float,
	g: c_float,
	b: c_float,
	a: c_float,
}

#[repr(C)] pub struct DXGI_SAMPLE_DESC {
	Count: UINT,
	Quality: UINT,
}

#[repr(C)] pub struct DXGI_SHARED_RESOURCE {
	Handle: HANDLE,
}

#[repr(C)] pub struct DXGI_SURFACE_DESC {
	Width: UINT,
	Height: UINT,
	Format: DXGI_FORMAT,
	SampleDesc: DXGI_SAMPLE_DESC,
}

#[repr(C)] pub struct DXGI_SWAP_CHAIN_DESC {
	BufferDesc: DXGI_MODE_DESC,
	SampleDesc: DXGI_SAMPLE_DESC,
	BufferUsage: DXGI_USAGE,
	BufferCount: UINT,
	OutputWindow: HWND,
	Windowed: BOOL,
	SwapEffect: DXGI_SWAP_EFFECT,
	Flags: UINT,
}

#[repr(C)] pub struct _DXGI_SWAP_CHAIN_DESC1 {
	Width: UINT,
	Height: UINT,
	Format: DXGI_FORMAT,
	Stereo: BOOL,
	SampleDesc: DXGI_SAMPLE_DESC,
	BufferUsage: DXGI_USAGE,
	BufferCount: UINT,
	Scaling: DXGI_SCALING,
	SwapEffect: DXGI_SWAP_EFFECT,
	AlphaMode: DXGI_ALPHA_MODE,
	Flags: UINT,
}

#[repr(C)] pub struct DXGI_SWAP_CHAIN_FULLSCREEN_DESC {
	RefreshRate: DXGI_RATIONAL,
	ScanlineOrdering: DXGI_MODE_SCANLINE_ORDER,
	Scaling: DXGI_MODE_SCALING,
	Windowed: BOOL,
}<|endoftext|>


<commit_before><commit_msg>Closes #6: Add support for duplicate headers in client handshake request, they are allowed<commit_after><|endoftext|>


<commit_before><commit_msg>Fix formatting for LDM_STM<commit_after><|endoftext|>


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

use prelude::v1::*;
use io::prelude::*;

use cmp;
use fmt;
use io::lazy::Lazy;
use io::{self, BufReader, LineWriter};
use sync::{Arc, Mutex, MutexGuard};
use sys::stdio;

/// A handle to a raw instance of the standard input stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdin_raw` function.
pub struct StdinRaw(stdio::Stdin);

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdout_raw` function.
pub struct StdoutRaw(stdio::Stdout);

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stderr_raw` function.
pub struct StderrRaw(stdio::Stderr);

/// Construct a new raw handle to the standard input of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
/// handles is **not** available to raw handles returned from this function.
///
/// The returned handle has no external synchronization or buffering.
pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }

/// Construct a new raw handle to the standard input stream of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`. Note that data is buffered by the
/// `std::io::stdin` handles so writes which happen via this raw handle may
/// appear before previous writes.
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }

/// Construct a new raw handle to the standard input stream of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`.
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
pub fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }

impl Read for StdinRaw {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
}
impl Write for StdoutRaw {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
impl Write for StderrRaw {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

/// A handle to the standard input stream of a process.
///
/// Each handle is a shared reference to a global buffer of input data to this
/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
/// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
/// to other writes.
///
/// This handle implements the `Read` trait, but beware that concurrent reads
/// of `Stdin` must be executed with care.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdin {
    inner: Arc<Mutex<BufReader<StdinRaw>>>,
}

/// A locked reference to the a `Stdin` handle.
///
/// This handle implements both the `Read` and `BufRead` traits and is
/// constructed via the `lock` method on `Stdin`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StdinLock<'a> {
    inner: MutexGuard<'a, BufReader<StdinRaw>>,
}

/// Create a new handle to the global standard input stream of this process.
///
/// The handle returned refers to a globally shared buffer between all threads.
/// Access is synchronized and can be explicitly controlled with the `lock()`
/// method.
///
/// The `Read` trait is implemented for the returned value but the `BufRead`
/// trait is not due to the global nature of the standard input stream. The
/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
///
/// To avoid locking and buffering altogether, it is recommended to use the
/// `stdin_raw` constructor.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdin() -> Stdin {
    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
    return Stdin {
        inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
    };

    fn stdin_init() -> Arc<Mutex<BufReader<StdinRaw>>> {
        // The default buffer capacity is 64k, but apparently windows
        // doesn't like 64k reads on stdin. See #13304 for details, but the
        // idea is that on windows we use a slightly smaller buffer that's
        // been seen to be acceptable.
        Arc::new(Mutex::new(if cfg!(windows) {
            BufReader::with_capacity(8 * 1024, stdin_raw())
        } else {
            BufReader::new(stdin_raw())
        }))
    }
}

impl Stdin {
    /// Lock this handle to the standard input stream, returning a readable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Read` and `BufRead` traits for
    /// accessing the underlying data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StdinLock {
        StdinLock { inner: self.inner.lock().unwrap() }
    }

    /// Locks this handle and reads a line of input into the specified buffer.
    ///
    /// For detailed semantics of this method, see the documentation on
    /// `BufRead::read_line`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        self.lock().read_line(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Stdin {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.lock().read(buf)
    }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.lock().read_to_end(buf)
    }
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        self.lock().read_to_string(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for StdinLock<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for StdinLock<'a> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
    fn consume(&mut self, n: usize) { self.inner.consume(n) }
}

// As with stdin on windows, stdout often can't handle writes of large
// sizes. For an example, see #14940. For this reason, don't try to
// write the entire output buffer on windows. On unix we can just
// write the whole buffer all at once.
//
// For some other references, it appears that this problem has been
// encountered by others [1] [2]. We choose the number 8KB just because
// libuv does the same.
//
// [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
// [2]: http://www.mail-archive.com/log4net-dev@logging.apache.org/msg00661.html
#[cfg(windows)]
const OUT_MAX: usize = 8192;
#[cfg(unix)]
const OUT_MAX: usize = ::usize::MAX;

/// A handle to the global standard output stream of the current process.
///
/// Each handle shares a global buffer of data to be written to the standard
/// output stream. Access is also synchronized via a lock and explicit control
/// over locking is available via the `lock` method.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdout {
    // FIXME: this should be LineWriter or BufWriter depending on the state of
    //        stdout (tty or not). Note that if this is not line buffered it
    //        should also flush-on-panic or some form of flush-on-abort.
    inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
}

/// A locked reference to the a `Stdout` handle.
///
/// This handle implements the `Write` trait and is constructed via the `lock`
/// method on `Stdout`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StdoutLock<'a> {
    inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
}

/// Constructs a new reference to the standard output of the current process.
///
/// Each handle returned is a reference to a shared global buffer whose access
/// is synchronized via a mutex. Explicit control over synchronization is
/// provided via the `lock` method.
///
/// The returned handle implements the `Write` trait.
///
/// To avoid locking and buffering altogether, it is recommended to use the
/// `stdout_raw` constructor.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdout() -> Stdout {
    static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
    return Stdout {
        inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
    };

    fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
        Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
    }
}

impl Stdout {
    /// Lock this handle to the standard output stream, returning a writable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Write` trait for writing data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StdoutLock {
        StdoutLock { inner: self.inner.lock().unwrap() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Stdout {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.lock().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.lock().flush()
    }
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.lock().write_all(buf)
    }
    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.lock().write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for StdoutLock<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
    }
    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}

/// A handle to the standard error stream of a process.
///
/// For more information, see `stderr`
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stderr {
    inner: Arc<Mutex<StderrRaw>>,
}

/// A locked reference to the a `Stderr` handle.
///
/// This handle implements the `Write` trait and is constructed via the `lock`
/// method on `Stderr`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StderrLock<'a> {
    inner: MutexGuard<'a, StderrRaw>,
}

/// Constructs a new reference to the standard error stream of a process.
///
/// Each returned handle is synchronized amongst all other handles created from
/// this function. No handles are buffered, however.
///
/// The returned handle implements the `Write` trait.
///
/// To avoid locking altogether, it is recommended to use the `stderr_raw`
/// constructor.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stderr() -> Stderr {
    static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
    return Stderr {
        inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
    };

    fn stderr_init() -> Arc<Mutex<StderrRaw>> {
        Arc::new(Mutex::new(stderr_raw()))
    }
}

impl Stderr {
    /// Lock this handle to the standard error stream, returning a writable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Write` trait for writing data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StderrLock {
        StderrLock { inner: self.inner.lock().unwrap() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Stderr {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.lock().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.lock().flush()
    }
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.lock().write_all(buf)
    }
    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.lock().write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for StderrLock<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
    }
    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}

/// Resets the task-local stdout handle to the specified writer
///
/// This will replace the current task's stdout handle, returning the old
/// handle. All future calls to `print` and friends will emit their output to
/// this specified handle.
///
/// Note that this does not need to be called for all new tasks; the default
/// output handle is to the process's stdout stream.
#[unstable(feature = "set_panic",
           reason = "this function may disappear completely or be replaced \
                     with a more general mechanism")]
#[doc(hidden)]
pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
    use panicking::LOCAL_STDERR;
    use mem;
    LOCAL_STDERR.with(move |slot| {
        mem::replace(&mut *slot.borrow_mut(), Some(sink))
    }).and_then(|mut s| {
        let _ = s.flush();
        Some(s)
    })
}
<commit_msg>Remove incorrect references to _raw stdio functions<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use prelude::v1::*;
use io::prelude::*;

use cmp;
use fmt;
use io::lazy::Lazy;
use io::{self, BufReader, LineWriter};
use sync::{Arc, Mutex, MutexGuard};
use sys::stdio;

/// A handle to a raw instance of the standard input stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stdin_raw` function.
struct StdinRaw(stdio::Stdin);

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stdout_raw` function.
struct StdoutRaw(stdio::Stdout);

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stderr_raw` function.
struct StderrRaw(stdio::Stderr);

/// Construct a new raw handle to the standard input of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
/// handles is **not** available to raw handles returned from this function.
///
/// The returned handle has no external synchronization or buffering.
fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }

/// Construct a new raw handle to the standard input stream of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`. Note that data is buffered by the
/// `std::io::stdin` handles so writes which happen via this raw handle may
/// appear before previous writes.
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }

/// Construct a new raw handle to the standard input stream of this process.
///
/// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`.
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }

impl Read for StdinRaw {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
}
impl Write for StdoutRaw {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
impl Write for StderrRaw {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
    fn flush(&mut self) -> io::Result<()> { Ok(()) }
}

/// A handle to the standard input stream of a process.
///
/// Each handle is a shared reference to a global buffer of input data to this
/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
/// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
/// to other writes.
///
/// This handle implements the `Read` trait, but beware that concurrent reads
/// of `Stdin` must be executed with care.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdin {
    inner: Arc<Mutex<BufReader<StdinRaw>>>,
}

/// A locked reference to the a `Stdin` handle.
///
/// This handle implements both the `Read` and `BufRead` traits and is
/// constructed via the `lock` method on `Stdin`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StdinLock<'a> {
    inner: MutexGuard<'a, BufReader<StdinRaw>>,
}

/// Create a new handle to the global standard input stream of this process.
///
/// The handle returned refers to a globally shared buffer between all threads.
/// Access is synchronized and can be explicitly controlled with the `lock()`
/// method.
///
/// The `Read` trait is implemented for the returned value but the `BufRead`
/// trait is not due to the global nature of the standard input stream. The
/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdin() -> Stdin {
    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
    return Stdin {
        inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
    };

    fn stdin_init() -> Arc<Mutex<BufReader<StdinRaw>>> {
        // The default buffer capacity is 64k, but apparently windows
        // doesn't like 64k reads on stdin. See #13304 for details, but the
        // idea is that on windows we use a slightly smaller buffer that's
        // been seen to be acceptable.
        Arc::new(Mutex::new(if cfg!(windows) {
            BufReader::with_capacity(8 * 1024, stdin_raw())
        } else {
            BufReader::new(stdin_raw())
        }))
    }
}

impl Stdin {
    /// Lock this handle to the standard input stream, returning a readable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Read` and `BufRead` traits for
    /// accessing the underlying data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StdinLock {
        StdinLock { inner: self.inner.lock().unwrap() }
    }

    /// Locks this handle and reads a line of input into the specified buffer.
    ///
    /// For detailed semantics of this method, see the documentation on
    /// `BufRead::read_line`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
        self.lock().read_line(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Stdin {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.lock().read(buf)
    }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.lock().read_to_end(buf)
    }
    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
        self.lock().read_to_string(buf)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for StdinLock<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.inner.read(buf)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for StdinLock<'a> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
    fn consume(&mut self, n: usize) { self.inner.consume(n) }
}

// As with stdin on windows, stdout often can't handle writes of large
// sizes. For an example, see #14940. For this reason, don't try to
// write the entire output buffer on windows. On unix we can just
// write the whole buffer all at once.
//
// For some other references, it appears that this problem has been
// encountered by others [1] [2]. We choose the number 8KB just because
// libuv does the same.
//
// [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
// [2]: http://www.mail-archive.com/log4net-dev@logging.apache.org/msg00661.html
#[cfg(windows)]
const OUT_MAX: usize = 8192;
#[cfg(unix)]
const OUT_MAX: usize = ::usize::MAX;

/// A handle to the global standard output stream of the current process.
///
/// Each handle shares a global buffer of data to be written to the standard
/// output stream. Access is also synchronized via a lock and explicit control
/// over locking is available via the `lock` method.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdout {
    // FIXME: this should be LineWriter or BufWriter depending on the state of
    //        stdout (tty or not). Note that if this is not line buffered it
    //        should also flush-on-panic or some form of flush-on-abort.
    inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
}

/// A locked reference to the a `Stdout` handle.
///
/// This handle implements the `Write` trait and is constructed via the `lock`
/// method on `Stdout`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StdoutLock<'a> {
    inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
}

/// Constructs a new reference to the standard output of the current process.
///
/// Each handle returned is a reference to a shared global buffer whose access
/// is synchronized via a mutex. Explicit control over synchronization is
/// provided via the `lock` method.
///
/// The returned handle implements the `Write` trait.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stdout() -> Stdout {
    static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
    return Stdout {
        inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
    };

    fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
        Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
    }
}

impl Stdout {
    /// Lock this handle to the standard output stream, returning a writable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Write` trait for writing data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StdoutLock {
        StdoutLock { inner: self.inner.lock().unwrap() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Stdout {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.lock().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.lock().flush()
    }
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.lock().write_all(buf)
    }
    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.lock().write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for StdoutLock<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
    }
    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}

/// A handle to the standard error stream of a process.
///
/// For more information, see `stderr`
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stderr {
    inner: Arc<Mutex<StderrRaw>>,
}

/// A locked reference to the a `Stderr` handle.
///
/// This handle implements the `Write` trait and is constructed via the `lock`
/// method on `Stderr`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StderrLock<'a> {
    inner: MutexGuard<'a, StderrRaw>,
}

/// Constructs a new reference to the standard error stream of a process.
///
/// Each returned handle is synchronized amongst all other handles created from
/// this function. No handles are buffered, however.
///
/// The returned handle implements the `Write` trait.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stderr() -> Stderr {
    static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
    return Stderr {
        inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
    };

    fn stderr_init() -> Arc<Mutex<StderrRaw>> {
        Arc::new(Mutex::new(stderr_raw()))
    }
}

impl Stderr {
    /// Lock this handle to the standard error stream, returning a writable
    /// guard.
    ///
    /// The lock is released when the returned lock goes out of scope. The
    /// returned guard also implements the `Write` trait for writing data.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn lock(&self) -> StderrLock {
        StderrLock { inner: self.inner.lock().unwrap() }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Stderr {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.lock().write(buf)
    }
    fn flush(&mut self) -> io::Result<()> {
        self.lock().flush()
    }
    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.lock().write_all(buf)
    }
    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.lock().write_fmt(fmt)
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for StderrLock<'a> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
    }
    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}

/// Resets the task-local stdout handle to the specified writer
///
/// This will replace the current task's stdout handle, returning the old
/// handle. All future calls to `print` and friends will emit their output to
/// this specified handle.
///
/// Note that this does not need to be called for all new tasks; the default
/// output handle is to the process's stdout stream.
#[unstable(feature = "set_panic",
           reason = "this function may disappear completely or be replaced \
                     with a more general mechanism")]
#[doc(hidden)]
pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
    use panicking::LOCAL_STDERR;
    use mem;
    LOCAL_STDERR.with(move |slot| {
        mem::replace(&mut *slot.borrow_mut(), Some(sink))
    }).and_then(|mut s| {
        let _ = s.flush();
        Some(s)
    })
}
<|endoftext|>


<commit_before>//! The main parser interface

export parse_sess;
export new_parse_sess, new_parse_sess_special_handler;
export next_node_id;
export new_parser_from_file, new_parser_etc_from_file;
export new_parser_from_source_str;
export new_parser_from_tts;
export new_sub_parser_from_file;
export parse_crate_from_file, parse_crate_from_crate_file;
export parse_crate_from_source_str;
export parse_expr_from_source_str, parse_item_from_source_str;
export parse_stmt_from_source_str;
export parse_tts_from_source_str;
export parse_from_source_str;

use parser::Parser;
use attr::parser_attr;
use common::parser_common;
use ast::node_id;
use util::interner;
use diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};
use lexer::{reader, string_reader};
use parse::token::{ident_interner, mk_ident_interner};
use codemap::{span, CodeMap, FileMap, CharPos, BytePos};

type parse_sess = @{
    cm: @codemap::CodeMap,
    mut next_id: node_id,
    span_diagnostic: span_handler,
    interner: @ident_interner,
};

fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
    let cm = @CodeMap::new();
    return @{cm: cm,
             mut next_id: 1,
             span_diagnostic: mk_span_handler(mk_handler(demitter), cm),
             interner: mk_ident_interner(),
            };
}

fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
    -> parse_sess {
    return @{cm: cm,
             mut next_id: 1,
             span_diagnostic: sh,
             interner: mk_ident_interner(),
             };
}

fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg,
                         sess: parse_sess) -> @ast::crate {
    if input.filetype() == Some(~".rc") {
        parse_crate_from_crate_file(input, cfg, sess)
    } else if input.filetype() == Some(~".rs") {
        parse_crate_from_source_file(input, cfg, sess)
    } else {
        sess.span_diagnostic.handler().fatal(~"unknown input file type: " +
                                             input.to_str())
    }
}

fn parse_crate_from_crate_file(input: &Path, cfg: ast::crate_cfg,
                               sess: parse_sess) -> @ast::crate {
    let p = new_crate_parser_from_file(sess, cfg, input);
    let lo = p.span.lo;
    let prefix = input.dir_path();
    let leading_attrs = p.parse_inner_attrs_and_next();
    let { inner: crate_attrs, next: first_cdir_attr } = leading_attrs;
    let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
    let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg};
    let companionmod = input.filestem().map(|s| Path(*s));
    let (m, attrs) = eval::eval_crate_directives_to_mod(
        cx, cdirs, &prefix, &companionmod);
    let mut hi = p.span.hi;
    p.expect(token::EOF);
    p.abort_if_errors();
    return @ast_util::respan(ast_util::mk_sp(lo, hi),
                          {directives: cdirs,
                           module: m,
                           attrs: vec::append(crate_attrs, attrs),
                           config: /* FIXME (#2543) */ copy p.cfg});
}

fn parse_crate_from_source_file(input: &Path, cfg: ast::crate_cfg,
                                sess: parse_sess) -> @ast::crate {
    let p = new_crate_parser_from_file(sess, cfg, input);
    let r = p.parse_crate_mod(cfg);
    return r;
}

fn parse_crate_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                               sess: parse_sess) -> @ast::crate {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_crate_mod(cfg);
    p.abort_if_errors();
    return r;
}

fn parse_expr_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              sess: parse_sess) -> @ast::expr {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_expr();
    p.abort_if_errors();
    return r;
}

fn parse_item_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              +attrs: ~[ast::attribute],
                              sess: parse_sess) -> Option<@ast::item> {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_item(attrs);
    p.abort_if_errors();
    return r;
}

fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              +attrs: ~[ast::attribute],
                              sess: parse_sess) -> @ast::stmt {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_stmt(attrs);
    p.abort_if_errors();
    return r;
}

fn parse_tts_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                             sess: parse_sess) -> ~[ast::token_tree] {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    p.quote_depth += 1u;
    let r = p.parse_all_token_trees();
    p.abort_if_errors();
    return r;
}

fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
                            name: ~str, ss: codemap::FileSubstr,
                            source: @~str, cfg: ast::crate_cfg,
                            sess: parse_sess)
    -> T
{
    let p = new_parser_from_source_str(sess, cfg, name, ss,
                                       source);
    let r = f(p);
    if !p.reader.is_eof() {
        p.reader.fatal(~"expected end-of-string");
    }
    p.abort_if_errors();
    move r
}

fn next_node_id(sess: parse_sess) -> node_id {
    let rv = sess.next_id;
    sess.next_id += 1;
    // ID 0 is reserved for the crate and doesn't actually exist in the AST
    assert rv != 0;
    return rv;
}

fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
                              +name: ~str, +ss: codemap::FileSubstr,
                              source: @~str) -> Parser {
    let filemap = sess.cm.new_filemap_w_substr(name, ss, source);
    let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
                                        sess.interner);
    return Parser(sess, cfg, srdr as reader);
}

fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                        path: &Path) -> Result<Parser, ~str> {
    match io::read_whole_file_str(path) {
      result::Ok(move src) => {
          let filemap = sess.cm.new_filemap(path.to_str(), @move src);
          let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
                                              sess.interner);

          Ok(Parser(sess, cfg, srdr as reader))

      }
      result::Err(move e) => Err(move e)
    }
}

/// Create a new parser for an entire crate, handling errors as appropriate
/// if the file doesn't exist
fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                              path: &Path) -> Parser {
    match new_parser_from_file(sess, cfg, path) {
        Ok(move parser) => move parser,
        Err(move e) => {
            sess.span_diagnostic.handler().fatal(e)
        }
    }
}

/// Create a new parser based on a span from an existing parser. Handles
/// error messages correctly when the file does not exist.
fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                            path: &Path, sp: span) -> Parser {
    match new_parser_from_file(sess, cfg, path) {
        Ok(move parser) => move parser,
        Err(move e) => {
            sess.span_diagnostic.span_fatal(sp, e)
        }
    }
}

fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg,
                       tts: ~[ast::token_tree]) -> Parser {
    let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner,
                                    None, tts);
    return Parser(sess, cfg, trdr as reader)
}
<commit_msg>Add a temporary hack to divert the parser to an alternate file<commit_after>//! The main parser interface

export parse_sess;
export new_parse_sess, new_parse_sess_special_handler;
export next_node_id;
export new_parser_from_file, new_parser_etc_from_file;
export new_parser_from_source_str;
export new_parser_from_tts;
export new_sub_parser_from_file;
export parse_crate_from_file, parse_crate_from_crate_file;
export parse_crate_from_source_str;
export parse_expr_from_source_str, parse_item_from_source_str;
export parse_stmt_from_source_str;
export parse_tts_from_source_str;
export parse_from_source_str;

use parser::Parser;
use attr::parser_attr;
use common::parser_common;
use ast::node_id;
use util::interner;
use diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};
use lexer::{reader, string_reader};
use parse::token::{ident_interner, mk_ident_interner};
use codemap::{span, CodeMap, FileMap, CharPos, BytePos};

type parse_sess = @{
    cm: @codemap::CodeMap,
    mut next_id: node_id,
    span_diagnostic: span_handler,
    interner: @ident_interner,
};

fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
    let cm = @CodeMap::new();
    return @{cm: cm,
             mut next_id: 1,
             span_diagnostic: mk_span_handler(mk_handler(demitter), cm),
             interner: mk_ident_interner(),
            };
}

fn new_parse_sess_special_handler(sh: span_handler, cm: @codemap::CodeMap)
    -> parse_sess {
    return @{cm: cm,
             mut next_id: 1,
             span_diagnostic: sh,
             interner: mk_ident_interner(),
             };
}

fn parse_crate_from_file(input: &Path, cfg: ast::crate_cfg,
                         sess: parse_sess) -> @ast::crate {
    if input.filetype() == Some(~".rc") {
        parse_crate_from_crate_file(input, cfg, sess)
    } else if input.filetype() == Some(~".rs") {
        parse_crate_from_source_file(input, cfg, sess)
    } else {
        sess.span_diagnostic.handler().fatal(~"unknown input file type: " +
                                             input.to_str())
    }
}

fn parse_crate_from_crate_file(input: &Path, cfg: ast::crate_cfg,
                               sess: parse_sess) -> @ast::crate {
    let p = new_crate_parser_from_file(sess, cfg, input);
    let lo = p.span.lo;
    let prefix = input.dir_path();
    let leading_attrs = p.parse_inner_attrs_and_next();
    let { inner: crate_attrs, next: first_cdir_attr } = leading_attrs;
    let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
    let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg};
    let companionmod = input.filestem().map(|s| Path(*s));
    let (m, attrs) = eval::eval_crate_directives_to_mod(
        cx, cdirs, &prefix, &companionmod);
    let mut hi = p.span.hi;
    p.expect(token::EOF);
    p.abort_if_errors();
    return @ast_util::respan(ast_util::mk_sp(lo, hi),
                          {directives: cdirs,
                           module: m,
                           attrs: vec::append(crate_attrs, attrs),
                           config: /* FIXME (#2543) */ copy p.cfg});
}

fn parse_crate_from_source_file(input: &Path, cfg: ast::crate_cfg,
                                sess: parse_sess) -> @ast::crate {
    let p = new_crate_parser_from_file(sess, cfg, input);
    let r = p.parse_crate_mod(cfg);
    return r;
}

fn parse_crate_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                               sess: parse_sess) -> @ast::crate {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_crate_mod(cfg);
    p.abort_if_errors();
    return r;
}

fn parse_expr_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              sess: parse_sess) -> @ast::expr {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_expr();
    p.abort_if_errors();
    return r;
}

fn parse_item_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              +attrs: ~[ast::attribute],
                              sess: parse_sess) -> Option<@ast::item> {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_item(attrs);
    p.abort_if_errors();
    return r;
}

fn parse_stmt_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                              +attrs: ~[ast::attribute],
                              sess: parse_sess) -> @ast::stmt {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    let r = p.parse_stmt(attrs);
    p.abort_if_errors();
    return r;
}

fn parse_tts_from_source_str(name: ~str, source: @~str, cfg: ast::crate_cfg,
                             sess: parse_sess) -> ~[ast::token_tree] {
    let p = new_parser_from_source_str(sess, cfg, name,
                                       codemap::FssNone, source);
    p.quote_depth += 1u;
    let r = p.parse_all_token_trees();
    p.abort_if_errors();
    return r;
}

fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
                            name: ~str, ss: codemap::FileSubstr,
                            source: @~str, cfg: ast::crate_cfg,
                            sess: parse_sess)
    -> T
{
    let p = new_parser_from_source_str(sess, cfg, name, ss,
                                       source);
    let r = f(p);
    if !p.reader.is_eof() {
        p.reader.fatal(~"expected end-of-string");
    }
    p.abort_if_errors();
    move r
}

fn next_node_id(sess: parse_sess) -> node_id {
    let rv = sess.next_id;
    sess.next_id += 1;
    // ID 0 is reserved for the crate and doesn't actually exist in the AST
    assert rv != 0;
    return rv;
}

fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
                              +name: ~str, +ss: codemap::FileSubstr,
                              source: @~str) -> Parser {
    let filemap = sess.cm.new_filemap_w_substr(name, ss, source);
    let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
                                        sess.interner);
    return Parser(sess, cfg, srdr as reader);
}

fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                        path: &Path) -> Result<Parser, ~str> {
    match io::read_whole_file_str(path) {
      result::Ok(move src) => {

          // HACK: If the file contains a special token use a different
          // source file. Used to send the stage1+ parser (the stage0 parser
          // doesn't have this hack) to a different crate file.
          // Transitional. Remove me.
          let src = if src.starts_with("// DIVERT") {
              let actual_path = &path.with_filestem("alternate_crate");
              result::unwrap(io::read_whole_file_str(actual_path))
          } else {
              move src
          };

          let filemap = sess.cm.new_filemap(path.to_str(), @move src);
          let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
                                              sess.interner);

          Ok(Parser(sess, cfg, srdr as reader))

      }
      result::Err(move e) => Err(move e)
    }
}

/// Create a new parser for an entire crate, handling errors as appropriate
/// if the file doesn't exist
fn new_crate_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                              path: &Path) -> Parser {
    match new_parser_from_file(sess, cfg, path) {
        Ok(move parser) => move parser,
        Err(move e) => {
            sess.span_diagnostic.handler().fatal(e)
        }
    }
}

/// Create a new parser based on a span from an existing parser. Handles
/// error messages correctly when the file does not exist.
fn new_sub_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
                            path: &Path, sp: span) -> Parser {
    match new_parser_from_file(sess, cfg, path) {
        Ok(move parser) => move parser,
        Err(move e) => {
            sess.span_diagnostic.span_fatal(sp, e)
        }
    }
}

fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg,
                       tts: ~[ast::token_tree]) -> Parser {
    let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner,
                                    None, tts);
    return Parser(sess, cfg, trdr as reader)
}
<|endoftext|>


<commit_before><commit_msg>Added squares example<commit_after>extern crate turtle;

use turtle::Turtle;

fn main() {
    let mut turtle = Turtle::new();

    for _ in 0..36 {
        square(&mut turtle);
        turtle.right(10.0);
    }
}

fn square(turtle: &mut Turtle) {
    for _ in 0..4 {
        turtle.forward(200.0);
        turtle.right(90.0);
    }
}
<|endoftext|>


<commit_before><commit_msg>add some test coverage around peers map (peer_addr hashing impl) (#3039)<commit_after>// Copyright 2019 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

use grin_p2p as p2p;

use crate::p2p::types::PeerAddr;

// Test the behavior of a hashmap of peers keyed by peer_addr.
#[test]
fn test_peer_addr_hashing() {
	let mut peers: HashMap<PeerAddr, String> = HashMap::new();

	let socket_addr1 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)), 8080);
	let peer_addr1 = PeerAddr(socket_addr1);
	peers.insert(peer_addr1, "peer1".into());

	assert!(peers.contains_key(&peer_addr1));
	assert_eq!(peers.len(), 1);

	let socket_addr2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)), 8081);
	let peer_addr2 = PeerAddr(socket_addr2);

	// Expected behavior here is to ignore the port when hashing peer_addr.
	// This means the two peer_addr instances above are seen as the same addr.
	assert!(peers.contains_key(&peer_addr1));
	assert!(peers.contains_key(&peer_addr2));

	peers.insert(peer_addr2, "peer2".into());

	// Inserting the second instance is a no-op as they are treated as the same addr.
	assert!(peers.contains_key(&peer_addr1));
	assert!(peers.contains_key(&peer_addr2));
	assert_eq!(peers.len(), 1);

	// Check they are treated as the same even though their underlying ports are different.
	assert_eq!(peer_addr1, peer_addr2);
	assert_eq!(peer_addr1.0, socket_addr1);
	assert_eq!(peer_addr2.0, socket_addr2);
	assert_eq!(peer_addr1.0.port(), 8080);
	assert_eq!(peer_addr2.0.port(), 8081);
}
<|endoftext|>


<commit_before><commit_msg>Fix: Explicitely use Itertools::flatten()<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary return keyword<commit_after><|endoftext|>


<commit_before><commit_msg>Add bench<commit_after>#![feature(test)]
extern crate test;
extern crate fast_sweeping;

mod bench {
    use test::{black_box, Bencher};
    use fast_sweeping::*;

    fn bench_2d(b: &mut Bencher, dim: (usize, usize)) {
        let (nx, ny) = dim;
        let mut u = vec![0.; nx * ny];
        let mut d = black_box(vec![0.; nx * ny]);

        let r = 0.3;
        let hx = 1. / (nx - 1) as f64;
        let hy = 1. / (ny - 1) as f64;

        for i in 0..nx {
            for j in 0..ny {
                let x = i as f64 * hx - 0.5;
                let y = j as f64 * hy - 0.5;
                u[i * ny + j] = (x * x + y * y).sqrt() - r;
            }
        }

        b.iter(|| {
            signed_distance_2d(&mut d, &u, dim, hx);
        });
    }

    #[bench]
    fn s128(b: &mut Bencher) {
        bench_2d(b, (128, 128));
    }

    #[bench]
    fn s512(b: &mut Bencher) {
        bench_2d(b, (512, 512));
    }

    // too slow now
    // #[bench]
    // fn s2048(b: &mut Bencher) {
    //     bench_2d(b, (2048, 2048));
    // }
}
<|endoftext|>


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

use syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::c_int;
use std::ffi::{CStr, CString};

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

static POISONED: AtomicBool = AtomicBool::new(false);
static INIT: Once = Once::new();

pub(crate) fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED.store(true, Ordering::SeqCst);
            }

            configure_llvm(sess);
        });

        if POISONED.load(Ordering::SeqCst) {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

fn require_inited() {
    INIT.call_once(|| bug!("llvm is not initialized"));
    if POISONED.load(Ordering::SeqCst) {
        bug!("couldn't enable multi-threaded LLVM");
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features must be known to LLVM or the feature
// detection code will walk past the end of the feature array,
// leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];

const AARCH64_WHITELIST: &'static [&'static str] = &["neon\0"];

const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
                                                 "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
                                                 "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
                                                 "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0",
                                                 "xsave\0", "xsaveopt\0", "xsavec\0",
                                                 "xsaves\0", "aes\0",
                                                 "avx512bw\0", "avx512cd\0",
                                                 "avx512dq\0", "avx512er\0",
                                                 "avx512f\0", "avx512ifma\0",
                                                 "avx512pf\0", "avx512vbmi\0",
                                                 "avx512vl\0", "avx512vpopcntdq\0",
                                                 "mmx\0", "fxsr\0"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];

const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0",
                                                     "power8-altivec\0", "power9-altivec\0",
                                                     "power8-vector\0", "power9-vector\0",
                                                     "vsx\0"];

const MIPS_WHITELIST: &'static [&'static str] = &["msa\0"];

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let whitelist = target_feature_whitelist(sess);
    let target_machine = create_target_machine(sess);
    let mut features = Vec::new();
    for feat in whitelist {
        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr()) } {
            features.push(Symbol::intern(feat.to_str().unwrap()));
        }
    }
    features
}

pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> {
    let whitelist = match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "aarch64" => AARCH64_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        "mips" | "mips64" => MIPS_WHITELIST,
        "powerpc" | "powerpc64" => POWERPC_WHITELIST,
        _ => &[],
    };
    whitelist.iter().map(|m| {
        CStr::from_bytes_with_nul(m.as_bytes()).unwrap()
    }).collect()
}

pub fn print_version() {
    // Can be called without initializing LLVM
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    // Can be called without initializing LLVM
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub(crate) fn print(req: PrintRequest, sess: &Session) {
    require_inited();
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}
<commit_msg>Rollup merge of #47826 - gnzlbg:patch-2, r=alexcrichton<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::c_int;
use std::ffi::{CStr, CString};

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

static POISONED: AtomicBool = AtomicBool::new(false);
static INIT: Once = Once::new();

pub(crate) fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED.store(true, Ordering::SeqCst);
            }

            configure_llvm(sess);
        });

        if POISONED.load(Ordering::SeqCst) {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

fn require_inited() {
    INIT.call_once(|| bug!("llvm is not initialized"));
    if POISONED.load(Ordering::SeqCst) {
        bug!("couldn't enable multi-threaded LLVM");
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features must be known to LLVM or the feature
// detection code will walk past the end of the feature array,
// leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0", "vfp2\0", "vfp3\0", "vfp4\0"];

const AARCH64_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0"];

const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
                                                 "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
                                                 "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
                                                 "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0",
                                                 "xsave\0", "xsaveopt\0", "xsavec\0",
                                                 "xsaves\0", "aes\0",
                                                 "avx512bw\0", "avx512cd\0",
                                                 "avx512dq\0", "avx512er\0",
                                                 "avx512f\0", "avx512ifma\0",
                                                 "avx512pf\0", "avx512vbmi\0",
                                                 "avx512vl\0", "avx512vpopcntdq\0",
                                                 "mmx\0", "fxsr\0"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];

const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0",
                                                     "power8-altivec\0", "power9-altivec\0",
                                                     "power8-vector\0", "power9-vector\0",
                                                     "vsx\0"];

const MIPS_WHITELIST: &'static [&'static str] = &["msa\0"];

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let whitelist = target_feature_whitelist(sess);
    let target_machine = create_target_machine(sess);
    let mut features = Vec::new();
    for feat in whitelist {
        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr()) } {
            features.push(Symbol::intern(feat.to_str().unwrap()));
        }
    }
    features
}

pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> {
    let whitelist = match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "aarch64" => AARCH64_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        "mips" | "mips64" => MIPS_WHITELIST,
        "powerpc" | "powerpc64" => POWERPC_WHITELIST,
        _ => &[],
    };
    whitelist.iter().map(|m| {
        CStr::from_bytes_with_nul(m.as_bytes()).unwrap()
    }).collect()
}

pub fn print_version() {
    // Can be called without initializing LLVM
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    // Can be called without initializing LLVM
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub(crate) fn print(req: PrintRequest, sess: &Session) {
    require_inited();
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>auto merge of #6483 : catamorphism/rust/issue-4107, r=catamorphism<commit_after>// Copyright 2013 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.

pub fn main() {
    let id: &Mat2<float> = &Matrix::identity();
}

pub trait Index<Index,Result> { }
pub trait Dimensional<T>: Index<uint, T> { }

pub struct Mat2<T> { x: () }
pub struct Vec2<T> { x: () }

impl<T> Dimensional<Vec2<T>> for Mat2<T> { }
impl<T> Index<uint, Vec2<T>> for Mat2<T> { }

impl<T> Dimensional<T> for Vec2<T> { }
impl<T> Index<uint, T> for Vec2<T> { }

pub trait Matrix<T,V>: Dimensional<V> {
    fn identity() -> Self;
}

impl<T> Matrix<T, Vec2<T>> for Mat2<T> {
    fn identity() -> Mat2<T> { Mat2{ x: () } }
}
<|endoftext|>


<commit_before><commit_msg>Added notes on Rust primitive types<commit_after>// A compilation of notes and lessons from https://doc.rust-lang.org/book/primitive-types.html

fn main() {
    // bools - fairly straightforward. either true or false
    let foo: bool = false;

    // char is also fairly straightforward but has a quirk compared to C++ - it's a Unicode char. This means it's 4 bytes instead of 1
    let bar = "😎";

    // There are lots of different types of numbers. We have signed int (i), unsigned int (u), and floating point (f)
    // These come in different sizes: i/u8, i/u16, i/u32, i/u64, f32, f64
    // The defaults are i32 and f64
    let baz = 2;    // i32
    let qux = 1.0;  // f64

    // There are also two 'special' numeric types whose size depends on the system architecture (32 or 64 bit)
    // these are usize and isize

    // Arrays are, by default, immutable. Just like everything else in Rust :) note that the 'mut' keyword works here
    // [T, N] is the form. T is a templated type, N is a compile time constant
    let a: [i32; 3] = [1, 2, 3];

    // A shorthand exists to fill in all items in an array with a specific value. For example, this fills in all 20 values
    // in 'b' with the value 0
    let b = [0; 20];

    // You can access items the say way as every other language - foo[2]. Arrays are zero-indexed
    // You can also access 'slices' of arrays, which can be accessed like so: this selects [1, 3, 3]
    let c = [0, 1, 2, 3, 4];
    let d = &[1..4];

    // Tuples, like other languages, are ordered lists of fixed size. They can hold different types, like so
    // A single tuple can be called for by using a comma after the value - (0,) is a single value tuple, (0) is a zero
    // in parentheses
    let e: (i64, &str) = (3, "foo");

    // Tuples can be assigned to each other if they contain the same types and arity (number).
    // Fields of a tuple can be accessed through a "destructuring let". This sets f and g to each of the parts
    // of the tuple e
    let (f, g) = e;

    // You can also access parts of a tuple via indexing
    let h = e.0;

    // Functions also have a type and can be used to create function pointers. For information on that see the "Functions"
    // section notes
}<|endoftext|>


<commit_before>// Microbenchmarks for various functions in core and std

use std;

import std::time::precise_time_s;
import std::map;
import std::map::{map, hashmap};

import io::{reader, reader_util};

fn main(argv: [str]/~) {
    #macro[
        [#bench[id],
         if tests.len() == 0 || vec::contains(tests, #stringify(id)) {
             run_test(#stringify(id), id);
         }
        ]
    ];

    let tests = vec::view(argv, 1, argv.len());

    #bench[shift_push];
    #bench[read_line];
    #bench[str_set];
    #bench[vec_plus];
    #bench[vec_append];
    #bench[vec_push_all];
}

fn run_test(name: str, test: fn()) {
    let start = precise_time_s();
    test();
    let stop = precise_time_s();

    io::println(#fmt("%s:\t\t%f ms", name, (stop - start) * 1000f));
}

fn shift_push() {
    let mut v1 = vec::from_elem(30000, 1);
    let mut v2 = []/~;

    while v1.len() > 0 {
        vec::push(v2, vec::shift(v1));
    }
}

fn read_line() {
    let path = path::connect(
        #env("CFG_SRC_DIR"),
        "src/test/bench/shootout-k-nucleotide.data"
    );

    for int::range(0, 3) {|_i|
        let reader = result::get(io::file_reader(path));
        while !reader.eof() {
            reader.read_line();
        }
    }
}

fn str_set() {
    let r = rand::rng();

    let s = map::hashmap(str::hash, str::eq);

    for int::range(0, 1000) {|_i|
        map::set_add(s, r.gen_str(10));
    }

    let mut found = 0;
    for int::range(0, 1000) {|_i|
        alt s.find(r.gen_str(10)) {
          some(_) { found += 1; }
          none { }
        }
    }
}

fn vec_plus() {
    let r = rand::rng();

    let mut v = []/~;
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            v += rv;
        }
        else {
            v = rv + v;
        }
        i += 1;
    }
}

fn vec_append() {
    let r = rand::rng();

    let mut v = []/~;
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            v = vec::append(v, rv);
        }
        else {
            v = vec::append(rv, v);
        }
        i += 1;
    }
}

fn vec_push_all() {
    let r = rand::rng();

    let mut v = []/~;
    for uint::range(0, 1500) {|i|
        let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            vec::push_all(v, rv);
        }
        else {
            v <-> rv;
            vec::push_all(v, rv);
        }
    }
}
<commit_msg>make core-std respect RUST_BENCH<commit_after>// Microbenchmarks for various functions in core and std

use std;

import std::time::precise_time_s;
import std::map;
import std::map::{map, hashmap};

import io::{reader, reader_util};

fn main(argv: [str]/~) {
    #macro[
        [#bench[id],
         maybe_run_test(argv, #stringify(id), id)
        ]
    ];

    let tests = vec::view(argv, 1, argv.len());

    #bench[shift_push];
    #bench[read_line];
    #bench[str_set];
    #bench[vec_plus];
    #bench[vec_append];
    #bench[vec_push_all];
}

fn maybe_run_test(argv: [str]/&, name: str, test: fn()) {
    let mut run_test = false;

    if os::getenv("RUST_BENCH").is_some() { run_test = true }
    else if argv.len() > 0 {
        run_test = argv.contains("all") || argv.contains(name)
    }

    if !run_test { ret }

    let start = precise_time_s();
    test();
    let stop = precise_time_s();

    io::println(#fmt("%s:\t\t%f ms", name, (stop - start) * 1000f));
}

fn shift_push() {
    let mut v1 = vec::from_elem(30000, 1);
    let mut v2 = []/~;

    while v1.len() > 0 {
        vec::push(v2, vec::shift(v1));
    }
}

fn read_line() {
    let path = path::connect(
        #env("CFG_SRC_DIR"),
        "src/test/bench/shootout-k-nucleotide.data"
    );

    for int::range(0, 3) {|_i|
        let reader = result::get(io::file_reader(path));
        while !reader.eof() {
            reader.read_line();
        }
    }
}

fn str_set() {
    let r = rand::rng();

    let s = map::hashmap(str::hash, str::eq);

    for int::range(0, 1000) {|_i|
        map::set_add(s, r.gen_str(10));
    }

    let mut found = 0;
    for int::range(0, 1000) {|_i|
        alt s.find(r.gen_str(10)) {
          some(_) { found += 1; }
          none { }
        }
    }
}

fn vec_plus() {
    let r = rand::rng();

    let mut v = []/~;
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            v += rv;
        }
        else {
            v = rv + v;
        }
        i += 1;
    }
}

fn vec_append() {
    let r = rand::rng();

    let mut v = []/~;
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            v = vec::append(v, rv);
        }
        else {
            v = vec::append(rv, v);
        }
        i += 1;
    }
}

fn vec_push_all() {
    let r = rand::rng();

    let mut v = []/~;
    for uint::range(0, 1500) {|i|
        let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen_bool() {
            vec::push_all(v, rv);
        }
        else {
            v <-> rv;
            vec::push_all(v, rv);
        }
    }
}
<|endoftext|>