<commit_before>// Copyright 2014 The Gfx-rs 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::HashSet;
use std::ffi;
use std::fmt;
use std::mem;
use std::str;
use super::gl;

use gfx::device::Capabilities;
use gfx::device::shade;

/// A version number for a specific component of an OpenGL implementation
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Version {
    pub major: u32,
    pub minor: u32,
    pub revision: Option<u32>,
    pub vendor_info: &'static str,
}

// FIXME https://github.com/rust-lang/rust/issues/18738
// derive

#[automatically_derived]
impl ::std::cmp::Ord for Version {
    #[inline]
    fn cmp(&self, other: &Version) -> ::std::cmp::Ordering {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}
#[automatically_derived]
impl ::std::cmp::PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> ::std::option::Option<::std::cmp::Ordering> {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .partial_cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}

impl Version {
    /// Create a new OpenGL version number
    pub fn new(major: u32, minor: u32, revision: Option<u32>,
               vendor_info: &'static str) -> Version {
        Version {
            major: major,
            minor: minor,
            revision: revision,
            vendor_info: vendor_info,
        }
    }

    /// According to the OpenGL specification, the version information is
    /// expected to follow the following syntax:
    ///
    /// ~~~bnf
    /// <major>       ::= <number>
    /// <minor>       ::= <number>
    /// <revision>    ::= <number>
    /// <vendor-info> ::= <string>
    /// <release>     ::= <major> "." <minor> ["." <release>]
    /// <version>     ::= <release> [" " <vendor-info>]
    /// ~~~
    ///
    /// Note that this function is intentionally lenient in regards to parsing,
    /// and will try to recover at least the first two version numbers without
    /// resulting in an `Err`.
    pub fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = match src.find(' ') {
            Some(i) => (&src[..i], &src[(i + 1)..]),
            None => (src, ""),
        };

        // TODO: make this even more lenient so that we can also accept
        // `<major> "." <minor> [<???>]`
        let mut it = version.split('.');
        let major = it.next().and_then(|s| s.parse().ok());
        let minor = it.next().and_then(|s| s.parse().ok());
        let revision = it.next().and_then(|s| s.parse().ok());

        match (major, minor, revision) {
            (Some(major), Some(minor), revision) => Ok(Version {
                major: major,
                minor: minor,
                revision: revision,
                vendor_info: vendor_info,
            }),
            (_, _, _) => Err(src),
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match (self.major, self.minor, self.revision, self.vendor_info) {
            (major, minor, Some(revision), "") =>
                write!(f, "{}.{}.{}", major, minor, revision),
            (major, minor, None, "") =>
                write!(f, "{}.{}", major, minor),
            (major, minor, Some(revision), vendor_info) =>
                write!(f, "{}.{}.{}, {}", major, minor, revision, vendor_info),
            (major, minor, None, vendor_info) =>
                write!(f, "{}.{}, {}", major, minor, vendor_info),
        }
    }
}

const EMPTY_STRING: &'static str = "";

/// Get a statically allocated string from the implementation using
/// `glGetString`. Fails if it `GLenum` cannot be handled by the
/// implementation's `gl.GetString` function.
fn get_string(gl: &gl::Gl, name: gl::types::GLenum) -> &'static str {
    let ptr = unsafe { gl.GetString(name) } as *const i8;
    if !ptr.is_null() {
        // This should be safe to mark as statically allocated because
        // GlGetString only returns static strings.
        unsafe { c_str_as_static_str(ptr) }
    } else {
        error!("Invalid GLenum passed to `get_string`: {:x}", name);
        EMPTY_STRING
    }
}

fn get_usize(gl: &gl::Gl, name: gl::types::GLenum) -> usize {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl.GetIntegerv(name, &mut value) };
    value as usize
}

unsafe fn c_str_as_static_str(c_str: *const i8) -> &'static str {
    mem::transmute(str::from_utf8(ffi::CStr::from_ptr(c_str).to_bytes()).unwrap())
}

/// A unique platform identifier that does not change between releases
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct PlatformName {
    /// The company responsible for the OpenGL implementation
    pub vendor: &'static str,
    /// The name of the renderer
    pub renderer: &'static str,
}

impl PlatformName {
    fn get(gl: &gl::Gl) -> PlatformName {
        PlatformName {
            vendor: get_string(gl, gl::VENDOR),
            renderer: get_string(gl, gl::RENDERER),
        }
    }
}

/// OpenGL implementation information
#[derive(Debug)]
pub struct Info {
    /// The platform identifier
    pub platform_name: PlatformName,
    /// The OpenGL API vesion number
    pub version: Version,
    /// The GLSL vesion number
    pub shading_language: Version,
    /// The extensions supported by the implementation
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn get(gl: &gl::Gl) -> Info {
        let platform_name = PlatformName::get(gl);
        let version = Version::parse(get_string(gl, gl::VERSION)).unwrap();
        let shading_language = Version::parse(get_string(gl, gl::SHADING_LANGUAGE_VERSION)).unwrap();
        let extensions = if version >= Version::new(3, 2, None, "") {
            let num_exts = get_usize(gl, gl::NUM_EXTENSIONS) as gl::types::GLuint;
            (0..num_exts)
                .map(|i| unsafe { c_str_as_static_str(gl.GetStringi(gl::EXTENSIONS, i) as *const i8) })
                .collect()
        } else {
            // Fallback
            get_string(gl, gl::EXTENSIONS).split(' ').collect()
        };
        Info {
            platform_name: platform_name,
            version: version,
            shading_language: shading_language,
            extensions: extensions,
        }
    }

    /// Returns `true` if the implementation supports the extension
    pub fn is_extension_supported(&self, s: &'static str) -> bool {
        self.extensions.contains(&s)
    }

    pub fn is_version_or_extension_supported(&self, major: u32, minor: u32, ext: &'static str) -> bool {
        self.version >= Version::new(major, minor, None, "") || self.is_extension_supported(ext)
    }
}

fn to_shader_model(v: &Version) -> shade::ShaderModel {
    use gfx::device::shade::ShaderModel;
    match v {
        v if *v < Version::new(1, 20, None, "") => ShaderModel::Unsupported,
        v if *v < Version::new(1, 50, None, "") => ShaderModel::Version30,
        v if *v < Version::new(3,  0, None, "") => ShaderModel::Version40,
        v if *v < Version::new(4, 30, None, "") => ShaderModel::Version41,
        _                                       => ShaderModel::Version50,
    }
}

/// Load the information pertaining to the driver and the corresponding device
/// capabilities.
pub fn get(gl: &gl::Gl) -> (Info, Capabilities) {
    let info = Info::get(gl);
    let caps = Capabilities {
        shader_model:                   to_shader_model(&info.shading_language),

        max_vertex_count:               get_usize(gl, gl::MAX_ELEMENTS_VERTICES),
        max_index_count:                get_usize(gl, gl::MAX_ELEMENTS_INDICES),
        max_draw_buffers:               get_usize(gl, gl::MAX_DRAW_BUFFERS),
        max_texture_size:               get_usize(gl, gl::MAX_TEXTURE_SIZE),
        max_vertex_attributes:          get_usize(gl, gl::MAX_VERTEX_ATTRIBS),

        buffer_role_change_allowed:     true, //TODO

        array_buffer_supported:         info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
        fragment_output_supported:      info.is_version_or_extension_supported(3, 0, "GL_EXT_gpu_shader4"),
        immutable_storage_supported:    info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
        instance_base_supported:        info.is_version_or_extension_supported(4, 2, "GL_ARB_base_instance"),
        instance_call_supported:        info.is_version_or_extension_supported(3, 1, "GL_ARB_draw_instanced"),
        instance_rate_supported:        info.is_version_or_extension_supported(3, 3, "GL_ARB_instanced_arrays"),
        render_targets_supported:       info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object"),
        srgb_color_supported:           info.is_version_or_extension_supported(3, 2, "GL_ARB_framebuffer_sRGB"),
        sampler_objects_supported:      info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
        uniform_block_supported:        info.is_version_or_extension_supported(3, 0, "GL_ARB_uniform_buffer_object"),
        vertex_base_supported:          info.is_version_or_extension_supported(3, 2, "GL_ARB_draw_elements_base_vertex"),
    };
    (info, caps)
}

#[cfg(test)]
mod tests {
    use super::Version;
    use super::to_shader_model;

    #[test]
    fn test_version_parse() {
        assert_eq!(Version::parse("1"), Err("1"));
        assert_eq!(Version::parse("1."), Err("1."));
        assert_eq!(Version::parse("1 h3l1o. W0rld"), Err("1 h3l1o. W0rld"));
        assert_eq!(Version::parse("1. h3l1o. W0rld"), Err("1. h3l1o. W0rld"));
        assert_eq!(Version::parse("1.2.3"), Ok(Version::new(1, 2, Some(3), "")));
        assert_eq!(Version::parse("1.2"), Ok(Version::new(1, 2, None, "")));
        assert_eq!(Version::parse("1.2 h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.h3l1o. W0rld"), Ok(Version::new(1, 2, None, "W0rld")));
        assert_eq!(Version::parse("1.2. h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.3.h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "W0rld")));
        assert_eq!(Version::parse("1.2.3 h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "h3l1o. W0rld")));
    }

    #[test]
    fn test_shader_model() {
        use gfx::device::shade::ShaderModel;
        assert_eq!(to_shader_model(&Version::parse("1.10").unwrap()), ShaderModel::Unsupported);
        assert_eq!(to_shader_model(&Version::parse("1.20").unwrap()), ShaderModel::Version30);
        assert_eq!(to_shader_model(&Version::parse("1.50").unwrap()), ShaderModel::Version40);
        assert_eq!(to_shader_model(&Version::parse("3.00").unwrap()), ShaderModel::Version41);
        assert_eq!(to_shader_model(&Version::parse("4.30").unwrap()), ShaderModel::Version50);
    }
}
<commit_msg>Use glGetStringi to get extensions on OpenGL 3.0+<commit_after>// Copyright 2014 The Gfx-rs 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::HashSet;
use std::ffi;
use std::fmt;
use std::mem;
use std::str;
use super::gl;

use gfx::device::Capabilities;
use gfx::device::shade;

/// A version number for a specific component of an OpenGL implementation
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Version {
    pub major: u32,
    pub minor: u32,
    pub revision: Option<u32>,
    pub vendor_info: &'static str,
}

// FIXME https://github.com/rust-lang/rust/issues/18738
// derive

#[automatically_derived]
impl ::std::cmp::Ord for Version {
    #[inline]
    fn cmp(&self, other: &Version) -> ::std::cmp::Ordering {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}
#[automatically_derived]
impl ::std::cmp::PartialOrd for Version {
    #[inline]
    fn partial_cmp(&self, other: &Version) -> ::std::option::Option<::std::cmp::Ordering> {
        (&self.major, &self.minor, &self.revision, self.vendor_info)
            .partial_cmp(&(&other.major, &other.minor, &other.revision, other.vendor_info))
    }
}

impl Version {
    /// Create a new OpenGL version number
    pub fn new(major: u32, minor: u32, revision: Option<u32>,
               vendor_info: &'static str) -> Version {
        Version {
            major: major,
            minor: minor,
            revision: revision,
            vendor_info: vendor_info,
        }
    }

    /// According to the OpenGL specification, the version information is
    /// expected to follow the following syntax:
    ///
    /// ~~~bnf
    /// <major>       ::= <number>
    /// <minor>       ::= <number>
    /// <revision>    ::= <number>
    /// <vendor-info> ::= <string>
    /// <release>     ::= <major> "." <minor> ["." <release>]
    /// <version>     ::= <release> [" " <vendor-info>]
    /// ~~~
    ///
    /// Note that this function is intentionally lenient in regards to parsing,
    /// and will try to recover at least the first two version numbers without
    /// resulting in an `Err`.
    pub fn parse(src: &'static str) -> Result<Version, &'static str> {
        let (version, vendor_info) = match src.find(' ') {
            Some(i) => (&src[..i], &src[(i + 1)..]),
            None => (src, ""),
        };

        // TODO: make this even more lenient so that we can also accept
        // `<major> "." <minor> [<???>]`
        let mut it = version.split('.');
        let major = it.next().and_then(|s| s.parse().ok());
        let minor = it.next().and_then(|s| s.parse().ok());
        let revision = it.next().and_then(|s| s.parse().ok());

        match (major, minor, revision) {
            (Some(major), Some(minor), revision) => Ok(Version {
                major: major,
                minor: minor,
                revision: revision,
                vendor_info: vendor_info,
            }),
            (_, _, _) => Err(src),
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match (self.major, self.minor, self.revision, self.vendor_info) {
            (major, minor, Some(revision), "") =>
                write!(f, "{}.{}.{}", major, minor, revision),
            (major, minor, None, "") =>
                write!(f, "{}.{}", major, minor),
            (major, minor, Some(revision), vendor_info) =>
                write!(f, "{}.{}.{}, {}", major, minor, revision, vendor_info),
            (major, minor, None, vendor_info) =>
                write!(f, "{}.{}, {}", major, minor, vendor_info),
        }
    }
}

const EMPTY_STRING: &'static str = "";

/// Get a statically allocated string from the implementation using
/// `glGetString`. Fails if it `GLenum` cannot be handled by the
/// implementation's `gl.GetString` function.
fn get_string(gl: &gl::Gl, name: gl::types::GLenum) -> &'static str {
    let ptr = unsafe { gl.GetString(name) } as *const i8;
    if !ptr.is_null() {
        // This should be safe to mark as statically allocated because
        // GlGetString only returns static strings.
        unsafe { c_str_as_static_str(ptr) }
    } else {
        error!("Invalid GLenum passed to `get_string`: {:x}", name);
        EMPTY_STRING
    }
}

fn get_usize(gl: &gl::Gl, name: gl::types::GLenum) -> usize {
    let mut value = 0 as gl::types::GLint;
    unsafe { gl.GetIntegerv(name, &mut value) };
    value as usize
}

unsafe fn c_str_as_static_str(c_str: *const i8) -> &'static str {
    mem::transmute(str::from_utf8(ffi::CStr::from_ptr(c_str).to_bytes()).unwrap())
}

/// A unique platform identifier that does not change between releases
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct PlatformName {
    /// The company responsible for the OpenGL implementation
    pub vendor: &'static str,
    /// The name of the renderer
    pub renderer: &'static str,
}

impl PlatformName {
    fn get(gl: &gl::Gl) -> PlatformName {
        PlatformName {
            vendor: get_string(gl, gl::VENDOR),
            renderer: get_string(gl, gl::RENDERER),
        }
    }
}

/// OpenGL implementation information
#[derive(Debug)]
pub struct Info {
    /// The platform identifier
    pub platform_name: PlatformName,
    /// The OpenGL API vesion number
    pub version: Version,
    /// The GLSL vesion number
    pub shading_language: Version,
    /// The extensions supported by the implementation
    pub extensions: HashSet<&'static str>,
}

impl Info {
    fn get(gl: &gl::Gl) -> Info {
        let platform_name = PlatformName::get(gl);
        let version = Version::parse(get_string(gl, gl::VERSION)).unwrap();
        let shading_language = Version::parse(get_string(gl, gl::SHADING_LANGUAGE_VERSION)).unwrap();
        let extensions = if version >= Version::new(3, 0, None, "") {
            let num_exts = get_usize(gl, gl::NUM_EXTENSIONS) as gl::types::GLuint;
            (0..num_exts)
                .map(|i| unsafe { c_str_as_static_str(gl.GetStringi(gl::EXTENSIONS, i) as *const i8) })
                .collect()
        } else {
            // Fallback
            get_string(gl, gl::EXTENSIONS).split(' ').collect()
        };
        Info {
            platform_name: platform_name,
            version: version,
            shading_language: shading_language,
            extensions: extensions,
        }
    }

    /// Returns `true` if the implementation supports the extension
    pub fn is_extension_supported(&self, s: &'static str) -> bool {
        self.extensions.contains(&s)
    }

    pub fn is_version_or_extension_supported(&self, major: u32, minor: u32, ext: &'static str) -> bool {
        self.version >= Version::new(major, minor, None, "") || self.is_extension_supported(ext)
    }
}

fn to_shader_model(v: &Version) -> shade::ShaderModel {
    use gfx::device::shade::ShaderModel;
    match v {
        v if *v < Version::new(1, 20, None, "") => ShaderModel::Unsupported,
        v if *v < Version::new(1, 50, None, "") => ShaderModel::Version30,
        v if *v < Version::new(3,  0, None, "") => ShaderModel::Version40,
        v if *v < Version::new(4, 30, None, "") => ShaderModel::Version41,
        _                                       => ShaderModel::Version50,
    }
}

/// Load the information pertaining to the driver and the corresponding device
/// capabilities.
pub fn get(gl: &gl::Gl) -> (Info, Capabilities) {
    let info = Info::get(gl);
    let caps = Capabilities {
        shader_model:                   to_shader_model(&info.shading_language),

        max_vertex_count:               get_usize(gl, gl::MAX_ELEMENTS_VERTICES),
        max_index_count:                get_usize(gl, gl::MAX_ELEMENTS_INDICES),
        max_draw_buffers:               get_usize(gl, gl::MAX_DRAW_BUFFERS),
        max_texture_size:               get_usize(gl, gl::MAX_TEXTURE_SIZE),
        max_vertex_attributes:          get_usize(gl, gl::MAX_VERTEX_ATTRIBS),

        buffer_role_change_allowed:     true, //TODO

        array_buffer_supported:         info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
        fragment_output_supported:      info.is_version_or_extension_supported(3, 0, "GL_EXT_gpu_shader4"),
        immutable_storage_supported:    info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
        instance_base_supported:        info.is_version_or_extension_supported(4, 2, "GL_ARB_base_instance"),
        instance_call_supported:        info.is_version_or_extension_supported(3, 1, "GL_ARB_draw_instanced"),
        instance_rate_supported:        info.is_version_or_extension_supported(3, 3, "GL_ARB_instanced_arrays"),
        render_targets_supported:       info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object"),
        srgb_color_supported:           info.is_version_or_extension_supported(3, 2, "GL_ARB_framebuffer_sRGB"),
        sampler_objects_supported:      info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
        uniform_block_supported:        info.is_version_or_extension_supported(3, 0, "GL_ARB_uniform_buffer_object"),
        vertex_base_supported:          info.is_version_or_extension_supported(3, 2, "GL_ARB_draw_elements_base_vertex"),
    };
    (info, caps)
}

#[cfg(test)]
mod tests {
    use super::Version;
    use super::to_shader_model;

    #[test]
    fn test_version_parse() {
        assert_eq!(Version::parse("1"), Err("1"));
        assert_eq!(Version::parse("1."), Err("1."));
        assert_eq!(Version::parse("1 h3l1o. W0rld"), Err("1 h3l1o. W0rld"));
        assert_eq!(Version::parse("1. h3l1o. W0rld"), Err("1. h3l1o. W0rld"));
        assert_eq!(Version::parse("1.2.3"), Ok(Version::new(1, 2, Some(3), "")));
        assert_eq!(Version::parse("1.2"), Ok(Version::new(1, 2, None, "")));
        assert_eq!(Version::parse("1.2 h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.h3l1o. W0rld"), Ok(Version::new(1, 2, None, "W0rld")));
        assert_eq!(Version::parse("1.2. h3l1o. W0rld"), Ok(Version::new(1, 2, None, "h3l1o. W0rld")));
        assert_eq!(Version::parse("1.2.3.h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "W0rld")));
        assert_eq!(Version::parse("1.2.3 h3l1o. W0rld"), Ok(Version::new(1, 2, Some(3), "h3l1o. W0rld")));
    }

    #[test]
    fn test_shader_model() {
        use gfx::device::shade::ShaderModel;
        assert_eq!(to_shader_model(&Version::parse("1.10").unwrap()), ShaderModel::Unsupported);
        assert_eq!(to_shader_model(&Version::parse("1.20").unwrap()), ShaderModel::Version30);
        assert_eq!(to_shader_model(&Version::parse("1.50").unwrap()), ShaderModel::Version40);
        assert_eq!(to_shader_model(&Version::parse("3.00").unwrap()), ShaderModel::Version41);
        assert_eq!(to_shader_model(&Version::parse("4.30").unwrap()), ShaderModel::Version50);
    }
}
<|endoftext|>


<commit_before><commit_msg>Adds benches for blake2b_single_block<commit_after><|endoftext|>


<commit_before><commit_msg>add Token type<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Implemented Insertion Sort in Rust<commit_after><|endoftext|>


<commit_before><commit_msg>2019: Day 2, part 1.<commit_after>use std::io;

type Code = usize;
type Codes = Vec<Code>;

fn main() -> io::Result<()> {
    let mut input: String = String::new();
    io::stdin().read_line(&mut input)?;

    let mut codes: Codes = input
        .trim()
        .split(",")
        .map(|code| {
            code.parse::<Code>()
                .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
        })
        .collect::<io::Result<_>>()?;

    codes[1] = 12;
    codes[2] = 2;

    let mut position = 0;

    loop {
        match codes[position] {
            1 => {
                operate(&mut codes, position, |a, b| a + b);
                position += 4;
            }
            2 => {
                operate(&mut codes, position, |a, b| a * b);
                position += 4;
            }
            99 => break,
            invalid => panic!("Invalid opcode: {}", invalid),
        }
    }

    println!("{}", codes[0]);

    Ok(())
}

fn operate<Op>(codes: &mut Codes, position: Code, op: Op)
where
    Op: Fn(Code, Code) -> Code,
{
    let a_position = codes[position + 1];
    let a = codes[a_position];
    let b_position = codes[position + 2];
    let b = codes[b_position];
    let destination = codes[position + 3];
    codes[destination] = op(a, b);
}
<|endoftext|>


<commit_before><commit_msg>Refactor the ids command<commit_after><|endoftext|>


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

use build::{Location, ScopeAuxiliaryVec};
use rustc::hir;
use rustc::mir::repr::*;
use rustc::mir::transform::MirSource;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fnv::FnvHashMap;
use std::fmt::Display;
use std::fs;
use std::io::{self, Write};
use syntax::ast::NodeId;
use syntax::codemap::Span;

const INDENT: &'static str = "    ";
/// Alignment for lining up comments following MIR statements
const ALIGN: usize = 40;

/// If the session is properly configured, dumps a human-readable
/// representation of the mir into:
///
/// ```text
/// rustc.node<node_id>.<pass_name>.<disambiguator>
/// ```
///
/// Output from this function is controlled by passing `-Z dump-mir=<filter>`,
/// where `<filter>` takes the following forms:
///
/// - `all` -- dump MIR for all fns, all passes, all everything
/// - `substring1&substring2,...` -- `&`-separated list of substrings
///   that can appear in the pass-name or the `item_path_str` for the given
///   node-id. If any one of the substrings match, the data is dumped out.
pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          pass_name: &str,
                          disambiguator: &Display,
                          src: MirSource,
                          mir: &Mir<'tcx>,
                          auxiliary: Option<&ScopeAuxiliaryVec>) {
    let filters = match tcx.sess.opts.debugging_opts.dump_mir {
        None => return,
        Some(ref filters) => filters,
    };
    let node_id = src.item_id();
    let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
    let is_matched =
        filters.split("&")
               .any(|filter| {
                   filter == "all" ||
                       pass_name.contains(filter) ||
                       node_path.contains(filter)
               });
    if !is_matched {
        return;
    }

    let file_name = format!("rustc.node{}.{}.{}.mir",
                            node_id, pass_name, disambiguator);
    let _ = fs::File::create(&file_name).and_then(|mut file| {
        try!(writeln!(file, "// MIR for `{}`", node_path));
        try!(writeln!(file, "// node_id = {}", node_id));
        try!(writeln!(file, "// pass_name = {}", pass_name));
        try!(writeln!(file, "// disambiguator = {}", disambiguator));
        try!(writeln!(file, ""));
        try!(write_mir_fn(tcx, src, mir, &mut file, auxiliary));
        Ok(())
    });
}

/// Write out a human-readable textual representation for the given MIR.
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                         iter: I,
                                         w: &mut Write)
                                         -> io::Result<()>
    where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
{
    let mut first = true;
    for (&id, mir) in iter {
        if first {
            first = false;
        } else {
            // Put empty lines between all items
            writeln!(w, "")?;
        }

        let src = MirSource::from_node(tcx, id);
        write_mir_fn(tcx, src, mir, w, None)?;

        for (i, mir) in mir.promoted.iter().enumerate() {
            writeln!(w, "")?;
            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?;
        }
    }
    Ok(())
}

enum Annotation {
    EnterScope(ScopeId),
    ExitScope(ScopeId),
}

pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              src: MirSource,
                              mir: &Mir<'tcx>,
                              w: &mut Write,
                              auxiliary: Option<&ScopeAuxiliaryVec>)
                              -> io::Result<()> {
    // compute scope/entry exit annotations
    let mut annotations = FnvHashMap();
    if let Some(auxiliary) = auxiliary {
        for (index, auxiliary) in auxiliary.vec.iter().enumerate() {
            let scope_id = ScopeId::new(index);

            annotations.entry(auxiliary.dom)
                       .or_insert(vec![])
                       .push(Annotation::EnterScope(scope_id));

            for &loc in &auxiliary.postdoms {
                annotations.entry(loc)
                           .or_insert(vec![])
                           .push(Annotation::ExitScope(scope_id));
            }
        }
    }

    write_mir_intro(tcx, src, mir, w)?;
    for block in mir.all_basic_blocks() {
        write_basic_block(tcx, block, mir, w, &annotations)?;
    }

    // construct a scope tree and write it out
    let mut scope_tree: FnvHashMap<Option<ScopeId>, Vec<ScopeId>> = FnvHashMap();
    for (index, scope_data) in mir.scopes.iter().enumerate() {
        scope_tree.entry(scope_data.parent_scope)
                  .or_insert(vec![])
                  .push(ScopeId::new(index));
    }

    writeln!(w, "{}scope tree:", INDENT)?;
    write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?;
    writeln!(w, "")?;

    writeln!(w, "}}")?;
    Ok(())
}

/// Write out a human-readable textual representation for the given basic block.
fn write_basic_block(tcx: TyCtxt,
                     block: BasicBlock,
                     mir: &Mir,
                     w: &mut Write,
                     annotations: &FnvHashMap<Location, Vec<Annotation>>)
                     -> io::Result<()> {
    let data = mir.basic_block_data(block);

    // Basic block label at the top.
    writeln!(w, "{}{:?}: {{", INDENT, block)?;

    // List of statements in the middle.
    let mut current_location = Location { block: block, statement_index: 0 };
    for statement in &data.statements {
        if let Some(ref annotations) = annotations.get(&current_location) {
            for annotation in annotations.iter() {
                match *annotation {
                    Annotation::EnterScope(id) =>
                        writeln!(w, "{0}{0}// Enter Scope({1})",
                                 INDENT, id.index())?,
                    Annotation::ExitScope(id) =>
                        writeln!(w, "{0}{0}// Exit Scope({1})",
                                 INDENT, id.index())?,
                }
            }
        }

        let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
        writeln!(w, "{0:1$} // {2}",
                 indented_mir,
                 ALIGN,
                 comment(tcx, statement.scope, statement.span))?;

        current_location.statement_index += 1;
    }

    // Terminator at the bottom.
    let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
    writeln!(w, "{0:1$} // {2}",
             indented_terminator,
             ALIGN,
             comment(tcx, data.terminator().scope, data.terminator().span))?;

    writeln!(w, "{}}}\n", INDENT)
}

fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
    format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
}

fn write_scope_tree(tcx: TyCtxt,
                    mir: &Mir,
                    auxiliary: Option<&ScopeAuxiliaryVec>,
                    scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>,
                    w: &mut Write,
                    parent: Option<ScopeId>,
                    depth: usize,
                    same_line: bool)
                    -> io::Result<()> {
    let indent = if same_line {
        0
    } else {
        depth * INDENT.len()
    };

    let children = match scope_tree.get(&parent) {
        Some(childs) => childs,
        None => return Ok(()),
    };

    for (index, &child) in children.iter().enumerate() {
        if index == 0 && same_line {
            // We know we're going to output a scope, so prefix it with a space to separate it from
            // the previous scopes on this line
            write!(w, " ")?;
        }

        let data = &mir.scopes[child];
        assert_eq!(data.parent_scope, parent);
        write!(w, "{0:1$}{2}", "", indent, child.index())?;

        let indent = indent + INDENT.len();

        if let Some(auxiliary) = auxiliary {
            let extent = auxiliary[child].extent;
            let data = tcx.region_maps.code_extent_data(extent);
            writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?;
        }

        let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0);
        if child_count < 2 {
            // Skip the braces when there's no or only a single subscope
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth, true)?;
        } else {
            // 2 or more child scopes? Put them in braces and on new lines.
            writeln!(w, " {{")?;
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth + 1, false)?;

            write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?;
        }

        if !same_line && index + 1 < children.len() {
            writeln!(w, "")?;
        }
    }

    Ok(())
}

/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
/// local variables (both user-defined bindings and compiler temporaries).
fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             src: MirSource,
                             mir: &Mir,
                             w: &mut Write)
                             -> io::Result<()> {
    match src {
        MirSource::Fn(_) => write!(w, "fn")?,
        MirSource::Const(_) => write!(w, "const")?,
        MirSource::Static(_, hir::MutImmutable) => write!(w, "static")?,
        MirSource::Static(_, hir::MutMutable) => write!(w, "static mut")?,
        MirSource::Promoted(_, i) => write!(w, "promoted{} in", i)?
    }

    write!(w, " {}", tcx.node_path_str(src.item_id()))?;

    if let MirSource::Fn(_) = src {
        write!(w, "(")?;

        // fn argument types.
        for (i, arg) in mir.arg_decls.iter().enumerate() {
            if i > 0 {
                write!(w, ", ")?;
            }
            write!(w, "{:?}: {}", Lvalue::Arg(i as u32), arg.ty)?;
        }

        write!(w, ") -> ")?;

        // fn return type.
        match mir.return_ty {
            ty::FnOutput::FnConverging(ty) => write!(w, "{}", ty)?,
            ty::FnOutput::FnDiverging => write!(w, "!")?,
        }
    } else {
        assert!(mir.arg_decls.is_empty());
        write!(w, ": {} =", mir.return_ty.unwrap())?;
    }

    writeln!(w, " {{")?;

    // User variable types (including the user's name in a comment).
    for (i, var) in mir.var_decls.iter().enumerate() {
        let mut_str = if var.mutability == Mutability::Mut {
            "mut "
        } else {
            ""
        };

        let indented_var = format!("{}let {}{:?}: {};",
                                   INDENT,
                                   mut_str,
                                   Lvalue::Var(i as u32),
                                   var.ty);
        writeln!(w, "{0:1$} // \"{2}\" in {3}",
                 indented_var,
                 ALIGN,
                 var.name,
                 comment(tcx, var.scope, var.span))?;
    }

    // Compiler-introduced temporary types.
    for (i, temp) in mir.temp_decls.iter().enumerate() {
        writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?;
    }

    // Wrote any declaration? Add an empty line before the first block is printed.
    if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() {
        writeln!(w, "")?;
    }

    Ok(())
}
<commit_msg>`rustc_mir::pretty`: factor out scope entry/exit annotation computation.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use build::{Location, ScopeAuxiliaryVec};
use rustc::hir;
use rustc::mir::repr::*;
use rustc::mir::transform::MirSource;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fnv::FnvHashMap;
use std::fmt::Display;
use std::fs;
use std::io::{self, Write};
use syntax::ast::NodeId;
use syntax::codemap::Span;

const INDENT: &'static str = "    ";
/// Alignment for lining up comments following MIR statements
const ALIGN: usize = 40;

/// If the session is properly configured, dumps a human-readable
/// representation of the mir into:
///
/// ```text
/// rustc.node<node_id>.<pass_name>.<disambiguator>
/// ```
///
/// Output from this function is controlled by passing `-Z dump-mir=<filter>`,
/// where `<filter>` takes the following forms:
///
/// - `all` -- dump MIR for all fns, all passes, all everything
/// - `substring1&substring2,...` -- `&`-separated list of substrings
///   that can appear in the pass-name or the `item_path_str` for the given
///   node-id. If any one of the substrings match, the data is dumped out.
pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          pass_name: &str,
                          disambiguator: &Display,
                          src: MirSource,
                          mir: &Mir<'tcx>,
                          auxiliary: Option<&ScopeAuxiliaryVec>) {
    let filters = match tcx.sess.opts.debugging_opts.dump_mir {
        None => return,
        Some(ref filters) => filters,
    };
    let node_id = src.item_id();
    let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
    let is_matched =
        filters.split("&")
               .any(|filter| {
                   filter == "all" ||
                       pass_name.contains(filter) ||
                       node_path.contains(filter)
               });
    if !is_matched {
        return;
    }

    let file_name = format!("rustc.node{}.{}.{}.mir",
                            node_id, pass_name, disambiguator);
    let _ = fs::File::create(&file_name).and_then(|mut file| {
        try!(writeln!(file, "// MIR for `{}`", node_path));
        try!(writeln!(file, "// node_id = {}", node_id));
        try!(writeln!(file, "// pass_name = {}", pass_name));
        try!(writeln!(file, "// disambiguator = {}", disambiguator));
        try!(writeln!(file, ""));
        try!(write_mir_fn(tcx, src, mir, &mut file, auxiliary));
        Ok(())
    });
}

/// Write out a human-readable textual representation for the given MIR.
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                         iter: I,
                                         w: &mut Write)
                                         -> io::Result<()>
    where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
{
    let mut first = true;
    for (&id, mir) in iter {
        if first {
            first = false;
        } else {
            // Put empty lines between all items
            writeln!(w, "")?;
        }

        let src = MirSource::from_node(tcx, id);
        write_mir_fn(tcx, src, mir, w, None)?;

        for (i, mir) in mir.promoted.iter().enumerate() {
            writeln!(w, "")?;
            write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?;
        }
    }
    Ok(())
}

enum Annotation {
    EnterScope(ScopeId),
    ExitScope(ScopeId),
}

fn scope_entry_exit_annotations(auxiliary: Option<&ScopeAuxiliaryVec>)
                                -> FnvHashMap<Location, Vec<Annotation>>
{
    // compute scope/entry exit annotations
    let mut annotations = FnvHashMap();
    if let Some(auxiliary) = auxiliary {
        for (index, auxiliary) in auxiliary.vec.iter().enumerate() {
            let scope_id = ScopeId::new(index);

            annotations.entry(auxiliary.dom)
                       .or_insert(vec![])
                       .push(Annotation::EnterScope(scope_id));

            for &loc in &auxiliary.postdoms {
                annotations.entry(loc)
                           .or_insert(vec![])
                           .push(Annotation::ExitScope(scope_id));
            }
        }
    }
    return annotations;
}

pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              src: MirSource,
                              mir: &Mir<'tcx>,
                              w: &mut Write,
                              auxiliary: Option<&ScopeAuxiliaryVec>)
                              -> io::Result<()> {
    let annotations = scope_entry_exit_annotations(auxiliary);
    write_mir_intro(tcx, src, mir, w)?;
    for block in mir.all_basic_blocks() {
        write_basic_block(tcx, block, mir, w, &annotations)?;
    }

    // construct a scope tree and write it out
    let mut scope_tree: FnvHashMap<Option<ScopeId>, Vec<ScopeId>> = FnvHashMap();
    for (index, scope_data) in mir.scopes.iter().enumerate() {
        scope_tree.entry(scope_data.parent_scope)
                  .or_insert(vec![])
                  .push(ScopeId::new(index));
    }

    writeln!(w, "{}scope tree:", INDENT)?;
    write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?;
    writeln!(w, "")?;

    writeln!(w, "}}")?;
    Ok(())
}

/// Write out a human-readable textual representation for the given basic block.
fn write_basic_block(tcx: TyCtxt,
                     block: BasicBlock,
                     mir: &Mir,
                     w: &mut Write,
                     annotations: &FnvHashMap<Location, Vec<Annotation>>)
                     -> io::Result<()> {
    let data = mir.basic_block_data(block);

    // Basic block label at the top.
    writeln!(w, "{}{:?}: {{", INDENT, block)?;

    // List of statements in the middle.
    let mut current_location = Location { block: block, statement_index: 0 };
    for statement in &data.statements {
        if let Some(ref annotations) = annotations.get(&current_location) {
            for annotation in annotations.iter() {
                match *annotation {
                    Annotation::EnterScope(id) =>
                        writeln!(w, "{0}{0}// Enter Scope({1})",
                                 INDENT, id.index())?,
                    Annotation::ExitScope(id) =>
                        writeln!(w, "{0}{0}// Exit Scope({1})",
                                 INDENT, id.index())?,
                }
            }
        }

        let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
        writeln!(w, "{0:1$} // {2}",
                 indented_mir,
                 ALIGN,
                 comment(tcx, statement.scope, statement.span))?;

        current_location.statement_index += 1;
    }

    // Terminator at the bottom.
    let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
    writeln!(w, "{0:1$} // {2}",
             indented_terminator,
             ALIGN,
             comment(tcx, data.terminator().scope, data.terminator().span))?;

    writeln!(w, "{}}}\n", INDENT)
}

fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
    format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
}

fn write_scope_tree(tcx: TyCtxt,
                    mir: &Mir,
                    auxiliary: Option<&ScopeAuxiliaryVec>,
                    scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>,
                    w: &mut Write,
                    parent: Option<ScopeId>,
                    depth: usize,
                    same_line: bool)
                    -> io::Result<()> {
    let indent = if same_line {
        0
    } else {
        depth * INDENT.len()
    };

    let children = match scope_tree.get(&parent) {
        Some(childs) => childs,
        None => return Ok(()),
    };

    for (index, &child) in children.iter().enumerate() {
        if index == 0 && same_line {
            // We know we're going to output a scope, so prefix it with a space to separate it from
            // the previous scopes on this line
            write!(w, " ")?;
        }

        let data = &mir.scopes[child];
        assert_eq!(data.parent_scope, parent);
        write!(w, "{0:1$}{2}", "", indent, child.index())?;

        let indent = indent + INDENT.len();

        if let Some(auxiliary) = auxiliary {
            let extent = auxiliary[child].extent;
            let data = tcx.region_maps.code_extent_data(extent);
            writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?;
        }

        let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0);
        if child_count < 2 {
            // Skip the braces when there's no or only a single subscope
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth, true)?;
        } else {
            // 2 or more child scopes? Put them in braces and on new lines.
            writeln!(w, " {{")?;
            write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
                             Some(child), depth + 1, false)?;

            write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?;
        }

        if !same_line && index + 1 < children.len() {
            writeln!(w, "")?;
        }
    }

    Ok(())
}

/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
/// local variables (both user-defined bindings and compiler temporaries).
fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             src: MirSource,
                             mir: &Mir,
                             w: &mut Write)
                             -> io::Result<()> {
    match src {
        MirSource::Fn(_) => write!(w, "fn")?,
        MirSource::Const(_) => write!(w, "const")?,
        MirSource::Static(_, hir::MutImmutable) => write!(w, "static")?,
        MirSource::Static(_, hir::MutMutable) => write!(w, "static mut")?,
        MirSource::Promoted(_, i) => write!(w, "promoted{} in", i)?
    }

    write!(w, " {}", tcx.node_path_str(src.item_id()))?;

    if let MirSource::Fn(_) = src {
        write!(w, "(")?;

        // fn argument types.
        for (i, arg) in mir.arg_decls.iter().enumerate() {
            if i > 0 {
                write!(w, ", ")?;
            }
            write!(w, "{:?}: {}", Lvalue::Arg(i as u32), arg.ty)?;
        }

        write!(w, ") -> ")?;

        // fn return type.
        match mir.return_ty {
            ty::FnOutput::FnConverging(ty) => write!(w, "{}", ty)?,
            ty::FnOutput::FnDiverging => write!(w, "!")?,
        }
    } else {
        assert!(mir.arg_decls.is_empty());
        write!(w, ": {} =", mir.return_ty.unwrap())?;
    }

    writeln!(w, " {{")?;

    // User variable types (including the user's name in a comment).
    for (i, var) in mir.var_decls.iter().enumerate() {
        let mut_str = if var.mutability == Mutability::Mut {
            "mut "
        } else {
            ""
        };

        let indented_var = format!("{}let {}{:?}: {};",
                                   INDENT,
                                   mut_str,
                                   Lvalue::Var(i as u32),
                                   var.ty);
        writeln!(w, "{0:1$} // \"{2}\" in {3}",
                 indented_var,
                 ALIGN,
                 var.name,
                 comment(tcx, var.scope, var.span))?;
    }

    // Compiler-introduced temporary types.
    for (i, temp) in mir.temp_decls.iter().enumerate() {
        writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?;
    }

    // Wrote any declaration? Add an empty line before the first block is printed.
    if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() {
        writeln!(w, "")?;
    }

    Ok(())
}
<|endoftext|>


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

//! Access to a single thread-local pointer.
//!
//! The runtime will use this for storing ~Task.
//!
//! XXX: Add runtime checks for usage of inconsistent pointer types.
//! and for overwriting an existing pointer.

#[allow(dead_code)];

use cast;
use ops::Drop;

#[cfg(windows)]               // mingw-w32 doesn't like thread_local things
#[cfg(target_os = "android")] // see #10686
pub use self::native::*;

#[cfg(not(windows), not(target_os = "android"))]
pub use self::compiled::*;

/// Encapsulates a borrowed value. When this value goes out of scope, the
/// pointer is returned.
pub struct Borrowed<T> {
    priv val: *(),
}

#[unsafe_destructor]
impl<T> Drop for Borrowed<T> {
    fn drop(&mut self) {
        unsafe {
            if self.val.is_null() {
                rtabort!("Aiee, returning null borrowed object!");
            }
            let val: ~T = cast::transmute(self.val);
            put::<T>(val);
            assert!(exists());
        }
    }
}

impl<T> Borrowed<T> {
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        unsafe {
            let val_ptr: &mut ~T = cast::transmute(&mut self.val);
            let val_ptr: &'a mut T = *val_ptr;
            val_ptr
        }
    }
}

/// Borrow the thread-local value from thread-local storage.
/// While the value is borrowed it is not available in TLS.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn borrow<T>() -> Borrowed<T> {
    let val: *() = cast::transmute(take::<T>());
    Borrowed {
        val: val,
    }
}

/// Compiled implementation of accessing the runtime local pointer. This is
/// implemented using LLVM's thread_local attribute which isn't necessarily
/// working on all platforms. This implementation is faster, however, so we use
/// it wherever possible.
#[cfg(not(windows), not(target_os = "android"))]
pub mod compiled {
    use cast;
    use option::{Option, Some, None};
    #[cfg(not(test))] use libc::c_void;

    #[cfg(test)]
    pub use realstd::rt::shouldnt_be_public::RT_TLS_PTR;

    #[cfg(not(test))]
    #[thread_local]
    pub static mut RT_TLS_PTR: *mut c_void = 0 as *mut c_void;

    pub fn init() {}

    pub unsafe fn cleanup() {}

    /// Give a pointer to thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn put<T>(sched: ~T) {
        RT_TLS_PTR = cast::transmute(sched)
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn take<T>() -> ~T {
        let ptr: ~T = cast::transmute(RT_TLS_PTR);
        // can't use `as`, due to type not matching with `cfg(test)`
        RT_TLS_PTR = cast::transmute(0);
        ptr
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    /// Leaves the old pointer in TLS for speed.
    #[inline]
    pub unsafe fn unsafe_take<T>() -> ~T {
        cast::transmute(RT_TLS_PTR)
    }

    /// Check whether there is a thread-local pointer installed.
    pub fn exists() -> bool {
        unsafe {
            RT_TLS_PTR.is_not_null()
        }
    }

    pub unsafe fn unsafe_borrow<T>() -> *mut T {
        if RT_TLS_PTR.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        RT_TLS_PTR as *mut T
    }

    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
        if RT_TLS_PTR.is_null() {
            None
        } else {
            Some(RT_TLS_PTR as *mut T)
        }
    }
}

/// Native implementation of having the runtime thread-local pointer. This
/// implementation uses the `thread_local_storage` module to provide a
/// thread-local value.
pub mod native {
    use cast;
    use libc::c_void;
    use option::{Option, Some, None};
    use ptr;
    use tls = rt::thread_local_storage;
    use unstable::mutex::{Mutex, MUTEX_INIT};

    static mut LOCK: Mutex = MUTEX_INIT;
    static mut INITIALIZED: bool = false;
    static mut RT_TLS_KEY: tls::Key = -1;

    /// Initialize the TLS key. Other ops will fail if this isn't executed
    /// first.
    pub fn init() {
        unsafe {
            LOCK.lock();
            if !INITIALIZED {
                tls::create(&mut RT_TLS_KEY);
                INITIALIZED = true;
            }
            LOCK.unlock();
        }
    }

    pub unsafe fn cleanup() {
        assert!(INITIALIZED);
        tls::destroy(RT_TLS_KEY);
        LOCK.destroy();
        INITIALIZED = false;
    }

    /// Give a pointer to thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn put<T>(sched: ~T) {
        let key = tls_key();
        let void_ptr: *mut c_void = cast::transmute(sched);
        tls::set(key, void_ptr);
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn take<T>() -> ~T {
        let key = tls_key();
        let void_ptr: *mut c_void = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        let ptr: ~T = cast::transmute(void_ptr);
        tls::set(key, ptr::mut_null());
        return ptr;
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    /// Leaves the old pointer in TLS for speed.
    #[inline]
    pub unsafe fn unsafe_take<T>() -> ~T {
        let key = tls_key();
        let void_ptr: *mut c_void = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        let ptr: ~T = cast::transmute(void_ptr);
        return ptr;
    }

    /// Check whether there is a thread-local pointer installed.
    pub fn exists() -> bool {
        unsafe {
            match maybe_tls_key() {
                Some(key) => tls::get(key).is_not_null(),
                None => false
            }
        }
    }

    /// Borrow a mutable reference to the thread-local value
    ///
    /// # Safety Note
    ///
    /// Because this leaves the value in thread-local storage it is possible
    /// For the Scheduler pointer to be aliased
    pub unsafe fn unsafe_borrow<T>() -> *mut T {
        let key = tls_key();
        let void_ptr = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        void_ptr as *mut T
    }

    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
        match maybe_tls_key() {
            Some(key) => {
                let void_ptr = tls::get(key);
                if void_ptr.is_null() {
                    None
                } else {
                    Some(void_ptr as *mut T)
                }
            }
            None => None
        }
    }

    #[inline]
    fn tls_key() -> tls::Key {
        match maybe_tls_key() {
            Some(key) => key,
            None => rtabort!("runtime tls key not initialized")
        }
    }

    #[inline]
    #[cfg(not(test))]
    pub fn maybe_tls_key() -> Option<tls::Key> {
        unsafe {
            // NB: This is a little racy because, while the key is
            // initalized under a mutex and it's assumed to be initalized
            // in the Scheduler ctor by any thread that needs to use it,
            // we are not accessing the key under a mutex.  Threads that
            // are not using the new Scheduler but still *want to check*
            // whether they are running under a new Scheduler may see a 0
            // value here that is in the process of being initialized in
            // another thread. I think this is fine since the only action
            // they could take if it was initialized would be to check the
            // thread-local value and see that it's not set.
            if RT_TLS_KEY != -1 {
                return Some(RT_TLS_KEY);
            } else {
                return None;
            }
        }
    }

    #[inline] #[cfg(test)]
    pub fn maybe_tls_key() -> Option<tls::Key> {
        use realstd;
        unsafe {
            cast::transmute(realstd::rt::shouldnt_be_public::maybe_tls_key())
        }
    }
}
<commit_msg>std: Fix a bug where Local::take() didn't zero out<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.

//! Access to a single thread-local pointer.
//!
//! The runtime will use this for storing ~Task.
//!
//! XXX: Add runtime checks for usage of inconsistent pointer types.
//! and for overwriting an existing pointer.

#[allow(dead_code)];

use cast;
use ops::Drop;

#[cfg(windows)]               // mingw-w32 doesn't like thread_local things
#[cfg(target_os = "android")] // see #10686
pub use self::native::*;

#[cfg(not(windows), not(target_os = "android"))]
pub use self::compiled::*;

/// Encapsulates a borrowed value. When this value goes out of scope, the
/// pointer is returned.
pub struct Borrowed<T> {
    priv val: *(),
}

#[unsafe_destructor]
impl<T> Drop for Borrowed<T> {
    fn drop(&mut self) {
        unsafe {
            if self.val.is_null() {
                rtabort!("Aiee, returning null borrowed object!");
            }
            let val: ~T = cast::transmute(self.val);
            put::<T>(val);
            assert!(exists());
        }
    }
}

impl<T> Borrowed<T> {
    pub fn get<'a>(&'a mut self) -> &'a mut T {
        unsafe {
            let val_ptr: &mut ~T = cast::transmute(&mut self.val);
            let val_ptr: &'a mut T = *val_ptr;
            val_ptr
        }
    }
}

/// Borrow the thread-local value from thread-local storage.
/// While the value is borrowed it is not available in TLS.
///
/// # Safety note
///
/// Does not validate the pointer type.
#[inline]
pub unsafe fn borrow<T>() -> Borrowed<T> {
    let val: *() = cast::transmute(take::<T>());
    Borrowed {
        val: val,
    }
}

/// Compiled implementation of accessing the runtime local pointer. This is
/// implemented using LLVM's thread_local attribute which isn't necessarily
/// working on all platforms. This implementation is faster, however, so we use
/// it wherever possible.
#[cfg(not(windows), not(target_os = "android"))]
pub mod compiled {
    use cast;
    use option::{Option, Some, None};
    #[cfg(not(test))] use libc::c_void;

    #[cfg(test)]
    pub use realstd::rt::shouldnt_be_public::RT_TLS_PTR;

    #[cfg(not(test))]
    #[thread_local]
    pub static mut RT_TLS_PTR: *mut c_void = 0 as *mut c_void;

    pub fn init() {}

    pub unsafe fn cleanup() {}

    /// Give a pointer to thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn put<T>(sched: ~T) {
        RT_TLS_PTR = cast::transmute(sched)
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn take<T>() -> ~T {
        let ptr = RT_TLS_PTR;
        assert!(!ptr.is_null());
        let ptr: ~T = cast::transmute(ptr);
        // can't use `as`, due to type not matching with `cfg(test)`
        RT_TLS_PTR = cast::transmute(0);
        ptr
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    /// Leaves the old pointer in TLS for speed.
    #[inline]
    pub unsafe fn unsafe_take<T>() -> ~T {
        cast::transmute(RT_TLS_PTR)
    }

    /// Check whether there is a thread-local pointer installed.
    pub fn exists() -> bool {
        unsafe {
            RT_TLS_PTR.is_not_null()
        }
    }

    pub unsafe fn unsafe_borrow<T>() -> *mut T {
        if RT_TLS_PTR.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        RT_TLS_PTR as *mut T
    }

    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
        if RT_TLS_PTR.is_null() {
            None
        } else {
            Some(RT_TLS_PTR as *mut T)
        }
    }
}

/// Native implementation of having the runtime thread-local pointer. This
/// implementation uses the `thread_local_storage` module to provide a
/// thread-local value.
pub mod native {
    use cast;
    use libc::c_void;
    use option::{Option, Some, None};
    use ptr;
    use tls = rt::thread_local_storage;
    use unstable::mutex::{Mutex, MUTEX_INIT};

    static mut LOCK: Mutex = MUTEX_INIT;
    static mut INITIALIZED: bool = false;
    static mut RT_TLS_KEY: tls::Key = -1;

    /// Initialize the TLS key. Other ops will fail if this isn't executed
    /// first.
    pub fn init() {
        unsafe {
            LOCK.lock();
            if !INITIALIZED {
                tls::create(&mut RT_TLS_KEY);
                INITIALIZED = true;
            }
            LOCK.unlock();
        }
    }

    pub unsafe fn cleanup() {
        assert!(INITIALIZED);
        tls::destroy(RT_TLS_KEY);
        LOCK.destroy();
        INITIALIZED = false;
    }

    /// Give a pointer to thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn put<T>(sched: ~T) {
        let key = tls_key();
        let void_ptr: *mut c_void = cast::transmute(sched);
        tls::set(key, void_ptr);
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    #[inline]
    pub unsafe fn take<T>() -> ~T {
        let key = tls_key();
        let void_ptr: *mut c_void = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        let ptr: ~T = cast::transmute(void_ptr);
        tls::set(key, ptr::mut_null());
        return ptr;
    }

    /// Take ownership of a pointer from thread-local storage.
    ///
    /// # Safety note
    ///
    /// Does not validate the pointer type.
    /// Leaves the old pointer in TLS for speed.
    #[inline]
    pub unsafe fn unsafe_take<T>() -> ~T {
        let key = tls_key();
        let void_ptr: *mut c_void = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        let ptr: ~T = cast::transmute(void_ptr);
        return ptr;
    }

    /// Check whether there is a thread-local pointer installed.
    pub fn exists() -> bool {
        unsafe {
            match maybe_tls_key() {
                Some(key) => tls::get(key).is_not_null(),
                None => false
            }
        }
    }

    /// Borrow a mutable reference to the thread-local value
    ///
    /// # Safety Note
    ///
    /// Because this leaves the value in thread-local storage it is possible
    /// For the Scheduler pointer to be aliased
    pub unsafe fn unsafe_borrow<T>() -> *mut T {
        let key = tls_key();
        let void_ptr = tls::get(key);
        if void_ptr.is_null() {
            rtabort!("thread-local pointer is null. bogus!");
        }
        void_ptr as *mut T
    }

    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
        match maybe_tls_key() {
            Some(key) => {
                let void_ptr = tls::get(key);
                if void_ptr.is_null() {
                    None
                } else {
                    Some(void_ptr as *mut T)
                }
            }
            None => None
        }
    }

    #[inline]
    fn tls_key() -> tls::Key {
        match maybe_tls_key() {
            Some(key) => key,
            None => rtabort!("runtime tls key not initialized")
        }
    }

    #[inline]
    #[cfg(not(test))]
    pub fn maybe_tls_key() -> Option<tls::Key> {
        unsafe {
            // NB: This is a little racy because, while the key is
            // initalized under a mutex and it's assumed to be initalized
            // in the Scheduler ctor by any thread that needs to use it,
            // we are not accessing the key under a mutex.  Threads that
            // are not using the new Scheduler but still *want to check*
            // whether they are running under a new Scheduler may see a 0
            // value here that is in the process of being initialized in
            // another thread. I think this is fine since the only action
            // they could take if it was initialized would be to check the
            // thread-local value and see that it's not set.
            if RT_TLS_KEY != -1 {
                return Some(RT_TLS_KEY);
            } else {
                return None;
            }
        }
    }

    #[inline] #[cfg(test)]
    pub fn maybe_tls_key() -> Option<tls::Key> {
        use realstd;
        unsafe {
            cast::transmute(realstd::rt::shouldnt_be_public::maybe_tls_key())
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>concurrent: add `try_pop`/`try_push` to the queues<commit_after><|endoftext|>


<commit_before><commit_msg>Add util mod<commit_after>pub mod int;
pub mod ptr;

#[cfg(target_word_size = "32")]
pub mod rt;
<|endoftext|>


<commit_before><commit_msg>start new<commit_after>//pub fn longest_palindrome(s: String) -> String {}

/// find palindrome, return length, start index
fn find_palindrome(s: &String, start: usize) -> (usize, usize) {
    (0, 0, 0)
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Stock<commit_after><|endoftext|>


<commit_before><commit_msg>log high scores<commit_after><|endoftext|>


<commit_before><commit_msg>Add another `url::Url::username` doc example.<commit_after><|endoftext|>


<commit_before><commit_msg>Update feature flags<commit_after><|endoftext|>


<commit_before><commit_msg>Adding new BMPVersion enum.<commit_after><|endoftext|>


<commit_before><commit_msg>lib: add skeleton for future use<commit_after>#[macro_use]
extern crate lazy_static;

extern crate uuid;
use self::uuid::Uuid;

mod imp {
    fn get_machine_id() -> Option<Uuid> {
        None
    }
}

use std::fmt;

#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct MachineId {
    uuid: Uuid,
}

lazy_static! {
    static ref GENERATED_ID: Uuid = Uuid::new_v4();
    static ref GLOBAL_ID: Option<Uuid> = imp::get_machine_id();
}

impl MachineId {
    pub fn new() -> MachineId {
        MachineId {
            uuid: GLOBAL_ID.unwrap_or(*GENERATED_ID).clone(),
        }
    }
}

impl fmt::Display for MachineId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.uuid)
    }
}
<|endoftext|>


<commit_before><commit_msg>Make Error::new private to the crate.<commit_after><|endoftext|>


<commit_before><commit_msg>Convert to use Timespec internally.<commit_after><|endoftext|>


<commit_before><commit_msg>Fixup final lib.rs errors<commit_after><|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before>use std::{cmp, io};

use serde::iter::LineColIterator;

/// Trait used by the deserializer for iterating over input. This is manually
/// "specialized" for iterating over &[u8]. Once feature(specialization) is
/// stable we can use actual specialization.
pub trait Read {
    fn next(&mut self) -> io::Result<Option<u8>>;
    fn peek(&mut self) -> io::Result<Option<u8>>;

    /// Only valid after a call to peek(). Discards the peeked byte.
    fn discard(&mut self);

    /// Position of the most recent call to next().
    ///
    /// The most recent call was probably next() and not peek(), but this method
    /// should try to return a sensible result if the most recent call was
    /// actually peek() because we don't always know.
    ///
    /// Only called in case of an error, so performance is not important.
    fn position(&self) -> Position;

    /// Position of the most recent call to peek().
    ///
    /// The most recent call was probably peek() and not next(), but this method
    /// should try to return a sensible result if the most recent call was
    /// actually next() because we don't always know.
    ///
    /// Only called in case of an error, so performance is not important.
    fn peek_position(&self) -> Position;
}

pub struct Position {
    pub line: usize,
    pub column: usize,
}

pub struct IteratorRead<Iter> where Iter: Iterator<Item=io::Result<u8>> {
    iter: LineColIterator<Iter>,
    /// Temporary storage of peeked byte.
    ch: Option<u8>,
}

/// Specialization for Iter=&[u8]. This is more efficient than other iterators
/// because peek() can be read-only and we can compute line/col position only if
/// an error happens.
pub struct SliceRead<'a> {
    slice: &'a [u8],
    /// Index of the *next* byte that will be returned by next() or peek().
    index: usize,
}

//////////////////////////////////////////////////////////////////////////////

impl<Iter> IteratorRead<Iter>
    where Iter: Iterator<Item=io::Result<u8>>,
{
    pub fn new(iter: Iter) -> Self {
        IteratorRead {
            iter: LineColIterator::new(iter),
            ch: None,
        }
    }
}

impl<Iter> Read for IteratorRead<Iter>
    where Iter: Iterator<Item=io::Result<u8>>,
{
    #[inline]
    fn next(&mut self) -> io::Result<Option<u8>> {
        match self.ch.take() {
            Some(ch) => Ok(Some(ch)),
            None => {
                match self.iter.next() {
                    Some(Err(err)) => Err(err),
                    Some(Ok(ch)) => Ok(Some(ch)),
                    None => Ok(None),
                }
            }
        }
    }

    #[inline]
    fn peek(&mut self) -> io::Result<Option<u8>> {
        match self.ch {
            Some(ch) => Ok(Some(ch)),
            None => {
                match self.iter.next() {
                    Some(Err(err)) => Err(err),
                    Some(Ok(ch)) => {
                        self.ch = Some(ch);
                        Ok(self.ch)
                    }
                    None => Ok(None),
                }
            }
        }
    }

    #[inline]
    fn discard(&mut self) {
        self.ch = None;
    }

    fn position(&self) -> Position {
        Position {
            line: self.iter.line(),
            column: self.iter.col(),
        }
    }

    fn peek_position(&self) -> Position {
        // The LineColIterator updates its position during peek() so it has the
        // right one here.
        self.position()
    }
}

//////////////////////////////////////////////////////////////////////////////

impl<'a> SliceRead<'a> {
    pub fn new(slice: &'a [u8]) -> Self {
        SliceRead {
            slice: slice,
            index: 0,
        }
    }

    fn position_of_index(&self, i: usize) -> Position {
        let mut pos = Position { line: 1, column: 0 };
        for ch in &self.slice[..i] {
            match *ch {
                b'\n' => {
                    pos.line += 1;
                    pos.column = 0;
                }
                _ => {
                    pos.column += 1;
                }
            }
        }
        pos
    }
}

impl<'a> Read for SliceRead<'a> {
    #[inline]
    fn next(&mut self) -> io::Result<Option<u8>> {
        Ok(if self.index < self.slice.len() {
            let ch = self.slice[self.index];
            self.index += 1;
            Some(ch)
        } else {
            None
        })
    }

    #[inline]
    fn peek(&mut self) -> io::Result<Option<u8>> {
        Ok(if self.index < self.slice.len() {
            Some(self.slice[self.index])
        } else {
            None
        })
    }

    #[inline]
    fn discard(&mut self) {
        self.index += 1;
    }

    fn position(&self) -> Position {
        self.position_of_index(self.index)
    }

    fn peek_position(&self) -> Position {
        // Cap it at slice.len() just in case the most recent call was next()
        // and it returned the last byte.
        self.position_of_index(cmp::min(self.slice.len(), self.index + 1))
    }
}
<commit_msg>Add comment about self.slice.get(self.index) being slow<commit_after>use std::{cmp, io};

use serde::iter::LineColIterator;

/// Trait used by the deserializer for iterating over input. This is manually
/// "specialized" for iterating over &[u8]. Once feature(specialization) is
/// stable we can use actual specialization.
pub trait Read {
    fn next(&mut self) -> io::Result<Option<u8>>;
    fn peek(&mut self) -> io::Result<Option<u8>>;

    /// Only valid after a call to peek(). Discards the peeked byte.
    fn discard(&mut self);

    /// Position of the most recent call to next().
    ///
    /// The most recent call was probably next() and not peek(), but this method
    /// should try to return a sensible result if the most recent call was
    /// actually peek() because we don't always know.
    ///
    /// Only called in case of an error, so performance is not important.
    fn position(&self) -> Position;

    /// Position of the most recent call to peek().
    ///
    /// The most recent call was probably peek() and not next(), but this method
    /// should try to return a sensible result if the most recent call was
    /// actually next() because we don't always know.
    ///
    /// Only called in case of an error, so performance is not important.
    fn peek_position(&self) -> Position;
}

pub struct Position {
    pub line: usize,
    pub column: usize,
}

pub struct IteratorRead<Iter> where Iter: Iterator<Item=io::Result<u8>> {
    iter: LineColIterator<Iter>,
    /// Temporary storage of peeked byte.
    ch: Option<u8>,
}

/// Specialization for Iter=&[u8]. This is more efficient than other iterators
/// because peek() can be read-only and we can compute line/col position only if
/// an error happens.
pub struct SliceRead<'a> {
    slice: &'a [u8],
    /// Index of the *next* byte that will be returned by next() or peek().
    index: usize,
}

//////////////////////////////////////////////////////////////////////////////

impl<Iter> IteratorRead<Iter>
    where Iter: Iterator<Item=io::Result<u8>>,
{
    pub fn new(iter: Iter) -> Self {
        IteratorRead {
            iter: LineColIterator::new(iter),
            ch: None,
        }
    }
}

impl<Iter> Read for IteratorRead<Iter>
    where Iter: Iterator<Item=io::Result<u8>>,
{
    #[inline]
    fn next(&mut self) -> io::Result<Option<u8>> {
        match self.ch.take() {
            Some(ch) => Ok(Some(ch)),
            None => {
                match self.iter.next() {
                    Some(Err(err)) => Err(err),
                    Some(Ok(ch)) => Ok(Some(ch)),
                    None => Ok(None),
                }
            }
        }
    }

    #[inline]
    fn peek(&mut self) -> io::Result<Option<u8>> {
        match self.ch {
            Some(ch) => Ok(Some(ch)),
            None => {
                match self.iter.next() {
                    Some(Err(err)) => Err(err),
                    Some(Ok(ch)) => {
                        self.ch = Some(ch);
                        Ok(self.ch)
                    }
                    None => Ok(None),
                }
            }
        }
    }

    #[inline]
    fn discard(&mut self) {
        self.ch = None;
    }

    fn position(&self) -> Position {
        Position {
            line: self.iter.line(),
            column: self.iter.col(),
        }
    }

    fn peek_position(&self) -> Position {
        // The LineColIterator updates its position during peek() so it has the
        // right one here.
        self.position()
    }
}

//////////////////////////////////////////////////////////////////////////////

impl<'a> SliceRead<'a> {
    pub fn new(slice: &'a [u8]) -> Self {
        SliceRead {
            slice: slice,
            index: 0,
        }
    }

    fn position_of_index(&self, i: usize) -> Position {
        let mut pos = Position { line: 1, column: 0 };
        for ch in &self.slice[..i] {
            match *ch {
                b'\n' => {
                    pos.line += 1;
                    pos.column = 0;
                }
                _ => {
                    pos.column += 1;
                }
            }
        }
        pos
    }
}

impl<'a> Read for SliceRead<'a> {
    #[inline]
    fn next(&mut self) -> io::Result<Option<u8>> {
        // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))`
        // is about 10% slower.
        Ok(if self.index < self.slice.len() {
            let ch = self.slice[self.index];
            self.index += 1;
            Some(ch)
        } else {
            None
        })
    }

    #[inline]
    fn peek(&mut self) -> io::Result<Option<u8>> {
        // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower
        // for some reason.
        Ok(if self.index < self.slice.len() {
            Some(self.slice[self.index])
        } else {
            None
        })
    }

    #[inline]
    fn discard(&mut self) {
        self.index += 1;
    }

    fn position(&self) -> Position {
        self.position_of_index(self.index)
    }

    fn peek_position(&self) -> Position {
        // Cap it at slice.len() just in case the most recent call was next()
        // and it returned the last byte.
        self.position_of_index(cmp::min(self.slice.len(), self.index + 1))
    }
}
<|endoftext|>


<commit_before><commit_msg>Rewrite filter(...).next().is_some() with .any(...)<commit_after><|endoftext|>


<commit_before><commit_msg>Tnago: use PMU in platform configuration<commit_after>//! Power Management Unit (PMU)
//!
//! The Power Management Unit (PMU) controls the chip's power states and clock
//! power, as well as allows the chip to interface with peripherals at different
//! voltage levels.
//!
//! There are three types of power domains:
//!
//!   1. VDDIOMR:
//!
//!     * Always-on main I/O voltage supply domain necessary for the running the
//!       core.
//!     * Nominal 3.3V
//!
//!   2. VDDIOA & VDDIOB:
//!
//!     * I/O voltage supply domains for external peripherals.
//!
//!     * Can be shut down at any moment (not critical for core functions).
//!
//!     * Designed for 1.8-3.6V
//!
//!   3. VDDIOF:
//!
//!     * I/O voltage supply domain for flash memory.
//!
//!     * Designed for 1.8-3.6V
//!

use common::volatile_cell::VolatileCell;
use core::mem::transmute;

/// Registers for the Power Management Unit (PMU)
// Non-public fields prefixed with "_" mark unused registers
#[repr(C, packed)]
pub struct PMURegisters {
    _reset: VolatileCell<u32>,
    _set_reset: VolatileCell<u32>,

    /// Clear register for the reset source
    pub clear_reset: VolatileCell<u32>,

    /// Status for source of last reset event
    ///
    /// Bits 0-7 correspond to:
    ///
    /// | bit | Description                                       |
    /// | --- | :------------------------------------------------ |
    /// | 0   | Power on reset                                    |
    /// | 1   | Low power exit                                    |
    /// | 2   | Watchdog reset                                    |
    /// | 3   | Lockup reset                                      |
    /// | 4   | SYSRESET                                          |
    /// | 5   | Software initiated reset through PMU_GLOBAL_RESET |
    /// | 6   | Fast burnout circuit                              |
    /// | 7   | Security breach reset                             |
    ///
    pub reset_source: VolatileCell<u32>,

    /// Global chip reset
    ///
    /// Initiates a reset of the system similar to toggling the external reset
    /// pin. To initiate a reset, write the key 0x7041776 to this register.
    pub global_reset: VolatileCell<u32>,

    pub low_power_disable: VolatileCell<u32>,

    pub low_power_bypass: VolatileCell<u32>,

    pub low_power_bypass_value: VolatileCell<u32>,

    pub set_wakeup_interrupt_controller: VolatileCell<u32>,

    pub clear_wakeup_interrupt_controller: VolatileCell<u32>,

    /// Value of the system vector table offset
    pub sysvtor: VolatileCell<u32>,

    /// Enable PMU to gate some clocks when processor is sleeping
    pub nap_enable: VolatileCell<u32>,

    _pmu_sw_pdb: VolatileCell<u32>,
    _pmu_vref: VolatileCell<u32>,
    _xtl_osc_bypass: VolatileCell<u32>,
    _flash_tm0_test_en_bypass: VolatileCell<u32>,

    /// Battery level indicator
    ///
    /// When non-zero, the voltage level is higher than specified in the vref
    /// register's BATMON field.
    pub battery_level_ok: VolatileCell<u32>,

    _b_reg_dig_ctrl: VolatileCell<u32>,
    _exitpd_mask: VolatileCell<u32>,
    _exitpd_src: VolatileCell<u32>,
    _exitpd_mon: VolatileCell<u32>,
    _osc_ctrl: VolatileCell<u32>,

    /// Turn on clocks for memory
    ///
    /// Bits 0-6 correspond to memory banks 0-6, respectively.
    pub memory_clk_set: VolatileCell<u32>,

    /// Turn off clocks for memory
    ///
    /// Bits 0-6 correspond to memory banks 0-6, respectively.
    pub memory_clk_clear: VolatileCell<u32>,

    /// Enable peripheral clocks (bank 0).
    ///
    /// Each bit corresponds to a different peripheral clock.
    pub peripheral_clocks0_enable: VolatileCell<u32>,

    /// Disable peripheral clocks (bank 0).
    ///
    /// Each bit corresponds to a different peripheral clock.
    pub peripheral_clocks0_disable: VolatileCell<u32>,

    /// Enable peripheral clocks (bank 1).
    ///
    /// Each bit corresponds to a different peripheral clock.
    pub peripheral_clocks1_enable: VolatileCell<u32>,

    /// Disable peripheral clocks (bank 1).
    ///
    /// Each bit corresponds to a different peripheral clock.
    pub peripheral_clocks1_disable: VolatileCell<u32>,
}

const PMU_BASE : isize = 0x40000000;

static mut PMU : *mut PMURegisters = PMU_BASE as *mut PMURegisters;

#[derive(Clone,Copy)]
pub enum PeripheralClock0 {
    Camo0,
    Crpyto0,
    Dma0,
    Flash0,
    Fuse0,
    GlobalSec,
    GlobalSecTimer,
    GlobalSecHs,
    Gpio0,
    Gpio1,
    I2C0,
    I2C1,
    I2CS0,
    KeyMgr0,
    PeriAPB0,
    PeriAPB1,
    PeriAPB2,
    PeriAPB2Timer,
    PeriAPB3,
    PeriAPB3Timer,
    PeriAPB3HS,
    PinMux,
    Pmu,
    RBox0,
    Rdd0,
    Rtc0,
    Rtc0Timer,
    Spi0Hs,
    Spi1Hs,
    Sps0,
    Sps0TimerHs,
    Swdp0,
    Temp0
}

#[derive(Clone,Copy)]
pub enum PeripheralClock1 {
    TimeHs0Timer,
    TimeHs1Timer,
    TimeLs0,
    TimeUs0Timer,
    Trng0,
    Uart0Timer,
    Uart1Timer,
    Uart2Timer,
    Usb0,
    Usb0TimerHs,
    Volt0,
    Watchdog0,
    Xo0,
    Xo0Timer,
    PeripheralMasterMatrix,
    PeripheralMatrix
}

#[derive(Clone,Copy)]
pub enum PeripheralClock {
    Bank0(PeripheralClock0),
    Bank1(PeripheralClock1)
}

/// Wrapper struct around `PeripheralClock` that can only be created by.
/// trusted code.
#[derive(Clone,Copy)]
pub struct Clock {
    // It's important that this field is private!
    clock: PeripheralClock
}

impl Clock {
    pub unsafe fn new(clock: PeripheralClock) -> Clock {
        Clock { clock: clock }
    }

    pub fn enable(&self) {
        let pmu : &mut PMURegisters = unsafe { transmute(PMU) };
        match self.clock {
            PeripheralClock::Bank0(clock) => {
                pmu.peripheral_clocks0_enable.set(1 << (clock as u32));
            },
            PeripheralClock::Bank1(clock) => {
                pmu.peripheral_clocks1_enable.set(1 << (clock as u32));
            }
        }
    }

    pub fn disable(&self) {
        let pmu : &mut PMURegisters = unsafe { transmute(PMU) };
        match self.clock {
            PeripheralClock::Bank0(clock) => {
                pmu.peripheral_clocks0_disable.set(1 << (clock as u32));
            },
            PeripheralClock::Bank1(clock) => {
                pmu.peripheral_clocks1_disable.set(1 << (clock as u32));
            }
        }
    }
}

<|endoftext|>


<commit_before>extern crate iron;

use iron::{Iron, Request, Response, IronResult, AfterMiddleware, Chain};

struct DefaultContentType;
impl AfterMiddleware for DefaultContentType {
    fn after(&self, _req: &mut Request, mut resp: Response) -> IronResult<Response> {
        if resp.headers.get::<iron::headers::ContentType>() == None {
            resp.headers.set(iron::headers::ContentType::plaintext());
        }
        Ok(resp)
    }
}

fn user_agent(req: &mut Request) -> IronResult<Response> {
    let ua = match req.headers.get::<iron::headers::UserAgent>() {
        Some(ua_header) => ua_header,
        None => "No User-Agent",
    };
    Ok(Response::with((iron::status::Ok, format!("{}\n", ua))))
}

fn main() {
    let mut chain = Chain::new(user_agent);
    chain.link_after(DefaultContentType);
    Iron::new(chain)
        .http(format!("localhost:{}", 3000))
        .unwrap();
}
<commit_msg>Adding an example for non-standard headers<commit_after>extern crate iron;

use iron::{Iron, Request, Response, IronResult, AfterMiddleware, Chain};

struct DefaultContentType;
impl AfterMiddleware for DefaultContentType {
    // This is run for every requests, AFTER all handlers have been executed
    fn after(&self, _req: &mut Request, mut resp: Response) -> IronResult<Response> {
        if resp.headers.get::<iron::headers::ContentType>() == None {
            // Set a standard header
            resp.headers.set(iron::headers::ContentType::plaintext());
        }
        Ok(resp)
    }
}

fn info(req: &mut Request) -> IronResult<Response> {
    // Get a header using a standard iron::headers
    let ua = match req.headers.get::<iron::headers::UserAgent>() {
        Some(ua_header) => format!("User Agent: {}\n", ua_header),
        None => "No User Agent.\n".to_string(),
    };
    // Get a non-standard header using the raw header
    let x_forwarded_for = match req.headers.get_raw("X-Forwarded-For") {
        Some(proxies) => format!("Proxies: {}\n", std::str::from_utf8(&proxies[0]).unwrap()),
        None => "No proxy.\n".to_string(),
    };
    let body = format!("{}{}\n", ua, x_forwarded_for);

    Ok(Response::with((iron::status::Ok, body)))
}

fn main() {
    let mut chain = Chain::new(info);
    chain.link_after(DefaultContentType);
    Iron::new(chain)
        .http(format!("localhost:{}", 3000))
        .unwrap();
}
<|endoftext|>