<commit_before>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;

pub use whitespace::{ Whitespace, WHITESPACE };

mod whitespace;

/// Types of properties.
pub enum Type {
    /// Either true or false.
    Bool,
}

/// Errors reporting expected values.
pub enum Error<'a> {
    /// Not supported.
    NotSupported,
    /// Expected nodes with other names.
    ExpectedNode(&'a [&'a str]),
    /// Expected another propert type.
    ExpectedPropertyType(Type),
    /// Reaching end of node, but expected more properties.
    ExpectedMoreProperties(&'a [&'a str]),
}

/// Implemented by meta readers.
///
/// A meta reader contains an internal state that corresponds to a virtual
/// tree structure. The meta parser communicates with the meta reader such
/// that parsing is interrupted if any error happens.
pub trait MetaReader {
    /// The state that points to a location in the parsed structure.
    type State;

    /// Starts parsing a node.
    fn start_node(&mut self, name: &str, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends parsing a node.
    fn end_node(&mut self, state: &Self::State) -> Result<Self::State, Error>;
    /// Starts optional section of a node.
    fn start_optional(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends optional section of a node.
    fn end_optional(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Starts selection.
    fn start_select(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends selection.
    fn end_select(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a bool property of the node.
    fn set_as_bool(&mut self, name: &str, val: bool, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a string property of the node.
    fn set_as_str(&mut self, name: &str, val: &str, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a f64 property of the node.
    fn set_as_f64(&mut self, name: &str, val: f64, state: &Self::State) ->
        Result<Self::State, Error>;
}

/// Stores information about token.
pub struct Token<'a> {
    /// The text to match against.
    pub text: &'a str,
    /// Whether to set property to true or false (inverted).
    pub inverted: Option<bool>,
    /// Which predicate to set if token matches.
    /// This is the name of the property in current node.
    pub predicate: Option<&'a str>,
}

/// Stores information about a parameter.
pub struct Parameter<'a> {
    /// The name of the parameter.
    pub name: &'a str,
    /// The properties of the parameter.
    /// This is used to check the property names set by sub rules.
    /// If a property name does not match any of the arguments to the parameter,
    /// then an error is reported.
    pub args: &'a [&'a str],
    /// The property name of parent to set the value.
    pub value: Option<&'a str>,
    /// The body of the parameter.
    pub body: &'a [Rule<'a>],
}

/// A rule describes how some section of a document should be parsed.
pub enum Rule<'a> {
    /// Read whitespace.
    Whitespace(Whitespace),
    /// Match against a token.
    Token(Token<'a>),
    /// Select one of the sub rules.
    /// If the first one does not succeed, try another and so on.
    /// If all sub rules fail, then the rule fails.
    Select(&'a [Rule<'a>]),
    /// Read parameter.
    Parameter(Parameter<'a>),
}
<commit_msg>Added more types<commit_after>#![deny(missing_docs)]

//! Meta parsing and encoding for data oriented design

extern crate read_token;

pub use whitespace::{ Whitespace, WHITESPACE };

mod whitespace;

/// Types of properties.
pub enum Type {
    /// Either true or false.
    Bool,
    /// Text.
    String,
    /// Number.
    F64,
}

/// Errors reporting expected values.
pub enum Error<'a> {
    /// Not supported.
    NotSupported,
    /// Expected nodes with other names.
    ExpectedNode(&'a [&'a str]),
    /// Expected another propert type.
    ExpectedPropertyType(Type),
    /// Reaching end of node, but expected more properties.
    ExpectedMoreProperties(&'a [&'a str]),
}

/// Implemented by meta readers.
///
/// A meta reader contains an internal state that corresponds to a virtual
/// tree structure. The meta parser communicates with the meta reader such
/// that parsing is interrupted if any error happens.
pub trait MetaReader {
    /// The state that points to a location in the parsed structure.
    type State;

    /// Starts parsing a node.
    fn start_node(&mut self, name: &str, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends parsing a node.
    fn end_node(&mut self, state: &Self::State) -> Result<Self::State, Error>;
    /// Starts optional section of a node.
    fn start_optional(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends optional section of a node.
    fn end_optional(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Starts selection.
    fn start_select(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Ends selection.
    fn end_select(&mut self, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a bool property of the node.
    fn set_as_bool(&mut self, name: &str, val: bool, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a string property of the node.
    fn set_as_str(&mut self, name: &str, val: &str, state: &Self::State) ->
        Result<Self::State, Error>;
    /// Sets a f64 property of the node.
    fn set_as_f64(&mut self, name: &str, val: f64, state: &Self::State) ->
        Result<Self::State, Error>;
}

/// Stores information about token.
pub struct Token<'a> {
    /// The text to match against.
    pub text: &'a str,
    /// Whether to set property to true or false (inverted).
    pub inverted: Option<bool>,
    /// Which predicate to set if token matches.
    /// This is the name of the property in current node.
    pub predicate: Option<&'a str>,
}

/// Stores information about a parameter.
pub struct Parameter<'a> {
    /// The name of the parameter.
    pub name: &'a str,
    /// The properties of the parameter.
    /// This is used to check the property names set by sub rules.
    /// If a property name does not match any of the arguments to the parameter,
    /// then an error is reported.
    pub args: &'a [&'a str],
    /// The property name of parent to set the value.
    pub value: Option<&'a str>,
    /// The body of the parameter.
    pub body: &'a [Rule<'a>],
}

/// A rule describes how some section of a document should be parsed.
pub enum Rule<'a> {
    /// Read whitespace.
    Whitespace(Whitespace),
    /// Match against a token.
    Token(Token<'a>),
    /// Select one of the sub rules.
    /// If the first one does not succeed, try another and so on.
    /// If all sub rules fail, then the rule fails.
    Select(&'a [Rule<'a>]),
    /// Read parameter.
    Parameter(Parameter<'a>),
}
<|endoftext|>


<commit_before>//! CHIP-8 emulator backend.
//! You can develop your own frontends for it.
//!
//! The reference frontend is
//! [crusty-chip-sfml](https://github.com/crumblingstatue/crusty-chip-sfml).
//!
//! The CHIP-8 technical documentation in the comments is copied from
//! http://devernay.free.fr/hacks/chip8/C8TECH10.HTM,
//! Copyright (c) Thomas P. Greene.

#![feature(core)]

use std::slice::bytes::copy_memory;

mod ops;

const START_ADDR: u16 = 0x200;
const MEM_SIZE: usize = 4096;
pub const DISPLAY_WIDTH: usize = 64;
pub const DISPLAY_HEIGHT: usize = 32;

static FONTSET: [u8; 5 * 0x10] = [
    0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
    0x20, 0x60, 0x20, 0x20, 0x70, // 1
    0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
    0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
    0x90, 0x90, 0xF0, 0x10, 0x10, // 4
    0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
    0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
    0xF0, 0x10, 0x20, 0x40, 0x40, // 7
    0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
    0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
    0xF0, 0x90, 0xF0, 0x90, 0x90, // A
    0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
    0xF0, 0x80, 0x80, 0x80, 0xF0, // C
    0xE0, 0x90, 0x90, 0x90, 0xE0, // D
    0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
    0xF0, 0x80, 0xF0, 0x80, 0x80, // F
];

/// Draw callback.
///
/// Takes a slice of u8, where each u8 is a pixel.
///
/// A **non-zero** pixel is visible, a **zero** pixel is not visible.
///
/// The coordinate system is from top-left to bottom-right.
///
/// Example:
///
/// ```rust
///     use crusty_chip::{ DISPLAY_WIDTH, VirtualMachine };
///     // Dump the pixels to stdout
///     fn dump_pixels(pixels: &[u8]) {
///         for (i, px) in pixels.iter().enumerate() {
///             match *px {
///                 0 => print!(" "),
///                 _ => print!("#")
///             }
///             if i % DISPLAY_WIDTH == 0 {
///                 print!("\n");
///             }
///         }
///     }
///     let mut f: fn(&[u8]) = dump_pixels;
///     let mut ch8 = VirtualMachine::new(&mut f);
///     // ...
/// ```
pub type DrawCallback<'a> = FnMut(&[u8]) + 'a;

struct KeypressWait {
    wait: bool,
    vx: usize
}

/// CHIP-8 virtual machine
pub struct VirtualMachine<'a> {
    ram: [u8; MEM_SIZE],
    v: [u8; 16],
    i: u16,
    delay_timer: u8,
    sound_timer: u8,
    pc: u16,
    sp: u8,
    stack: [u16; 16],
    display: [u8; DISPLAY_WIDTH * DISPLAY_HEIGHT],
    draw_callback: &'a mut DrawCallback<'a>,
    keys: [bool; 16],
    keypress_wait: KeypressWait
}

impl <'a> VirtualMachine <'a> {

    /// Constructs a new `VirtualMachine`.
    ///
    /// ## Arguments ##
    /// * draw_callback - Callback used when drawing
    pub fn new(draw_callback: &'a mut DrawCallback<'a>) -> VirtualMachine<'a> {
        let mut ch8 = VirtualMachine {
            ram: [0; MEM_SIZE],
            v: [0; 16],
            i: 0,
            delay_timer: 0,
            sound_timer: 0,
            pc: START_ADDR,
            sp: 0,
            stack: [0; 16],
            display: [0; DISPLAY_WIDTH * DISPLAY_HEIGHT],
            draw_callback: draw_callback,
            keys: [false; 16],
            keypress_wait: KeypressWait {
                wait: false,
                vx: 0
            }
        };
        copy_memory(&mut ch8.ram[0usize..5 * 0x10], &FONTSET);
        ch8
    }

    /// Load a ROM
    ///
    /// ## Arguments ##
    /// * rom - ROM to load
    pub fn load_rom(&mut self, rom: &[u8]) {
        let len = self.ram.len();
        copy_memory(&mut self.ram[START_ADDR as usize .. len], rom);
    }

    /// Do an emulation cycle.
    pub fn do_cycle(&mut self) {
        if self.keypress_wait.wait {
            return;
        }

        let ins = self.fetch_ins();
        self.dispatch(ins);
    }

    // Decode instruction and execute it
    fn dispatch(&mut self, ins: u16) {
        // A 12-bit value, the lowest 12 bits of the instruction
        let nnn = ins & 0x0FFF;
        // A 4-bit value, the lowest 4 bits of the instruction
        let n = ins & 0x000F;
        // A 4-bit value, the lower 4 bits of the high byte of the instruction
        let x = (ins & 0x0F00) >> 8;
        // A 4-bit value, the upper 4 bits of the low byte of the instruction
        let y = (ins & 0x00F0) >> 4;
        // kk or byte - An 8-bit value, the lowest 8 bits of the instruction
        let kk = (ins & 0x00FF) as u8;

        match (ins & 0xF000) >> 12 {
            0x0 => match nnn {
                0x0E0 => ops::clear_display(self, ),
                0x0EE => ops::ret_from_subroutine(self, ),
                _ => ops::jump_to_sys_routine(self, 0)
            },
            0x1 => ops::jump_addr(self, nnn),
            0x2 => ops::call_subroutine(self, nnn as usize),
            0x3 => ops::skip_next_vx_eq(self, x as usize, kk),
            0x4 => ops::skip_next_vx_ne(self, x as usize, kk),
            0x5 => match n {
                0x0 => ops::skip_next_vx_eq_vy(self, x as usize, y as usize),
                _ => panic!("Unknown 0x5XXX instruction: {:x}", ins)
            },
            0x6 => ops::set_vx_byte(self, x as usize, kk),
            0x7 => ops::add_vx_byte(self, x as usize, kk),
            0x8 => {
                let (x, y) = (x as usize, y as usize);
                match n {
                    0x0 => ops::set_vx_to_vy(self, x, y),
                    0x1 => ops::set_vx_to_vx_or_vy(self, x, y),
                    0x2 => ops::set_vx_to_vx_and_vy(self, x, y),
                    0x3 => ops::set_vx_to_vx_xor_vy(self, x, y),
                    0x4 => ops::add_vx_vy(self, x, y),
                    0x5 => ops::sub_vx_vy(self, x, y),
                    0x6 => ops::set_vx_to_vx_shr_1(self, x),
                    0xE => ops::set_vx_to_vx_shl_1(self, x),
                    _ => panic!("Unknown 0x8XXX instruction: {:x}", ins)
                }
            },
            0x9 => match n {
                0x0 => ops::skip_next_vx_ne_vy(self, x as usize, y as usize),
                _ => panic!("Unknown 0x9XXX instruction: {:x}", ins)
            },
            0xA => ops::set_i(self, nnn),
            0xC => ops::set_vx_rand_and(self, x as usize, kk),
            0xD => ops::display_sprite(self, x as usize, y as usize, n as usize),
            0xE => match kk {
                0xA1 => ops::skip_next_key_vx_not_pressed(self, x as usize),
                0x9E => ops::skip_next_key_vx_pressed(self, x as usize),
                _ => panic!("Unknown 0xEXXX instruction: {:x}", ins)
            },
            0xF => {
                match kk {
                    0x07 => ops::set_vx_to_delay_timer(self, x as usize),
                    0x0A => ops::wait_for_keypress_store_in_vx(self, x as usize),
                    0x15 => ops::set_delay_timer(self, x as usize),
                    0x18 => ops::set_sound_timer(self, x as usize),
                    0x1E => ops::add_vx_to_i(self, x as usize),
                    0x29 => ops::set_i_to_loc_of_digit_vx(self, x as usize),
                    0x33 => ops::store_bcd_of_vx_to_i(self, x as usize),
                    0x55 => ops::copy_v0_through_vx_to_mem(self, x as usize),
                    0x65 => ops::read_v0_through_vx_from_mem(self, x as usize),
                    _ => panic!("Unknown 0xFXXX instruction: {:x}", ins)
                }
            },
            _ => panic!("Unknown instruction: {:04x}", ins)
        }
    }

    fn fetch_ins(&mut self) -> u16 {
        let b1 = self.ram[self.pc as usize];
        let b2 = self.ram[(self.pc + 1) as usize];
        self.pc += 2;
        (b1 as u16) << 8 | b2 as u16
    }

    /// Press a key on the hexadecimal keypad
    ///
    /// `key` should be in the range `0..15`
    pub fn press_key(&mut self, key: usize) {
        assert!(key <= 15);
        self.keys[key] = true;
        if self.keypress_wait.wait {
            self.v[self.keypress_wait.vx] = key as u8;
            self.keypress_wait.wait = false;
        }
    }

    /// Release a key on the hexadecimal keypad
    ///
    /// `key` should be in the range `0..15`
    pub fn release_key(&mut self, key: usize) {
        assert!(key <= 15);
        self.keys[key] = false;
    }

    /// Decrement the sound and delay timers
    ///
    /// They should be decremented at a rate of 60 Hz
    pub fn decrement_timers(&mut self) {
        if self.delay_timer > 0 {
            self.delay_timer -= 1;
        }
        if self.sound_timer > 0 {
            self.sound_timer -= 1;
        }
    }
}
<commit_msg>Update to latest nightly<commit_after>//! CHIP-8 emulator backend.
//! You can develop your own frontends for it.
//!
//! The reference frontend is
//! [crusty-chip-sfml](https://github.com/crumblingstatue/crusty-chip-sfml).
//!
//! The CHIP-8 technical documentation in the comments is copied from
//! http://devernay.free.fr/hacks/chip8/C8TECH10.HTM,
//! Copyright (c) Thomas P. Greene.

#![feature(core)]

use std::slice::bytes::copy_memory;

mod ops;

const START_ADDR: u16 = 0x200;
const MEM_SIZE: usize = 4096;
pub const DISPLAY_WIDTH: usize = 64;
pub const DISPLAY_HEIGHT: usize = 32;

static FONTSET: [u8; 5 * 0x10] = [
    0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
    0x20, 0x60, 0x20, 0x20, 0x70, // 1
    0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
    0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
    0x90, 0x90, 0xF0, 0x10, 0x10, // 4
    0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
    0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
    0xF0, 0x10, 0x20, 0x40, 0x40, // 7
    0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
    0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
    0xF0, 0x90, 0xF0, 0x90, 0x90, // A
    0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
    0xF0, 0x80, 0x80, 0x80, 0xF0, // C
    0xE0, 0x90, 0x90, 0x90, 0xE0, // D
    0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
    0xF0, 0x80, 0xF0, 0x80, 0x80, // F
];

/// Draw callback.
///
/// Takes a slice of u8, where each u8 is a pixel.
///
/// A **non-zero** pixel is visible, a **zero** pixel is not visible.
///
/// The coordinate system is from top-left to bottom-right.
///
/// Example:
///
/// ```rust
///     use crusty_chip::{ DISPLAY_WIDTH, VirtualMachine };
///     // Dump the pixels to stdout
///     fn dump_pixels(pixels: &[u8]) {
///         for (i, px) in pixels.iter().enumerate() {
///             match *px {
///                 0 => print!(" "),
///                 _ => print!("#")
///             }
///             if i % DISPLAY_WIDTH == 0 {
///                 print!("\n");
///             }
///         }
///     }
///     let mut f: fn(&[u8]) = dump_pixels;
///     let mut ch8 = VirtualMachine::new(&mut f);
///     // ...
/// ```
pub type DrawCallback<'a> = FnMut(&[u8]) + 'a;

struct KeypressWait {
    wait: bool,
    vx: usize
}

/// CHIP-8 virtual machine
pub struct VirtualMachine<'a> {
    ram: [u8; MEM_SIZE],
    v: [u8; 16],
    i: u16,
    delay_timer: u8,
    sound_timer: u8,
    pc: u16,
    sp: u8,
    stack: [u16; 16],
    display: [u8; DISPLAY_WIDTH * DISPLAY_HEIGHT],
    draw_callback: &'a mut DrawCallback<'a>,
    keys: [bool; 16],
    keypress_wait: KeypressWait
}

impl <'a> VirtualMachine <'a> {

    /// Constructs a new `VirtualMachine`.
    ///
    /// ## Arguments ##
    /// * draw_callback - Callback used when drawing
    pub fn new(draw_callback: &'a mut DrawCallback<'a>) -> VirtualMachine<'a> {
        let mut ch8 = VirtualMachine {
            ram: [0; MEM_SIZE],
            v: [0; 16],
            i: 0,
            delay_timer: 0,
            sound_timer: 0,
            pc: START_ADDR,
            sp: 0,
            stack: [0; 16],
            display: [0; DISPLAY_WIDTH * DISPLAY_HEIGHT],
            draw_callback: draw_callback,
            keys: [false; 16],
            keypress_wait: KeypressWait {
                wait: false,
                vx: 0
            }
        };
        copy_memory(&FONTSET, &mut ch8.ram[0usize..5 * 0x10]);
        ch8
    }

    /// Load a ROM
    ///
    /// ## Arguments ##
    /// * rom - ROM to load
    pub fn load_rom(&mut self, rom: &[u8]) {
        let len = self.ram.len();
        copy_memory(rom, &mut self.ram[START_ADDR as usize .. len]);
    }

    /// Do an emulation cycle.
    pub fn do_cycle(&mut self) {
        if self.keypress_wait.wait {
            return;
        }

        let ins = self.fetch_ins();
        self.dispatch(ins);
    }

    // Decode instruction and execute it
    fn dispatch(&mut self, ins: u16) {
        // A 12-bit value, the lowest 12 bits of the instruction
        let nnn = ins & 0x0FFF;
        // A 4-bit value, the lowest 4 bits of the instruction
        let n = ins & 0x000F;
        // A 4-bit value, the lower 4 bits of the high byte of the instruction
        let x = (ins & 0x0F00) >> 8;
        // A 4-bit value, the upper 4 bits of the low byte of the instruction
        let y = (ins & 0x00F0) >> 4;
        // kk or byte - An 8-bit value, the lowest 8 bits of the instruction
        let kk = (ins & 0x00FF) as u8;

        match (ins & 0xF000) >> 12 {
            0x0 => match nnn {
                0x0E0 => ops::clear_display(self, ),
                0x0EE => ops::ret_from_subroutine(self, ),
                _ => ops::jump_to_sys_routine(self, 0)
            },
            0x1 => ops::jump_addr(self, nnn),
            0x2 => ops::call_subroutine(self, nnn as usize),
            0x3 => ops::skip_next_vx_eq(self, x as usize, kk),
            0x4 => ops::skip_next_vx_ne(self, x as usize, kk),
            0x5 => match n {
                0x0 => ops::skip_next_vx_eq_vy(self, x as usize, y as usize),
                _ => panic!("Unknown 0x5XXX instruction: {:x}", ins)
            },
            0x6 => ops::set_vx_byte(self, x as usize, kk),
            0x7 => ops::add_vx_byte(self, x as usize, kk),
            0x8 => {
                let (x, y) = (x as usize, y as usize);
                match n {
                    0x0 => ops::set_vx_to_vy(self, x, y),
                    0x1 => ops::set_vx_to_vx_or_vy(self, x, y),
                    0x2 => ops::set_vx_to_vx_and_vy(self, x, y),
                    0x3 => ops::set_vx_to_vx_xor_vy(self, x, y),
                    0x4 => ops::add_vx_vy(self, x, y),
                    0x5 => ops::sub_vx_vy(self, x, y),
                    0x6 => ops::set_vx_to_vx_shr_1(self, x),
                    0xE => ops::set_vx_to_vx_shl_1(self, x),
                    _ => panic!("Unknown 0x8XXX instruction: {:x}", ins)
                }
            },
            0x9 => match n {
                0x0 => ops::skip_next_vx_ne_vy(self, x as usize, y as usize),
                _ => panic!("Unknown 0x9XXX instruction: {:x}", ins)
            },
            0xA => ops::set_i(self, nnn),
            0xC => ops::set_vx_rand_and(self, x as usize, kk),
            0xD => ops::display_sprite(self, x as usize, y as usize, n as usize),
            0xE => match kk {
                0xA1 => ops::skip_next_key_vx_not_pressed(self, x as usize),
                0x9E => ops::skip_next_key_vx_pressed(self, x as usize),
                _ => panic!("Unknown 0xEXXX instruction: {:x}", ins)
            },
            0xF => {
                match kk {
                    0x07 => ops::set_vx_to_delay_timer(self, x as usize),
                    0x0A => ops::wait_for_keypress_store_in_vx(self, x as usize),
                    0x15 => ops::set_delay_timer(self, x as usize),
                    0x18 => ops::set_sound_timer(self, x as usize),
                    0x1E => ops::add_vx_to_i(self, x as usize),
                    0x29 => ops::set_i_to_loc_of_digit_vx(self, x as usize),
                    0x33 => ops::store_bcd_of_vx_to_i(self, x as usize),
                    0x55 => ops::copy_v0_through_vx_to_mem(self, x as usize),
                    0x65 => ops::read_v0_through_vx_from_mem(self, x as usize),
                    _ => panic!("Unknown 0xFXXX instruction: {:x}", ins)
                }
            },
            _ => panic!("Unknown instruction: {:04x}", ins)
        }
    }

    fn fetch_ins(&mut self) -> u16 {
        let b1 = self.ram[self.pc as usize];
        let b2 = self.ram[(self.pc + 1) as usize];
        self.pc += 2;
        (b1 as u16) << 8 | b2 as u16
    }

    /// Press a key on the hexadecimal keypad
    ///
    /// `key` should be in the range `0..15`
    pub fn press_key(&mut self, key: usize) {
        assert!(key <= 15);
        self.keys[key] = true;
        if self.keypress_wait.wait {
            self.v[self.keypress_wait.vx] = key as u8;
            self.keypress_wait.wait = false;
        }
    }

    /// Release a key on the hexadecimal keypad
    ///
    /// `key` should be in the range `0..15`
    pub fn release_key(&mut self, key: usize) {
        assert!(key <= 15);
        self.keys[key] = false;
    }

    /// Decrement the sound and delay timers
    ///
    /// They should be decremented at a rate of 60 Hz
    pub fn decrement_timers(&mut self) {
        if self.delay_timer > 0 {
            self.delay_timer -= 1;
        }
        if self.sound_timer > 0 {
            self.sound_timer -= 1;
        }
    }
}
<|endoftext|>


<commit_before>extern crate image;
extern crate libc;
extern crate rust_resemble as resemble;

use libc::{c_double, size_t};
use image::load_from_memory;
use std::mem::forget;

#[no_mangle]
pub extern "C" fn compare_images(img1: *const u8,
                                 img1_length: size_t,
                                 img2: *const u8,
                                 img2_length: size_t)
                                 -> c_double {

    let v1;
    let v2;

    unsafe {
        v1 = std::slice::from_raw_parts(img1, img1_length);
        v2 = std::slice::from_raw_parts(img2, img2_length);
    }

    let img1 = load_from_memory(v1).unwrap();
    let img2 = load_from_memory(v2).unwrap();
    let opts = resemble::ComparisonOptions::new().ignore_antialiasing();

    let r = resemble::compare_images(&img1, &img2, &opts);

    forget(img1);   // do not free that memory
    forget(img2);   // do not free that memory

    r.mismatch_percent
}<commit_msg>Revert "attempt to fix an issue with nodejs 7.6"<commit_after>extern crate image;
extern crate libc;
extern crate rust_resemble as resemble;

use libc::{c_double, size_t};
use image::load_from_memory;

#[no_mangle]
pub extern "C" fn compare_images(img1: *const u8,
                                 img1_length: size_t,
                                 img2: *const u8,
                                 img2_length: size_t)
                                 -> c_double {

    let v1;
    let v2;

    unsafe {
        v1 = std::slice::from_raw_parts(img1, img1_length);
        v2 = std::slice::from_raw_parts(img2, img2_length);
    }

    let img1 = load_from_memory(v1).unwrap();
    let img2 = load_from_memory(v2).unwrap();
    let opts = resemble::ComparisonOptions::new().ignore_antialiasing();

    let r = resemble::compare_images(&img1, &img2, &opts);
    r.mismatch_percent
}<|endoftext|>


<commit_before>#[crate_id = "fragments#0.1-pre"];

#[comment = "A simple template library for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "rlib"];

extern crate collections;

use std::fmt;
use std::from_str::FromStr;
use std::io::BufReader;
use collections::hashmap::{HashMap, HashSet};

type ParserState = Option<fn(&mut Buffer) -> ParserResult>;

struct ParserResult {
	token: Token,
	next_parser: ParserState
}

#[deriving(Eq, TotalEq, Show)]
enum Token {
	String(~str),
	Placeholder(~str),
	Conditional(~str, bool, ~[Token])
}

///A string template with placeholders and conditional content.
///
///Placeholders are written as `[[:label]]`, where `label` becomes the name of the placeholder.
///The label is then used to insert content: `my_template.insert(~"label", my_content);`.
///The assigned content for a placeholder can be anything that implements `Show`.
///Even other templates may be inserted, which allows a more atomic structure.
///
///Conditional segments are surrounded by `[[?label]]...[[/]]`, where `label` becomes the name of the condition,
///and they are used to display content depending on whether its label exists in the `conditions` set.
///`[[/]]` marks the end of a block and may contain other characters after the `/`, which may be useful for labeling the end mark.
///Conditions can be made negative by writing `[[?!label]]...[[/]]`, which makes the content visible if the label
///is missing from the `conditions` set.
///
///Any character can be escaped by writing `\` before it. It can be used like this: `\[[[:label1]], [[:label2]]]`
///which will result in `[content1, content2]`, since the first `[` will be ignored by the parser and just added to the
///rest of the content.
pub struct Template {
	///Content for the placeholders
	content: ~HashMap<~str, ~fmt::Show>,
	///Conditional switches
	conditions: ~HashSet<~str>,
	priv tokens: ~[Token]
}

impl Template {
	pub fn from_buffer(b: &mut Buffer) -> Template {
		Template {
			content: ~HashMap::new(),
			conditions: ~HashSet::new(),
			tokens: parse_block(b)
		}
	}

	///Convenience method for inserting content.
	pub fn insert<T: fmt::Show + Send>(&mut self, placeholder: ~str, item: ~T) {
		self.content.insert(placeholder, item as ~fmt::Show);
	}

	fn format_tokens(&self, tokens: &[Token], f: &mut fmt::Formatter) -> fmt::Result {
		for token in tokens.iter() {
			let res = match token {
				&String(ref s) => f.buf.write_str(*s),

				&Placeholder(ref k) => {
					match self.content.find(k) {
						Some(value) => value.fmt(f),
						None => Ok(())
					}
				},

				&Conditional(ref k, expected, ref tokens) => {
					if self.conditions.contains(k) == expected {
						self.format_tokens(*tokens, f)
					} else {
						Ok(())
					}
				}
			};

			match res {
				Err(e) => return Err(e),
				_ => {}
			}
		}

		Ok(())
	}
}

impl FromStr for Template {
	///Creates a new `Template` from a string.
	fn from_str(s: &str) -> Option<Template> {
		Some(Template::from_buffer(&mut BufReader::new(s.as_bytes())))
	}
}

impl fmt::Show for Template {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		self.format_tokens(self.tokens, f)
	}
}

fn parse_block(b: &mut Buffer) -> ~[Token] {
	let mut tokens = ~[];
	let mut parser = parse_string;

	loop {
		let ParserResult{token: token, next_parser: next} = parser(b);

		tokens.push(token);

		match next {
			Some(p) => parser = p,
			None => break
		}
	}

	tokens
}

fn parse_string(b: &mut Buffer) -> ParserResult {
	let mut content = ~"";

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						content.push_char(c);
					},
					_ => break
				}
			},
			Ok('[') => {
				match b.read_char() {
					Ok('[') => {
						match b.read_char() {
							Ok(':') => return ParserResult{
								token: String(content),
								next_parser: Some(parse_placeholder)
							},
							Ok('?') => return ParserResult{
								token: String(content),
								next_parser: Some(parse_conditional)
							},
							Ok('/') => {
								skip_to_token_end(b);

								return ParserResult{
									token: String(content),
									next_parser: None
								}
							},
							_ => break
						}
					},
					Ok(c) => {
						content.push_char('[');
						content.push_char(c);
					},
					Err(_) => content.push_char('[')
				}
			},
			Ok(c) => content.push_char(c),
			Err(_) => break
		}
	}

	ParserResult{
		token: String(content),
		next_parser: None
	}
}

fn skip_to_token_end(b: &mut Buffer) {
	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(_) => {},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => break,
					_ => {}
				}
			},
			Err(_) => break,
			_ => {}
		}
	}
}

fn parse_placeholder(b: &mut Buffer) -> ParserResult {
	let mut label = ~"";

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						label.push_char(c);
					},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => {
						return ParserResult{
							token: Placeholder(label),
							next_parser: Some(parse_string)
						}
					},
					Ok(c) => {
						label.push_char(']');
						label.push_char(c);
					},
					Err(_) => label.push_char(']')
				}
			},
			Ok(c) => label.push_char(c),
			Err(_) => break
		}
	}

	ParserResult{
		token: Placeholder(label),
		next_parser: None
	}
}

fn parse_conditional(b: &mut Buffer) -> ParserResult {
	let mut label = ~"";
	let mut expected = true;
	let mut expected_set = false;

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						label.push_char(c);
					},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => {
						return ParserResult{
							token: Conditional(label, expected, parse_block(b)),
							next_parser: Some(parse_string)
						}
					},
					Ok(c) => {
						label.push_char(']');
						label.push_char(c);
					},
					Err(_) => label.push_char(']')
				}
			},
			Ok('!') => {
				if label.len() == 0 && !expected_set {
					expected = false;
					expected_set = true;
				} else {
					label.push_char('!');
				}
			},
			Ok(c) => {
				label.push_char(c)
			},
			Err(_) => break
		}
	}

	ParserResult{
		token: Conditional(label, expected, ~[]),
		next_parser: None
	}
}

#[cfg(test)]
mod test {
	use super::{Template, Placeholder, String};

	#[test]
	fn basic_tokens() {
		let template: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}

	#[test]
	fn strange_tokens() {
		let template: Template = from_str("Hello, [[[:name]]]! This is a [[[[:something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
	}

	#[test]
	fn escaped_tokens() {
		let template: Template = from_str("Hello, [[:name]]! Write placeholders like \\[[:this]] and escape them like \\\\\\[[:this]]").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! Write placeholders like [[:this]] and escape them like \\[[:this]]"));
	}

	#[test]
	fn replacement() {
		let mut template: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		template.insert(~"name", ~("Peter"));
		template.insert(~"something", ~("nice"));
		assert_eq!(template.to_str(), ~"Hello, Peter! This is a nice template.");
	}

	#[test]
	fn templates_in_templates() {
		let mut template1: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		let mut template2: ~Template = ~from_str("really [[:something]]").unwrap();
		template1.insert(~"name", ~("Peter"));
		template2.insert(~"something", ~("nice"));

		template1.insert(~"something", template2);

		assert_eq!(template1.to_str(), ~"Hello, Peter! This is a really nice template.");
	}

	#[test]
	fn conditional() {
		let mut template: Template = from_str("Hello, [[:name]]![[?condition]] The condition is true.[[/condition]]").unwrap();
		template.insert(~"name", ~("Peter"));
		assert_eq!(template.to_str(), ~"Hello, Peter!");
		template.conditions.insert(~"condition");
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is true.");
	}

	#[test]
	fn conditional_switch() {
		let mut template: Template = from_str("Hello, [[:name]]! The condition is [[?condition]]true[[/condition]][[?!condition]]false[[/condition]].").unwrap();
		template.insert(~"name", ~("Peter"));
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is false.");
		template.conditions.insert(~"condition");
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is true.");
	}
}<commit_msg>Added convenience method for setting conditions<commit_after>#[crate_id = "fragments#0.1-pre"];

#[comment = "A simple template library for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "rlib"];

extern crate collections;

use std::fmt;
use std::from_str::FromStr;
use std::io::BufReader;
use collections::hashmap::{HashMap, HashSet};

type ParserState = Option<fn(&mut Buffer) -> ParserResult>;

struct ParserResult {
	token: Token,
	next_parser: ParserState
}

#[deriving(Eq, TotalEq, Show)]
enum Token {
	String(~str),
	Placeholder(~str),
	Conditional(~str, bool, ~[Token])
}

///A string template with placeholders and conditional content.
///
///Placeholders are written as `[[:label]]`, where `label` becomes the name of the placeholder.
///The label is then used to insert content: `my_template.insert(~"label", my_content);`.
///The assigned content for a placeholder can be anything that implements `Show`.
///Even other templates may be inserted, which allows a more atomic structure.
///
///Conditional segments are surrounded by `[[?label]]...[[/]]`, where `label` becomes the name of the condition,
///and they are used to display content depending on whether its label exists in the `conditions` set.
///`[[/]]` marks the end of a block and may contain other characters after the `/`, which may be useful for labeling the end mark.
///Conditions can be made negative by writing `[[?!label]]...[[/]]`, which makes the content visible if the label
///is missing from the `conditions` set.
///
///Any character can be escaped by writing `\` before it. It can be used like this: `\[[[:label1]], [[:label2]]]`
///which will result in `[content1, content2]`, since the first `[` will be ignored by the parser and just added to the
///rest of the content.
pub struct Template {
	///Content for the placeholders
	content: ~HashMap<~str, ~fmt::Show>,
	///Conditional switches
	conditions: ~HashSet<~str>,
	priv tokens: ~[Token]
}

impl Template {
	pub fn from_buffer(b: &mut Buffer) -> Template {
		Template {
			content: ~HashMap::new(),
			conditions: ~HashSet::new(),
			tokens: parse_block(b)
		}
	}

	///Convenience method for inserting content.
	pub fn insert<T: fmt::Show + Send>(&mut self, placeholder: ~str, item: ~T) {
		self.content.insert(placeholder, item as ~fmt::Show);
	}

	///Convenience method for setting a condition.
	pub fn set(&mut self, condition: ~str, value: bool) {
		if value {
			self.conditions.insert(condition);
		} else {
			self.conditions.remove(&condition);
		}
	}

	fn format_tokens(&self, tokens: &[Token], f: &mut fmt::Formatter) -> fmt::Result {
		for token in tokens.iter() {
			let res = match token {
				&String(ref s) => f.buf.write_str(*s),

				&Placeholder(ref k) => {
					match self.content.find(k) {
						Some(value) => value.fmt(f),
						None => Ok(())
					}
				},

				&Conditional(ref k, expected, ref tokens) => {
					if self.conditions.contains(k) == expected {
						self.format_tokens(*tokens, f)
					} else {
						Ok(())
					}
				}
			};

			match res {
				Err(e) => return Err(e),
				_ => {}
			}
		}

		Ok(())
	}
}

impl FromStr for Template {
	///Creates a new `Template` from a string.
	fn from_str(s: &str) -> Option<Template> {
		Some(Template::from_buffer(&mut BufReader::new(s.as_bytes())))
	}
}

impl fmt::Show for Template {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		self.format_tokens(self.tokens, f)
	}
}

fn parse_block(b: &mut Buffer) -> ~[Token] {
	let mut tokens = ~[];
	let mut parser = parse_string;

	loop {
		let ParserResult{token: token, next_parser: next} = parser(b);

		tokens.push(token);

		match next {
			Some(p) => parser = p,
			None => break
		}
	}

	tokens
}

fn parse_string(b: &mut Buffer) -> ParserResult {
	let mut content = ~"";

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						content.push_char(c);
					},
					_ => break
				}
			},
			Ok('[') => {
				match b.read_char() {
					Ok('[') => {
						match b.read_char() {
							Ok(':') => return ParserResult{
								token: String(content),
								next_parser: Some(parse_placeholder)
							},
							Ok('?') => return ParserResult{
								token: String(content),
								next_parser: Some(parse_conditional)
							},
							Ok('/') => {
								skip_to_token_end(b);

								return ParserResult{
									token: String(content),
									next_parser: None
								}
							},
							_ => break
						}
					},
					Ok(c) => {
						content.push_char('[');
						content.push_char(c);
					},
					Err(_) => content.push_char('[')
				}
			},
			Ok(c) => content.push_char(c),
			Err(_) => break
		}
	}

	ParserResult{
		token: String(content),
		next_parser: None
	}
}

fn skip_to_token_end(b: &mut Buffer) {
	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(_) => {},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => break,
					_ => {}
				}
			},
			Err(_) => break,
			_ => {}
		}
	}
}

fn parse_placeholder(b: &mut Buffer) -> ParserResult {
	let mut label = ~"";

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						label.push_char(c);
					},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => {
						return ParserResult{
							token: Placeholder(label),
							next_parser: Some(parse_string)
						}
					},
					Ok(c) => {
						label.push_char(']');
						label.push_char(c);
					},
					Err(_) => label.push_char(']')
				}
			},
			Ok(c) => label.push_char(c),
			Err(_) => break
		}
	}

	ParserResult{
		token: Placeholder(label),
		next_parser: None
	}
}

fn parse_conditional(b: &mut Buffer) -> ParserResult {
	let mut label = ~"";
	let mut expected = true;
	let mut expected_set = false;

	loop {
		match b.read_char() {
			Ok('\\') => {
				match b.read_char() {
					Ok(c) => {
						label.push_char(c);
					},
					_ => break
				}
			},
			Ok(']') => {
				match b.read_char() {
					Ok(']') => {
						return ParserResult{
							token: Conditional(label, expected, parse_block(b)),
							next_parser: Some(parse_string)
						}
					},
					Ok(c) => {
						label.push_char(']');
						label.push_char(c);
					},
					Err(_) => label.push_char(']')
				}
			},
			Ok('!') => {
				if label.len() == 0 && !expected_set {
					expected = false;
					expected_set = true;
				} else {
					label.push_char('!');
				}
			},
			Ok(c) => {
				label.push_char(c)
			},
			Err(_) => break
		}
	}

	ParserResult{
		token: Conditional(label, expected, ~[]),
		next_parser: None
	}
}

#[cfg(test)]
mod test {
	use super::{Template, Placeholder, String};

	#[test]
	fn basic_tokens() {
		let template: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}

	#[test]
	fn strange_tokens() {
		let template: Template = from_str("Hello, [[[:name]]]! This is a [[[[:something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
	}

	#[test]
	fn escaped_tokens() {
		let template: Template = from_str("Hello, [[:name]]! Write placeholders like \\[[:this]] and escape them like \\\\\\[[:this]]").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! Write placeholders like [[:this]] and escape them like \\[[:this]]"));
	}

	#[test]
	fn replacement() {
		let mut template: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		template.insert(~"name", ~("Peter"));
		template.insert(~"something", ~("nice"));
		assert_eq!(template.to_str(), ~"Hello, Peter! This is a nice template.");
	}

	#[test]
	fn templates_in_templates() {
		let mut template1: Template = from_str("Hello, [[:name]]! This is a [[:something]] template.").unwrap();
		let mut template2: ~Template = ~from_str("really [[:something]]").unwrap();
		template1.insert(~"name", ~("Peter"));
		template2.insert(~"something", ~("nice"));

		template1.insert(~"something", template2);

		assert_eq!(template1.to_str(), ~"Hello, Peter! This is a really nice template.");
	}

	#[test]
	fn conditional() {
		let mut template: Template = from_str("Hello, [[:name]]![[?condition]] The condition is true.[[/condition]]").unwrap();
		template.insert(~"name", ~("Peter"));
		assert_eq!(template.to_str(), ~"Hello, Peter!");
		template.set(~"condition", true);
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is true.");
	}

	#[test]
	fn conditional_switch() {
		let mut template: Template = from_str("Hello, [[:name]]! The condition is [[?condition]]true[[/condition]][[?!condition]]false[[/condition]].").unwrap();
		template.insert(~"name", ~("Peter"));
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is false.");
		template.set(~"condition", true);
		assert_eq!(template.to_str(), ~"Hello, Peter! The condition is true.");
	}
}<|endoftext|>


<commit_before>use std::ptr;

pub type TssHContext = u32;
pub type TssHTPM = u32;
pub type TssResult = u32;
pub type TssUnicode = u16;

pub const TSS_SUCCESS: TssResult = 0;

pub struct TssContext {
    pub handle: u32
}
pub struct TssTpm<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Connect(phContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_GetTpmObject(phContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_Context_FreeMemory(phContext: TssHContext, rgbMemory: *mut u8) -> TssResult;
    fn Tspi_Context_Close(phContext: TssHContext) -> TssResult;
    fn Tspi_TPM_PcrRead(hTPM: TssHTPM, ulPcrIndex: u32, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
}

impl TssContext {
    pub fn new() -> Result<TssContext, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_Create(&mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssContext { handle: handle })
    }

    // TODO: support destination
    pub fn connect(&self) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_Context_Connect(self.handle, ptr::null())
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }

    pub fn get_tpm_object(&self) -> Result<TssTpm, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_GetTpmObject(self.handle, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssTpm { context: self, handle: handle })
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_FreeMemory(self.handle, 0 as *mut u8);
            Tspi_Context_Close(self.handle);
        }
    }
}

impl<'context> TssTpm<'context> {
    pub fn pcr_read(&self, pcr_index: u32) -> Result<Vec<u8>, TssResult> {
        let mut ulPcrValueLength = -1;
        let mut pRgbPcrValue = 0 as *mut u8;
        let result = unsafe {
            Tspi_TPM_PcrRead(self.handle, pcr_index, &mut ulPcrValueLength, &mut pRgbPcrValue)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        let mut vec = Vec::new();
        unsafe {
            for i in 0..ulPcrValueLength {
                vec.push(*pRgbPcrValue.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pRgbPcrValue);
        }
        Ok(vec)
    }
}
<commit_msg>Rename TssTpm to TssTPM<commit_after>use std::ptr;

pub type TssHContext = u32;
pub type TssHTPM = u32;
pub type TssResult = u32;
pub type TssUnicode = u16;

pub const TSS_SUCCESS: TssResult = 0;

pub struct TssContext {
    pub handle: u32
}
pub struct TssTPM<'context> {
    pub context: &'context TssContext,
    pub handle: u32
}

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Connect(phContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_GetTpmObject(phContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_Context_FreeMemory(phContext: TssHContext, rgbMemory: *mut u8) -> TssResult;
    fn Tspi_Context_Close(phContext: TssHContext) -> TssResult;
    fn Tspi_TPM_PcrRead(hTPM: TssHTPM, ulPcrIndex: u32, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
}

impl TssContext {
    pub fn new() -> Result<TssContext, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_Create(&mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssContext { handle: handle })
    }

    // TODO: support destination
    pub fn connect(&self) -> Result<(), TssResult> {
        let result = unsafe {
            Tspi_Context_Connect(self.handle, ptr::null())
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(())
    }

    pub fn get_tpm_object(&self) -> Result<TssTPM, TssResult> {
        let mut handle = 0;
        let result = unsafe {
            Tspi_Context_GetTpmObject(self.handle, &mut handle)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        Ok(TssTPM { context: self, handle: handle })
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_FreeMemory(self.handle, 0 as *mut u8);
            Tspi_Context_Close(self.handle);
        }
    }
}

impl<'context> TssTPM<'context> {
    pub fn pcr_read(&self, pcr_index: u32) -> Result<Vec<u8>, TssResult> {
        let mut ulPcrValueLength = -1;
        let mut pRgbPcrValue = 0 as *mut u8;
        let result = unsafe {
            Tspi_TPM_PcrRead(self.handle, pcr_index, &mut ulPcrValueLength, &mut pRgbPcrValue)
        };
        if result != TSS_SUCCESS {
            return Err(result);
        }
        let mut vec = Vec::new();
        unsafe {
            for i in 0..ulPcrValueLength {
                vec.push(*pRgbPcrValue.offset(i as isize));
            }
            Tspi_Context_FreeMemory(self.context.handle, pRgbPcrValue);
        }
        Ok(vec)
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate bitflags;

#[cfg(feature = "glium")]
#[macro_use]
extern crate glium;

extern crate libc;

#[cfg(feature = "sdl2")]
extern crate sdl2;

use libc::{c_float, c_int, c_uchar};
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;

pub use ffi::{ImDrawIdx, ImDrawVert, ImVec2, ImVec4};

pub mod ffi;

#[cfg(feature = "glium")]
pub mod glium_renderer;

pub struct ImGui;

pub struct TextureHandle<'a> {
   pub width: u32,
   pub height: u32,
   pub pixels: &'a [c_uchar]
}

impl ImGui {
   pub fn init() -> ImGui {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.render_draw_lists_fn = Some(render_draw_lists);

      ImGui
   }
   pub fn prepare_texture<'a, F, T>(&mut self, f: F) -> T where F: FnOnce(TextureHandle<'a>) -> T {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      let mut pixels: *mut c_uchar = ptr::null_mut();
      let mut width: c_int = 0;
      let mut height: c_int = 0;
      let mut bytes_per_pixel: c_int = 0;
      unsafe {
         ffi::ImFontAtlas_GetTexDataAsRGBA32(io.fonts, &mut pixels, &mut width, &mut height, &mut bytes_per_pixel);
         f(TextureHandle {
            width: width as u32,
            height: height as u32,
            pixels: slice::from_raw_parts(pixels, (width * height * bytes_per_pixel) as usize)
         })
      }
   }
   pub fn draw_mouse_cursor(&mut self, value: bool) {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_draw_cursor = value;
   }
   #[cfg(feature = "sdl2")]
   pub fn update_mouse(&mut self, mouse: &::sdl2::mouse::MouseUtil) {
      let (mouse_state, mouse_x, mouse_y) = mouse.get_mouse_state();
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_pos.x = mouse_x as f32;
      io.mouse_pos.y = mouse_y as f32;
      io.mouse_down = [
         mouse_state.left(),
         mouse_state.right(),
         mouse_state.middle(),
         mouse_state.x1(),
         mouse_state.x2()
      ];
   }
   pub fn frame<'a>(&'a mut self, width: u32, height: u32, delta_time: f32) -> Frame<'a> {
      unsafe {
         let io: &mut ffi::ImGuiIO = mem::transmute(ffi::igGetIO());
         io.display_size.x = width as c_float;
         io.display_size.y = height as c_float;
         io.delta_time = delta_time;

         ffi::igNewFrame();
      }
      Frame {
         _phantom: PhantomData
      }
   }
}

impl Drop for ImGui {
   fn drop(&mut self) {
      unsafe {
         ffi::igShutdown();
      }
   }
}

pub struct DrawList<'a> {
   pub cmd_buffer: &'a [ffi::ImDrawCmd],
   pub idx_buffer: &'a [ffi::ImDrawIdx],
   pub vtx_buffer: &'a [ffi::ImDrawVert]
}

pub struct Frame<'a> {
   _phantom: PhantomData<&'a ImGui>
}

impl<'a> Frame<'a> {
   pub fn show_test_window(&mut self) -> bool {
      let mut opened = true;
      unsafe {
         ffi::igShowTestWindow(&mut opened);
      }
      opened
   }
   pub fn render<F, E>(self, mut f: F) -> Result<(), E>
         where F: FnMut(DrawList<'a>) -> Result<(), E> {
      unsafe {
         let mut im_draw_data = mem::zeroed();
         RENDER_DRAW_LISTS_STATE.0 = &mut im_draw_data;
         ffi::igRender();
         RENDER_DRAW_LISTS_STATE.0 = 0 as *mut ffi::ImDrawData;

         for &cmd_list in im_draw_data.cmd_lists() {
            let draw_list =
               DrawList {
                  cmd_buffer: (*cmd_list).cmd_buffer.as_slice(),
                  idx_buffer: (*cmd_list).idx_buffer.as_slice(),
                  vtx_buffer: (*cmd_list).vtx_buffer.as_slice()
               };
            try!(f(draw_list));
         }
      }
      Ok(())
   }
}

struct RenderDrawListsState(*mut ffi::ImDrawData);
unsafe impl Sync for RenderDrawListsState {}

static mut RENDER_DRAW_LISTS_STATE: RenderDrawListsState =
   RenderDrawListsState(0 as *mut ffi::ImDrawData);

extern "C" fn render_draw_lists(data: *mut ffi::ImDrawData) {
   unsafe {
      ptr::copy_nonoverlapping(data, RENDER_DRAW_LISTS_STATE.0, 1);
   }
}
<commit_msg>Basic mouse support<commit_after>#[macro_use]
extern crate bitflags;

#[cfg(feature = "glium")]
#[macro_use]
extern crate glium;

extern crate libc;

#[cfg(feature = "sdl2")]
extern crate sdl2;

use libc::{c_float, c_int, c_uchar};
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;

pub use ffi::{ImDrawIdx, ImDrawVert, ImVec2, ImVec4};

pub mod ffi;

#[cfg(feature = "glium")]
pub mod glium_renderer;

pub struct ImGui;

pub struct TextureHandle<'a> {
   pub width: u32,
   pub height: u32,
   pub pixels: &'a [c_uchar]
}

impl ImGui {
   pub fn init() -> ImGui {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.render_draw_lists_fn = Some(render_draw_lists);

      ImGui
   }
   pub fn prepare_texture<'a, F, T>(&mut self, f: F) -> T where F: FnOnce(TextureHandle<'a>) -> T {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      let mut pixels: *mut c_uchar = ptr::null_mut();
      let mut width: c_int = 0;
      let mut height: c_int = 0;
      let mut bytes_per_pixel: c_int = 0;
      unsafe {
         ffi::ImFontAtlas_GetTexDataAsRGBA32(io.fonts, &mut pixels, &mut width, &mut height, &mut bytes_per_pixel);
         f(TextureHandle {
            width: width as u32,
            height: height as u32,
            pixels: slice::from_raw_parts(pixels, (width * height * bytes_per_pixel) as usize)
         })
      }
   }
   pub fn draw_mouse_cursor(&mut self, value: bool) {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_draw_cursor = value;
   }
   #[cfg(feature = "sdl2")]
   pub fn update_mouse(&mut self, mouse: &::sdl2::mouse::MouseUtil) {
      let (mouse_state, mouse_x, mouse_y) = mouse.get_mouse_state();
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_pos.x = mouse_x as f32;
      io.mouse_pos.y = mouse_y as f32;
      io.mouse_down = [
         mouse_state.left(),
         mouse_state.right(),
         mouse_state.middle(),
         mouse_state.x1(),
         mouse_state.x2()
      ];
   }
   pub fn set_mouse_pos(&mut self, x: f32, y: f32) {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_pos.x = x;
      io.mouse_pos.y = y;
   }
   pub fn set_mouse_down(&mut self, states: &[bool; 5]) {
      let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
      io.mouse_down = *states;
   }
   pub fn frame<'a>(&'a mut self, width: u32, height: u32, delta_time: f32) -> Frame<'a> {
      unsafe {
         let io: &mut ffi::ImGuiIO = mem::transmute(ffi::igGetIO());
         io.display_size.x = width as c_float;
         io.display_size.y = height as c_float;
         io.delta_time = delta_time;

         ffi::igNewFrame();
      }
      Frame {
         _phantom: PhantomData
      }
   }
}

impl Drop for ImGui {
   fn drop(&mut self) {
      unsafe {
         ffi::igShutdown();
      }
   }
}

pub struct DrawList<'a> {
   pub cmd_buffer: &'a [ffi::ImDrawCmd],
   pub idx_buffer: &'a [ffi::ImDrawIdx],
   pub vtx_buffer: &'a [ffi::ImDrawVert]
}

pub struct Frame<'a> {
   _phantom: PhantomData<&'a ImGui>
}

impl<'a> Frame<'a> {
   pub fn show_test_window(&mut self) -> bool {
      let mut opened = true;
      unsafe {
         ffi::igShowTestWindow(&mut opened);
      }
      opened
   }
   pub fn render<F, E>(self, mut f: F) -> Result<(), E>
         where F: FnMut(DrawList<'a>) -> Result<(), E> {
      unsafe {
         let mut im_draw_data = mem::zeroed();
         RENDER_DRAW_LISTS_STATE.0 = &mut im_draw_data;
         ffi::igRender();
         RENDER_DRAW_LISTS_STATE.0 = 0 as *mut ffi::ImDrawData;

         for &cmd_list in im_draw_data.cmd_lists() {
            let draw_list =
               DrawList {
                  cmd_buffer: (*cmd_list).cmd_buffer.as_slice(),
                  idx_buffer: (*cmd_list).idx_buffer.as_slice(),
                  vtx_buffer: (*cmd_list).vtx_buffer.as_slice()
               };
            try!(f(draw_list));
         }
      }
      Ok(())
   }
}

struct RenderDrawListsState(*mut ffi::ImDrawData);
unsafe impl Sync for RenderDrawListsState {}

static mut RENDER_DRAW_LISTS_STATE: RenderDrawListsState =
   RenderDrawListsState(0 as *mut ffi::ImDrawData);

extern "C" fn render_draw_lists(data: *mut ffi::ImDrawData) {
   unsafe {
      ptr::copy_nonoverlapping(data, RENDER_DRAW_LISTS_STATE.0, 1);
   }
}
<|endoftext|>


<commit_before>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinNode {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinNode {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinNode {
        BinNode {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Call closure for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v == true)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinNode>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinNode::from_pairs(pairs));
    }

    /// Returns true if the graph contains a choice.
    pub fn contains_choice(&self, state: &BinNode, i: uint) -> bool {
        self.data.iter().any(|st|
            range(0, st.choices.len()).all(|j|
                state.choices.get(j) == if j == i {
                        !state.choices.get(j)
                    } else {
                        state.choices.get(j)
                    }
            )
        )
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinNode {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinNode::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinNode> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinNode::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion.clone());

    assert!(!g.contains_choice(&suggestion, 0));

    g.push_pairs([
        (true, true), // is swimming, can stop.
        (false, false), // is not reading book, can't read book.
    ]);
}

<commit_msg>Added `BinNode::with_choices_not_in`<commit_after>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

#[cfg(test)]
extern crate debug;

use std::collections::Bitv;

/// Contains a binary state and the choices.
#[deriving(PartialEq, Eq, Show, Clone)]
pub struct BinNode {
    /// The state composed of bits.
    pub state: Bitv,
    /// The choices represented as bits that can be flipped.
    pub choices: Bitv
}

impl BinNode {
    /// Gets pairs from pair of booleans.
    pub fn from_pairs(pairs: &[(bool, bool)]) -> BinNode {
        BinNode {
            state: pairs.iter().map(|&(a, _)| a).collect(),
            choices: pairs.iter().map(|&(_, b)| b).collect()
        }
    }

    /// Call closure for each available choice.
    #[inline(always)]
    pub fn with_choices(&self, f: |i: uint|) {
        for i in range(0, self.choices.len())
            .zip(self.choices.iter())
            .filter(|&(_, v)| v == true)
            .map(|(i, _)| i
        ) {
            f(i)
        }
    }

    /// Calls closure for all choices that are not in graph.
    #[inline(always)]
    pub fn with_choices_not_in<TAction>(
        &self,
        graph: &BinGraph<TAction>,
        f: |i: uint|
    ) {
        self.with_choices(|i| if !graph.contains_choice(self, i) { f(i) })
    }
}

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<BinNode>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

impl<TAction> BinGraph<TAction> {
    /// Creates a new BinGraph.
    pub fn new() -> BinGraph<TAction> {
        BinGraph {
            data: Vec::new(),
            actions: Vec::new()
        }
    }

    /// Adds new information about state and choices.
    ///
    /// The first bool indicate state, the second whether it can change.
    pub fn push_pairs(&mut self, pairs: &[(bool, bool)]) {
        self.data.push(BinNode::from_pairs(pairs));
    }

    /// Returns true if the graph contains a choice.
    pub fn contains_choice(&self, state: &BinNode, i: uint) -> bool {
        self.data.iter().any(|st|
            range(0, st.choices.len()).all(|j|
                state.choices.get(j) == if j == i {
                        !state.choices.get(j)
                    } else {
                        state.choices.get(j)
                    }
            )
        )
    }

    /// Returns the suggestion in default state that are open to all choices.
    pub fn default_suggestion(&self) -> BinNode {
        let open_for_all_choices: Vec<(bool, bool)> =
            range(0, self.actions.len()).map(|_| (false, true)).collect();
        BinNode::from_pairs(open_for_all_choices.as_slice())
    }

    /// Suggests a missing state with choices.
    pub fn suggestion(&self) -> Option<BinNode> {
        if self.data.len() == 0 {
            Some(self.default_suggestion())
        } else {
            None
        }
    }
}

#[test]
fn test_exclusive() {
    let mut g: BinGraph<&'static str> = BinGraph::new();
    g.actions.push("Go swiming");
    g.actions.push("Read a book");

    let suggestion = g.suggestion().unwrap();
    assert_eq!(suggestion, BinNode::from_pairs([
        (false, true),
        (false, true)
    ]));

    g.data.push(suggestion.clone());

    assert!(!g.contains_choice(&suggestion, 0));

    g.push_pairs([
        (true, true), // is swimming, can stop.
        (false, false), // is not reading book, can't read book.
    ]);
}

<|endoftext|>


<commit_before>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

<commit_msg>Added `BinGraph`<commit_after>#![crate_name = "binstat"]
#![deny(missing_doc)]

//! A library for modelling and reasoning about multidimensional
//! binary states.

use std::collections::Bitv;

/// Models a multidimensional binary state.
pub struct BinGraph<TAction> {
    /// The states and the bits that can be flipped.
    pub data: Vec<(Bitv, Bitv)>,
    /// A description the action that takes when flipping bits.
    pub actions: Vec<TAction>,
}

<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(interpolate_idents)]

extern crate libc;

pub mod ffi;
pub mod apr;
pub mod httpd;
pub mod wrapper;
pub mod cookie;

pub use libc::{c_void, c_char, c_int};

pub use httpd::{Request, Status, ProxyReq, CmdParms, server_banner, server_description,
   server_built, show_mpm};
pub use apr::{apr_version_string, apu_version_string, HookOrder, time_now};
pub use cookie::Cookie;

#[macro_export]
macro_rules! AP_DECLARE_MODULE {
   (
      $module:ident,
      $mod_name:expr,
      $create_dir_config:expr,
      $merge_dir_config:expr,
      $create_server_config:expr,
      $merge_server_config:expr,
      $cmds:expr,
      $register_hooks:expr
   ) => {
      #[allow(unused_unsafe)]
      #[no_mangle]
      pub static mut $module: $crate::ffi::module = $crate::ffi::module {
         version: $crate::ffi::MODULE_MAGIC_NUMBER_MAJOR,
         minor_version: $crate::ffi::MODULE_MAGIC_NUMBER_MINOR,
         module_index: -1,
         name: $mod_name as *const u8 as *const $crate::c_char,
         dynamic_load_handle: 0 as *mut $crate::c_void,
         next: 0 as *mut $crate::ffi::module,
         magic: $crate::ffi::MODULE_MAGIC_COOKIE,
         rewrite_args: None,
         create_dir_config: $create_dir_config,
         merge_dir_config: $merge_dir_config,
         create_server_config: $create_server_config,
         merge_server_config: $merge_server_config,
         cmds: unsafe { $cmds as *const $crate::ffi::command_rec },
         register_hooks: $register_hooks
      };
   }
}

#[macro_export]
macro_rules! apache2_module {
   ($name:ident, $mod_name:expr) => {
      apache2_module!($name, $mod_name, ap_hook_handler, $crate::HookOrder::MIDDLE);
   };

   ($name:ident, $mod_name:expr, $hook:ident, $order:expr) => {
      apache2_module!($name, $mod_name, $hook, $order, []);
   };

   ($name:ident, $mod_name:expr, $hook:ident, $order:expr, [ $( $cmd:expr );* ]) => {
      interpolate_idents! {
         DECLARE_COMMAND_ARRAY!([$name _cmds], { $( $cmd );* });

         AP_DECLARE_MODULE!(
            [$name _module],
            $mod_name,
            None,
            None,
            None,
            None,
            &[$name _cmds],
            Some([$name _hooks])
         );

         extern "C" fn [$name _hooks](_: *mut $crate::ffi::apr_pool_t) {
            unsafe {
               $crate::ffi::$hook(
                  Some([c_ $name _handler]),
                  std::ptr::null(),
                  std::ptr::null(),
                  $order.into()
               );
            }
         }
      }

      #[no_mangle]
      interpolate_idents! {
         pub extern "C" fn [c_ $name _handler](r: *mut $crate::ffi::request_rec) -> $crate::c_int {
            match $crate::httpd::Request::from_raw_ptr(r) {
               Err(_) => $crate::httpd::Status::DECLINED.into(),
               Ok(mut request) => match [$name _handler](&mut request) {
                  Ok(status) => status,
                  Err(_) => $crate::httpd::Status::HTTP_INTERNAL_SERVER_ERROR
               }.into()
            }
         }
      }
   }
}

#[macro_export]
macro_rules! DECLARE_COMMAND_REC {
   (
      $name:expr,
      $func:expr,
      $cmd_data:expr,
      $req_override:expr,
      $args_how:expr,
      $errmsg:expr
   ) => {
      $crate::ffi::command_rec {
         name: $name as *const u8 as *const $crate::c_char,
         func: $crate::ffi::cmd_func {
            _bindgen_data_: [$func as u64]
         },
         cmd_data: $cmd_data as *mut $crate::c_void,
         req_override: $req_override,
         args_how: $args_how,
         errmsg: $errmsg as *const u8 as *const $crate::c_char
      }
   }
}

#[macro_export]
macro_rules! NULL_COMMAND_REC {
   () => {
      DECLARE_COMMAND_REC!(0, 0, 0, 0, 0, 0)
   }
}

#[macro_export]
macro_rules! AP_INIT_NO_ARGS {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::NO_ARGS, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_RAW_ARGS {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::RAW_ARGS, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE_ARGV {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE_ARGV, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE1 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE1, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_ITERATE {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::ITERATE, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE2 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE2, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE12 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE12, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_ITERATE2 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::ITERATE2, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE13 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE13, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE23 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE23, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE123 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE123, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE3 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE3, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_FLAG {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::FLAG, $errmsg)
   }
}

#[macro_export]
macro_rules! DECLARE_COMMAND_ARRAY {
   ($cmds_name:ident, $cmd_count:expr, { $( $cmd:expr );* }) => {
      #[no_mangle]
      pub static mut $cmds_name: [$crate::ffi::command_rec; $cmd_count] = [
         $( $cmd, )*
         NULL_COMMAND_REC!()
      ];
   };

   ($cmds_name:ident, {}) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 1, {});
   };

   ($cmds_name:ident, { $cmd1:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 2, { $cmd1 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 3, { $cmd1; $cmd2 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 4, { $cmd1; $cmd2; $cmd3 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 5, { $cmd1; $cmd2; $cmd3; $cmd4 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 6, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 7, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr; $cmd7:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 8, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6; $cmd7 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr; $cmd7:expr; $cmd8:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 9, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6; $cmd7; $cmd8 });
   };
}
<commit_msg>Rename AP_DECLARE_MODULE to DECLARE_MODULE.<commit_after>#![feature(plugin)]
#![plugin(interpolate_idents)]

extern crate libc;

pub mod ffi;
pub mod apr;
pub mod httpd;
pub mod wrapper;
pub mod cookie;

pub use libc::{c_void, c_char, c_int};

pub use httpd::{Request, Status, ProxyReq, CmdParms, server_banner, server_description,
   server_built, show_mpm};
pub use apr::{apr_version_string, apu_version_string, HookOrder, time_now};
pub use cookie::Cookie;

#[macro_export]
macro_rules! apache2_module {
   ($name:ident, $mod_name:expr) => {
      apache2_module!($name, $mod_name, ap_hook_handler, $crate::HookOrder::MIDDLE);
   };

   ($name:ident, $mod_name:expr, $hook:ident, $order:expr) => {
      apache2_module!($name, $mod_name, $hook, $order, []);
   };

   ($name:ident, $mod_name:expr, $hook:ident, $order:expr, [ $( $cmd:expr );* ]) => {
      interpolate_idents! {
         DECLARE_COMMAND_ARRAY!([$name _cmds], { $( $cmd );* });

         DECLARE_MODULE!(
            [$name _module],
            $mod_name,
            None,
            None,
            None,
            None,
            &[$name _cmds],
            Some([$name _hooks])
         );

         extern "C" fn [$name _hooks](_: *mut $crate::ffi::apr_pool_t) {
            unsafe {
               $crate::ffi::$hook(
                  Some([c_ $name _handler]),
                  std::ptr::null(),
                  std::ptr::null(),
                  $order.into()
               );
            }
         }
      }

      #[no_mangle]
      interpolate_idents! {
         pub extern "C" fn [c_ $name _handler](r: *mut $crate::ffi::request_rec) -> $crate::c_int {
            match $crate::httpd::Request::from_raw_ptr(r) {
               Err(_) => $crate::httpd::Status::DECLINED.into(),
               Ok(mut request) => match [$name _handler](&mut request) {
                  Ok(status) => status,
                  Err(_) => $crate::httpd::Status::HTTP_INTERNAL_SERVER_ERROR
               }.into()
            }
         }
      }
   }
}

#[macro_export]
macro_rules! DECLARE_MODULE {
   (
      $module:ident,
      $mod_name:expr,
      $create_dir_config:expr,
      $merge_dir_config:expr,
      $create_server_config:expr,
      $merge_server_config:expr,
      $cmds:expr,
      $register_hooks:expr
   ) => {
      #[allow(unused_unsafe)]
      #[no_mangle]
      pub static mut $module: $crate::ffi::module = $crate::ffi::module {
         version: $crate::ffi::MODULE_MAGIC_NUMBER_MAJOR,
         minor_version: $crate::ffi::MODULE_MAGIC_NUMBER_MINOR,
         module_index: -1,
         name: $mod_name as *const u8 as *const $crate::c_char,
         dynamic_load_handle: 0 as *mut $crate::c_void,
         next: 0 as *mut $crate::ffi::module,
         magic: $crate::ffi::MODULE_MAGIC_COOKIE,
         rewrite_args: None,
         create_dir_config: $create_dir_config,
         merge_dir_config: $merge_dir_config,
         create_server_config: $create_server_config,
         merge_server_config: $merge_server_config,
         cmds: unsafe { $cmds as *const $crate::ffi::command_rec },
         register_hooks: $register_hooks
      };
   }
}

#[macro_export]
macro_rules! DECLARE_COMMAND_REC {
   (
      $name:expr,
      $func:expr,
      $cmd_data:expr,
      $req_override:expr,
      $args_how:expr,
      $errmsg:expr
   ) => {
      $crate::ffi::command_rec {
         name: $name as *const u8 as *const $crate::c_char,
         func: $crate::ffi::cmd_func {
            _bindgen_data_: [$func as u64]
         },
         cmd_data: $cmd_data as *mut $crate::c_void,
         req_override: $req_override,
         args_how: $args_how,
         errmsg: $errmsg as *const u8 as *const $crate::c_char
      }
   }
}

#[macro_export]
macro_rules! NULL_COMMAND_REC {
   () => {
      DECLARE_COMMAND_REC!(0, 0, 0, 0, 0, 0)
   }
}

#[macro_export]
macro_rules! AP_INIT_NO_ARGS {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::NO_ARGS, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_RAW_ARGS {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::RAW_ARGS, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE_ARGV {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE_ARGV, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE1 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE1, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_ITERATE {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::ITERATE, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE2 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE2, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE12 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE12, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_ITERATE2 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::ITERATE2, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE13 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE13, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE23 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE23, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE123 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE123, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_TAKE3 {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::TAKE3, $errmsg)
   }
}

#[macro_export]
macro_rules! AP_INIT_FLAG {
   ($name:expr, $func:expr, $req_override:expr, $errmsg:expr) => {
      DECLARE_COMMAND_REC!($name, $func, 0, $req_override, $crate::ffi::FLAG, $errmsg)
   }
}

#[macro_export]
macro_rules! DECLARE_COMMAND_ARRAY {
   ($cmds_name:ident, $cmd_count:expr, { $( $cmd:expr );* }) => {
      #[no_mangle]
      pub static mut $cmds_name: [$crate::ffi::command_rec; $cmd_count] = [
         $( $cmd, )*
         NULL_COMMAND_REC!()
      ];
   };

   ($cmds_name:ident, {}) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 1, {});
   };

   ($cmds_name:ident, { $cmd1:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 2, { $cmd1 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 3, { $cmd1; $cmd2 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 4, { $cmd1; $cmd2; $cmd3 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 5, { $cmd1; $cmd2; $cmd3; $cmd4 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 6, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 7, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr; $cmd7:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 8, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6; $cmd7 });
   };

   ($cmds_name:ident, { $cmd1:expr; $cmd2:expr; $cmd3:expr; $cmd4:expr; $cmd5:expr; $cmd6:expr; $cmd7:expr; $cmd8:expr }) => {
      DECLARE_COMMAND_ARRAY!($cmds_name, 9, { $cmd1; $cmd2; $cmd3; $cmd4; $cmd5; $cmd6; $cmd7; $cmd8 });
   };
}
<|endoftext|>


<commit_before>//! This crate provides only one struct, `PrimeIter` implementing `Iterator`
//! which yields prime numbers as an `u64`.
//!

/// `PrimeIter` is used for generating an endless stream of prime numbers in an
/// efficient way.
///
/// The implementation of `Iterator` makes it easy to iterate over prime
/// numbers.
///
/// Generating the first ten prime numbers:
///
/// ```
/// # use primeiter::PrimeIter;
///
/// let primes = PrimeIter::new();
/// let v: Vec<_> = primes.take(10).collect();
///
/// assert_eq!(v,vec![2,3,5,7,11,13,17,19,23,29]);
/// ```
///
/// Printing an endless stream of prime numbers:
///
/// ```no_run
/// # use primeiter::PrimeIter;
/// for prime in PrimeIter::new()
/// {
///		println!("{}",prime);
/// }
/// ```
///
pub struct PrimeIter
{
	primes: Vec<u64>,
}

impl PrimeIter
{
	/// Returns a new instance of `PrimeIter`.
	///
	/// # Examples
	///
	/// ```
	/// # use primeiter::PrimeIter;
	/// let iter = PrimeIter::new();
	/// ```
	///
	pub fn new()->PrimeIter
	{
		PrimeIter
		{
			primes: Vec::new(),
		}
	}
}

impl Iterator for PrimeIter
{
	type Item = u64;

	fn next(&mut self)->Option<Self::Item>
	{
		if self.primes.last()==None
		{
			self.primes.push(2);
			return Some(2);
		}
		'outer: for num in ((self.primes.last().unwrap()+1)..).filter(|i|*i%2!=0)
		{
			if self.primes.iter().take_while(|i|*i**i<=num).any(|i|num%i==0)
			{
				continue 'outer;
			}
			self.primes.push(num);
			return Some(num);
		}
		None
	}
}

<commit_msg>spaces<commit_after>//! This crate provides only one struct, `PrimeIter` implementing `Iterator`
//! which yields prime numbers as an `u64`.
//!

/// `PrimeIter` is used for generating an endless stream of prime numbers in an
/// efficient way.
///
/// The implementation of `Iterator` makes it easy to iterate over prime
/// numbers.
///
/// Generating the first ten prime numbers:
///
/// ```
/// # use primeiter::PrimeIter;
///
/// let primes = PrimeIter::new();
/// let v: Vec<_> = primes.take(10).collect();
///
/// assert_eq!(v,vec![2,3,5,7,11,13,17,19,23,29]);
/// ```
///
/// Printing an endless stream of prime numbers:
///
/// ```no_run
/// # use primeiter::PrimeIter;
/// for prime in PrimeIter::new()
/// {
///		println!("{}",prime);
/// }
/// ```
///
pub struct PrimeIter
{
	primes: Vec<u64>,
}

impl PrimeIter
{
	/// Returns a new instance of `PrimeIter`.
	///
	/// # Examples
	///
	/// ```
	/// # use primeiter::PrimeIter;
	/// let iter = PrimeIter::new();
	/// ```
	///
	pub fn new() -> PrimeIter
	{
		PrimeIter
		{
			primes: Vec::new(),
		}
	}
}

impl Iterator for PrimeIter
{
	type Item = u64;

	fn next(&mut self) -> Option<Self::Item>
	{
		if self.primes.last() == None
		{
			self.primes.push(2);
			return Some(2);
		}
		'outer: for num in ((self.primes.last().unwrap()+1)..).filter(|i|*i%2!=0)
		{
			if self.primes.iter().take_while(|i|*i**i<=num).any(|i|num%i==0)
			{
				continue 'outer;
			}
			self.primes.push(num);
			return Some(num);
		}
		None
	}
}

<|endoftext|>