<commit_before>use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration};

#[cfg(feature = "egl")]
use smithay::backend::egl::EGLGraphicsBackend;
use smithay::{
    backend::{graphics::gl::GLGraphicsBackend, input::InputBackend, winit},
    reexports::{
        calloop::EventLoop,
        wayland_server::{protocol::wl_output, Display},
        winit::window::CursorIcon,
    },
    wayland::{
        output::{Mode, Output, PhysicalProperties},
        seat::CursorImageStatus,
    },
};

use slog::Logger;

use crate::buffer_utils::BufferUtils;
use crate::glium_drawer::GliumDrawer;
use crate::state::AnvilState;

pub fn run_winit(
    display: Rc<RefCell<Display>>,
    event_loop: &mut EventLoop<AnvilState>,
    log: Logger,
) -> Result<(), ()> {
    let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
        slog::crit!(log, "Failed to initialize Winit backend: {}", err);
    })?;

    #[cfg(feature = "egl")]
    let egl_buffer_reader = Rc::new(RefCell::new(
        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
            info!(log, "EGL hardware-acceleration enabled");
            Some(egl_buffer_reader)
        } else {
            None
        },
    ));

    #[cfg(feature = "egl")]
    let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone());
    #[cfg(not(feature = "egl"))]
    let buffer_utils = BufferUtils::new(log.clone());

    let (w, h) = renderer.get_framebuffer_dimensions();
    let drawer = GliumDrawer::init(renderer, buffer_utils.clone(), log.clone());

    /*
     * Initialize the globals
     */

    let mut state = AnvilState::init(
        display.clone(),
        event_loop.handle(),
        buffer_utils,
        None,
        None,
        log.clone(),
    );

    let (output, _) = Output::new(
        &mut display.borrow_mut(),
        "Winit".into(),
        PhysicalProperties {
            width: 0,
            height: 0,
            subpixel: wl_output::Subpixel::Unknown,
            make: "Smithay".into(),
            model: "Winit".into(),
        },
        log.clone(),
    );

    output.change_current_state(
        Some(Mode {
            width: w as i32,
            height: h as i32,
            refresh: 60_000,
        }),
        None,
        None,
    );
    output.set_preferred(Mode {
        width: w as i32,
        height: h as i32,
        refresh: 60_000,
    });

    let start_time = std::time::Instant::now();

    info!(log, "Initialization completed, starting the main loop.");

    while state.running.load(Ordering::SeqCst) {
        input
            .dispatch_new_events(|event, _| state.process_input_event(event))
            .unwrap();

        // drawing logic
        {
            use glium::Surface;
            let mut frame = drawer.draw();
            frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None);

            // draw the windows
            drawer.draw_windows(&mut frame, &*state.window_map.borrow(), None, state.ctoken);

            let (x, y) = *state.pointer_location.borrow();
            // draw the dnd icon if any
            {
                let guard = state.dnd_icon.lock().unwrap();
                if let Some(ref surface) = *guard {
                    if surface.as_ref().is_alive() {
                        drawer.draw_dnd_icon(&mut frame, surface, (x as i32, y as i32), state.ctoken);
                    }
                }
            }
            // draw the cursor as relevant
            {
                let mut guard = state.cursor_status.lock().unwrap();
                // reset the cursor if the surface is no longer alive
                let mut reset = false;
                if let CursorImageStatus::Image(ref surface) = *guard {
                    reset = !surface.as_ref().is_alive();
                }
                if reset {
                    *guard = CursorImageStatus::Default;
                }
                // draw as relevant
                if let CursorImageStatus::Image(ref surface) = *guard {
                    drawer.draw_software_cursor(&mut frame, surface, (x as i32, y as i32), state.ctoken);
                } else {
                    drawer.draw_hardware_cursor(&CursorIcon::Default, (0, 0), (x as i32, y as i32));
                }
            }

            if let Err(err) = frame.finish() {
                error!(log, "Error during rendering: {:?}", err);
            }
        }
        // Send frame events so that client start drawing their next frame
        state
            .window_map
            .borrow()
            .send_frames(start_time.elapsed().as_millis() as u32);
        display.borrow_mut().flush_clients(&mut state);

        if event_loop
            .dispatch(Some(Duration::from_millis(16)), &mut state)
            .is_err()
        {
            state.running.store(false, Ordering::SeqCst);
        } else {
            display.borrow_mut().flush_clients(&mut state);
            state.window_map.borrow_mut().refresh();
        }
    }

    // Cleanup stuff
    state.window_map.borrow_mut().clear();

    Ok(())
}
<commit_msg>anvil: send frame callback before blocking to draw on winit<commit_after>use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration};

#[cfg(feature = "egl")]
use smithay::backend::egl::EGLGraphicsBackend;
use smithay::{
    backend::{graphics::gl::GLGraphicsBackend, input::InputBackend, winit},
    reexports::{
        calloop::EventLoop,
        wayland_server::{protocol::wl_output, Display},
        winit::window::CursorIcon,
    },
    wayland::{
        output::{Mode, Output, PhysicalProperties},
        seat::CursorImageStatus,
    },
};

use slog::Logger;

use crate::buffer_utils::BufferUtils;
use crate::glium_drawer::GliumDrawer;
use crate::state::AnvilState;

pub fn run_winit(
    display: Rc<RefCell<Display>>,
    event_loop: &mut EventLoop<AnvilState>,
    log: Logger,
) -> Result<(), ()> {
    let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
        slog::crit!(log, "Failed to initialize Winit backend: {}", err);
    })?;

    #[cfg(feature = "egl")]
    let egl_buffer_reader = Rc::new(RefCell::new(
        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
            info!(log, "EGL hardware-acceleration enabled");
            Some(egl_buffer_reader)
        } else {
            None
        },
    ));

    #[cfg(feature = "egl")]
    let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone());
    #[cfg(not(feature = "egl"))]
    let buffer_utils = BufferUtils::new(log.clone());

    let (w, h) = renderer.get_framebuffer_dimensions();
    let drawer = GliumDrawer::init(renderer, buffer_utils.clone(), log.clone());

    /*
     * Initialize the globals
     */

    let mut state = AnvilState::init(
        display.clone(),
        event_loop.handle(),
        buffer_utils,
        None,
        None,
        log.clone(),
    );

    let (output, _) = Output::new(
        &mut display.borrow_mut(),
        "Winit".into(),
        PhysicalProperties {
            width: 0,
            height: 0,
            subpixel: wl_output::Subpixel::Unknown,
            make: "Smithay".into(),
            model: "Winit".into(),
        },
        log.clone(),
    );

    output.change_current_state(
        Some(Mode {
            width: w as i32,
            height: h as i32,
            refresh: 60_000,
        }),
        None,
        None,
    );
    output.set_preferred(Mode {
        width: w as i32,
        height: h as i32,
        refresh: 60_000,
    });

    let start_time = std::time::Instant::now();

    info!(log, "Initialization completed, starting the main loop.");

    while state.running.load(Ordering::SeqCst) {
        input
            .dispatch_new_events(|event, _| state.process_input_event(event))
            .unwrap();

        // Send frame events so that client start drawing their next frame
        state
            .window_map
            .borrow()
            .send_frames(start_time.elapsed().as_millis() as u32);
        display.borrow_mut().flush_clients(&mut state);

        // drawing logic
        {
            use glium::Surface;
            let mut frame = drawer.draw();
            frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None);

            // draw the windows
            drawer.draw_windows(&mut frame, &*state.window_map.borrow(), None, state.ctoken);

            let (x, y) = *state.pointer_location.borrow();
            // draw the dnd icon if any
            {
                let guard = state.dnd_icon.lock().unwrap();
                if let Some(ref surface) = *guard {
                    if surface.as_ref().is_alive() {
                        drawer.draw_dnd_icon(&mut frame, surface, (x as i32, y as i32), state.ctoken);
                    }
                }
            }
            // draw the cursor as relevant
            {
                let mut guard = state.cursor_status.lock().unwrap();
                // reset the cursor if the surface is no longer alive
                let mut reset = false;
                if let CursorImageStatus::Image(ref surface) = *guard {
                    reset = !surface.as_ref().is_alive();
                }
                if reset {
                    *guard = CursorImageStatus::Default;
                }
                // draw as relevant
                if let CursorImageStatus::Image(ref surface) = *guard {
                    drawer.draw_software_cursor(&mut frame, surface, (x as i32, y as i32), state.ctoken);
                } else {
                    drawer.draw_hardware_cursor(&CursorIcon::Default, (0, 0), (x as i32, y as i32));
                }
            }

            if let Err(err) = frame.finish() {
                error!(log, "Error during rendering: {:?}", err);
            }
        }

        if event_loop
            .dispatch(Some(Duration::from_millis(16)), &mut state)
            .is_err()
        {
            state.running.store(false, Ordering::SeqCst);
        } else {
            display.borrow_mut().flush_clients(&mut state);
            state.window_map.borrow_mut().refresh();
        }
    }

    // Cleanup stuff
    state.window_map.borrow_mut().clear();

    Ok(())
}
<|endoftext|>


<commit_before>//! ra_db defines basic database traits. Concrete DB is defined by ra_analysis.
mod syntax_ptr;
mod input;
mod loc2id;
pub mod mock;

use std::sync::Arc;
use ra_editor::LineIndex;
use ra_syntax::{TextUnit, SourceFileNode};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Canceled;

pub type Cancelable<T> = Result<T, Canceled>;

impl std::fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        fmt.write_str("canceled")
    }
}

impl std::error::Error for Canceled {}

pub use crate::{
    syntax_ptr::LocalSyntaxPtr,
    input::{
        FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph,
        FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
        FileRelativePathQuery
    },
    loc2id::{LocationIntener, NumericId},
};

#[macro_export]
macro_rules! impl_numeric_id {
    ($id:ident) => {
        impl $crate::NumericId for $id {
            fn from_u32(id: u32) -> Self {
                $id(id)
            }
            fn to_u32(self) -> u32 {
                self.0
            }
        }
    };
}

pub trait BaseDatabase: salsa::Database {
    fn check_canceled(&self) -> Cancelable<()> {
        if self.salsa_runtime().is_current_revision_canceled() {
            Err(Canceled)
        } else {
            Ok(())
        }
    }
}

salsa::query_group! {
    pub trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
        fn source_file(file_id: FileId) -> SourceFileNode {
            type SourceFileQuery;
        }
        fn file_lines(file_id: FileId) -> Arc<LineIndex> {
            type FileLinesQuery;
        }
    }
}

fn source_file(db: &impl SyntaxDatabase, file_id: FileId) -> SourceFileNode {
    let text = db.file_text(file_id);
    SourceFileNode::parse(&*text)
}
fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}

#[derive(Clone, Copy, Debug)]
pub struct FilePosition {
    pub file_id: FileId,
    pub offset: TextUnit,
}
<commit_msg>cancelled is not Copy<commit_after>//! ra_db defines basic database traits. Concrete DB is defined by ra_analysis.
mod syntax_ptr;
mod input;
mod loc2id;
pub mod mock;

use std::sync::Arc;
use ra_editor::LineIndex;
use ra_syntax::{TextUnit, SourceFileNode};

#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Canceled;

pub type Cancelable<T> = Result<T, Canceled>;

impl std::fmt::Display for Canceled {
    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        fmt.write_str("canceled")
    }
}

impl std::error::Error for Canceled {}

pub use crate::{
    syntax_ptr::LocalSyntaxPtr,
    input::{
        FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph,
        FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery,
        FileRelativePathQuery
    },
    loc2id::{LocationIntener, NumericId},
};

#[macro_export]
macro_rules! impl_numeric_id {
    ($id:ident) => {
        impl $crate::NumericId for $id {
            fn from_u32(id: u32) -> Self {
                $id(id)
            }
            fn to_u32(self) -> u32 {
                self.0
            }
        }
    };
}

pub trait BaseDatabase: salsa::Database {
    fn check_canceled(&self) -> Cancelable<()> {
        if self.salsa_runtime().is_current_revision_canceled() {
            Err(Canceled)
        } else {
            Ok(())
        }
    }
}

salsa::query_group! {
    pub trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
        fn source_file(file_id: FileId) -> SourceFileNode {
            type SourceFileQuery;
        }
        fn file_lines(file_id: FileId) -> Arc<LineIndex> {
            type FileLinesQuery;
        }
    }
}

fn source_file(db: &impl SyntaxDatabase, file_id: FileId) -> SourceFileNode {
    let text = db.file_text(file_id);
    SourceFileNode::parse(&*text)
}
fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}

#[derive(Clone, Copy, Debug)]
pub struct FilePosition {
    pub file_id: FileId,
    pub offset: TextUnit,
}
<|endoftext|>


<commit_before>#[derive(Debug)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> Result<&mut Self, String> {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn left_shift(&mut self, v: &i32) {}
}

fn main() {
    let mut a = Tree::new(&3);
    a.insert(&2);
    a.insert(&1);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    println!("{:?}", a.look_up(&1));
    println!("{:?}", a);
}
<commit_msg>add find father node method<commit_after>#[derive(Debug, Clone)]
struct Tree {
    enter: Node,
    left: Option<Box<Tree>>,
    right: Option<Box<Tree>>,
}

//for red-black tree
#[derive(Debug, Clone)]
enum Color {
    Black,
    Red,
    White,
}

#[derive(Debug, Clone)]
struct Node {
    val: i32,
    color: Color,
}

impl Node {
    fn new(v: &i32) -> Node {
        Node {
            val: *v,
            color: Color::White,
        }
    }
}

type ReTr<'a> = Result<&'a mut Tree, String>;

impl Tree {
    fn new(v: &i32) -> Tree {
        Tree {
            enter: Node::new(v),
            left: None,
            right: None,
        }
    }

    fn insert(&mut self, v: &i32) {
        let target = if *v > self.enter.val {
            &mut self.right
        } else {
            &mut self.left
        };
        //println!("target is -> {:?}", target);
        match target {
            Some(next) => {
                //println!("next is -> {:?}", &next);
                next.insert(v)
            }
            None => {
                let new_node = Node::new(v);
                let new_tree = Tree {
                    enter: new_node,
                    left: None,
                    right: None,
                };
                *target = Some(Box::new(new_tree));
            }
        }
    }

    fn look_up_recursive(&mut self, v: &i32) -> Result<&mut Self, String> {
        if *v == self.enter.val {
            return Ok(self);
        } else if *v > self.enter.val {
            if let Some(_) = self.right {
                let next = self.right.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        } else {
            if let Some(_) = self.left {
                let next = self.left.as_mut().unwrap();
                return next.look_up(v);
            } else {
                Err("not find".to_string())
            }
        }
    }

    fn look_up(&mut self, v: &i32) -> ReTr {
        let mut this: &mut Self = self;
        loop {
            if *v == this.enter.val {
                return Ok(this);
            } else if *v > this.enter.val {
                if let None = this.right {
                    return Err("not find".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return Err("not find".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn look_up_father(&mut self, v: &i32) -> (ReTr, String) {
        let mut this: &mut Self = self;
        loop {
            if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "right".to_string());
            } else if *v == this.right.as_ref().unwrap().enter.val {
                return (Ok(this), "left".to_string());
            } else if *v > this.enter.val {
                if let None = this.right {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.right.as_mut().unwrap();
            } else {
                if let None = this.left {
                    return (Err("not find".to_string()), "Error".to_string());
                }
                this = { this }.left.as_mut().unwrap();
            }
        }
    }

    fn left_shift(&mut self, v: &i32) {}
}

fn main() {
    let mut a = Tree::new(&3);
    a.insert(&2);
    a.insert(&1);
    a.insert(&4);
    a.insert(&5);

    //println!("{:?}", a);
    //println!("{:?}", a.look_up(&1));
    println!("{:?}", a.look_up_father(&4));
    //println!("{:?}", a);
}
<|endoftext|>


<commit_before>use std::path::Path;

use nmk::platform::{is_alpine, is_arch, is_mac};

use crate::cmdline::Opt;
use crate::core::*;

fn has_vendored_zsh(nmk_home: &Path) -> bool {
    nmk_home.join("vendor").join("bin").join("zsh").exists()
}

pub fn use_global_rcs(arg: &Opt, nmk_home: &Path) -> bool {
    // Some linux distribution global zprofile contains a line that will source everything
    // from /etc/profile. And they do reset $PATH completely.
    // It makes PATH set by nmk unusable
    let hostile = is_mac() || is_alpine() || is_arch();
    let no_global_rcs = !arg.no_autofix && hostile && !has_vendored_zsh(nmk_home);
    !no_global_rcs
}

pub fn setup(arg: &Opt, nmk_home: &Path) {
    let global_rcs = use_global_rcs(arg, nmk_home);
    if !global_rcs {
        log::debug!("ignore zsh global rcs");
    }
    set_env("NMK_ZSH_GLOBAL_RCS", one_hot!(global_rcs));
}
<commit_msg>Clarify reasons why zsh global resource configuration files are ignored<commit_after>use std::path::Path;

use nmk::platform::{is_alpine, is_arch, is_mac};

use crate::cmdline::Opt;
use crate::core::*;

fn has_vendored_zsh(nmk_home: &Path) -> bool {
    nmk_home.join("vendor").join("bin").join("zsh").exists()
}

pub fn use_global_rcs(_arg: &Opt, nmk_home: &Path) -> bool {
    // Disable global resource files on some platform
    //   - Some linux distributions force sourcing /etc/profile, they do reset PATH set by nmk.
    //   - MacOs doesn't respect PATH set by nmk, it change the order.
    let not_friendly_global_rcs = is_mac() || is_alpine() || is_arch();
    let no_global_rcs = not_friendly_global_rcs && !has_vendored_zsh(nmk_home);
    !no_global_rcs
}

pub fn setup(arg: &Opt, nmk_home: &Path) {
    let global_rcs = use_global_rcs(arg, nmk_home);
    if !global_rcs {
        log::debug!("ignore zsh global rcs");
    }
    set_env("NMK_ZSH_GLOBAL_RCS", one_hot!(global_rcs));
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_type = "bin"]
#![feature(collections, core, env, io, os)]

extern crate capnp;
extern crate rand;

use capnp::{MessageReader, MessageBuilder};

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

mod uncompressed {
    use capnp;

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn write_buffered<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R: capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize::new_reader(input_stream, options).unwrap()
    }
}

mod packed {
    use capnp;
    use capnp::serialize_packed::{write_packed_message, write_packed_message_unbuffered};

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message_unbuffered(writer, message).unwrap();
    }

    pub fn write_buffered<T : capnp::io::BufferedOutputStream, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R:capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize_packed::new_reader(input_stream, options).unwrap()
    }

}

const SCRATCH_SIZE : usize = 128 * 1024;

#[derive(Copy)]
pub struct NoScratch;

impl NoScratch {
    fn new_builder(&mut self, _idx : usize) -> capnp::message::MallocMessageBuilder {
        capnp::message::MallocMessageBuilder::new_default()
    }
}

pub struct UseScratch {
    scratch_space : ::std::vec::Vec<capnp::Word>
}

impl UseScratch {
    pub fn new() -> UseScratch {
        UseScratch {
            scratch_space : capnp::common::allocate_zeroed_words(SCRATCH_SIZE * 6)
        }
    }

    fn new_builder<'a>(&mut self, idx : usize) -> capnp::message::ScratchSpaceMallocMessageBuilder<'a> {
        assert!(idx < 6);
        unsafe {
            capnp::message::ScratchSpaceMallocMessageBuilder::new_default(
                ::std::slice::from_raw_parts_mut(self.scratch_space.get_unchecked_mut(idx * SCRATCH_SIZE),
                                                 SCRATCH_SIZE))
        }
    }
}

macro_rules! pass_by_object(
    ( $testcase:ident, $reuse:ident, $iters:expr ) => ({
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);
                let mut message_res = $reuse.new_builder(1);

                let expected = $testcase::setup_request(&mut rng,
                                                        message_req.init_root::<$testcase::RequestBuilder>());

                $testcase::handle_request(message_req.get_root::<$testcase::RequestBuilder>().as_reader(),
                                          message_res.init_root::<$testcase::ResponseBuilder>());

                if !$testcase::check_response(message_res.get_root::<$testcase::ResponseBuilder>().as_reader(),
                                              expected) {
                    panic!("Incorrect response.");
                }
            }
        });
    );

macro_rules! pass_by_bytes(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr ) => ({
        let mut request_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut response_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut rng = common::FastRand::new();
        for _ in range(0, $iters) {
            let mut message_req = $reuse.new_builder(0);
            let mut message_res = $reuse.new_builder(1);

            let expected = {
                let request = message_req.init_root::<$testcase::RequestBuilder>();
                $testcase::setup_request(&mut rng, request)
            };

            {
                let response = message_res.init_root::<$testcase::ResponseBuilder>();

                {
                    let mut writer = capnp::io::ArrayOutputStream::new(request_bytes.as_mut_slice());
                    $compression::write_buffered(&mut writer, &message_req)
                }

                let message_reader = $compression::new_buffered_reader(
                    &mut capnp::io::ArrayInputStream::new(request_bytes.as_slice()),
                    capnp::message::DEFAULT_READER_OPTIONS);

                let request_reader : $testcase::RequestReader = message_reader.get_root();
                $testcase::handle_request(request_reader, response);
            }

            {
                let mut writer = capnp::io::ArrayOutputStream::new(response_bytes.as_mut_slice());
                $compression::write_buffered(&mut writer, &message_res)
            }

            let message_reader = $compression::new_buffered_reader(
                &mut capnp::io::ArrayInputStream::new(response_bytes.as_slice()),
                capnp::message::DEFAULT_READER_OPTIONS);

            let response_reader : $testcase::ResponseReader = message_reader.get_root();
            if !$testcase::check_response(response_reader, expected) {
                panic!("Incorrect response.");
            }
        }
    });
    );

macro_rules! server(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr, $input:expr, $output:expr) => ({
            let mut out_buffered = capnp::io::BufferedOutputStreamWrapper::new(&mut $output);
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut $input);
            for _ in range(0, $iters) {
                let mut message_res = $reuse.new_builder(0);

                {
                    let response = message_res.init_root::<$testcase::ResponseBuilder>();
                    let message_reader = $compression::new_buffered_reader(
                        &mut in_buffered,
                        capnp::message::DEFAULT_READER_OPTIONS);
                    let request_reader : $testcase::RequestReader = message_reader.get_root();
                    $testcase::handle_request(request_reader, response);
                }

                $compression::write_buffered(&mut out_buffered, &message_res);
                out_buffered.flush().unwrap();
            }
        });
    );

macro_rules! sync_client(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
            let mut out_stream = ::std::old_io::stdio::stdout_raw();
            let mut in_stream = ::std::old_io::stdio::stdin_raw();
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut in_stream);
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);

                let expected = {
                    let request = message_req.init_root::<$testcase::RequestBuilder>();
                    $testcase::setup_request(&mut rng, request)
                };
                $compression::write(&mut out_stream, &message_req);

                let message_reader = $compression::new_buffered_reader(
                    &mut in_buffered,
                    capnp::message::DEFAULT_READER_OPTIONS);
                let response_reader : $testcase::ResponseReader = message_reader.get_root();
                assert!($testcase::check_response(response_reader, expected));

            }
        });
    );

macro_rules! pass_by_pipe(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
        use std::old_io::process;

        let mut args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();
        args[2] = "client".to_string();

        let mut command = process::Command::new(args[0].as_slice());
        command.args(args.slice(1, args.len()));
        command.stdin(process::CreatePipe(true, false));
        command.stdout(process::CreatePipe(false, true));
        command.stderr(process::Ignored);
        match command.spawn() {
            Ok(ref mut p) => {
                let mut child_std_out = p.stdout.take().unwrap();
                let mut child_std_in = p.stdin.take().unwrap();

                server!($testcase, $reuse, $compression, $iters, child_std_out, child_std_in);
                println!("{}", p.wait().unwrap());
            }
            Err(e) => {
                println!("could not start process: {}", e);
            }
        }
    });
    );

macro_rules! do_testcase(
    ( $testcase:ident, $mode:expr, $reuse:ident, $compression:ident, $iters:expr ) => ({
            match $mode.as_slice() {
                "object" => pass_by_object!($testcase, $reuse, $iters),
                "bytes" => pass_by_bytes!($testcase, $reuse, $compression, $iters),
                "client" => sync_client!($testcase, $reuse, $compression, $iters),
                "server" => {
                    let mut input = ::std::old_io::stdio::stdin_raw();
                    let mut output = ::std::old_io::stdio::stdout_raw();
                    server!($testcase, $reuse, $compression, $iters, input, output)
                }
                "pipe" => pass_by_pipe!($testcase, $reuse, $compression, $iters),
                s => panic!("unrecognized mode: {}", s)
            }
        });
    );

macro_rules! do_testcase1(
    ( $testcase:expr, $mode:expr, $reuse:ident, $compression:ident, $iters:expr) => ({
            match $testcase.as_slice() {
                "carsales" => do_testcase!(carsales, $mode, $reuse, $compression, $iters),
                "catrank" => do_testcase!(catrank, $mode, $reuse, $compression, $iters),
                "eval" => do_testcase!(eval, $mode, $reuse, $compression, $iters),
                s => panic!("unrecognized test case: {}", s)
            }
        });
    );

macro_rules! do_testcase2(
    ( $testcase:expr, $mode:expr, $reuse:expr, $compression:ident, $iters:expr) => ({
            match $reuse.as_slice() {
                "no-reuse" => {
                    let mut scratch = NoScratch;
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                "reuse" => {
                    let mut scratch = UseScratch::new();
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                s => panic!("unrecognized reuse option: {}", s)
            }
        });
    );

pub fn main() {
    let args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();

    if args.len() != 6 {
        println!("USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", args[0]);
        ::std::env::set_exit_status(1);
        return;
    }

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) => {
            println!("Could not parse a u64 from: {}", args[5]);
            ::std::env::set_exit_status(1);
            return;
        }
    };

    match args[4].as_slice() {
        "none" => do_testcase2!(args[1], args[2],  args[3], uncompressed, iters),
        "packed" => do_testcase2!(args[1], args[2], args[3], packed, iters),
        s => panic!("unrecognized compression: {}", s)
    }
}
<commit_msg>allocate_zeroed_words -> allocate_zeroed_vec<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_type = "bin"]
#![feature(collections, core, env, io, os)]

extern crate capnp;
extern crate rand;

use capnp::{MessageReader, MessageBuilder};

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

mod uncompressed {
    use capnp;

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn write_buffered<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R: capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize::new_reader(input_stream, options).unwrap()
    }
}

mod packed {
    use capnp;
    use capnp::serialize_packed::{write_packed_message, write_packed_message_unbuffered};

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message_unbuffered(writer, message).unwrap();
    }

    pub fn write_buffered<T : capnp::io::BufferedOutputStream, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R:capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize_packed::new_reader(input_stream, options).unwrap()
    }

}

const SCRATCH_SIZE : usize = 128 * 1024;

#[derive(Copy)]
pub struct NoScratch;

impl NoScratch {
    fn new_builder(&mut self, _idx : usize) -> capnp::message::MallocMessageBuilder {
        capnp::message::MallocMessageBuilder::new_default()
    }
}

pub struct UseScratch {
    scratch_space : ::std::vec::Vec<capnp::Word>
}

impl UseScratch {
    pub fn new() -> UseScratch {
        UseScratch {
            scratch_space : ::capnp::Word::allocate_zeroed_vec(SCRATCH_SIZE * 6)
        }
    }

    fn new_builder<'a>(&mut self, idx : usize) -> capnp::message::ScratchSpaceMallocMessageBuilder<'a> {
        assert!(idx < 6);
        unsafe {
            capnp::message::ScratchSpaceMallocMessageBuilder::new_default(
                ::std::slice::from_raw_parts_mut(self.scratch_space.get_unchecked_mut(idx * SCRATCH_SIZE),
                                                 SCRATCH_SIZE))
        }
    }
}

macro_rules! pass_by_object(
    ( $testcase:ident, $reuse:ident, $iters:expr ) => ({
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);
                let mut message_res = $reuse.new_builder(1);

                let expected = $testcase::setup_request(&mut rng,
                                                        message_req.init_root::<$testcase::RequestBuilder>());

                $testcase::handle_request(message_req.get_root::<$testcase::RequestBuilder>().as_reader(),
                                          message_res.init_root::<$testcase::ResponseBuilder>());

                if !$testcase::check_response(message_res.get_root::<$testcase::ResponseBuilder>().as_reader(),
                                              expected) {
                    panic!("Incorrect response.");
                }
            }
        });
    );

macro_rules! pass_by_bytes(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr ) => ({
        let mut request_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut response_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut rng = common::FastRand::new();
        for _ in range(0, $iters) {
            let mut message_req = $reuse.new_builder(0);
            let mut message_res = $reuse.new_builder(1);

            let expected = {
                let request = message_req.init_root::<$testcase::RequestBuilder>();
                $testcase::setup_request(&mut rng, request)
            };

            {
                let response = message_res.init_root::<$testcase::ResponseBuilder>();

                {
                    let mut writer = capnp::io::ArrayOutputStream::new(request_bytes.as_mut_slice());
                    $compression::write_buffered(&mut writer, &message_req)
                }

                let message_reader = $compression::new_buffered_reader(
                    &mut capnp::io::ArrayInputStream::new(request_bytes.as_slice()),
                    capnp::message::DEFAULT_READER_OPTIONS);

                let request_reader : $testcase::RequestReader = message_reader.get_root();
                $testcase::handle_request(request_reader, response);
            }

            {
                let mut writer = capnp::io::ArrayOutputStream::new(response_bytes.as_mut_slice());
                $compression::write_buffered(&mut writer, &message_res)
            }

            let message_reader = $compression::new_buffered_reader(
                &mut capnp::io::ArrayInputStream::new(response_bytes.as_slice()),
                capnp::message::DEFAULT_READER_OPTIONS);

            let response_reader : $testcase::ResponseReader = message_reader.get_root();
            if !$testcase::check_response(response_reader, expected) {
                panic!("Incorrect response.");
            }
        }
    });
    );

macro_rules! server(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr, $input:expr, $output:expr) => ({
            let mut out_buffered = capnp::io::BufferedOutputStreamWrapper::new(&mut $output);
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut $input);
            for _ in range(0, $iters) {
                let mut message_res = $reuse.new_builder(0);

                {
                    let response = message_res.init_root::<$testcase::ResponseBuilder>();
                    let message_reader = $compression::new_buffered_reader(
                        &mut in_buffered,
                        capnp::message::DEFAULT_READER_OPTIONS);
                    let request_reader : $testcase::RequestReader = message_reader.get_root();
                    $testcase::handle_request(request_reader, response);
                }

                $compression::write_buffered(&mut out_buffered, &message_res);
                out_buffered.flush().unwrap();
            }
        });
    );

macro_rules! sync_client(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
            let mut out_stream = ::std::old_io::stdio::stdout_raw();
            let mut in_stream = ::std::old_io::stdio::stdin_raw();
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut in_stream);
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);

                let expected = {
                    let request = message_req.init_root::<$testcase::RequestBuilder>();
                    $testcase::setup_request(&mut rng, request)
                };
                $compression::write(&mut out_stream, &message_req);

                let message_reader = $compression::new_buffered_reader(
                    &mut in_buffered,
                    capnp::message::DEFAULT_READER_OPTIONS);
                let response_reader : $testcase::ResponseReader = message_reader.get_root();
                assert!($testcase::check_response(response_reader, expected));

            }
        });
    );

macro_rules! pass_by_pipe(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
        use std::old_io::process;

        let mut args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();
        args[2] = "client".to_string();

        let mut command = process::Command::new(args[0].as_slice());
        command.args(args.slice(1, args.len()));
        command.stdin(process::CreatePipe(true, false));
        command.stdout(process::CreatePipe(false, true));
        command.stderr(process::Ignored);
        match command.spawn() {
            Ok(ref mut p) => {
                let mut child_std_out = p.stdout.take().unwrap();
                let mut child_std_in = p.stdin.take().unwrap();

                server!($testcase, $reuse, $compression, $iters, child_std_out, child_std_in);
                println!("{}", p.wait().unwrap());
            }
            Err(e) => {
                println!("could not start process: {}", e);
            }
        }
    });
    );

macro_rules! do_testcase(
    ( $testcase:ident, $mode:expr, $reuse:ident, $compression:ident, $iters:expr ) => ({
            match $mode.as_slice() {
                "object" => pass_by_object!($testcase, $reuse, $iters),
                "bytes" => pass_by_bytes!($testcase, $reuse, $compression, $iters),
                "client" => sync_client!($testcase, $reuse, $compression, $iters),
                "server" => {
                    let mut input = ::std::old_io::stdio::stdin_raw();
                    let mut output = ::std::old_io::stdio::stdout_raw();
                    server!($testcase, $reuse, $compression, $iters, input, output)
                }
                "pipe" => pass_by_pipe!($testcase, $reuse, $compression, $iters),
                s => panic!("unrecognized mode: {}", s)
            }
        });
    );

macro_rules! do_testcase1(
    ( $testcase:expr, $mode:expr, $reuse:ident, $compression:ident, $iters:expr) => ({
            match $testcase.as_slice() {
                "carsales" => do_testcase!(carsales, $mode, $reuse, $compression, $iters),
                "catrank" => do_testcase!(catrank, $mode, $reuse, $compression, $iters),
                "eval" => do_testcase!(eval, $mode, $reuse, $compression, $iters),
                s => panic!("unrecognized test case: {}", s)
            }
        });
    );

macro_rules! do_testcase2(
    ( $testcase:expr, $mode:expr, $reuse:expr, $compression:ident, $iters:expr) => ({
            match $reuse.as_slice() {
                "no-reuse" => {
                    let mut scratch = NoScratch;
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                "reuse" => {
                    let mut scratch = UseScratch::new();
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                s => panic!("unrecognized reuse option: {}", s)
            }
        });
    );

pub fn main() {
    let args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();

    if args.len() != 6 {
        println!("USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", args[0]);
        ::std::env::set_exit_status(1);
        return;
    }

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) => {
            println!("Could not parse a u64 from: {}", args[5]);
            ::std::env::set_exit_status(1);
            return;
        }
    };

    match args[4].as_slice() {
        "none" => do_testcase2!(args[1], args[2],  args[3], uncompressed, iters),
        "packed" => do_testcase2!(args[1], args[2], args[3], packed, iters),
        s => panic!("unrecognized compression: {}", s)
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_type = "bin"]
#![feature(collections, core, env, io, os)]

extern crate capnp;
extern crate rand;

use capnp::{MessageReader, MessageBuilder};

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

mod uncompressed {
    use capnp;

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn write_buffered<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R: capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize::new_reader(input_stream, options).unwrap()
    }
}

mod packed {
    use capnp;
    use capnp::serialize_packed::{write_packed_message, write_packed_message_unbuffered};

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message_unbuffered(writer, message).unwrap();
    }

    pub fn write_buffered<T : capnp::io::BufferedOutputStream, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R:capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize_packed::new_reader(input_stream, options).unwrap()
    }

}

const SCRATCH_SIZE : usize = 128 * 1024;

#[derive(Copy)]
pub struct NoScratch;

impl NoScratch {
    fn new_builder(&mut self, _idx : usize) -> capnp::message::MallocMessageBuilder {
        capnp::message::MallocMessageBuilder::new_default()
    }
}

pub struct UseScratch {
    scratch_space : ::std::vec::Vec<capnp::Word>
}

impl UseScratch {
    pub fn new() -> UseScratch {
        UseScratch {
            scratch_space : capnp::common::allocate_zeroed_words(SCRATCH_SIZE * 6)
        }
    }

    fn new_builder<'a>(&mut self, idx : usize) -> capnp::message::ScratchSpaceMallocMessageBuilder<'a> {
        assert!(idx < 6);
        unsafe {
            capnp::message::ScratchSpaceMallocMessageBuilder::new_default(
                ::std::mem::transmute(
                    ::std::raw::Slice { data : self.scratch_space.get_unchecked(idx * SCRATCH_SIZE),
                                      len : SCRATCH_SIZE }))
        }
    }
}

macro_rules! pass_by_object(
    ( $testcase:ident, $reuse:ident, $iters:expr ) => ({
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);
                let mut message_res = $reuse.new_builder(1);

                let expected = $testcase::setup_request(&mut rng,
                                                        message_req.init_root::<$testcase::RequestBuilder>());

                $testcase::handle_request(message_req.get_root::<$testcase::RequestBuilder>().as_reader(),
                                          message_res.init_root::<$testcase::ResponseBuilder>());

                if !$testcase::check_response(message_res.get_root::<$testcase::ResponseBuilder>().as_reader(),
                                              expected) {
                    panic!("Incorrect response.");
                }
            }
        });
    );

macro_rules! pass_by_bytes(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr ) => ({
        let mut request_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut response_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut rng = common::FastRand::new();
        for _ in range(0, $iters) {
            let mut message_req = $reuse.new_builder(0);
            let mut message_res = $reuse.new_builder(1);

            let expected = {
                let request = message_req.init_root::<$testcase::RequestBuilder>();
                $testcase::setup_request(&mut rng, request)
            };

            {
                let response = message_res.init_root::<$testcase::ResponseBuilder>();

                {
                    let mut writer = capnp::io::ArrayOutputStream::new(request_bytes.as_mut_slice());
                    $compression::write_buffered(&mut writer, &message_req)
                }

                let message_reader = $compression::new_buffered_reader(
                    &mut capnp::io::ArrayInputStream::new(request_bytes.as_slice()),
                    capnp::message::DEFAULT_READER_OPTIONS);

                let request_reader : $testcase::RequestReader = message_reader.get_root();
                $testcase::handle_request(request_reader, response);
            }

            {
                let mut writer = capnp::io::ArrayOutputStream::new(response_bytes.as_mut_slice());
                $compression::write_buffered(&mut writer, &message_res)
            }

            let message_reader = $compression::new_buffered_reader(
                &mut capnp::io::ArrayInputStream::new(response_bytes.as_slice()),
                capnp::message::DEFAULT_READER_OPTIONS);

            let response_reader : $testcase::ResponseReader = message_reader.get_root();
            if !$testcase::check_response(response_reader, expected) {
                panic!("Incorrect response.");
            }
        }
    });
    );

macro_rules! server(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr, $input:expr, $output:expr) => ({
            let mut out_buffered = capnp::io::BufferedOutputStreamWrapper::new(&mut $output);
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut $input);
            for _ in range(0, $iters) {
                let mut message_res = $reuse.new_builder(0);

                {
                    let response = message_res.init_root::<$testcase::ResponseBuilder>();
                    let message_reader = $compression::new_buffered_reader(
                        &mut in_buffered,
                        capnp::message::DEFAULT_READER_OPTIONS);
                    let request_reader : $testcase::RequestReader = message_reader.get_root();
                    $testcase::handle_request(request_reader, response);
                }

                $compression::write_buffered(&mut out_buffered, &message_res);
                out_buffered.flush().unwrap();
            }
        });
    );

macro_rules! sync_client(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
            let mut out_stream = ::std::old_io::stdio::stdout_raw();
            let mut in_stream = ::std::old_io::stdio::stdin_raw();
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut in_stream);
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);

                let expected = {
                    let request = message_req.init_root::<$testcase::RequestBuilder>();
                    $testcase::setup_request(&mut rng, request)
                };
                $compression::write(&mut out_stream, &message_req);

                let message_reader = $compression::new_buffered_reader(
                    &mut in_buffered,
                    capnp::message::DEFAULT_READER_OPTIONS);
                let response_reader : $testcase::ResponseReader = message_reader.get_root();
                assert!($testcase::check_response(response_reader, expected));

            }
        });
    );

macro_rules! pass_by_pipe(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
        use std::old_io::process;

        let mut args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();
        args[2] = "client".to_string();

        let mut command = process::Command::new(args[0].as_slice());
        command.args(args.slice(1, args.len()));
        command.stdin(process::CreatePipe(true, false));
        command.stdout(process::CreatePipe(false, true));
        command.stderr(process::Ignored);
        match command.spawn() {
            Ok(ref mut p) => {
                let mut child_std_out = p.stdout.take().unwrap();
                let mut child_std_in = p.stdin.take().unwrap();

                server!($testcase, $reuse, $compression, $iters, child_std_out, child_std_in);
                println!("{}", p.wait().unwrap());
            }
            Err(e) => {
                println!("could not start process: {}", e);
            }
        }
    });
    );

macro_rules! do_testcase(
    ( $testcase:ident, $mode:expr, $reuse:ident, $compression:ident, $iters:expr ) => ({
            match $mode.as_slice() {
                "object" => pass_by_object!($testcase, $reuse, $iters),
                "bytes" => pass_by_bytes!($testcase, $reuse, $compression, $iters),
                "client" => sync_client!($testcase, $reuse, $compression, $iters),
                "server" => {
                    let mut input = ::std::old_io::stdio::stdin_raw();
                    let mut output = ::std::old_io::stdio::stdout_raw();
                    server!($testcase, $reuse, $compression, $iters, input, output)
                }
                "pipe" => pass_by_pipe!($testcase, $reuse, $compression, $iters),
                s => panic!("unrecognized mode: {}", s)
            }
        });
    );

macro_rules! do_testcase1(
    ( $testcase:expr, $mode:expr, $reuse:ident, $compression:ident, $iters:expr) => ({
            match $testcase.as_slice() {
                "carsales" => do_testcase!(carsales, $mode, $reuse, $compression, $iters),
                "catrank" => do_testcase!(catrank, $mode, $reuse, $compression, $iters),
                "eval" => do_testcase!(eval, $mode, $reuse, $compression, $iters),
                s => panic!("unrecognized test case: {}", s)
            }
        });
    );

macro_rules! do_testcase2(
    ( $testcase:expr, $mode:expr, $reuse:expr, $compression:ident, $iters:expr) => ({
            match $reuse.as_slice() {
                "no-reuse" => {
                    let mut scratch = NoScratch;
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                "reuse" => {
                    let mut scratch = UseScratch::new();
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                s => panic!("unrecognized reuse option: {}", s)
            }
        });
    );

pub fn main() {
    let args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();

    if args.len() != 6 {
        println!("USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", args[0]);
        ::std::env::set_exit_status(1);
        return;
    }

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) => {
            println!("Could not parse a u64 from: {}", args[5]);
            ::std::env::set_exit_status(1);
            return;
        }
    };

    match args[4].as_slice() {
        "none" => do_testcase2!(args[1], args[2],  args[3], uncompressed, iters),
        "packed" => do_testcase2!(args[1], args[2], args[3], packed, iters),
        s => panic!("unrecognized compression: {}", s)
    }
}
<commit_msg>mem::transmute -> slice::from_raw_parts_mut<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![crate_type = "bin"]
#![feature(collections, core, env, io, os)]

extern crate capnp;
extern crate rand;

use capnp::{MessageReader, MessageBuilder};

pub mod common;

pub mod carsales_capnp {
  include!(concat!(env!("OUT_DIR"), "/carsales_capnp.rs"));
}
pub mod carsales;

pub mod catrank_capnp {
  include!(concat!(env!("OUT_DIR"), "/catrank_capnp.rs"));
}
pub mod catrank;

pub mod eval_capnp {
  include!(concat!(env!("OUT_DIR"), "/eval_capnp.rs"));
}

pub mod eval;

mod uncompressed {
    use capnp;

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn write_buffered<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        capnp::serialize::write_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R: capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize::new_reader(input_stream, options).unwrap()
    }
}

mod packed {
    use capnp;
    use capnp::serialize_packed::{write_packed_message, write_packed_message_unbuffered};

    pub fn write<T : ::std::old_io::Writer, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message_unbuffered(writer, message).unwrap();
    }

    pub fn write_buffered<T : capnp::io::BufferedOutputStream, U : capnp::message::MessageBuilder>(
        writer: &mut T,
        message: &U) {
        write_packed_message(writer, message).unwrap();
    }

    pub fn new_buffered_reader<R:capnp::io::BufferedInputStream>(
        input_stream : &mut R,
        options : capnp::message::ReaderOptions) -> capnp::serialize::OwnedSpaceMessageReader {
        capnp::serialize_packed::new_reader(input_stream, options).unwrap()
    }

}

const SCRATCH_SIZE : usize = 128 * 1024;

#[derive(Copy)]
pub struct NoScratch;

impl NoScratch {
    fn new_builder(&mut self, _idx : usize) -> capnp::message::MallocMessageBuilder {
        capnp::message::MallocMessageBuilder::new_default()
    }
}

pub struct UseScratch {
    scratch_space : ::std::vec::Vec<capnp::Word>
}

impl UseScratch {
    pub fn new() -> UseScratch {
        UseScratch {
            scratch_space : capnp::common::allocate_zeroed_words(SCRATCH_SIZE * 6)
        }
    }

    fn new_builder<'a>(&mut self, idx : usize) -> capnp::message::ScratchSpaceMallocMessageBuilder<'a> {
        assert!(idx < 6);
        unsafe {
            capnp::message::ScratchSpaceMallocMessageBuilder::new_default(
                ::std::slice::from_raw_parts_mut(self.scratch_space.get_unchecked_mut(idx * SCRATCH_SIZE),
                                                 SCRATCH_SIZE))
        }
    }
}

macro_rules! pass_by_object(
    ( $testcase:ident, $reuse:ident, $iters:expr ) => ({
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);
                let mut message_res = $reuse.new_builder(1);

                let expected = $testcase::setup_request(&mut rng,
                                                        message_req.init_root::<$testcase::RequestBuilder>());

                $testcase::handle_request(message_req.get_root::<$testcase::RequestBuilder>().as_reader(),
                                          message_res.init_root::<$testcase::ResponseBuilder>());

                if !$testcase::check_response(message_res.get_root::<$testcase::ResponseBuilder>().as_reader(),
                                              expected) {
                    panic!("Incorrect response.");
                }
            }
        });
    );

macro_rules! pass_by_bytes(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr ) => ({
        let mut request_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut response_bytes : ::std::vec::Vec<u8> =
            ::std::iter::repeat(0u8).take(SCRATCH_SIZE * 8).collect();
        let mut rng = common::FastRand::new();
        for _ in range(0, $iters) {
            let mut message_req = $reuse.new_builder(0);
            let mut message_res = $reuse.new_builder(1);

            let expected = {
                let request = message_req.init_root::<$testcase::RequestBuilder>();
                $testcase::setup_request(&mut rng, request)
            };

            {
                let response = message_res.init_root::<$testcase::ResponseBuilder>();

                {
                    let mut writer = capnp::io::ArrayOutputStream::new(request_bytes.as_mut_slice());
                    $compression::write_buffered(&mut writer, &message_req)
                }

                let message_reader = $compression::new_buffered_reader(
                    &mut capnp::io::ArrayInputStream::new(request_bytes.as_slice()),
                    capnp::message::DEFAULT_READER_OPTIONS);

                let request_reader : $testcase::RequestReader = message_reader.get_root();
                $testcase::handle_request(request_reader, response);
            }

            {
                let mut writer = capnp::io::ArrayOutputStream::new(response_bytes.as_mut_slice());
                $compression::write_buffered(&mut writer, &message_res)
            }

            let message_reader = $compression::new_buffered_reader(
                &mut capnp::io::ArrayInputStream::new(response_bytes.as_slice()),
                capnp::message::DEFAULT_READER_OPTIONS);

            let response_reader : $testcase::ResponseReader = message_reader.get_root();
            if !$testcase::check_response(response_reader, expected) {
                panic!("Incorrect response.");
            }
        }
    });
    );

macro_rules! server(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr, $input:expr, $output:expr) => ({
            let mut out_buffered = capnp::io::BufferedOutputStreamWrapper::new(&mut $output);
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut $input);
            for _ in range(0, $iters) {
                let mut message_res = $reuse.new_builder(0);

                {
                    let response = message_res.init_root::<$testcase::ResponseBuilder>();
                    let message_reader = $compression::new_buffered_reader(
                        &mut in_buffered,
                        capnp::message::DEFAULT_READER_OPTIONS);
                    let request_reader : $testcase::RequestReader = message_reader.get_root();
                    $testcase::handle_request(request_reader, response);
                }

                $compression::write_buffered(&mut out_buffered, &message_res);
                out_buffered.flush().unwrap();
            }
        });
    );

macro_rules! sync_client(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
            let mut out_stream = ::std::old_io::stdio::stdout_raw();
            let mut in_stream = ::std::old_io::stdio::stdin_raw();
            let mut in_buffered = capnp::io::BufferedInputStreamWrapper::new(&mut in_stream);
            let mut rng = common::FastRand::new();
            for _ in range(0, $iters) {
                let mut message_req = $reuse.new_builder(0);

                let expected = {
                    let request = message_req.init_root::<$testcase::RequestBuilder>();
                    $testcase::setup_request(&mut rng, request)
                };
                $compression::write(&mut out_stream, &message_req);

                let message_reader = $compression::new_buffered_reader(
                    &mut in_buffered,
                    capnp::message::DEFAULT_READER_OPTIONS);
                let response_reader : $testcase::ResponseReader = message_reader.get_root();
                assert!($testcase::check_response(response_reader, expected));

            }
        });
    );

macro_rules! pass_by_pipe(
    ( $testcase:ident, $reuse:ident, $compression:ident, $iters:expr) => ({
        use std::old_io::process;

        let mut args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();
        args[2] = "client".to_string();

        let mut command = process::Command::new(args[0].as_slice());
        command.args(args.slice(1, args.len()));
        command.stdin(process::CreatePipe(true, false));
        command.stdout(process::CreatePipe(false, true));
        command.stderr(process::Ignored);
        match command.spawn() {
            Ok(ref mut p) => {
                let mut child_std_out = p.stdout.take().unwrap();
                let mut child_std_in = p.stdin.take().unwrap();

                server!($testcase, $reuse, $compression, $iters, child_std_out, child_std_in);
                println!("{}", p.wait().unwrap());
            }
            Err(e) => {
                println!("could not start process: {}", e);
            }
        }
    });
    );

macro_rules! do_testcase(
    ( $testcase:ident, $mode:expr, $reuse:ident, $compression:ident, $iters:expr ) => ({
            match $mode.as_slice() {
                "object" => pass_by_object!($testcase, $reuse, $iters),
                "bytes" => pass_by_bytes!($testcase, $reuse, $compression, $iters),
                "client" => sync_client!($testcase, $reuse, $compression, $iters),
                "server" => {
                    let mut input = ::std::old_io::stdio::stdin_raw();
                    let mut output = ::std::old_io::stdio::stdout_raw();
                    server!($testcase, $reuse, $compression, $iters, input, output)
                }
                "pipe" => pass_by_pipe!($testcase, $reuse, $compression, $iters),
                s => panic!("unrecognized mode: {}", s)
            }
        });
    );

macro_rules! do_testcase1(
    ( $testcase:expr, $mode:expr, $reuse:ident, $compression:ident, $iters:expr) => ({
            match $testcase.as_slice() {
                "carsales" => do_testcase!(carsales, $mode, $reuse, $compression, $iters),
                "catrank" => do_testcase!(catrank, $mode, $reuse, $compression, $iters),
                "eval" => do_testcase!(eval, $mode, $reuse, $compression, $iters),
                s => panic!("unrecognized test case: {}", s)
            }
        });
    );

macro_rules! do_testcase2(
    ( $testcase:expr, $mode:expr, $reuse:expr, $compression:ident, $iters:expr) => ({
            match $reuse.as_slice() {
                "no-reuse" => {
                    let mut scratch = NoScratch;
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                "reuse" => {
                    let mut scratch = UseScratch::new();
                    do_testcase1!($testcase, $mode, scratch, $compression, $iters)
                }
                s => panic!("unrecognized reuse option: {}", s)
            }
        });
    );

pub fn main() {
    let args : Vec<String> = ::std::env::args().map(|arg| {arg.into_string().unwrap()}).collect();

    if args.len() != 6 {
        println!("USAGE: {} CASE MODE REUSE COMPRESSION ITERATION_COUNT", args[0]);
        ::std::env::set_exit_status(1);
        return;
    }

    let iters = match args[5].parse::<u64>() {
        Ok(n) => n,
        Err(_) => {
            println!("Could not parse a u64 from: {}", args[5]);
            ::std::env::set_exit_status(1);
            return;
        }
    };

    match args[4].as_slice() {
        "none" => do_testcase2!(args[1], args[2],  args[3], uncompressed, iters),
        "packed" => do_testcase2!(args[1], args[2], args[3], packed, iters),
        s => panic!("unrecognized compression: {}", s)
    }
}
<|endoftext|>


<commit_before>use graphics::*;

// Local crate.
use Vector2d = vector2d::Vector2d;

static EPSILON: f64 = 0.0000000001;

pub fn area(contour: &[Vector2d]) -> f64 {
    let n = contour.len();
    let mut A = 0.0_f64;

    for i in range(0, n) {
        let q = i;
        let p = (i + n - 1) % n;
        A += contour.get(p).unwrap().get_x() * contour.get(q).unwrap().get_y()
            - contour.get(q).unwrap().get_x() * contour.get(p).unwrap().get_y();
    }

    A * 0.5_f64
}

/// InsideTriangle decides if a point P is Inside of the triangle
/// defined by A, B, C.
pub fn inside_triangle(
    Ax: f64, Ay: f64,
    Bx: f64, By: f64,
    Cx: f64, Cy: f64,
    Px: f64, Py: f64
) -> bool {

    let ax = Cx - Bx;
    let ay = Cy - By;
    let bx = Ax - Cx;
    let by = Ay - Cy;
    let cx = Bx - Ax;
    let cy = By - Ay;
    let apx = Px - Ax;
    let apy = Py - Ay;
    let bpx = Px - Bx;
    let bpy = Py - By;
    let cpx = Px - Cx;
    let cpy = Py - Cy;

    let aCROSSbp = ax*bpy - ay*bpx;
    let cCROSSap = cx*apy - cy*apx;
    let bCROSScp = bx*cpy - by*cpx;

    (
        (aCROSSbp >= 0.0_f64)
        && (bCROSScp >= 0.0_f64)
        && (cCROSSap >= 0.0_f64)
    )
}

pub fn snip(
    contour: &[Vector2d],
    triangle: [uint, ..3],
    n: uint,
    vertex_indices: &Vec<uint>
) -> bool {
    let (u, v, w) = (triangle[0], triangle[1], triangle[2]);

    let A = contour.get(*vertex_indices.get(u)).unwrap();
    let B = contour.get(*vertex_indices.get(v)).unwrap();
    let C = contour.get(*vertex_indices.get(w)).unwrap();

    let (Ax, Ay) = (A.get_x(), A.get_y());
    let (Bx, By) = (B.get_x(), B.get_y());
    let (Cx, Cy) = (C.get_x(), C.get_y());

    if EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) {
        return false;
    }

    for p in range(0, n) {
        // Do not check for any of the vertices in the triangle.
        if (p == u) || (p == v) || (p == w) { continue; }

        let P = contour.get(*vertex_indices.get(p)).unwrap();
        if inside_triangle(Ax,Ay,Bx,By,Cx,Cy,P.get_x(),P.get_y()) { return false; }
    }

    true
}

pub fn process(
    contour: &[Vector2d]
) -> Option<Vec<Vector2d>> {
    /* allocate and initialize list of Vertices in polygon */

    let n = contour.len();
    if n < 3 { return None; }

    let mut result: Vec<Vector2d> = Vec::new();
    let mut vertex_indices: Vec<uint> = Vec::with_capacity(n);

    /* we want a counter-clockwise polygon in V */

    // Computes the area which has opposite signs
    // whether the polygon is clock-wise or counter-clockwise.
    if 0.0_f64 < area(contour) {
        for v in range(0, n) { vertex_indices.push(v); }
    } else {
        // Add indices in reverse order.
        for v in range(0, n) { vertex_indices.push((n-1)-v); }
    }

    // Stores the number of vertices.
    // Used instead of `vertex_indices.len()` to emulate removing of vertices.
    let mut number_of_vertices = n;

    /*  remove nv-2 Vertices, creating 1 triangle every time */

    // Used for error detection.
    let mut count = 2 * number_of_vertices;

    let mut v = number_of_vertices - 1;
    while number_of_vertices > 2 {
        /* if we loop, it is probably a non-simple polygon */
        if count <= 0 {
            //** Triangulate: ERROR - probable bad polygon!
            return None;
        }

        count -= 1;

        /* three consecutive vertices in current polygon, <u,v,w> */
        let triangle = [
            v,
            vecmath::modular_offset_index(number_of_vertices, v, 1),
            vecmath::modular_offset_index(number_of_vertices, v, 2)
        ];
        v = triangle[1];

        if snip(contour, triangle, number_of_vertices, &mut vertex_indices) {
            for &i in triangle.iter() {
                result.push(*contour.get(*vertex_indices.get(i)).unwrap());
            }

            /* remove v from remaining polygon */
            for i in range(0, number_of_vertices - 3) {
                let s = v + i;
                let t = v + i + 1;

                *vertex_indices.get_mut(s) = *vertex_indices.get(t);
            }

            // "Removed" a vertex.
            number_of_vertices -= 1;

            /* resest error detection counter */
            count = 2 * number_of_vertices;
        }
    }

    Some(result)
}

<commit_msg>Simplified code<commit_after>use graphics::*;

// Local crate.
use Vector2d = vector2d::Vector2d;

static EPSILON: f64 = 0.0000000001;

pub fn area(contour: &[Vector2d]) -> f64 {
    let n = contour.len();
    let mut A = 0.0_f64;

    for i in range(0, n) {
        let q = i;
        let p = vecmath::modular_offset_index(n, i, -1);
        A += contour.get(p).unwrap().get_x() * contour.get(q).unwrap().get_y()
            - contour.get(q).unwrap().get_x() * contour.get(p).unwrap().get_y();
    }

    A * 0.5_f64
}

/// InsideTriangle decides if a point P is Inside of the triangle
/// defined by A, B, C.
pub fn inside_triangle(
    Ax: f64, Ay: f64,
    Bx: f64, By: f64,
    Cx: f64, Cy: f64,
    Px: f64, Py: f64
) -> bool {

    let ax = Cx - Bx;
    let ay = Cy - By;
    let bx = Ax - Cx;
    let by = Ay - Cy;
    let cx = Bx - Ax;
    let cy = By - Ay;
    let apx = Px - Ax;
    let apy = Py - Ay;
    let bpx = Px - Bx;
    let bpy = Py - By;
    let cpx = Px - Cx;
    let cpy = Py - Cy;

    let aCROSSbp = ax*bpy - ay*bpx;
    let cCROSSap = cx*apy - cy*apx;
    let bCROSScp = bx*cpy - by*cpx;

    (
        (aCROSSbp >= 0.0_f64)
        && (bCROSScp >= 0.0_f64)
        && (cCROSSap >= 0.0_f64)
    )
}

pub fn snip(
    contour: &[Vector2d],
    triangle: [uint, ..3],
    n: uint,
    vertex_indices: &Vec<uint>
) -> bool {
    let (u, v, w) = (triangle[0], triangle[1], triangle[2]);

    let A = contour.get(*vertex_indices.get(u)).unwrap();
    let B = contour.get(*vertex_indices.get(v)).unwrap();
    let C = contour.get(*vertex_indices.get(w)).unwrap();

    let (Ax, Ay) = (A.get_x(), A.get_y());
    let (Bx, By) = (B.get_x(), B.get_y());
    let (Cx, Cy) = (C.get_x(), C.get_y());

    if EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) {
        return false;
    }

    for p in range(0, n) {
        // Do not check for any of the vertices in the triangle.
        if (p == u) || (p == v) || (p == w) { continue; }

        let P = contour.get(*vertex_indices.get(p)).unwrap();
        if inside_triangle(Ax,Ay,Bx,By,Cx,Cy,P.get_x(),P.get_y()) { return false; }
    }

    true
}

pub fn process(
    contour: &[Vector2d]
) -> Option<Vec<Vector2d>> {
    /* allocate and initialize list of Vertices in polygon */

    let n = contour.len();
    if n < 3 { return None; }

    let mut result: Vec<Vector2d> = Vec::new();
    let mut vertex_indices: Vec<uint> = Vec::with_capacity(n);

    /* we want a counter-clockwise polygon in V */

    // Computes the area which has opposite signs
    // whether the polygon is clock-wise or counter-clockwise.
    if 0.0_f64 < area(contour) {
        for v in range(0, n) { vertex_indices.push(v); }
    } else {
        // Add indices in reverse order.
        for v in range(0, n) { vertex_indices.push((n-1)-v); }
    }

    // Stores the number of vertices.
    // Used instead of `vertex_indices.len()` to emulate removing of vertices.
    let mut number_of_vertices = n;

    /*  remove nv-2 Vertices, creating 1 triangle every time */

    // Used for error detection.
    let mut count = 2 * number_of_vertices;

    let mut v = number_of_vertices - 1;
    while number_of_vertices > 2 {
        /* if we loop, it is probably a non-simple polygon */
        if count <= 0 {
            //** Triangulate: ERROR - probable bad polygon!
            return None;
        }

        count -= 1;

        /* three consecutive vertices in current polygon, <u,v,w> */
        let triangle = [
            v,
            vecmath::modular_offset_index(number_of_vertices, v, 1),
            vecmath::modular_offset_index(number_of_vertices, v, 2)
        ];
        v = triangle[1];

        if snip(contour, triangle, number_of_vertices, &mut vertex_indices) {
            for &i in triangle.iter() {
                result.push(*contour.get(*vertex_indices.get(i)).unwrap());
            }

            /* remove v from remaining polygon */
            for i in range(0, number_of_vertices - 3) {
                let s = v + i;
                let t = v + i + 1;

                *vertex_indices.get_mut(s) = *vertex_indices.get(t);
            }

            // "Removed" a vertex.
            number_of_vertices -= 1;

            /* resest error detection counter */
            count = 2 * number_of_vertices;
        }
    }

    Some(result)
}

<|endoftext|>


<commit_before>use regex;

use crate::template::{TemplateInput, TemplateProcessor};

pub struct ClassicProcessor;

impl TemplateProcessor for ClassicProcessor {
    fn process(template: &str, values: &TemplateInput) -> Result<String, String> {
        let find_template_vars = regex::Regex::new(r#"\{\{(?:\|([^\|]*)\|)?([\w\d]*)(?:\|([^\|]*)\|)?\}\}"#).unwrap();

        let variables = &values.values;

        let mut variables_not_found: Vec<String> = Vec::new();

        let output = find_template_vars.replace_all(&template, |captures: &regex::Captures| {
            let prefix = captures.get(1).map(|v| v.as_str()).unwrap_or("");
            let variable_name = &captures[2];
            let suffix = captures.get(3).map(|v| v.as_str()).unwrap_or("");

            let variable_value = if let Some(value) = variables.get(variable_name).as_ref() {
                value
            } else {
                variables_not_found.push(variable_name.to_owned());

                ""
            };

            if variable_value.is_empty() {
                // If variable is empty, return a blank string.
                "".to_owned()
            } else {
                // If variable is not empty, concatenate prefix, value and suffix
                format!("{}{}{}", prefix, variable_value, suffix)
            }
        }).into_owned();

        if !variables_not_found.is_empty() {
            return Err(format!("Variables not found: {}", variables_not_found.join(", ")));
        }

        Ok(output)
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;

    use super::*;

    fn make_values() -> TemplateInput {
        let mut variables: HashMap<String, String> = HashMap::new();

        variables.insert("TheVariable".to_owned(), "42".to_owned());
        variables.insert("EmptyVariable".to_owned(), "".to_owned());

        TemplateInput {
            values: variables,
        }
    }

    macro_rules! test_processor {
        (
            $test_name:ident : $processor:ident {
                ok {
                    $( $template_data:expr => $expected_output:expr )*
                }

                err {
                    $( $err_template_data:expr => $err_expected_output:expr )*
                }
            }
        ) => {
            #[test]
            fn $test_name() {
                let values = make_values();

                $( assert_eq!($processor::process($template_data, &values).unwrap(), $expected_output); )*

                $( assert_eq!($processor::process($err_template_data, &values), Err($err_expected_output.to_owned())); )*
            }
        };
    }

    test_processor! {
        test_classic : ClassicProcessor {
            ok {
                "BLAH={{TheVariable}};" => "BLAH=42;"
                "BLAH={{|.|TheVariable}};" => "BLAH=.42;"
                "BLAH={{|.|TheVariable|.|}};" => "BLAH=.42.;"
                "BLAH={{TheVariable|.|}};" => "BLAH=42.;"
                "BLAH={{EmptyVariable}};" => "BLAH=;"
                "BLAH={{|.|EmptyVariable}};" => "BLAH=;"
                "BLAH={{|.|EmptyVariable|.|}};" => "BLAH=;"
                "BLAH={{EmptyVariable|.|}};" => "BLAH=;"
                "BLAH={{TheVariable}};YADA={{EmptyVariable}};" => "BLAH=42;YADA=;"
                "BLAH={{TheVariable}}.{{TheVariable}}.{{TheVariable}};" => "BLAH=42.42.42;"
                "BLAH={{TheVariable}}.{{TheVariable}}.{{TheVariable}}{{|-|TheVariable}}{{|+|TheVariable}};" => "BLAH=42.42.42-42+42;"
                "BLAH={{|prefix|TheVariable}};" => "BLAH=prefix42;"
                "BLAH={{TheVariable|suffix|}};" => "BLAH=42suffix;"
            }

            err {
                "BLAH={{NonExistentVariable}};" => "Variables not found: NonExistentVariable"
            }
        }
    }
}
<commit_msg>refactor: lazy_static! the classic template processor regex<commit_after>use lazy_static::lazy_static;
use regex::Regex;

use crate::template::{TemplateInput, TemplateProcessor};

lazy_static! {
    static ref REGEX_FIND_TEMPLATE_VARS: Regex = Regex::new(r#"\{\{(?:\|([^\|]*)\|)?([\w\d]*)(?:\|([^\|]*)\|)?\}\}"#).unwrap();
}

pub struct ClassicProcessor;

impl TemplateProcessor for ClassicProcessor {
    fn process(template: &str, values: &TemplateInput) -> Result<String, String> {
        let variables = &values.values;

        let mut variables_not_found: Vec<String> = Vec::new();

        let output = REGEX_FIND_TEMPLATE_VARS.replace_all(&template, |captures: &regex::Captures| {
            let prefix = captures.get(1).map(|v| v.as_str()).unwrap_or("");
            let variable_name = &captures[2];
            let suffix = captures.get(3).map(|v| v.as_str()).unwrap_or("");

            let variable_value = if let Some(value) = variables.get(variable_name) {
                value
            } else {
                variables_not_found.push(variable_name.to_owned());

                ""
            };

            if variable_value.is_empty() {
                // If variable is empty, return a blank string.
                "".to_owned()
            } else {
                // If variable is not empty, concatenate prefix, value and suffix
                format!("{}{}{}", prefix, variable_value, suffix)
            }
        }).into_owned();

        if !variables_not_found.is_empty() {
            return Err(format!("Variables not found: {}", variables_not_found.join(", ")));
        }

        Ok(output)
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;

    use super::*;

    fn make_values() -> TemplateInput {
        let mut variables: HashMap<String, String> = HashMap::new();

        variables.insert("TheVariable".to_owned(), "42".to_owned());
        variables.insert("EmptyVariable".to_owned(), "".to_owned());

        TemplateInput {
            values: variables,
        }
    }

    macro_rules! test_processor {
        (
            $test_name:ident : $processor:ident {
                ok {
                    $( $template_data:expr => $expected_output:expr )*
                }

                err {
                    $( $err_template_data:expr => $err_expected_output:expr )*
                }
            }
        ) => {
            #[test]
            fn $test_name() {
                let values = make_values();

                $( assert_eq!($processor::process($template_data, &values).unwrap(), $expected_output); )*

                $( assert_eq!($processor::process($err_template_data, &values), Err($err_expected_output.to_owned())); )*
            }
        };
    }

    test_processor! {
        test_classic : ClassicProcessor {
            ok {
                "BLAH={{TheVariable}};" => "BLAH=42;"
                "BLAH={{|.|TheVariable}};" => "BLAH=.42;"
                "BLAH={{|.|TheVariable|.|}};" => "BLAH=.42.;"
                "BLAH={{TheVariable|.|}};" => "BLAH=42.;"
                "BLAH={{EmptyVariable}};" => "BLAH=;"
                "BLAH={{|.|EmptyVariable}};" => "BLAH=;"
                "BLAH={{|.|EmptyVariable|.|}};" => "BLAH=;"
                "BLAH={{EmptyVariable|.|}};" => "BLAH=;"
                "BLAH={{TheVariable}};YADA={{EmptyVariable}};" => "BLAH=42;YADA=;"
                "BLAH={{TheVariable}}.{{TheVariable}}.{{TheVariable}};" => "BLAH=42.42.42;"
                "BLAH={{TheVariable}}.{{TheVariable}}.{{TheVariable}}{{|-|TheVariable}}{{|+|TheVariable}};" => "BLAH=42.42.42-42+42;"
                "BLAH={{|prefix|TheVariable}};" => "BLAH=prefix42;"
                "BLAH={{TheVariable|suffix|}};" => "BLAH=42suffix;"
            }

            err {
                "BLAH={{NonExistentVariable}};" => "Variables not found: NonExistentVariable"
            }
        }
    }
}
<|endoftext|>