<commit_before>
#[derive(Show,Clone)]
pub enum Exp<'x> {
    Value(int),
    Plus(Box<Exp<'x>>, Box<Exp<'x>>),

    // Meta nodes:
    StepsTo(&'x Exp<'x>,Box<Exp<'x>>), // Expresses a StepsTo Relationship,
    Ref(&'x Exp<'x>), // Refs allow for (non-affine) sharing.
}

mod borrow {
    use super::Exp;

    pub fn step<'x> (e:&'x Exp<'x>) -> Option<Exp<'x>> {
        match *e {
            Exp::Value(_) => None,
            Exp::Ref(e) => step(e),
            Exp::StepsTo(_, ref after) => step(&**after),
            Exp::Plus(ref e1, ref e2) =>
                match **e1 {
                    Exp::Value(n) =>
                        match **e2 {
                            Exp::Value(m) => Some(Exp::Value(n+m)),
                            _ => {
                                let e2_ = step(&**e2) ;
                                match e2_ {
                                    None => panic!("impossible"),
                                    Some(e2_) => Some(Exp::Plus(box Exp::Value(n), box e2_))
                                }
                            }
                        },

                    _ => {
                        let e1_ = step(&**e1) ;
                        match e1_ {
                            None => panic!("impossible"),
                            Some(e1_) => Some(Exp::Plus(box e1_, box Exp::Ref(&**e2)))
                        }
                    }
                }
        }
    }
}

pub fn test1 () {
    let e0 = Exp::Plus(box Exp::Plus(box Exp::Value(0),
                                     box Exp::Value(1)),
                       box Exp::Plus(box Exp::Value(2),
                                     box Exp::Plus(box Exp::Plus(box Exp::Value(0),
                                                                 box Exp::Value(3)),
                                                   box Exp::Plus(box Exp::Value(4),
                                                                 box Exp::Value(5))))) ;
    let e1 = borrow::step(&e0) ;
    match e1 {
        None => (),
        Some(ref e1) => {
            println!("{} --> {}", e0, e1) ;
            let e2 = borrow::step( e1 ) ;
            match e2 {
                None => (),
                Some(ref e2) => {
                    println!("{} --> {}", e1, e2) ;
                    let e3 = borrow::step( e2 ) ;
                    match e3 {
                        None => (),
                        Some(ref e3) => {
                            println!("{} --> {}", e2, e3) ;
                            let e4 = borrow::step( e3 ) ;
                            match e4 {
                                None => (),
                                Some(ref e4) => {
                                    println!("{} --> {}", e3, e4) ;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

fn step_loop<'x> ( stepcnt : int, exp : Exp<'x> ) {
    let s = borrow::step(&exp) ;
    match s {
        None => (), // exp
        Some(exp_) => {
            println!("{}: {} --> {}\n", stepcnt, exp, exp_) ;
            let step_full = Exp::StepsTo( &exp, box exp_) ;
            step_loop ( stepcnt+1, step_full )
        }
    }
}

pub fn test2 () {
    let e0 = Exp::Plus(box Exp::Value(1),
                       box Exp::Plus(box Exp::Value(2),
                                     box Exp::Plus(box Exp::Value(3),
                                                   box Exp::Plus(box Exp::Value(4),
                                                                 box Exp::Value(5))))) ;
    let e_trace = step_loop ( 0, e0 ) ;
    println!("Final trace: {}", e_trace)
}

pub fn main () {
    if false {
        test1 ()
    }
    else {
        test2 ()
    }
}
<commit_msg>no clone needed<commit_after>
#[derive(Show)]
pub enum Exp<'x> {
    Value(int),
    Plus(Box<Exp<'x>>, Box<Exp<'x>>),

    // Meta nodes:
    StepsTo(&'x Exp<'x>,Box<Exp<'x>>), // Expresses a StepsTo Relationship,
    Ref(&'x Exp<'x>), // Refs allow for (non-affine) sharing.
}

mod borrow {
    use super::Exp;

    pub fn step<'x> (e:&'x Exp<'x>) -> Option<Exp<'x>> {
        match *e {
            Exp::Value(_) => None,
            Exp::Ref(e) => step(e),
            Exp::StepsTo(_, ref after) => step(&**after),
            Exp::Plus(ref e1, ref e2) =>
                match **e1 {
                    Exp::Value(n) =>
                        match **e2 {
                            Exp::Value(m) => Some(Exp::Value(n+m)),
                            _ => {
                                let e2_ = step(&**e2) ;
                                match e2_ {
                                    None => panic!("impossible"),
                                    Some(e2_) => Some(Exp::Plus(box Exp::Value(n), box e2_))
                                }
                            }
                        },

                    _ => {
                        let e1_ = step(&**e1) ;
                        match e1_ {
                            None => panic!("impossible"),
                            Some(e1_) => Some(Exp::Plus(box e1_, box Exp::Ref(&**e2)))
                        }
                    }
                }
        }
    }
}

pub fn test1 () {
    let e0 = Exp::Plus(box Exp::Plus(box Exp::Value(0),
                                     box Exp::Value(1)),
                       box Exp::Plus(box Exp::Value(2),
                                     box Exp::Plus(box Exp::Plus(box Exp::Value(0),
                                                                 box Exp::Value(3)),
                                                   box Exp::Plus(box Exp::Value(4),
                                                                 box Exp::Value(5))))) ;
    let e1 = borrow::step(&e0) ;
    match e1 {
        None => (),
        Some(ref e1) => {
            println!("{} --> {}", e0, e1) ;
            let e2 = borrow::step( e1 ) ;
            match e2 {
                None => (),
                Some(ref e2) => {
                    println!("{} --> {}", e1, e2) ;
                    let e3 = borrow::step( e2 ) ;
                    match e3 {
                        None => (),
                        Some(ref e3) => {
                            println!("{} --> {}", e2, e3) ;
                            let e4 = borrow::step( e3 ) ;
                            match e4 {
                                None => (),
                                Some(ref e4) => {
                                    println!("{} --> {}", e3, e4) ;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

fn step_loop<'x> ( stepcnt : int, exp : Exp<'x> ) {
    let s = borrow::step(&exp) ;
    match s {
        None => (), // exp
        Some(exp_) => {
            println!("{}: {} --> {}\n", stepcnt, exp, exp_) ;
            let step_full = Exp::StepsTo( &exp, box exp_) ;
            step_loop ( stepcnt+1, step_full )
        }
    }
}

pub fn test2 () {
    let e0 = Exp::Plus(box Exp::Value(1),
                       box Exp::Plus(box Exp::Value(2),
                                     box Exp::Plus(box Exp::Value(3),
                                                   box Exp::Plus(box Exp::Value(4),
                                                                 box Exp::Value(5))))) ;
    let e_trace = step_loop ( 0, e0 ) ;
    println!("Final trace: {}", e_trace)
}

pub fn main () {
    if false {
        test1 ()
    }
    else {
        test2 ()
    }
}
<|endoftext|>


<commit_before>#![allow(unused_variables)]
#![allow(unused_imports)]

/// Note: Fred must be compiled with the `enable-tls` feature for this to work.

extern crate fred;
extern crate tokio_core;
extern crate futures;

use fred::RedisClient;
use fred::types::*;

use tokio_core::reactor::Core;
use futures::Future;

fn main() {
  let config = RedisConfig::Centralized {
    // Note: this must match the hostname tied to the cert
    host: "foo.bar.com".into(),
    port: 6379,
    key: Some("key".into()),
    // if compiled without `enable-tls` setting this to `true` does nothing, which is done to avoid requiring TLS dependencies unless necessary
    tls: true,
    max_value_size: None
  };

  // otherwise usage is the same as the non-tls client...

  let mut core = Core::new().unwrap();
  let handle = core.handle();

  println!("Connecting to {:?}...", config);

  let client = RedisClient::new(config);
  let connection = client.connect(&handle);

  let commands = client.on_connect().and_then(|client| {
    println!("Client connected.");

    client.select(0)
  })
  .and_then(|client| {
    println!("Selected database.");cargo

    client.info(None)
  })
  .and_then(|(client, info)| {
    println!("Redis server info: {}", info);

    client.get("foo")
  })
  .and_then(|(client, result)| {
    println!("Got foo: {:?}", result);

    client.set("foo", "bar", Some(Expiration::PX(1000)), Some(SetOptions::NX))
  })
  .and_then(|(client, result)| {
    println!("Set 'bar' at 'foo'? {}. Subscribing to 'baz'...", result);

    client.subscribe("baz")
  })
  .and_then(|(client, result)| {
    println!("Subscribed to 'baz'. Now subscribed to {} channels. Now exiting...", result);

    client.quit()
  });

  let (reason, client) = match core.run(connection.join(commands)) {
    Ok((r, c)) => (r, c),
    Err(e) => panic!("Connection closed abruptly: {}", e)
  };

  println!("Connection closed gracefully with error: {:?}", reason);
}<commit_msg>update tls<commit_after>#![allow(unused_variables)]
#![allow(unused_imports)]

/// Note: Fred must be compiled with the `enable-tls` feature for this to work.

extern crate fred;
extern crate tokio_core;
extern crate futures;

use fred::RedisClient;
use fred::types::*;

use tokio_core::reactor::Core;
use futures::Future;

fn main() {
  let config = RedisConfig::Centralized {
    // Note: this must match the hostname tied to the cert
    host: "foo.bar.com".into(),
    port: 6379,
    key: Some("key".into()),
    // if compiled without `enable-tls` setting this to `true` does nothing, which is done to avoid requiring TLS dependencies unless necessary
    tls: true,
    max_value_size: None
  };

  // otherwise usage is the same as the non-tls client...

  let mut core = Core::new().unwrap();
  let handle = core.handle();

  println!("Connecting to {:?}...", config);

  let client = RedisClient::new(config);
  let connection = client.connect(&handle);

  let commands = client.on_connect().and_then(|client| {
    println!("Client connected.");

    client.select(0)
  })
  .and_then(|client| {
    println!("Selected database.");

    client.info(None)
  })
  .and_then(|(client, info)| {
    println!("Redis server info: {}", info);

    client.get("foo")
  })
  .and_then(|(client, result)| {
    println!("Got foo: {:?}", result);

    client.set("foo", "bar", Some(Expiration::PX(1000)), Some(SetOptions::NX))
  })
  .and_then(|(client, result)| {
    println!("Set 'bar' at 'foo'? {}. Subscribing to 'baz'...", result);

    client.subscribe("baz")
  })
  .and_then(|(client, result)| {
    println!("Subscribed to 'baz'. Now subscribed to {} channels. Now exiting...", result);

    client.quit()
  });

  let (reason, client) = match core.run(connection.join(commands)) {
    Ok((r, c)) => (r, c),
    Err(e) => panic!("Connection closed abruptly: {}", e)
  };

  println!("Connection closed gracefully with error: {:?}", reason);
}<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::marker::PhantomData;
use std::sync::Arc;

use buffer::TypedBuffer;
use descriptor::descriptor::DescriptorType;
use descriptor::descriptor_set::DescriptorWrite;
use image::ImageView;
use sampler::Sampler;

/// Call this macro with the layout of a pipeline to generate some helper structs that wrap around
/// vulkano's unsafe APIs.
// TODO: more docs
#[macro_export]
macro_rules! pipeline_layout {
    (push_constants: { $($pc_f:ident: $pc_t:ty),* } $(, $name:ident: { $($field:ident: $ty:ty),* })*) => {
        use std::mem;
        use std::sync::Arc;
        use std::vec::IntoIter as VecIntoIter;
        use $crate::device::Device;
        use $crate::descriptor::descriptor::DescriptorDesc;
        use $crate::descriptor::descriptor::ShaderStages;
        use $crate::descriptor::pipeline_layout::PipelineLayout;
        use $crate::descriptor::pipeline_layout::PipelineLayoutDesc;
        use $crate::descriptor::pipeline_layout::UnsafePipelineLayout;
        use $crate::descriptor::pipeline_layout::UnsafePipelineLayoutCreationError;

        #[derive(Debug, Copy, Clone)]
        pub struct PushConstants {
            $(pub $pc_f: $pc_t,)*
        }

        pub struct CustomPipeline {
            inner: UnsafePipelineLayout
        }

        impl CustomPipeline {
            #[allow(unsafe_code)]
            pub fn new(device: &Arc<Device>)
                       -> Result<Arc<CustomPipeline>, UnsafePipelineLayoutCreationError>
            {
                let layouts = vec![
                    $(
                        Arc::new(try!($name::build_set_layout_raw(device)))
                    ),*
                ];

                let push_constants = if mem::size_of::<PushConstants>() >= 1 {
                    Some((0, mem::size_of::<PushConstants>(), ShaderStages::all()))
                } else {
                    None
                };

                let inner = {
                    try!(UnsafePipelineLayout::new(device, layouts.iter(), push_constants))
                };

                Ok(Arc::new(CustomPipeline {
                    inner: inner
                }))
            }
        }

        #[allow(unsafe_code)]
        unsafe impl PipelineLayout for CustomPipeline {
            #[inline]
            fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout {
                &self.inner
            }
        }

        #[allow(unsafe_code)]
        unsafe impl PipelineLayoutDesc for CustomPipeline {
            type SetsIter = VecIntoIter<Self::DescIter>;
            type DescIter = VecIntoIter<DescriptorDesc>;

            fn descriptors_desc(&self) -> Self::SetsIter {
                // FIXME:
                vec![].into_iter()
            }
        }

        /* TODO: uncomment when specialization lands
        #[allow(unsafe_code)]
        unsafe impl<'a> PipelineLayoutSetsCompatible<($(&'a Arc<$name::Set>),*)> for CustomPipeline {
            #[inline]
            default fn is_compatible(&self, _: &($(&'a Arc<$name::Set>),*)) -> bool {
                true
            }
        }*/

        pipeline_layout!{__inner__ (0) $($name: {$($field: $ty),*})*}
    };

    ($($name:ident: { $($field:ident: $ty:ty),* }),*) => {
        pipeline_layout!{ push_constants: {} $(, $name: {$($field: $ty),*})* }
    };

    (__inner__ ($num:expr) $name:ident: { $($field:ident: $ty:ty),* } $($rest:tt)*) => {
        pub mod $name {
            #![allow(unused_imports)]

            use std::sync::Arc;
            use std::vec::IntoIter as VecIntoIter;
            use super::CustomPipeline;
            use $crate::OomError;
            use $crate::device::Device;
            use $crate::descriptor::descriptor::DescriptorDesc;
            use $crate::descriptor::descriptor::ShaderStages;
            use $crate::descriptor::descriptor_set::DescriptorPool;
            use $crate::descriptor::descriptor_set::DescriptorSet;
            use $crate::descriptor::descriptor_set::DescriptorSetDesc;
            use $crate::descriptor::descriptor_set::UnsafeDescriptorSet;
            use $crate::descriptor::descriptor_set::UnsafeDescriptorSetLayout;
            use $crate::descriptor::descriptor_set::DescriptorWrite;
            use $crate::descriptor::pipeline_layout::PipelineLayout;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::CombinedImageSampler;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::DescriptorMarker;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::StorageBuffer;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::UniformBuffer;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::ValidParameter;

            // This constant is part of the API, but Rust sees it as dead code.
            #[allow(dead_code)]
            pub const SET_NUM: u32 = $num;

            #[allow(non_camel_case_types)]
            pub struct Descriptors<$($field),*> {
                $(
                    pub $field: $field
                ),*
            }

            #[allow(non_camel_case_types)]
            #[allow(unused_assignments)]
            impl<$($field: ValidParameter<$ty>),*> Descriptors<$($field),*> {
                pub fn writes(&self) -> Vec<DescriptorWrite> {
                    let mut writes = Vec::new();
                    let mut binding = 0;
                    $(
                        writes.push(self.$field.write(binding));
                        binding += 1;
                    )*
                    writes
                }
            }

            pub struct Set {
                inner: UnsafeDescriptorSet
            }

            impl Set {
                #[inline]
                #[allow(non_camel_case_types)]
                pub fn raw<$($field: ValidParameter<$ty>),*>
                          (pool: &Arc<DescriptorPool>, layout: &Arc<CustomPipeline>,
                           descriptors: &Descriptors<$($field),*>)
                           -> Result<Set, OomError>
                {
                    #![allow(unsafe_code)]
                    unsafe {
                        let layout = layout.inner_pipeline_layout().descriptor_set_layout($num).unwrap();
                        let mut set = try!(UnsafeDescriptorSet::uninitialized_raw(pool, layout));
                        set.write(descriptors.writes());
                        Ok(Set { inner: set })
                    }
                }

                #[inline]
                #[allow(non_camel_case_types)]
                pub fn new<$($field: ValidParameter<$ty>),*>
                          (pool: &Arc<DescriptorPool>, layout: &Arc<CustomPipeline>,
                           descriptors: &Descriptors<$($field),*>)
                           -> Arc<Set>
                {
                    Arc::new(Set::raw(pool, layout, descriptors).unwrap())
                }
            }

            #[allow(unsafe_code)]
            unsafe impl DescriptorSet for Set {
                #[inline]
                fn inner_descriptor_set(&self) -> &UnsafeDescriptorSet {
                    &self.inner
                }
            }

            #[allow(unsafe_code)]
            unsafe impl DescriptorSetDesc for Set {
                type Iter = VecIntoIter<DescriptorDesc>;

                #[inline]
                fn desc(&self) -> Self::Iter {
                    // FIXME:
                    vec![].into_iter()
                }
            }

            #[allow(unused_assignments)]
            pub fn build_set_layout_raw(device: &Arc<Device>)
                                        -> Result<UnsafeDescriptorSetLayout, OomError>
            {
                let mut descriptors = Vec::new();
                let mut binding = 0;

                $(
                    descriptors.push(DescriptorDesc {
                        binding: binding,
                        ty: <$ty as DescriptorMarker>::descriptor_type(),
                        array_count: 1,                     // TODO:
                        stages: ShaderStages::all(),        // TODO:
                        readonly: false,                    // TODO:
                    });

                    binding += 1;
                )*

                UnsafeDescriptorSetLayout::raw(device, descriptors.into_iter())
            }

            #[inline]
            pub fn build_set_layout(device: &Arc<Device>)
                                    -> Arc<UnsafeDescriptorSetLayout>
            {
                Arc::new(build_set_layout_raw(device).unwrap())
            }
        }

        pipeline_layout!{__inner__ ($num+1) $($rest)*}
    };

    (__inner__ ($num:expr)) => {};
}

pub unsafe trait ValidParameter<Target> {
    fn write(&self, binding: u32) -> DescriptorWrite;
}

pub unsafe trait DescriptorMarker {
    fn descriptor_type() -> DescriptorType;
}

pub struct UniformBuffer<T: ?Sized>(PhantomData<T>);
unsafe impl<T: ?Sized> DescriptorMarker for UniformBuffer<T> {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::UniformBuffer
    }
}

unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter<UniformBuffer<T>> for &'a Arc<B>
    where B: TypedBuffer<Content = T>
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::uniform_buffer(binding, *self)
    }
}

pub struct StorageBuffer<T: ?Sized>(PhantomData<T>);
unsafe impl<T: ?Sized> DescriptorMarker for StorageBuffer<T> {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::StorageBuffer
    }
}

unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter<StorageBuffer<T>> for &'a Arc<B>
    where B: TypedBuffer<Content = T>
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::storage_buffer(binding, *self)
    }
}

pub struct CombinedImageSampler;
unsafe impl DescriptorMarker for CombinedImageSampler {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::CombinedImageSampler
    }
}

unsafe impl<'a, I> ValidParameter<CombinedImageSampler> for (&'a Arc<Sampler>, &'a Arc<I>)
    where I: ImageView + 'static
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::combined_image_sampler(binding, self.0, self.1)
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn no_warning() {
        #![deny(warnings)]
        mod layout {
            pipeline_layout! {
                set0: {
                    field1: UniformBuffer<[u8]>,
                    field2: UniformBuffer<[u8]>
                },
                set1: {
                    field1: UniformBuffer<[u8]>,
                    field2: UniformBuffer<[u8]>
                }
            }
        }
    }
}
<commit_msg>Add input attachments for pipeline layouts<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::marker::PhantomData;
use std::sync::Arc;

use buffer::TypedBuffer;
use descriptor::descriptor::DescriptorType;
use descriptor::descriptor_set::DescriptorWrite;
use image::ImageView;
use sampler::Sampler;

/// Call this macro with the layout of a pipeline to generate some helper structs that wrap around
/// vulkano's unsafe APIs.
// TODO: more docs
#[macro_export]
macro_rules! pipeline_layout {
    (push_constants: { $($pc_f:ident: $pc_t:ty),* } $(, $name:ident: { $($field:ident: $ty:ty),* })*) => {
        use std::mem;
        use std::sync::Arc;
        use std::vec::IntoIter as VecIntoIter;
        use $crate::device::Device;
        use $crate::descriptor::descriptor::DescriptorDesc;
        use $crate::descriptor::descriptor::ShaderStages;
        use $crate::descriptor::pipeline_layout::PipelineLayout;
        use $crate::descriptor::pipeline_layout::PipelineLayoutDesc;
        use $crate::descriptor::pipeline_layout::UnsafePipelineLayout;
        use $crate::descriptor::pipeline_layout::UnsafePipelineLayoutCreationError;

        #[derive(Debug, Copy, Clone)]
        pub struct PushConstants {
            $(pub $pc_f: $pc_t,)*
        }

        pub struct CustomPipeline {
            inner: UnsafePipelineLayout
        }

        impl CustomPipeline {
            #[allow(unsafe_code)]
            pub fn new(device: &Arc<Device>)
                       -> Result<Arc<CustomPipeline>, UnsafePipelineLayoutCreationError>
            {
                let layouts = vec![
                    $(
                        Arc::new(try!($name::build_set_layout_raw(device)))
                    ),*
                ];

                let push_constants = if mem::size_of::<PushConstants>() >= 1 {
                    Some((0, mem::size_of::<PushConstants>(), ShaderStages::all()))
                } else {
                    None
                };

                let inner = {
                    try!(UnsafePipelineLayout::new(device, layouts.iter(), push_constants))
                };

                Ok(Arc::new(CustomPipeline {
                    inner: inner
                }))
            }
        }

        #[allow(unsafe_code)]
        unsafe impl PipelineLayout for CustomPipeline {
            #[inline]
            fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout {
                &self.inner
            }
        }

        #[allow(unsafe_code)]
        unsafe impl PipelineLayoutDesc for CustomPipeline {
            type SetsIter = VecIntoIter<Self::DescIter>;
            type DescIter = VecIntoIter<DescriptorDesc>;

            fn descriptors_desc(&self) -> Self::SetsIter {
                // FIXME:
                vec![].into_iter()
            }
        }

        /* TODO: uncomment when specialization lands
        #[allow(unsafe_code)]
        unsafe impl<'a> PipelineLayoutSetsCompatible<($(&'a Arc<$name::Set>),*)> for CustomPipeline {
            #[inline]
            default fn is_compatible(&self, _: &($(&'a Arc<$name::Set>),*)) -> bool {
                true
            }
        }*/

        pipeline_layout!{__inner__ (0) $($name: {$($field: $ty),*})*}
    };

    ($($name:ident: { $($field:ident: $ty:ty),* }),*) => {
        pipeline_layout!{ push_constants: {} $(, $name: {$($field: $ty),*})* }
    };

    (__inner__ ($num:expr) $name:ident: { $($field:ident: $ty:ty),* } $($rest:tt)*) => {
        pub mod $name {
            #![allow(unused_imports)]

            use std::sync::Arc;
            use std::vec::IntoIter as VecIntoIter;
            use super::CustomPipeline;
            use $crate::OomError;
            use $crate::device::Device;
            use $crate::descriptor::descriptor::DescriptorDesc;
            use $crate::descriptor::descriptor::ShaderStages;
            use $crate::descriptor::descriptor_set::DescriptorPool;
            use $crate::descriptor::descriptor_set::DescriptorSet;
            use $crate::descriptor::descriptor_set::DescriptorSetDesc;
            use $crate::descriptor::descriptor_set::UnsafeDescriptorSet;
            use $crate::descriptor::descriptor_set::UnsafeDescriptorSetLayout;
            use $crate::descriptor::descriptor_set::DescriptorWrite;
            use $crate::descriptor::pipeline_layout::PipelineLayout;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::CombinedImageSampler;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::DescriptorMarker;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::StorageBuffer;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::UniformBuffer;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::InputAttachment;
            use $crate::descriptor::pipeline_layout::custom_pipeline_macro::ValidParameter;

            // This constant is part of the API, but Rust sees it as dead code.
            #[allow(dead_code)]
            pub const SET_NUM: u32 = $num;

            #[allow(non_camel_case_types)]
            pub struct Descriptors<$($field),*> {
                $(
                    pub $field: $field
                ),*
            }

            #[allow(non_camel_case_types)]
            #[allow(unused_assignments)]
            impl<$($field: ValidParameter<$ty>),*> Descriptors<$($field),*> {
                pub fn writes(&self) -> Vec<DescriptorWrite> {
                    let mut writes = Vec::new();
                    let mut binding = 0;
                    $(
                        writes.push(self.$field.write(binding));
                        binding += 1;
                    )*
                    writes
                }
            }

            pub struct Set {
                inner: UnsafeDescriptorSet
            }

            impl Set {
                #[inline]
                #[allow(non_camel_case_types)]
                pub fn raw<$($field: ValidParameter<$ty>),*>
                          (pool: &Arc<DescriptorPool>, layout: &Arc<CustomPipeline>,
                           descriptors: &Descriptors<$($field),*>)
                           -> Result<Set, OomError>
                {
                    #![allow(unsafe_code)]
                    unsafe {
                        let layout = layout.inner_pipeline_layout().descriptor_set_layout($num).unwrap();
                        let mut set = try!(UnsafeDescriptorSet::uninitialized_raw(pool, layout));
                        set.write(descriptors.writes());
                        Ok(Set { inner: set })
                    }
                }

                #[inline]
                #[allow(non_camel_case_types)]
                pub fn new<$($field: ValidParameter<$ty>),*>
                          (pool: &Arc<DescriptorPool>, layout: &Arc<CustomPipeline>,
                           descriptors: &Descriptors<$($field),*>)
                           -> Arc<Set>
                {
                    Arc::new(Set::raw(pool, layout, descriptors).unwrap())
                }
            }

            #[allow(unsafe_code)]
            unsafe impl DescriptorSet for Set {
                #[inline]
                fn inner_descriptor_set(&self) -> &UnsafeDescriptorSet {
                    &self.inner
                }
            }

            #[allow(unsafe_code)]
            unsafe impl DescriptorSetDesc for Set {
                type Iter = VecIntoIter<DescriptorDesc>;

                #[inline]
                fn desc(&self) -> Self::Iter {
                    // FIXME:
                    vec![].into_iter()
                }
            }

            #[allow(unused_assignments)]
            pub fn build_set_layout_raw(device: &Arc<Device>)
                                        -> Result<UnsafeDescriptorSetLayout, OomError>
            {
                let mut descriptors = Vec::new();
                let mut binding = 0;

                $(
                    descriptors.push(DescriptorDesc {
                        binding: binding,
                        ty: <$ty as DescriptorMarker>::descriptor_type(),
                        array_count: 1,                     // TODO:
                        stages: ShaderStages::all(),        // TODO:
                        readonly: false,                    // TODO:
                    });

                    binding += 1;
                )*

                UnsafeDescriptorSetLayout::raw(device, descriptors.into_iter())
            }

            #[inline]
            pub fn build_set_layout(device: &Arc<Device>)
                                    -> Arc<UnsafeDescriptorSetLayout>
            {
                Arc::new(build_set_layout_raw(device).unwrap())
            }
        }

        pipeline_layout!{__inner__ ($num+1) $($rest)*}
    };

    (__inner__ ($num:expr)) => {};
}

pub unsafe trait ValidParameter<Target> {
    fn write(&self, binding: u32) -> DescriptorWrite;
}

pub unsafe trait DescriptorMarker {
    fn descriptor_type() -> DescriptorType;
}

pub struct UniformBuffer<T: ?Sized>(PhantomData<T>);
unsafe impl<T: ?Sized> DescriptorMarker for UniformBuffer<T> {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::UniformBuffer
    }
}

unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter<UniformBuffer<T>> for &'a Arc<B>
    where B: TypedBuffer<Content = T>
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::uniform_buffer(binding, *self)
    }
}

pub struct StorageBuffer<T: ?Sized>(PhantomData<T>);
unsafe impl<T: ?Sized> DescriptorMarker for StorageBuffer<T> {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::StorageBuffer
    }
}

unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter<StorageBuffer<T>> for &'a Arc<B>
    where B: TypedBuffer<Content = T>
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::storage_buffer(binding, *self)
    }
}

pub struct CombinedImageSampler;
unsafe impl DescriptorMarker for CombinedImageSampler {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::CombinedImageSampler
    }
}

unsafe impl<'a, I> ValidParameter<CombinedImageSampler> for (&'a Arc<Sampler>, &'a Arc<I>)
    where I: ImageView + 'static
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::combined_image_sampler(binding, self.0, self.1)
    }
}

pub struct InputAttachment;
unsafe impl DescriptorMarker for InputAttachment {
    #[inline]
    fn descriptor_type() -> DescriptorType {
        DescriptorType::InputAttachment
    }
}

unsafe impl<'a, I> ValidParameter<InputAttachment> for &'a Arc<I>
    where I: ImageView + 'static
{
    #[inline]
    fn write(&self, binding: u32) -> DescriptorWrite {
        DescriptorWrite::input_attachment(binding, self)
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn no_warning() {
        #![deny(warnings)]
        mod layout {
            pipeline_layout! {
                set0: {
                    field1: UniformBuffer<[u8]>,
                    field2: UniformBuffer<[u8]>
                },
                set1: {
                    field1: UniformBuffer<[u8]>,
                    field2: UniformBuffer<[u8]>
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(dead_code)]
mod lua {
    include!(concat!(env!("OUT_DIR"), "/lua.rs"));
}

pub use lua::{
    /* struct */
    lua_State,

    /* function */
    lua_close,
    lua_pushinteger,
    lua_tointegerx,
    lua_getglobal,
    lua_setglobal,
    lua_settop,
    lua_gettop,
    luaL_newstate,
};

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

    #[test]
    fn it_works() {
        unsafe {
            let lua = luaL_newstate();
            lua_close(lua);
        }
    }
}
<commit_msg>sort export function<commit_after>#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(dead_code)]
mod lua {
    include!(concat!(env!("OUT_DIR"), "/lua.rs"));
}

pub use lua::{
    /* struct */
    lua_State,

    /* function */
    luaL_newstate,
    lua_close,
    lua_getglobal,
    lua_gettop,
    lua_pushinteger,
    lua_setglobal,
    lua_settop,
    lua_tointegerx,
};

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

    #[test]
    fn it_works() {
        unsafe {
            let lua = luaL_newstate();
            lua_close(lua);
        }
    }
}
<|endoftext|>


<commit_before>use std::io;

/// A PPM image writer based off of the spec found here:
/// http://netpbm.sourceforge.net/doc/ppm.html
pub struct PPMWriter<'a, TWrite: 'a> {
    writer: &'a mut TWrite
}

impl<'a, TWrite: io::Write> PPMWriter<'a, TWrite> {
    pub fn new(writer: &'a mut TWrite) -> Self {
        PPMWriter {
            writer: writer
        }
    }

    pub fn write(&mut self, image_data: &[f32], width: usize, height: usize) -> io::Result<()> {
        try!(self.write_magic_number());
        try!(self.write_metadata(width, height, 255));

        self.write_image_data(image_data)
    }

    fn write_magic_number(&mut self) -> io::Result<()> {
        write!(&mut self.writer, "P3\n")
    }

    fn write_metadata(&mut self, width: usize, height: usize, max_pixel_val: u32) -> io::Result<()> {
        write!(&mut self.writer, "{} {}\n{}\n", width, height, max_pixel_val)
    }

    fn write_image_data(&mut self, image_data: &[f32]) -> io::Result<()> {
        for pixel in image_data.chunks(3) {
            let r = (255.0 * pixel[0]) as u8;
            let g = (255.0 * pixel[1]) as u8;
            let b = (255.0 * pixel[2]) as u8;

            try!(write!(self.writer, "{} {} {} ", r, g, b));
        }

        Ok(())
    }
}

#[test]
fn test_write_ppm() {
    let writer: Vec<u8> = Vec::new();

    let mut ppm_writer = PPMWriter::new(writer);

    let image_data = &[
        1.0, 0.0, 0.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0,
        1.0, 1.0, 0.0,  1.0, 1.0, 1.0,  0.0, 0.0, 0.0
    ];

    ppm_writer.write(image_data, 3, 2).unwrap();

    print!("{:?}", ppm_writer.writer);
}
<commit_msg>Remove useless test<commit_after>use std::io;

/// A PPM image writer based off of the spec found here:
/// http://netpbm.sourceforge.net/doc/ppm.html
pub struct PPMWriter<'a, TWrite: 'a> {
    writer: &'a mut TWrite
}

impl<'a, TWrite: io::Write> PPMWriter<'a, TWrite> {
    pub fn new(writer: &'a mut TWrite) -> Self {
        PPMWriter {
            writer: writer
        }
    }

    pub fn write(&mut self, image_data: &[f32], width: usize, height: usize) -> io::Result<()> {
        try!(self.write_magic_number());
        try!(self.write_metadata(width, height, 255));

        self.write_image_data(image_data)
    }

    fn write_magic_number(&mut self) -> io::Result<()> {
        write!(&mut self.writer, "P3\n")
    }

    fn write_metadata(&mut self, width: usize, height: usize, max_pixel_val: u32) -> io::Result<()> {
        write!(&mut self.writer, "{} {}\n{}\n", width, height, max_pixel_val)
    }

    fn write_image_data(&mut self, image_data: &[f32]) -> io::Result<()> {
        for pixel in image_data.chunks(3) {
            let r = (255.0 * pixel[0]) as u8;
            let g = (255.0 * pixel[1]) as u8;
            let b = (255.0 * pixel[2]) as u8;

            try!(write!(self.writer, "{} {} {} ", r, g, b));
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use regex_syntax::Expr;
use regex_syntax::Repeater;

use nfa::NFA;
use nfa::Spec;
use nfa::NFABuilder;
use nfa::Label;

struct Rule {
    regex: Expr,
    action: String,
}

/// Converts a sequence of characters into a concatenation of simple
/// transitions.
///
/// The return value is a Spec containing the concatenation of all
/// single transition automata generated for each character in `chars`.
fn literal_to_spec(chars: &Vec<char>) -> Spec {
    // take the first
    let mut tmp: Box<Spec> = Spec::single(Label::Symbol((*chars)[0]));

    // iterate for the others
    for i in chars.iter().skip(1) {
        let aux = Spec::single(Label::Symbol(*i));
        tmp = Spec::concat(tmp,aux);
    }

    // return the concatenation
    *tmp
}

/// Converts `re` and repeater specification `r` into a NFA `Spec`.
///
/// The repetition behavior is translated to the basic constructs
/// of a NFA `Spec`: union, concatenation and Kleene star of NFAs,
/// using the NFA built for `re` as one of the operands.
fn repeater_to_spec(re: &Expr, r: &Repeater) -> Spec {
    let s1 = Box::new(regex_to_nfa_spec(re));

    match *r {
        Repeater::ZeroOrOne => Spec::Union(Spec::single(Label::Epsilon), s1),
        Repeater::ZeroOrMore => Spec::Star(s1),
        Repeater::OneOrMore => Spec::Concat(s1.clone(), Spec::star(s1)),
        Repeater::Range { min, max } => unimplemented!()
    }
}

/// Converts the regexp `re` into a NFA `Spec`.
///
/// The function traverses the `re` syntax tree recursively, building
/// NFA Specs for each component and combining them according to the
/// operations in the ER.
pub fn regex_to_nfa_spec(re: &Expr) -> Spec {
    match *re {
        Expr::AnyChar => Spec::Single(Label::Any),
        Expr::AnyCharNoNL => Spec::Single(Label::Any),  // FIX: don't match newline
        Expr::Repeat { ref e, r, greedy } => repeater_to_spec(&*e, &r),
        Expr::Literal{ ref chars, casei} => literal_to_spec(chars),
        _ => unimplemented!()
    }
}

#[test]
fn test_repeater_zero_or_more1() {
    let re = Expr::parse(r".*").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::star(Spec::single(Label::Any)));

}

#[test]
fn test_literal() {
    let re = Expr::parse(r"ab").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::concat(Spec::single(Label::Symbol('a')), Spec::single(Label::Symbol('b'))));
}
<commit_msg>Range repeater_to_spec implemented and tested<commit_after>use regex_syntax::Expr;
use regex_syntax::Repeater;

use nfa::NFA;
use nfa::Spec;
use nfa::NFABuilder;
use nfa::Label;

struct Rule {
    regex: Expr,
    action: String,
}

/// Converts a sequence of characters into a concatenation of simple
/// transitions.
///
/// The return value is a Spec containing the concatenation of all
/// single transition automata generated for each character in `chars`.
fn literal_to_spec(chars: &Vec<char>) -> Spec {
    // take the first
    let mut tmp: Box<Spec> = Spec::single(Label::Symbol((*chars)[0]));

    // iterate for the others
    for i in chars.iter().skip(1) {
        let aux = Spec::single(Label::Symbol(*i));
        tmp = Spec::concat(tmp,aux);
    }

    // return the concatenation
    *tmp
}

fn repeater_range(s1: Box<Spec>, min: u32, max: Option<u32>) -> Spec {
    let mut begin:u32 = 0;
    let mut aux:Box<Spec>;
    let mut spec:Box<Spec>;

    if min == 0 {
        aux = Spec::single(Label::Epsilon);
    } else {
        aux = s1.clone();
        begin = 1;
    }

    for i in begin..min {
        aux = Spec::concat(aux, s1.clone());
    }

    if max == None {
        spec = Spec::concat(aux, Spec::star(s1))
    } else {
        spec = aux.clone();

        //iterate min + 1 ... max
        for i in min..max.unwrap() {
            aux = Spec::concat(aux, s1.clone());
            spec = Spec::union(spec, aux.clone());
        }
    }
    *spec
}

/// Converts `re` and repeater specification `r` into a NFA `Spec`.
///
/// The repetition behavior is translated to the basic constructs
/// of a NFA `Spec`: union, concatenation and Kleene star of NFAs,
/// using the NFA built for `re` as one of the operands.
fn repeater_to_spec(re: &Expr, r: &Repeater) -> Spec {
    let s1 = Box::new(regex_to_nfa_spec(re));

    match *r {
        Repeater::ZeroOrOne => Spec::Union(Spec::single(Label::Epsilon), s1),
        Repeater::ZeroOrMore => Spec::Star(s1),
        Repeater::OneOrMore => Spec::Concat(s1.clone(), Spec::star(s1)),
        Repeater::Range { min, max } => repeater_range(s1, min, max)
    }
}

/// Converts the regexp `re` into a NFA `Spec`.
///
/// The function traverses the `re` syntax tree recursively, building
/// NFA Specs for each component and combining them according to the
/// operations in the ER.
pub fn regex_to_nfa_spec(re: &Expr) -> Spec {
    match *re {
        Expr::AnyChar => Spec::Single(Label::Any),
        Expr::AnyCharNoNL => Spec::Single(Label::Any),  // FIX: don't match newline
        Expr::Repeat { ref e, r, greedy } => repeater_to_spec(&*e, &r),
        Expr::Literal{ ref chars, casei} => literal_to_spec(chars),
        _ => unimplemented!()
    }
}

#[test]
fn test_repeater_zero_or_more1() {
    let re = Expr::parse(r".*").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::star(Spec::single(Label::Any)));

}

#[test]
fn test_literal() {
    let re = Expr::parse(r"ab").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::concat(Spec::single(Label::Symbol('a')), Spec::single(Label::Symbol('b'))));
}

#[test]
fn test_repeater_range() {
    let re = Expr::parse(r"a{0,4}").unwrap();
    let spec = regex_to_nfa_spec(&re);
    let n = NFABuilder::build_from_spec(spec);

    println!("regex: {:?}", re);
    assert!(n.simulate("aaaa"));
    assert!(n.simulate(""));
    assert!(!n.simulate("aaaaaaaaaaaa"));
}<|endoftext|>


<commit_before>extern crate telegram_bot_raw;
extern crate telegram_bot_tokio;
extern crate tokio_core;
extern crate futures;

use std::env;

use futures::{Future, Stream};
use futures::future::ok;
use tokio_core::reactor::Core;
use telegram_bot_tokio::Bot;
use telegram_bot_raw::{MessageKind, UpdateKind, CanReplySendMessage};

fn main() {
    let token = env::var("TELEGRAM_BOT_TOKEN").unwrap();

    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let bot = Bot::from_token(&core.handle(), &token).unwrap();

    let future = bot.stream().for_each(|update| {
        if let UpdateKind::Message(message) = update.kind {
            if let MessageKind::Text {ref data, ..} = message.kind {
                let bot = bot.clone();
                let msg = message.text_reply(format!("Got the message: '{}'", data));
                handle.spawn_fn(move || {
                    bot.send(msg).then(|_| ok(()))
                })
            }
        }
        ok(())
    });

    core.run(future).unwrap();
}
<commit_msg>refactor: cleanup reply example<commit_after>extern crate telegram_bot_raw;
extern crate telegram_bot_tokio;
extern crate tokio_core;
extern crate futures;

use std::env;

use futures::{Stream};
use tokio_core::reactor::Core;
use telegram_bot_tokio::Bot;
use telegram_bot_raw::{MessageKind, UpdateKind, CanReplySendMessage};

fn main() {
    let token = env::var("TELEGRAM_BOT_TOKEN").unwrap();

    let mut core = Core::new().unwrap();
    let bot = Bot::from_token(&core.handle(), &token).unwrap();

    let future = bot.stream().for_each(|update| {
        if let UpdateKind::Message(message) = update.kind {
            if let MessageKind::Text {ref data, ..} = message.kind {
                let text = format!("Got the message: '{}'", data);
                bot.spawn(message.text_reply(text));
            }
        }
        Ok(())
    });

    core.run(future).unwrap();
}
<|endoftext|>


<commit_before>#![cfg_attr(not(feature = "full"), allow(unused_macros))]

#[macro_use]
#[cfg(test)]
mod assert;

#[macro_use]
mod cfg;

#[macro_use]
mod loom;

#[macro_use]
mod ready;

#[macro_use]
mod select;

#[macro_use]
mod thread_local;

cfg_macros! {
    // Includes re-exports needed to implement macros
    #[doc(hidden)]
    pub mod support;
}
<commit_msg>Don't export select unless macros is enabled (#2161)<commit_after>#![cfg_attr(not(feature = "full"), allow(unused_macros))]

#[macro_use]
#[cfg(test)]
mod assert;

#[macro_use]
mod cfg;

#[macro_use]
mod loom;

#[macro_use]
mod ready;

cfg_macros! {
    #[macro_use]
    mod select;
}

#[macro_use]
mod thread_local;

cfg_macros! {
    // Includes re-exports needed to implement macros
    #[doc(hidden)]
    pub mod support;
}
<|endoftext|>


<commit_before>#![crate_id(name="seq", vers="1.0.0", author="Daniel MacDougall")]

#![feature(macro_rules)]

// TODO: Make -w flag work with decimals
// TODO: Support -f flag

extern crate getopts;
extern crate libc;

use std::cmp;
use std::io;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "seq";

macro_rules! pipe_write(
    ($($args:expr),+) => (
        match write!(&mut io::stdout() as &mut Writer, $($args),+) {
            Ok(_) => {}
            Err(f) =>
                if f.kind == io::BrokenPipe {
                    return
                } else {
                    fail!("{}", f.to_str())
                }
        }
    )
)

#[deriving(Clone)]
struct SeqOptions {
    separator: String,
    terminator: Option<String>,
    widths: bool
}

fn parse_float(s: &str) -> Result<f64, String>{
    match from_str(s) {
        Some(n) => Ok(n),
        None => Err(format!("seq: invalid floating point argument: {:s}", s))
    }
}

fn escape_sequences(s: &str) -> String {
    s.replace("\\n", "\n").
        replace("\\t", "\t")
}

fn parse_options(args: Vec<String>, options: &mut SeqOptions) -> Result<Vec<String>, int> {
    let mut seq_args = vec!();
    let program = args.get(0).clone();
    let mut iter = args.move_iter().skip(1);
    loop {
        match iter.next() {
            Some(arg) => match arg.as_slice() {
                "--help" | "-h" => {
                    print_help(&program);
                    return Err(0);
                }
                "--version" | "-V" => {
                    print_version();
                    return Err(0);
                }
                "-s" | "--separator" => match iter.next() {
                    Some(sep) => options.separator = sep,
                    None => {
                        show_error!("expected a separator after {}", arg);
                        return Err(1);
                    }
                },
                "-t" | "--terminator" => match iter.next() {
                    Some(term) => options.terminator = Some(term),
                    None => {
                        show_error!("expected a terminator after '{}'", arg);
                        return Err(1);
                    }
                },
                "-w" | "--widths" => options.widths = true,
                "--" => {
                    seq_args.push_all_move(iter.collect());
                    break;
                },
                _ => {
                    if arg.len() > 1 && arg.as_slice().char_at(0) == '-' {
                        let argptr: *String = &arg;  // escape from the borrow checker
                        let mut chiter = unsafe { (*argptr).as_slice() }.chars().skip(1);
                        let mut ch = ' ';
                        while match chiter.next() { Some(m) => { ch = m; true } None => false } {
                            match ch {
                                'h' => {
                                    print_help(&program);
                                    return Err(0);
                                }
                                'V' => {
                                    print_version();
                                    return Err(0);
                                }
                                's' => match iter.next() {
                                    Some(sep) => {
                                        options.separator = sep;
                                        let next = chiter.next();
                                        if next.is_some() {
                                            show_error!("unexpected character ('{}')", next.unwrap());
                                            return Err(1);
                                        }
                                    }
                                    None => {
                                        show_error!("expected a separator after {}", arg);
                                        return Err(1);
                                    }
                                },
                                't' => match iter.next() {
                                    Some(term) => {
                                        options.terminator = Some(term);
                                        let next = chiter.next();
                                        if next.is_some() {
                                            show_error!("unexpected character ('{}')", next.unwrap());
                                            return Err(1);
                                        }
                                    }
                                    None => {
                                        show_error!("expected a terminator after {}", arg);
                                        return Err(1);
                                    }
                                },
                                'w' => options.widths = true,
                                _ => { seq_args.push(arg); break }
                            }
                        }
                    } else {
                        seq_args.push(arg);
                    }
                }
            },
            None => break
        }
    }
    Ok(seq_args)
}

fn print_help(program: &String) {
    let opts = [
        getopts::optopt("s", "separator", "Separator character (defaults to \\n)", ""),
        getopts::optopt("t", "terminator", "Terminator character (defaults to separator)", ""),
        getopts::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"),
        getopts::optflag("h", "help", "print this help text and exit"),
        getopts::optflag("V", "version", "print version and exit"),
    ];
    println!("seq 1.0.0\n");
    println!("Usage:\n  {} [-w] [-s string] [-t string] [first [step]] last\n", *program);
    println!("{:s}", getopts::usage("Print sequences of numbers", opts));
}

fn print_version() {
    println!("seq 1.0.0\n");
}

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).clone();
    let mut options = SeqOptions {
        separator: "\n".to_string(),
        terminator: None,
        widths: false
    };
    let free = match parse_options(args, &mut options) {
        Ok(m) => m,
        Err(f) => return f
    };
    if free.len() < 1 || free.len() > 3 {
        crash!(1, "too {} operands.\nTry '{} --help' for more information.",
               if free.len() < 1 { "few" } else { "many" }, program);
    }
    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if free.len() > 1 {
        let slice = free.get(0).as_slice();
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = len - dec;
        padding = dec;
        match parse_float(slice) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    } else {
        1.0
    };
    let step = if free.len() > 2 {
        let slice = free.get(1).as_slice();
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = cmp::max(largest_dec, len - dec);
        padding = cmp::max(padding, dec);
        match parse_float(free.get(1).as_slice()) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    } else {
        1.0
    };
    let last = {
        let slice = free.get(free.len() - 1).as_slice();
        padding = cmp::max(padding, slice.find('.').unwrap_or(slice.len()));
        match parse_float(slice) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    };
    let separator = escape_sequences(options.separator.as_slice());
    let terminator = match options.terminator {
        Some(term) => escape_sequences(term.as_slice()),
        None => separator.clone()
    };
    print_seq(first, step, last, largest_dec, separator, terminator, options.widths, padding);

    0
}

#[inline(always)]
fn done_printing(next: f64, step: f64, last: f64) -> bool {
    if step >= 0f64 {
        next > last
    } else {
        next < last
    }
}

fn print_seq(first: f64, step: f64, last: f64, largest_dec: uint, separator: String, terminator: String, pad: bool, padding: uint) {
    let mut i = 0;
    let mut value = first + i as f64 * step;
    while !done_printing(value, step, last) {
        let istr = value.to_str();
        let ilen = istr.len();
        let before_dec = istr.as_slice().find('.').unwrap_or(ilen);
        if pad && before_dec < padding {
            for _ in range(0, padding - before_dec) {
                pipe_write!("0");
            }
        }
        pipe_write!("{}", istr);
        let mut idec = ilen - before_dec;
        if idec < largest_dec {
            if idec == 0 {
                pipe_write!(".");
                idec += 1;
            }
            for _ in range(idec, largest_dec) {
                pipe_write!("0")
            }
        }
        i += 1;
        value = first + i as f64 * step;
        if !done_printing(value, step, last) {
            pipe_write!("{:s}", separator);
        }
    }
    if (first >= last && step < 0f64) || (first <= last && step > 0f64) {
        pipe_write!("{:s}", terminator);
    }
}
<commit_msg>seq: fix build<commit_after>#![crate_id(name="seq", vers="1.0.0", author="Daniel MacDougall")]

#![feature(macro_rules)]

// TODO: Make -w flag work with decimals
// TODO: Support -f flag

extern crate getopts;
extern crate libc;

use std::cmp;
use std::io;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "seq";

macro_rules! pipe_write(
    ($($args:expr),+) => (
        match write!(&mut io::stdout() as &mut Writer, $($args),+) {
            Ok(_) => {}
            Err(f) =>
                if f.kind == io::BrokenPipe {
                    return
                } else {
                    fail!("{}", f.to_str())
                }
        }
    )
)

#[deriving(Clone)]
struct SeqOptions {
    separator: String,
    terminator: Option<String>,
    widths: bool
}

fn parse_float(s: &str) -> Result<f64, String>{
    match from_str(s) {
        Some(n) => Ok(n),
        None => Err(format!("seq: invalid floating point argument: {:s}", s))
    }
}

fn escape_sequences(s: &str) -> String {
    s.replace("\\n", "\n").
        replace("\\t", "\t")
}

fn parse_options(args: Vec<String>, options: &mut SeqOptions) -> Result<Vec<String>, int> {
    let mut seq_args = vec!();
    let program = args.get(0).clone();
    let mut iter = args.move_iter().skip(1);
    loop {
        match iter.next() {
            Some(arg) => match arg.as_slice() {
                "--help" | "-h" => {
                    print_help(&program);
                    return Err(0);
                }
                "--version" | "-V" => {
                    print_version();
                    return Err(0);
                }
                "-s" | "--separator" => match iter.next() {
                    Some(sep) => options.separator = sep,
                    None => {
                        show_error!("expected a separator after {}", arg);
                        return Err(1);
                    }
                },
                "-t" | "--terminator" => match iter.next() {
                    Some(term) => options.terminator = Some(term),
                    None => {
                        show_error!("expected a terminator after '{}'", arg);
                        return Err(1);
                    }
                },
                "-w" | "--widths" => options.widths = true,
                "--" => {
                    seq_args.push_all_move(iter.collect());
                    break;
                },
                _ => {
                    if arg.len() > 1 && arg.as_slice().char_at(0) == '-' {
                        let argptr: *String = &arg;  // escape from the borrow checker
                        let mut chiter = unsafe { (*argptr).as_slice() }.chars().skip(1);
                        let mut ch = ' ';
                        while match chiter.next() { Some(m) => { ch = m; true } None => false } {
                            match ch {
                                'h' => {
                                    print_help(&program);
                                    return Err(0);
                                }
                                'V' => {
                                    print_version();
                                    return Err(0);
                                }
                                's' => match iter.next() {
                                    Some(sep) => {
                                        options.separator = sep;
                                        let next = chiter.next();
                                        if next.is_some() {
                                            show_error!("unexpected character ('{}')", next.unwrap());
                                            return Err(1);
                                        }
                                    }
                                    None => {
                                        show_error!("expected a separator after {}", arg);
                                        return Err(1);
                                    }
                                },
                                't' => match iter.next() {
                                    Some(term) => {
                                        options.terminator = Some(term);
                                        let next = chiter.next();
                                        if next.is_some() {
                                            show_error!("unexpected character ('{}')", next.unwrap());
                                            return Err(1);
                                        }
                                    }
                                    None => {
                                        show_error!("expected a terminator after {}", arg);
                                        return Err(1);
                                    }
                                },
                                'w' => options.widths = true,
                                _ => { seq_args.push(arg); break }
                            }
                        }
                    } else {
                        seq_args.push(arg);
                    }
                }
            },
            None => break
        }
    }
    Ok(seq_args)
}

fn print_help(program: &String) {
    let opts = [
        getopts::optopt("s", "separator", "Separator character (defaults to \\n)", ""),
        getopts::optopt("t", "terminator", "Terminator character (defaults to separator)", ""),
        getopts::optflag("w", "widths", "Equalize widths of all numbers by padding with zeros"),
        getopts::optflag("h", "help", "print this help text and exit"),
        getopts::optflag("V", "version", "print version and exit"),
    ];
    println!("seq 1.0.0\n");
    println!("Usage:\n  {} [-w] [-s string] [-t string] [first [step]] last\n", *program);
    println!("{:s}", getopts::usage("Print sequences of numbers", opts));
}

fn print_version() {
    println!("seq 1.0.0\n");
}

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).clone();
    let mut options = SeqOptions {
        separator: "\n".to_string(),
        terminator: None,
        widths: false
    };
    let free = match parse_options(args, &mut options) {
        Ok(m) => m,
        Err(f) => return f
    };
    if free.len() < 1 || free.len() > 3 {
        crash!(1, "too {} operands.\nTry '{} --help' for more information.",
               if free.len() < 1 { "few" } else { "many" }, program);
    }
    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if free.len() > 1 {
        let slice = free.get(0).as_slice();
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = len - dec;
        padding = dec;
        match parse_float(slice) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    } else {
        1.0
    };
    let step = if free.len() > 2 {
        let slice = free.get(1).as_slice();
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = cmp::max(largest_dec, len - dec);
        padding = cmp::max(padding, dec);
        match parse_float(free.get(1).as_slice()) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    } else {
        1.0
    };
    let last = {
        let slice = free.get(free.len() - 1).as_slice();
        padding = cmp::max(padding, slice.find('.').unwrap_or(slice.len()));
        match parse_float(slice) {
            Ok(n) => n,
            Err(s) => { show_error!("{:s}", s); return 1; }
        }
    };
    let separator = escape_sequences(options.separator.as_slice());
    let terminator = match options.terminator {
        Some(term) => escape_sequences(term.as_slice()),
        None => separator.clone()
    };
    print_seq(first, step, last, largest_dec, separator, terminator, options.widths, padding);

    0
}

#[inline(always)]
fn done_printing(next: f64, step: f64, last: f64) -> bool {
    if step >= 0f64 {
        next > last
    } else {
        next < last
    }
}

fn print_seq(first: f64, step: f64, last: f64, largest_dec: uint, separator: String, terminator: String, pad: bool, padding: uint) {
    let mut i = 0i;
    let mut value = first + i as f64 * step;
    while !done_printing(value, step, last) {
        let istr = value.to_str();
        let ilen = istr.len();
        let before_dec = istr.as_slice().find('.').unwrap_or(ilen);
        if pad && before_dec < padding {
            for _ in range(0, padding - before_dec) {
                pipe_write!("0");
            }
        }
        pipe_write!("{}", istr);
        let mut idec = ilen - before_dec;
        if idec < largest_dec {
            if idec == 0 {
                pipe_write!(".");
                idec += 1;
            }
            for _ in range(idec, largest_dec) {
                pipe_write!("0")
            }
        }
        i += 1;
        value = first + i as f64 * step;
        if !done_printing(value, step, last) {
            pipe_write!("{:s}", separator);
        }
    }
    if (first >= last && step < 0f64) || (first <= last && step > 0f64) {
        pipe_write!("{:s}", terminator);
    }
}
<|endoftext|>


<commit_before>// run-pass
#![allow(non_upper_case_globals)]

// Issue 23611: this test is ensuring that, for an instance `X` of the
// enum `E`, if you swap in a different variant during the execution
// of the `<E as Drop>::drop`, then the appropriate substructure will
// be torn down after the `<E as Drop>::drop` method returns.

use std::cell::RefCell;
use std::mem;

use self::d::D;

pub fn main() {
    let log = RefCell::new(vec![]);
    d::println("created empty log");
    test(&log);

    // println!("log: {:?}", &log.borrow()[..]);
    assert_eq!(
        &log.borrow()[..],
        [
            //                                         created empty log
            // +-- Make D(test_1, 10000000)
            // | +-- Make D(g_b_5, 50000001)
            // | |                                     in g_B(b2b0) from E::drop, b=b4b0
            // | +-- Drop D(g_b_5, 50000001)
            50000001,
            // |
            // | +-- Make D(drop_6, 60000002)
            // | | +-- Make D(g_b_5, 50000003)
            // | | |                                   in g_B(b2b0) from E::drop, b=b4b1
            // | | +-- Drop D(g_b_5, 50000003)
            50000003,
            // | |
            // | | +-- Make D(GaspB::drop_3, 30000004)
            // | | | +-- Make D(g_b_5, 50000005)
            // | | | |                                 in g_B(b4b2) from GaspB::drop
            // | | | +-- Drop D(g_b_5, 50000005)
            50000005,
            // | | |
            // | | +-- Drop D(GaspB::drop_3, 30000004)
            30000004,
            // | |
            // +-- Drop D(test_1, 10000000)
            10000000,
            //   |
            // +-- Make D(GaspA::drop_2, 20000006)
            // | | +-- Make D(f_a_4, 40000007)
            // | | |                                   in f_A(a3a0) from GaspA::drop
            // | | +-- Drop D(f_a_4, 40000007)
            40000007,
            // | |
            // +-- Drop D(GaspA::drop_2, 20000006)
            20000006,
            //   |
            //   +-- Drop D(drop_6, 60000002)
            60000002
            //
                ]);

    // For reference purposes, the old (incorrect) behavior would produce the following
    // output, which you can compare to the above:
    //
    //                                             created empty log
    // +-- Make D(test_1, 10000000)
    // | +-- Make D(g_b_5, 50000001)
    // | |                                     in g_B(b2b0) from E::drop, b=b4b0
    // | +-- Drop D(g_b_5, 50000001)
    // |
    // | +-- Make D(drop_6, 60000002)
    // | | +-- Make D(g_b_5, 50000003)
    // | | |                                   in g_B(b2b0) from E::drop, b=b4b1
    // | | +-- Drop D(g_b_5, 50000003)
    // | |
    // | | +-- Make D(GaspB::drop_3, 30000004)
    // | | | +-- Make D(g_b_5, 50000005)
    // | | | |                                 in g_B(b4b2) from GaspB::drop
    // | | | +-- Drop D(g_b_5, 50000005)
    // | | |
    // | | +-- Drop D(GaspB::drop_3, 30000004)
    // | |
    // +-- Drop D(test_1, 10000000)
    //   |
    // +-- Make D(GaspB::drop_3, 30000006)
    // | | +-- Make D(f_a_4, 40000007)
    // | | |                                   in f_A(a3a0) from GaspB::drop
    // | | +-- Drop D(f_a_4, 40000007)
    // | |
    // +-- Drop D(GaspB::drop_3, 30000006)
    //   |
    //   +-- Drop D(drop_6, 60000002)

    // Note that this calls f_A from GaspB::drop (and thus creates a D
    // with a uid incorporating the origin of GaspB's drop that
    // surrounds the f_A invocation), but the code as written only
    // ever hands f_A off to instances of GaspA, and thus one should
    // be able to prove the invariant that f_A is *only* invoked from
    // from an instance of GaspA (either via the GaspA drop
    // implementation or the E drop implementaton). Yet the old (bad)
    // behavior allowed a call to f_A to leak in while we are tearing
    // down a value of type GaspB.
}

fn test<'a>(log: d::Log<'a>) {
    let _e = E::B(GaspB(g_b, 0xB4B0, log, D::new("test", 1, log)), true);
}

struct GaspA<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
struct GaspB<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);

impl<'a> Drop for GaspA<'a> {
    fn drop(&mut self) {
        let _d = d::D::new("GaspA::drop", 2, self.2);
        (self.0)(self.1, "GaspA::drop", self.2);
    }
}

impl<'a> Drop for GaspB<'a> {
    fn drop(&mut self) {
        let _d = d::D::new("GaspB::drop", 3, self.2);
        (self.0)(self.1, "GaspB::drop", self.2);
    }
}

enum E<'a> {
    A(GaspA<'a>, bool), B(GaspB<'a>, bool),
}

fn f_a(x: u32, ctxt: &str, log: d::Log) {
    let _d = d::D::new("f_a", 4, log);
    d::println(&format!("in f_A({:x}) from {}", x, ctxt));
}
fn g_b(y: u32, ctxt: &str, log: d::Log) {
    let _d = d::D::new("g_b", 5, log);
    d::println(&format!("in g_B({:x}) from {}", y, ctxt));
}

impl<'a> Drop for E<'a> {
    fn drop(&mut self) {
        let (do_drop, log) = match *self {
            E::A(GaspA(ref f, ref mut val_a, log, ref _d_a), ref mut do_drop) => {
                f(0xA1A0, &format!("E::drop, a={:x}", val_a), log);
                *val_a += 1;
                // swap in do_drop := false to avoid infinite dtor regress
                (mem::replace(do_drop, false), log)
            }
            E::B(GaspB(ref g, ref mut val_b, log, ref _d_b), ref mut do_drop) => {
                g(0xB2B0, &format!("E::drop, b={:x}", val_b), log);
                *val_b += 1;
                // swap in do_drop := false to avoid infinite dtor regress
                (mem::replace(do_drop, false), log)
            }
        };

        if do_drop {
            let _ = mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true));
        }
    }
}

// This module provides simultaneous printouts of the dynamic extents
// of all of the D values, in addition to logging the order that each
// is dropped.
//
// This code is similar to a support code module embedded within
// test/run-pass/issue-123338-ensure-param-drop-order.rs; however,
// that (slightly simpler) code only identifies objects in the log via
// (creation) time-stamps; this incorporates both timestamping and the
// point of origin within the source code into the unique ID (uid).

const PREF_INDENT: u32 = 20;

pub mod d {
    #![allow(unused_parens)]
    use std::fmt;
    use std::mem;
    use std::cell::RefCell;

    static mut counter: u16 = 0;
    static mut trails: u64 = 0;

    pub type Log<'a> = &'a RefCell<Vec<u32>>;

    pub fn current_width() -> u32 {
        unsafe { max_width() - trails.leading_zeros() }
    }

    pub fn max_width() -> u32 {
        unsafe {
            (mem::size_of_val(&trails)*8) as u32
        }
    }

    pub fn indent_println(my_trails: u32, s: &str) {
        let mut indent: String = String::new();
        for i in 0..my_trails {
            unsafe {
                if trails & (1 << i) != 0 {
                    indent = indent + "| ";
                } else {
                    indent = indent + "  ";
                }
            }
        }
        println!("{}{}", indent, s);
    }

    pub fn println(s: &str) {
        indent_println(super::PREF_INDENT, s);
    }

    fn first_avail() -> u32 {
        unsafe {
            for i in 0..64 {
                if trails & (1 << i) == 0 {
                    return i;
                }
            }
        }
        panic!("exhausted trails");
    }

    pub struct D<'a> {
        name: &'static str, i: u8, uid: u32, trail: u32, log: Log<'a>
    }

    impl<'a> fmt::Display for D<'a> {
        fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
            write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
        }
    }

    impl<'a> D<'a> {
        pub fn new(name: &'static str, i: u8, log: Log<'a>) -> D<'a> {
            unsafe {
                let trail = first_avail();
                let ctr = ((i as u32) * 10_000_000) + (counter as u32);
                counter += 1;
                trails |= (1 << trail);
                let ret = D {
                    name: name, i: i, log: log, uid: ctr, trail: trail
                };
                indent_println(trail, &format!("+-- Make {}", ret));
                ret
            }
        }
    }

    impl<'a> Drop for D<'a> {
        fn drop(&mut self) {
            unsafe { trails &= !(1 << self.trail); };
            self.log.borrow_mut().push(self.uid);
            indent_println(self.trail, &format!("+-- Drop {}", self));
            indent_println(::PREF_INDENT, "");
        }
    }
}
<commit_msg>allow(unused_must_use) in issue-23611-enum-swap-in-drop.rs<commit_after>// run-pass
#![allow(non_upper_case_globals)]

// Issue 23611: this test is ensuring that, for an instance `X` of the
// enum `E`, if you swap in a different variant during the execution
// of the `<E as Drop>::drop`, then the appropriate substructure will
// be torn down after the `<E as Drop>::drop` method returns.

use std::cell::RefCell;
use std::mem;

use self::d::D;

pub fn main() {
    let log = RefCell::new(vec![]);
    d::println("created empty log");
    test(&log);

    // println!("log: {:?}", &log.borrow()[..]);
    assert_eq!(
        &log.borrow()[..],
        [
            //                                         created empty log
            // +-- Make D(test_1, 10000000)
            // | +-- Make D(g_b_5, 50000001)
            // | |                                     in g_B(b2b0) from E::drop, b=b4b0
            // | +-- Drop D(g_b_5, 50000001)
            50000001,
            // |
            // | +-- Make D(drop_6, 60000002)
            // | | +-- Make D(g_b_5, 50000003)
            // | | |                                   in g_B(b2b0) from E::drop, b=b4b1
            // | | +-- Drop D(g_b_5, 50000003)
            50000003,
            // | |
            // | | +-- Make D(GaspB::drop_3, 30000004)
            // | | | +-- Make D(g_b_5, 50000005)
            // | | | |                                 in g_B(b4b2) from GaspB::drop
            // | | | +-- Drop D(g_b_5, 50000005)
            50000005,
            // | | |
            // | | +-- Drop D(GaspB::drop_3, 30000004)
            30000004,
            // | |
            // +-- Drop D(test_1, 10000000)
            10000000,
            //   |
            // +-- Make D(GaspA::drop_2, 20000006)
            // | | +-- Make D(f_a_4, 40000007)
            // | | |                                   in f_A(a3a0) from GaspA::drop
            // | | +-- Drop D(f_a_4, 40000007)
            40000007,
            // | |
            // +-- Drop D(GaspA::drop_2, 20000006)
            20000006,
            //   |
            //   +-- Drop D(drop_6, 60000002)
            60000002
            //
                ]);

    // For reference purposes, the old (incorrect) behavior would produce the following
    // output, which you can compare to the above:
    //
    //                                             created empty log
    // +-- Make D(test_1, 10000000)
    // | +-- Make D(g_b_5, 50000001)
    // | |                                     in g_B(b2b0) from E::drop, b=b4b0
    // | +-- Drop D(g_b_5, 50000001)
    // |
    // | +-- Make D(drop_6, 60000002)
    // | | +-- Make D(g_b_5, 50000003)
    // | | |                                   in g_B(b2b0) from E::drop, b=b4b1
    // | | +-- Drop D(g_b_5, 50000003)
    // | |
    // | | +-- Make D(GaspB::drop_3, 30000004)
    // | | | +-- Make D(g_b_5, 50000005)
    // | | | |                                 in g_B(b4b2) from GaspB::drop
    // | | | +-- Drop D(g_b_5, 50000005)
    // | | |
    // | | +-- Drop D(GaspB::drop_3, 30000004)
    // | |
    // +-- Drop D(test_1, 10000000)
    //   |
    // +-- Make D(GaspB::drop_3, 30000006)
    // | | +-- Make D(f_a_4, 40000007)
    // | | |                                   in f_A(a3a0) from GaspB::drop
    // | | +-- Drop D(f_a_4, 40000007)
    // | |
    // +-- Drop D(GaspB::drop_3, 30000006)
    //   |
    //   +-- Drop D(drop_6, 60000002)

    // Note that this calls f_A from GaspB::drop (and thus creates a D
    // with a uid incorporating the origin of GaspB's drop that
    // surrounds the f_A invocation), but the code as written only
    // ever hands f_A off to instances of GaspA, and thus one should
    // be able to prove the invariant that f_A is *only* invoked from
    // from an instance of GaspA (either via the GaspA drop
    // implementation or the E drop implementaton). Yet the old (bad)
    // behavior allowed a call to f_A to leak in while we are tearing
    // down a value of type GaspB.
}

fn test<'a>(log: d::Log<'a>) {
    let _e = E::B(GaspB(g_b, 0xB4B0, log, D::new("test", 1, log)), true);
}

struct GaspA<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);
struct GaspB<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>);

impl<'a> Drop for GaspA<'a> {
    fn drop(&mut self) {
        let _d = d::D::new("GaspA::drop", 2, self.2);
        (self.0)(self.1, "GaspA::drop", self.2);
    }
}

impl<'a> Drop for GaspB<'a> {
    fn drop(&mut self) {
        let _d = d::D::new("GaspB::drop", 3, self.2);
        (self.0)(self.1, "GaspB::drop", self.2);
    }
}

enum E<'a> {
    A(GaspA<'a>, bool), B(GaspB<'a>, bool),
}

fn f_a(x: u32, ctxt: &str, log: d::Log) {
    let _d = d::D::new("f_a", 4, log);
    d::println(&format!("in f_A({:x}) from {}", x, ctxt));
}
fn g_b(y: u32, ctxt: &str, log: d::Log) {
    let _d = d::D::new("g_b", 5, log);
    d::println(&format!("in g_B({:x}) from {}", y, ctxt));
}

impl<'a> Drop for E<'a> {
    fn drop(&mut self) {
        let (do_drop, log) = match *self {
            E::A(GaspA(ref f, ref mut val_a, log, ref _d_a), ref mut do_drop) => {
                f(0xA1A0, &format!("E::drop, a={:x}", val_a), log);
                *val_a += 1;
                // swap in do_drop := false to avoid infinite dtor regress
                (mem::replace(do_drop, false), log)
            }
            E::B(GaspB(ref g, ref mut val_b, log, ref _d_b), ref mut do_drop) => {
                g(0xB2B0, &format!("E::drop, b={:x}", val_b), log);
                *val_b += 1;
                // swap in do_drop := false to avoid infinite dtor regress
                (mem::replace(do_drop, false), log)
            }
        };

        #[allow(unused_must_use)]
        if do_drop {
            mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true));
        }
    }
}

// This module provides simultaneous printouts of the dynamic extents
// of all of the D values, in addition to logging the order that each
// is dropped.
//
// This code is similar to a support code module embedded within
// test/run-pass/issue-123338-ensure-param-drop-order.rs; however,
// that (slightly simpler) code only identifies objects in the log via
// (creation) time-stamps; this incorporates both timestamping and the
// point of origin within the source code into the unique ID (uid).

const PREF_INDENT: u32 = 20;

pub mod d {
    #![allow(unused_parens)]
    use std::fmt;
    use std::mem;
    use std::cell::RefCell;

    static mut counter: u16 = 0;
    static mut trails: u64 = 0;

    pub type Log<'a> = &'a RefCell<Vec<u32>>;

    pub fn current_width() -> u32 {
        unsafe { max_width() - trails.leading_zeros() }
    }

    pub fn max_width() -> u32 {
        unsafe {
            (mem::size_of_val(&trails)*8) as u32
        }
    }

    pub fn indent_println(my_trails: u32, s: &str) {
        let mut indent: String = String::new();
        for i in 0..my_trails {
            unsafe {
                if trails & (1 << i) != 0 {
                    indent = indent + "| ";
                } else {
                    indent = indent + "  ";
                }
            }
        }
        println!("{}{}", indent, s);
    }

    pub fn println(s: &str) {
        indent_println(super::PREF_INDENT, s);
    }

    fn first_avail() -> u32 {
        unsafe {
            for i in 0..64 {
                if trails & (1 << i) == 0 {
                    return i;
                }
            }
        }
        panic!("exhausted trails");
    }

    pub struct D<'a> {
        name: &'static str, i: u8, uid: u32, trail: u32, log: Log<'a>
    }

    impl<'a> fmt::Display for D<'a> {
        fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
            write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
        }
    }

    impl<'a> D<'a> {
        pub fn new(name: &'static str, i: u8, log: Log<'a>) -> D<'a> {
            unsafe {
                let trail = first_avail();
                let ctr = ((i as u32) * 10_000_000) + (counter as u32);
                counter += 1;
                trails |= (1 << trail);
                let ret = D {
                    name: name, i: i, log: log, uid: ctr, trail: trail
                };
                indent_println(trail, &format!("+-- Make {}", ret));
                ret
            }
        }
    }

    impl<'a> Drop for D<'a> {
        fn drop(&mut self) {
            unsafe { trails &= !(1 << self.trail); };
            self.log.borrow_mut().push(self.uid);
            indent_println(self.trail, &format!("+-- Drop {}", self));
            indent_println(::PREF_INDENT, "");
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! `OpCounters` is a collection of convenience methods to add arbitrary counters to modules.
//! For now, it supports Int-Counters, Int-Gauges, and Histogram.

use prometheus::{
    core::{Collector, Desc},
    proto::MetricFamily,
    Histogram, HistogramOpts, HistogramTimer, HistogramVec, IntCounterVec, IntGauge, IntGaugeVec,
    Opts,
};

use std::time::Duration;

/// A small wrapper around Histogram to handle the special case
/// of duration buckets.
/// This Histogram will handle the correct granularity for logging
/// time duration in a way that fits the used buckets.
pub struct DurationHistogram {
    histogram: Histogram,
}

impl DurationHistogram {
    pub fn new(histogram: Histogram) -> DurationHistogram {
        DurationHistogram { histogram }
    }

    pub fn observe_duration(&self, d: Duration) {
        // Duration is full seconds + nanos elapsed from the previous full second
        let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
        self.histogram.observe(v);
    }
}

#[derive(Clone)]
pub struct OpMetrics {
    module: String,
    counters: IntCounterVec,
    gauges: IntGaugeVec,
    peer_gauges: IntGaugeVec,
    duration_histograms: HistogramVec,
}

impl OpMetrics {
    pub fn new<S: Into<String>>(name: S) -> OpMetrics {
        let name_str = name.into();
        OpMetrics {
            module: name_str.clone(),
            counters: IntCounterVec::new(
                Opts::new(name_str.clone(), format!("Counters for {}", name_str)),
                &["op"],
            )
            .unwrap(),
            gauges: IntGaugeVec::new(
                Opts::new(
                    format!("{}_gauge", name_str.clone()),
                    format!("Gauges for {}", name_str),
                ),
                &["op"],
            )
            .unwrap(),
            peer_gauges: IntGaugeVec::new(
                Opts::new(
                    format!("{}_peer_gauge", name_str.clone()),
                    format!("Gauges of each remote peer for {}", name_str),
                ),
                &["op", "remote_peer_id"],
            )
            .unwrap(),
            duration_histograms: HistogramVec::new(
                HistogramOpts::new(
                    format!("{}_duration", name_str.clone()),
                    format!("Histogram values for {}", name_str),
                ),
                &["op"],
            )
            .unwrap(),
        }
    }

    pub fn new_and_registered<S: Into<String>>(name: S) -> OpMetrics {
        let op_metrics = OpMetrics::new(name);
        prometheus::register(Box::new(op_metrics.clone()))
            .expect("OpMetrics registration on Prometheus failed.");
        op_metrics
    }

    #[inline]
    pub fn gauge(&self, name: &str) -> IntGauge {
        self.gauges.with_label_values(&[name])
    }

    #[inline]
    pub fn peer_gauge(&self, name: &str, remote_peer_id: &str) -> IntGauge {
        self.peer_gauges.with_label_values(&[name, remote_peer_id])
    }

    #[inline]
    pub fn inc(&self, op: &str) {
        self.counters.with_label_values(&[op]).inc();
    }

    #[inline]
    pub fn inc_by(&self, op: &str, v: usize) {
        // The underlying method is expecting i64, but most of the types
        // we're going to log are `u64` or `usize`.
        self.counters.with_label_values(&[op]).inc_by(v as i64);
    }

    #[inline]
    pub fn add(&self, op: &str) {
        self.gauges.with_label_values(&[op]).inc();
    }

    #[inline]
    pub fn sub(&self, op: &str) {
        self.gauges.with_label_values(&[op]).dec();
    }

    #[inline]
    pub fn set(&self, op: &str, v: usize) {
        // The underlying method is expecting i64, but most of the types
        // we're going to log are `u64` or `usize`.
        self.gauges.with_label_values(&[op]).set(v as i64);
    }

    #[inline]
    pub fn observe(&self, op: &str, v: f64) {
        self.duration_histograms.with_label_values(&[op]).observe(v);
    }

    pub fn observe_duration(&self, op: &str, d: Duration) {
        // Duration is full seconds + nanos elapsed from the previous full second
        let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
        self.duration_histograms.with_label_values(&[op]).observe(v);
    }

    pub fn timer(&self, op: &str) -> HistogramTimer {
        self.duration_histograms
            .with_label_values(&[op])
            .start_timer()
    }
}

impl Collector for OpMetrics {
    fn desc(&self) -> Vec<&Desc> {
        let mut ms = Vec::with_capacity(4);
        ms.extend(self.counters.desc());
        ms.extend(self.gauges.desc());
        ms.extend(self.peer_gauges.desc());
        ms.extend(self.duration_histograms.desc());
        ms
    }

    fn collect(&self) -> Vec<MetricFamily> {
        let mut ms = Vec::with_capacity(4);
        ms.extend(self.counters.collect());
        ms.extend(self.gauges.collect());
        ms.extend(self.peer_gauges.collect());
        ms.extend(self.duration_histograms.collect());
        ms
    }
}
<commit_msg>Removing add from common/metrics/src/op_counters.rs<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! `OpCounters` is a collection of convenience methods to add arbitrary counters to modules.
//! For now, it supports Int-Counters, Int-Gauges, and Histogram.

use prometheus::{
    core::{Collector, Desc},
    proto::MetricFamily,
    Histogram, HistogramOpts, HistogramTimer, HistogramVec, IntCounterVec, IntGauge, IntGaugeVec,
    Opts,
};

use std::time::Duration;

/// A small wrapper around Histogram to handle the special case
/// of duration buckets.
/// This Histogram will handle the correct granularity for logging
/// time duration in a way that fits the used buckets.
pub struct DurationHistogram {
    histogram: Histogram,
}

impl DurationHistogram {
    pub fn new(histogram: Histogram) -> DurationHistogram {
        DurationHistogram { histogram }
    }

    pub fn observe_duration(&self, d: Duration) {
        // Duration is full seconds + nanos elapsed from the previous full second
        let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
        self.histogram.observe(v);
    }
}

#[derive(Clone)]
pub struct OpMetrics {
    module: String,
    counters: IntCounterVec,
    gauges: IntGaugeVec,
    peer_gauges: IntGaugeVec,
    duration_histograms: HistogramVec,
}

impl OpMetrics {
    pub fn new<S: Into<String>>(name: S) -> OpMetrics {
        let name_str = name.into();
        OpMetrics {
            module: name_str.clone(),
            counters: IntCounterVec::new(
                Opts::new(name_str.clone(), format!("Counters for {}", name_str)),
                &["op"],
            )
            .unwrap(),
            gauges: IntGaugeVec::new(
                Opts::new(
                    format!("{}_gauge", name_str.clone()),
                    format!("Gauges for {}", name_str),
                ),
                &["op"],
            )
            .unwrap(),
            peer_gauges: IntGaugeVec::new(
                Opts::new(
                    format!("{}_peer_gauge", name_str.clone()),
                    format!("Gauges of each remote peer for {}", name_str),
                ),
                &["op", "remote_peer_id"],
            )
            .unwrap(),
            duration_histograms: HistogramVec::new(
                HistogramOpts::new(
                    format!("{}_duration", name_str.clone()),
                    format!("Histogram values for {}", name_str),
                ),
                &["op"],
            )
            .unwrap(),
        }
    }

    pub fn new_and_registered<S: Into<String>>(name: S) -> OpMetrics {
        let op_metrics = OpMetrics::new(name);
        prometheus::register(Box::new(op_metrics.clone()))
            .expect("OpMetrics registration on Prometheus failed.");
        op_metrics
    }

    #[inline]
    pub fn gauge(&self, name: &str) -> IntGauge {
        self.gauges.with_label_values(&[name])
    }

    #[inline]
    pub fn peer_gauge(&self, name: &str, remote_peer_id: &str) -> IntGauge {
        self.peer_gauges.with_label_values(&[name, remote_peer_id])
    }

    #[inline]
    pub fn inc(&self, op: &str) {
        self.counters.with_label_values(&[op]).inc();
    }

    #[inline]
    pub fn inc_by(&self, op: &str, v: usize) {
        // The underlying method is expecting i64, but most of the types
        // we're going to log are `u64` or `usize`.
        self.counters.with_label_values(&[op]).inc_by(v as i64);
    }

    #[inline]
    pub fn set(&self, op: &str, v: usize) {
        // The underlying method is expecting i64, but most of the types
        // we're going to log are `u64` or `usize`.
        self.gauges.with_label_values(&[op]).set(v as i64);
    }

    #[inline]
    pub fn observe(&self, op: &str, v: f64) {
        self.duration_histograms.with_label_values(&[op]).observe(v);
    }

    pub fn observe_duration(&self, op: &str, d: Duration) {
        // Duration is full seconds + nanos elapsed from the previous full second
        let v = d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1e9;
        self.duration_histograms.with_label_values(&[op]).observe(v);
    }

    pub fn timer(&self, op: &str) -> HistogramTimer {
        self.duration_histograms
            .with_label_values(&[op])
            .start_timer()
    }
}

impl Collector for OpMetrics {
    fn desc(&self) -> Vec<&Desc> {
        let mut ms = Vec::with_capacity(4);
        ms.extend(self.counters.desc());
        ms.extend(self.gauges.desc());
        ms.extend(self.peer_gauges.desc());
        ms.extend(self.duration_histograms.desc());
        ms
    }

    fn collect(&self) -> Vec<MetricFamily> {
        let mut ms = Vec::with_capacity(4);
        ms.extend(self.counters.collect());
        ms.extend(self.gauges.collect());
        ms.extend(self.peer_gauges.collect());
        ms.extend(self.duration_histograms.collect());
        ms
    }
}
<|endoftext|>