<commit_before>// See LICENSE file for copyright and license details.

#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;
extern crate cgmath;
extern crate serialize;

use self::glutin::{Event, VirtualKeyCode}; // TODO: why 'self'?
use core_types::{Size2, MInt};
use visualizer_types::{Color3, Color4, ColorId};
use mgl::Mgl;
use mgl;
use std::mem;

// TODO: remove 'gl'
use gl;
use gl::types::{GLfloat, GLuint};

static VS_SRC: &'static str = "\
    #version 100\n\
    attribute vec2 position;\n\
    void main() {\n\
        gl_Position = vec4(position, 0.0, 1.0);\n\
    }\n\
";

static FS_SRC: &'static str = "\
    #version 100\n\
    precision mediump float;
    uniform vec4 col;\n\
    void main() {\n\
        gl_FragColor = col;\n\
    }\n\
";

fn print_gl_info(mgl: &Mgl) {
    println!("GL_VERSION: {}", mgl.get_info(gl::VERSION));
    println!("GL_SHADING_LANGUAGE_VERSION: {}", mgl.get_info(gl::SHADING_LANGUAGE_VERSION));
    println!("GL_VENDOR: {}", mgl.get_info(gl::VENDOR));
    println!("GL_RENDERER: {}", mgl.get_info(gl::RENDERER));
    // println!("GL_EXTENSIONS: {}", mgl.get_info(gl::EXTENSIONS));
}

// TODO: Create 'Shader' class
fn compile_shaders(mgl: &Mgl) -> GLuint {
    let vs = mgl::compile_shader(&mgl.gl, VS_SRC, gl::VERTEX_SHADER);
    let fs = mgl::compile_shader(&mgl.gl, FS_SRC, gl::FRAGMENT_SHADER);
    mgl::link_program(&mgl.gl, vs, fs)
}

pub struct Visualizer {
    mgl: Mgl,
    window: glutin::Window,
    should_close: bool,
    color_counter: i32, // TODO: remove
    test_color: Color4,
    program: GLuint,
    color_unifrom_location: ColorId,
}

impl Visualizer {
    pub fn new() -> Visualizer {
        let window = glutin::Window::new().ok()
            .expect("Can`t create window");
        unsafe {
            window.make_current();
        };
        let mut mgl = Mgl::new(|s| window.get_proc_address(s));
        print_gl_info(&mgl);
        let program = compile_shaders(&mgl);
        let color_unifrom_location = ColorId {
            id: mgl.get_uniform(program, "col") as GLuint
        };
        mgl.set_clear_color(Color3{r: 0.0, g: 0.0, b: 0.4});
        Visualizer {
            mgl: mgl,
            window: window,
            should_close: false,
            color_counter: 0,
            test_color: Color4{r: 0.0, g: 0.0, b: 0.0, a: 0.0},
            program: program,
            color_unifrom_location: color_unifrom_location,
        }
    }

    pub fn is_running(&self) -> bool {
        !self.should_close
    }

    fn handle_events(&mut self) {
        let events = self.window.poll_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
        for event in events.iter() {
            match *event {
                Event::KeyboardInput(_, _, Some(VirtualKeyCode::Escape))
                    | Event::Closed =>
                {
                    self.should_close = true;
                },
                _ => {},
            }
        }
    }

    fn update_test_color(&mut self) {
        self.test_color = match self.color_counter {
            0 => Color4{r: 1.0, g: 0.0, b: 0.0, a: 1.0},
            30 => Color4{r: 0.0, g: 1.0, b: 0.0, a: 1.0},
            60 => Color4{r: 0.0, g: 0.0, b: 1.0, a: 1.0},
            _ => self.test_color,
        };
        self.color_counter += 1;
        if self.color_counter > 90 {
            self.color_counter = -1;
        }
    }

    fn draw(&mut self) {
        self.mgl.clear_screen();
        let vertices: [GLfloat, ..3 * 3] = [
            0.0,  0.5, 0.0,
            0.5, -0.5, 0.0,
            -0.5, -0.5, 0.0,
        ];
        let (w, h) = self.window.get_inner_size()
            .expect("Can`t get window size");
        self.mgl.set_viewport(Size2{w: w as MInt, h: h as MInt});
        unsafe {
            self.mgl.gl.UseProgram(self.program);
            self.mgl.set_uniform_color(self.color_unifrom_location, &self.test_color);
            self.mgl.gl.VertexAttribPointer(
                0, 3, gl::FLOAT, gl::FALSE, 0, mem::transmute(&vertices));
            self.mgl.gl.EnableVertexAttribArray(0);
            self.mgl.gl.DrawArrays(gl::TRIANGLES, 0, 3);
        }
        self.window.swap_buffers();
    }

    pub fn tick(&mut self) {
        self.handle_events();
        // self.logic();
        self.update_test_color();
        self.draw();
        // self.update_time();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Use glutin::WindowsBuilder for setting gl version<commit_after>// See LICENSE file for copyright and license details.

#[phase(plugin)]
extern crate gl_generator;

extern crate glutin;
extern crate cgmath;
extern crate serialize;

use self::glutin::{Event, VirtualKeyCode}; // TODO: why 'self'?
use core_types::{Size2, MInt};
use visualizer_types::{Color3, Color4, ColorId};
use mgl::Mgl;
use mgl;
use std::mem;

// TODO: remove 'gl'
use gl;
use gl::types::{GLfloat, GLuint};

static VS_SRC: &'static str = "\
    #version 100\n\
    attribute vec2 position;\n\
    void main() {\n\
        gl_Position = vec4(position, 0.0, 1.0);\n\
    }\n\
";

static FS_SRC: &'static str = "\
    #version 100\n\
    precision mediump float;
    uniform vec4 col;\n\
    void main() {\n\
        gl_FragColor = col;\n\
    }\n\
";

fn print_gl_info(mgl: &Mgl) {
    println!("GL_VERSION: {}", mgl.get_info(gl::VERSION));
    println!("GL_SHADING_LANGUAGE_VERSION: {}", mgl.get_info(gl::SHADING_LANGUAGE_VERSION));
    println!("GL_VENDOR: {}", mgl.get_info(gl::VENDOR));
    println!("GL_RENDERER: {}", mgl.get_info(gl::RENDERER));
    // println!("GL_EXTENSIONS: {}", mgl.get_info(gl::EXTENSIONS));
}

// TODO: Create 'Shader' class
fn compile_shaders(mgl: &Mgl) -> GLuint {
    let vs = mgl::compile_shader(&mgl.gl, VS_SRC, gl::VERTEX_SHADER);
    let fs = mgl::compile_shader(&mgl.gl, FS_SRC, gl::FRAGMENT_SHADER);
    mgl::link_program(&mgl.gl, vs, fs)
}

pub struct Visualizer {
    mgl: Mgl,
    window: glutin::Window,
    should_close: bool,
    color_counter: i32, // TODO: remove
    test_color: Color4,
    program: GLuint,
    color_unifrom_location: ColorId,
}

impl Visualizer {
    pub fn new() -> Visualizer {
        let window_builder = glutin::WindowBuilder::new().with_gl_version((2, 0));
        let window = window_builder.build().ok().expect("Can`t create window");
        unsafe {
            window.make_current();
        };
        let mut mgl = Mgl::new(|s| window.get_proc_address(s));
        print_gl_info(&mgl);
        let program = compile_shaders(&mgl);
        let color_unifrom_location = ColorId {
            id: mgl.get_uniform(program, "col") as GLuint
        };
        mgl.set_clear_color(Color3{r: 0.0, g: 0.0, b: 0.4});
        Visualizer {
            mgl: mgl,
            window: window,
            should_close: false,
            color_counter: 0,
            test_color: Color4{r: 0.0, g: 0.0, b: 0.0, a: 0.0},
            program: program,
            color_unifrom_location: color_unifrom_location,
        }
    }

    pub fn is_running(&self) -> bool {
        !self.should_close
    }

    fn handle_events(&mut self) {
        let events = self.window.poll_events().collect::<Vec<_>>();
        if !events.is_empty() {
            println!("{}", events);
        }
        for event in events.iter() {
            match *event {
                Event::KeyboardInput(_, _, Some(VirtualKeyCode::Escape))
                    | Event::Closed =>
                {
                    self.should_close = true;
                },
                _ => {},
            }
        }
    }

    fn update_test_color(&mut self) {
        self.test_color = match self.color_counter {
            0 => Color4{r: 1.0, g: 0.0, b: 0.0, a: 1.0},
            30 => Color4{r: 0.0, g: 1.0, b: 0.0, a: 1.0},
            60 => Color4{r: 0.0, g: 0.0, b: 1.0, a: 1.0},
            _ => self.test_color,
        };
        self.color_counter += 1;
        if self.color_counter > 90 {
            self.color_counter = -1;
        }
    }

    fn draw(&mut self) {
        self.mgl.clear_screen();
        let vertices: [GLfloat, ..3 * 3] = [
            0.0,  0.5, 0.0,
            0.5, -0.5, 0.0,
            -0.5, -0.5, 0.0,
        ];
        let (w, h) = self.window.get_inner_size()
            .expect("Can`t get window size");
        self.mgl.set_viewport(Size2{w: w as MInt, h: h as MInt});
        unsafe {
            self.mgl.gl.UseProgram(self.program);
            self.mgl.set_uniform_color(self.color_unifrom_location, &self.test_color);
            self.mgl.gl.VertexAttribPointer(
                0, 3, gl::FLOAT, gl::FALSE, 0, mem::transmute(&vertices));
            self.mgl.gl.EnableVertexAttribArray(0);
            self.mgl.gl.DrawArrays(gl::TRIANGLES, 0, 3);
        }
        self.window.swap_buffers();
    }

    pub fn tick(&mut self) {
        self.handle_events();
        // self.logic();
        self.update_test_color();
        self.draw();
        // self.update_time();
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>use iron::middleware::Handler;
use router::Router;
use std::collections::HashSet;

const DOC_RUST_LANG_ORG_REDIRECTS: &[&str] = &["alloc", "core", "proc_macro", "std", "test"];

pub(super) fn build_routes() -> Routes {
    let mut routes = Routes::new();

    routes.static_resource("/style.css", super::style_css_handler);
    routes.static_resource("/robots.txt", super::sitemap::robots_txt_handler);
    routes.static_resource("/sitemap.xml", super::sitemap::sitemap_handler);
    routes.static_resource("/opensearch.xml", super::opensearch_xml_handler);

    routes.internal_page("/", super::releases::home_page);

    routes.internal_page("/about", super::sitemap::about_handler);
    routes.internal_page("/about/metrics", super::metrics::metrics_handler);

    routes.internal_page("/releases", super::releases::recent_releases_handler);
    routes.static_resource("/releases/feed", super::releases::releases_feed_handler);
    routes.internal_page("/releases/:author", super::releases::author_handler);
    routes.internal_page("/releases/:author/:page", super::releases::author_handler);
    routes.internal_page("/releases/activity", super::releases::activity_handler);
    routes.internal_page("/releases/search", super::releases::search_handler);
    routes.internal_page("/releases/queue", super::releases::build_queue_handler);
    routes.internal_page(
        "/releases/recent/:page",
        super::releases::recent_releases_handler,
    );
    routes.internal_page(
        "/releases/stars",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/stars/:page",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/recent-failures",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/recent-failures/:page",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/failures",
        super::releases::releases_failures_by_stars_handler,
    );
    routes.internal_page(
        "/releases/failures/:page",
        super::releases::releases_failures_by_stars_handler,
    );

    routes.internal_page("/crate/:name", super::crate_details::crate_details_handler);
    routes.internal_page(
        "/crate/:name/:version",
        super::crate_details::crate_details_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds",
        super::builds::build_list_handler,
    );
    routes.static_resource(
        "/crate/:name/:version/builds.json",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds/:id",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source/",
        super::source::source_browser_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source/*",
        super::source::source_browser_handler,
    );

    routes.rustdoc_page("/:crate", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/badge.svg", super::rustdoc::badge_handler);
    routes.rustdoc_page(
        "/:crate/:version",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/settings.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/all.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/*.html",
        super::rustdoc::rustdoc_html_server_handler,
    );

    for redirect in DOC_RUST_LANG_ORG_REDIRECTS {
        routes.internal_page(
            &format!("/{}", redirect),
            super::rustdoc::RustLangRedirector::new(redirect),
        );
    }

    routes
}

pub(super) struct Routes {
    get: Vec<(String, Box<dyn Handler>)>,
    rustdoc_get: Vec<(String, Box<dyn Handler>)>,
    page_prefixes: HashSet<String>,
}

impl Routes {
    fn new() -> Self {
        Self {
            get: Vec::new(),
            rustdoc_get: Vec::new(),
            page_prefixes: HashSet::new(),
        }
    }

    pub(super) fn page_prefixes(&self) -> HashSet<String> {
        self.page_prefixes.clone()
    }

    pub(super) fn iron_router(mut self) -> Router {
        let mut router = Router::new();
        for (pattern, handler) in self.get.drain(..) {
            router.get(&pattern, handler, calculate_id(&pattern));
        }

        // All rustdoc pages have the prefixes of other docs.rs pages blacklisted. This prevents,
        // for example, a crate named "about" from hijacking /about/0.1.0/index.html.
        let blacklist = self.page_prefixes();
        for (pattern, handler) in self.rustdoc_get.drain(..) {
            router.get(
                &pattern,
                BlockBlacklistedPrefixes::new(blacklist.clone(), handler),
                calculate_id(&pattern),
            );
        }

        router
    }

    /// A static resource is a normal page without any special behavior on the router side.
    fn static_resource(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));
    }

    /// Internal pages are docs.rs's own pages, instead of the documentation of a crate uploaded by
    /// an user. The router adds these extra things when adding a new internal page:
    ///
    /// - The first component of the page's URL will be registered as a "page prefix". Page
    /// prefixes are blacklisted by rustdoc pages, to prevent a crate named the same as a prefix
    /// from hijacking docs.rs's own URLs.
    ///
    /// - If the page URL doesn't end with a slash, a redirect from the URL with the trailing slash
    /// to the one without is automatically added.
    fn internal_page(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));

        // Automatically add another route ending with / that redirects to the slash-less route.
        if !pattern.ends_with('/') {
            let pattern = format!("{}/", pattern);
            self.get
                .push((pattern.to_string(), Box::new(remove_slashes)));
        }

        // Register the prefix if it's not the home page and the first path component is not a
        // pattern or a wildcard.
        if pattern != "/" {
            if let Some(first_component) = pattern.trim_matches('/').split('/').next() {
                if !first_component.contains('*') && !first_component.starts_with(':') {
                    self.page_prefixes.insert(first_component.to_string());
                }
            }
        }
    }

    /// A rustdoc page is a page serving generated documentation. It's similar to a static
    /// resource, but path prefixes are automatically blacklisted (see internal pages to learn more
    /// about page prefixes).
    fn rustdoc_page(&mut self, pattern: &str, handler: impl Handler) {
        self.rustdoc_get
            .push((pattern.to_string(), Box::new(handler)));
    }
}

/// Simple Iron route that redirects to the same path without the trailing slash, for example
/// /foo/bar/baz/ to /foo/bar/baz.
fn remove_slashes(req: &mut iron::Request) -> iron::IronResult<iron::Response> {
    let mut url: iron::url::Url = req.url.clone().into();
    url.set_path(&url.path().trim_end_matches('/').to_string());
    Ok(iron::Response::with((
        iron::status::Found,
        iron::modifiers::Redirect(iron::Url::parse(&url.to_string()).unwrap()),
    )))
}

/// Iron Middleware that prevents requests to blacklisted prefixes.
///
/// In our application, a prefix is blacklisted if a docs.rs page exists below it. For example,
/// since /releases/queue is a docs.rs page, /releases is a blacklisted prefix.
///
/// The middleware must be used for all the pages serving crates at the top level, to prevent a
/// crate from putting their own content in an URL that's supposed to be used by docs.rs.
pub(super) struct BlockBlacklistedPrefixes {
    blacklist: HashSet<String>,
    handler: Box<dyn Handler>,
}

impl BlockBlacklistedPrefixes {
    pub(super) fn new(blacklist: HashSet<String>, handler: Box<dyn Handler>) -> Self {
        Self { blacklist, handler }
    }
}

impl Handler for BlockBlacklistedPrefixes {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        if let Some(prefix) = req.url.path().get(0) {
            if self.blacklist.contains(*prefix) {
                return Err(iron::IronError::new(
                    super::error::Nope::CrateNotFound,
                    iron::status::NotFound,
                ));
            }
        }
        self.handler.handle(req)
    }
}

/// Automatically generate a Route ID from a pattern. Every non-alphanumeric character is replaced
/// with `_`.
fn calculate_id(pattern: &str) -> String {
    pattern
        .chars()
        .map(|c| if c.is_alphanumeric() { c } else { '_' })
        .collect()
}
<commit_msg>web: add /crate/:name/:version/source redirect<commit_after>use iron::middleware::Handler;
use router::Router;
use std::collections::HashSet;

const DOC_RUST_LANG_ORG_REDIRECTS: &[&str] = &["alloc", "core", "proc_macro", "std", "test"];

pub(super) fn build_routes() -> Routes {
    let mut routes = Routes::new();

    routes.static_resource("/style.css", super::style_css_handler);
    routes.static_resource("/robots.txt", super::sitemap::robots_txt_handler);
    routes.static_resource("/sitemap.xml", super::sitemap::sitemap_handler);
    routes.static_resource("/opensearch.xml", super::opensearch_xml_handler);

    routes.internal_page("/", super::releases::home_page);

    routes.internal_page("/about", super::sitemap::about_handler);
    routes.internal_page("/about/metrics", super::metrics::metrics_handler);

    routes.internal_page("/releases", super::releases::recent_releases_handler);
    routes.static_resource("/releases/feed", super::releases::releases_feed_handler);
    routes.internal_page("/releases/:author", super::releases::author_handler);
    routes.internal_page("/releases/:author/:page", super::releases::author_handler);
    routes.internal_page("/releases/activity", super::releases::activity_handler);
    routes.internal_page("/releases/search", super::releases::search_handler);
    routes.internal_page("/releases/queue", super::releases::build_queue_handler);
    routes.internal_page(
        "/releases/recent/:page",
        super::releases::recent_releases_handler,
    );
    routes.internal_page(
        "/releases/stars",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/stars/:page",
        super::releases::releases_by_stars_handler,
    );
    routes.internal_page(
        "/releases/recent-failures",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/recent-failures/:page",
        super::releases::releases_recent_failures_handler,
    );
    routes.internal_page(
        "/releases/failures",
        super::releases::releases_failures_by_stars_handler,
    );
    routes.internal_page(
        "/releases/failures/:page",
        super::releases::releases_failures_by_stars_handler,
    );

    routes.internal_page("/crate/:name", super::crate_details::crate_details_handler);
    routes.internal_page(
        "/crate/:name/:version",
        super::crate_details::crate_details_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds",
        super::builds::build_list_handler,
    );
    routes.static_resource(
        "/crate/:name/:version/builds.json",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/builds/:id",
        super::builds::build_list_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source",
        SimpleRedirect::new(|url| url.set_path(&format!("{}/", url.path()))),
    );
    routes.internal_page(
        "/crate/:name/:version/source/",
        super::source::source_browser_handler,
    );
    routes.internal_page(
        "/crate/:name/:version/source/*",
        super::source::source_browser_handler,
    );

    routes.rustdoc_page("/:crate", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/", super::rustdoc::rustdoc_redirector_handler);
    routes.rustdoc_page("/:crate/badge.svg", super::rustdoc::badge_handler);
    routes.rustdoc_page(
        "/:crate/:version",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/settings.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/all.html",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target",
        super::rustdoc::rustdoc_redirector_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/",
        super::rustdoc::rustdoc_html_server_handler,
    );
    routes.rustdoc_page(
        "/:crate/:version/:target/*.html",
        super::rustdoc::rustdoc_html_server_handler,
    );

    for redirect in DOC_RUST_LANG_ORG_REDIRECTS {
        routes.internal_page(
            &format!("/{}", redirect),
            super::rustdoc::RustLangRedirector::new(redirect),
        );
    }

    routes
}

pub(super) struct Routes {
    get: Vec<(String, Box<dyn Handler>)>,
    rustdoc_get: Vec<(String, Box<dyn Handler>)>,
    page_prefixes: HashSet<String>,
}

impl Routes {
    fn new() -> Self {
        Self {
            get: Vec::new(),
            rustdoc_get: Vec::new(),
            page_prefixes: HashSet::new(),
        }
    }

    pub(super) fn page_prefixes(&self) -> HashSet<String> {
        self.page_prefixes.clone()
    }

    pub(super) fn iron_router(mut self) -> Router {
        let mut router = Router::new();
        for (pattern, handler) in self.get.drain(..) {
            router.get(&pattern, handler, calculate_id(&pattern));
        }

        // All rustdoc pages have the prefixes of other docs.rs pages blacklisted. This prevents,
        // for example, a crate named "about" from hijacking /about/0.1.0/index.html.
        let blacklist = self.page_prefixes();
        for (pattern, handler) in self.rustdoc_get.drain(..) {
            router.get(
                &pattern,
                BlockBlacklistedPrefixes::new(blacklist.clone(), handler),
                calculate_id(&pattern),
            );
        }

        router
    }

    /// A static resource is a normal page without any special behavior on the router side.
    fn static_resource(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));
    }

    /// Internal pages are docs.rs's own pages, instead of the documentation of a crate uploaded by
    /// an user. The router adds these extra things when adding a new internal page:
    ///
    /// - The first component of the page's URL will be registered as a "page prefix". Page
    /// prefixes are blacklisted by rustdoc pages, to prevent a crate named the same as a prefix
    /// from hijacking docs.rs's own URLs.
    ///
    /// - If the page URL doesn't end with a slash, a redirect from the URL with the trailing slash
    /// to the one without is automatically added.
    fn internal_page(&mut self, pattern: &str, handler: impl Handler) {
        self.get.push((pattern.to_string(), Box::new(handler)));

        // Automatically add another route ending with / that redirects to the slash-less route.
        if !pattern.ends_with('/') {
            let pattern = format!("{}/", pattern);
            self.get.push((
                pattern.to_string(),
                Box::new(SimpleRedirect::new(|url| {
                    url.set_path(&url.path().trim_end_matches('/').to_string())
                })),
            ));
        }

        // Register the prefix if it's not the home page and the first path component is not a
        // pattern or a wildcard.
        if pattern != "/" {
            if let Some(first_component) = pattern.trim_matches('/').split('/').next() {
                if !first_component.contains('*') && !first_component.starts_with(':') {
                    self.page_prefixes.insert(first_component.to_string());
                }
            }
        }
    }

    /// A rustdoc page is a page serving generated documentation. It's similar to a static
    /// resource, but path prefixes are automatically blacklisted (see internal pages to learn more
    /// about page prefixes).
    fn rustdoc_page(&mut self, pattern: &str, handler: impl Handler) {
        self.rustdoc_get
            .push((pattern.to_string(), Box::new(handler)));
    }
}

#[derive(Copy, Clone)]
struct SimpleRedirect {
    url_mangler: fn(&mut iron::url::Url),
}

impl SimpleRedirect {
    fn new(url_mangler: fn(&mut iron::url::Url)) -> Self {
        Self { url_mangler }
    }
}

impl Handler for SimpleRedirect {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        let mut url: iron::url::Url = req.url.clone().into();
        (self.url_mangler)(&mut url);
        Ok(iron::Response::with((
            iron::status::Found,
            iron::modifiers::Redirect(iron::Url::parse(&url.to_string()).unwrap()),
        )))
    }
}

/// Iron Middleware that prevents requests to blacklisted prefixes.
///
/// In our application, a prefix is blacklisted if a docs.rs page exists below it. For example,
/// since /releases/queue is a docs.rs page, /releases is a blacklisted prefix.
///
/// The middleware must be used for all the pages serving crates at the top level, to prevent a
/// crate from putting their own content in an URL that's supposed to be used by docs.rs.
pub(super) struct BlockBlacklistedPrefixes {
    blacklist: HashSet<String>,
    handler: Box<dyn Handler>,
}

impl BlockBlacklistedPrefixes {
    pub(super) fn new(blacklist: HashSet<String>, handler: Box<dyn Handler>) -> Self {
        Self { blacklist, handler }
    }
}

impl Handler for BlockBlacklistedPrefixes {
    fn handle(&self, req: &mut iron::Request) -> iron::IronResult<iron::Response> {
        if let Some(prefix) = req.url.path().get(0) {
            if self.blacklist.contains(*prefix) {
                return Err(iron::IronError::new(
                    super::error::Nope::CrateNotFound,
                    iron::status::NotFound,
                ));
            }
        }
        self.handler.handle(req)
    }
}

/// Automatically generate a Route ID from a pattern. Every non-alphanumeric character is replaced
/// with `_`.
fn calculate_id(pattern: &str) -> String {
    pattern
        .chars()
        .map(|c| if c.is_alphanumeric() { c } else { '_' })
        .collect()
}
<|endoftext|>


<commit_before>mod immediate;
mod multithreaded;
#[cfg(feature = "rayon")]
mod rayon;

use alloc::sync::Arc;
use alloc::vec::Vec;
use crate::error::Result;
use crate::parser::Component;

pub struct RowData {
    pub index: usize,
    pub component: Component,
    pub quantization_table: Arc<[u16; 64]>,
}

pub trait Worker {
    fn start(&mut self, row_data: RowData) -> Result<()>;
    fn append_row(&mut self, row: (usize, Vec<i16>)) -> Result<()>;
    fn get_result(&mut self, index: usize) -> Result<Vec<u8>>;
    /// Default implementation for spawning multiple tasks.
    fn append_rows(&mut self, row: &mut dyn Iterator<Item=(usize, Vec<i16>)>)
        -> Result<()>
    {
        for item in row {
            self.append_row(item)?;
        }
        Ok(())
    }
}

pub enum PreferWorkerKind {
    Immediate,
    Multithreaded,
}

/// Execute something with a worker system.
pub fn with_worker<T>(prefer: PreferWorkerKind, f: impl FnOnce(&mut dyn Worker) -> T) -> T {
    match prefer {
        #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
        #[cfg(feature = "rayon")]
        PreferWorkerKind::Multithreaded => self::rayon::with_rayon(f),
        #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
        PreferWorkerKind::Multithreaded => self::multithreaded::with_multithreading(f),
        _ => self::immediate::with_immediate(f),
    }
}
<commit_msg>Fixing issue with worker on wasm targets<commit_after>mod immediate;
mod multithreaded;
#[cfg(feature = "rayon")]
mod rayon;

use alloc::sync::Arc;
use alloc::vec::Vec;
use crate::error::Result;
use crate::parser::Component;

pub struct RowData {
    pub index: usize,
    pub component: Component,
    pub quantization_table: Arc<[u16; 64]>,
}

pub trait Worker {
    fn start(&mut self, row_data: RowData) -> Result<()>;
    fn append_row(&mut self, row: (usize, Vec<i16>)) -> Result<()>;
    fn get_result(&mut self, index: usize) -> Result<Vec<u8>>;
    /// Default implementation for spawning multiple tasks.
    fn append_rows(&mut self, row: &mut dyn Iterator<Item=(usize, Vec<i16>)>)
        -> Result<()>
    {
        for item in row {
            self.append_row(item)?;
        }
        Ok(())
    }
}

pub enum PreferWorkerKind {
    Immediate,
    Multithreaded,
}

/// Execute something with a worker system.
pub fn with_worker<T>(prefer: PreferWorkerKind, f: impl FnOnce(&mut dyn Worker) -> T) -> T {
    #[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))]
    {
        return self::immediate::with_immediate(f);
    }
    match prefer {
        #[cfg(feature = "rayon")]
        PreferWorkerKind::Multithreaded => self::rayon::with_rayon(f),
        PreferWorkerKind::Multithreaded => self::multithreaded::with_multithreading(f),
        _ => self::immediate::with_immediate(f),
    }
}

<|endoftext|>


<commit_before>extern crate disasm6502;

#[test]
fn check_disasm() {
    let bytes = vec![0x05, 0x0B, 0x6C, 0x01, 0x02, 0x0A, 0xA2, 0xFF, 0x20, 0x02, 0xFD, 0x78, 0xD0, 0xFC, 0x1D, 0x05, 0x1E, 0x04, 0x15, 0x02, 0x96, 0xAB, 0x58, 0x61, 0x01, 0x91, 0xFB];

    let instructions = disasm6502::from_array(&bytes).unwrap();

    for i in instructions.iter() {
        println!("{}", i);
    }
}

#[test]
fn check_disasm_file() {
    let instructions = disasm6502::from_file("tests/test_pattern.bin").unwrap();

    for i in instructions.iter() {
        let cc = if i.extra_cycle {
            format!("(*{}) ", i.cycles)
        } else {
            format!("({})  ", i.cycles)
        };

        let rr = if let Some(ref reg_read) = i.registers_read {
            let mut r_str = String::from(" Reads:[");
            for r in reg_read.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("          ")
        };

        let rw = if let Some(ref reg_written) = i.registers_written {
            let mut r_str = String::from(" Writes:[");
            for r in reg_written.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("")
        };

        let af = if let Some(ref aff_flags) = i.affected_flags {
            let mut f_str = String::from(" Affects:[");
            for f in aff_flags.iter() {
                f_str.push_str(format!("{}", f).as_str());
            }
            f_str.push_str("]");
            f_str.to_owned()
        } else {
            String::from("")
        };

        println!("{}{}{}{}{}", i, cc, rr, rw, af);
    }
}

#[test]
#[should_panic]
fn check_disasm_file_fail() {
    let _ = disasm6502::from_file("tests/foo").unwrap_or_else(|e| { panic!("{}", e); }); }
<commit_msg>added faulty code to test case<commit_after>extern crate disasm6502;

#[test]
fn check_disasm() {
    let bytes = vec![0x05, 0x0B, 0x6C, 0x01, 0x02, 0x0A, 0xA2, 0xFF, 0x20, 0x02, 0xFD, 0x78, 0xD0, 0xFC, 0x1D, 0x05, 0x1E, 0x04, 0x15, 0x02, 0x96, 0xAB, 0x58, 0x61, 0x01, 0x91, 0xFB, 0x90];

    let instructions = disasm6502::from_array(&bytes).unwrap();

    for i in instructions.iter() {
        println!("{}", i);
    }
}

#[test]
fn check_disasm_file() {
    let instructions = disasm6502::from_file("tests/test_pattern.bin").unwrap();

    for i in instructions.iter() {
        let cc = if i.extra_cycle {
            format!("(*{}) ", i.cycles)
        } else {
            format!("({})  ", i.cycles)
        };

        let rr = if let Some(ref reg_read) = i.registers_read {
            let mut r_str = String::from(" Reads:[");
            for r in reg_read.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("          ")
        };

        let rw = if let Some(ref reg_written) = i.registers_written {
            let mut r_str = String::from(" Writes:[");
            for r in reg_written.iter() {
                r_str.push_str(format!("{}", r).as_str());
            }
            r_str.push_str("]");
            r_str.to_owned()
        } else {
            String::from("")
        };

        let af = if let Some(ref aff_flags) = i.affected_flags {
            let mut f_str = String::from(" Affects:[");
            for f in aff_flags.iter() {
                f_str.push_str(format!("{}", f).as_str());
            }
            f_str.push_str("]");
            f_str.to_owned()
        } else {
            String::from("")
        };

        println!("{}{}{}{}{}", i, cc, rr, rw, af);
    }
}

#[test]
#[should_panic]
fn check_disasm_file_fail() {
    let _ = disasm6502::from_file("tests/foo").unwrap_or_else(|e| { panic!("{}", e); }); }
<|endoftext|>


<commit_before>#![feature(globs,macro_rules)]
extern crate vobject;
use vobject::parse_component;

macro_rules! s(
    ($i:expr) => (&$i.into_string());
)

#[test]
fn test_vcard_basic() {
    let item = parse_component(s!(
        "BEGIN:VCARD\n\
        VERSION:2.1\n\
        N:Mustermann;Erika\n\
        FN:Erika Mustermann\n\
        ORG:Wikipedia\n\
        TITLE:Oberleutnant\n\
        PHOTO;JPEG:http://commons.wikimedia.org/wiki/File:Erika_Mustermann_2010.jpg\n\
        TEL;WORK;VOICE:(0221) 9999123\n\n\n\
        TEL;HOME;VOICE:(0221) 1234567\n\
        ADR;HOME:;;Heidestrasse 17;Koeln;;51147;Deutschland\n\
        EMAIL;PREF;INTERNET:erika@mustermann.de\n\
        REV:20140301T221110Z\n\
        END:VCARD\n\r\n\n")).unwrap();

    assert_eq!(item.single_prop(s!("FN")).unwrap().get_raw_value(), s!("Erika Mustermann"));
    assert_eq!(item.single_prop(s!("N")).unwrap().get_raw_value(),  s!("Mustermann;Erika"));

    let mut tel_values = item.all_props(s!("TEL")).iter().map(|x| x.get_raw_value());
    assert_eq!(tel_values.next().unwrap(), s!("(0221) 9999123"));
    assert_eq!(tel_values.next().unwrap(), s!("(0221) 1234567"));
    assert!(tel_values.next().is_none());
}

#[test]
fn test_line_cont() {
    let item = parse_component(s!(
        "BEGIN:VCARD\n\
        VERSION:2.1\n\
        N;ENCODING=QUOTED-PRINTABLE:Nikdo;Nikdo=\n\t\
        vic\n\
        NOTE:This ends with equal sign=\n\
        TEL;WORK:5555\n \
        4444\n\
        END:VCARD")).unwrap();

    assert_eq!(&item.name, s!("VCARD"));
    assert_eq!(item.single_prop(s!("TEL")).unwrap().get_raw_value(), s!("55554444"));
    assert_eq!(item.single_prop(s!("N")).unwrap().get_raw_value(), s!("Nikdo;Nikdo=vic"));
}

#[test]
fn test_icalendar_basic() {
    let item = parse_component(s!(
            "BEGIN:VCALENDAR\n\
            VERSION:2.0\n\
            PRODID:http://www.example.com/calendarapplication/\n\
            METHOD:PUBLISH\n\
            BEGIN:VEVENT\n\
            UID:461092315540@example.com\n\
            ORGANIZER;CN=\"Alice Balder, Example Inc.\":MAILTO:alice@example.com\n\
            LOCATION:Somewhere\n\
            SUMMARY:Eine Kurzinfo\n\
            DESCRIPTION:Beschreibung des Termines\n\
            CLASS:PUBLIC\n\
            DTSTART:20060910T220000Z\n\
            DTEND:20060919T215900Z\n\
            DTSTAMP:20060812T125900Z\n\
            END:VEVENT\n\
            END:VCALENDAR\n")).unwrap();

    assert_eq!(&item.name, s!("VCALENDAR"));
    assert!(item.single_prop(s!("LOCATION")).is_none());
    assert!(item.single_prop(s!("ORGANIZER")).is_none());

    let event = &item.subcomponents[0];
    assert_eq!(&event.name, s!("VEVENT"));
    assert!(event.single_prop(s!("ORGANIZER")).is_some());
    assert_eq!(event.single_prop(s!("LOCATION")).unwrap().get_raw_value(), s!("Somewhere"));
}

#[test]
fn test_escaping() {
    let item = parse_component(s!(
            "BEGIN:VCALENDAR\n\
            ORGANIZER;CN=\"Cott:n Eye Joe\":mailto:joe@joe.com\n\
            END:VCALENDAR\n")).unwrap();
    assert_eq!(&item.name, s!("VCALENDAR"));
    assert_eq!(item.single_prop(s!("ORGANIZER")).unwrap().get_raw_value(), s!("mailto:joe@joe.com"));
}
<commit_msg>add semicolon for nightly update<commit_after>#![feature(globs,macro_rules)]
extern crate vobject;
use vobject::parse_component;

macro_rules! s(
    ($i:expr) => (&$i.into_string());
);

#[test]
fn test_vcard_basic() {
    let item = parse_component(s!(
        "BEGIN:VCARD\n\
        VERSION:2.1\n\
        N:Mustermann;Erika\n\
        FN:Erika Mustermann\n\
        ORG:Wikipedia\n\
        TITLE:Oberleutnant\n\
        PHOTO;JPEG:http://commons.wikimedia.org/wiki/File:Erika_Mustermann_2010.jpg\n\
        TEL;WORK;VOICE:(0221) 9999123\n\n\n\
        TEL;HOME;VOICE:(0221) 1234567\n\
        ADR;HOME:;;Heidestrasse 17;Koeln;;51147;Deutschland\n\
        EMAIL;PREF;INTERNET:erika@mustermann.de\n\
        REV:20140301T221110Z\n\
        END:VCARD\n\r\n\n")).unwrap();

    assert_eq!(item.single_prop(s!("FN")).unwrap().get_raw_value(), s!("Erika Mustermann"));
    assert_eq!(item.single_prop(s!("N")).unwrap().get_raw_value(),  s!("Mustermann;Erika"));

    let mut tel_values = item.all_props(s!("TEL")).iter().map(|x| x.get_raw_value());
    assert_eq!(tel_values.next().unwrap(), s!("(0221) 9999123"));
    assert_eq!(tel_values.next().unwrap(), s!("(0221) 1234567"));
    assert!(tel_values.next().is_none());
}

#[test]
fn test_line_cont() {
    let item = parse_component(s!(
        "BEGIN:VCARD\n\
        VERSION:2.1\n\
        N;ENCODING=QUOTED-PRINTABLE:Nikdo;Nikdo=\n\t\
        vic\n\
        NOTE:This ends with equal sign=\n\
        TEL;WORK:5555\n \
        4444\n\
        END:VCARD")).unwrap();

    assert_eq!(&item.name, s!("VCARD"));
    assert_eq!(item.single_prop(s!("TEL")).unwrap().get_raw_value(), s!("55554444"));
    assert_eq!(item.single_prop(s!("N")).unwrap().get_raw_value(), s!("Nikdo;Nikdo=vic"));
}

#[test]
fn test_icalendar_basic() {
    let item = parse_component(s!(
            "BEGIN:VCALENDAR\n\
            VERSION:2.0\n\
            PRODID:http://www.example.com/calendarapplication/\n\
            METHOD:PUBLISH\n\
            BEGIN:VEVENT\n\
            UID:461092315540@example.com\n\
            ORGANIZER;CN=\"Alice Balder, Example Inc.\":MAILTO:alice@example.com\n\
            LOCATION:Somewhere\n\
            SUMMARY:Eine Kurzinfo\n\
            DESCRIPTION:Beschreibung des Termines\n\
            CLASS:PUBLIC\n\
            DTSTART:20060910T220000Z\n\
            DTEND:20060919T215900Z\n\
            DTSTAMP:20060812T125900Z\n\
            END:VEVENT\n\
            END:VCALENDAR\n")).unwrap();

    assert_eq!(&item.name, s!("VCALENDAR"));
    assert!(item.single_prop(s!("LOCATION")).is_none());
    assert!(item.single_prop(s!("ORGANIZER")).is_none());

    let event = &item.subcomponents[0];
    assert_eq!(&event.name, s!("VEVENT"));
    assert!(event.single_prop(s!("ORGANIZER")).is_some());
    assert_eq!(event.single_prop(s!("LOCATION")).unwrap().get_raw_value(), s!("Somewhere"));
}

#[test]
fn test_escaping() {
    let item = parse_component(s!(
            "BEGIN:VCALENDAR\n\
            ORGANIZER;CN=\"Cott:n Eye Joe\":mailto:joe@joe.com\n\
            END:VCALENDAR\n")).unwrap();
    assert_eq!(&item.name, s!("VCALENDAR"));
    assert_eq!(item.single_prop(s!("ORGANIZER")).unwrap().get_raw_value(), s!("mailto:joe@joe.com"));
}
<|endoftext|>


<commit_before><commit_msg>rustfmt<commit_after><|endoftext|>


<commit_before>extern crate rand;
extern crate rdx_sort;

use std::f32;
use std::f64;
use std::iter;
use std::ops;

use rand::{Rng, XorShiftRng};
use rand::distributions::{IndependentSample, Range};
use rand::distributions::range::SampleRange;

use rdx_sort::*;

fn is_sorted<T>(data: &Vec<T>) -> bool
    where T: Clone,
          T: PartialOrd
{
    let mut last_entry: Option<T> = None;
    for x in data.iter().cloned() {
        match last_entry {
            Some(l) => {
                if !(l.le(&x)) {
                    return false;
                }
            }
            None => {}
        }
        last_entry = Some(x);
    }
    return true;
}

fn test_generic<T>(data: Vec<T>)
    where T: Clone + PartialOrd,
          Vec<T>: RdxSort
{
    let mut data = data;
    let n = data.len();
    let mut data_sorted_ref = data.clone();
    data_sorted_ref.sort_by(|a, b| a.partial_cmp(b).unwrap());

    data.rdxsort();
    assert!(data.len() == n, "sorted data has wrong lenght!");
    assert!(is_sorted(&data), "data is not sorted!");
    for (x, y) in data.iter().zip(data_sorted_ref.iter()) {
        assert!(x == y, "sortd data does not match the reference!");
    }
}

fn test_rnd_generic<T>(vmin: T, vmax: T, vspecial: Vec<T>)
    where T: Clone + PartialOrd + SampleRange,
          Vec<T>: RdxSort
{
    // config
    let n = 10_000;

    // generate data
    let r = Range::new(vmin.clone(), vmax.clone());
    let mut rng = XorShiftRng::new_unseeded();
    let mut data = Vec::with_capacity(n);
    for _ in (0 as usize)..n {
        data.push(r.ind_sample(&mut rng));
    }
    let mut positions = Vec::with_capacity(n);
    for i in 0..n {
        positions.push(i);
    }
    rng.shuffle(&mut positions[..]);
    assert!(vspecial.len() + 2 < n, "to many special values to test!");
    data[positions[0]] = vmin;
    data[positions[1]] = vmax;
    for (i, x) in positions.into_iter().skip(2).zip(vspecial.into_iter()) {
        data[i] = x;
    }
    assert!(data.len() == n, "generated data has wrong length!");

    test_generic(data);
}

fn test_full_generic<T>(vmin: T, vmax: T)
    where T: Clone+ PartialOrd + ops::Add,
          ops::Range<T>: iter::Iterator,
          Vec<T>: iter::FromIterator<<ops::Range<T> as iter::Iterator>::Item>,
          Vec<T>: RdxSort
{
    // TODO: use inclusive range once it's stable
    let mut data: Vec<T> = (vmin.clone()..vmax.clone()).collect();
    data.push(vmax);

    let mut rng = XorShiftRng::new_unseeded();
    rng.shuffle(&mut data[..]);

    test_generic(data);
}

#[test]
fn test_rnd_i8() {
    test_rnd_generic::<i8>(i8::min_value(), i8::max_value(), vec![i8::min_value() + 1, -1i8, 0i8, 1i8, i8::max_value() - 1]);
}

#[test]
fn test_full_i8() {
    test_full_generic::<i8>(i8::min_value(), i8::max_value());
}

#[test]
fn test_rnd_i16() {
    test_rnd_generic::<i16>(i16::min_value(), i16::max_value(), vec![i16::min_value() + 1, -1i16, 0i16, 1i16, i16::max_value() - 1]);
}

#[test]
fn test_full_i16() {
    test_full_generic::<i16>(i16::min_value(), i16::max_value());
}

#[test]
fn test_rnd_i32() {
    test_rnd_generic::<i32>(i32::min_value(), i32::max_value(), vec![i32::min_value() + 1, -1i32, 0i32, 1i32, i32::max_value() - 1]);
}

#[test]
fn test_rnd_i64() {
    test_rnd_generic::<i64>(i64::min_value(), i64::max_value(), vec![i64::min_value() + 1, -1i64, 0i64, 1i64, i64::max_value() - 1]);
}

#[test]
fn test_rnd_u8() {
    test_rnd_generic::<u8>(u8::min_value(), u8::max_value(), vec![0u8, 1u8, u8::max_value() - 1]);
}

#[test]
fn test_full_u8() {
    test_full_generic::<u8>(u8::min_value(), u8::max_value());
}

#[test]
fn test_rnd_u16() {
    test_rnd_generic::<u16>(u16::min_value(), u16::max_value(), vec![0u16, 1u16, u16::max_value() - 1]);
}

#[test]
fn test_full_u16() {
    test_full_generic::<u16>(u16::min_value(), u16::max_value());
}

#[test]
fn test_rnd_u32() {
    test_rnd_generic::<u32>(u32::min_value(), u32::max_value(), vec![0u32, 1u32, u32::max_value() - 1]);
}

#[test]
fn test_rnd_u64() {
    test_rnd_generic::<u64>(u64::min_value(), u64::max_value(), vec![0u64, 1u64, u64::max_value() - 1]);
}

#[test]
fn test_rnd_f32() {
    // DO NOT use MIN/MAX here, since that overflows the RNG system!
    test_rnd_generic::<f32>(0f32, 1f32, vec![-f32::INFINITY, -0f32, 0f32, f32::INFINITY]);
}

#[test]
fn test_rnd_f64() {
    // DO NOT use MIN/MAX here, since that overflows the RNG system!
    test_rnd_generic::<f64>(0f64, 1f64, vec![-f64::INFINITY, -0f64, 0f64, f64::INFINITY]);
}
<commit_msg>test entropy of rnd test data to check for messy generator<commit_after>extern crate rand;
extern crate rdx_sort;

use std::collections;
use std::f32;
use std::f64;
use std::hash;
use std::hash::Hash;
use std::hash::Hasher;
use std::iter;
use std::mem;
use std::ops;

use rand::{Rng, XorShiftRng};
use rand::distributions::{IndependentSample, Range};
use rand::distributions::range::SampleRange;

use rdx_sort::*;

fn is_sorted<T>(data: &Vec<T>) -> bool
    where T: Clone,
          T: PartialOrd
{
    let mut last_entry: Option<T> = None;
    for x in data.iter().cloned() {
        match last_entry {
            Some(l) => {
                if !(l.le(&x)) {
                    return false;
                }
            }
            None => {}
        }
        last_entry = Some(x);
    }
    return true;
}

trait MyHash {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher;
}

impl MyHash for u8 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for u16 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for u32 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for u64 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for i8 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for i16 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for i32 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for i64 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        self.hash(state);
    }
}

impl MyHash for f32 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        let alias = unsafe {mem::transmute_copy::<f32, u32>(self)};
        alias.hash(state);
    }
}

impl MyHash for f64 {
    fn hash_it<H>(&self, state: &mut H) where H: Hasher {
        let alias = unsafe {mem::transmute_copy::<f64, u64>(self)};
        alias.hash(state);
    }
}

fn guess_entropy<T>(data: &Vec<T>) -> f64 where T: MyHash {
    let mut counter = collections::HashMap::<u64, usize>::new();

    for x in data {
        let mut hasher = hash::SipHasher::new();
        x.hash_it(&mut hasher);
        let key = hasher.finish();

        let state = counter.entry(key).or_insert(0);
        *state += 1;
    }

    counter.values().map(|&x| x as f64 / data.len() as f64).map(|x| -x * x.log2()).fold(0f64, |a, b| a + b)
}

fn test_generic<T>(data: Vec<T>)
    where T: Clone + PartialOrd,
          Vec<T>: RdxSort
{
    let mut data = data;
    let n = data.len();
    let mut data_sorted_ref = data.clone();
    data_sorted_ref.sort_by(|a, b| a.partial_cmp(b).unwrap());

    data.rdxsort();
    assert!(data.len() == n, "sorted data has wrong lenght!");
    assert!(is_sorted(&data), "data is not sorted!");
    for (x, y) in data.iter().zip(data_sorted_ref.iter()) {
        assert!(x == y, "sortd data does not match the reference!");
    }
}

fn test_rnd_generic<T>(vmin: T, vmax: T, vspecial: Vec<T>)
    where T: Clone + PartialOrd + SampleRange + MyHash,
          Vec<T>: RdxSort
{
    // config
    let n = 10_000;
    let entropy_threshold = 1f64;

    // generate data
    let r = Range::new(vmin.clone(), vmax.clone());
    let mut rng = XorShiftRng::new_unseeded();
    let mut data = Vec::with_capacity(n);
    for _ in (0 as usize)..n {
        data.push(r.ind_sample(&mut rng));
    }
    let mut positions = Vec::with_capacity(n);
    for i in 0..n {
        positions.push(i);
    }
    rng.shuffle(&mut positions[..]);
    assert!(vspecial.len() + 2 < n, "to many special values to test!");
    data[positions[0]] = vmin;
    data[positions[1]] = vmax;
    for (i, x) in positions.into_iter().skip(2).zip(vspecial.into_iter()) {
        data[i] = x;
    }
    assert!(data.len() == n, "generated data has wrong length!");
    assert!(guess_entropy(&data) >= entropy_threshold, "generated data does not contain enough entropy!");

    test_generic(data);
}

fn test_full_generic<T>(vmin: T, vmax: T)
    where T: Clone+ PartialOrd + ops::Add,
          ops::Range<T>: iter::Iterator,
          Vec<T>: iter::FromIterator<<ops::Range<T> as iter::Iterator>::Item>,
          Vec<T>: RdxSort
{
    // TODO: use inclusive range once it's stable
    let mut data: Vec<T> = (vmin.clone()..vmax.clone()).collect();
    data.push(vmax);

    let mut rng = XorShiftRng::new_unseeded();
    rng.shuffle(&mut data[..]);

    test_generic(data);
}

#[test]
fn test_rnd_i8() {
    test_rnd_generic::<i8>(i8::min_value(), i8::max_value(), vec![i8::min_value() + 1, -1i8, 0i8, 1i8, i8::max_value() - 1]);
}

#[test]
fn test_full_i8() {
    test_full_generic::<i8>(i8::min_value(), i8::max_value());
}

#[test]
fn test_rnd_i16() {
    test_rnd_generic::<i16>(i16::min_value(), i16::max_value(), vec![i16::min_value() + 1, -1i16, 0i16, 1i16, i16::max_value() - 1]);
}

#[test]
fn test_full_i16() {
    test_full_generic::<i16>(i16::min_value(), i16::max_value());
}

#[test]
fn test_rnd_i32() {
    test_rnd_generic::<i32>(i32::min_value(), i32::max_value(), vec![i32::min_value() + 1, -1i32, 0i32, 1i32, i32::max_value() - 1]);
}

#[test]
fn test_rnd_i64() {
    test_rnd_generic::<i64>(i64::min_value(), i64::max_value(), vec![i64::min_value() + 1, -1i64, 0i64, 1i64, i64::max_value() - 1]);
}

#[test]
fn test_rnd_u8() {
    test_rnd_generic::<u8>(u8::min_value(), u8::max_value(), vec![0u8, 1u8, u8::max_value() - 1]);
}

#[test]
fn test_full_u8() {
    test_full_generic::<u8>(u8::min_value(), u8::max_value());
}

#[test]
fn test_rnd_u16() {
    test_rnd_generic::<u16>(u16::min_value(), u16::max_value(), vec![0u16, 1u16, u16::max_value() - 1]);
}

#[test]
fn test_full_u16() {
    test_full_generic::<u16>(u16::min_value(), u16::max_value());
}

#[test]
fn test_rnd_u32() {
    test_rnd_generic::<u32>(u32::min_value(), u32::max_value(), vec![0u32, 1u32, u32::max_value() - 1]);
}

#[test]
fn test_rnd_u64() {
    test_rnd_generic::<u64>(u64::min_value(), u64::max_value(), vec![0u64, 1u64, u64::max_value() - 1]);
}

#[test]
fn test_rnd_f32() {
    // DO NOT use MIN/MAX here, since that overflows the RNG system!
    test_rnd_generic::<f32>(0f32, 1f32, vec![-f32::INFINITY, -0f32, 0f32, f32::INFINITY]);
}

#[test]
fn test_rnd_f64() {
    // DO NOT use MIN/MAX here, since that overflows the RNG system!
    test_rnd_generic::<f64>(0f64, 1f64, vec![-f64::INFINITY, -0f64, 0f64, f64::INFINITY]);
}
<|endoftext|>


<commit_before>extern crate opentype;
extern crate postscript;
extern crate truetype;

use std::fs::File;
use std::io::{Seek, SeekFrom};

mod fixture;

use fixture::Fixture;

macro_rules! ok(($result:expr) => ($result.unwrap()));

macro_rules! setup(
    ($fixture:ident) => (::setup(::fixture::Fixture::$fixture, None));
    ($fixture:ident, $table:expr) => (::setup(::fixture::Fixture::$fixture, Some($table)));
);

macro_rules! tags(($($name:expr),*) => (vec![$(::truetype::Tag(*$name)),*]));

mod file;
mod glyph_definition;
mod glyph_positioning;
mod glyph_substitution;

fn setup(fixture: Fixture, table: Option<&str>) -> File {
    let mut file = ok!(File::open(fixture.path()));
    ok!(file.seek(SeekFrom::Start(table.map(|table| fixture.offset(table)).unwrap_or(0))));
    file
}
<commit_msg>Make a cosmetic adjustment<commit_after>extern crate opentype;
extern crate postscript;
extern crate truetype;

use std::fs::File;

macro_rules! ok(($result:expr) => ($result.unwrap()));

macro_rules! setup(
    ($fixture:ident) => (::setup(::fixture::Fixture::$fixture, None));
    ($fixture:ident, $table:expr) => (::setup(::fixture::Fixture::$fixture, Some($table)));
);

macro_rules! tags(($($name:expr),*) => (vec![$(::truetype::Tag(*$name)),*]));

mod file;
mod fixture;
mod glyph_definition;
mod glyph_positioning;
mod glyph_substitution;

use fixture::Fixture;

fn setup(fixture: Fixture, table: Option<&str>) -> File {
    use std::io::{Seek, SeekFrom};

    let mut file = ok!(File::open(fixture.path()));
    ok!(file.seek(SeekFrom::Start(table.map(|table| fixture.offset(table)).unwrap_or(0))));
    file
}
<|endoftext|>


<commit_before><commit_msg>Extract method<commit_after><|endoftext|>


<commit_before>//! An Asteroids-ish example game to show off ggez.
//! The idea is that this game is simple but still
//! non-trivial enough to be interesting.

extern crate ggez;
extern crate rand;

use ggez::conf;
use ggez::event;
use ggez::game::{Game, GameState};
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::graphics::Drawable;
use ggez::timer;
use std::time::Duration;

extern crate nalgebra as na;
type Vector2 = na::Vector2<f64>;

extern crate ggez_goodies;
use ggez_goodies::camera::*;

struct MainState {
    camera: Camera,
    image: graphics::Image,
    image_location: Vector2,
}

const WINDOW_WIDTH: u32 = 640;
const WINDOW_HEIGHT: u32 = 480;

const CAMERA_WIDTH: f64 = 40.0;
const CAMERA_HEIGHT: f64 = 30.0;

impl GameState for MainState {
    fn load(ctx: &mut Context, _conf: &conf::Conf) -> GameResult<Self> {
        let camera = Camera::new(WINDOW_WIDTH, WINDOW_HEIGHT, CAMERA_WIDTH, CAMERA_HEIGHT);

        println!("Camera test instructions; WASD move the object, arrow keys move the camera.");
        println!("The red dots are drawn on every integer point in the camera's coordinate \
                  system.");
        let image = graphics::Image::new(ctx, "tile.png")?;
        graphics::set_background_color(ctx, ggez::graphics::Color::RGBA(0, 0, 0, 0));
        let state = MainState {
            camera: camera,
            image: image,
            image_location: na::zero(),
        };
        Ok(state)
    }
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);

        let dest_rect = ggez::graphics::Rect::new(0, 0, 0, 0);
        self.image.draw(ctx, None, Some(dest_rect))?;
        self.image
            .draw_camera(&self.camera, self.image_location, ctx, None, (64, 64))?;

        let half_width = (CAMERA_WIDTH / 2.0) as i32;
        let half_height = (CAMERA_HEIGHT / 2.0) as i32;
        graphics::set_color(ctx, graphics::Color::RGB(255, 0, 0));
        for y in -half_height..half_height {
            for x in -half_width..half_width {
                let fromvec = Vector2::new(x as f64, y as f64);
                let (px, py) = self.camera.world_to_screen_coords(fromvec);
                let to = graphics::Point::new(px, py);
                graphics::point(ctx, to)?;
            }
        }

        graphics::present(ctx);
        timer::sleep_until_next_frame(ctx, 60);
        Ok(())
    }

    fn key_down_event(&mut self,
                      keycode: Option<event::Keycode>,
                      _keymod: event::Mod,
                      _repeat: bool) {
        if let Some(key) = keycode {
            match key {
                event::Keycode::W => {
                    self.image_location.y += 0.1;
                }
                event::Keycode::A => {
                    self.image_location.x -= 0.1;
                }
                event::Keycode::S => {
                    self.image_location.y -= 0.1;
                }
                event::Keycode::D => {
                    self.image_location.x += 0.1;
                }
                event::Keycode::Up => self.camera.move_by(Vector2::new(0.0, 0.1)),
                event::Keycode::Left => self.camera.move_by(Vector2::new(-0.1, 0.0)),
                event::Keycode::Down => self.camera.move_by(Vector2::new(0.0, -0.1)),
                event::Keycode::Right => self.camera.move_by(Vector2::new(0.1, 0.0)),
                _ => (),
            };
            println!("Camera position is now {}, object position is {}",
                     self.camera.location(),
                     self.image_location);
        }

    }
}

pub fn main() {
    let mut c = conf::Conf::new();
    c.window_title = "Shiny particles".to_string();
    c.window_width = WINDOW_WIDTH as u32;
    c.window_height = WINDOW_HEIGHT as u32;
    let game: GameResult<Game<MainState>> = Game::new("camera_test", c);
    match game {
        Err(e) => {
            println!("Could not load game!");
            println!("Error: {:?}", e);
        }
        Ok(mut game) => {
            let result = game.run();
            if let Err(e) = result {
                println!("Error encountered running game: {:?}", e);
            } else {
                println!("Game exited cleanly.");
            }
        }
    }
}
<commit_msg>Minor cleanup on camera example, ready to start something new.<commit_after>//! An Asteroids-ish example game to show off ggez.
//! The idea is that this game is simple but still
//! non-trivial enough to be interesting.

extern crate ggez;
extern crate rand;

use ggez::conf;
use ggez::event;
use ggez::game::{Game, GameState};
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::graphics::Drawable;
use ggez::timer;
use std::time::Duration;

extern crate nalgebra as na;
type Vector2 = na::Vector2<f64>;

extern crate ggez_goodies;
use ggez_goodies::camera::*;

struct MainState {
    camera: Camera,
    image: graphics::Image,
    image_location: Vector2,
}

const WINDOW_WIDTH: u32 = 640;
const WINDOW_HEIGHT: u32 = 480;

const CAMERA_WIDTH: f64 = 40.0;
const CAMERA_HEIGHT: f64 = 30.0;

impl GameState for MainState {
    fn load(ctx: &mut Context, _conf: &conf::Conf) -> GameResult<Self> {
        let camera = Camera::new(WINDOW_WIDTH, WINDOW_HEIGHT, CAMERA_WIDTH, CAMERA_HEIGHT);

        println!("Camera test instructions; WASD move the object, arrow keys move the camera.");
        println!("The red dots are drawn on every integer point in the camera's coordinate \
                  system.");
        let image = graphics::Image::new(ctx, "tile.png")?;
        graphics::set_background_color(ctx, ggez::graphics::Color::RGBA(0, 0, 0, 0));
        let state = MainState {
            camera: camera,
            image: image,
            image_location: na::zero(),
        };
        Ok(state)
    }
    fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx);

        let dest_rect = ggez::graphics::Rect::new(0, 0, 0, 0);

        let half_width = (CAMERA_WIDTH / 2.0) as i32;
        let half_height = (CAMERA_HEIGHT / 2.0) as i32;
        graphics::set_color(ctx, graphics::Color::RGB(255, 0, 0));
        for y in -half_height..half_height {
            for x in -half_width..half_width {
                let fromvec = Vector2::new(x as f64, y as f64);
                let (px, py) = self.camera.world_to_screen_coords(fromvec);
                let to = graphics::Point::new(px, py);
                graphics::point(ctx, to)?;
            }
        }
        self.image
            .draw_camera(&self.camera, self.image_location, ctx, None, (64, 64))?;
        graphics::present(ctx);
        timer::sleep_until_next_frame(ctx, 60);
        Ok(())
    }

    fn key_down_event(&mut self,
                      keycode: Option<event::Keycode>,
                      _keymod: event::Mod,
                      _repeat: bool) {
        if let Some(key) = keycode {
            match key {
                event::Keycode::W => {
                    self.image_location.y += 0.1;
                }
                event::Keycode::A => {
                    self.image_location.x -= 0.1;
                }
                event::Keycode::S => {
                    self.image_location.y -= 0.1;
                }
                event::Keycode::D => {
                    self.image_location.x += 0.1;
                }
                event::Keycode::Up => self.camera.move_by(Vector2::new(0.0, 0.1)),
                event::Keycode::Left => self.camera.move_by(Vector2::new(-0.1, 0.0)),
                event::Keycode::Down => self.camera.move_by(Vector2::new(0.0, -0.1)),
                event::Keycode::Right => self.camera.move_by(Vector2::new(0.1, 0.0)),
                _ => (),
            };
            println!("Camera position is now {}, object position is {}",
                     self.camera.location(),
                     self.image_location);
        }

    }
}

pub fn main() {
    let mut c = conf::Conf::new();
    c.window_title = "Shiny particles".to_string();
    c.window_width = WINDOW_WIDTH as u32;
    c.window_height = WINDOW_HEIGHT as u32;
    let game: GameResult<Game<MainState>> = Game::new("camera_test", c);
    match game {
        Err(e) => {
            println!("Could not load game!");
            println!("Error: {:?}", e);
        }
        Ok(mut game) => {
            let result = game.run();
            if let Err(e) = result {
                println!("Error encountered running game: {:?}", e);
            } else {
                println!("Game exited cleanly.");
            }
        }
    }
}
<|endoftext|>


<commit_before>//! MySQL Proxy Server
extern crate mysql_proxy;
use mysql_proxy::*;

#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate byteorder;

use std::rc::Rc;
use std::env;
use std::net::{SocketAddr};
use std::str;

use futures::{Future};
use futures::stream::Stream;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core};

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

    // determine address for the proxy to bind to
    let bind_addr = env::args().nth(1).unwrap_or("127.0.0.1:3307".to_string());
    let bind_addr = bind_addr.parse::<SocketAddr>().unwrap();

    // determine address of the MySQL instance we are proxying for
    let mysql_addr = env::args().nth(2).unwrap_or("127.0.0.1:3306".to_string());
    let mysql_addr = mysql_addr.parse::<SocketAddr>().unwrap();

    // Create the tokio event loop that will drive this server
    let mut l = Core::new().unwrap();

    // Get a reference to the reactor event loop
    let handle = l.handle();

    // Create a TCP listener which will listen for incoming connections
    let socket = TcpListener::bind(&bind_addr, &l.handle()).unwrap();
    println!("Listening on: {}", bind_addr);

    // for each incoming connection
    let done = socket.incoming().for_each(move |(socket, _)| {

        // create a future to serve requests
        let future = TcpStream::connect(&mysql_addr, &handle)
            .and_then(move |mysql| { Ok((socket, mysql)) })
            .and_then(move |(client, server)|
                { Pipe::new(Rc::new(client), Rc::new(server), PassthroughHandler {})
                });

        // tell the tokio reactor to run the future
        handle.spawn(future.map_err(|err| {
            println!("Failed to spawn future: {:?}", err);
        }));

        // everything is great!
        Ok(())

    });
    l.run(done).unwrap();
}

struct PassthroughHandler {}

impl PacketHandler for PassthroughHandler {

    fn handle_request(&mut self, p: &Packet) -> Action {
        print_packet_chars(&p.bytes);
        Action::Forward
    }

    fn handle_response(&mut self, _: &Packet) -> Action {
        // forward all responses to the client
        Action::Forward
    }

}

#[allow(dead_code)]
pub fn print_packet_chars(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        print!("{} ", buf[i] as char);
    }
    println!("]");
}

#[allow(dead_code)]
pub fn print_packet_bytes(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        if i%8==0 { println!(""); }
        print!("{:#04x} ",buf[i]);
    }
    println!("]");
}
<commit_msg>remove print chars from passthrough proxy<commit_after>//! MySQL Proxy Server
extern crate mysql_proxy;
use mysql_proxy::*;

#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate byteorder;

use std::rc::Rc;
use std::env;
use std::net::{SocketAddr};
use std::str;

use futures::{Future};
use futures::stream::Stream;
use tokio_core::net::{TcpStream, TcpListener};
use tokio_core::reactor::{Core};

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

    // determine address for the proxy to bind to
    let bind_addr = env::args().nth(1).unwrap_or("127.0.0.1:3307".to_string());
    let bind_addr = bind_addr.parse::<SocketAddr>().unwrap();

    // determine address of the MySQL instance we are proxying for
    let mysql_addr = env::args().nth(2).unwrap_or("127.0.0.1:3306".to_string());
    let mysql_addr = mysql_addr.parse::<SocketAddr>().unwrap();

    // Create the tokio event loop that will drive this server
    let mut l = Core::new().unwrap();

    // Get a reference to the reactor event loop
    let handle = l.handle();

    // Create a TCP listener which will listen for incoming connections
    let socket = TcpListener::bind(&bind_addr, &l.handle()).unwrap();
    println!("Listening on: {}", bind_addr);

    // for each incoming connection
    let done = socket.incoming().for_each(move |(socket, _)| {

        // create a future to serve requests
        let future = TcpStream::connect(&mysql_addr, &handle)
            .and_then(move |mysql| { Ok((socket, mysql)) })
            .and_then(move |(client, server)|
                { Pipe::new(Rc::new(client), Rc::new(server), PassthroughHandler {})
                });

        // tell the tokio reactor to run the future
        handle.spawn(future.map_err(|err| {
            println!("Failed to spawn future: {:?}", err);
        }));

        // everything is great!
        Ok(())

    });
    l.run(done).unwrap();
}

struct PassthroughHandler {}

impl PacketHandler for PassthroughHandler {

    fn handle_request(&mut self, p: &Packet) -> Action {
        Action::Forward
    }

    fn handle_response(&mut self, _: &Packet) -> Action {
        // forward all responses to the client
        Action::Forward
    }

}

#[allow(dead_code)]
pub fn print_packet_chars(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        print!("{} ", buf[i] as char);
    }
    println!("]");
}

#[allow(dead_code)]
pub fn print_packet_bytes(buf: &[u8]) {
    print!("[");
    for i in 0..buf.len() {
        if i%8==0 { println!(""); }
        print!("{:#04x} ",buf[i]);
    }
    println!("]");
}
<|endoftext|>


<commit_before>use std::{run, str};

#[test]
fn test_output_multi_files_print_all_chars() {
    let prog = run::process_output("build/cat",
                                   [~"cat/fixtures/alpha.txt", ~"cat/fixtures/256.txt",
                                    ~"-A", ~"-n"]).unwrap();
    let out = str::from_utf8_owned(prog.output);
    assert_eq!(out,
               ~"     1\tabcde$\n     2\tfghij$\n     3\tklmno$\n     4\tpqrst$\n     5\tuvwxyz$\n     6\t^@^A^B^C^D^E^F^G^H^I$\n     7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-<M-=M->M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?");
}

#[test]
fn test_stdin_squeeze() {
    let mut prog = run::Process::new("build/cat", [~"-A"], run::ProcessOptions::new()).unwrap();

    prog.input().write(bytes!("\x00\x01\x02"));
    prog.close_input();

    let out = str::from_utf8_owned(prog.finish_with_output().output);
    assert_eq!(out, ~"^@^A^B");
}

#[test]
fn test_stdin_number_non_blank() {
    let mut prog = run::Process::new("build/cat", [~"-b", ~"-"], run::ProcessOptions::new()).unwrap();

    prog.input().write(bytes!("\na\nb\n\n\nc"));
    prog.close_input();

    let out = str::from_utf8_owned(prog.finish_with_output().output);
    assert_eq!(out, ~"\n     1\ta\n     2\tb\n\n\n     3\tc");
}
<commit_msg>cat: fix tests<commit_after>use std::{run, str};

#[test]
fn test_output_multi_files_print_all_chars() {
    let prog = run::process_output("build/cat",
                                   [~"cat/fixtures/alpha.txt", ~"cat/fixtures/256.txt",
                                    ~"-A", ~"-n"]).unwrap();
    let out = str::from_utf8_owned(prog.output).unwrap();
    assert_eq!(out,
               ~"     1\tabcde$\n     2\tfghij$\n     3\tklmno$\n     4\tpqrst$\n     5\tuvwxyz$\n     6\t^@^A^B^C^D^E^F^G^H^I$\n     7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^VM-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:M-;M-<M-=M->M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?");
}

#[test]
fn test_stdin_squeeze() {
    let mut prog = run::Process::new("build/cat", [~"-A"], run::ProcessOptions::new()).unwrap();

    prog.input().write(bytes!("\x00\x01\x02"));
    prog.close_input();

    let out = str::from_utf8_owned(prog.finish_with_output().output).unwrap();
    assert_eq!(out, ~"^@^A^B");
}

#[test]
fn test_stdin_number_non_blank() {
    let mut prog = run::Process::new("build/cat", [~"-b", ~"-"], run::ProcessOptions::new()).unwrap();

    prog.input().write(bytes!("\na\nb\n\n\nc"));
    prog.close_input();

    let out = str::from_utf8_owned(prog.finish_with_output().output).unwrap();
    assert_eq!(out, ~"\n     1\ta\n     2\tb\n\n\n     3\tc");
}
<|endoftext|>


<commit_before>//! Simple script to verify the coding style of this library
//!
//! ## How to run
//!
//! The first argument to this script is the directory to run on, so running
//! this script should be as simple as:
//!
//! ```notrust
//! rustc ci/style.rs
//! ./style src
//! ```
//!
//! ## Guidelines
//!
//! The current style is:
//!
//! * No trailing whitespace
//! * No tabs
//! * 80-character lines
//! * Specific module layout:
//!     1. use directives
//!     2. typedefs
//!     3. structs
//!     4. constants
//!     5. f! { ... } functions
//!     6. extern functions
//!     7. modules + pub use
//!
//! Things not verified:
//!
//! * alignment
//! * 4-space tabs
//! * leading colons on paths

use std::env;
use std::fs;
use std::io::prelude::*;
use std::path::Path;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

fn main() {
    let arg = env::args().skip(1).next().unwrap_or(".".to_string());

    let mut errors = Errors { errs: false };
    walk(Path::new(&arg), &mut errors);

    if errors.errs {
        panic!("found some lint errors");
    } else {
        println!("good style!");
    }
}

fn walk(path: &Path, err: &mut Errors) {
    for entry in t!(path.read_dir()).map(|e| t!(e)) {
        let path = entry.path();
        if t!(entry.file_type()).is_dir() {
            walk(&path, err);
            continue
        }

        let name = entry.file_name().into_string().unwrap();
        match &name[..] {
            n if !n.ends_with(".rs") => continue,

            "dox.rs" |
            "lib.rs" |
            "ctypes.rs" |
            "libc.rs" |
            "macros.rs" => continue,

            _ => {}
        }

        let mut contents = String::new();
        t!(t!(fs::File::open(&path)).read_to_string(&mut contents));

        check_style(&contents, &path, err);
    }
}

struct Errors {
    errs: bool,
}

#[derive(Clone, Copy, PartialEq)]
enum State {
    Start,
    Imports,
    Typedefs,
    Structs,
    Constants,
    FunctionDefinitions,
    Functions,
    Modules,
}

fn check_style(file: &str, path: &Path, err: &mut Errors) {
    let mut state = State::Start;
    let mut s_macros = 0;
    let mut f_macros = 0;
    let mut prev_blank = false;

    for (i, line) in file.lines().enumerate() {
        if line == "" {
            if prev_blank {
                err.error(path, i, "double blank line");
            }
            prev_blank = true;
        } else {
            prev_blank = false;
        }
        if line != line.trim_end() {
            err.error(path, i, "trailing whitespace");
        }
        if line.contains("\t") {
            err.error(path, i, "tab character");
        }
        if line.len() > 80 {
            err.error(path, i, "line longer than 80 chars");
        }
        if line.contains("#[cfg(") && line.contains(']') && !line.contains(" if ")
            && !(line.contains("target_endian") ||
                 line.contains("target_arch"))
        {
            if state != State::Structs {
                err.error(path, i, "use cfg_if! and submodules \
                                    instead of #[cfg]");
            }
        }
        if line.contains("#[derive(") && (line.contains("Copy") || line.contains("Clone")) {
            err.error(path, i, "impl ::Copy and ::Clone manually");
        }

        let orig_line = line;
        let line = line.trim_start();
        let is_pub = line.starts_with("pub ");
        let line = if is_pub {&line[4..]} else {line};

        let line_state = if line.starts_with("use ") {
            if line.contains("c_void") {
                continue;
            }
            if is_pub {
                State::Modules
            } else {
                State::Imports
            }
        } else if line.starts_with("const ") {
            State::Constants
        } else if line.starts_with("type ") {
            State::Typedefs
        } else if line.starts_with("s! {") {
            s_macros += 1;
            State::Structs
        } else if line.starts_with("f! {") {
            f_macros += 1;
            State::FunctionDefinitions
        } else if line.starts_with("extern ") && !orig_line.starts_with(" ") {
            State::Functions
        } else if line.starts_with("mod ") {
            State::Modules
        } else {
            continue
        };

        if state as usize > line_state as usize {
            err.error(path, i, &format!("{} found after {} when \
                                         it belongs before",
                                        line_state.desc(), state.desc()));
        }

        if f_macros == 2 {
            f_macros += 1;
            err.error(path, i, "multiple f! macros in one module");
        }
        if s_macros == 2 {
            s_macros += 1;
            err.error(path, i, "multiple s! macros in one module");
        }

        state = line_state;
    }
}

impl State {
    fn desc(&self) -> &str {
        match *self {
            State::Start => "start",
            State::Imports => "import",
            State::Typedefs => "typedef",
            State::Structs => "struct",
            State::Constants => "constant",
            State::FunctionDefinitions => "function definition",
            State::Functions => "extern function",
            State::Modules => "module",
        }
    }
}

impl Errors {
    fn error(&mut self, path: &Path, line: usize, msg: &str) {
        self.errs = true;
        println!("{}:{} - {}", path.display(), line + 1, msg);
    }
}
<commit_msg>Allow long comments containing a link<commit_after>//! Simple script to verify the coding style of this library
//!
//! ## How to run
//!
//! The first argument to this script is the directory to run on, so running
//! this script should be as simple as:
//!
//! ```notrust
//! rustc ci/style.rs
//! ./style src
//! ```
//!
//! ## Guidelines
//!
//! The current style is:
//!
//! * No trailing whitespace
//! * No tabs
//! * 80-character lines
//! * Specific module layout:
//!     1. use directives
//!     2. typedefs
//!     3. structs
//!     4. constants
//!     5. f! { ... } functions
//!     6. extern functions
//!     7. modules + pub use
//!
//! Things not verified:
//!
//! * alignment
//! * 4-space tabs
//! * leading colons on paths

use std::env;
use std::fs;
use std::io::prelude::*;
use std::path::Path;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

fn main() {
    let arg = env::args().skip(1).next().unwrap_or(".".to_string());

    let mut errors = Errors { errs: false };
    walk(Path::new(&arg), &mut errors);

    if errors.errs {
        panic!("found some lint errors");
    } else {
        println!("good style!");
    }
}

fn walk(path: &Path, err: &mut Errors) {
    for entry in t!(path.read_dir()).map(|e| t!(e)) {
        let path = entry.path();
        if t!(entry.file_type()).is_dir() {
            walk(&path, err);
            continue
        }

        let name = entry.file_name().into_string().unwrap();
        match &name[..] {
            n if !n.ends_with(".rs") => continue,

            "dox.rs" |
            "lib.rs" |
            "ctypes.rs" |
            "libc.rs" |
            "macros.rs" => continue,

            _ => {}
        }

        let mut contents = String::new();
        t!(t!(fs::File::open(&path)).read_to_string(&mut contents));

        check_style(&contents, &path, err);
    }
}

struct Errors {
    errs: bool,
}

#[derive(Clone, Copy, PartialEq)]
enum State {
    Start,
    Imports,
    Typedefs,
    Structs,
    Constants,
    FunctionDefinitions,
    Functions,
    Modules,
}

fn check_style(file: &str, path: &Path, err: &mut Errors) {
    let mut state = State::Start;
    let mut s_macros = 0;
    let mut f_macros = 0;
    let mut prev_blank = false;

    for (i, line) in file.lines().enumerate() {
        if line == "" {
            if prev_blank {
                err.error(path, i, "double blank line");
            }
            prev_blank = true;
        } else {
            prev_blank = false;
        }
        if line != line.trim_end() {
            err.error(path, i, "trailing whitespace");
        }
        if line.contains("\t") {
            err.error(path, i, "tab character");
        }
        if line.len() > 80 && !(line.contains("https://") || line.contains("http://")) {
            err.error(path, i, "line longer than 80 chars");
        }
        if line.contains("#[cfg(") && line.contains(']') && !line.contains(" if ")
            && !(line.contains("target_endian") ||
                 line.contains("target_arch"))
        {
            if state != State::Structs {
                err.error(path, i, "use cfg_if! and submodules \
                                    instead of #[cfg]");
            }
        }
        if line.contains("#[derive(") && (line.contains("Copy") || line.contains("Clone")) {
            err.error(path, i, "impl ::Copy and ::Clone manually");
        }

        let orig_line = line;
        let line = line.trim_start();
        let is_pub = line.starts_with("pub ");
        let line = if is_pub {&line[4..]} else {line};

        let line_state = if line.starts_with("use ") {
            if line.contains("c_void") {
                continue;
            }
            if is_pub {
                State::Modules
            } else {
                State::Imports
            }
        } else if line.starts_with("const ") {
            State::Constants
        } else if line.starts_with("type ") {
            State::Typedefs
        } else if line.starts_with("s! {") {
            s_macros += 1;
            State::Structs
        } else if line.starts_with("f! {") {
            f_macros += 1;
            State::FunctionDefinitions
        } else if line.starts_with("extern ") && !orig_line.starts_with(" ") {
            State::Functions
        } else if line.starts_with("mod ") {
            State::Modules
        } else {
            continue
        };

        if state as usize > line_state as usize {
            err.error(path, i, &format!("{} found after {} when \
                                         it belongs before",
                                        line_state.desc(), state.desc()));
        }

        if f_macros == 2 {
            f_macros += 1;
            err.error(path, i, "multiple f! macros in one module");
        }
        if s_macros == 2 {
            s_macros += 1;
            err.error(path, i, "multiple s! macros in one module");
        }

        state = line_state;
    }
}

impl State {
    fn desc(&self) -> &str {
        match *self {
            State::Start => "start",
            State::Imports => "import",
            State::Typedefs => "typedef",
            State::Structs => "struct",
            State::Constants => "constant",
            State::FunctionDefinitions => "function definition",
            State::Functions => "extern function",
            State::Modules => "module",
        }
    }
}

impl Errors {
    fn error(&mut self, path: &Path, line: usize, msg: &str) {
        self.errs = true;
        println!("{}:{} - {}", path.display(), line + 1, msg);
    }
}
<|endoftext|>


<commit_before>extern crate cfg_if;

use cfg_if::cfg_if;

cfg_if! {
    if #[cfg(all(windows, feature = "neon-sys"))] {
        use std::env::var;
        use std::path::Path;

        const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
        const NODE_ARCH:     &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
        const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
            let configuration = if debug { "Debug" } else { "Release" };
            let node_lib_file_path = Path::new(NODE_LIB_FILE);
            let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
            node_lib_path.push(NODE_ARCH);
            println!("cargo:rustc-link-search={}\\{}", NODE_ROOT_DIR, configuration);
            println!("cargo:rustc-link-search=native={}", &node_lib_path.display());
            println!("cargo:rustc-link-lib={}", &node_lib_file_path.file_stem().unwrap().to_str().unwrap());

            // Link `win_delay_load_hook.obj` for windows electron
            let node_runtime_env = "npm_config_runtime";
            println!("cargo:rerun-if-env-changed={}", node_runtime_env);
            if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
                println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
                println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
                println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
            }
        }
    } else if #[cfg(windows)] {
        // ^ automatically not neon-sys
        use std::io::{Error, ErrorKind, Result};
        use std::process::Command;
        use std::path::Path;

        fn node_version() -> Result<String> {
            let output = Command::new("node").arg("-v").output()?;
            if !output.status.success() {
                let hopefully_stack_trace = String::from_utf8(output.stderr)
                    .unwrap_or_else(|_| "<subprocess output garbage>".to_string());
                panic!("Could not download node.lib: {}", hopefully_stack_trace);
            }
            let stdout = String::from_utf8(output.stdout).map_err(|error| {
                Error::new(ErrorKind::InvalidData, error)
            })?;
            Ok(stdout.trim().to_string())
        }

        fn download_node_lib(version: &str, arch: &str) -> Result<Vec<u8>> {
            let script = r#"
                var url = process.argv[1]
                require("https").get(url, function (res) {
                    res.pipe(process.stdout);
                });
            "#;
            let url = format!("https://nodejs.org/dist/{version}/win-{arch}/node.lib", version = version, arch = arch);

            let output = Command::new("node")
                .arg("-e").arg(script)
                .arg(url)
                .output()?;

            Ok(output.stdout)
        }

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            // If the user specified a node.lib path, we do not need to download
            if let Some(node_lib_path) = std::env::var_os("NEON_NODE_LIB") {
                let node_lib_path = Path::new(&node_lib_path);
                // Clearing the file name returns the root+directory name
                let dir = node_lib_path.with_file_name("");
                let basename = node_lib_path.file_stem().expect("Could not parse lib name from NEON_NODE_LIB. Does the path include the full file name?");

                println!("cargo:rustc-link-search=native={}", dir.display());
                // Littul hack to output the OsStr file stem
                println!("cargo:rustc-link-lib={}", Path::new(basename).display());
                return;
            }

            let version = node_version().expect("Could not determine Node.js version");
            let arch = if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "x86" {
                "x86"
            } else {
                "x64"
            };

            let node_lib_store_path = format!(r"{}/node-{}.lib", env!("OUT_DIR"), arch);

            // Download node.lib if it does not exist
            if let Err(_) = std::fs::metadata(&node_lib_store_path) {
                let node_lib = download_node_lib(&version, arch).expect("Could not download `node.lib`");
                std::fs::write(&node_lib_store_path, &node_lib).expect("Could not save `node.lib`");
            }

            println!("cargo:rustc-link-search=native={}", env!("OUT_DIR"));
            println!("cargo:rustc-link-lib=node-{}", arch);
        }
    } else if #[cfg(target_os = "macos")] {
        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            println!("cargo:rustc-cdylib-link-arg=-undefined");
            println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
        }
    } else {
        pub fn setup() { }
    }
}
<commit_msg>pass through raw output from failing node -v call<commit_after>extern crate cfg_if;

use cfg_if::cfg_if;

cfg_if! {
    if #[cfg(all(windows, feature = "neon-sys"))] {
        use std::env::var;
        use std::path::Path;

        const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
        const NODE_ARCH:     &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
        const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
            let configuration = if debug { "Debug" } else { "Release" };
            let node_lib_file_path = Path::new(NODE_LIB_FILE);
            let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
            node_lib_path.push(NODE_ARCH);
            println!("cargo:rustc-link-search={}\\{}", NODE_ROOT_DIR, configuration);
            println!("cargo:rustc-link-search=native={}", &node_lib_path.display());
            println!("cargo:rustc-link-lib={}", &node_lib_file_path.file_stem().unwrap().to_str().unwrap());

            // Link `win_delay_load_hook.obj` for windows electron
            let node_runtime_env = "npm_config_runtime";
            println!("cargo:rerun-if-env-changed={}", node_runtime_env);
            if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
                println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
                println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
                println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
            }
        }
    } else if #[cfg(windows)] {
        // ^ automatically not neon-sys
        use std::io::{Error, ErrorKind, Write, Result};
        use std::process::Command;
        use std::path::Path;

        fn node_version() -> Result<String> {
            let output = Command::new("node").arg("-v").output()?;
            if !output.status.success() {
                let _ = std::io::stderr().write_all(&output.stderr);
                panic!("Could not download node.lib. There is likely more information from stderr above.");
            }
            let stdout = String::from_utf8(output.stdout).map_err(|error| {
                Error::new(ErrorKind::InvalidData, error)
            })?;
            Ok(stdout.trim().to_string())
        }

        fn download_node_lib(version: &str, arch: &str) -> Result<Vec<u8>> {
            let script = r#"
                var url = process.argv[1]
                require("https").get(url, function (res) {
                    res.pipe(process.stdout);
                });
            "#;
            let url = format!("https://nodejs.org/dist/{version}/win-{arch}/node.lib", version = version, arch = arch);

            let output = Command::new("node")
                .arg("-e").arg(script)
                .arg(url)
                .output()?;

            Ok(output.stdout)
        }

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            // If the user specified a node.lib path, we do not need to download
            if let Some(node_lib_path) = std::env::var_os("NEON_NODE_LIB") {
                let node_lib_path = Path::new(&node_lib_path);
                // Clearing the file name returns the root+directory name
                let dir = node_lib_path.with_file_name("");
                let basename = node_lib_path.file_stem().expect("Could not parse lib name from NEON_NODE_LIB. Does the path include the full file name?");

                println!("cargo:rustc-link-search=native={}", dir.display());
                // Littul hack to output the OsStr file stem
                println!("cargo:rustc-link-lib={}", Path::new(basename).display());
                return;
            }

            let version = node_version().expect("Could not determine Node.js version");
            let arch = if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "x86" {
                "x86"
            } else {
                "x64"
            };

            let node_lib_store_path = format!(r"{}/node-{}.lib", env!("OUT_DIR"), arch);

            // Download node.lib if it does not exist
            if let Err(_) = std::fs::metadata(&node_lib_store_path) {
                let node_lib = download_node_lib(&version, arch).expect("Could not download `node.lib`");
                std::fs::write(&node_lib_store_path, &node_lib).expect("Could not save `node.lib`");
            }

            println!("cargo:rustc-link-search=native={}", env!("OUT_DIR"));
            println!("cargo:rustc-link-lib=node-{}", arch);
        }
    } else if #[cfg(target_os = "macos")] {
        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            println!("cargo:rustc-cdylib-link-arg=-undefined");
            println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
        }
    } else {
        pub fn setup() { }
    }
}
<|endoftext|>