<commit_before><commit_msg>add blkid/mod.rs<commit_after>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

extern crate libc;

use std::cell::Cell;
use self::libc::size_t;
use self::libc::c_int;
use self::libc::c_char;
use std::ptr;
use std::ffi::CString;

//////////////////////////////////////////////////////////////////
pub struct Prober<'a> {
    file:       &'a str,
    raw_prober: Cell<*const i32>
}

impl<'a> Prober<'a> {
    pub fn new(filename: &str) -> Prober {
        Prober{file: filename,
               raw_prober: Cell::new(ptr::null())}
    }

    pub fn probe(&self) -> Result<(), String> {
        let name = CString::new(self.file).unwrap();
        let name_raw = name.into_raw();
        unsafe {
            self.raw_prober.set(blkid_new_probe_from_filename(name_raw));
        }

        if self.raw_prober.get().is_null() {
            return Err("Error in blkid_new_probe_from_filename!".to_string());
        }

        let rr: c_int;
        unsafe {
            rr = blkid_do_probe(self.raw_prober.get());
        }

        if rr < 0 {
            let message = "Error in blkid_do_probe!".to_string();
            return Err(message);
        }
        Ok(())
    }

    pub fn getType(&self) -> Result<String, String> {
        return self.get("TYPE");
    }

    pub fn getLabel(&self) -> Result<String, String> {
        return self.get("LABEL");
    }

    pub fn get(&self, key: &str) -> Result<String, String> {
        let c_key = CString::new(key).unwrap();
        let c_key_raw = c_key.into_raw();
        let mut buff: c_char = 0;
        let mut p_buff: *mut c_char = &mut buff;
        let p_p_buff: *mut *mut c_char = &mut p_buff;
        let i: size_t = 0;
        let p_i: *const size_t  = &i;

        let res: c_int;
        unsafe {
            res = blkid_probe_lookup_value(self.raw_prober.get(),
                                           c_key_raw,
                                           p_p_buff,
                                           p_i);
        }

        if res < 0 {
            let message = "Error in blkid_probe_lookup_value!".to_string();
            return Err(message);
        }

        unsafe {
            let ss = CString::from_raw(p_buff);
            let sss = ss.into_string();
            match sss {
                Ok(r)  => Ok(r),
                _      => Err("Error in CString::into_string!".to_string())
            }
        }
    }
}

impl<'a> Drop for Prober<'a> {
    fn drop(&mut self) {
        let ptr = self.raw_prober.get();
        if ptr.is_null() {
            return;
        }

        unsafe {
            blkid_free_probe(ptr);
        }
    }
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[link(name = "blkid")]
extern {
    fn blkid_new_probe_from_filename(file: *const c_char) -> *const i32;
    fn blkid_do_probe(prober: *const i32) -> c_int;
    fn blkid_probe_lookup_value(prober: *const i32,
                                key: *const c_char,
                                data: *mut *mut c_char,
                                size: *const size_t) -> c_int;
    fn blkid_free_probe(prober: *const i32);
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
#[test]
fn test_blkid_01() {
    let p = Prober::new("/dev/sda1");
    let p_r = p.probe();
    match p_r {
        Err(r) => {
            println!("{}", r);
            return;
        },
        _       => println!("********* OK ***********")
    }

    let t = p.getType();
    match t {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }

    let l = p.getLabel();
    match l {
        Ok(r)  => println!("{}", r),
        Err(r) => println!("{}", r)
    }
}
//////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before><commit_msg>tests(Unicode): adds safe unicode tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for version<commit_after>extern crate bamrescue;

#[test]
fn version() {
    bamrescue::version();
}
<|endoftext|>


<commit_before>use std::env;
use self_update::{self, InstallOpts};
use errors::*;
use clap::{App, Arg, AppSettings};
use rustup_dist::dist::TargetTriple;
use common;

mod sys_check {
}

pub fn main() -> Result<()> {
    let args: Vec<_> = env::args().collect();
    let arg1 = args.get(1).map(|a| &**a);

    // Secret command used during self-update. Not for users.
    if arg1 == Some("--self-replace") {
        return self_update::self_replace();
    }

    let cli = App::new("rustup-init")
        .version(common::version())
        .about("The installer for rustup")
        .setting(AppSettings::DeriveDisplayOrder)
        .arg(Arg::with_name("verbose")
             .short("v")
             .long("verbose")
             .help("Enable verbose output"))
        .arg(Arg::with_name("no-prompt")
             .short("y")
             .help("Disable confirmation prompt."))
        .arg(Arg::with_name("default-host")
             .long("default-host")
             .takes_value(true)
             .help("Choose a default host triple"))
        .arg(Arg::with_name("default-toolchain")
             .long("default-toolchain")
             .takes_value(true)
             .help("Choose a default toolchain to install"))
        .arg(Arg::with_name("no-modify-path")
             .long("no-modify-path")
             .help("Don't configure the PATH environment variable"));

    let matches = cli.get_matches();
    let no_prompt = matches.is_present("no-prompt");
    let verbose = matches.is_present("verbose");
    let default_host = matches.value_of("default-host").map(|s| s.to_owned()).unwrap_or_else(|| {
        TargetTriple::from_host_or_build().to_string()
    });
    let default_toolchain = matches.value_of("default-toolchain").unwrap_or("stable");
    let no_modify_path = matches.is_present("no-modify-path");

    let opts = InstallOpts {
        default_host_triple: default_host,
        default_toolchain: default_toolchain.to_owned(),
        no_modify_path: no_modify_path,
    };

    try!(self_update::install(no_prompt, verbose, opts));

    Ok(())
}
<commit_msg>Remove unused mod. Oops<commit_after>use std::env;
use self_update::{self, InstallOpts};
use errors::*;
use clap::{App, Arg, AppSettings};
use rustup_dist::dist::TargetTriple;
use common;

pub fn main() -> Result<()> {
    let args: Vec<_> = env::args().collect();
    let arg1 = args.get(1).map(|a| &**a);

    // Secret command used during self-update. Not for users.
    if arg1 == Some("--self-replace") {
        return self_update::self_replace();
    }

    let cli = App::new("rustup-init")
        .version(common::version())
        .about("The installer for rustup")
        .setting(AppSettings::DeriveDisplayOrder)
        .arg(Arg::with_name("verbose")
             .short("v")
             .long("verbose")
             .help("Enable verbose output"))
        .arg(Arg::with_name("no-prompt")
             .short("y")
             .help("Disable confirmation prompt."))
        .arg(Arg::with_name("default-host")
             .long("default-host")
             .takes_value(true)
             .help("Choose a default host triple"))
        .arg(Arg::with_name("default-toolchain")
             .long("default-toolchain")
             .takes_value(true)
             .help("Choose a default toolchain to install"))
        .arg(Arg::with_name("no-modify-path")
             .long("no-modify-path")
             .help("Don't configure the PATH environment variable"));

    let matches = cli.get_matches();
    let no_prompt = matches.is_present("no-prompt");
    let verbose = matches.is_present("verbose");
    let default_host = matches.value_of("default-host").map(|s| s.to_owned()).unwrap_or_else(|| {
        TargetTriple::from_host_or_build().to_string()
    });
    let default_toolchain = matches.value_of("default-toolchain").unwrap_or("stable");
    let no_modify_path = matches.is_present("no-modify-path");

    let opts = InstallOpts {
        default_host_triple: default_host,
        default_toolchain: default_toolchain.to_owned(),
        no_modify_path: no_modify_path,
    };

    try!(self_update::install(no_prompt, verbose, opts));

    Ok(())
}
<|endoftext|>


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

//! Macros for implementing PipelineInit and PipelineData.

#[macro_export]
macro_rules! gfx_pipeline_inner {
    {
        $( $field:ident: $ty:ty, )*
    } => {
        use $crate::pso::{DataLink, DataBind, Descriptor, InitError, RawDataSet, AccessInfo};

        #[derive(Clone, Debug)]
        pub struct Data<R: $crate::Resources> {
            $( pub $field: <$ty as DataBind<R>>::Data, )*
        }

        pub struct Meta {
            $( $field: $ty, )*
        }

        pub struct Init<'a> {
            $( pub $field: <$ty as DataLink<'a>>::Init, )*
        }

        impl<'a> $crate::pso::PipelineInit for Init<'a> {
            type Meta = Meta;
            fn link_to<'s>(&self, desc: &mut Descriptor, info: &'s $crate::ProgramInfo)
                       -> Result<Self::Meta, InitError<&'s str>>
            {
                let mut meta = Meta {
                    $( $field: <$ty as DataLink<'a>>::new(), )*
                };
                // v#
                let mut _num_vb = 0;
                $(
                    if let Some(d) = meta.$field.link_vertex_buffer(_num_vb, &self.$field) {
                        assert!(meta.$field.is_active());
                        desc.vertex_buffers[_num_vb as usize] = Some(d);
                        _num_vb += 1;
                    }
                )*
                for at in &info.vertex_attributes {
                    $(
                        match meta.$field.link_input(at, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.attributes[at.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::VertexImport(&at.name, Some(fm))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::VertexImport(&at.name, None));
                }
                // c#
                for cb in &info.constant_buffers {
                    $(
                        match meta.$field.link_constant_buffer(cb, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.constant_buffers[cb.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(e)) => return Err(
                                InitError::ConstantBuffer(&cb.name, Some(e))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::ConstantBuffer(&cb.name, None));
                }
                // global constants
                for gc in &info.globals {
                    $(
                        match meta.$field.link_global_constant(gc, &self.$field) {
                            Some(Ok(())) => {
                                assert!(meta.$field.is_active());
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::GlobalConstant(&gc.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::GlobalConstant(&gc.name, None));
                }
                // t#
                for srv in &info.textures {
                    $(
                        match meta.$field.link_resource_view(srv, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.resource_views[srv.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::ResourceView(&srv.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::ResourceView(&srv.name, None));
                }
                // u#
                for uav in &info.unordereds {
                    $(
                        match meta.$field.link_unordered_view(uav, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.unordered_views[uav.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::UnorderedView(&uav.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::UnorderedView(&uav.name, None));
                }
                // s#
                for sm in &info.samplers {
                    $(
                        match meta.$field.link_sampler(sm, &self.$field) {
                            Some(d) => {
                                assert!(meta.$field.is_active());
                                desc.samplers[sm.slot as usize] = Some(d);
                                continue;
                            },
                            None => (),
                        }
                    )*
                    return Err(InitError::Sampler(&sm.name, None));
                }
                // color targets
                for out in &info.outputs {
                    $(
                        match meta.$field.link_output(out, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.color_targets[out.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::PixelExport(&out.name, Some(fm))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::PixelExport(&out.name, None));
                }
                if !info.knows_outputs {
                    use $crate::shade::core as s;
                    let mut out = s::OutputVar {
                        name: String::new(),
                        slot: 0,
                        base_type: s::BaseType::F32,
                        container: s::ContainerType::Vector(4),
                    };
                    $(
                        match meta.$field.link_output(&out, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.color_targets[out.slot as usize] = Some(d);
                                out.slot += 1;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::PixelExport(&"!known", Some(fm))
                            ),
                            None => (),
                        }
                    )*
                }
                // depth-stencil, scissor
                for _ in 0 .. 1 {
                    $(
                        if let Some(d) = meta.$field.link_depth_stencil(&self.$field) {
                            assert!(meta.$field.is_active());
                            desc.depth_stencil = Some(d);
                        }
                        if meta.$field.link_scissor() {
                            assert!(meta.$field.is_active());
                            desc.scissor = true;
                        }
                    )*
                }
                // done
                Ok(meta)
            }
        }

        impl<R: $crate::Resources> $crate::pso::PipelineData<R> for Data<R> {
            type Meta = Meta;
            fn bake_to(&self,
                       out: &mut RawDataSet<R>,
                       meta: &Self::Meta,
                       man: &mut $crate::handle::Manager<R>,
                       access: &mut AccessInfo<R>) {
                $(
                    meta.$field.bind_to(out, &self.$field, man, access);
                )*
            }
        }
    }
}

#[macro_export]
macro_rules! gfx_pipeline_base {
    ($module:ident {
        $( $field:ident: $ty:ty, )*
    }) => {
        pub mod $module {
            use $crate;
            #[allow(unused_imports)]
            use super::*;
            gfx_pipeline_inner!{ $(
                $field: $ty,
            )*}
        }
    }
}

#[macro_export]
macro_rules! gfx_pipeline {
    ($module:ident {
        $( $field:ident: $ty:ty = $value:expr, )*
    }) => {
        pub mod $module {
            use $crate;
            #[allow(unused_imports)]
            use super::*;
            gfx_pipeline_inner!{ $(
                $field: $ty,
            )*}
            pub fn new() -> Init<'static> {
                Init {
                    $( $field: $value, )*
                }
            }
        }
    }
}
<commit_msg>Fix pipeline definition macro due to recent restrictions for $crate in macros<commit_after>// Copyright 2015 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.

//! Macros for implementing PipelineInit and PipelineData.

#[macro_export]
macro_rules! gfx_pipeline_inner {
    {
        $( $field:ident: $ty:ty, )*
    } => {
        use $crate::pso::{DataLink, DataBind, Descriptor, InitError, RawDataSet, AccessInfo};

        #[derive(Clone, Debug)]
        pub struct Data<R: $crate::Resources> {
            $( pub $field: <$ty as DataBind<R>>::Data, )*
        }

        pub struct Meta {
            $( $field: $ty, )*
        }

        pub struct Init<'a> {
            $( pub $field: <$ty as DataLink<'a>>::Init, )*
        }

        impl<'a> $crate::pso::PipelineInit for Init<'a> {
            type Meta = Meta;
            fn link_to<'s>(&self, desc: &mut Descriptor, info: &'s $crate::ProgramInfo)
                       -> Result<Self::Meta, InitError<&'s str>>
            {
                let mut meta = Meta {
                    $( $field: <$ty as DataLink<'a>>::new(), )*
                };
                // v#
                let mut _num_vb = 0;
                $(
                    if let Some(d) = meta.$field.link_vertex_buffer(_num_vb, &self.$field) {
                        assert!(meta.$field.is_active());
                        desc.vertex_buffers[_num_vb as usize] = Some(d);
                        _num_vb += 1;
                    }
                )*
                for at in &info.vertex_attributes {
                    $(
                        match meta.$field.link_input(at, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.attributes[at.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::VertexImport(&at.name, Some(fm))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::VertexImport(&at.name, None));
                }
                // c#
                for cb in &info.constant_buffers {
                    $(
                        match meta.$field.link_constant_buffer(cb, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.constant_buffers[cb.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(e)) => return Err(
                                InitError::ConstantBuffer(&cb.name, Some(e))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::ConstantBuffer(&cb.name, None));
                }
                // global constants
                for gc in &info.globals {
                    $(
                        match meta.$field.link_global_constant(gc, &self.$field) {
                            Some(Ok(())) => {
                                assert!(meta.$field.is_active());
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::GlobalConstant(&gc.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::GlobalConstant(&gc.name, None));
                }
                // t#
                for srv in &info.textures {
                    $(
                        match meta.$field.link_resource_view(srv, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.resource_views[srv.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::ResourceView(&srv.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::ResourceView(&srv.name, None));
                }
                // u#
                for uav in &info.unordereds {
                    $(
                        match meta.$field.link_unordered_view(uav, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.unordered_views[uav.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(_)) => return Err(
                                InitError::UnorderedView(&uav.name, Some(()))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::UnorderedView(&uav.name, None));
                }
                // s#
                for sm in &info.samplers {
                    $(
                        match meta.$field.link_sampler(sm, &self.$field) {
                            Some(d) => {
                                assert!(meta.$field.is_active());
                                desc.samplers[sm.slot as usize] = Some(d);
                                continue;
                            },
                            None => (),
                        }
                    )*
                    return Err(InitError::Sampler(&sm.name, None));
                }
                // color targets
                for out in &info.outputs {
                    $(
                        match meta.$field.link_output(out, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.color_targets[out.slot as usize] = Some(d);
                                continue;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::PixelExport(&out.name, Some(fm))
                            ),
                            None => (),
                        }
                    )*
                    return Err(InitError::PixelExport(&out.name, None));
                }
                if !info.knows_outputs {
                    use $crate::shade::core as s;
                    let mut out = s::OutputVar {
                        name: String::new(),
                        slot: 0,
                        base_type: s::BaseType::F32,
                        container: s::ContainerType::Vector(4),
                    };
                    $(
                        match meta.$field.link_output(&out, &self.$field) {
                            Some(Ok(d)) => {
                                assert!(meta.$field.is_active());
                                desc.color_targets[out.slot as usize] = Some(d);
                                out.slot += 1;
                            },
                            Some(Err(fm)) => return Err(
                                InitError::PixelExport(&"!known", Some(fm))
                            ),
                            None => (),
                        }
                    )*
                }
                // depth-stencil, scissor
                for _ in 0 .. 1 {
                    $(
                        if let Some(d) = meta.$field.link_depth_stencil(&self.$field) {
                            assert!(meta.$field.is_active());
                            desc.depth_stencil = Some(d);
                        }
                        if meta.$field.link_scissor() {
                            assert!(meta.$field.is_active());
                            desc.scissor = true;
                        }
                    )*
                }
                // done
                Ok(meta)
            }
        }

        impl<R: $crate::Resources> $crate::pso::PipelineData<R> for Data<R> {
            type Meta = Meta;
            fn bake_to(&self,
                       out: &mut RawDataSet<R>,
                       meta: &Self::Meta,
                       man: &mut $crate::handle::Manager<R>,
                       access: &mut AccessInfo<R>) {
                $(
                    meta.$field.bind_to(out, &self.$field, man, access);
                )*
            }
        }
    }
}

#[macro_export]
macro_rules! gfx_pipeline_base {
    ($module:ident {
        $( $field:ident: $ty:ty, )*
    }) => {
        pub mod $module {
            #[allow(unused_imports)]
            use super::*;
            use super::gfx;
            gfx_pipeline_inner!{ $(
                $field: $ty,
            )*}
        }
    }
}

#[macro_export]
macro_rules! gfx_pipeline {
    ($module:ident {
        $( $field:ident: $ty:ty = $value:expr, )*
    }) => {
        pub mod $module {
            #[allow(unused_imports)]
            use super::*;
            use super::gfx;
            gfx_pipeline_inner!{ $(
                $field: $ty,
            )*}
            pub fn new() -> Init<'static> {
                Init {
                    $( $field: $value, )*
                }
            }
        }
    }
}
<|endoftext|>


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

//! Render target components for the PSO macro.

use std::marker::PhantomData;
use gfx_core::{ColorSlot, Resources};
use gfx_core::{format, handle, pso, state, target};
use gfx_core::factory::Phantom;
use gfx_core::shade::OutputVar;
use super::{DataLink, DataBind, RawDataSet};

/// Render target component. Typically points to a color-formatted texture.
/// - init: `&str` = name of the target
/// - data: `RenderTargetView<T>`
pub struct RenderTarget<T>(Option<ColorSlot>, PhantomData<T>);
/// Render target component with active blending mode.
/// - init: (`&str`, `ColorMask`, `Blend` = blending state)
/// - data: `RenderTargetView<T>`
pub struct BlendTarget<T>(Option<ColorSlot>, PhantomData<T>);
/// Service struct to simplify the implementations of `DepthTarget`,
/// `StencilTarget`, and `DepthStencilTarget`.
pub struct DepthStencilCommon<T, I>(bool, bool, PhantomData<(T, I)>);
/// Depth target component.
/// - init: `Depth` = depth state
/// - data: `DepthStencilView<T>`
pub type DepthTarget<T> = DepthStencilCommon<T, state::Depth>;
/// Stencil target component.
/// - init: `Stencil` = stencil state
/// - data: `DepthStencilView<T>`
pub type StencilTarget<T> = DepthStencilCommon<T, state::Stencil>;
/// Depth + stencil target component.
/// - init: (`Depth` = depth state, `Stencil` = stencil state)
/// - data: `DepthStencilView<T>`
pub type DepthStencilTarget<T> = DepthStencilCommon<T, (state::Depth, state::Stencil)>;
/// Scissor component. Sets up the scissor test for rendering.
/// - init: `()`
/// - data: `Rect` = target area
pub struct Scissor;
/// Blend reference component. Sets up the reference color for blending.
/// - init: `()`
/// - data: `ColorValue`
pub struct BlendRef;

impl<'a, T: format::RenderFormat> DataLink<'a> for RenderTarget<T> {
    type Init = &'a str;
    fn new() -> Self {
        RenderTarget(None, PhantomData)
    }
    fn is_active(&self) -> bool {
        self.0.is_some()
    }
    fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
                   Option<Result<pso::ColorTargetDesc, format::Format>> {
        if out.name.is_empty() || &out.name == init {
            self.0 = Some(out.slot);
            let desc = (T::get_format(), state::MASK_ALL.into());
            Some(Ok(desc))
        }else {
            None
        }
    }
}

impl<R: Resources, T> DataBind<R> for RenderTarget<T> {
    type Data = handle::RenderTargetView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        if let Some(slot) = self.0 {
            out.pixel_targets.add_color(slot, man.ref_rtv(data.raw()), data.raw().get_dimensions());
        }
    }
}

impl<'a, T: format::BlendFormat> DataLink<'a> for BlendTarget<T> {
    type Init = (&'a str, state::ColorMask, state::Blend);
    fn new() -> Self {
        BlendTarget(None, PhantomData)
    }
    fn is_active(&self) -> bool {
        self.0.is_some()
    }
    fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
                   Option<Result<pso::ColorTargetDesc, format::Format>> {
        if out.name.is_empty() || &out.name == init.0 {
            self.0 = Some(out.slot);
            let desc = (T::get_format(), pso::ColorInfo {
                mask: init.1,
                color: Some(init.2.color),
                alpha: Some(init.2.alpha),
            });
            Some(Ok(desc))
        }else {
            None
        }
    }
}

impl<R: Resources, T> DataBind<R> for BlendTarget<T> {
    type Data = handle::RenderTargetView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        if let Some(slot) = self.0 {
            out.pixel_targets.add_color(slot, man.ref_rtv(data.raw()), data.raw().get_dimensions());
        }
    }
}

impl<'a,
    T: format::Formatted,
    I: 'a + Copy + Into<pso::DepthStencilInfo>
> DataLink<'a> for DepthStencilCommon<T, I> {
    type Init = I;
    fn new() -> Self {
        DepthStencilCommon(false, false, PhantomData)
    }
    fn is_active(&self) -> bool {
        self.0 || self.1
    }
    fn link_depth_stencil(&mut self, init: &Self::Init) ->
                          Option<pso::DepthStencilDesc> {
        let format = T::get_format();
        let info = (*init).into();
        self.0 = info.depth.is_some();
        self.1 = info.front.is_some() || info.back.is_some();
        Some((format.0, info))
    }
}

impl<R: Resources, T, I> DataBind<R> for DepthStencilCommon<T, I> {
    type Data = handle::DepthStencilView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        out.pixel_targets.add_depth_stencil(man.ref_dsv(data.raw()),
            self.0, self.1, data.raw().get_dimensions());
    }
}

impl<'a> DataLink<'a> for Scissor {
    type Init = ();
    fn new() -> Self { Scissor }
    fn is_active(&self) -> bool { true }
}

impl<R: Resources> DataBind<R> for Scissor {
    type Data = target::Rect;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, _: &mut handle::Manager<R>) {
        out.scissor = Some(*data);
    }
}

impl<'a> DataLink<'a> for BlendRef {
    type Init = ();
    fn new() -> Self { BlendRef }
    fn is_active(&self) -> bool { true }
}

impl<R: Resources> DataBind<R> for BlendRef {
    type Data = target::ColorValue;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, _: &mut handle::Manager<R>) {
        out.ref_values.blend = *data;
    }
}
<commit_msg>PSO - full support for stencil reference values<commit_after>// Copyright 2015 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.

//! Render target components for the PSO macro.

use std::marker::PhantomData;
use gfx_core::{ColorSlot, Resources};
use gfx_core::{format, handle, pso, state, target};
use gfx_core::factory::Phantom;
use gfx_core::shade::OutputVar;
use super::{DataLink, DataBind, RawDataSet};

/// Render target component. Typically points to a color-formatted texture.
/// - init: `&str` = name of the target
/// - data: `RenderTargetView<T>`
pub struct RenderTarget<T>(Option<ColorSlot>, PhantomData<T>);
/// Render target component with active blending mode.
/// - init: (`&str`, `ColorMask`, `Blend` = blending state)
/// - data: `RenderTargetView<T>`
pub struct BlendTarget<T>(Option<ColorSlot>, PhantomData<T>);
/// Depth target component.
/// - init: `Depth` = depth state
/// - data: `DepthStencilView<T>`
pub struct DepthTarget<T>(PhantomData<T>);
/// Stencil target component.
/// - init: `Stencil` = stencil state
/// - data: (`DepthStencilView<T>`, `(front, back)` = stencil reference values)
pub struct StencilTarget<T>(PhantomData<T>);
/// Depth + stencil target component.
/// - init: (`Depth` = depth state, `Stencil` = stencil state)
/// - data: (`DepthStencilView<T>`, `(front, back)` = stencil reference values)
pub struct DepthStencilTarget<T>(PhantomData<T>);
/// Scissor component. Sets up the scissor test for rendering.
/// - init: `()`
/// - data: `Rect` = target area
pub struct Scissor;
/// Blend reference component. Sets up the reference color for blending.
/// - init: `()`
/// - data: `ColorValue`
pub struct BlendRef;

impl<'a, T: format::RenderFormat> DataLink<'a> for RenderTarget<T> {
    type Init = &'a str;
    fn new() -> Self {
        RenderTarget(None, PhantomData)
    }
    fn is_active(&self) -> bool {
        self.0.is_some()
    }
    fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
                   Option<Result<pso::ColorTargetDesc, format::Format>> {
        if out.name.is_empty() || &out.name == init {
            self.0 = Some(out.slot);
            let desc = (T::get_format(), state::MASK_ALL.into());
            Some(Ok(desc))
        }else {
            None
        }
    }
}

impl<R: Resources, T> DataBind<R> for RenderTarget<T> {
    type Data = handle::RenderTargetView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        if let Some(slot) = self.0 {
            out.pixel_targets.add_color(slot, man.ref_rtv(data.raw()), data.raw().get_dimensions());
        }
    }
}

impl<'a, T: format::BlendFormat> DataLink<'a> for BlendTarget<T> {
    type Init = (&'a str, state::ColorMask, state::Blend);
    fn new() -> Self {
        BlendTarget(None, PhantomData)
    }
    fn is_active(&self) -> bool {
        self.0.is_some()
    }
    fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
                   Option<Result<pso::ColorTargetDesc, format::Format>> {
        if out.name.is_empty() || &out.name == init.0 {
            self.0 = Some(out.slot);
            let desc = (T::get_format(), pso::ColorInfo {
                mask: init.1,
                color: Some(init.2.color),
                alpha: Some(init.2.alpha),
            });
            Some(Ok(desc))
        }else {
            None
        }
    }
}

impl<R: Resources, T> DataBind<R> for BlendTarget<T> {
    type Data = handle::RenderTargetView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        if let Some(slot) = self.0 {
            out.pixel_targets.add_color(slot, man.ref_rtv(data.raw()), data.raw().get_dimensions());
        }
    }
}

impl<'a, T: format::DepthFormat> DataLink<'a> for DepthTarget<T> {
    type Init = state::Depth;
    fn new() -> Self { DepthTarget(PhantomData) }
    fn is_active(&self) -> bool { true }
    fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
        Some((T::get_format().0, (*init).into()))
    }
}

impl<R: Resources, T> DataBind<R> for DepthTarget<T> {
    type Data = handle::DepthStencilView<R, T>;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        let dsv = data.raw();
        out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), true, false, dsv.get_dimensions());
    }
}

impl<'a, T: format::StencilFormat> DataLink<'a> for StencilTarget<T> {
    type Init = state::Stencil;
    fn new() -> Self { StencilTarget(PhantomData) }
    fn is_active(&self) -> bool { true }
    fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
        Some((T::get_format().0, (*init).into()))
    }
}

impl<R: Resources, T> DataBind<R> for StencilTarget<T> {
    type Data = (handle::DepthStencilView<R, T>, (target::Stencil, target::Stencil));
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        let dsv = data.0.raw();
        out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), false, true, dsv.get_dimensions());
        out.ref_values.stencil = data.1;
    }
}

impl<'a, T: format::DepthStencilFormat> DataLink<'a> for DepthStencilTarget<T> {
    type Init = (state::Depth, state::Stencil);
    fn new() -> Self { DepthStencilTarget(PhantomData) }
    fn is_active(&self) -> bool { true }
    fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
        Some((T::get_format().0, (*init).into()))
    }
}

impl<R: Resources, T> DataBind<R> for DepthStencilTarget<T> {
    type Data = (handle::DepthStencilView<R, T>, (target::Stencil, target::Stencil));
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, man: &mut handle::Manager<R>) {
        let dsv = data.0.raw();
        out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), true, true, dsv.get_dimensions());
        out.ref_values.stencil = data.1;
    }
}

impl<'a> DataLink<'a> for Scissor {
    type Init = ();
    fn new() -> Self { Scissor }
    fn is_active(&self) -> bool { true }
}

impl<R: Resources> DataBind<R> for Scissor {
    type Data = target::Rect;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, _: &mut handle::Manager<R>) {
        out.scissor = Some(*data);
    }
}

impl<'a> DataLink<'a> for BlendRef {
    type Init = ();
    fn new() -> Self { BlendRef }
    fn is_active(&self) -> bool { true }
}

impl<R: Resources> DataBind<R> for BlendRef {
    type Data = target::ColorValue;
    fn bind_to(&self, out: &mut RawDataSet<R>, data: &Self::Data, _: &mut handle::Manager<R>) {
        out.ref_values.blend = *data;
    }
}
<|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.

/*! Task-local reference-counted boxes (`Rc` type)

The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
overhead of atomic reference counting.

The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
freed.

For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
pointers, and then storing the parent pointers as `Weak` pointers.

*/

use cast::transmute;
use ops::Drop;
use cmp::{Eq, Ord};
use clone::{Clone, DeepClone};
use kinds::marker;
use rt::global_heap::exchange_free;
use ptr::read_ptr;
use option::{Option, Some, None};

struct RcBox<T> {
    value: T,
    strong: uint,
    weak: uint
}

/// Immutable reference counted pointer type
#[unsafe_no_drop_flag]
pub struct Rc<T> {
    priv ptr: *mut RcBox<T>,
    priv marker: marker::NoSend
}

impl<T> Rc<T> {
    /// Construct a new reference-counted box
    pub fn new(value: T) -> Rc<T> {
        unsafe {
            Rc {
                ptr: transmute(~RcBox { value: value, strong: 1, weak: 0 }),
                marker: marker::NoSend,
            }
        }
    }
}

impl<T> Rc<T> {
    /// Borrow the value contained in the reference-counted box
    #[inline(always)]
    pub fn borrow<'a>(&'a self) -> &'a T {
        unsafe { &(*self.ptr).value }
    }

    /// Downgrade the reference-counted pointer to a weak reference
    pub fn downgrade(&self) -> Weak<T> {
        unsafe {
            (*self.ptr).weak += 1;
            Weak { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Rc<T> {
    fn drop(&mut self) {
        unsafe {
            if self.ptr != 0 as *mut RcBox<T> {
                (*self.ptr).strong -= 1;
                if (*self.ptr).strong == 0 {
                    read_ptr(self.borrow()); // destroy the contained object
                    if (*self.ptr).weak == 0 {
                        exchange_free(self.ptr as *u8)
                    }
                }
            }
        }
    }
}

impl<T> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        unsafe {
            (*self.ptr).strong += 1;
            Rc { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

impl<T: DeepClone> DeepClone for Rc<T> {
    #[inline]
    fn deep_clone(&self) -> Rc<T> {
        Rc::new(self.borrow().deep_clone())
    }
}

impl<T: Eq> Eq for Rc<T> {
    #[inline(always)]
    fn eq(&self, other: &Rc<T>) -> bool { *self.borrow() == *other.borrow() }

    #[inline(always)]
    fn ne(&self, other: &Rc<T>) -> bool { *self.borrow() != *other.borrow() }
}

impl<T: Ord> Ord for Rc<T> {
    #[inline(always)]
    fn lt(&self, other: &Rc<T>) -> bool { *self.borrow() < *other.borrow() }

    #[inline(always)]
    fn le(&self, other: &Rc<T>) -> bool { *self.borrow() <= *other.borrow() }

    #[inline(always)]
    fn gt(&self, other: &Rc<T>) -> bool { *self.borrow() > *other.borrow() }

    #[inline(always)]
    fn ge(&self, other: &Rc<T>) -> bool { *self.borrow() >= *other.borrow() }
}

/// Weak reference to a reference-counted box
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    priv ptr: *mut RcBox<T>,
    priv marker: marker::NoSend
}

impl<T> Weak<T> {
    /// Upgrade a weak reference to a strong reference
    pub fn upgrade(&self) -> Option<Rc<T>> {
        unsafe {
            if (*self.ptr).strong == 0 {
                None
            } else {
                (*self.ptr).strong += 1;
                Some(Rc { ptr: self.ptr, marker: marker::NoSend })
            }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Weak<T> {
    fn drop(&mut self) {
        unsafe {
            if self.ptr != 0 as *mut RcBox<T> {
                (*self.ptr).weak -= 1;
                if (*self.ptr).weak == 0 && (*self.ptr).strong == 0 {
                    exchange_free(self.ptr as *u8)
                }
            }
        }
    }
}

impl<T> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        unsafe {
            (*self.ptr).weak += 1;
            Weak { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use super::*;
    use cell::RefCell;

    #[test]
    fn test_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.clone();
        x.borrow().with_mut(|inner| {
            *inner = 20;
        });
        assert_eq!(y.borrow().with(|v| *v), 20);
    }

    #[test]
    fn test_deep_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.deep_clone();
        x.borrow().with_mut(|inner| {
            *inner = 20;
        });
        assert_eq!(y.borrow().with(|v| *v), 5);
    }

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x.borrow(), 5);
    }

    #[test]
    fn test_simple_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x.borrow(), 5);
        assert_eq!(*y.borrow(), 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(~5);
        assert_eq!(**x.borrow(), 5);
    }

    #[test]
    fn test_live() {
        let x = Rc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Rc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn gc_inside() {
        // see issue #11532
        use gc::Gc;
        let a = Rc::new(RefCell::new(Gc::new(1)));
        assert!(a.borrow().try_borrow_mut().is_some());
    }
}
<commit_msg>Ensure an Rc isn't freed while running its own destructor.<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.

/*! Task-local reference-counted boxes (`Rc` type)

The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
overhead of atomic reference counting.

The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
freed.

For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
pointers, and then storing the parent pointers as `Weak` pointers.

*/

use cast::transmute;
use ops::Drop;
use cmp::{Eq, Ord};
use clone::{Clone, DeepClone};
use kinds::marker;
use rt::global_heap::exchange_free;
use ptr::read_ptr;
use option::{Option, Some, None};

struct RcBox<T> {
    value: T,
    strong: uint,
    weak: uint
}

/// Immutable reference counted pointer type
#[unsafe_no_drop_flag]
pub struct Rc<T> {
    priv ptr: *mut RcBox<T>,
    priv marker: marker::NoSend
}

impl<T> Rc<T> {
    /// Construct a new reference-counted box
    pub fn new(value: T) -> Rc<T> {
        unsafe {
            Rc {
                // there is an implicit weak pointer owned by all the
                // strong pointers, which ensures that the weak
                // destructor never frees the allocation while the
                // strong destructor is running, even if the weak
                // pointer is stored inside the strong one.
                ptr: transmute(~RcBox { value: value, strong: 1, weak: 1 }),
                marker: marker::NoSend,
            }
        }
    }
}

impl<T> Rc<T> {
    /// Borrow the value contained in the reference-counted box
    #[inline(always)]
    pub fn borrow<'a>(&'a self) -> &'a T {
        unsafe { &(*self.ptr).value }
    }

    /// Downgrade the reference-counted pointer to a weak reference
    pub fn downgrade(&self) -> Weak<T> {
        unsafe {
            (*self.ptr).weak += 1;
            Weak { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Rc<T> {
    fn drop(&mut self) {
        unsafe {
            if self.ptr != 0 as *mut RcBox<T> {
                (*self.ptr).strong -= 1;
                if (*self.ptr).strong == 0 {
                    read_ptr(self.borrow()); // destroy the contained object

                    // remove the implicit "strong weak" pointer now
                    // that we've destroyed the contents.
                    (*self.ptr).weak -= 1;

                    if (*self.ptr).weak == 0 {
                        exchange_free(self.ptr as *u8)
                    }
                }
            }
        }
    }
}

impl<T> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        unsafe {
            (*self.ptr).strong += 1;
            Rc { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

impl<T: DeepClone> DeepClone for Rc<T> {
    #[inline]
    fn deep_clone(&self) -> Rc<T> {
        Rc::new(self.borrow().deep_clone())
    }
}

impl<T: Eq> Eq for Rc<T> {
    #[inline(always)]
    fn eq(&self, other: &Rc<T>) -> bool { *self.borrow() == *other.borrow() }

    #[inline(always)]
    fn ne(&self, other: &Rc<T>) -> bool { *self.borrow() != *other.borrow() }
}

impl<T: Ord> Ord for Rc<T> {
    #[inline(always)]
    fn lt(&self, other: &Rc<T>) -> bool { *self.borrow() < *other.borrow() }

    #[inline(always)]
    fn le(&self, other: &Rc<T>) -> bool { *self.borrow() <= *other.borrow() }

    #[inline(always)]
    fn gt(&self, other: &Rc<T>) -> bool { *self.borrow() > *other.borrow() }

    #[inline(always)]
    fn ge(&self, other: &Rc<T>) -> bool { *self.borrow() >= *other.borrow() }
}

/// Weak reference to a reference-counted box
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    priv ptr: *mut RcBox<T>,
    priv marker: marker::NoSend
}

impl<T> Weak<T> {
    /// Upgrade a weak reference to a strong reference
    pub fn upgrade(&self) -> Option<Rc<T>> {
        unsafe {
            if (*self.ptr).strong == 0 {
                None
            } else {
                (*self.ptr).strong += 1;
                Some(Rc { ptr: self.ptr, marker: marker::NoSend })
            }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Weak<T> {
    fn drop(&mut self) {
        unsafe {
            if self.ptr != 0 as *mut RcBox<T> {
                (*self.ptr).weak -= 1;
                // the weak count starts at 1, and will only go to
                // zero if all the strong pointers have disappeared.
                if (*self.ptr).weak == 0 {
                    exchange_free(self.ptr as *u8)
                }
            }
        }
    }
}

impl<T> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        unsafe {
            (*self.ptr).weak += 1;
            Weak { ptr: self.ptr, marker: marker::NoSend }
        }
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use super::*;
    use cell::RefCell;

    #[test]
    fn test_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.clone();
        x.borrow().with_mut(|inner| {
            *inner = 20;
        });
        assert_eq!(y.borrow().with(|v| *v), 20);
    }

    #[test]
    fn test_deep_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.deep_clone();
        x.borrow().with_mut(|inner| {
            *inner = 20;
        });
        assert_eq!(y.borrow().with(|v| *v), 5);
    }

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x.borrow(), 5);
    }

    #[test]
    fn test_simple_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x.borrow(), 5);
        assert_eq!(*y.borrow(), 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(~5);
        assert_eq!(**x.borrow(), 5);
    }

    #[test]
    fn test_live() {
        let x = Rc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Rc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn gc_inside() {
        // see issue #11532
        use gc::Gc;
        let a = Rc::new(RefCell::new(Gc::new(1)));
        assert!(a.borrow().try_borrow_mut().is_some());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: RefCell<Option<Weak<Cycle>>>
        }

        let a = Rc::new(Cycle { x: RefCell::new(None) });
        let b = a.clone().downgrade();
        *a.borrow().x.borrow_mut().get() = Some(b);

        // hopefully we don't double-free (or leak)...
    }
}
<|endoftext|>


<commit_before><commit_msg>exterior mutability illustrated<commit_after><|endoftext|>


<commit_before>extern crate winit;
extern crate ash;
extern crate gfx_core as core;
extern crate gfx_device_vulkan as backend;

#[cfg(target_os = "windows")]
extern crate kernel32;

use ash::vk;
use ash::extensions as ext;
use std::collections::VecDeque;
use std::ptr;
use std::sync::Arc;
use core::FrameSync;
use backend::{conversions as conv, native,
    Instance, VK_ENTRY,
};

pub struct Surface {
    // Vk (EXT) specs [29.2.7 Platform-Independent Information]
    // For vkDestroySurfaceKHR: Host access to surface must be externally synchronized
    raw: Arc<RawSurface>,
    width: u32,
    height: u32,
}

pub struct RawSurface {
    handle: vk::SurfaceKHR,
    functor: ext::Surface,
    instance: Arc<backend::RawInstance>,
}

impl Drop for RawSurface {
    fn drop(&mut self) {
        unsafe {
            self.functor.destroy_surface_khr(self.handle, None);
        }
    }
}

impl Surface {
    fn from_raw(instance: &Instance, surface: vk::SurfaceKHR, (width, height): (u32, u32)) -> Surface {
        let entry = VK_ENTRY.as_ref().expect("Unable to load Vulkan entry points");
        let functor = ext::Surface::new(entry, &instance.raw.0)
            .expect("Unable to load surface functions");

        let raw = Arc::new(RawSurface {
            handle: surface,
            functor,
            instance: instance.raw.clone(),
        });

        Surface {
            raw,
            width,
            height,
        }
    }

    #[cfg(not(target_os = "windows"))]
    fn from_window(window: &winit::Window, instance: &Instance) -> Surface {
        let entry = VK_ENTRY.as_ref().expect("Unable to load Vulkan entry points");

        let surface = instance.surface_extensions.iter().map(|&extension| {
            match extension {
                vk::VK_KHR_XLIB_SURFACE_EXTENSION_NAME => {
                    use winit::os::unix::WindowExt;
                    let xlib_loader = if let Ok(loader) = ash::extensions::XlibSurface::new(entry, &instance.raw.0) {
                        loader
                    } else {
                        return None;
                    };

                    unsafe {
                        let info = vk::XlibSurfaceCreateInfoKHR {
                            s_type: vk::StructureType::XlibSurfaceCreateInfoKhr,
                            p_next: ptr::null(),
                            flags: vk::XlibSurfaceCreateFlagsKHR::empty(),
                            window: window.get_xlib_window().unwrap() as *const _,
                            dpy: window.get_xlib_display().unwrap() as *mut _,
                        };

                        xlib_loader.create_xlib_surface_khr(&info, None).ok()
                    }
                },
                // TODO: other platforms
                _ => None,
            }
        }).find(|x| x.is_some())
          .expect("Unable to find a surface implementation.")
          .unwrap();

        Self::from_raw(instance, surface, window.get_inner_size_pixels().unwrap())
    }

    #[cfg(target_os = "windows")]
    fn from_window(window: &winit::Window, instance: &Instance) -> Surface {
        use winit::os::windows::WindowExt;
        let entry = VK_ENTRY.as_ref().expect("Unable to load Vulkan entry points");
        let win32_loader = ash::extensions::Win32Surface::new(entry, &instance.raw)
            .expect("Unable to load win32 surface functions");

        let surface = unsafe {
            let info = vk::Win32SurfaceCreateInfoKHR {
                s_type: vk::StructureType::Win32SurfaceCreateInfoKhr,
                p_next: ptr::null(),
                flags: vk::Win32SurfaceCreateFlagsKHR::empty(),
                hinstance: unsafe { kernel32::GetModuleHandleW(ptr::null()) } as *mut _,
                hwnd: window.get_hwnd() as *mut _,
            };

            win32_loader.create_win32_surface_khr(&info, None)
                .expect("Error on surface creation")
        };

        Self::from_raw(instance, surface, window.get_inner_size_pixels().unwrap())
    }
}

impl core::Surface<backend::Backend> for Surface {
    type Swapchain = Swapchain;

    fn supports_queue(&self, queue_family: &backend::QueueFamily) -> bool {
        self.raw.functor.get_physical_device_surface_support_khr(
            queue_family.device(),
            queue_family.family_index(), //Note: should be queue index?
            self.raw.handle,
        )
    }

    fn build_swapchain<C>(&mut self,
        config: core::SwapchainConfig,
        present_queue: &core::CommandQueue<backend::Backend, C>,
    ) -> Self::Swapchain
    {
        let functor = ext::Swapchain::new(
            &self.raw.instance.0,
            &present_queue.raw().device().0,
            ).expect("Unable to query swapchain function");

        // TODO: check for better ones if available
        let present_mode = vk::PresentModeKHR::Fifo; // required to be supported

        // TODO: handle depth stencil
        let format = config.color_format;

        let info = vk::SwapchainCreateInfoKHR {
            s_type: vk::StructureType::SwapchainCreateInfoKhr,
            p_next: ptr::null(),
            flags: vk::SwapchainCreateFlagsKHR::empty(),
            surface: self.raw.handle,
            min_image_count: 2, // TODO: let the user specify the value
            image_format: conv::map_format(format.0, format.1).unwrap(),
            image_color_space: vk::ColorSpaceKHR::SrgbNonlinear,
            image_extent: vk::Extent2D {
                width: self.width,
                height: self.height,
            },
            image_array_layers: 1,
            image_usage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
            image_sharing_mode: vk::SharingMode::Exclusive,
            queue_family_index_count: 0,
            p_queue_family_indices: ptr::null(),
            pre_transform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
            composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
            present_mode: present_mode,
            clipped: 1,
            old_swapchain: vk::SwapchainKHR::null(),
        };

        let swapchain = unsafe {
            functor.create_swapchain_khr(&info, None)
        }.expect("Unable to create a swapchain");

        let backbuffer_images = {
            functor.get_swapchain_images_khr(swapchain)
        }.expect("Unable to get swapchain images");

        let backbuffers = backbuffer_images
            .into_iter()
            .map(|image| {
                core::Backbuffer {
                    color: native::Image {
                        raw: image,
                        bytes_per_texel: 4,
                        extent: vk::Extent3D {
                            width: self.width,
                            height: self.height,
                            depth: 1,
                        },
                    },
                    depth_stencil: None,
                }
            }).collect();

        Swapchain {
            raw: swapchain,
            functor,
            backbuffers,
            frame_queue: VecDeque::new(),
        }
    }
}

pub struct Swapchain {
    raw: vk::SwapchainKHR,
    functor: ext::Swapchain,
    backbuffers: Vec<core::Backbuffer<backend::Backend>>,
    // Queued up frames for presentation
    frame_queue: VecDeque<usize>,
}

impl core::Swapchain<backend::Backend> for Swapchain {
    fn get_backbuffers(&mut self) -> &[core::Backbuffer<backend::Backend>] {
        &self.backbuffers
    }

    fn acquire_frame(&mut self, sync: FrameSync<backend::Backend>) -> core::Frame {
        let (semaphore, fence) = match sync {
            FrameSync::Semaphore(semaphore) => {
                (semaphore.0, vk::Fence::null())
            }
            FrameSync::Fence(fence) => {
                (vk::Semaphore::null(), fence.0)
            }
        };

        let index = unsafe {
            // will block if no image is available
            self.functor.acquire_next_image_khr(self.raw, std::u64::MAX, semaphore, fence)
        }.expect("Unable to acquire a swapchain image");

        self.frame_queue.push_back(index as usize);
        core::Frame::new(index as usize)
    }

    fn present<C>(&mut self,
        present_queue: &mut core::CommandQueue<backend::Backend, C>,
        wait_semaphores: &[&native::Semaphore],
    ) {
        let frame = self.frame_queue
            .pop_front()
            .expect("No frame currently queued up. Need to acquire a frame first.");

        let semaphores = wait_semaphores
            .iter()
            .map(|sem| sem.0)
            .collect::<Vec<_>>();

        // TODO: wait semaphores
        let info = vk::PresentInfoKHR {
            s_type: vk::StructureType::PresentInfoKhr,
            p_next: ptr::null(),
            wait_semaphore_count: semaphores.len() as u32,
            p_wait_semaphores: semaphores.as_ptr(),
            swapchain_count: 1,
            p_swapchains: &self.raw,
            p_image_indices: &(frame as u32),
            p_results: ptr::null_mut(),
        };

        assert_eq!(Ok(()), unsafe {
            self.functor.queue_present_khr(*present_queue.raw().raw(), &info)
        });
        // TODO: handle result and return code
    }
}

pub struct Window(pub winit::Window);

impl core::WindowExt<backend::Backend> for Window {
    type Surface = Surface;
    type Adapter = backend::Adapter;

    fn get_surface_and_adapters(&mut self) -> (Surface, Vec<backend::Adapter>) {
        let instance = Instance::create("gfx-rs demo", 0);
        let surface = Surface::from_window(&self.0, &instance);
        let adapters = Instance::enumerate_adapters(&instance);
        (surface, adapters)
    }
}
<commit_msg>[ll] vk: Reformat vulkan window backend<commit_after>extern crate winit;
extern crate ash;
extern crate gfx_core as core;
extern crate gfx_device_vulkan as backend;

#[cfg(target_os = "windows")]
extern crate kernel32;

use ash::vk;
use ash::extensions as ext;
use std::collections::VecDeque;
use std::ptr;
use std::sync::Arc;
use core::FrameSync;
use backend::{conversions as conv, native, Instance, VK_ENTRY};

pub struct Surface {
    // Vk (EXT) specs [29.2.7 Platform-Independent Information]
    // For vkDestroySurfaceKHR: Host access to surface must be externally synchronized
    raw: Arc<RawSurface>,
    width: u32,
    height: u32,
}

pub struct RawSurface {
    handle: vk::SurfaceKHR,
    functor: ext::Surface,
    instance: Arc<backend::RawInstance>,
}

impl Drop for RawSurface {
    fn drop(&mut self) {
        unsafe {
            self.functor.destroy_surface_khr(self.handle, None);
        }
    }
}

impl Surface {
    fn from_raw(
        instance: &Instance,
        surface: vk::SurfaceKHR,
        (width, height): (u32, u32),
    ) -> Surface {
        let entry = VK_ENTRY
            .as_ref()
            .expect("Unable to load Vulkan entry points");
        let functor =
            ext::Surface::new(entry, &instance.raw.0).expect("Unable to load surface functions");

        let raw = Arc::new(RawSurface {
            handle: surface,
            functor,
            instance: instance.raw.clone(),
        });

        Surface { raw, width, height }
    }

    #[cfg(not(target_os = "windows"))]
    fn from_window(window: &winit::Window, instance: &Instance) -> Surface {
        let entry = VK_ENTRY
            .as_ref()
            .expect("Unable to load Vulkan entry points");

        let surface = instance
            .surface_extensions
            .iter()
            .map(|&extension| {
                match extension {
                    vk::VK_KHR_XLIB_SURFACE_EXTENSION_NAME => {
                        use winit::os::unix::WindowExt;
                        let xlib_loader = if let Ok(loader) =
                            ash::extensions::XlibSurface::new(entry, &instance.raw.0)
                        {
                            loader
                        } else {
                            return None;
                        };

                        unsafe {
                            let info = vk::XlibSurfaceCreateInfoKHR {
                                s_type: vk::StructureType::XlibSurfaceCreateInfoKhr,
                                p_next: ptr::null(),
                                flags: vk::XlibSurfaceCreateFlagsKHR::empty(),
                                window: window.get_xlib_window().unwrap() as *const _,
                                dpy: window.get_xlib_display().unwrap() as *mut _,
                            };

                            xlib_loader.create_xlib_surface_khr(&info, None).ok()
                        }
                    }
                    // TODO: other platforms
                    _ => None,
                }
            })
            .find(|x| x.is_some())
            .expect("Unable to find a surface implementation.")
            .unwrap();

        Self::from_raw(instance, surface, window.get_inner_size_pixels().unwrap())
    }

    #[cfg(target_os = "windows")]
    fn from_window(window: &winit::Window, instance: &Instance) -> Surface {
        use winit::os::windows::WindowExt;
        let entry = VK_ENTRY
            .as_ref()
            .expect("Unable to load Vulkan entry points");
        let win32_loader = ash::extensions::Win32Surface::new(entry, &instance.raw)
            .expect("Unable to load win32 surface functions");

        let surface = unsafe {
            let info = vk::Win32SurfaceCreateInfoKHR {
                s_type: vk::StructureType::Win32SurfaceCreateInfoKhr,
                p_next: ptr::null(),
                flags: vk::Win32SurfaceCreateFlagsKHR::empty(),
                hinstance: kernel32::GetModuleHandleW(ptr::null()) as *mut _,
                hwnd: window.get_hwnd() as *mut _,
            };

            win32_loader
                .create_win32_surface_khr(&info, None)
                .expect("Error on surface creation")
        };

        Self::from_raw(instance, surface, window.get_inner_size_pixels().unwrap())
    }
}

impl core::Surface<backend::Backend> for Surface {
    type Swapchain = Swapchain;

    fn supports_queue(&self, queue_family: &backend::QueueFamily) -> bool {
        self.raw.functor.get_physical_device_surface_support_khr(
            queue_family.device(),
            queue_family.family_index(), //Note: should be queue index?
            self.raw.handle,
        )
    }

    fn build_swapchain<C>(
        &mut self,
        config: core::SwapchainConfig,
        present_queue: &core::CommandQueue<backend::Backend, C>,
    ) -> Self::Swapchain {
        let functor = ext::Swapchain::new(&self.raw.instance.0, &present_queue.raw().device().0)
            .expect("Unable to query swapchain function");

        // TODO: check for better ones if available
        let present_mode = vk::PresentModeKHR::Fifo; // required to be supported

        // TODO: handle depth stencil
        let format = config.color_format;

        let info = vk::SwapchainCreateInfoKHR {
            s_type: vk::StructureType::SwapchainCreateInfoKhr,
            p_next: ptr::null(),
            flags: vk::SwapchainCreateFlagsKHR::empty(),
            surface: self.raw.handle,
            min_image_count: 2, // TODO: let the user specify the value
            image_format: conv::map_format(format.0, format.1).unwrap(),
            image_color_space: vk::ColorSpaceKHR::SrgbNonlinear,
            image_extent: vk::Extent2D {
                width: self.width,
                height: self.height,
            },
            image_array_layers: 1,
            image_usage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
            image_sharing_mode: vk::SharingMode::Exclusive,
            queue_family_index_count: 0,
            p_queue_family_indices: ptr::null(),
            pre_transform: vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
            composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
            present_mode: present_mode,
            clipped: 1,
            old_swapchain: vk::SwapchainKHR::null(),
        };

        let swapchain = unsafe { functor.create_swapchain_khr(&info, None) }
            .expect("Unable to create a swapchain");

        let backbuffer_images = { functor.get_swapchain_images_khr(swapchain) }
            .expect("Unable to get swapchain images");

        let backbuffers = backbuffer_images
            .into_iter()
            .map(|image| {
                core::Backbuffer {
                    color: native::Image {
                        raw: image,
                        bytes_per_texel: 4,
                        extent: vk::Extent3D {
                            width: self.width,
                            height: self.height,
                            depth: 1,
                        },
                    },
                    depth_stencil: None,
                }
            })
            .collect();

        Swapchain {
            raw: swapchain,
            functor,
            backbuffers,
            frame_queue: VecDeque::new(),
        }
    }
}

pub struct Swapchain {
    raw: vk::SwapchainKHR,
    functor: ext::Swapchain,
    backbuffers: Vec<core::Backbuffer<backend::Backend>>,
    // Queued up frames for presentation
    frame_queue: VecDeque<usize>,
}

impl core::Swapchain<backend::Backend> for Swapchain {
    fn get_backbuffers(&mut self) -> &[core::Backbuffer<backend::Backend>] {
        &self.backbuffers
    }

    fn acquire_frame(&mut self, sync: FrameSync<backend::Backend>) -> core::Frame {
        let (semaphore, fence) = match sync {
            FrameSync::Semaphore(semaphore) => (semaphore.0, vk::Fence::null()),
            FrameSync::Fence(fence) => (vk::Semaphore::null(), fence.0),
        };

        let index = unsafe {
            // will block if no image is available
            self.functor
                .acquire_next_image_khr(self.raw, std::u64::MAX, semaphore, fence)
        }.expect("Unable to acquire a swapchain image");

        self.frame_queue.push_back(index as usize);
        core::Frame::new(index as usize)
    }

    fn present<C>(
        &mut self,
        present_queue: &mut core::CommandQueue<backend::Backend, C>,
        wait_semaphores: &[&native::Semaphore],
    ) {
        let frame = self.frame_queue.pop_front().expect(
            "No frame currently queued up. Need to acquire a frame first.",
        );

        let semaphores = wait_semaphores.iter().map(|sem| sem.0).collect::<Vec<_>>();

        // TODO: wait semaphores
        let info = vk::PresentInfoKHR {
            s_type: vk::StructureType::PresentInfoKhr,
            p_next: ptr::null(),
            wait_semaphore_count: semaphores.len() as u32,
            p_wait_semaphores: semaphores.as_ptr(),
            swapchain_count: 1,
            p_swapchains: &self.raw,
            p_image_indices: &(frame as u32),
            p_results: ptr::null_mut(),
        };

        assert_eq!(Ok(()), unsafe {
            self.functor
                .queue_present_khr(*present_queue.raw().raw(), &info)
        });
        // TODO: handle result and return code
    }
}

pub struct Window(pub winit::Window);

impl core::WindowExt<backend::Backend> for Window {
    type Surface = Surface;
    type Adapter = backend::Adapter;

    fn get_surface_and_adapters(&mut self) -> (Surface, Vec<backend::Adapter>) {
        let instance = Instance::create("gfx-rs demo", 0);
        let surface = Surface::from_window(&self.0, &instance);
        let adapters = Instance::enumerate_adapters(&instance);
        (surface, adapters)
    }
}
<|endoftext|>


<commit_before><commit_msg>added more buffers<commit_after><|endoftext|>


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


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


<commit_before>#[derive(PartialEq)]
#[derive(Debug)]
pub enum Token {
    Word(String),
    End,
}

enum TokenizerState {
    Default,
    DoubleQuoted,
    SingleQuoted,
    Commented,
}

fn process_character_double_quoted(_: &mut Vec<Token>,
                                   current_token: &mut String,
                                   chr: char) -> TokenizerState {
    match chr {
        '"' => TokenizerState::Default,
        _ => {
            current_token.push(chr);
            TokenizerState::DoubleQuoted
        },
    }
}

fn process_character_single_quoted(_: &mut Vec<Token>,
                                   current_token: &mut String,
                                   chr: char) -> TokenizerState {
    match chr {
        '\'' => TokenizerState::Default,
        _ => {
            current_token.push(chr);
            TokenizerState::SingleQuoted
        },
    }
}

fn process_character_default(tokens: &mut Vec<Token>,
                             current_token: &mut String,
                             chr: char) -> TokenizerState {
    let mut next_state = TokenizerState::Default;
    match chr {
        ' ' | '\t' => {
            if !current_token.is_empty() {
                tokens.push(Token::Word(current_token.clone()));
                current_token.clear();
            }
        },
        '#' => {
            next_state = TokenizerState::Commented;
        },
        '\n' | '\r' | ';' => {
            if !current_token.is_empty() {
                tokens.push(Token::Word(current_token.clone()));
                current_token.clear();
            }
            tokens.push(Token::End);
        }
        '"' => {
            next_state = TokenizerState::DoubleQuoted;
        },
        '\'' => {
            next_state = TokenizerState::SingleQuoted;
        },
        _ => {
            current_token.push(chr);
        },
    }
    next_state
}

pub fn tokenize(input: &str) -> Vec<Token> {
    let mut state = TokenizerState::Default;
    let mut tokens: Vec<Token> = vec![];
    let mut current_token: String = String::new();
    for chr in input.chars() {
        state = match state {
            TokenizerState::DoubleQuoted =>
                process_character_double_quoted(&mut tokens, &mut current_token, chr),
            TokenizerState::SingleQuoted =>
                process_character_single_quoted(&mut tokens, &mut current_token, chr),
            TokenizerState::Commented => TokenizerState::Commented,
            _ => process_character_default(&mut tokens, &mut current_token, chr),
        }
    }
    if !current_token.is_empty() {
        tokens.push(Token::Word(current_token.clone()));
    }
    tokens.push(Token::End);
    tokens
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn tokenize_empty_string() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize(""));
    }

    #[test]
    fn tokenize_single_word() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word"));
    }

    #[test]
    fn tokenize_whitespace() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize(" \t   "));
    }

    #[test]
    fn tokenize_multiple_words() {
        let expected = vec![
            Token::Word("one".to_string()),
            Token::Word("two".to_string()),
            Token::Word("three".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("one two three"));
    }

    #[test]
    fn tokenize_comment() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize("# some text"));
    }

    #[test]
    fn tokenize_end_of_line_comment() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word # more stuff"));
    }

    #[test]
    fn tokenize_newline_produces_end_token() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word"));
    }

    #[test]
    fn double_quotes_escape_space() {
        let expected = vec![
            Token::Word("escaped space".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("\"escaped space\""));
    }

    #[test]
    fn mixed_quoted_and_unquoted() {
        let expected = vec![
            Token::Word("one".to_string()),
            Token::Word("two# three".to_string()),
            Token::Word("four".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("one \"two# three\" four"));
    }

    #[test]
    fn mixed_double_and_single_quotes() {
        let expected = vec![
            Token::Word("''".to_string()),
            Token::Word("\"\"".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("\"''\" '\"\"'"));
    }
}
<commit_msg>End comment when newline is reached<commit_after>#[derive(PartialEq)]
#[derive(Debug)]
pub enum Token {
    Word(String),
    End,
}

enum TokenizerState {
    Default,
    DoubleQuoted,
    SingleQuoted,
    Commented,
}

fn process_character_double_quoted(_: &mut Vec<Token>,
                                   current_token: &mut String,
                                   chr: char) -> TokenizerState {
    match chr {
        '"' => TokenizerState::Default,
        _ => {
            current_token.push(chr);
            TokenizerState::DoubleQuoted
        },
    }
}

fn process_character_single_quoted(_: &mut Vec<Token>,
                                   current_token: &mut String,
                                   chr: char) -> TokenizerState {
    match chr {
        '\'' => TokenizerState::Default,
        _ => {
            current_token.push(chr);
            TokenizerState::SingleQuoted
        },
    }
}

fn process_character_comment(tokens: &mut Vec<Token>,
                             current_token: &mut String,
                             chr: char) -> TokenizerState {
    match chr {
        '\n' | '\r' => {
            tokens.push(Token::End);
            TokenizerState::Default
        },
        _ => TokenizerState::Commented
    }
}

fn process_character_default(tokens: &mut Vec<Token>,
                             current_token: &mut String,
                             chr: char) -> TokenizerState {
    let mut next_state = TokenizerState::Default;
    match chr {
        ' ' | '\t' => {
            if !current_token.is_empty() {
                tokens.push(Token::Word(current_token.clone()));
                current_token.clear();
            }
        },
        '#' => {
            next_state = TokenizerState::Commented;
        },
        '\n' | '\r' | ';' => {
            if !current_token.is_empty() {
                tokens.push(Token::Word(current_token.clone()));
                current_token.clear();
            }
            tokens.push(Token::End);
        }
        '"' => {
            next_state = TokenizerState::DoubleQuoted;
        },
        '\'' => {
            next_state = TokenizerState::SingleQuoted;
        },
        _ => {
            current_token.push(chr);
        },
    }
    next_state
}

pub fn tokenize(input: &str) -> Vec<Token> {
    let mut state = TokenizerState::Default;
    let mut tokens: Vec<Token> = vec![];
    let mut current_token: String = String::new();
    for chr in input.chars() {
        state = match state {
            TokenizerState::DoubleQuoted =>
                process_character_double_quoted(&mut tokens, &mut current_token, chr),
            TokenizerState::SingleQuoted =>
                process_character_single_quoted(&mut tokens, &mut current_token, chr),
            TokenizerState::Commented =>
                process_character_comment(&mut tokens, &mut current_token, chr),
            _ => process_character_default(&mut tokens, &mut current_token, chr),
        }
    }
    if !current_token.is_empty() {
        tokens.push(Token::Word(current_token.clone()));
    }
    tokens.push(Token::End);
    tokens
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn tokenize_empty_string() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize(""));
    }

    #[test]
    fn tokenize_single_word() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word"));
    }

    #[test]
    fn tokenize_whitespace() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize(" \t   "));
    }

    #[test]
    fn tokenize_multiple_words() {
        let expected = vec![
            Token::Word("one".to_string()),
            Token::Word("two".to_string()),
            Token::Word("three".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("one two three"));
    }

    #[test]
    fn tokenize_comment() {
        let expected = vec![Token::End];
        assert_eq!(expected, tokenize("# some text"));
    }

    #[test]
    fn tokenize_end_of_line_comment() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word # more stuff"));
    }

    #[test]
    fn tokenize_newline_produces_end_token() {
        let expected = vec![
            Token::Word("word".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("word"));
    }

    #[test]
    fn double_quotes_escape_space() {
        let expected = vec![
            Token::Word("escaped space".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("\"escaped space\""));
    }

    #[test]
    fn mixed_quoted_and_unquoted() {
        let expected = vec![
            Token::Word("one".to_string()),
            Token::Word("two# three".to_string()),
            Token::Word("four".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("one \"two# three\" four"));
    }

    #[test]
    fn mixed_double_and_single_quotes() {
        let expected = vec![
            Token::Word("''".to_string()),
            Token::Word("\"\"".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("\"''\" '\"\"'"));
    }

    #[test]
    fn comment_before_newline() {
        let expected = vec![
            Token::Word("ls".to_string()),
            Token::End,
            Token::Word("help".to_string()),
            Token::End];
        assert_eq!(expected, tokenize("ls # look in dir\nhelp"));
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement Responder for Response.<commit_after><|endoftext|>


<commit_before><commit_msg>higher_order_functions<commit_after><|endoftext|>


<commit_before><commit_msg>Create linked_list.rs<commit_after>// Linked list implementation using rust semantics

#[derive(Debug)]
enum NextOrNone {
	Next(Box<Node>),
	None,
}

use NextOrNone::{Next,None};

#[derive(Debug)]
struct Node {
	data: u32,
	next: Box<NextOrNone>,
}

impl Node {

	fn init(val:u32) -> Node {
		Node {data:val,next:Box::new(None)}
	}

}

fn main() {

	let head = Node::init(23);

}
<|endoftext|>


<commit_before><commit_msg>keeper close<commit_after><|endoftext|>


<commit_before><commit_msg>build: don't collect child proc output<commit_after><|endoftext|>


<commit_before><commit_msg>Added files via upload<commit_after>//extern crate rustc_serialize;
//extern crate hyper;
//#[macro_use] extern crate lazy_static;

//mod util;

mod examples {
    mod hello_world;

}

#[test]
fn test_works() {}<|endoftext|>