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

extern crate env_logger;
extern crate winit;
extern crate glutin;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_window_glutin;
// extern crate gfx_window_glfw;

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

#[cfg(feature = "metal")]
extern crate gfx_device_metal;
#[cfg(feature = "metal")]
extern crate gfx_window_metal;

#[cfg(feature = "vulkan")]
extern crate gfx_device_vulkan;
#[cfg(feature = "vulkan")]
extern crate gfx_window_vulkan;

pub mod shade;

#[cfg(not(feature = "vulkan"))]
pub type ColorFormat = gfx::format::Rgba8;
#[cfg(feature = "vulkan")]
pub type ColorFormat = gfx::format::Bgra8;

#[cfg(feature = "metal")]
pub type DepthFormat = gfx::format::Depth32F;
#[cfg(not(feature = "metal"))]
pub type DepthFormat = gfx::format::DepthStencil;

pub struct Init<R: gfx::Resources> {
    pub backend: shade::Backend,
    pub color: gfx::handle::RenderTargetView<R, ColorFormat>,
    pub depth: gfx::handle::DepthStencilView<R, DepthFormat>,
    pub aspect_ratio: f32,
}

pub enum Backend {
    OpenGL2,
    Direct3D11 { pix_mode: bool },
    Metal,
}

struct Harness {
    start: std::time::Instant,
    num_frames: f64,
}

impl Harness {
    fn new() -> Harness {
        Harness {
            start: std::time::Instant::now(),
            num_frames: 0.0,
        }
    }
    fn bump(&mut self) {
        self.num_frames += 1.0;
    }
}

impl Drop for Harness {
    fn drop(&mut self) {
        let time_end = self.start.elapsed();
        println!("Avg frame time: {} ms",
                 ((time_end.as_secs() * 1000) as f64 +
                  (time_end.subsec_nanos() / 1000_000) as f64) / self.num_frames);
    }
}

pub trait Factory<R: gfx::Resources>: gfx::Factory<R> {
    type CommandBuffer: gfx::CommandBuffer<R>;
    fn create_encoder(&mut self) -> gfx::Encoder<R, Self::CommandBuffer>;
}

pub trait ApplicationBase<R: gfx::Resources, C: gfx::CommandBuffer<R>> {
    fn new<F>(F, Init<R>) -> Self where F: Factory<R, CommandBuffer = C>;
    fn render<D>(&mut self, &mut D) where D: gfx::Device<Resources = R, CommandBuffer = C>;
    fn on(&mut self, winit::Event) -> bool;
}

impl Factory<gfx_device_gl::Resources> for gfx_device_gl::Factory {
    type CommandBuffer = gfx_device_gl::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_gl::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

pub fn launch_gl3<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer>
{
    use gfx::traits::Device;

    env_logger::init().unwrap();
    let gl_version = glutin::GlRequest::GlThenGles {
        opengl_version: (3, 2), // TODO: try more versions
        opengles_version: (2, 0),
    };
    let builder = glutin::WindowBuilder::from_winit_builder(wb)
                                        .with_gl(gl_version)
                                        .with_vsync();
    let (window, mut device, factory, main_color, main_depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder);
    let (width, height) = window.get_inner_size_points().unwrap();
    let shade_lang = device.get_info().shading_language;

    let mut app = A::new(factory, Init {
        backend: if shade_lang.is_embedded {
            shade::Backend::GlslEs(shade_lang)
        } else {
            shade::Backend::Glsl(shade_lang)
        },
        color: main_color,
        depth: main_depth,
        aspect_ratio: width as f32 / height as f32,
    });

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if !app.on(event) {
                return
            }
        }
        // draw a frame
        app.render(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
        harness.bump();
    }
}

#[cfg(target_os = "windows")]
pub type D3D11CommandBuffer = gfx_device_dx11::CommandBuffer<gfx_device_dx11::DeferredContext>;
#[cfg(target_os = "windows")]
pub type D3D11CommandBufferFake = gfx_device_dx11::CommandBuffer<gfx_device_dx11::CommandList>;

#[cfg(target_os = "windows")]
impl Factory<gfx_device_dx11::Resources> for gfx_device_dx11::Factory {
    type CommandBuffer = D3D11CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_dx11::Resources, Self::CommandBuffer> {
        self.create_command_buffer_native().into()
    }
}

#[cfg(target_os = "windows")]
pub fn launch_d3d11<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_dx11::Resources, D3D11CommandBuffer>
{
    use gfx::traits::{Device, Factory};

    env_logger::init().unwrap();
    let (window, device, mut factory, main_color) =
        gfx_window_dxgi::init::<ColorFormat>(wb).unwrap();
    let main_depth = factory.create_depth_stencil_view_only(window.size.0, window.size.1)
                            .unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Hlsl(device.get_shader_model()),
        color: main_color,
        depth: main_depth,
        aspect_ratio: window.size.0 as f32 / window.size.1 as f32,
    });
    let mut device = gfx_device_dx11::Deferred::from(device);

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if !app.on(event) {
                return
            }
        }
        app.render(&mut device);
        window.swap_buffers(1);
        device.cleanup();
        harness.bump();
    }
}

#[cfg(feature = "metal")]
impl Factory<gfx_device_metal::Resources> for gfx_device_metal::Factory {
    type CommandBuffer = gfx_device_metal::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_metal::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

#[cfg(feature = "metal")]
pub fn launch_metal<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_metal::Resources, gfx_device_metal::CommandBuffer>
{
    use gfx::traits::{Device, Factory};
    use gfx::texture::Size;

    env_logger::init().unwrap();
    let (window, mut device, mut factory, main_color) = gfx_window_metal::init::<ColorFormat>(wb)
                                                                                .unwrap();
    let (width, height) = window.get_inner_size_points().unwrap();
    let main_depth = factory.create_depth_stencil_view_only(width as Size, height as Size).unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Msl(device.get_shader_model()),
        color: main_color,
        depth: main_depth,
        aspect_ratio: width as f32 / height as f32
    });

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if !app.on(event) {
                return
            }
        }
        app.render(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
        harness.bump();
    }
}

#[cfg(feature = "vulkan")]
impl Factory<gfx_device_vulkan::Resources> for gfx_device_vulkan::Factory {
    type CommandBuffer = gfx_device_vulkan::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_vulkan::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

#[cfg(feature = "vulkan")]
pub fn launch_vulkan<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_vulkan::Resources, gfx_device_vulkan::CommandBuffer>
{
    use gfx::traits::{Device, Factory};
    use gfx::texture::Size;

    env_logger::init().unwrap();
    let (mut win, mut factory) = gfx_window_vulkan::init::<ColorFormat>(wb);
    let (width, height) = win.get_size();
    let main_depth = factory.create_depth_stencil::<DepthFormat>(width as Size, height as Size).unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Vulkan,
        color: win.get_any_target(),
        depth: main_depth.2,
        aspect_ratio: width as f32 / height as f32, //TODO
    });

    let mut harness = Harness::new();
    loop {
        for event in win.get_window().poll_events() {
            if !app.on(event) {
                return
            }
        }
        let mut frame = win.start_frame();
        app.render(frame.get_queue());
        frame.get_queue().cleanup();
        harness.bump();
    }
}

#[cfg(all(not(target_os = "windows"), not(feature = "vulkan"), not(feature = "metal")))]
pub type DefaultResources = gfx_device_gl::Resources;
#[cfg(all(target_os = "windows", not(feature = "vulkan")))]
pub type DefaultResources = gfx_device_dx11::Resources;
#[cfg(feature = "metal")]
pub type DefaultResources = gfx_device_metal::Resources;
#[cfg(feature = "vulkan")]
pub type DefaultResources = gfx_device_vulkan::Resources;

pub trait Application<R: gfx::Resources>: Sized {
    fn new<F: gfx::Factory<R>>(F, Init<R>) -> Self;
    fn render<C: gfx::CommandBuffer<R>>(&mut self, &mut gfx::Encoder<R, C>);
    fn on(&mut self, event: winit::Event) -> bool {
        match event {
            winit::Event::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape)) |
            winit::Event::Closed => false,
            _ => true
        }
    }

    fn launch_simple(name: &str) where Self: Application<DefaultResources> {
        let wb = winit::WindowBuilder::new().with_title(name);
        <Self as Application<DefaultResources>>::launch_default(wb)
    }
    #[cfg(all(not(target_os = "windows"), not(feature = "vulkan"), not(feature = "metal")))]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_gl3::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(all(target_os = "windows", not(feature = "vulkan")))]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_d3d11::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(feature = "metal")]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_metal::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(feature = "vulkan")]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_vulkan::<Wrap<_, _, Self>>(wb);
    }
}

pub struct Wrap<R: gfx::Resources, C, A> {
    encoder: gfx::Encoder<R, C>,
    app: A,
}

impl<R, C, A> ApplicationBase<R, C> for Wrap<R, C, A>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          A: Application<R>
{
    fn new<F>(mut factory: F, init: Init<R>) -> Self
        where F: Factory<R, CommandBuffer = C>
    {
        Wrap {
            encoder: factory.create_encoder(),
            app: A::new(factory, init),
        }
    }

    fn render<D>(&mut self, device: &mut D)
        where D: gfx::Device<Resources = R, CommandBuffer = C>
    {
        self.app.render(&mut self.encoder);
        self.encoder.flush(device);
    }

    fn on(&mut self, event: winit::Event) -> bool {
        self.app.on(event)
    }
}
<commit_msg>First pass at window resize in gfx_app<commit_after>// Copyright 2016 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate env_logger;
extern crate winit;
extern crate glutin;
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_window_glutin;
// extern crate gfx_window_glfw;

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

#[cfg(feature = "metal")]
extern crate gfx_device_metal;
#[cfg(feature = "metal")]
extern crate gfx_window_metal;

#[cfg(feature = "vulkan")]
extern crate gfx_device_vulkan;
#[cfg(feature = "vulkan")]
extern crate gfx_window_vulkan;

pub mod shade;

#[cfg(not(feature = "vulkan"))]
pub type ColorFormat = gfx::format::Rgba8;
#[cfg(feature = "vulkan")]
pub type ColorFormat = gfx::format::Bgra8;

#[cfg(feature = "metal")]
pub type DepthFormat = gfx::format::Depth32F;
#[cfg(not(feature = "metal"))]
pub type DepthFormat = gfx::format::DepthStencil;

pub struct Init<R: gfx::Resources> {
    pub backend: shade::Backend,
    pub color: gfx::handle::RenderTargetView<R, ColorFormat>,
    pub depth: gfx::handle::DepthStencilView<R, DepthFormat>,
    pub aspect_ratio: f32,
}

pub enum Backend {
    OpenGL2,
    Direct3D11 { pix_mode: bool },
    Metal,
}

struct Harness {
    start: std::time::Instant,
    num_frames: f64,
}

impl Harness {
    fn new() -> Harness {
        Harness {
            start: std::time::Instant::now(),
            num_frames: 0.0,
        }
    }
    fn bump(&mut self) {
        self.num_frames += 1.0;
    }
}

impl Drop for Harness {
    fn drop(&mut self) {
        let time_end = self.start.elapsed();
        println!("Avg frame time: {} ms",
                 ((time_end.as_secs() * 1000) as f64 +
                  (time_end.subsec_nanos() / 1000_000) as f64) / self.num_frames);
    }
}

pub trait Factory<R: gfx::Resources>: gfx::Factory<R> {
    type CommandBuffer: gfx::CommandBuffer<R>;
    fn create_encoder(&mut self) -> gfx::Encoder<R, Self::CommandBuffer>;
}

pub trait ApplicationBase<R: gfx::Resources, C: gfx::CommandBuffer<R>> {
    fn new<F>(F, Init<R>) -> Self where F: Factory<R, CommandBuffer = C>;
    fn render<D>(&mut self, &mut D) where D: gfx::Device<Resources = R, CommandBuffer = C>;
    fn on(&mut self, winit::Event) -> bool;
    fn on_update_window_size(&mut self, color: gfx::handle::RenderTargetView<R, ColorFormat>, depth: gfx::handle::DepthStencilView<R, DepthFormat>, aspect_ratio: f32);
}

impl Factory<gfx_device_gl::Resources> for gfx_device_gl::Factory {
    type CommandBuffer = gfx_device_gl::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_gl::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

pub fn launch_gl3<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer>
{
    use gfx::traits::Device;

    env_logger::init().unwrap();
    let gl_version = glutin::GlRequest::GlThenGles {
        opengl_version: (3, 2), // TODO: try more versions
        opengles_version: (2, 0),
    };
    let builder = glutin::WindowBuilder::from_winit_builder(wb)
                                        .with_gl(gl_version)
                                        .with_vsync();
    let (window, mut device, factory, main_color, main_depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder);
    let (width, height) = window.get_inner_size_points().unwrap();
    let shade_lang = device.get_info().shading_language;

    let mut app = A::new(factory, Init {
        backend: if shade_lang.is_embedded {
            shade::Backend::GlslEs(shade_lang)
        } else {
            shade::Backend::Glsl(shade_lang)
        },
        color: main_color,
        depth: main_depth,
        aspect_ratio: width as f32 / height as f32,
    });

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if let winit::Event::Resized(width, height) = event {
                let new_color = panic!();
                let new_depth = panic!();
                let new_aspect_ratio = width as f32 / height as f32;
                app.on_update_window_size(new_color, new_depth, new_aspect_ratio);
            }
            if !app.on(event) {
                return
            }
        }
        // draw a frame
        app.render(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
        harness.bump();
    }
}

#[cfg(target_os = "windows")]
pub type D3D11CommandBuffer = gfx_device_dx11::CommandBuffer<gfx_device_dx11::DeferredContext>;
#[cfg(target_os = "windows")]
pub type D3D11CommandBufferFake = gfx_device_dx11::CommandBuffer<gfx_device_dx11::CommandList>;

#[cfg(target_os = "windows")]
impl Factory<gfx_device_dx11::Resources> for gfx_device_dx11::Factory {
    type CommandBuffer = D3D11CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_dx11::Resources, Self::CommandBuffer> {
        self.create_command_buffer_native().into()
    }
}

#[cfg(target_os = "windows")]
pub fn launch_d3d11<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_dx11::Resources, D3D11CommandBuffer>
{
    use gfx::traits::{Device, Factory};

    env_logger::init().unwrap();
    let (window, device, mut factory, main_color) =
        gfx_window_dxgi::init::<ColorFormat>(wb).unwrap();
    let main_depth = factory.create_depth_stencil_view_only(window.size.0, window.size.1)
                            .unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Hlsl(device.get_shader_model()),
        color: main_color,
        depth: main_depth,
        aspect_ratio: window.size.0 as f32 / window.size.1 as f32,
    });
    let mut device = gfx_device_dx11::Deferred::from(device);

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if !app.on(event) {
                return
            }
        }
        app.render(&mut device);
        window.swap_buffers(1);
        device.cleanup();
        harness.bump();
    }
}

#[cfg(feature = "metal")]
impl Factory<gfx_device_metal::Resources> for gfx_device_metal::Factory {
    type CommandBuffer = gfx_device_metal::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_metal::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

#[cfg(feature = "metal")]
pub fn launch_metal<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_metal::Resources, gfx_device_metal::CommandBuffer>
{
    use gfx::traits::{Device, Factory};
    use gfx::texture::Size;

    env_logger::init().unwrap();
    let (window, mut device, mut factory, main_color) = gfx_window_metal::init::<ColorFormat>(wb)
                                                                                .unwrap();
    let (width, height) = window.get_inner_size_points().unwrap();
    let main_depth = factory.create_depth_stencil_view_only(width as Size, height as Size).unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Msl(device.get_shader_model()),
        color: main_color,
        depth: main_depth,
        aspect_ratio: width as f32 / height as f32
    });

    let mut harness = Harness::new();
    loop {
        for event in window.poll_events() {
            if !app.on(event) {
                return
            }
        }
        app.render(&mut device);
        window.swap_buffers().unwrap();
        device.cleanup();
        harness.bump();
    }
}

#[cfg(feature = "vulkan")]
impl Factory<gfx_device_vulkan::Resources> for gfx_device_vulkan::Factory {
    type CommandBuffer = gfx_device_vulkan::CommandBuffer;
    fn create_encoder(&mut self) -> gfx::Encoder<gfx_device_vulkan::Resources, Self::CommandBuffer> {
        self.create_command_buffer().into()
    }
}

#[cfg(feature = "vulkan")]
pub fn launch_vulkan<A>(wb: winit::WindowBuilder) where
A: Sized + ApplicationBase<gfx_device_vulkan::Resources, gfx_device_vulkan::CommandBuffer>
{
    use gfx::traits::{Device, Factory};
    use gfx::texture::Size;

    env_logger::init().unwrap();
    let (mut win, mut factory) = gfx_window_vulkan::init::<ColorFormat>(wb);
    let (width, height) = win.get_size();
    let main_depth = factory.create_depth_stencil::<DepthFormat>(width as Size, height as Size).unwrap();

    let mut app = A::new(factory, Init {
        backend: shade::Backend::Vulkan,
        color: win.get_any_target(),
        depth: main_depth.2,
        aspect_ratio: width as f32 / height as f32, //TODO
    });

    let mut harness = Harness::new();
    loop {
        for event in win.get_window().poll_events() {
            if !app.on(event) {
                return
            }
        }
        let mut frame = win.start_frame();
        app.render(frame.get_queue());
        frame.get_queue().cleanup();
        harness.bump();
    }
}

#[cfg(all(not(target_os = "windows"), not(feature = "vulkan"), not(feature = "metal")))]
pub type DefaultResources = gfx_device_gl::Resources;
#[cfg(all(target_os = "windows", not(feature = "vulkan")))]
pub type DefaultResources = gfx_device_dx11::Resources;
#[cfg(feature = "metal")]
pub type DefaultResources = gfx_device_metal::Resources;
#[cfg(feature = "vulkan")]
pub type DefaultResources = gfx_device_vulkan::Resources;

pub trait Application<R: gfx::Resources>: Sized {
    fn new<F: gfx::Factory<R>>(F, Init<R>) -> Self;
    fn render<C: gfx::CommandBuffer<R>>(&mut self, &mut gfx::Encoder<R, C>);
    fn on_update_window_size(&mut self, color: gfx::handle::RenderTargetView<R, ColorFormat>, depth: gfx::handle::DepthStencilView<R, DepthFormat>, aspect_ratio: f32);
    fn on(&mut self, event: winit::Event) -> bool {
        match event {
            winit::Event::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape)) |
            winit::Event::Closed => false,
            _ => true
        }
    }

    fn launch_simple(name: &str) where Self: Application<DefaultResources> {
        let wb = winit::WindowBuilder::new().with_title(name);
        <Self as Application<DefaultResources>>::launch_default(wb)
    }
    #[cfg(all(not(target_os = "windows"), not(feature = "vulkan"), not(feature = "metal")))]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_gl3::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(all(target_os = "windows", not(feature = "vulkan")))]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_d3d11::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(feature = "metal")]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_metal::<Wrap<_, _, Self>>(wb);
    }
    #[cfg(feature = "vulkan")]
    fn launch_default(wb: winit::WindowBuilder) where Self: Application<DefaultResources> {
        launch_vulkan::<Wrap<_, _, Self>>(wb);
    }
}

pub struct Wrap<R: gfx::Resources, C, A> {
    encoder: gfx::Encoder<R, C>,
    app: A,
}

impl<R, C, A> ApplicationBase<R, C> for Wrap<R, C, A>
    where R: gfx::Resources,
          C: gfx::CommandBuffer<R>,
          A: Application<R>
{
    fn new<F>(mut factory: F, init: Init<R>) -> Self
        where F: Factory<R, CommandBuffer = C>
    {
        Wrap {
            encoder: factory.create_encoder(),
            app: A::new(factory, init),
        }
    }

    fn render<D>(&mut self, device: &mut D)
        where D: gfx::Device<Resources = R, CommandBuffer = C>
    {
        self.app.render(&mut self.encoder);
        self.encoder.flush(device);
    }

    fn on(&mut self, event: winit::Event) -> bool {
        self.app.on(event)
    }

    fn on_update_window_size(&mut self, color: gfx::handle::RenderTargetView<R, ColorFormat>, depth: gfx::handle::DepthStencilView<R, DepthFormat>, aspect_ratio: f32) {
        self.app.on_update_window_size(color, depth, aspect_ratio);
    }
}
<|endoftext|>


<commit_before><commit_msg>updated ref<commit_after><|endoftext|>


<commit_before>#![feature(macro_rules)]

pub struct Slide<T: Iterator, A> {
  iter: T,
  n: uint,
  window: Vec
}

macro_rules! return_if(
  ($cond:expr, $value:expr) => (
    if $cond {
      return $value;
    }
  );
)

impl<A: Clone, T: Iterator> Slide<T, A> {
  fn push_window(&mut self) -> bool {
    let iter_next = self.iter.next();

    if iter_next.is_some() {
      self.window.push(iter_next.unwrap());
      true
    } else {
      false
    }
  }

  fn new(iter: T, n: uint) -> Slide<T, A> {
    Slide{
      iter: iter,
      n: n,
      window: Vec::with_capacity(n)
    }
  }
}

impl<A: Clone, T: Iterator> Iterator<Vec> for Slide<T, A> {
  fn next(&mut self) -> Option<Vec> {
    return_if!(self.n == 0, None);
    return_if!(!self.push_window(), None);

    loop {
      let window_status = self.window.len().cmp(&self.n);

      match window_status {
        Greater => { self.window.remove(0); }
        Equal => { return Some(self.window.clone()); }
        Less => { return_if!(!self.push_window(), None); }
      }
    }
  }
}

pub trait SlideIterator<T: Iterator, A> {
  fn slide(self, n: uint) -> Slide<T, A>;
}

impl<A: Clone, T: Iterator> SlideIterator<T, A> for T {
  fn slide(self, n: uint) -> Slide<T, A> {
    Slide::new(self, n)
  }
}

#[test]
fn test_slide() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(3);
  assert_eq!(slide_iter.next().unwrap(), vec![1, 2, 3])
  assert_eq!(slide_iter.next().unwrap(), vec![2, 3, 4])
  assert_eq!(slide_iter.next().unwrap(), vec![3, 4, 5])
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_equal_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(5);
  assert_eq!(slide_iter.next().unwrap(), vec![1, 2, 3, 4, 5])
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_zero_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(0);
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_overlong_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(7);
  assert!(slide_iter.next().is_none())
}
<commit_msg>Give the window an extra initial capacity slot<commit_after>#![feature(macro_rules)]

pub struct Slide<T: Iterator, A> {
  iter: T,
  n: uint,
  window: Vec
}

macro_rules! return_if(
  ($cond:expr, $value:expr) => (
    if $cond {
      return $value;
    }
  );
)

impl<A: Clone, T: Iterator> Slide<T, A> {
  fn push_window(&mut self) -> bool {
    let iter_next = self.iter.next();

    if iter_next.is_some() {
      self.window.push(iter_next.unwrap());
      true
    } else {
      false
    }
  }

  fn new(iter: T, n: uint) -> Slide<T, A> {
    Slide{
      iter: iter,
      n: n,
      window: Vec::with_capacity(n + 1)
    }
  }
}

impl<A: Clone, T: Iterator> Iterator<Vec> for Slide<T, A> {
  fn next(&mut self) -> Option<Vec> {
    return_if!(self.n == 0, None);
    return_if!(!self.push_window(), None);

    loop {
      let window_status = self.window.len().cmp(&self.n);

      match window_status {
        Greater => { self.window.remove(0); }
        Equal => { return Some(self.window.clone()); }
        Less => { return_if!(!self.push_window(), None); }
      }
    }
  }
}

pub trait SlideIterator<T: Iterator, A> {
  fn slide(self, n: uint) -> Slide<T, A>;
}

impl<A: Clone, T: Iterator> SlideIterator<T, A> for T {
  fn slide(self, n: uint) -> Slide<T, A> {
    Slide::new(self, n)
  }
}

#[test]
fn test_slide() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(3);
  assert_eq!(slide_iter.next().unwrap(), vec![1, 2, 3])
  assert_eq!(slide_iter.next().unwrap(), vec![2, 3, 4])
  assert_eq!(slide_iter.next().unwrap(), vec![3, 4, 5])
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_equal_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(5);
  assert_eq!(slide_iter.next().unwrap(), vec![1, 2, 3, 4, 5])
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_zero_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(0);
  assert!(slide_iter.next().is_none())
}

#[test]
fn test_slide_overlong_window() {
  let mut slide_iter = vec![1i, 2, 3, 4, 5].into_iter().slide(7);
  assert!(slide_iter.next().is_none())
}
<|endoftext|>


<commit_before><commit_msg>now it's a lib<commit_after>
pub mod graph {
	use std::collections::HashMap;

	struct Graph {
		elements: i64,
		vertices: HashMap<i64, Box<Vertex>>,
	}

	impl Graph {
		fn new() -> Box<Graph> {
			let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
			Box::new(Graph{elements:0, vertices:vertices})
		}
		fn add_vertex(&mut self) -> VertexProxy {
			let new_id = self.elements + 1;
			self.elements += 1;
			let v = Vertex::new(new_id);

			let ptr: *const Box<Vertex> = &v as *const Box<Vertex>;

			self .vertices.insert(new_id, v);

			// return the proxy which knows it's own id
			VertexProxy{id:new_id, v: ptr}
		}
	}

	struct Vertex {
		id: i64,
		edges: *mut Vec<Edge>,
	}

	impl Vertex {
		fn new(id: i64) -> Box<Vertex> {

			let mut edges : Vec<Edge> = Vec::new();
			let edges_ptr :    *mut Vec<Edge> = &mut edges;
			let vertex = Vertex{id:id, edges:edges_ptr};
			let mut v = Box::new(vertex);
			return v;
		}

		fn query(self) {

		}
	}

	#[derive(Debug)]
	struct VertexProxy {
		id: i64,
		v: *const Box<Vertex>,
	}

	//let i: u32 = 1;
	//// explicit cast
	//let p_imm: *const u32 = &i as *const u32;
	//let mut m: u32 = 2;
	//// implicit coercion
	//let p_mut: *mut u32 = &mut m;
	//
	//unsafe {
	//let ref_imm: &u32 = &*p_imm;
	//let ref_mut: &mut u32 = &mut *p_mut;
	//}

	impl VertexProxy {
		fn add_edge(& self, to_vertex: &VertexProxy) {
			unsafe {
				let in_vertex =  &* self .v;
				let out_vertex = &*to_vertex.v;
			}
			// create the edge
			let e = Edge{from_vertex: self.v,
			to_vertex:   to_vertex.v};

		}
	}

	struct Edge {
		from_vertex: *const Box<Vertex>,
		to_vertex: *const Box<Vertex>
	}

	#[test]
	fn test_unsafe_vertex() {
		let mut g = Graph::new();
		let mut v1 = g.add_vertex();
		assert!(v1.id == 1);

		let mut v2 = g.add_vertex();
		assert!(v2.id == 2);
	}

	#[test]
	fn test_add_edge() {
		let mut g = Graph::new();
		let mut v1 = g.add_vertex();
		let mut v2 = g.add_vertex();
		v2.add_edge(&v2);

	}

}
<|endoftext|>


<commit_before><commit_msg>Cleanup and documentation<commit_after><|endoftext|>


<commit_before><commit_msg>Add http-only check to cookie matching.<commit_after><|endoftext|>


<commit_before><commit_msg>Change 'scenario' to 'context' in LibError::InvalidKind's display message<commit_after><|endoftext|>


<commit_before><commit_msg>removes empty test<commit_after><|endoftext|>


<commit_before><commit_msg>updated to work with new buildable<commit_after><|endoftext|>


<commit_before><commit_msg>feat: refact find_key to also find into arrays<commit_after><|endoftext|>


<commit_before><commit_msg>Update main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Moved free bank<commit_after><|endoftext|>


<commit_before>extern crate alpm;
#[macro_use]
extern crate clap;
extern crate curl;
extern crate env_logger;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate rustc_serialize;

use clap::App;
use curl::easy::Easy;
use itertools::Itertools;
use rustc_serialize::json::Json;
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry::{Occupied, Vacant};
use std::default::Default;
use std::process::exit;
use std::str;
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq, PartialOrd)]
enum Severity {
    Unknown,
    Low,
    Medium,
    High,
    Critical,
}

impl FromStr for Severity {
    type Err = ();

    fn from_str(s: &str) -> Result<Severity, ()> {
        match s {
            "Critical" => Ok(Severity::Critical),
            "High" => Ok(Severity::High),
            "Medium" => Ok(Severity::Medium),
            "Low" => Ok(Severity::Low),
            _ => Ok(Severity::Unknown),
        }
    }
}

#[derive(Clone, Debug)]
struct AVG {
    issues: Vec<String>,
    fixed: Option<String>,
    severity: Severity,
}

impl Default for AVG {
    fn default() -> AVG {
        AVG {
            issues: vec![],
            fixed: None,
            severity: Severity::Unknown,
        }
    }
}

struct Options {
    format: Option<String>,
    quiet: u64,
    upgradable_only: bool,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            format: None,
            quiet: 0,
            upgradable_only: false,
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let yaml = load_yaml!("cli.yml");
    let args = App::from_yaml(yaml).get_matches();

    let options = Options {
        format: {
            match args.value_of("format") {
                Some(f) => Some(f.to_string()),
                None => None,
            }
        },
        quiet: args.occurrences_of("quiet"),
        upgradable_only: args.is_present("upgradable"),
    };

    let mut avgs = String::new();
    {
        info!("Downloading AVGs...");
        let avgs_url = "https://security.archlinux.org/json";

        let mut easy = Easy::new();
        easy.url(avgs_url).unwrap();
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
                avgs.push_str(str::from_utf8(data).unwrap());
                Ok(data.len())
            })
            .unwrap();
        match transfer.perform() {
            Ok(_) => {}
            Err(_) => {
                println!("Cannot fetch data, please check your network connection!");
                exit(1)
            }
        };
    }

    let pacman = match args.value_of("dbpath") {
        Some(path) => alpm::Alpm::with_dbpath(path.to_string()).unwrap(),
        None => alpm::Alpm::new().unwrap(),
    };

    let mut cves: BTreeMap<String, Vec<_>> = BTreeMap::new();
    {
        let json = Json::from_str(&avgs).unwrap();

        for avg in json.as_array().unwrap() {
            let packages = avg["packages"]
                .as_array()
                .unwrap()
                .iter()
                .map(|s| s.as_string().unwrap().to_string())
                .collect::<Vec<_>>();

            if !package_is_installed(&pacman, &packages) {
                continue;
            }

            let info = AVG {
                issues: avg["issues"]
                    .as_array()
                    .unwrap()
                    .iter()
                    .map(|s| s.as_string().unwrap().to_string())
                    .collect(),
                fixed: match avg["fixed"].as_string() {
                    Some(s) => Some(s.to_string()),
                    None => None,
                },
                severity: avg["severity"]
                    .as_string()
                    .unwrap()
                    .to_string()
                    .parse::<Severity>()
                    .unwrap(),
            };

            let status = avg["status"].as_string().unwrap();

            if !status.starts_with("Not affected") {
                for p in packages {
                    match cves.entry(p) {
                            Occupied(c) => c.into_mut(),
                            Vacant(c) => c.insert(vec![]),
                        }
                        .push(info.clone());
                }
            }
        }
    }

    let mut affected_avgs: BTreeMap<String, Vec<_>> = BTreeMap::new();
    for (pkg, avgs) in cves {
        for avg in &avgs {
            if system_is_affected(&pacman, &pkg, &avg) {
                match affected_avgs.entry(pkg.clone()) {
                        Occupied(c) => c.into_mut(),
                        Vacant(c) => c.insert(vec![]),
                    }
                    .push(avg.clone());
            }
        }
    }

    let merged = merge_avgs(&pacman, &affected_avgs);
    print_avgs(&options, &merged);
}

/// Given a package and an AVG, returns true if the system is affected
fn system_is_affected(pacman: &alpm::Alpm, pkg: &String, avg: &AVG) -> bool {
    match pacman.query_package_version(pkg.clone()) {
        Ok(v) => {
            info!("Found installed version {} for package {}", v, pkg);
            match avg.fixed {
                Some(ref version) => {
                    info!("Comparing with fixed version {}", version);
                    match pacman.vercmp(v.clone(), version.clone()).unwrap() {
                        Ordering::Less => return true,
                        _ => {}
                    };
                }
                None => return true,
            };
        }
        Err(_) => debug!("Package {} not installed", pkg),
    }

    return false;
}

#[test]
fn test_system_is_affected() {
    let pacman = alpm::Alpm::new().unwrap();

    let avg1 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("1.0.0".to_string()),
        severity: Severity::Unknown,
    };

    assert_eq!(false,
               system_is_affected(&pacman, &"pacman".to_string(), &avg1));

    let avg2 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("7.0.0".to_string()),
        severity: Severity::Unknown,
    };
    assert!(system_is_affected(&pacman, &"pacman".to_string(), &avg2));
}

/// Given a list of package names, returns true when at least one is installed
fn package_is_installed(pacman: &alpm::Alpm, packages: &Vec<String>) -> bool {
    for pkg in packages {
        match pacman.query_package_version(pkg.as_str()) {
            Ok(_) => {
                info!("Package {} is installed", pkg);
                return true;
            }
            Err(_) => debug!("Package {} not installed", pkg),
        }
    }
    return false;
}

#[test]
fn test_package_is_installed() {
    let pacman = alpm::Alpm::new().unwrap();

    let packages = vec!["pacman".to_string(), "pac".to_string()];
    assert!(package_is_installed(&pacman, &packages));

    let packages = vec!["pac".to_string()];
    assert_eq!(false, package_is_installed(&pacman, &packages));
}

/// Merge a list of AVGs into a single AVG using major version as version
fn merge_avgs(pacman: &alpm::Alpm, cves: &BTreeMap<String, Vec<AVG>>) -> BTreeMap<String, AVG> {
    let mut avgs: BTreeMap<String, AVG> = BTreeMap::new();
    for (pkg, list) in cves.iter() {
        let mut avg_issues = vec![];
        let mut avg_fixed: Option<String> = None;
        let mut avg_severity = Severity::Unknown;

        for a in list.iter() {
            avg_issues.append(&mut a.issues.clone());

            match avg_fixed.clone() {
                Some(ref version) => {
                    match a.fixed {
                        Some(ref v) => {
                            match pacman.vercmp(version.to_string(), v.to_string()).unwrap() {
                                Ordering::Greater => avg_fixed = a.fixed.clone(),
                                _ => {}
                            }
                        }
                        None => {}
                    }
                }
                None => avg_fixed = a.fixed.clone(),
            }

            if a.severity > avg_severity {
                avg_severity = a.severity.clone();
            }
        }

        let avg = AVG {
            issues: avg_issues,
            fixed: avg_fixed,
            severity: avg_severity,
        };
        avgs.insert(pkg.to_string(), avg);
    }

    avgs
}

#[test]
fn test_merge_avgs() {
    let mut avgs: BTreeMap<String, Vec<_>> = BTreeMap::new();

    let avg1 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("1.0.0".to_string()),
        severity: Severity::Unknown,
    };

    let avg2 = AVG {
        issues: vec!["CVE-4".to_string(), "CVE-10".to_string()],
        fixed: Some("0.9.8".to_string()),
        severity: Severity::High,
    };

    assert!(Severity::Critical > Severity::High);

    avgs.insert("package".to_string(), vec![avg1.clone(), avg2.clone()]);

    avgs.insert("package2".to_string(), vec![avg1, avg2]);

    let pacman = alpm::Alpm::new().unwrap();
    let merged = merge_avgs(&pacman, &avgs);

    assert_eq!(2, merged.len());
    assert_eq!(4, merged.get(&"package".to_string()).unwrap().issues.len());
    assert_eq!(Severity::High,
               merged.get(&"package".to_string()).unwrap().severity);
}

/// Print a list of AVGs
fn print_avgs(options: &Options, avgs: &BTreeMap<String, AVG>) {
    for (pkg, avg) in avgs {
        let msg = format!("Package {} is affected by {:?}", pkg, avg.issues);

        match avg.fixed {
            Some(ref v) => {
                if options.quiet == 1 {
                    println!("{}>={}", pkg, v);
                } else if options.quiet >= 2 {
                    println!("{}", pkg);
                } else {
                    match options.format {
                        Some(ref f) => {
                            println!("{}",
                                     f.replace("%n", pkg.as_str())
                                         .replace("%c", avg.issues.iter().join(",").as_str()))
                        }
                        None => println!("{}. Update to {}!", msg, v),
                    }
                }
            }
            None => {
                if !options.upgradable_only {
                    if options.quiet > 0 {
                        println!("{}", pkg);
                    } else {
                        match options.format {
                            Some(ref f) => {
                                println!("{}",
                                         f.replace("%n", pkg.as_str())
                                             .replace("%c", avg.issues.iter().join(",").as_str()))
                            }
                            None => println!("{}. {:?} risk!", msg, avg.severity),
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>Refactoring<commit_after>extern crate alpm;
#[macro_use]
extern crate clap;
extern crate curl;
extern crate env_logger;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate rustc_serialize;

use clap::App;
use curl::easy::Easy;
use itertools::Itertools;
use rustc_serialize::json::Json;
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry::{Occupied, Vacant};
use std::default::Default;
use std::process::exit;
use std::str;
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq, PartialOrd)]
enum Severity {
    Unknown,
    Low,
    Medium,
    High,
    Critical,
}

impl FromStr for Severity {
    type Err = ();

    fn from_str(s: &str) -> Result<Severity, ()> {
        match s {
            "Critical" => Ok(Severity::Critical),
            "High" => Ok(Severity::High),
            "Medium" => Ok(Severity::Medium),
            "Low" => Ok(Severity::Low),
            _ => Ok(Severity::Unknown),
        }
    }
}

#[derive(Clone, Debug)]
struct AVG {
    issues: Vec<String>,
    fixed: Option<String>,
    severity: Severity,
}

impl Default for AVG {
    fn default() -> AVG {
        AVG {
            issues: vec![],
            fixed: None,
            severity: Severity::Unknown,
        }
    }
}

struct Options {
    format: Option<String>,
    quiet: u64,
    upgradable_only: bool,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            format: None,
            quiet: 0,
            upgradable_only: false,
        }
    }
}

fn main() {
    env_logger::init().unwrap();

    let yaml = load_yaml!("cli.yml");
    let args = App::from_yaml(yaml).get_matches();

    let options = Options {
        format: {
            match args.value_of("format") {
                Some(f) => Some(f.to_string()),
                None => None,
            }
        },
        quiet: args.occurrences_of("quiet"),
        upgradable_only: args.is_present("upgradable"),
    };

    let mut avgs = String::new();
    {
        info!("Downloading AVGs...");
        let avgs_url = "https://security.archlinux.org/json";

        let mut easy = Easy::new();
        easy.url(avgs_url).unwrap();
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
                avgs.push_str(str::from_utf8(data).unwrap());
                Ok(data.len())
            })
            .unwrap();
        match transfer.perform() {
            Ok(_) => {}
            Err(_) => {
                println!("Cannot fetch data, please check your network connection!");
                exit(1)
            }
        };
    }

    let pacman = match args.value_of("dbpath") {
        Some(path) => alpm::Alpm::with_dbpath(path.to_string()).unwrap(),
        None => alpm::Alpm::new().unwrap(),
    };

    let mut cves: BTreeMap<String, Vec<_>> = BTreeMap::new();
    {
        let json = Json::from_str(&avgs).unwrap();

        for avg in json.as_array().unwrap() {
            let packages = avg["packages"]
                .as_array()
                .unwrap()
                .iter()
                .map(|s| s.as_string().unwrap().to_string())
                .collect::<Vec<_>>();

            if !package_is_installed(&pacman, &packages) {
                continue;
            }

            let status = avg["status"].as_string().unwrap();

            if !status.starts_with("Not affected") {
                let info = to_avg(avg);

                for p in packages {
                    match cves.entry(p) {
                            Occupied(c) => c.into_mut(),
                            Vacant(c) => c.insert(vec![]),
                        }
                        .push(info.clone());
                }
            }
        }
    }

    let mut affected_avgs: BTreeMap<String, Vec<_>> = BTreeMap::new();
    for (pkg, avgs) in cves {
        for avg in &avgs {
            if system_is_affected(&pacman, &pkg, &avg) {
                match affected_avgs.entry(pkg.clone()) {
                        Occupied(c) => c.into_mut(),
                        Vacant(c) => c.insert(vec![]),
                    }
                    .push(avg.clone());
            }
        }
    }

    let merged = merge_avgs(&pacman, &affected_avgs);
    print_avgs(&options, &merged);
}

fn to_avg(data: &Json) -> AVG {
    AVG {
        issues: data["issues"]
            .as_array()
            .unwrap()
            .iter()
            .map(|s| s.as_string().unwrap().to_string())
            .collect(),
        fixed: match data["fixed"].as_string() {
            Some(s) => Some(s.to_string()),
            None => None,
        },
        severity: data["severity"]
            .as_string()
            .unwrap()
            .to_string()
            .parse::<Severity>()
            .unwrap(),
    }
}

/// Given a package and an AVG, returns true if the system is affected
fn system_is_affected(pacman: &alpm::Alpm, pkg: &String, avg: &AVG) -> bool {
    match pacman.query_package_version(pkg.clone()) {
        Ok(v) => {
            info!("Found installed version {} for package {}", v, pkg);
            match avg.fixed {
                Some(ref version) => {
                    info!("Comparing with fixed version {}", version);
                    match pacman.vercmp(v.clone(), version.clone()).unwrap() {
                        Ordering::Less => return true,
                        _ => {}
                    };
                }
                None => return true,
            };
        }
        Err(_) => debug!("Package {} not installed", pkg),
    }

    return false;
}

#[test]
fn test_system_is_affected() {
    let pacman = alpm::Alpm::new().unwrap();

    let avg1 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("1.0.0".to_string()),
        severity: Severity::Unknown,
    };

    assert_eq!(false,
               system_is_affected(&pacman, &"pacman".to_string(), &avg1));

    let avg2 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("7.0.0".to_string()),
        severity: Severity::Unknown,
    };
    assert!(system_is_affected(&pacman, &"pacman".to_string(), &avg2));
}

/// Given a list of package names, returns true when at least one is installed
fn package_is_installed(pacman: &alpm::Alpm, packages: &Vec<String>) -> bool {
    for pkg in packages {
        match pacman.query_package_version(pkg.as_str()) {
            Ok(_) => {
                info!("Package {} is installed", pkg);
                return true;
            }
            Err(_) => debug!("Package {} not installed", pkg),
        }
    }
    return false;
}

#[test]
fn test_package_is_installed() {
    let pacman = alpm::Alpm::new().unwrap();

    let packages = vec!["pacman".to_string(), "pac".to_string()];
    assert!(package_is_installed(&pacman, &packages));

    let packages = vec!["pac".to_string()];
    assert_eq!(false, package_is_installed(&pacman, &packages));
}

/// Merge a list of AVGs into a single AVG using major version as version
fn merge_avgs(pacman: &alpm::Alpm, cves: &BTreeMap<String, Vec<AVG>>) -> BTreeMap<String, AVG> {
    let mut avgs: BTreeMap<String, AVG> = BTreeMap::new();
    for (pkg, list) in cves.iter() {
        let mut avg_issues = vec![];
        let mut avg_fixed: Option<String> = None;
        let mut avg_severity = Severity::Unknown;

        for a in list.iter() {
            avg_issues.append(&mut a.issues.clone());

            match avg_fixed.clone() {
                Some(ref version) => {
                    match a.fixed {
                        Some(ref v) => {
                            match pacman.vercmp(version.to_string(), v.to_string()).unwrap() {
                                Ordering::Greater => avg_fixed = a.fixed.clone(),
                                _ => {}
                            }
                        }
                        None => {}
                    }
                }
                None => avg_fixed = a.fixed.clone(),
            }

            if a.severity > avg_severity {
                avg_severity = a.severity.clone();
            }
        }

        let avg = AVG {
            issues: avg_issues,
            fixed: avg_fixed,
            severity: avg_severity,
        };
        avgs.insert(pkg.to_string(), avg);
    }

    avgs
}

#[test]
fn test_merge_avgs() {
    let mut avgs: BTreeMap<String, Vec<_>> = BTreeMap::new();

    let avg1 = AVG {
        issues: vec!["CVE-1".to_string(), "CVE-2".to_string()],
        fixed: Some("1.0.0".to_string()),
        severity: Severity::Unknown,
    };

    let avg2 = AVG {
        issues: vec!["CVE-4".to_string(), "CVE-10".to_string()],
        fixed: Some("0.9.8".to_string()),
        severity: Severity::High,
    };

    assert!(Severity::Critical > Severity::High);

    avgs.insert("package".to_string(), vec![avg1.clone(), avg2.clone()]);

    avgs.insert("package2".to_string(), vec![avg1, avg2]);

    let pacman = alpm::Alpm::new().unwrap();
    let merged = merge_avgs(&pacman, &avgs);

    assert_eq!(2, merged.len());
    assert_eq!(4, merged.get(&"package".to_string()).unwrap().issues.len());
    assert_eq!(Severity::High,
               merged.get(&"package".to_string()).unwrap().severity);
}

/// Print a list of AVGs
fn print_avgs(options: &Options, avgs: &BTreeMap<String, AVG>) {
    for (pkg, avg) in avgs {
        let msg = format!("Package {} is affected by {:?}", pkg, avg.issues);

        match avg.fixed {
            Some(ref v) => {
                if options.quiet == 1 {
                    println!("{}>={}", pkg, v);
                } else if options.quiet >= 2 {
                    println!("{}", pkg);
                } else {
                    match options.format {
                        Some(ref f) => {
                            println!("{}",
                                     f.replace("%n", pkg.as_str())
                                         .replace("%c", avg.issues.iter().join(",").as_str()))
                        }
                        None => println!("{}. Update to {}!", msg, v),
                    }
                }
            }
            None => {
                if !options.upgradable_only {
                    if options.quiet > 0 {
                        println!("{}", pkg);
                    } else {
                        match options.format {
                            Some(ref f) => {
                                println!("{}",
                                         f.replace("%n", pkg.as_str())
                                             .replace("%c", avg.issues.iter().join(",").as_str()))
                            }
                            None => println!("{}. {:?} risk!", msg, avg.severity),
                        }
                    }
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>fix iota subscript + capital, neaten up some things<commit_after><|endoftext|>


<commit_before><commit_msg>Sleep between tries<commit_after><|endoftext|>


<commit_before><commit_msg>Moved input handling to a new function<commit_after><|endoftext|>


<commit_before><commit_msg>Add client support for org.freedesktop.DBus.Properties<commit_after>use super::{Connection, Message, MessageItem, Error};
use std::collections::TreeMap;

pub struct Props {
    name: String,
    path: String,
    interface: String,
    timeout_ms: int,
}

impl Props {
    pub fn new(name: &str, path: &str, interface: &str, timeout_ms: int) -> Props {
        Props {
            name: name.to_string(),
            path: path.to_string(),
            interface: interface.to_string(),
            timeout_ms: timeout_ms
        }
    }

    pub fn get(&self, conn: &mut Connection, propname: &str) -> Result<MessageItem, Error> {
        let mut m = Message::new_method_call(self.name.as_slice(), self.path.as_slice(),
            "org.freedesktop.DBus.Properties", "Get").unwrap();
        m.append_items(&vec!(
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string())
        ));
        let mut r = try!(conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            match &reply[0] {
                &MessageItem::Variant(ref v) => return Ok(*v.deref().clone()),
                _ => {},
            }
       }
       let f = format!("Invalid reply for property get {}: '{}'", propname, reply);
       return Err(Error::new_custom("InvalidReply", f.as_slice()));
    }

    pub fn set(&self, conn: &mut Connection, propname: &str, value: MessageItem) -> Result<(), Error> {
        let mut m = Message::new_method_call(self.name.as_slice(), self.path.as_slice(),
            "org.freedesktop.DBus.Properties", "Set").unwrap();
        m.append_items(&vec!(
            MessageItem::Str(self.interface.clone()),
            MessageItem::Str(propname.to_string()),
            MessageItem::Variant(box value),
        ));
        let mut r = try!(conn.send_with_reply_and_block(m, self.timeout_ms));
        try!(r.as_result());
        Ok(())
    }

    pub fn get_all(&self, conn: &mut Connection) -> Result<TreeMap<String, MessageItem>, Error> {
        let mut m = Message::new_method_call(self.name.as_slice(), self.path.as_slice(),
            "org.freedesktop.DBus.Properties", "GetAll").unwrap();
        m.append_items(&vec!(MessageItem::Str(self.interface.clone())));
        let mut r = try!(conn.send_with_reply_and_block(m, self.timeout_ms));
        let reply = try!(r.as_result()).get_items();
        if reply.len() == 1 {
            match &reply[0] {
                &MessageItem::Array(ref a, _) => {
                    let mut t = TreeMap::new();
                    let mut haserr = false;
                    for p in a.iter() {
                        match p {
                            &MessageItem::DictEntry(ref k, ref v) => {
                                match &**k {
                                    &MessageItem::Str(ref ks) => { t.insert(ks.to_string(), *v.deref().clone()); },
                                    _ => { haserr = true; }
                                }
                            }
                            _ => { haserr = true; }
                        }
                    }
                    if !haserr {
                        return Ok(t)
                    };
                }
                _ => {},
            }
       }
       let f = format!("Invalid reply for property GetAll: '{}'", reply);
       return Err(Error::new_custom("InvalidReply", f.as_slice()));
    }
}

/* Unfortunately org.freedesktop.DBus has no properties we can use for testing, but PolicyKit should be around on most distros. */
#[test]
fn test_get_policykit_version() {
    use super::BusType;
    let mut c = Connection::get_private(BusType::System).unwrap();
    let p = Props::new("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority",
        "org.freedesktop.PolicyKit1.Authority", 10000);

    /* Let's use both the get and getall methods and see if we get the same result */
    let v = p.get(&mut c, "BackendVersion").unwrap();
    let vall = p.get_all(&mut c).unwrap();

    let v2 = match vall.get("BackendVersion").unwrap() {
        &MessageItem::Variant(ref q) => &**q,
        _ => { panic!("Invalid GetAll: {}", vall); }
    };

    assert_eq!(&v, &*v2);
    match v {
        MessageItem::Str(ref s) => { println!("Policykit Backend version is {}", s); }
        _ => { panic!("Invalid Get: {}", v); }
    };

}
<|endoftext|>


<commit_before><commit_msg>Add TagEvent.<commit_after><|endoftext|>


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

use attr;
use ast;
use codemap::{spanned, Spanned, mk_sp, Span};
use parse::common::*; //resolve bug?
use parse::token;
use parse::parser::Parser;
use ptr::P;

/// A parser that can parse attributes.
pub trait ParserAttr {
    fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
    fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
    fn parse_inner_attrs_and_next(&mut self)
                                  -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
    fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
    fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
    fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
}

impl<'a> ParserAttr for Parser<'a> {
    /// Parse attributes that appear before an item
    fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
        let mut attrs: Vec<ast::Attribute> = Vec::new();
        loop {
            debug!("parse_outer_attributes: self.token={}",
                   self.token);
            match self.token {
              token::Pound => {
                attrs.push(self.parse_attribute(false));
              }
              token::DocComment(s) => {
                let attr = ::attr::mk_sugared_doc_attr(
                    attr::mk_attr_id(),
                    self.id_to_interned_str(s.ident()),
                    self.span.lo,
                    self.span.hi
                );
                if attr.node.style != ast::AttrOuter {
                  self.fatal("expected outer comment");
                }
                attrs.push(attr);
                self.bump();
              }
              _ => break
            }
        }
        return attrs;
    }

    /// Matches `attribute = # ! [ meta_item ]`
    ///
    /// If permit_inner is true, then a leading `!` indicates an inner
    /// attribute
    fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
        debug!("parse_attributes: permit_inner={} self.token={}",
               permit_inner, self.token);
        let (span, value, mut style) = match self.token {
            token::Pound => {
                let lo = self.span.lo;
                self.bump();

                let style = if self.eat(&token::Not) {
                    if !permit_inner {
                        let span = self.span;
                        self.span_err(span,
                                      "an inner attribute is not permitted in \
                                       this context");
                    }
                    ast::AttrInner
                } else {
                    ast::AttrOuter
                };

                self.expect(&token::OpenDelim(token::Bracket));
                let meta_item = self.parse_meta_item();
                let hi = self.span.hi;
                self.expect(&token::CloseDelim(token::Bracket));

                (mk_sp(lo, hi), meta_item, style)
            }
            _ => {
                let token_str = self.this_token_to_string();
                self.fatal(format!("expected `#`, found `{}`",
                                   token_str).as_slice());
            }
        };

        if permit_inner && self.eat(&token::Semi) {
            self.span_warn(span, "this inner attribute syntax is deprecated. \
                           The new syntax is `#![foo]`, with a bang and no semicolon.");
            style = ast::AttrInner;
        }

        return Spanned {
            span: span,
            node: ast::Attribute_ {
                id: attr::mk_attr_id(),
                style: style,
                value: value,
                is_sugared_doc: false
            }
        };
    }

    /// Parse attributes that appear after the opening of an item. These should
    /// be preceded by an exclamation mark, but we accept and warn about one
    /// terminated by a semicolon. In addition to a vector of inner attributes,
    /// this function also returns a vector that may contain the first outer
    /// attribute of the next item (since we can't know whether the attribute
    /// is an inner attribute of the containing item or an outer attribute of
    /// the first contained item until we see the semi).

    /// matches inner_attrs* outer_attr?
    /// you can make the 'next' field an Option, but the result is going to be
    /// more useful as a vector.
    fn parse_inner_attrs_and_next(&mut self)
                                  -> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
        let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
        let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
        loop {
            let attr = match self.token {
                token::Pound => {
                    self.parse_attribute(true)
                }
                token::DocComment(s) => {
                    // we need to get the position of this token before we bump.
                    let Span { lo, hi, .. } = self.span;
                    self.bump();
                    attr::mk_sugared_doc_attr(attr::mk_attr_id(),
                                              self.id_to_interned_str(s.ident()),
                                              lo,
                                              hi)
                }
                _ => {
                    break;
                }
            };
            if attr.node.style == ast::AttrInner {
                inner_attrs.push(attr);
            } else {
                next_outer_attrs.push(attr);
                break;
            }
        }
        (inner_attrs, next_outer_attrs)
    }

    /// matches meta_item = IDENT
    /// | IDENT = lit
    /// | IDENT meta_seq
    fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
        let nt_meta = match self.token {
            token::Interpolated(token::NtMeta(ref e)) => {
                Some(e.clone())
            }
            _ => None
        };

        match nt_meta {
            Some(meta) => {
                self.bump();
                return meta;
            }
            None => {}
        }

        let lo = self.span.lo;
        let ident = self.parse_ident();
        let name = self.id_to_interned_str(ident);
        match self.token {
            token::Eq => {
                self.bump();
                let lit = self.parse_lit();
                // FIXME #623 Non-string meta items are not serialized correctly;
                // just forbid them for now
                match lit.node {
                    ast::LitStr(..) => {}
                    _ => {
                        self.span_err(
                            lit.span,
                            "non-string literals are not allowed in meta-items");
                    }
                }
                let hi = self.span.hi;
                P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
            }
            token::OpenDelim(token::Paren) => {
                let inner_items = self.parse_meta_seq();
                let hi = self.span.hi;
                P(spanned(lo, hi, ast::MetaList(name, inner_items)))
            }
            _ => {
                let hi = self.last_span.hi;
                P(spanned(lo, hi, ast::MetaWord(name)))
            }
        }
    }

    /// matches meta_seq = ( COMMASEP(meta_item) )
    fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
        self.parse_seq(&token::OpenDelim(token::Paren),
                       &token::CloseDelim(token::Paren),
                       seq_sep_trailing_disallowed(token::Comma),
                       |p| p.parse_meta_item()).node
    }

    fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>> {
        match self.token {
            token::OpenDelim(token::Paren) => self.parse_meta_seq(),
            _ => Vec::new()
        }
    }
}
<commit_msg>auto merge of #18766 : liigo/rust/improve-inner-attr-msg, r=huonw<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use attr;
use ast;
use codemap::{spanned, Spanned, mk_sp, Span};
use parse::common::*; //resolve bug?
use parse::token;
use parse::parser::Parser;
use ptr::P;

/// A parser that can parse attributes.
pub trait ParserAttr {
    fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
    fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
    fn parse_inner_attrs_and_next(&mut self)
                                  -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
    fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
    fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
    fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
}

impl<'a> ParserAttr for Parser<'a> {
    /// Parse attributes that appear before an item
    fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
        let mut attrs: Vec<ast::Attribute> = Vec::new();
        loop {
            debug!("parse_outer_attributes: self.token={}",
                   self.token);
            match self.token {
              token::Pound => {
                attrs.push(self.parse_attribute(false));
              }
              token::DocComment(s) => {
                let attr = ::attr::mk_sugared_doc_attr(
                    attr::mk_attr_id(),
                    self.id_to_interned_str(s.ident()),
                    self.span.lo,
                    self.span.hi
                );
                if attr.node.style != ast::AttrOuter {
                  self.fatal("expected outer comment");
                }
                attrs.push(attr);
                self.bump();
              }
              _ => break
            }
        }
        return attrs;
    }

    /// Matches `attribute = # ! [ meta_item ]`
    ///
    /// If permit_inner is true, then a leading `!` indicates an inner
    /// attribute
    fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
        debug!("parse_attributes: permit_inner={} self.token={}",
               permit_inner, self.token);
        let (span, value, mut style) = match self.token {
            token::Pound => {
                let lo = self.span.lo;
                self.bump();

                let style = if self.eat(&token::Not) {
                    if !permit_inner {
                        let span = self.span;
                        self.span_err(span,
                                      "an inner attribute is not permitted in \
                                       this context");
                        self.span_help(span,
                                       "place inner attribute at the top of the module or block");
                    }
                    ast::AttrInner
                } else {
                    ast::AttrOuter
                };

                self.expect(&token::OpenDelim(token::Bracket));
                let meta_item = self.parse_meta_item();
                let hi = self.span.hi;
                self.expect(&token::CloseDelim(token::Bracket));

                (mk_sp(lo, hi), meta_item, style)
            }
            _ => {
                let token_str = self.this_token_to_string();
                self.fatal(format!("expected `#`, found `{}`",
                                   token_str).as_slice());
            }
        };

        if permit_inner && self.eat(&token::Semi) {
            self.span_warn(span, "this inner attribute syntax is deprecated. \
                           The new syntax is `#![foo]`, with a bang and no semicolon.");
            style = ast::AttrInner;
        }

        return Spanned {
            span: span,
            node: ast::Attribute_ {
                id: attr::mk_attr_id(),
                style: style,
                value: value,
                is_sugared_doc: false
            }
        };
    }

    /// Parse attributes that appear after the opening of an item. These should
    /// be preceded by an exclamation mark, but we accept and warn about one
    /// terminated by a semicolon. In addition to a vector of inner attributes,
    /// this function also returns a vector that may contain the first outer
    /// attribute of the next item (since we can't know whether the attribute
    /// is an inner attribute of the containing item or an outer attribute of
    /// the first contained item until we see the semi).

    /// matches inner_attrs* outer_attr?
    /// you can make the 'next' field an Option, but the result is going to be
    /// more useful as a vector.
    fn parse_inner_attrs_and_next(&mut self)
                                  -> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
        let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
        let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
        loop {
            let attr = match self.token {
                token::Pound => {
                    self.parse_attribute(true)
                }
                token::DocComment(s) => {
                    // we need to get the position of this token before we bump.
                    let Span { lo, hi, .. } = self.span;
                    self.bump();
                    attr::mk_sugared_doc_attr(attr::mk_attr_id(),
                                              self.id_to_interned_str(s.ident()),
                                              lo,
                                              hi)
                }
                _ => {
                    break;
                }
            };
            if attr.node.style == ast::AttrInner {
                inner_attrs.push(attr);
            } else {
                next_outer_attrs.push(attr);
                break;
            }
        }
        (inner_attrs, next_outer_attrs)
    }

    /// matches meta_item = IDENT
    /// | IDENT = lit
    /// | IDENT meta_seq
    fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
        let nt_meta = match self.token {
            token::Interpolated(token::NtMeta(ref e)) => {
                Some(e.clone())
            }
            _ => None
        };

        match nt_meta {
            Some(meta) => {
                self.bump();
                return meta;
            }
            None => {}
        }

        let lo = self.span.lo;
        let ident = self.parse_ident();
        let name = self.id_to_interned_str(ident);
        match self.token {
            token::Eq => {
                self.bump();
                let lit = self.parse_lit();
                // FIXME #623 Non-string meta items are not serialized correctly;
                // just forbid them for now
                match lit.node {
                    ast::LitStr(..) => {}
                    _ => {
                        self.span_err(
                            lit.span,
                            "non-string literals are not allowed in meta-items");
                    }
                }
                let hi = self.span.hi;
                P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
            }
            token::OpenDelim(token::Paren) => {
                let inner_items = self.parse_meta_seq();
                let hi = self.span.hi;
                P(spanned(lo, hi, ast::MetaList(name, inner_items)))
            }
            _ => {
                let hi = self.last_span.hi;
                P(spanned(lo, hi, ast::MetaWord(name)))
            }
        }
    }

    /// matches meta_seq = ( COMMASEP(meta_item) )
    fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
        self.parse_seq(&token::OpenDelim(token::Paren),
                       &token::CloseDelim(token::Paren),
                       seq_sep_trailing_disallowed(token::Comma),
                       |p| p.parse_meta_item()).node
    }

    fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>> {
        match self.token {
            token::OpenDelim(token::Paren) => self.parse_meta_seq(),
            _ => Vec::new()
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add regression test for miri issue 2433<commit_after>#![feature(type_alias_impl_trait)]

trait T { type Item; }

type Alias<'a> = impl T<Item = &'a ()>;

struct S;
impl<'a> T for &'a S {
    type Item = &'a ();
}

fn filter_positive<'a>() -> Alias<'a> {
    &S
}

fn with_positive(fun: impl Fn(Alias<'_>)) {
    fun(filter_positive());
}

fn main() {
    with_positive(|_| ());
}
<|endoftext|>


<commit_before><commit_msg>Fix caching bug in resolve, get rid of enumness kludge<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed commented out case.<commit_after><|endoftext|>


<commit_before><commit_msg>Type anti-quotes now work, add test case.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: We dont have a subcommand "internal" anymore<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for mutable references to unique boxes as function arguments<commit_after>fn f(&i: ~int) {
    i = ~200;
}

fn main() {
    let i = ~100;
    f(i);
    assert *i == 200;
}<|endoftext|>


<commit_before><commit_msg>Problem 38<commit_after>// Compile with `rustc p38.rs --test` and execute with `./p38 --bench`
extern mod extra;
use std::iter::MultiplicativeIterator;

fn gcd(a: uint, b: uint) -> uint {
    match (a, b) {
        (0, b) => b,
        (a, b) => gcd(b%a, a)
    }
}

fn coprime(a: uint, b: uint) -> bool {
    gcd(a, b) == 1
}

fn phi(n: uint) -> uint {
    range(1, n).filter(|&i| coprime(n, i)).len()
}

fn factors(n: uint) -> ~[(uint, uint)] {
    if n <= 1 {
        return ~[(n, 1)];
    }
    let mut primes = ~[2];
    let mut result = ~[];
    let mut i = 3;
    let mut n = n;
    while n != 1 {
        let &p = primes.last().unwrap();
        let mut j = 0;
        while n % p == 0 {
            j += 1;
            n /= p;
        }
        if j > 0 {
            result.push((p, j));
        }
        while primes.iter().any(|&x| i%x == 0) {
            i += 2;
        }
        primes.push(i);
    }
    result
}

fn phi_improved(n: uint) -> uint {
    factors(n).iter().map(|&(p, m)| (p-1)*std::num::pow(p, m-1)).product()
}

#[bench]
fn compute_phi(b: &mut extra::test::BenchHarness) {
    b.iter(|| {phi(10090);});
}

#[bench]
fn compute_phi_improved(b: &mut extra::test::BenchHarness) {
    b.iter(|| {phi_improved(10090);});
}
<|endoftext|>


<commit_before>import syntax::ast;
import syntax::visit;
import option::some;
import syntax::print::pprust::expr_to_str;

export check_crate_fn_usage;

type fn_usage_ctx = {
    tcx: ty::ctxt,
    unsafe_fn_legal: bool
};

fn fn_usage_expr(expr: @ast::expr,
                 ctx: fn_usage_ctx,
                 v: visit::vt<fn_usage_ctx>) {
    alt expr.node {
      ast::expr_path(path) {
        if !ctx.unsafe_fn_legal {
            alt ctx.tcx.def_map.find(expr.id) {
              some(ast::def_fn(_, ast::unsafe_fn.)) |
              some(ast::def_native_fn(_, ast::unsafe_fn.)) {
                log_err ("expr=", expr_to_str(expr));
                ctx.tcx.sess.span_fatal(
                    expr.span,
                    "unsafe functions can only be called");
              }

              _ {}
            }
        }
      }

      ast::expr_call(f, args, _) {
        let f_ctx = {unsafe_fn_legal: true with ctx};
        v.visit_expr(f, f_ctx, v);

        let args_ctx = {unsafe_fn_legal: false with ctx};
        visit::visit_exprs(args, args_ctx, v);
      }

      ast::expr_bind(f, args) {
        let f_ctx = {unsafe_fn_legal: false with ctx};
        v.visit_expr(f, f_ctx, v);

        let args_ctx = {unsafe_fn_legal: false with ctx};
        for arg in args {
            visit::visit_expr_opt(arg, args_ctx, v);
        }
      }

      _ {
        let subctx = {unsafe_fn_legal: false with ctx};
        visit::visit_expr(expr, subctx, v);
      }
    }
}

fn check_crate_fn_usage(tcx: ty::ctxt, crate: @ast::crate) {
    let visit =
        visit::mk_vt(
            @{visit_expr: fn_usage_expr
                  with *visit::default_visitor()});
    let ctx = {
        tcx: tcx,
        unsafe_fn_legal: false
    };
    visit::visit_crate(*crate, ctx, visit);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>restore old functionality for now<commit_after>import syntax::ast;
import syntax::visit;
import option::some;
import syntax::print::pprust::expr_to_str;

export check_crate_fn_usage;

type fn_usage_ctx = {
    tcx: ty::ctxt,
    unsafe_fn_legal: bool,
    generic_bare_fn_legal: bool
};

fn fn_usage_expr(expr: @ast::expr,
                 ctx: fn_usage_ctx,
                 v: visit::vt<fn_usage_ctx>) {
    alt expr.node {
      ast::expr_path(path) {
        if !ctx.unsafe_fn_legal {
            alt ctx.tcx.def_map.find(expr.id) {
              some(ast::def_fn(_, ast::unsafe_fn.)) |
              some(ast::def_native_fn(_, ast::unsafe_fn.)) {
                log_err ("expr=", expr_to_str(expr));
                ctx.tcx.sess.span_fatal(
                    expr.span,
                    "unsafe functions can only be called");
              }

              _ {}
            }
        }
        if !ctx.generic_bare_fn_legal
            && ty::expr_has_ty_params(ctx.tcx, expr) {
            alt ty::struct(ctx.tcx, ty::expr_ty(ctx.tcx, expr)) {
              ty::ty_fn(ast::proto_bare., _, _, _, _) {
                ctx.tcx.sess.span_fatal(
                    expr.span,
                    "generic bare functions can only be called or bound");
              }
              _ { }
            }
        }
      }

      ast::expr_call(f, args, _) {
        let f_ctx = {unsafe_fn_legal: true,
                     generic_bare_fn_legal: true with ctx};
        v.visit_expr(f, f_ctx, v);

        let args_ctx = {unsafe_fn_legal: false,
                        generic_bare_fn_legal: false with ctx};
        visit::visit_exprs(args, args_ctx, v);
      }

      ast::expr_bind(f, args) {
        let f_ctx = {unsafe_fn_legal: false,
                     generic_bare_fn_legal: true with ctx};
        v.visit_expr(f, f_ctx, v);

        let args_ctx = {unsafe_fn_legal: false,
                        generic_bare_fn_legal: false with ctx};
        for arg in args {
            visit::visit_expr_opt(arg, args_ctx, v);
        }
      }

      _ {
        let subctx = {unsafe_fn_legal: false,
                      generic_bare_fn_legal: false with ctx};
        visit::visit_expr(expr, subctx, v);
      }
    }
}

fn check_crate_fn_usage(tcx: ty::ctxt, crate: @ast::crate) {
    let visit =
        visit::mk_vt(
            @{visit_expr: fn_usage_expr
                  with *visit::default_visitor()});
    let ctx = {
        tcx: tcx,
        unsafe_fn_legal: false,
        generic_bare_fn_legal: false
    };
    visit::visit_crate(*crate, ctx, visit);
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before>fn main() {
  auto s = #shell { uname -a && hg identify };
  log s;
}
<commit_msg>Fix hg dependency in testsuite.<commit_after>fn main() {
  auto s = #shell { uname -a };
  log s;
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #25288 - DrKwint:master, r=alexcrichton<commit_after><|endoftext|>


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

use core::prelude::*;

use driver::session::{Session, Session_, No, Less, Default};
use driver::session;
use lib::llvm::{PassRef, ModuleRef,PassManagerRef,ValueRef,TargetDataRef};
use lib::llvm::llvm;
use lib;

pub struct PassManager {
    priv llpm: PassManagerRef
}

impl Drop for PassManager {
    fn finalize(&self) {
        unsafe {
            llvm::LLVMDisposePassManager(self.llpm);
        }
    }
}

impl PassManager {
    pub fn new(td: TargetDataRef) -> PassManager {
        unsafe {
            let pm = PassManager {
                llpm: llvm::LLVMCreatePassManager()
            };
            llvm::LLVMAddTargetData(td, pm.llpm);

            return pm;
        }
    }

    pub fn addPass(&mut self, pass:PassRef) {
        unsafe {
            llvm::LLVMAddPass(self.llpm, pass);
        }
    }

    pub fn run(&self, md:ModuleRef) -> bool {
        unsafe {
            llvm::LLVMRunPassManager(self.llpm, md) == lib::llvm::True
        }
    }
}

pub fn populatePassManager(pm: &mut PassManager, level:session::OptLevel) {
    unsafe {
        // We add a lot of potentially-unused prototypes, so strip them right at the
        // start. We do it again later when we know for certain which ones are used
        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());

        if level == session::No {
            pm.addPass(llvm::LLVMCreateAlwaysInlinerPass());
            return;
        }

        //NOTE: Add library info

        pm.addPass(llvm::LLVMCreateTypeBasedAliasAnalysisPass());
        pm.addPass(llvm::LLVMCreateBasicAliasAnalysisPass());

        pm.addPass(llvm::LLVMCreateSROAPass());
        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateLowerExpectIntrinsicPass());

        pm.addPass(llvm::LLVMCreateGlobalOptimizerPass());
        pm.addPass(llvm::LLVMCreateIPSCCPPass());
        pm.addPass(llvm::LLVMCreateDeadArgEliminationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());

        pm.addPass(llvm::LLVMCreatePruneEHPass());

        match level {
            session::Less       => pm.addPass(llvm::LLVMCreateFunctionInliningPass(200)),
            session::Default    => pm.addPass(llvm::LLVMCreateFunctionInliningPass(225)),
            session::Aggressive => pm.addPass(llvm::LLVMCreateFunctionInliningPass(275)),
            session::No         => ()
        }

        pm.addPass(llvm::LLVMCreateFunctionAttrsPass());

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateArgumentPromotionPass());
        }

        pm.addPass(llvm::LLVMCreateSROAPass());

        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());

        pm.addPass(llvm::LLVMCreateTailCallEliminationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateReassociatePass());
        pm.addPass(llvm::LLVMCreateLoopRotatePass());
        pm.addPass(llvm::LLVMCreateLICMPass());

        pm.addPass(llvm::LLVMCreateLoopUnswitchPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateIndVarSimplifyPass());
        pm.addPass(llvm::LLVMCreateLoopIdiomPass());
        pm.addPass(llvm::LLVMCreateLoopDeletionPass());

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateLoopUnrollPass());
        }
        pm.addPass(llvm::LLVMCreateLoopUnrollPass());

        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGVNPass());
        }
        pm.addPass(llvm::LLVMCreateMemCpyOptPass());
        pm.addPass(llvm::LLVMCreateSCCPPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());

        pm.addPass(llvm::LLVMCreateBBVectorizePass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGlobalDCEPass());
            pm.addPass(llvm::LLVMCreateConstantMergePass());
        }

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateMergeFunctionsPass());
        }

        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());

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

use core::prelude::*;

use driver::session::{Session, Session_, No, Less, Default};
use driver::session;
use lib::llvm::{PassRef, ModuleRef,PassManagerRef,ValueRef,TargetDataRef};
use lib::llvm::llvm;
use lib;

pub struct PassManager {
    priv llpm: PassManagerRef
}

impl Drop for PassManager {
    fn finalize(&self) {
        unsafe {
            llvm::LLVMDisposePassManager(self.llpm);
        }
    }
}

impl PassManager {
    pub fn new(td: TargetDataRef) -> PassManager {
        unsafe {
            let pm = PassManager {
                llpm: llvm::LLVMCreatePassManager()
            };
            llvm::LLVMAddTargetData(td, pm.llpm);

            return pm;
        }
    }

    pub fn addPass(&mut self, pass:PassRef) {
        unsafe {
            llvm::LLVMAddPass(self.llpm, pass);
        }
    }

    pub fn run(&self, md:ModuleRef) -> bool {
        unsafe {
            llvm::LLVMRunPassManager(self.llpm, md) == lib::llvm::True
        }
    }
}

pub fn populatePassManager(pm: &mut PassManager, level:session::OptLevel) {
    unsafe {
        // We add a lot of potentially-unused prototypes, so strip them right at the
        // start. We do it again later when we know for certain which ones are used
        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());

        if level == session::No {
            pm.addPass(llvm::LLVMCreateAlwaysInlinerPass());
            return;
        }

        //NOTE: Add library info

        pm.addPass(llvm::LLVMCreateTypeBasedAliasAnalysisPass());
        pm.addPass(llvm::LLVMCreateBasicAliasAnalysisPass());

        pm.addPass(llvm::LLVMCreateSROAPass());
        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateLowerExpectIntrinsicPass());

        pm.addPass(llvm::LLVMCreateGlobalOptimizerPass());
        pm.addPass(llvm::LLVMCreateIPSCCPPass());
        pm.addPass(llvm::LLVMCreateDeadArgEliminationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());

        pm.addPass(llvm::LLVMCreatePruneEHPass());

        match level {
            session::Less       => pm.addPass(llvm::LLVMCreateFunctionInliningPass(200)),
            session::Default    => pm.addPass(llvm::LLVMCreateFunctionInliningPass(225)),
            session::Aggressive => pm.addPass(llvm::LLVMCreateFunctionInliningPass(275)),
            session::No         => ()
        }

        pm.addPass(llvm::LLVMCreateFunctionAttrsPass());

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateArgumentPromotionPass());
        }

        pm.addPass(llvm::LLVMCreateSROAPass());

        pm.addPass(llvm::LLVMCreateEarlyCSEPass());
        pm.addPass(llvm::LLVMCreateSimplifyLibCallsPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());

        pm.addPass(llvm::LLVMCreateTailCallEliminationPass());
        pm.addPass(llvm::LLVMCreateCFGSimplificationPass());
        pm.addPass(llvm::LLVMCreateReassociatePass());
        pm.addPass(llvm::LLVMCreateLoopRotatePass());
        pm.addPass(llvm::LLVMCreateLICMPass());

        pm.addPass(llvm::LLVMCreateLoopUnswitchPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateIndVarSimplifyPass());
        pm.addPass(llvm::LLVMCreateLoopIdiomPass());
        pm.addPass(llvm::LLVMCreateLoopDeletionPass());

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateLoopVectorizePass());
        }
        pm.addPass(llvm::LLVMCreateLoopUnrollPass());

        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGVNPass());
        }
        pm.addPass(llvm::LLVMCreateMemCpyOptPass());
        pm.addPass(llvm::LLVMCreateSCCPPass());

        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        pm.addPass(llvm::LLVMCreateJumpThreadingPass());
        pm.addPass(llvm::LLVMCreateCorrelatedValuePropagationPass());
        pm.addPass(llvm::LLVMCreateDeadStoreEliminationPass());

        pm.addPass(llvm::LLVMCreateBBVectorizePass());
        pm.addPass(llvm::LLVMCreateInstructionCombiningPass());
        if level != session::Less {
            pm.addPass(llvm::LLVMCreateGlobalDCEPass());
            pm.addPass(llvm::LLVMCreateConstantMergePass());
        }

        if level == session::Aggressive {
            pm.addPass(llvm::LLVMCreateMergeFunctionsPass());
        }

        pm.addPass(llvm::LLVMCreateStripDeadPrototypesPass());

    }
}
<|endoftext|>