<commit_before>/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/0.6/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: parse/trait.Parse.html
///
/// ```
/// #[macro_use]
/// extern crate syn;
///
/// #[macro_use]
/// extern crate quote;
///
/// use syn::Stmt;
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available if Syn is built with the `"parsing"` feature,
/// although interpolation of syntax tree nodes into the quoted tokens is only
/// supported if Syn is built with the `"printing"` feature as well.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// # #[macro_use]
/// # extern crate syn;
/// #
/// # #[macro_use]
/// # extern crate quote;
/// #
/// # use syn::{Generics, GenericParam};
/// #
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(ref mut type_param) = *param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// #
/// # fn main() {}
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
///
/// [`Attribute`]: struct.Attribute.html
/// [`Punctuated<T, P>`]: punctuated/struct.Punctuated.html
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::parse_quote::parse($crate::export::From::from(quote!($($tt)*)))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Synom.

use parse::{Parse, ParseStream, Parser, Result};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

// Not public API.
#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

#[cfg(any(feature = "full", feature = "derive"))]
use {attr, Attribute};

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}
<commit_msg>Restore ParseQuote impl for Punctuated<commit_after>/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/0.6/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: parse/trait.Parse.html
///
/// ```
/// #[macro_use]
/// extern crate syn;
///
/// #[macro_use]
/// extern crate quote;
///
/// use syn::Stmt;
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available if Syn is built with the `"parsing"` feature,
/// although interpolation of syntax tree nodes into the quoted tokens is only
/// supported if Syn is built with the `"printing"` feature as well.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// # #[macro_use]
/// # extern crate syn;
/// #
/// # #[macro_use]
/// # extern crate quote;
/// #
/// # use syn::{Generics, GenericParam};
/// #
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(ref mut type_param) = *param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// #
/// # fn main() {}
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
///
/// [`Attribute`]: struct.Attribute.html
/// [`Punctuated<T, P>`]: punctuated/struct.Punctuated.html
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::parse_quote::parse($crate::export::From::from(quote!($($tt)*)))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Synom.

use parse::{Parse, ParseStream, Parser, Result};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

// Not public API.
#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

#[cfg(any(feature = "full", feature = "derive"))]
use {attr, Attribute};
use punctuated::Punctuated;

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}

impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
    fn parse(input: ParseStream) -> Result<Self> {
        Self::parse_terminated(input)
    }
}
<|endoftext|>


<commit_before>use common::*;
use super::{Capability, CapHalf};
use super::untyped::{UntypedHalf};
use arch::{ThreadRuntime};
use core::mem::{size_of, align_of};
use arch;

#[derive(Debug)]
pub struct TCB {
    cpool: Capability,
    runtime: ThreadRuntime
}

#[derive(Debug, Clone)]
pub struct TCBHalf {
    start_paddr: PAddr,
    deleted: bool
}

normal_half!(TCBHalf);

impl TCBHalf {
    // TODO handle data races
    pub fn with_tcb<Return, F: FnOnce(&TCB) -> Return>(&self, f: F) -> Return {
        unsafe {
            arch::with_object(self.start_paddr, |tcb: &TCB| {
                f(tcb)
            })
        }
    }

    // TODO handle data races
    pub fn with_tcb_mut<Return, F: FnOnce(&mut TCB) -> Return>(&mut self, f: F) -> Return {
        unsafe {
            arch::with_object_mut(self.start_paddr, |tcb: &mut TCB| {
                f(tcb)
            })
        }
    }

    pub fn new(cpool: Capability,
               runtime: ThreadRuntime,
               untyped: &mut UntypedHalf) -> TCBHalf {
        let alignment = align_of::<TCB>();
        let length = size_of::<TCB>();
        let start_paddr = untyped.allocate(length, alignment);

        let mut cap = TCBHalf {
            start_paddr: start_paddr,
            deleted: false
        };

        cap.with_tcb_mut(|tcb| {
            *tcb = TCB {
                cpool: cpool,
                runtime: runtime
            }
        });

        cap
    }
}
<commit_msg>remove TODOs<commit_after>use common::*;
use super::{Capability, CapHalf};
use super::untyped::{UntypedHalf};
use arch::{ThreadRuntime};
use core::mem::{size_of, align_of};
use arch;

#[derive(Debug)]
pub struct TCB {
    cpool: Capability,
    runtime: ThreadRuntime
}

#[derive(Debug, Clone)]
pub struct TCBHalf {
    start_paddr: PAddr,
    deleted: bool
}

normal_half!(TCBHalf);

impl TCBHalf {
    pub fn with_tcb<Return, F: FnOnce(&TCB) -> Return>(&self, f: F) -> Return {
        unsafe {
            arch::with_object(self.start_paddr, |tcb: &TCB| {
                f(tcb)
            })
        }
    }

    pub fn with_tcb_mut<Return, F: FnOnce(&mut TCB) -> Return>(&mut self, f: F) -> Return {
        unsafe {
            arch::with_object_mut(self.start_paddr, |tcb: &mut TCB| {
                f(tcb)
            })
        }
    }

    pub fn new(cpool: Capability,
               runtime: ThreadRuntime,
               untyped: &mut UntypedHalf) -> TCBHalf {
        let alignment = align_of::<TCB>();
        let length = size_of::<TCB>();
        let start_paddr = untyped.allocate(length, alignment);

        let mut cap = TCBHalf {
            start_paddr: start_paddr,
            deleted: false
        };

        cap.with_tcb_mut(|tcb| {
            *tcb = TCB {
                cpool: cpool,
                runtime: runtime
            }
        });

        cap
    }
}
<|endoftext|>


<commit_before>extern crate syntax;

pub use syntax::ast;
pub use syntax::ast::P;
pub use syntax::codemap::DUMMY_SP;
pub use syntax::ext::base::ExtCtxt;
pub use syntax::ast::{Mod, Item, Expr};
pub use syntax::parse::token::str_to_ident;
pub use syntax::ext::build::AstBuilder;
pub use syntax::print::pprust::{expr_to_str, item_to_str};

pub fn module(items: Vec<P<Item>>) -> P<Mod> {
	P(Mod{
		inner: DUMMY_SP,
		view_items: Vec::new(),
		items: items,
	})
}

pub fn parse_expr(e: &str) -> P<ast::Expr> {
	let ps = syntax::parse::new_parse_sess();
	let mut p = syntax::parse::new_parser_from_source_str(&ps, Vec::new(), "file".to_string(), e.to_string());
	let r = p.parse_expr();
	p.abort_if_errors();
	r
}

pub fn parse_type(e: &str) -> P<ast::Ty> {
	let ps = syntax::parse::new_parse_sess();
	let mut p = syntax::parse::new_parser_from_source_str(&ps, Vec::new(), "file".to_string(), e.to_string());
	let r = p.parse_ty(false);
	p.abort_if_errors();
	r
}

struct ErrLoader;
impl syntax::ext::base::CrateLoader for ErrLoader {
	fn load_crate(&mut self, _: &syntax::ast::ViewItem) -> syntax::ext::base::MacroCrate {
		fail!("can't load_crate")
	}
}

pub fn with_fake_extctxt<T>(f: |&ExtCtxt| -> T) -> T {
	let ps = syntax::parse::new_parse_sess();
	let mut loader = ErrLoader;

	let mut cx = syntax::ext::base::ExtCtxt::new(&ps, Vec::new(), syntax::ext::expand::ExpansionConfig {
		loader: &mut loader,
		deriving_hash_type_parameter: false,
		crate_id: from_str("test").unwrap(),
	});

	cx.bt_push(syntax::codemap::ExpnInfo{
		call_site: DUMMY_SP,
		callee: syntax::codemap::NameAndSpan {
			name: "test".to_string(),
			format: syntax::codemap::MacroBang,
			span: None,
		}
	});

	f(&cx)
}
<commit_msg>rust: CrateLoader was removed<commit_after>extern crate syntax;

pub use syntax::ast;
pub use syntax::ast::P;
pub use syntax::codemap::DUMMY_SP;
pub use syntax::ext::base::ExtCtxt;
pub use syntax::ast::{Mod, Item, Expr};
pub use syntax::parse::token::str_to_ident;
pub use syntax::ext::build::AstBuilder;
pub use syntax::print::pprust::{expr_to_str, item_to_str};

pub fn module(items: Vec<P<Item>>) -> P<Mod> {
	P(Mod{
		inner: DUMMY_SP,
		view_items: Vec::new(),
		items: items,
	})
}

pub fn parse_expr(e: &str) -> P<ast::Expr> {
	let ps = syntax::parse::new_parse_sess();
	let mut p = syntax::parse::new_parser_from_source_str(&ps, Vec::new(), "file".to_string(), e.to_string());
	let r = p.parse_expr();
	p.abort_if_errors();
	r
}

pub fn parse_type(e: &str) -> P<ast::Ty> {
	let ps = syntax::parse::new_parse_sess();
	let mut p = syntax::parse::new_parser_from_source_str(&ps, Vec::new(), "file".to_string(), e.to_string());
	let r = p.parse_ty(false);
	p.abort_if_errors();
	r
}

pub fn with_fake_extctxt<T>(f: |&ExtCtxt| -> T) -> T {
	let ps = syntax::parse::new_parse_sess();

	let mut cx = syntax::ext::base::ExtCtxt::new(&ps, Vec::new(), syntax::ext::expand::ExpansionConfig {
		deriving_hash_type_parameter: false,
		crate_id: from_str("test").unwrap(),
	});

	cx.bt_push(syntax::codemap::ExpnInfo{
		call_site: DUMMY_SP,
		callee: syntax::codemap::NameAndSpan {
			name: "test".to_string(),
			format: syntax::codemap::MacroBang,
			span: None,
		}
	});

	f(&cx)
}
<|endoftext|>


<commit_before>use vangers::{
    config,
    render::{ScreenTargets, COLOR_FORMAT, DEPTH_FORMAT},
};

use env_logger;
use log::info;
use wgpu;
use wgpu::winit;

pub trait Application {
    fn on_key(&mut self, input: winit::KeyboardInput) -> bool;
    fn on_mouse_wheel(&mut self, _delta: winit::MouseScrollDelta) {}
    fn on_cursor_move(&mut self, _position: (f64, f64)) {}
    fn on_mouse_button(&mut self, _state: winit::ElementState, _button: winit::MouseButton) {}
    fn resize(&mut self, _device: &wgpu::Device, _extent: wgpu::Extent3d) {}
    fn reload(&mut self, _device: &wgpu::Device);
    fn update(&mut self, delta: f32);
    fn draw(
        &mut self,
        device: &wgpu::Device,
        targets: ScreenTargets,
    ) -> wgpu::CommandBuffer;
}

pub struct Harness {
    events_loop: winit::EventsLoop,
    window: winit::Window,
    pub device: wgpu::Device,
    surface: wgpu::Surface,
    swap_chain: wgpu::SwapChain,
    extent: wgpu::Extent3d,
    depth_target: wgpu::TextureView,
}

impl Harness {
    pub fn init(title: &str) -> (Self, config::Settings) {
        info!("Initializing the device");
        env_logger::init();

        let instance = wgpu::Instance::new();
        let adapter = instance.get_adapter(&wgpu::AdapterDescriptor {
            power_preference: wgpu::PowerPreference::LowPower,
        });
        let device = adapter.create_device(&wgpu::DeviceDescriptor {
            extensions: wgpu::Extensions {
                anisotropic_filtering: false,
            },
        });

        info!("Loading the settings");
        let settings = config::Settings::load("config/settings.ron");
        let extent = wgpu::Extent3d {
            width: settings.window.size[0],
            height: settings.window.size[1],
            depth: 1,
        };

        info!("Initializing the window...");
        let events_loop = winit::EventsLoop::new();
        let dpi = events_loop
            .get_primary_monitor()
            .get_hidpi_factor();
        let window = winit::WindowBuilder::new()
            .with_title(title)
            .with_dimensions(
                winit::dpi::LogicalSize::from_physical((extent.width, extent.height), dpi),
            )
            .with_resizable(true)
            .build(&events_loop)
            .unwrap();

        let surface = instance.create_surface(&window);
        let sc_desc = wgpu::SwapChainDescriptor {
            usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
            format: COLOR_FORMAT,
            width: extent.width,
            height: extent.height,
        };
        let swap_chain = device.create_swap_chain(&surface, &sc_desc);
        let depth_target = device
            .create_texture(&wgpu::TextureDescriptor {
                size: extent,
                array_size: 1,
                dimension: wgpu::TextureDimension::D2,
                format: DEPTH_FORMAT,
                usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
            })
            .create_default_view();

        let harness = Harness {
            events_loop,
            window,
            device,
            surface,
            swap_chain,
            extent,
            depth_target,
        };

        (harness, settings)
    }

    pub fn main_loop<A: Application>(&mut self, mut app: A) {
        use std::time;
        use wgpu::winit::{Event, WindowEvent};

        let mut last_time = time::Instant::now();
        loop {
            let win = &self.window;
            let mut running = true;
            let mut resized_extent = None;
            let mut reload_shaders = false;
            self.events_loop.poll_events(|event| match event {
                Event::WindowEvent { window_id, ref event } if window_id == win.id() => {
                    match *event {
                        WindowEvent::Resized(size) => {
                            let physical = size.to_physical(win.get_hidpi_factor());
                            info!("Resizing to {:?}", physical);
                            resized_extent = Some(wgpu::Extent3d {
                                width: physical.width as u32,
                                height: physical.height as u32,
                                depth: 1,
                            });
                        }
                        WindowEvent::Focused(true) => {
                            info!("Reloading shaders");
                            reload_shaders = true;
                        }
                        WindowEvent::CloseRequested => {
                            running = false;
                        }
                        WindowEvent::KeyboardInput { input, .. } => {
                            if !app.on_key(input) {
                                running = false;
                            }
                        }
                        WindowEvent::MouseWheel {delta, ..} => {
                            app.on_mouse_wheel(delta)
                        }
                        WindowEvent::CursorMoved {position, ..} => {
                            let physical = position.to_physical(win.get_hidpi_factor());
                            app.on_cursor_move(physical.into())
                        }
                        WindowEvent::MouseInput {state, button, ..} => {
                            app.on_mouse_button(state, button)
                        }
                        _ => {}
                    }
                }
                _ => {}
            });

            if !running {
                break;
            }
            if let Some(extent) = resized_extent {
                self.extent = extent;
                let sc_desc = wgpu::SwapChainDescriptor {
                    usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
                    format: COLOR_FORMAT,
                    width: extent.width,
                    height: extent.height,
                };
                self.swap_chain = self.device.create_swap_chain(&self.surface, &sc_desc);
                self.depth_target = self.device
                    .create_texture(&wgpu::TextureDescriptor {
                        size: extent,
                        array_size: 1,
                        dimension: wgpu::TextureDimension::D2,
                        format: DEPTH_FORMAT,
                        usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
                    })
                    .create_default_view();
                app.resize(&self.device, extent);
            }
            if reload_shaders {
                app.reload(&self.device);
            }

            let duration = time::Instant::now() - last_time;
            last_time += duration;
            let delta = duration.as_secs() as f32 +
                duration.subsec_nanos() as f32 * 1.0e-9;

            app.update(delta);
            {
                let frame = self.swap_chain.get_next_texture();
                let targets = ScreenTargets {
                    extent: self.extent,
                    color: &frame.view,
                    depth: &self.depth_target,
                };
                let command_buffer = app.draw(&self.device, targets);
                self.device
                    .get_queue()
                    .submit(&[ command_buffer ]);
            }
        }
    }
}
<commit_msg>Round window sizes<commit_after>use vangers::{
    config,
    render::{ScreenTargets, COLOR_FORMAT, DEPTH_FORMAT},
};

use env_logger;
use log::info;
use wgpu;
use wgpu::winit;

pub trait Application {
    fn on_key(&mut self, input: winit::KeyboardInput) -> bool;
    fn on_mouse_wheel(&mut self, _delta: winit::MouseScrollDelta) {}
    fn on_cursor_move(&mut self, _position: (f64, f64)) {}
    fn on_mouse_button(&mut self, _state: winit::ElementState, _button: winit::MouseButton) {}
    fn resize(&mut self, _device: &wgpu::Device, _extent: wgpu::Extent3d) {}
    fn reload(&mut self, _device: &wgpu::Device);
    fn update(&mut self, delta: f32);
    fn draw(
        &mut self,
        device: &wgpu::Device,
        targets: ScreenTargets,
    ) -> wgpu::CommandBuffer;
}

pub struct Harness {
    events_loop: winit::EventsLoop,
    window: winit::Window,
    pub device: wgpu::Device,
    surface: wgpu::Surface,
    swap_chain: wgpu::SwapChain,
    extent: wgpu::Extent3d,
    depth_target: wgpu::TextureView,
}

impl Harness {
    pub fn init(title: &str) -> (Self, config::Settings) {
        info!("Initializing the device");
        env_logger::init();

        let instance = wgpu::Instance::new();
        let adapter = instance.get_adapter(&wgpu::AdapterDescriptor {
            power_preference: wgpu::PowerPreference::LowPower,
        });
        let device = adapter.create_device(&wgpu::DeviceDescriptor {
            extensions: wgpu::Extensions {
                anisotropic_filtering: false,
            },
        });

        info!("Loading the settings");
        let settings = config::Settings::load("config/settings.ron");
        let extent = wgpu::Extent3d {
            width: settings.window.size[0],
            height: settings.window.size[1],
            depth: 1,
        };

        info!("Initializing the window...");
        let events_loop = winit::EventsLoop::new();
        let dpi = events_loop
            .get_primary_monitor()
            .get_hidpi_factor();
        let window = winit::WindowBuilder::new()
            .with_title(title)
            .with_dimensions(
                winit::dpi::LogicalSize::from_physical((extent.width, extent.height), dpi),
            )
            .with_resizable(true)
            .build(&events_loop)
            .unwrap();

        let surface = instance.create_surface(&window);
        let sc_desc = wgpu::SwapChainDescriptor {
            usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
            format: COLOR_FORMAT,
            width: extent.width,
            height: extent.height,
        };
        let swap_chain = device.create_swap_chain(&surface, &sc_desc);
        let depth_target = device
            .create_texture(&wgpu::TextureDescriptor {
                size: extent,
                array_size: 1,
                dimension: wgpu::TextureDimension::D2,
                format: DEPTH_FORMAT,
                usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
            })
            .create_default_view();

        let harness = Harness {
            events_loop,
            window,
            device,
            surface,
            swap_chain,
            extent,
            depth_target,
        };

        (harness, settings)
    }

    pub fn main_loop<A: Application>(&mut self, mut app: A) {
        use std::time;
        use wgpu::winit::{Event, WindowEvent};

        let mut last_time = time::Instant::now();
        loop {
            let win = &self.window;
            let mut running = true;
            let mut resized_extent = None;
            let mut reload_shaders = false;
            self.events_loop.poll_events(|event| match event {
                Event::WindowEvent { window_id, ref event } if window_id == win.id() => {
                    match *event {
                        WindowEvent::Resized(size) => {
                            let physical = size.to_physical(win.get_hidpi_factor());
                            info!("Resizing to {:?}", physical);
                            resized_extent = Some(wgpu::Extent3d {
                                width: physical.width.round() as u32,
                                height: physical.height.round() as u32,
                                depth: 1,
                            });
                        }
                        WindowEvent::Focused(true) => {
                            info!("Reloading shaders");
                            reload_shaders = true;
                        }
                        WindowEvent::CloseRequested => {
                            running = false;
                        }
                        WindowEvent::KeyboardInput { input, .. } => {
                            if !app.on_key(input) {
                                running = false;
                            }
                        }
                        WindowEvent::MouseWheel {delta, ..} => {
                            app.on_mouse_wheel(delta)
                        }
                        WindowEvent::CursorMoved {position, ..} => {
                            let physical = position.to_physical(win.get_hidpi_factor());
                            app.on_cursor_move(physical.into())
                        }
                        WindowEvent::MouseInput {state, button, ..} => {
                            app.on_mouse_button(state, button)
                        }
                        _ => {}
                    }
                }
                _ => {}
            });

            if !running {
                break;
            }
            if let Some(extent) = resized_extent {
                self.extent = extent;
                let sc_desc = wgpu::SwapChainDescriptor {
                    usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
                    format: COLOR_FORMAT,
                    width: extent.width,
                    height: extent.height,
                };
                self.swap_chain = self.device.create_swap_chain(&self.surface, &sc_desc);
                self.depth_target = self.device
                    .create_texture(&wgpu::TextureDescriptor {
                        size: extent,
                        array_size: 1,
                        dimension: wgpu::TextureDimension::D2,
                        format: DEPTH_FORMAT,
                        usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT,
                    })
                    .create_default_view();
                app.resize(&self.device, extent);
            }
            if reload_shaders {
                app.reload(&self.device);
            }

            let duration = time::Instant::now() - last_time;
            last_time += duration;
            let delta = duration.as_secs() as f32 +
                duration.subsec_nanos() as f32 * 1.0e-9;

            app.update(delta);
            {
                let frame = self.swap_chain.get_next_texture();
                let targets = ScreenTargets {
                    extent: self.extent,
                    color: &frame.view,
                    depth: &self.depth_target,
                };
                let command_buffer = app.draw(&self.device, targets);
                self.device
                    .get_queue()
                    .submit(&[ command_buffer ]);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate htmlescape;

use irc::client::prelude::*;

use regex::Regex;

use plugin::*;
use utils;

use self::error::*;
use error::FrippyError;
use error::ErrorKind as FrippyErrorKind;
use failure::Fail;
use failure::ResultExt;

lazy_static! {
    static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap();
}

#[derive(PluginName, Debug)]
pub struct Url {
    max_kib: usize,
}

impl Url {
    /// If a file is larger than `max_kib` KiB the download is stopped
    pub fn new(max_kib: usize) -> Url {
        Url { max_kib: max_kib }
    }

    fn grep_url(&self, msg: &str) -> Option<String> {
        let captures = RE.captures(msg)?;
        debug!("Url captures: {:?}", captures);

        Some(captures.get(2)?.as_str().to_owned())
    }

    fn get_title<'a>(&self, body: &str) -> Result<String, UrlError> {
        let title = body.find("<title")
            .map(|tag| {
                body[tag..]
                    .find('>')
                    .map(|offset| tag + offset + 1)
                    .map(|start| {
                        body[start..]
                            .find("</title>")
                            .map(|offset| start + offset)
                            .map(|end| &body[start..end])
                    })
            })
            .and_then(|s| s.and_then(|s| s))
            .ok_or(ErrorKind::MissingTitle)?;

        debug!("Title: {:?}", title);

        htmlescape::decode_html(title).map_err(|_| ErrorKind::HtmlDecoding.into())
    }

    fn url(&self, text: &str) -> Result<String, UrlError> {
        let url = self.grep_url(text).ok_or(ErrorKind::MissingUrl)?;
        let body = utils::download(&url, Some(self.max_kib)).context(ErrorKind::Download)?;

        let title = self.get_title(&body)?;

        Ok(title.replace('\n', "|").replace('\r', "|"))
    }
}

impl Plugin for Url {
    fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus {
        match message.command {
            Command::PRIVMSG(_, ref msg) => if RE.is_match(msg) {
                ExecutionStatus::RequiresThread
            } else {
                ExecutionStatus::Done
            },
            _ => ExecutionStatus::Done,
        }
    }

    fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> {
        Ok(match message.command {
            Command::PRIVMSG(_, ref content) => match self.url(content) {
                Ok(title) => client
                    .send_privmsg(message.response_target().unwrap(), &title)
                    .context(FrippyErrorKind::Connection)?,
                Err(e) => Err(e).context(FrippyErrorKind::Url)?,
            },
            _ => (),
        })
    }

    fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> {
        Ok(client
            .send_notice(
                &command.source,
                "This Plugin does not implement any commands.",
            )
            .context(FrippyErrorKind::Connection)?)
    }

    fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result<String, String> {
        self.url(&command.tokens[0])
            .map_err(|e| e.cause().unwrap().to_string())
    }
}

pub mod error {
    /// A URL plugin error
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "UrlError"]
    pub enum ErrorKind {
        /// A download error
        #[fail(display = "A download error occured")]
        Download,

        /// Missing URL error
        #[fail(display = "No URL was found")]
        MissingUrl,

        /// Missing title error
        #[fail(display = "No title was found")]
        MissingTitle,

        /// Html decoding error
        #[fail(display = "Failed to decode Html characters")]
        HtmlDecoding,
    }
}
<commit_msg>Trim titles in the url plugin<commit_after>extern crate htmlescape;

use irc::client::prelude::*;

use regex::Regex;

use plugin::*;
use utils;

use self::error::*;
use error::FrippyError;
use error::ErrorKind as FrippyErrorKind;
use failure::Fail;
use failure::ResultExt;

lazy_static! {
    static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap();
}

#[derive(PluginName, Debug)]
pub struct Url {
    max_kib: usize,
}

impl Url {
    /// If a file is larger than `max_kib` KiB the download is stopped
    pub fn new(max_kib: usize) -> Url {
        Url { max_kib: max_kib }
    }

    fn grep_url(&self, msg: &str) -> Option<String> {
        let captures = RE.captures(msg)?;
        debug!("Url captures: {:?}", captures);

        Some(captures.get(2)?.as_str().to_owned())
    }

    fn get_title<'a>(&self, body: &str) -> Result<String, UrlError> {
        let title = body.find("<title")
            .map(|tag| {
                body[tag..]
                    .find('>')
                    .map(|offset| tag + offset + 1)
                    .map(|start| {
                        body[start..]
                            .find("</title>")
                            .map(|offset| start + offset)
                            .map(|end| &body[start..end])
                    })
            })
            .and_then(|s| s.and_then(|s| s))
            .ok_or(ErrorKind::MissingTitle)?;

        debug!("Title: {:?}", title);

        htmlescape::decode_html(title).map_err(|_| ErrorKind::HtmlDecoding.into())
    }

    fn url(&self, text: &str) -> Result<String, UrlError> {
        let url = self.grep_url(text).ok_or(ErrorKind::MissingUrl)?;
        let body = utils::download(&url, Some(self.max_kib)).context(ErrorKind::Download)?;

        let title = self.get_title(&body)?;

        Ok(title.trim().replace('\n', "|").replace('\r', "|"))
    }
}

impl Plugin for Url {
    fn execute(&self, _: &IrcClient, message: &Message) -> ExecutionStatus {
        match message.command {
            Command::PRIVMSG(_, ref msg) => if RE.is_match(msg) {
                ExecutionStatus::RequiresThread
            } else {
                ExecutionStatus::Done
            },
            _ => ExecutionStatus::Done,
        }
    }

    fn execute_threaded(&self, client: &IrcClient, message: &Message) -> Result<(), FrippyError> {
        Ok(match message.command {
            Command::PRIVMSG(_, ref content) => match self.url(content) {
                Ok(title) => client
                    .send_privmsg(message.response_target().unwrap(), &title)
                    .context(FrippyErrorKind::Connection)?,
                Err(e) => Err(e).context(FrippyErrorKind::Url)?,
            },
            _ => (),
        })
    }

    fn command(&self, client: &IrcClient, command: PluginCommand) -> Result<(), FrippyError> {
        Ok(client
            .send_notice(
                &command.source,
                "This Plugin does not implement any commands.",
            )
            .context(FrippyErrorKind::Connection)?)
    }

    fn evaluate(&self, _: &IrcClient, command: PluginCommand) -> Result<String, String> {
        self.url(&command.tokens[0])
            .map_err(|e| e.cause().unwrap().to_string())
    }
}

pub mod error {
    /// A URL plugin error
    #[derive(Copy, Clone, Eq, PartialEq, Debug, Fail, Error)]
    #[error = "UrlError"]
    pub enum ErrorKind {
        /// A download error
        #[fail(display = "A download error occured")]
        Download,

        /// Missing URL error
        #[fail(display = "No URL was found")]
        MissingUrl,

        /// Missing title error
        #[fail(display = "No title was found")]
        MissingTitle,

        /// Html decoding error
        #[fail(display = "Failed to decode Html characters")]
        HtmlDecoding,
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

// snippet-start:[rust.example_code.s3.scenario_getting_started.bin]

// snippet-start:[rust.example_code.s3.basics.imports]

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::{Client, Error, Region};
use uuid::Uuid;

// snippet-end:[rust.example_code.s3.basics.import]

// snippet-start:[rust.example_code.s3.basics.main]
#[tokio::main]
async fn main() -> Result<(), Error> {
    let (region, client, bucket_name, file_name, key, target_key) = initialize_variables().await;

    if let Err(e) = run_s3_operations(region, client, bucket_name, file_name, key, target_key).await
    {
        println!("{:?}", e);
    };

    Ok(())
}
// snippet-end:[rust.example_code.s3.basics.main]

// snippet-start:[rust.example_code.s3.basics.initialize_variables]
async fn initialize_variables() -> (Region, Client, String, String, String, String) {
    let region_provider = RegionProviderChain::first_try(Region::new("us-west-2"));
    let region = region_provider.region().await.unwrap();

    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client = Client::new(&shared_config);

    let bucket_name = format!("{}{}", "doc-example-bucket-", Uuid::new_v4().to_string());
    let file_name = "s3/testfile.txt".to_string();
    let key = "test file key name".to_string();
    let target_key = "target_key".to_string();

    (region, client, bucket_name, file_name, key, target_key)
}
// snippet-end:[rust.example_code.initialize_variables]

// snippet-start:[rust.example_code.s3.basics.run_s3_operations]
async fn run_s3_operations(
    region: Region,
    client: Client,
    bucket_name: String,
    file_name: String,
    key: String,
    target_key: String,
) -> Result<(), Error> {
    s3_service::create_bucket(&client, &bucket_name, region.as_ref()).await?;
    s3_service::upload_object(&client, &bucket_name, &file_name, &key).await?;
    s3_service::download_object(&client, &bucket_name, &key).await?;
    s3_service::copy_object(&client, &bucket_name, &key, &target_key).await?;
    s3_service::list_objects(&client, &bucket_name).await?;
    s3_service::delete_objects(&client, &bucket_name).await?;
    s3_service::delete_bucket(&client, &bucket_name).await?;

    Ok(())
}
// snippet-end:[rust.example_code.s3.basics.run_s3_operations]

// snippet-end:[rust.example_code.s3.scenario_getting_started.bin]
<commit_msg>Fixes incorrect end snippet.<commit_after>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

// snippet-start:[rust.example_code.s3.scenario_getting_started.bin]

// snippet-start:[rust.example_code.s3.basics.imports]

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::{Client, Error, Region};
use uuid::Uuid;

// snippet-end:[rust.example_code.s3.basics.imports]

// snippet-start:[rust.example_code.s3.basics.main]
#[tokio::main]
async fn main() -> Result<(), Error> {
    let (region, client, bucket_name, file_name, key, target_key) = initialize_variables().await;

    if let Err(e) = run_s3_operations(region, client, bucket_name, file_name, key, target_key).await
    {
        println!("{:?}", e);
    };

    Ok(())
}
// snippet-end:[rust.example_code.s3.basics.main]

// snippet-start:[rust.example_code.s3.basics.initialize_variables]
async fn initialize_variables() -> (Region, Client, String, String, String, String) {
    let region_provider = RegionProviderChain::first_try(Region::new("us-west-2"));
    let region = region_provider.region().await.unwrap();

    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client = Client::new(&shared_config);

    let bucket_name = format!("{}{}", "doc-example-bucket-", Uuid::new_v4().to_string());
    let file_name = "s3/testfile.txt".to_string();
    let key = "test file key name".to_string();
    let target_key = "target_key".to_string();

    (region, client, bucket_name, file_name, key, target_key)
}
// snippet-end:[rust.example_code.initialize_variables]

// snippet-start:[rust.example_code.s3.basics.run_s3_operations]
async fn run_s3_operations(
    region: Region,
    client: Client,
    bucket_name: String,
    file_name: String,
    key: String,
    target_key: String,
) -> Result<(), Error> {
    s3_service::create_bucket(&client, &bucket_name, region.as_ref()).await?;
    s3_service::upload_object(&client, &bucket_name, &file_name, &key).await?;
    s3_service::download_object(&client, &bucket_name, &key).await?;
    s3_service::copy_object(&client, &bucket_name, &key, &target_key).await?;
    s3_service::list_objects(&client, &bucket_name).await?;
    s3_service::delete_objects(&client, &bucket_name).await?;
    s3_service::delete_bucket(&client, &bucket_name).await?;

    Ok(())
}
// snippet-end:[rust.example_code.s3.basics.run_s3_operations]

// snippet-end:[rust.example_code.s3.scenario_getting_started.bin]
<|endoftext|>


<commit_before>use std::fmt;
use std::error::Error;
use std::sync::Mutex;
use CapabilitiesSource;

use gl;
use version::Api;
use version::Version;

pub use self::compute::{ComputeShader, ComputeCommand};
pub use self::program::Program;
pub use self::reflection::{Uniform, UniformBlock, BlockLayout, OutputPrimitives};
pub use self::reflection::{Attribute, TransformFeedbackVarying, TransformFeedbackBuffer, TransformFeedbackMode};
pub use self::reflection::{ShaderStage, SubroutineData, SubroutineUniform};

mod compute;
mod program;
mod raw;
mod reflection;
mod shader;
mod uniforms_storage;
mod binary_header;

/// Returns true if the backend supports geometry shaders.
#[inline]
pub fn is_geometry_shader_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    shader::check_shader_type_compatibility(ctxt, gl::GEOMETRY_SHADER)
}

/// Returns true if the backend supports tessellation shaders.
#[inline]
pub fn is_tessellation_shader_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    shader::check_shader_type_compatibility(ctxt, gl::TESS_CONTROL_SHADER)
}

/// Returns true if the backend supports creating and retreiving binary format.
#[inline]
pub fn is_binary_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    ctxt.get_version() >= &Version(Api::Gl, 4, 1) || ctxt.get_version() >= &Version(Api::GlEs, 2, 0)
        || ctxt.get_extensions().gl_arb_get_programy_binary
}

/// Returns true if the backend supports shader subroutines.
#[inline]
pub fn is_subroutine_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    ctxt.get_version() >= &Version(Api::Gl, 4, 0) || ctxt.get_extensions().gl_arb_shader_subroutine
}

/// Some shader compilers have race-condition issues, so we lock this mutex
/// in the GL thread every time we compile a shader or link a program.
// TODO: replace by a StaticMutex
lazy_static! {
    static ref COMPILER_GLOBAL_LOCK: Mutex<()> = Mutex::new(());
}

/// Error that can be triggered when creating a `Program`.
#[derive(Clone, Debug)]
pub enum ProgramCreationError {
    /// Error while compiling one of the shaders.
    CompilationError(String),

    /// Error while linking the program.
    LinkingError(String),

    /// One of the requested shader types is not supported by the backend.
    ///
    /// Usually the case for geometry shaders.
    ShaderTypeNotSupported,

    /// The OpenGL implementation doesn't provide a compiler.
    CompilationNotSupported,

    /// You have requested transform feedback varyings, but transform feedback is not supported
    /// by the backend.
    TransformFeedbackNotSupported,

    /// You have requested point size setting from the shader, but it's not
    /// supported by the backend.
    PointSizeNotSupported,

    /// The glium-specific binary header was not found or is corrupt.
    BinaryHeaderError,
}

impl fmt::Display for ProgramCreationError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::ProgramCreationError::*;
        match *self {
            CompilationError(ref s) =>
                write!(fmt, "{}: {}", self.description(), s),
            LinkingError(ref s) =>
                write!(fmt, "{}: {}", self.description(), s),
            _ =>
                write!(fmt, "{}", self.description()),
        }
    }
}

impl Error for ProgramCreationError {
    fn description(&self) -> &str {
        use self::ProgramCreationError::*;
        match *self {
            CompilationError(_) =>
                "Compilation error in one of the shaders",
            LinkingError(_) =>
                "Error while linking shaders together",
            ShaderTypeNotSupported =>
                "One of the request shader type is not supported by the backend",
            CompilationNotSupported =>
                "The backend doesn't support shaders compilation",
            TransformFeedbackNotSupported =>
                "Transform feedback is not supported by the backend.",
            PointSizeNotSupported =>
                "Point size is not supported by the backend.",
            BinaryHeaderError =>
                "The glium-specific binary header was not found or is corrupt.",
        }
    }
}

/// Error type that is returned by the `program!` macro.
#[derive(Clone, Debug)]
pub enum ProgramChooserCreationError {
    /// No available version has been found.
    NoVersion,

    /// A version has been found but it triggered the given error.
    ProgramCreationError(ProgramCreationError),
}

impl fmt::Display for ProgramChooserCreationError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", self.description())
    }
}

impl Error for ProgramChooserCreationError {
    #[inline]
    fn description(&self) -> &str {
        use self::ProgramChooserCreationError::*;
        match *self {
            ProgramCreationError(ref err) => err.description(),
            NoVersion => "No version of the program has been found for the current OpenGL version.",
        }
    }

    #[inline]
    fn cause(&self) -> Option<&Error> {
        use self::ProgramChooserCreationError::*;
        match *self {
            ProgramCreationError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<ProgramCreationError> for ProgramChooserCreationError {
    fn from(err: ProgramCreationError) -> ProgramChooserCreationError {
        ProgramChooserCreationError::ProgramCreationError(err)
    }
}

/// Error while retreiving the binary representation of a program.
#[derive(Copy, Clone, Debug)]
pub enum GetBinaryError {
    /// The backend doesn't support binary.
    NotSupported,
    /// The backend does not supply any binary formats.
    NoFormats,
}

impl fmt::Display for GetBinaryError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}

impl Error for GetBinaryError {
    fn description(&self) -> &str {
        use self::GetBinaryError::*;
        match *self {
            NotSupported => "The backend doesn't support binary",
            NoFormats => "The backend does not supply any binary formats.",
        }
    }
}

/// Input when creating a program.
pub enum ProgramCreationInput<'a> {
    /// Use GLSL source code.
    SourceCode {
        /// Source code of the vertex shader.
        vertex_shader: &'a str,

        /// Source code of the optional tessellation control shader.
        tessellation_control_shader: Option<&'a str>,

        /// Source code of the optional tessellation evaluation shader.
        tessellation_evaluation_shader: Option<&'a str>,

        /// Source code of the optional geometry shader.
        geometry_shader: Option<&'a str>,

        /// Source code of the fragment shader.
        fragment_shader: &'a str,

        /// The list of variables and mode to use for transform feedback.
        ///
        /// The information specified here will be passed to the OpenGL linker. If you pass
        /// `None`, then you won't be able to use transform feedback.
        transform_feedback_varyings: Option<(Vec<String>, TransformFeedbackMode)>,

        /// Whether the fragment shader outputs colors in `sRGB` or `RGB`. This is false by default,
        /// meaning that the program outputs `RGB`.
        ///
        /// If this is false, then `GL_FRAMEBUFFER_SRGB` will be enabled when this program is used
        /// (if it is supported).
        outputs_srgb: bool,

        /// Whether the shader uses point size.
        uses_point_size: bool,
    },

    /// Use a precompiled binary.
    Binary {
        /// The data.
        data: Binary,

        /// See `SourceCode::outputs_srgb`.
        outputs_srgb: bool,

        /// Whether the shader uses point size.
        uses_point_size: bool,
    }
}

/// Represents the source code of a program.
pub struct SourceCode<'a> {
    /// Source code of the vertex shader.
    pub vertex_shader: &'a str,

    /// Source code of the optional tessellation control shader.
    pub tessellation_control_shader: Option<&'a str>,

    /// Source code of the optional tessellation evaluation shader.
    pub tessellation_evaluation_shader: Option<&'a str>,

    /// Source code of the optional geometry shader.
    pub geometry_shader: Option<&'a str>,

    /// Source code of the fragment shader.
    pub fragment_shader: &'a str,
}

impl<'a> From<SourceCode<'a>> for ProgramCreationInput<'a> {
    #[inline]
    fn from(code: SourceCode<'a>) -> ProgramCreationInput<'a> {
        let SourceCode { vertex_shader, fragment_shader, geometry_shader,
                         tessellation_control_shader, tessellation_evaluation_shader } = code;

        ProgramCreationInput::SourceCode {
            vertex_shader: vertex_shader,
            tessellation_control_shader: tessellation_control_shader,
            tessellation_evaluation_shader: tessellation_evaluation_shader,
            geometry_shader: geometry_shader,
            fragment_shader: fragment_shader,
            transform_feedback_varyings: None,
            outputs_srgb: false,
            uses_point_size: false,
        }
    }
}

/// Represents the compiled binary data of a program.
pub struct Binary {
    /// An implementation-defined format.
    pub format: u32,

    /// The binary data.
    pub content: Vec<u8>,
}

impl<'a> From<Binary> for ProgramCreationInput<'a> {
    #[inline]
    fn from(binary: Binary) -> ProgramCreationInput<'a> {
        ProgramCreationInput::Binary {
            data: binary,
            outputs_srgb: false,
            uses_point_size: false,
        }
    }
}
<commit_msg>Add workaround for faulty NVIDIA driver on Windows; Fixes #1439<commit_after>use std::fmt;
use std::error::Error;
use std::sync::Mutex;
use CapabilitiesSource;

use gl;
use version::Api;
use version::Version;

pub use self::compute::{ComputeShader, ComputeCommand};
pub use self::program::Program;
pub use self::reflection::{Uniform, UniformBlock, BlockLayout, OutputPrimitives};
pub use self::reflection::{Attribute, TransformFeedbackVarying, TransformFeedbackBuffer, TransformFeedbackMode};
pub use self::reflection::{ShaderStage, SubroutineData, SubroutineUniform};

mod compute;
mod program;
mod raw;
mod reflection;
mod shader;
mod uniforms_storage;
mod binary_header;

/// Returns true if the backend supports geometry shaders.
#[inline]
pub fn is_geometry_shader_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    shader::check_shader_type_compatibility(ctxt, gl::GEOMETRY_SHADER)
}

/// Returns true if the backend supports tessellation shaders.
#[inline]
pub fn is_tessellation_shader_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    shader::check_shader_type_compatibility(ctxt, gl::TESS_CONTROL_SHADER)
}

/// Returns true if the backend supports creating and retreiving binary format.
#[inline]
pub fn is_binary_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    ctxt.get_version() >= &Version(Api::Gl, 4, 1) || ctxt.get_version() >= &Version(Api::GlEs, 2, 0)
        || ctxt.get_extensions().gl_arb_get_programy_binary
}

/// Returns true if the backend supports shader subroutines.
#[inline]
pub fn is_subroutine_supported<C>(ctxt: &C) -> bool where C: CapabilitiesSource {
    // WORKAROUND: Windows only; NVIDIA doesn't actually return a valid function pointer for
    //              GetProgramStageiv despite supporting ARB_shader_subroutine; see #1439
    if cfg!(target_os = "windows")
        && ctxt.get_version() <= &Version(Api::Gl, 4, 0)
        && ctxt.get_capabilities().vendor == "NVIDIA Corporation" {
        return false;
    }
    ctxt.get_version() >= &Version(Api::Gl, 4, 0) || ctxt.get_extensions().gl_arb_shader_subroutine
}

/// Some shader compilers have race-condition issues, so we lock this mutex
/// in the GL thread every time we compile a shader or link a program.
// TODO: replace by a StaticMutex
lazy_static! {
    static ref COMPILER_GLOBAL_LOCK: Mutex<()> = Mutex::new(());
}

/// Error that can be triggered when creating a `Program`.
#[derive(Clone, Debug)]
pub enum ProgramCreationError {
    /// Error while compiling one of the shaders.
    CompilationError(String),

    /// Error while linking the program.
    LinkingError(String),

    /// One of the requested shader types is not supported by the backend.
    ///
    /// Usually the case for geometry shaders.
    ShaderTypeNotSupported,

    /// The OpenGL implementation doesn't provide a compiler.
    CompilationNotSupported,

    /// You have requested transform feedback varyings, but transform feedback is not supported
    /// by the backend.
    TransformFeedbackNotSupported,

    /// You have requested point size setting from the shader, but it's not
    /// supported by the backend.
    PointSizeNotSupported,

    /// The glium-specific binary header was not found or is corrupt.
    BinaryHeaderError,
}

impl fmt::Display for ProgramCreationError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::ProgramCreationError::*;
        match *self {
            CompilationError(ref s) =>
                write!(fmt, "{}: {}", self.description(), s),
            LinkingError(ref s) =>
                write!(fmt, "{}: {}", self.description(), s),
            _ =>
                write!(fmt, "{}", self.description()),
        }
    }
}

impl Error for ProgramCreationError {
    fn description(&self) -> &str {
        use self::ProgramCreationError::*;
        match *self {
            CompilationError(_) =>
                "Compilation error in one of the shaders",
            LinkingError(_) =>
                "Error while linking shaders together",
            ShaderTypeNotSupported =>
                "One of the request shader type is not supported by the backend",
            CompilationNotSupported =>
                "The backend doesn't support shaders compilation",
            TransformFeedbackNotSupported =>
                "Transform feedback is not supported by the backend.",
            PointSizeNotSupported =>
                "Point size is not supported by the backend.",
            BinaryHeaderError =>
                "The glium-specific binary header was not found or is corrupt.",
        }
    }
}

/// Error type that is returned by the `program!` macro.
#[derive(Clone, Debug)]
pub enum ProgramChooserCreationError {
    /// No available version has been found.
    NoVersion,

    /// A version has been found but it triggered the given error.
    ProgramCreationError(ProgramCreationError),
}

impl fmt::Display for ProgramChooserCreationError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", self.description())
    }
}

impl Error for ProgramChooserCreationError {
    #[inline]
    fn description(&self) -> &str {
        use self::ProgramChooserCreationError::*;
        match *self {
            ProgramCreationError(ref err) => err.description(),
            NoVersion => "No version of the program has been found for the current OpenGL version.",
        }
    }

    #[inline]
    fn cause(&self) -> Option<&Error> {
        use self::ProgramChooserCreationError::*;
        match *self {
            ProgramCreationError(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<ProgramCreationError> for ProgramChooserCreationError {
    fn from(err: ProgramCreationError) -> ProgramChooserCreationError {
        ProgramChooserCreationError::ProgramCreationError(err)
    }
}

/// Error while retreiving the binary representation of a program.
#[derive(Copy, Clone, Debug)]
pub enum GetBinaryError {
    /// The backend doesn't support binary.
    NotSupported,
    /// The backend does not supply any binary formats.
    NoFormats,
}

impl fmt::Display for GetBinaryError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}

impl Error for GetBinaryError {
    fn description(&self) -> &str {
        use self::GetBinaryError::*;
        match *self {
            NotSupported => "The backend doesn't support binary",
            NoFormats => "The backend does not supply any binary formats.",
        }
    }
}

/// Input when creating a program.
pub enum ProgramCreationInput<'a> {
    /// Use GLSL source code.
    SourceCode {
        /// Source code of the vertex shader.
        vertex_shader: &'a str,

        /// Source code of the optional tessellation control shader.
        tessellation_control_shader: Option<&'a str>,

        /// Source code of the optional tessellation evaluation shader.
        tessellation_evaluation_shader: Option<&'a str>,

        /// Source code of the optional geometry shader.
        geometry_shader: Option<&'a str>,

        /// Source code of the fragment shader.
        fragment_shader: &'a str,

        /// The list of variables and mode to use for transform feedback.
        ///
        /// The information specified here will be passed to the OpenGL linker. If you pass
        /// `None`, then you won't be able to use transform feedback.
        transform_feedback_varyings: Option<(Vec<String>, TransformFeedbackMode)>,

        /// Whether the fragment shader outputs colors in `sRGB` or `RGB`. This is false by default,
        /// meaning that the program outputs `RGB`.
        ///
        /// If this is false, then `GL_FRAMEBUFFER_SRGB` will be enabled when this program is used
        /// (if it is supported).
        outputs_srgb: bool,

        /// Whether the shader uses point size.
        uses_point_size: bool,
    },

    /// Use a precompiled binary.
    Binary {
        /// The data.
        data: Binary,

        /// See `SourceCode::outputs_srgb`.
        outputs_srgb: bool,

        /// Whether the shader uses point size.
        uses_point_size: bool,
    }
}

/// Represents the source code of a program.
pub struct SourceCode<'a> {
    /// Source code of the vertex shader.
    pub vertex_shader: &'a str,

    /// Source code of the optional tessellation control shader.
    pub tessellation_control_shader: Option<&'a str>,

    /// Source code of the optional tessellation evaluation shader.
    pub tessellation_evaluation_shader: Option<&'a str>,

    /// Source code of the optional geometry shader.
    pub geometry_shader: Option<&'a str>,

    /// Source code of the fragment shader.
    pub fragment_shader: &'a str,
}

impl<'a> From<SourceCode<'a>> for ProgramCreationInput<'a> {
    #[inline]
    fn from(code: SourceCode<'a>) -> ProgramCreationInput<'a> {
        let SourceCode { vertex_shader, fragment_shader, geometry_shader,
                         tessellation_control_shader, tessellation_evaluation_shader } = code;

        ProgramCreationInput::SourceCode {
            vertex_shader: vertex_shader,
            tessellation_control_shader: tessellation_control_shader,
            tessellation_evaluation_shader: tessellation_evaluation_shader,
            geometry_shader: geometry_shader,
            fragment_shader: fragment_shader,
            transform_feedback_varyings: None,
            outputs_srgb: false,
            uses_point_size: false,
        }
    }
}

/// Represents the compiled binary data of a program.
pub struct Binary {
    /// An implementation-defined format.
    pub format: u32,

    /// The binary data.
    pub content: Vec<u8>,
}

impl<'a> From<Binary> for ProgramCreationInput<'a> {
    #[inline]
    fn from(binary: Binary) -> ProgramCreationInput<'a> {
        ProgramCreationInput::Binary {
            data: binary,
            outputs_srgb: false,
            uses_point_size: false,
        }
    }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "bit-ops"]

pub mod algebra;

#[test]
fn test_adding () {
    let a = 3i8;
    let b = 6i8;
    assert!(a + b == algebra::add(a, b));
}

#[test]
fn test_subtracting () {
    let a = 9i8;
    let b = 3i8;

    let result = a - b == algebra::subtract(a, b);
    assert!(result);

    let minuend = 8i8;

    for subtrahend in range(0i8, 128) {
        let result = minuend - subtrahend == algebra::subtract(minuend, subtrahend);
        assert!(result);
    }

}
<commit_msg>more tests<commit_after>#![crate_type = "lib"]
#![crate_name = "bit-ops"]

pub mod algebra;

#[test]
fn test_adding () {
    let a = 3i8;
    let b = 6i8;
    assert!(a + b == algebra::add(a, b));
}

#[test]
fn test_subtracting () {
    let a = 9i8;
    let b = 3i8;

    let result = a - b == algebra::subtract(a, b);
    assert!(result);

    for minuend in range(0i8, 128) {
        for subtrahend in range(0i8, 128) {
            let result = minuend - subtrahend == algebra::subtract(minuend, subtrahend);
            assert!(result);
        }
    }

}
<|endoftext|>


<commit_before>use alloc::heap;
use std::marker;
use std::marker::Sized;
use std::mem;
use std::slice;
use std::slice::Iter;
use std::raw::Slice;
use std::iter::Iterator;

use intrinsics::sse;
use types::{DataTy, HasDataTy};
use common::constant::VECTOR_SIZE;

pub trait Vector : HasDataTy {
  fn size(&self) -> usize;
  fn as_ptr(&self) -> *const u8;
  fn as_mut_ptr(&mut self) ->*mut u8;
  fn is_const(&self) -> bool;
}

pub struct ArrayVector<'a> {
  ptr: *mut u8,
  data_ty: DataTy,
  _marker: marker::PhantomData<&'a ()>
}

impl<'a> ArrayVector<'a> {
  pub fn new(data_ty: &DataTy) -> ArrayVector {
    let alloc_size = sse::compute_aligned_size(
      data_ty.bytes_len() as usize * VECTOR_SIZE);

    let ptr = unsafe {
      heap::allocate(alloc_size, sse::ALIGNED_SIZE)
    };

    ArrayVector {
      ptr: ptr,
      data_ty: data_ty.clone(),
      _marker: marker::PhantomData
    }
  }
}

impl<'a> Drop for ArrayVector<'a> {
  fn drop(&mut self) {
    unsafe {
      let alloc_size = sse::compute_aligned_size(
        self.data_ty.bytes_len() as usize * VECTOR_SIZE);

      heap::deallocate(self.ptr as *mut u8, alloc_size, sse::ALIGNED_SIZE);
    }
  }
}

impl<'a> Vector for ArrayVector<'a> {
  #[inline]
  fn size(&self) -> usize {VECTOR_SIZE}

  #[inline]
  fn as_ptr(&self) -> *const u8 {
    self.ptr
  }

  #[inline]
  fn as_mut_ptr(&mut self) -> *mut u8 {
    self.ptr
  }

  #[inline]
  fn is_const(&self) -> bool { false }
}

impl<'a> HasDataTy for ArrayVector<'a> {
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}

#[inline]
pub fn first_value<T>(v: &Vector) -> &T {
  let array = unsafe {
    slice::from_raw_parts(v.as_ptr() as *const T, 1) as &[T]
  };

  &array[0]
}

#[inline]
pub fn as_array<T>(v: &Vector) -> &[T] {
  unsafe {
    slice::from_raw_parts(v.as_ptr() as *const T, VECTOR_SIZE)
  }
}

#[inline]
pub fn as_mut_array<T>(v: &mut Vector) -> &mut [T] {
  unsafe {
    slice::from_raw_parts_mut(v.as_mut_ptr() as *mut T, VECTOR_SIZE)
  }
}<commit_msg>Implemented ConstVector to contain a singular value.<commit_after>use alloc::heap;
use std::marker;
use std::mem;
use std::slice;
use std::slice::Iter;
use std::ptr;
use std::raw::Slice;
use std::iter::Iterator;

use common::constant::VECTOR_SIZE;
use common::StringSlice;
use expr::Datum;
use intrinsics::sse;
use types::*;

pub trait Vector : HasDataTy {
  fn size(&self) -> usize;
  fn as_ptr(&self) -> *const u8;
  fn as_mut_ptr(&mut self) ->*mut u8;
  fn is_const(&self) -> bool;
}

pub struct ArrayVector<'a> {
  ptr: *mut u8,
  data_ty: DataTy,
  _marker: marker::PhantomData<&'a ()>
}

impl<'a> ArrayVector<'a> {
  pub fn new(data_ty: &DataTy) -> ArrayVector {
    let alloc_size = sse::compute_aligned_size(
      data_ty.bytes_len() as usize * VECTOR_SIZE);

    let ptr = unsafe {
      heap::allocate(alloc_size, sse::ALIGNED_SIZE)
    };

    ArrayVector {
      ptr: ptr,
      data_ty: data_ty.clone(),
      _marker: marker::PhantomData
    }
  }
}

impl<'a> Drop for ArrayVector<'a> {
  fn drop(&mut self) {
    unsafe {
      let alloc_size = sse::compute_aligned_size(
        self.data_ty.bytes_len() as usize * VECTOR_SIZE);

      heap::deallocate(self.ptr as *mut u8, alloc_size, sse::ALIGNED_SIZE);
    }
  }
}

impl<'a> Vector for ArrayVector<'a> {
  #[inline]
  fn size(&self) -> usize { VECTOR_SIZE }

  #[inline]
  fn as_ptr(&self) -> *const u8 {
    self.ptr
  }

  #[inline]
  fn as_mut_ptr(&mut self) -> *mut u8 {
    self.ptr
  }

  #[inline]
  fn is_const(&self) -> bool { false }
}

impl<'a> HasDataTy for ArrayVector<'a> {
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}

pub struct ConstVector<'a> {
  value: [u8; 16],
  data_ty: DataTy,
  _marker: marker::PhantomData<&'a ()>
}

impl<'a> ConstVector<'a> {
  pub fn new(datum: &'a Datum) -> ConstVector {
    let value: [u8; 16] = unsafe { mem::zeroed() };
    unsafe {
      match *datum {
        Datum::Bool(v) => ptr::write(value.as_ptr() as *mut BOOL_T, v),
        Datum::Int1(v) => ptr::write(value.as_ptr() as *mut INT1_T, v),
        Datum::Int2(v) => ptr::write(value.as_ptr() as *mut INT2_T, v),
        Datum::Int4(v) => ptr::write(value.as_ptr() as *mut INT4_T, v),
        Datum::Int8(v) => ptr::write(value.as_ptr() as *mut INT8_T, v),
        Datum::Float4(v) => ptr::write(value.as_ptr() as *mut FLOAT4_T, v),
        Datum::Float8(v) => ptr::write(value.as_ptr() as *mut FLOAT8_T, v),
        Datum::Time(v) => ptr::write(value.as_ptr() as *mut TIME_T, v),
        Datum::Date(v) => ptr::write(value.as_ptr() as *mut DATE_T, v),
        Datum::Timestamp(v) => ptr::write(value.as_ptr() as *mut TIMESTAMP_T, v),
        // Datum::Interval(v) => ptr::write(value.as_ptr() as *mut INTERVAL_T, v),
        // Datum::Char(v) => ptr::write(value.as_ptr() , v),
        Datum::Text(ref v) => {
          let text: TEXT_T = StringSlice::new_from_str(v.as_str());
          ptr::write(value.as_ptr() as *mut TEXT_T, text);
        }
        // Datum::Varchar(v) => ptr::write(value.as_ptr(), v),
        // Datum::Blob(v) => ptr::write(value.as_ptr(), v),
        _ => panic!("not support type")
      }
    }

    ConstVector {
      value: value,
      data_ty: DataTy::new(datum.ty()),
      _marker: marker::PhantomData // to keep the lifetime of BLOB values
    }
  }
}

impl<'a> HasDataTy for ConstVector<'a> {
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}

impl<'a> Vector for ConstVector<'a> {
  #[inline]
  fn size(&self) -> usize { 1 }

  #[inline]
  fn as_ptr(&self) -> *const u8 {
    self.value.as_ptr() as *const u8
  }

  #[inline]
  fn as_mut_ptr(&mut self) -> *mut u8 {
    self.value.as_ptr() as *mut u8
  }

  #[inline]
  fn is_const(&self) -> bool { false }
}

#[inline]
pub fn first_value<T>(v: &Vector) -> &T {
  let array = unsafe {
    slice::from_raw_parts(v.as_ptr() as *const T, 1) as &[T]
  };

  &array[0]
}

#[inline]
pub fn as_array<T>(v: &Vector) -> &[T] {
  unsafe {
    slice::from_raw_parts(v.as_ptr() as *const T, VECTOR_SIZE)
  }
}

#[inline]
pub fn as_mut_array<T>(v: &mut Vector) -> &mut [T] {
  unsafe {
    slice::from_raw_parts_mut(v.as_mut_ptr() as *mut T, VECTOR_SIZE)
  }
}

#[test]
fn test_const_vector() {
  let bool_value = Datum::Bool(true);
  let bool_vec: &Vector = &ConstVector::new(&bool_value);
  assert_eq!(Ty::Bool, bool_value.ty());
  assert_eq!(Ty::Bool, bool_vec.data_ty().ty());
  assert_eq!(1, bool_vec.size());
  assert_eq!(true, *first_value(bool_vec));

  let int1_value = Datum::Int1(7);
  let int1_vec: &Vector = &ConstVector::new(&int1_value);
  assert_eq!(Ty::Int1, int1_value.ty());
  assert_eq!(Ty::Int1, int1_vec.data_ty().ty());
  assert_eq!(1, int1_vec.size());
  assert_eq!(7, *first_value(int1_vec));

  let int2_value = Datum::Int2(17);
  let int2_vec: &Vector = &ConstVector::new(&int2_value);
  assert_eq!(Ty::Int2, int2_value.ty());
  assert_eq!(Ty::Int2, int2_vec.data_ty().ty());
  assert_eq!(1, int2_vec.size());
  assert_eq!(17, *first_value(int2_vec));

  let int4_value = Datum::Int4(178910);
  let int4_vec: &Vector = &ConstVector::new(&int4_value);
  assert_eq!(Ty::Int4, int4_value.ty());
  assert_eq!(Ty::Int4, int4_vec.data_ty().ty());
  assert_eq!(1, int4_vec.size());
  assert_eq!(178910, *first_value(int4_vec));

  let int8_value = Datum::Int8(981627341);
  let int8_vec: &Vector = &ConstVector::new(&int8_value);
  assert_eq!(Ty::Int8, int8_value.ty());
  assert_eq!(Ty::Int8, int8_vec.data_ty().ty());
  assert_eq!(1, int8_vec.size());
  assert_eq!(981627341, *first_value(int8_vec));

  let float4_value = Datum::Float4(3.14f32);
  let float4_vec: &Vector = &ConstVector::new(&float4_value);
  assert_eq!(Ty::Float4, float4_value.ty());
  assert_eq!(Ty::Float4, float4_vec.data_ty().ty());
  assert_eq!(1, float4_vec.size());
  assert_eq!(3.14f32, *first_value(float4_vec));

  let float8_value = Datum::Float8(87123.1452f64);
  let float8_vec: &Vector = &ConstVector::new(&float8_value);
  assert_eq!(Ty::Float8, float8_value.ty());
  assert_eq!(Ty::Float8, float8_vec.data_ty().ty());
  assert_eq!(1, float8_vec.size());
  assert_eq!(87123.1452f64, *first_value(float8_vec));

  let text_value = Datum::Text("hyunsik".to_string());
  let text_vec: &Vector = &ConstVector::new(&text_value);
  assert_eq!(Ty::Text, text_value.ty());
  assert_eq!(Ty::Text, text_vec.data_ty().ty());
  assert_eq!(1, text_vec.size());
  let expected = StringSlice::new_from_str("hyunsik");
  assert_eq!(expected, *first_value(text_vec));
}<|endoftext|>


<commit_before>/*
 * rustboy/cpu.rs
 *
 * This is the CPU of the GameBoy emulator. A technical specification
 * of the GameBoy can be found here: http://problemkaputt.de/pandocs.htm
 *
 */

// Declarations
// These have Z80 added to the names because eventually ARM7TDMI architecture
// will also be defined here.
struct Z80_Clock;
struct Z80_CPU;
struct Z80_Registers;

// The Z80 keeps two internal clocks, m and t. t is a measure of CPU cycles
// and m is 1/4 of t.
struct Z80_Clock {
    m: u8,
    t: u8
}

/*
  16bit Hi   Lo   Name/Function
  AF    A    -    Accumulator & Flags
  BC    B    C    BC
  DE    D    E    DE
  HL    H    L    HL
  SP    -    -    Stack Pointer
  PC    -    -    Program Counter/Pointer
*/
struct Z80_Registers {
    // 8-bit registers:
    a: u8,      // acc and flags
    b: u8,      // BC
    c: u8,
    d: u8,      // DE
    e: u8,
    h: u8,      // HL
    l: u8,
    // 16-bit registers:
    af: u16,    // acc and flags
    bc: u16,    // BC
    de: u16,    // DE
    hl: u16,    // HL
    // pointers:
    sp: u16,    // stack pointer
    pc: u16     // program counter / instruction pointer
}

struct Z80_CPU {
    clock: Z80_Clock,
    //mem: memory,
    regs: Z80_Registers,
}

impl Z80_CPU {
    pub fn reset(&mut self) {
        // clear 8-bit registers
        self.regs.a = 0;
        self.regs.b = 0;
        self.regs.c = 0;
        self.regs.d = 0;
        self.regs.e = 0;
        self.regs.h = 0;
        self.regs.l = 0;
        // clear 16-bit registers
        self.regs.af = 0;
        self.regs.bc = 0;
        self.regs.de = 0;
        self.regs.hl = 0;
        // clear pointers
        self.regs.sp = 0; // beginning of stack
        self.regs.pc = 0; // back to first instruction

        // reset the clock
        self.clock.m = 0;
        self.clock.t = 0;
    }
}
<commit_msg>added trace and flags register<commit_after>/*
 * rustboy/cpu.rs
 *
 * This is the CPU of the GameBoy emulator. A technical specification
 * of the GameBoy can be found here: http://problemkaputt.de/pandocs.htm
 *
 */

// Declarations
// These have Z80 added to the names because eventually ARM7TDMI architecture
// will also be defined here.
struct Z80_Clock;
struct Z80_CPU;
struct Z80_Registers;

// The Z80 keeps two internal clocks, m and t. t is a measure of CPU cycles
// and m is 1/4 of t.
struct Z80_Clock {
    m: u8,
    t: u8
}

/*
  16bit Hi   Lo   Name/Function
  AF    A    -    Accumulator & Flags
  BC    B    C    BC
  DE    D    E    DE
  HL    H    L    HL
  SP    -    -    Stack Pointer
  PC    -    -    Program Counter/Pointer
*/
struct Z80_Registers {
    // 8-bit registers:
    a: u8,      // acc and flags
    b: u8,      // BC
    c: u8,
    d: u8,      // DE
    e: u8,
    h: u8,      // HL
    l: u8,
    // 16-bit registers:
    af: u16,    // acc and flags
    bc: u16,    // BC
    de: u16,    // DE
    hl: u16,    // HL
    // flags
    f: u8,
    // pointers:
    sp: u16,    // stack pointer
    pc: u16     // program counter / instruction pointer
}

struct Z80_CPU {
    clock: Z80_Clock,
    //mem: memory,
    regs: Z80_Registers,
}

impl Z80_CPU {
    pub fn reset(&mut self) {
        // clear 8-bit registers
        self.regs.a = 0;
        self.regs.b = 0;
        self.regs.c = 0;
        self.regs.d = 0;
        self.regs.e = 0;
        self.regs.h = 0;
        self.regs.l = 0;
        // clear 16-bit registers
        self.regs.af = 0;
        self.regs.bc = 0;
        self.regs.de = 0;
        self.regs.hl = 0;
        // clear flags
        self.regs.f = 0;
        // clear pointers
        self.regs.sp = 0; // beginning of stack
        self.regs.pc = 0; // back to first instruction

        // reset the clock
        self.clock.m = 0;
        self.clock.t = 0;
    }

    fn trace(&mut self) {
        // TODO: Add disassembler to give real stack trace
        println!(
            "ZIP:{:04X}\nZA:{:02X}\nZB:{:02X} ZC:{:02X}\n\
            ZD:{:02X} ZE:{:02X}\nZH:{:02X} ZL:{:02X}\n\
            ZSP:{:02X} CYC:{}\
            F:{:02X}",
            self.regs.pc, self.regs.a, self.regs.b, self.regs.c,
            self.regs.d, self.regs.e, self.regs.h, self.regs.l,
            self.regs.sp, self.clock.t, self.regs.f
        );
    }
}
<|endoftext|>


<commit_before>#[doc = "Generate markdown from a document tree"];

import std::io;
import std::io::writer_util;

export mk_pass;

fn mk_pass(
    writer: fn~() -> io::writer
) -> pass {
    ret fn~(
        _srv: astsrv::srv,
        doc: doc::cratedoc
    ) -> doc::cratedoc {
        write_markdown(doc, writer());
        doc
    };
}

type ctxt = {
    w: io::writer
};

fn write_markdown(
    doc: doc::cratedoc,
    writer: io::writer
) {
    let ctxt = {
        w: writer
    };

    write_crate(ctxt, doc);
}

enum hlvl {
    h1 = 1,
    h2 = 2,
    h3 = 3
}

fn write_header(ctxt: ctxt, lvl: hlvl, title: str) {
    let hashes = str::from_chars(vec::init_elt(lvl as uint, '#'));
    ctxt.w.write_line(#fmt("%s %s", hashes, title));
    ctxt.w.write_line("");
}

fn write_crate(
    ctxt: ctxt,
    doc: doc::cratedoc
) {
    write_header(ctxt, h1, #fmt("Crate %s", doc.topmod.name));
    write_top_module(ctxt, doc.topmod);
}

fn write_top_module(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_mod_contents(ctxt, moddoc);
}

fn write_mod(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    let fullpath = str::connect(moddoc.path + [moddoc.name], "::");
    write_header(ctxt, h2, #fmt("Module `%s`", fullpath));
    write_mod_contents(ctxt, moddoc);
}

#[test]
fn should_write_full_path_to_mod() {
    let markdown = test::render("mod a { mod b { mod c { } } }");
    assert str::contains(markdown, "## Module `a::b::c`");
}

fn write_mod_contents(
    ctxt: ctxt,
    doc: doc::moddoc
) {
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);

    for constdoc in *doc.consts {
        write_const(ctxt, constdoc);
    }

    for fndoc in *doc.fns {
        write_fn(ctxt, fndoc);
    }

    for moddoc in *doc.mods {
        write_mod(ctxt, moddoc);
    }
}

#[test]
fn should_write_crate_brief_description() {
    let markdown = test::render("#[doc(brief = \"this is the crate\")];");
    assert str::contains(markdown, "this is the crate");
}

#[test]
fn should_write_crate_description() {
    let markdown = test::render("#[doc = \"this is the crate\"];");
    assert str::contains(markdown, "this is the crate");
}

fn write_fn(
    ctxt: ctxt,
    doc: doc::fndoc
) {
    write_header(ctxt, h3, #fmt("Function `%s`", doc.name));
    write_sig(ctxt, doc.sig);
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);
    write_args(ctxt, doc.args);
    write_return(ctxt, doc.return);
}

fn write_sig(ctxt: ctxt, sig: option<str>) {
    alt sig {
      some(sig) {
        ctxt.w.write_line(code_block_indent(sig));
        ctxt.w.write_line("");
      }
      none { fail "unimplemented" }
    }
}

fn code_block_indent(s: str) -> str {
    let lines = str::lines_any(s);
    let indented = vec::map(lines, { |line| #fmt("    %s", line) });
    str::connect(indented, "\n")
}

#[test]
fn should_write_the_function_signature() {
    let markdown = test::render("#[doc = \"f\"] fn a() { }");
    assert str::contains(markdown, "\n    fn a()\n");
}

#[test]
fn should_insert_blank_line_after_fn_signature() {
    let markdown = test::render("#[doc = \"f\"] fn a() { }");
    assert str::contains(markdown, "fn a()\n\n");
}

#[test]
fn should_correctly_indent_fn_signature() {
    let doc = test::create_doc("fn a() { }");
    let doc = ~{
        topmod: ~{
            fns: doc::fnlist([~{
                sig: some("line 1\nline 2")
                with *doc.topmod.fns[0]
            }])
            with *doc.topmod
        }
        with *doc
    };
    let markdown = test::write_markdown_str(doc);
    assert str::contains(markdown, "    line 1\n    line 2");
}

fn write_brief(
    ctxt: ctxt,
    brief: option<str>
) {
    alt brief {
      some(brief) {
        ctxt.w.write_line(brief);
        ctxt.w.write_line("");
      }
      none { }
    }
}

fn write_desc(
    ctxt: ctxt,
    desc: option<str>
) {
    alt desc {
        some(desc) {
            ctxt.w.write_line(desc);
            ctxt.w.write_line("");
        }
        none { }
    }
}

fn write_args(
    ctxt: ctxt,
    args: [doc::argdoc]
) {
    if vec::is_not_empty(args) {
        ctxt.w.write_line("Arguments:");
        ctxt.w.write_line("");
        vec::iter(args) {|arg| write_arg(ctxt, arg) };
        ctxt.w.write_line("");
    }
}

fn write_arg(ctxt: ctxt, arg: doc::argdoc) {
    assert option::is_some(arg.ty);
    ctxt.w.write_str(#fmt(
        "* `%s`: `%s`",
        arg.name,
        option::get(arg.ty)
    ));
    alt arg.desc {
      some(desc) {
        ctxt.w.write_str(#fmt(" - %s", desc));
      }
      none { }
    }
    ctxt.w.write_line("");
}

#[test]
fn should_write_argument_list() {
    let source = "fn a(b: int, c: int) { }";
    let markdown = test::render(source);
    assert str::contains(
        markdown,
        "Arguments:\n\
         \n\
         * `b`: `int`\n\
         * `c`: `int`\n\
         \n"
    );
}

#[test]
fn should_not_write_arguments_if_none() {
    let source = "fn a() { } fn b() { }";
    let markdown = test::render(source);
    assert !str::contains(markdown, "Arguments");
}

#[test]
fn should_write_argument_description() {
    let source = "#[doc(args(a = \"milk\"))] fn f(a: bool) { }";
    let markdown = test::render(source);
    assert str::contains(markdown, "`a`: `bool` - milk");
}

fn write_return(
    ctxt: ctxt,
    doc: doc::retdoc
) {
    alt doc.ty {
      some(ty) {
        ctxt.w.write_str(#fmt("Returns `%s`", ty));
        alt doc.desc {
          some(d) {
            ctxt.w.write_line(#fmt(" - %s", d));
            ctxt.w.write_line("");
          }
          none {
            ctxt.w.write_line("");
            ctxt.w.write_line("");
          }
        }
      }
      none { }
    }
}

#[test]
fn should_write_return_type_on_new_line() {
    let markdown = test::render("fn a() -> int { }");
    assert str::contains(markdown, "\nReturns `int`");
}

#[test]
fn should_write_blank_line_between_return_type_and_next_header() {
    let markdown = test::render(
        "fn a() -> int { } \
         fn b() -> int { }"
    );
    assert str::contains(markdown, "Returns `int`\n\n##");
}

#[test]
fn should_not_write_return_type_when_there_is_none() {
    let markdown = test::render("fn a() { }");
    assert !str::contains(markdown, "Returns");
}

#[test]
fn should_write_blank_line_after_return_description() {
    let markdown = test::render(
        "#[doc(return = \"blorp\")] fn a() -> int { }"
    );
    assert str::contains(markdown, "blorp\n\n");
}

#[test]
fn should_write_return_description_on_same_line_as_type() {
    let markdown = test::render(
        "#[doc(return = \"blorp\")] fn a() -> int { }"
    );
    assert str::contains(markdown, "Returns `int` - blorp");
}

fn write_const(
    ctxt: ctxt,
    doc: doc::constdoc
) {
    write_header(ctxt, h3, #fmt("Const `%s`", doc.name));
    write_sig(ctxt, doc.ty);
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);
}

#[test]
fn should_write_const_header() {
    let markdown = test::render("const a: bool = true;");
    assert str::contains(markdown, "### Const `a`\n\n");
}

#[test]
fn should_write_const_description() {
    let markdown = test::render(
        "#[doc(brief = \"a\", desc = \"b\")]\
         const a: bool = true;");
    assert str::contains(markdown, "\n\na\n\nb\n\n");
}

#[cfg(test)]
mod test {
    fn render(source: str) -> str {
        let doc = create_doc(source);
        let markdown = write_markdown_str(doc);
        #debug("markdown: %s", markdown);
        markdown
    }

    fn create_doc(source: str) -> doc::cratedoc {
        let srv = astsrv::mk_srv_from_str(source);
        let doc = extract::from_srv(srv, "");
        #debug("doc (extract): %?", doc);
        let doc = tystr_pass::mk_pass()(srv, doc);
        #debug("doc (tystr): %?", doc);
        let doc = path_pass::mk_pass()(srv, doc);
        #debug("doc (path): %?", doc);
        let doc = attr_pass::mk_pass()(srv, doc);
        #debug("doc (attr): %?", doc);
        doc
    }

    fn write_markdown_str(
        doc: doc::cratedoc
    ) -> str {
        let buffer = io::mk_mem_buffer();
        let writer = io::mem_buffer_writer(buffer);
        write_markdown(doc, writer);
        ret io::mem_buffer_str(buffer);
    }

    #[test]
    fn write_markdown_should_write_crate_header() {
        let srv = astsrv::mk_srv_from_str("");
        let doc = extract::from_srv(srv, "belch");
        let doc = attr_pass::mk_pass()(srv, doc);
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "# Crate belch");
    }

    #[test]
    fn write_markdown_should_write_function_header() {
        let markdown = render("fn func() { }");
        assert str::contains(markdown, "## Function `func`");
    }

    #[test]
    fn write_markdown_should_write_mod_headers() {
        let markdown = render("mod moo { }");
        assert str::contains(markdown, "## Module `moo`");
    }

    #[test]
    fn should_leave_blank_line_after_header() {
        let markdown = render("mod morp { }");
        assert str::contains(markdown, "Module `morp`\n\n");
    }

    #[test]
    fn should_leave_blank_line_between_fn_header_and_sig() {
        let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
        assert str::contains(markdown, "Function `a`\n\n    fn a()");
    }

    #[test]
    fn should_leave_blank_line_after_brief() {
        let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
        assert str::contains(markdown, "brief\n\n");
    }

    #[test]
    fn should_leave_blank_line_between_brief_and_desc() {
        let markdown = render(
            "#[doc(brief = \"brief\", desc = \"desc\")] fn a() { }"
        );
        assert str::contains(markdown, "brief\n\ndesc");
    }

}<commit_msg>rustdoc: Update one of the markdown fn tests<commit_after>#[doc = "Generate markdown from a document tree"];

import std::io;
import std::io::writer_util;

export mk_pass;

fn mk_pass(
    writer: fn~() -> io::writer
) -> pass {
    ret fn~(
        _srv: astsrv::srv,
        doc: doc::cratedoc
    ) -> doc::cratedoc {
        write_markdown(doc, writer());
        doc
    };
}

type ctxt = {
    w: io::writer
};

fn write_markdown(
    doc: doc::cratedoc,
    writer: io::writer
) {
    let ctxt = {
        w: writer
    };

    write_crate(ctxt, doc);
}

enum hlvl {
    h1 = 1,
    h2 = 2,
    h3 = 3
}

fn write_header(ctxt: ctxt, lvl: hlvl, title: str) {
    let hashes = str::from_chars(vec::init_elt(lvl as uint, '#'));
    ctxt.w.write_line(#fmt("%s %s", hashes, title));
    ctxt.w.write_line("");
}

fn write_crate(
    ctxt: ctxt,
    doc: doc::cratedoc
) {
    write_header(ctxt, h1, #fmt("Crate %s", doc.topmod.name));
    write_top_module(ctxt, doc.topmod);
}

fn write_top_module(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_mod_contents(ctxt, moddoc);
}

fn write_mod(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    let fullpath = str::connect(moddoc.path + [moddoc.name], "::");
    write_header(ctxt, h2, #fmt("Module `%s`", fullpath));
    write_mod_contents(ctxt, moddoc);
}

#[test]
fn should_write_full_path_to_mod() {
    let markdown = test::render("mod a { mod b { mod c { } } }");
    assert str::contains(markdown, "## Module `a::b::c`");
}

fn write_mod_contents(
    ctxt: ctxt,
    doc: doc::moddoc
) {
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);

    for constdoc in *doc.consts {
        write_const(ctxt, constdoc);
    }

    for fndoc in *doc.fns {
        write_fn(ctxt, fndoc);
    }

    for moddoc in *doc.mods {
        write_mod(ctxt, moddoc);
    }
}

#[test]
fn should_write_crate_brief_description() {
    let markdown = test::render("#[doc(brief = \"this is the crate\")];");
    assert str::contains(markdown, "this is the crate");
}

#[test]
fn should_write_crate_description() {
    let markdown = test::render("#[doc = \"this is the crate\"];");
    assert str::contains(markdown, "this is the crate");
}

fn write_fn(
    ctxt: ctxt,
    doc: doc::fndoc
) {
    write_header(ctxt, h3, #fmt("Function `%s`", doc.name));
    write_sig(ctxt, doc.sig);
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);
    write_args(ctxt, doc.args);
    write_return(ctxt, doc.return);
}

fn write_sig(ctxt: ctxt, sig: option<str>) {
    alt sig {
      some(sig) {
        ctxt.w.write_line(code_block_indent(sig));
        ctxt.w.write_line("");
      }
      none { fail "unimplemented" }
    }
}

fn code_block_indent(s: str) -> str {
    let lines = str::lines_any(s);
    let indented = vec::map(lines, { |line| #fmt("    %s", line) });
    str::connect(indented, "\n")
}

#[test]
fn should_write_the_function_signature() {
    let markdown = test::render("#[doc = \"f\"] fn a() { }");
    assert str::contains(markdown, "\n    fn a()\n");
}

#[test]
fn should_insert_blank_line_after_fn_signature() {
    let markdown = test::render("#[doc = \"f\"] fn a() { }");
    assert str::contains(markdown, "fn a()\n\n");
}

#[test]
fn should_correctly_indent_fn_signature() {
    let doc = test::create_doc("fn a() { }");
    let doc = ~{
        topmod: ~{
            fns: doc::fnlist([~{
                sig: some("line 1\nline 2")
                with *doc.topmod.fns[0]
            }])
            with *doc.topmod
        }
        with *doc
    };
    let markdown = test::write_markdown_str(doc);
    assert str::contains(markdown, "    line 1\n    line 2");
}

fn write_brief(
    ctxt: ctxt,
    brief: option<str>
) {
    alt brief {
      some(brief) {
        ctxt.w.write_line(brief);
        ctxt.w.write_line("");
      }
      none { }
    }
}

fn write_desc(
    ctxt: ctxt,
    desc: option<str>
) {
    alt desc {
        some(desc) {
            ctxt.w.write_line(desc);
            ctxt.w.write_line("");
        }
        none { }
    }
}

fn write_args(
    ctxt: ctxt,
    args: [doc::argdoc]
) {
    if vec::is_not_empty(args) {
        ctxt.w.write_line("Arguments:");
        ctxt.w.write_line("");
        vec::iter(args) {|arg| write_arg(ctxt, arg) };
        ctxt.w.write_line("");
    }
}

fn write_arg(ctxt: ctxt, arg: doc::argdoc) {
    assert option::is_some(arg.ty);
    ctxt.w.write_str(#fmt(
        "* `%s`: `%s`",
        arg.name,
        option::get(arg.ty)
    ));
    alt arg.desc {
      some(desc) {
        ctxt.w.write_str(#fmt(" - %s", desc));
      }
      none { }
    }
    ctxt.w.write_line("");
}

#[test]
fn should_write_argument_list() {
    let source = "fn a(b: int, c: int) { }";
    let markdown = test::render(source);
    assert str::contains(
        markdown,
        "Arguments:\n\
         \n\
         * `b`: `int`\n\
         * `c`: `int`\n\
         \n"
    );
}

#[test]
fn should_not_write_arguments_if_none() {
    let source = "fn a() { } fn b() { }";
    let markdown = test::render(source);
    assert !str::contains(markdown, "Arguments");
}

#[test]
fn should_write_argument_description() {
    let source = "#[doc(args(a = \"milk\"))] fn f(a: bool) { }";
    let markdown = test::render(source);
    assert str::contains(markdown, "`a`: `bool` - milk");
}

fn write_return(
    ctxt: ctxt,
    doc: doc::retdoc
) {
    alt doc.ty {
      some(ty) {
        ctxt.w.write_str(#fmt("Returns `%s`", ty));
        alt doc.desc {
          some(d) {
            ctxt.w.write_line(#fmt(" - %s", d));
            ctxt.w.write_line("");
          }
          none {
            ctxt.w.write_line("");
            ctxt.w.write_line("");
          }
        }
      }
      none { }
    }
}

#[test]
fn should_write_return_type_on_new_line() {
    let markdown = test::render("fn a() -> int { }");
    assert str::contains(markdown, "\nReturns `int`");
}

#[test]
fn should_write_blank_line_between_return_type_and_next_header() {
    let markdown = test::render(
        "fn a() -> int { } \
         fn b() -> int { }"
    );
    assert str::contains(markdown, "Returns `int`\n\n##");
}

#[test]
fn should_not_write_return_type_when_there_is_none() {
    let markdown = test::render("fn a() { }");
    assert !str::contains(markdown, "Returns");
}

#[test]
fn should_write_blank_line_after_return_description() {
    let markdown = test::render(
        "#[doc(return = \"blorp\")] fn a() -> int { }"
    );
    assert str::contains(markdown, "blorp\n\n");
}

#[test]
fn should_write_return_description_on_same_line_as_type() {
    let markdown = test::render(
        "#[doc(return = \"blorp\")] fn a() -> int { }"
    );
    assert str::contains(markdown, "Returns `int` - blorp");
}

fn write_const(
    ctxt: ctxt,
    doc: doc::constdoc
) {
    write_header(ctxt, h3, #fmt("Const `%s`", doc.name));
    write_sig(ctxt, doc.ty);
    write_brief(ctxt, doc.brief);
    write_desc(ctxt, doc.desc);
}

#[test]
fn should_write_const_header() {
    let markdown = test::render("const a: bool = true;");
    assert str::contains(markdown, "### Const `a`\n\n");
}

#[test]
fn should_write_const_description() {
    let markdown = test::render(
        "#[doc(brief = \"a\", desc = \"b\")]\
         const a: bool = true;");
    assert str::contains(markdown, "\n\na\n\nb\n\n");
}

#[cfg(test)]
mod test {
    fn render(source: str) -> str {
        let doc = create_doc(source);
        let markdown = write_markdown_str(doc);
        #debug("markdown: %s", markdown);
        markdown
    }

    fn create_doc(source: str) -> doc::cratedoc {
        let srv = astsrv::mk_srv_from_str(source);
        let doc = extract::from_srv(srv, "");
        #debug("doc (extract): %?", doc);
        let doc = tystr_pass::mk_pass()(srv, doc);
        #debug("doc (tystr): %?", doc);
        let doc = path_pass::mk_pass()(srv, doc);
        #debug("doc (path): %?", doc);
        let doc = attr_pass::mk_pass()(srv, doc);
        #debug("doc (attr): %?", doc);
        doc
    }

    fn write_markdown_str(
        doc: doc::cratedoc
    ) -> str {
        let buffer = io::mk_mem_buffer();
        let writer = io::mem_buffer_writer(buffer);
        write_markdown(doc, writer);
        ret io::mem_buffer_str(buffer);
    }

    #[test]
    fn write_markdown_should_write_crate_header() {
        let srv = astsrv::mk_srv_from_str("");
        let doc = extract::from_srv(srv, "belch");
        let doc = attr_pass::mk_pass()(srv, doc);
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "# Crate belch");
    }

    #[test]
    fn write_markdown_should_write_function_header() {
        let markdown = render("fn func() { }");
        assert str::contains(markdown, "### Function `func`");
    }

    #[test]
    fn write_markdown_should_write_mod_headers() {
        let markdown = render("mod moo { }");
        assert str::contains(markdown, "## Module `moo`");
    }

    #[test]
    fn should_leave_blank_line_after_header() {
        let markdown = render("mod morp { }");
        assert str::contains(markdown, "Module `morp`\n\n");
    }

    #[test]
    fn should_leave_blank_line_between_fn_header_and_sig() {
        let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
        assert str::contains(markdown, "Function `a`\n\n    fn a()");
    }

    #[test]
    fn should_leave_blank_line_after_brief() {
        let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
        assert str::contains(markdown, "brief\n\n");
    }

    #[test]
    fn should_leave_blank_line_between_brief_and_desc() {
        let markdown = render(
            "#[doc(brief = \"brief\", desc = \"desc\")] fn a() { }"
        );
        assert str::contains(markdown, "brief\n\ndesc");
    }

}<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

#[macro_use]
mod commands;

use docopt::Docopt;
use flac::{Stream, StreamProducer, StreamReader};
use flac::metadata::{self, Picture, SeekPoint, VorbisComment};

use std::env;
use std::io::{self, Write};
use std::fs::File;

use commands::{streaminfo, comments, seektable, picture};

const USAGE: &'static str = "
Usage: metadata <command> [<args>...]
       metadata [options]

Options:
  -h, --help  Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_command: Option<Command>,
  arg_args: Vec<String>,
}

#[derive(Debug, RustcDecodable)]
enum Command {
  StreamInfo,
  Comments,
  SeekTable,
  Picture,
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.options_first(true).decode())
    .unwrap_or_else(|e| e.exit());

  match args.arg_command.unwrap() {
    Command::StreamInfo => {
      let sub_args: streaminfo::Arguments = Docopt::new(streaminfo::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      streaminfo::run(&sub_args)
    }
    Command::Comments   => {
      let sub_args: comments::Arguments = Docopt::new(comments::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      comments::run(&sub_args)
    }
    Command::SeekTable  => {
      let sub_args: seektable::Arguments = Docopt::new(seektable::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      seektable::run(&sub_args)
    }
    Command::Picture    => {
      let sub_args: picture::Arguments = Docopt::new(picture::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      picture::run(&sub_args)
    }
  }
}
<commit_msg>Remove unused exports<commit_after>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

#[macro_use]
mod commands;

use std::env;

use commands::{streaminfo, comments, seektable, picture};
use docopt::Docopt;

const USAGE: &'static str = "
Usage: metadata <command> [<args>...]
       metadata [options]

Options:
  -h, --help  Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_command: Option<Command>,
  arg_args: Vec<String>,
}

#[derive(Debug, RustcDecodable)]
enum Command {
  StreamInfo,
  Comments,
  SeekTable,
  Picture,
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.options_first(true).decode())
    .unwrap_or_else(|e| e.exit());

  match args.arg_command.unwrap() {
    Command::StreamInfo => {
      let sub_args: streaminfo::Arguments = Docopt::new(streaminfo::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      streaminfo::run(&sub_args)
    }
    Command::Comments   => {
      let sub_args: comments::Arguments = Docopt::new(comments::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      comments::run(&sub_args)
    }
    Command::SeekTable  => {
      let sub_args: seektable::Arguments = Docopt::new(seektable::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      seektable::run(&sub_args)
    }
    Command::Picture    => {
      let sub_args: picture::Arguments = Docopt::new(picture::USAGE)
        .and_then(|d| d.argv(env::args()).decode())
        .unwrap_or_else(|e| e.exit());

      picture::run(&sub_args)
    }
  }
}
<|endoftext|>