<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::{self, Command};
use syntax::ast;
use std::io::{self, Write};

extern crate cargo_metadata;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType
    ) -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>
    ) -> Compilation {
        self.default.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session,
                                                                             state.krate
                                                                                .as_ref()
                                                                                .expect("at this compilation stage \
                                                                                the krate must be parsed")
                                                                                .span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           mir_passes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.mir_passes.borrow_mut().extend(mir_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref()
            .map(AsRef::as_ref)) {
            metadata
        } else {
            let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
            process::exit(101);
        };

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages
            .iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else {
                    let current_dir = current_dir.as_ref().expect("could not read current directory");
                    let package_manifest_directory = package_manifest_path.parent()
                        .expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args),
                                               &dep_path) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or_else(|| {
                    Command::new("rustc")
                        .arg("--print")
                        .arg("sysroot")
                        .output()
                        .ok()
                        .and_then(|out| String::from_utf8(out.stdout).ok())
                        .map(|s| s.trim().to_owned())
                })
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
        };

        rustc_driver::in_rustc_thread(|| {
                // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
                // without having to pass --sysroot or anything
                let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
                    env::args().collect()
                } else {
                    env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
                };

                // this check ensures that dependencies are built but not linted and the final crate is
                // linted but not built
                let clippy_enabled = env::args().any(|s| s == "-Zno-trans");

                if clippy_enabled {
                    args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
                }

                let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
                let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
                if let Err(err_count) = result {
                    if err_count > 0 {
                        std::process::exit(1);
                    }
                }
            })
            .expect("rustc_thread failed");
    }
}

fn process<P, I>(old_args: I, dep_path: P) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push("-Zno-trans".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Fix compilation on latest nightly<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]

#![allow(unknown_lints, missing_docs_in_private_items)]

extern crate clippy_lints;
extern crate getopts;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_plugin;
extern crate syntax;

use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
use rustc::session::{config, Session};
use rustc::session::config::{Input, ErrorOutputType};
use std::path::PathBuf;
use std::process::{self, Command};
use syntax::ast;
use std::io::{self, Write};

extern crate cargo_metadata;

struct ClippyCompilerCalls {
    default: RustcDefaultCalls,
    run_lints: bool,
}

impl ClippyCompilerCalls {
    fn new(run_lints: bool) -> Self {
        ClippyCompilerCalls {
            default: RustcDefaultCalls,
            run_lints: run_lints,
        }
    }
}

impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType
    ) -> Compilation {
        self.default.early_callback(matches, sopts, cfg, descriptions, output)
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions)
    }
    fn late_callback(
        &mut self,
        matches: &getopts::Matches,
        sess: &Session,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>
    ) -> Compilation {
        self.default.late_callback(matches, sess, input, odir, ofile)
    }
    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> driver::CompileController<'a> {
        let mut control = self.default.build_controller(sess, matches);

        if self.run_lints {
            let old = std::mem::replace(&mut control.after_parse.callback, box |_| {});
            control.after_parse.callback = Box::new(move |state| {
                {
                    let mut registry = rustc_plugin::registry::Registry::new(state.session,
                                                                             state.krate
                                                                                .as_ref()
                                                                                .expect("at this compilation stage \
                                                                                the krate must be parsed")
                                                                                .span);
                    registry.args_hidden = Some(Vec::new());
                    clippy_lints::register_plugins(&mut registry);

                    let rustc_plugin::registry::Registry { early_lint_passes,
                                                           late_lint_passes,
                                                           lint_groups,
                                                           llvm_passes,
                                                           attributes,
                                                           .. } = registry;
                    let sess = &state.session;
                    let mut ls = sess.lint_store.borrow_mut();
                    for pass in early_lint_passes {
                        ls.register_early_pass(Some(sess), true, pass);
                    }
                    for pass in late_lint_passes {
                        ls.register_late_pass(Some(sess), true, pass);
                    }

                    for (name, to) in lint_groups {
                        ls.register_group(Some(sess), true, name, to);
                    }

                    sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
                    sess.plugin_attributes.borrow_mut().extend(attributes);
                }
                old(state);
            });
        }

        control
    }
}

use std::path::Path;

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit

Other options are the same as `cargo rustc`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    use std::env;

    if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
        panic!("yummy");
    }

    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    let dep_path = env::current_dir().expect("current dir is not readable").join("target").join("debug").join("deps");

    if let Some("clippy") = std::env::args().nth(1).as_ref().map(AsRef::as_ref) {
        // this arm is executed on the initial call to `cargo clippy`

        let manifest_path_arg = std::env::args().skip(2).find(|val| val.starts_with("--manifest-path="));

        let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref()
            .map(AsRef::as_ref)) {
            metadata
        } else {
            let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n"));
            process::exit(101);
        };

        let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));

        let current_dir = std::env::current_dir();

        let package_index = metadata.packages
            .iter()
            .position(|package| {
                let package_manifest_path = Path::new(&package.manifest_path);
                if let Some(ref manifest_path) = manifest_path {
                    package_manifest_path == manifest_path
                } else {
                    let current_dir = current_dir.as_ref().expect("could not read current directory");
                    let package_manifest_directory = package_manifest_path.parent()
                        .expect("could not find parent directory of package manifest");
                    package_manifest_directory == current_dir
                }
            })
            .expect("could not find matching package");
        let package = metadata.packages.remove(package_index);
        for target in package.targets {
            let args = std::env::args().skip(2);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args), &dep_path) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    if let Err(code) = process(vec![format!("--{}", first), target.name].into_iter().chain(args),
                                               &dep_path) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    } else {
        // this arm is executed when cargo-clippy runs `cargo rustc` with the `RUSTC` env var set to itself

        let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
        let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
        let sys_root = if let (Some(home), Some(toolchain)) = (home, toolchain) {
            format!("{}/toolchains/{}", home, toolchain)
        } else {
            option_env!("SYSROOT")
                .map(|s| s.to_owned())
                .or_else(|| {
                    Command::new("rustc")
                        .arg("--print")
                        .arg("sysroot")
                        .output()
                        .ok()
                        .and_then(|out| String::from_utf8(out.stdout).ok())
                        .map(|s| s.trim().to_owned())
                })
                .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust")
        };

        rustc_driver::in_rustc_thread(|| {
                // this conditional check for the --sysroot flag is there so users can call `cargo-clippy` directly
                // without having to pass --sysroot or anything
                let mut args: Vec<String> = if env::args().any(|s| s == "--sysroot") {
                    env::args().collect()
                } else {
                    env::args().chain(Some("--sysroot".to_owned())).chain(Some(sys_root)).collect()
                };

                // this check ensures that dependencies are built but not linted and the final crate is
                // linted but not built
                let clippy_enabled = env::args().any(|s| s == "-Zno-trans");

                if clippy_enabled {
                    args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
                }

                let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
                let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
                if let Err(err_count) = result {
                    if err_count > 0 {
                        std::process::exit(1);
                    }
                }
            })
            .expect("rustc_thread failed");
    }
}

fn process<P, I>(old_args: I, dep_path: P) -> Result<(), i32>
    where P: AsRef<Path>,
          I: Iterator<Item = String>
{

    let mut args = vec!["rustc".to_owned()];

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("-L".to_owned());
    args.push(dep_path.as_ref().to_string_lossy().into_owned());
    args.push("-Zno-trans".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let path = std::env::current_exe().expect("current executable path invalid");
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC", path)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate time;

use std::mem;

use glium::{DisplayBuild, Program, Surface, VertexBuffer, IndexBuffer};
use glium::texture::Texture2d;
use glium::index::PrimitiveType;
use glium::glutin::Event;
use glium::backend::Facade;
use glium::backend::glutin_backend::GlutinFacade;

// Our vertices are boring. We only ever draw 2 triangles
// covering the whole surface.
#[derive(Copy, Clone)]
struct Vertex {
    pos: [f32; 2],
}

implement_vertex!(Vertex, pos);

fn whole_surface_triangles<F>(facade: &F)
    -> (VertexBuffer<Vertex>, IndexBuffer<u8>)
    where F: Facade,
{
    let vertices = [
        Vertex { pos: [-1.0, -1.0] },
        Vertex { pos: [-1.0,  1.0] },
        Vertex { pos: [ 1.0,  1.0] },
        Vertex { pos: [ 1.0, -1.0] },
    ];

    let indices = [
        0, 1, 2,
        2, 3, 0,
    ];

    let vertex_buffer = VertexBuffer::new(facade, &vertices).unwrap();
    let index_buffer = IndexBuffer::new(facade,
                                        PrimitiveType::TrianglesList,
                                        &indices).unwrap();

    (vertex_buffer, index_buffer)
}

// Size in pixels for the feedback textures.
const FEEDBACK_TEXTURE_SIZE: u32
    = 2048;

// Create a feedback texture.
fn feedback_texture<F>(facade: &F) -> Texture2d
    where F: Facade,
{
    // Returns a texture with undefined contents.
    Texture2d::empty(facade,
                     FEEDBACK_TEXTURE_SIZE,
                     FEEDBACK_TEXTURE_SIZE).unwrap()
}

// Shaders, as GLSL source code. These are included at compile time, so
// you don't need any files present at runtime. However it means you
// need to recompile even if you've only changed a shader.

// Trivial vertex shader.
const VERTEX_SHADER_SRC: &str
    = include_str!("shaders/vertex.glsl");

// Simple fragment shader, used to copy a texture to the screen.
const BLIT_SHADER_SRC: &str
    = include_str!("shaders/blit.glsl");

// Fragment shader which runs video feedback between two textures.
const FEEDBACK_SHADER_SRC: &str
    = include_str!("shaders/feedback.glsl");

// The screen and the feedback textures are interpreted as
// subsets of the complex plane:
//
//     (-SCALE to SCALE) + i*(-SCALE to SCALE)
//
const SCALE: f32 = 1.4;

// Convert a window position in pixels to a complex number.
//
// TODO: Is it slow to look up the size on every mouse move?
fn window_px_to_z(facade: &GlutinFacade, (x, y): (i32, i32))
    -> (f32, f32)
{
    let window = facade.get_window().unwrap();
    let (sx, sy) = window.get_inner_size().unwrap();

    (((x as f32) / ((sx-1) as f32) * 2.0 - 1.0) * SCALE,
     ((y as f32) / ((sy-1) as f32) * 2.0 - 1.0) * SCALE)
}

fn main() {
    // Create a glutin / glium window.
    let display = glium::glutin::WindowBuilder::new()
        .with_title("a z u r e s c e n s".to_owned())
        .with_vsync()
        .build_glium()
        .unwrap();

    // Create two textures for feedback.
    let mut read_texture  = feedback_texture(&display);
    let mut write_texture = feedback_texture(&display);

    // Prepare to draw triangles which cover a whole surface.
    let (vertex_buffer, index_buffer) = whole_surface_triangles(&display);
    let draw_params = Default::default();

    // Prepare shader programs.
    let blit_program = Program::from_source(&display,
        VERTEX_SHADER_SRC, BLIT_SHADER_SRC, None).unwrap();

    let feedback_program = Program::from_source(&display,
        VERTEX_SHADER_SRC, FEEDBACK_SHADER_SRC, None).unwrap();

    // Clear the screen.
    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 1.0);
    target.finish().unwrap();

    // Initial value for the complex parameter 'c'.
    let mut param_c = (0.3, 0.3);

    loop {
        // Run video feedback from one texture into the other.
        // We do this twice before drawing to the screen.
        // The reason is that each frame inverts colors and
        // we want to avoid a distracting blinky effect.
        for _ in 0..2 {
            {
                let uniforms = uniform! {
                    src: &read_texture,
                    scale: SCALE,
                    param_c: param_c,
                    param_t: time::precise_time_s() as f32,
                };

                let mut target = write_texture.as_surface();
                target.draw(&vertex_buffer, &index_buffer, &feedback_program,
                            &uniforms, &draw_params).unwrap();
            }

            mem::swap(&mut read_texture, &mut write_texture);
        }

        // Draw the most recently written texture to the screen.
        let uniforms = uniform! {
            src: &read_texture,
        };

        let mut target = display.draw();
        target.draw(&vertex_buffer, &index_buffer, &blit_program,
                    &uniforms, &draw_params).unwrap();
        target.finish().unwrap();

        // Handle events.
        for ev in display.poll_events() {
            match ev {
                Event::Closed => return,
                Event::MouseMoved(x, y) => {
                    // Update the parameter 'c' according to
                    // the mouse position.
                    param_c = window_px_to_z(&display, (x,y));
                }
                _ => (),
            }
        }
    }
}
<commit_msg>Explicit lifetimes on static strs, for older rustc compat<commit_after>#[macro_use]
extern crate glium;
extern crate time;

use std::mem;

use glium::{DisplayBuild, Program, Surface, VertexBuffer, IndexBuffer};
use glium::texture::Texture2d;
use glium::index::PrimitiveType;
use glium::glutin::Event;
use glium::backend::Facade;
use glium::backend::glutin_backend::GlutinFacade;

// Our vertices are boring. We only ever draw 2 triangles
// covering the whole surface.
#[derive(Copy, Clone)]
struct Vertex {
    pos: [f32; 2],
}

implement_vertex!(Vertex, pos);

fn whole_surface_triangles<F>(facade: &F)
    -> (VertexBuffer<Vertex>, IndexBuffer<u8>)
    where F: Facade,
{
    let vertices = [
        Vertex { pos: [-1.0, -1.0] },
        Vertex { pos: [-1.0,  1.0] },
        Vertex { pos: [ 1.0,  1.0] },
        Vertex { pos: [ 1.0, -1.0] },
    ];

    let indices = [
        0, 1, 2,
        2, 3, 0,
    ];

    let vertex_buffer = VertexBuffer::new(facade, &vertices).unwrap();
    let index_buffer = IndexBuffer::new(facade,
                                        PrimitiveType::TrianglesList,
                                        &indices).unwrap();

    (vertex_buffer, index_buffer)
}

// Size in pixels for the feedback textures.
const FEEDBACK_TEXTURE_SIZE: u32
    = 2048;

// Create a feedback texture.
fn feedback_texture<F>(facade: &F) -> Texture2d
    where F: Facade,
{
    // Returns a texture with undefined contents.
    Texture2d::empty(facade,
                     FEEDBACK_TEXTURE_SIZE,
                     FEEDBACK_TEXTURE_SIZE).unwrap()
}

// Shaders, as GLSL source code. These are included at compile time, so
// you don't need any files present at runtime. However it means you
// need to recompile even if you've only changed a shader.

// Trivial vertex shader.
const VERTEX_SHADER_SRC: &'static str
    = include_str!("shaders/vertex.glsl");

// Simple fragment shader, used to copy a texture to the screen.
const BLIT_SHADER_SRC: &'static str
    = include_str!("shaders/blit.glsl");

// Fragment shader which runs video feedback between two textures.
const FEEDBACK_SHADER_SRC: &'static str
    = include_str!("shaders/feedback.glsl");

// The screen and the feedback textures are interpreted as
// subsets of the complex plane:
//
//     (-SCALE to SCALE) + i*(-SCALE to SCALE)
//
const SCALE: f32 = 1.4;

// Convert a window position in pixels to a complex number.
//
// TODO: Is it slow to look up the size on every mouse move?
fn window_px_to_z(facade: &GlutinFacade, (x, y): (i32, i32))
    -> (f32, f32)
{
    let window = facade.get_window().unwrap();
    let (sx, sy) = window.get_inner_size().unwrap();

    (((x as f32) / ((sx-1) as f32) * 2.0 - 1.0) * SCALE,
     ((y as f32) / ((sy-1) as f32) * 2.0 - 1.0) * SCALE)
}

fn main() {
    // Create a glutin / glium window.
    let display = glium::glutin::WindowBuilder::new()
        .with_title("a z u r e s c e n s".to_owned())
        .with_vsync()
        .build_glium()
        .unwrap();

    // Create two textures for feedback.
    let mut read_texture  = feedback_texture(&display);
    let mut write_texture = feedback_texture(&display);

    // Prepare to draw triangles which cover a whole surface.
    let (vertex_buffer, index_buffer) = whole_surface_triangles(&display);
    let draw_params = Default::default();

    // Prepare shader programs.
    let blit_program = Program::from_source(&display,
        VERTEX_SHADER_SRC, BLIT_SHADER_SRC, None).unwrap();

    let feedback_program = Program::from_source(&display,
        VERTEX_SHADER_SRC, FEEDBACK_SHADER_SRC, None).unwrap();

    // Clear the screen.
    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 1.0);
    target.finish().unwrap();

    // Initial value for the complex parameter 'c'.
    let mut param_c = (0.3, 0.3);

    loop {
        // Run video feedback from one texture into the other.
        // We do this twice before drawing to the screen.
        // The reason is that each frame inverts colors and
        // we want to avoid a distracting blinky effect.
        for _ in 0..2 {
            {
                let uniforms = uniform! {
                    src: &read_texture,
                    scale: SCALE,
                    param_c: param_c,
                    param_t: time::precise_time_s() as f32,
                };

                let mut target = write_texture.as_surface();
                target.draw(&vertex_buffer, &index_buffer, &feedback_program,
                            &uniforms, &draw_params).unwrap();
            }

            mem::swap(&mut read_texture, &mut write_texture);
        }

        // Draw the most recently written texture to the screen.
        let uniforms = uniform! {
            src: &read_texture,
        };

        let mut target = display.draw();
        target.draw(&vertex_buffer, &index_buffer, &blit_program,
                    &uniforms, &draw_params).unwrap();
        target.finish().unwrap();

        // Handle events.
        for ev in display.poll_events() {
            match ev {
                Event::Closed => return,
                Event::MouseMoved(x, y) => {
                    // Update the parameter 'c' according to
                    // the mouse position.
                    param_c = window_px_to_z(&display, (x,y));
                }
                _ => (),
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(collections, core, env, libc, old_io, old_path, std_misc)]

// Other platforms than macos don't need std_misc but you can't
// use #[cfg] on features.
#![allow(unused_features)]

extern crate ansi_term;
extern crate datetime;
extern crate getopts;
extern crate locale;
extern crate natord;
extern crate number_prefix;
extern crate pad;
extern crate users;

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

use std::env;
use std::old_io::{fs, FileType};

use dir::Dir;
use file::File;
use options::{Options, View};
use output::lines_view;

pub mod column;
pub mod dir;
pub mod file;
pub mod filetype;
pub mod options;
pub mod output;
pub mod term;
pub mod xattr;

struct Exa<'a> {
    count:   usize,
    options: Options,
    dirs:    Vec<Path>,
    files:   Vec<File<'a>>,
}

impl<'a> Exa<'a> {
    fn new(options: Options) -> Exa<'a> {
        Exa {
            count: 0,
            options: options,
            dirs: Vec::new(),
            files: Vec::new(),
        }
    }

    fn load<T>(&mut self, iter: T) where T: Iterator<Item = &'a String> {
        // Separate the user-supplied paths into directories and files.
        // Files are shown first, and then each directory is expanded
        // and listed second.
        for file in iter {
            let path = Path::new(file);
            match fs::stat(&path) {
                Ok(stat) => {
                    if stat.kind == FileType::Directory {
                        if self.options.dir_action.is_tree() {
                            self.files.push(File::with_stat(stat, &path, None, true));
                        }
                        else {
                            self.dirs.push(path);
                        }
                    }
                    else {
                        self.files.push(File::with_stat(stat, &path, None, false));
                    }
                }
                Err(e) => println!("{}: {}", file, e),
            }

            self.count += 1;
        }
    }

    fn print_files(&self) {
        if !self.files.is_empty() {
            self.print(None, &self.files[..]);
        }
    }

    fn print_dirs(&mut self) {
        let mut first = self.files.is_empty();

        // Directories are put on a stack rather than just being iterated through,
        // as the vector can change as more directories are added.
        loop {
            let dir_path = match self.dirs.pop() {
                None => break,
                Some(f) => f,
            };

            // Put a gap between directories, or between the list of files and the
            // first directory.
            if first {
                first = false;
            }
            else {
                print!("\n");
            }

            match Dir::readdir(&dir_path) {
                Ok(ref dir) => {
                    let mut files = dir.files(false);
                    self.options.transform_files(&mut files);

                    // When recursing, add any directories to the dirs stack
                    // backwards: the *last* element of the stack is used each
                    // time, so by inserting them backwards, they get displayed in
                    // the correct sort order.
                    if let Some(recurse_opts) = self.options.dir_action.recurse_options() {
                        let depth = dir_path.components().filter(|&c| c != b".").count() + 1;
                        if !recurse_opts.tree && !recurse_opts.is_too_deep(depth) {
                            for dir in files.iter().filter(|f| f.stat.kind == FileType::Directory).rev() {
                                self.dirs.push(dir.path.clone());
                            }
                        }
                    }

                    if self.count > 1 {
                        println!("{}:", dir_path.display());
                    }
                    self.count += 1;

                    self.print(Some(dir), &files[..]);
                }
                Err(e) => {
                    println!("{}: {}", dir_path.display(), e);
                    return;
                }
            };
        }
    }

    fn print(&self, dir: Option<&Dir>, files: &[File]) {
        match self.options.view {
            View::Grid(g)     => g.view(files),
            View::Details(d)  => d.view(dir, files),
            View::Lines       => lines_view(files),
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();

    match Options::getopts(args.tail()) {
        Ok((options, paths)) => {
            let mut exa = Exa::new(options);
            exa.load(paths.iter());
            exa.print_files();
            exa.print_dirs();
        },
        Err(e) => {
            println!("{}", e);
            env::set_exit_status(e.error_code());
        },
    };
}
<commit_msg>Fewer warnings when testing<commit_after>#![feature(collections, core, env, io, libc, old_io, old_path, std_misc)]

// Other platforms than macos don't need std_misc but you can't
// use #[cfg] on features.
#![allow(unused_features)]

extern crate ansi_term;
extern crate datetime;
extern crate getopts;
extern crate locale;
extern crate natord;
extern crate number_prefix;
extern crate pad;
extern crate users;

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

use std::env;
use std::old_io::{fs, FileType};

use dir::Dir;
use file::File;
use options::{Options, View};
use output::lines_view;

pub mod column;
pub mod dir;
pub mod file;
pub mod filetype;
pub mod options;
pub mod output;
pub mod term;
pub mod xattr;

#[cfg(not(test))]
struct Exa<'a> {
    count:   usize,
    options: Options,
    dirs:    Vec<Path>,
    files:   Vec<File<'a>>,
}

#[cfg(not(test))]
impl<'a> Exa<'a> {
    fn new(options: Options) -> Exa<'a> {
        Exa {
            count: 0,
            options: options,
            dirs: Vec::new(),
            files: Vec::new(),
        }
    }

    fn load<T>(&mut self, iter: T) where T: Iterator<Item = &'a String> {
        // Separate the user-supplied paths into directories and files.
        // Files are shown first, and then each directory is expanded
        // and listed second.
        for file in iter {
            let path = Path::new(file);
            match fs::stat(&path) {
                Ok(stat) => {
                    if stat.kind == FileType::Directory {
                        if self.options.dir_action.is_tree() {
                            self.files.push(File::with_stat(stat, &path, None, true));
                        }
                        else {
                            self.dirs.push(path);
                        }
                    }
                    else {
                        self.files.push(File::with_stat(stat, &path, None, false));
                    }
                }
                Err(e) => println!("{}: {}", file, e),
            }

            self.count += 1;
        }
    }

    fn print_files(&self) {
        if !self.files.is_empty() {
            self.print(None, &self.files[..]);
        }
    }

    fn print_dirs(&mut self) {
        let mut first = self.files.is_empty();

        // Directories are put on a stack rather than just being iterated through,
        // as the vector can change as more directories are added.
        loop {
            let dir_path = match self.dirs.pop() {
                None => break,
                Some(f) => f,
            };

            // Put a gap between directories, or between the list of files and the
            // first directory.
            if first {
                first = false;
            }
            else {
                print!("\n");
            }

            match Dir::readdir(&dir_path) {
                Ok(ref dir) => {
                    let mut files = dir.files(false);
                    self.options.transform_files(&mut files);

                    // When recursing, add any directories to the dirs stack
                    // backwards: the *last* element of the stack is used each
                    // time, so by inserting them backwards, they get displayed in
                    // the correct sort order.
                    if let Some(recurse_opts) = self.options.dir_action.recurse_options() {
                        let depth = dir_path.components().filter(|&c| c != b".").count() + 1;
                        if !recurse_opts.tree && !recurse_opts.is_too_deep(depth) {
                            for dir in files.iter().filter(|f| f.stat.kind == FileType::Directory).rev() {
                                self.dirs.push(dir.path.clone());
                            }
                        }
                    }

                    if self.count > 1 {
                        println!("{}:", dir_path.display());
                    }
                    self.count += 1;

                    self.print(Some(dir), &files[..]);
                }
                Err(e) => {
                    println!("{}: {}", dir_path.display(), e);
                    return;
                }
            };
        }
    }

    fn print(&self, dir: Option<&Dir>, files: &[File]) {
        match self.options.view {
            View::Grid(g)     => g.view(files),
            View::Details(d)  => d.view(dir, files),
            View::Lines       => lines_view(files),
        }
    }
}

#[cfg(not(test))]
fn main() {
    let args: Vec<String> = env::args().collect();

    match Options::getopts(args.tail()) {
        Ok((options, paths)) => {
            let mut exa = Exa::new(options);
            exa.load(paths.iter());
            exa.print_files();
            exa.print_dirs();
        },
        Err(e) => {
            println!("{}", e);
            env::set_exit_status(e.error_code());
        },
    };
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 fd developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

extern crate ansi_term;
extern crate atty;
#[macro_use]
extern crate clap;
extern crate ignore;
#[macro_use]
extern crate lazy_static;
#[cfg(all(unix, not(target_os = "redox")))]
extern crate libc;
extern crate num_cpus;
extern crate regex;
extern crate regex_syntax;
#[cfg(windows)]
extern crate windows;

pub mod fshelper;
pub mod lscolors;
mod app;
mod exec;
mod internal;
mod output;
mod walk;

use std::env;
use std::error::Error;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time;

use atty::Stream;
use regex::RegexBuilder;

use exec::TokenizedCommand;
use internal::{error, pattern_has_uppercase_char, FdOptions, PathDisplay};
use lscolors::LsColors;
use walk::FileType;

fn main() {
    let matches = app::build_app().get_matches();

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.value_of("pattern").unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir = Path::new(".");
    if !fshelper::is_dir(current_dir) {
        error("Error: could not get current directory.");
    }

    // Get the root directory for the search
    let mut root_dir_buf = match matches.value_of("path") {
        Some(path) => PathBuf::from(path),
        None => current_dir.to_path_buf(),
    };
    if !fshelper::is_dir(&root_dir_buf) {
        error(&format!(
            "Error: '{}' is not a directory.",
            root_dir_buf.to_string_lossy()
        ));
    }

    let path_display = if matches.is_present("absolute-path") || root_dir_buf.is_absolute() {
        PathDisplay::Absolute
    } else {
        PathDisplay::Relative
    };

    if path_display == PathDisplay::Absolute && root_dir_buf.is_relative() {
        root_dir_buf = fshelper::absolute_path(root_dir_buf.as_path()).unwrap();
    }
    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case") &&
        (matches.is_present("case-sensitive") || pattern_has_uppercase_char(pattern));

    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => atty::is(Stream::Stdout),
    };
    #[cfg(windows)]
    let colored_output = colored_output && windows::enable_colored_output();

    let ls_colors = if colored_output {
        Some(
            env::var("LS_COLORS")
                .ok()
                .map(|val| LsColors::from_string(&val))
                .unwrap_or_default(),
        )
    } else {
        None
    };

    let command = matches.value_of("exec").map(|x| TokenizedCommand::new(x));

    let config = FdOptions {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden") ||
                             matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_ignore: !(matches.is_present("no-ignore") ||
                           matches.is_present("rg-alias-hidden-ignore")),
        follow_links: matches.is_present("follow"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches.value_of("depth").and_then(|n| {
            usize::from_str_radix(n, 10).ok()
        }),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        path_display,
        ls_colors,
        file_type: match matches.value_of("file-type") {
            Some("f") | Some("file") => FileType::RegularFile,
            Some("d") |
            Some("directory") => FileType::Directory,
            Some("l") | Some("symlink") => FileType::SymLink,
            _ => FileType::Any,
        },
        extension: matches.value_of("extension").map(|e| {
            e.trim_left_matches('.').to_lowercase()
        }),
        command,
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or(vec![]),
    };

    match RegexBuilder::new(pattern)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build() {
        Ok(re) => walk::scan(root_dir, Arc::new(re), Arc::new(config)),
        Err(err) => error(err.description()),
    }
}
<commit_msg>Fix root directory for Windows<commit_after>// Copyright (c) 2017 fd developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

extern crate ansi_term;
extern crate atty;
#[macro_use]
extern crate clap;
extern crate ignore;
#[macro_use]
extern crate lazy_static;
#[cfg(all(unix, not(target_os = "redox")))]
extern crate libc;
extern crate num_cpus;
extern crate regex;
extern crate regex_syntax;
#[cfg(windows)]
extern crate windows;

pub mod fshelper;
pub mod lscolors;
mod app;
mod exec;
mod internal;
mod output;
mod walk;

use std::env;
use std::error::Error;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time;

use atty::Stream;
use regex::RegexBuilder;

use exec::TokenizedCommand;
use internal::{error, pattern_has_uppercase_char, FdOptions, PathDisplay};
use lscolors::LsColors;
use walk::FileType;

fn main() {
    let matches = app::build_app().get_matches();

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.value_of("pattern").unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir = Path::new(".");
    if !fshelper::is_dir(current_dir) {
        error("Error: could not get current directory.");
    }

    // Get the root directory for the search
    let mut root_dir_buf = match matches.value_of("path") {
        Some(path) => {
            #[cfg(windows)]
            let path = path.replace('/', "\\");

            PathBuf::from(path)
        }
        None => current_dir.to_path_buf(),
    };
    if !fshelper::is_dir(&root_dir_buf) {
        error(&format!(
            "Error: '{}' is not a directory.",
            root_dir_buf.to_string_lossy()
        ));
    }

    let path_display = if matches.is_present("absolute-path") || root_dir_buf.is_absolute() {
        PathDisplay::Absolute
    } else {
        PathDisplay::Relative
    };

    if path_display == PathDisplay::Absolute && root_dir_buf.is_relative() {
        root_dir_buf = fshelper::absolute_path(root_dir_buf.as_path()).unwrap();
    }
    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case") &&
        (matches.is_present("case-sensitive") || pattern_has_uppercase_char(pattern));

    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => atty::is(Stream::Stdout),
    };
    #[cfg(windows)]
    let colored_output = colored_output && windows::enable_colored_output();

    let ls_colors = if colored_output {
        Some(
            env::var("LS_COLORS")
                .ok()
                .map(|val| LsColors::from_string(&val))
                .unwrap_or_default(),
        )
    } else {
        None
    };

    let command = matches.value_of("exec").map(|x| TokenizedCommand::new(x));

    let config = FdOptions {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden") ||
                             matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_ignore: !(matches.is_present("no-ignore") ||
                           matches.is_present("rg-alias-hidden-ignore")),
        follow_links: matches.is_present("follow"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches.value_of("depth").and_then(|n| {
            usize::from_str_radix(n, 10).ok()
        }),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        path_display,
        ls_colors,
        file_type: match matches.value_of("file-type") {
            Some("f") | Some("file") => FileType::RegularFile,
            Some("d") |
            Some("directory") => FileType::Directory,
            Some("l") | Some("symlink") => FileType::SymLink,
            _ => FileType::Any,
        },
        extension: matches.value_of("extension").map(|e| {
            e.trim_left_matches('.').to_lowercase()
        }),
        command,
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or(vec![]),
    };

    match RegexBuilder::new(pattern)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build() {
        Ok(re) => walk::scan(root_dir, Arc::new(re), Arc::new(config)),
        Err(err) => error(err.description()),
    }
}
<|endoftext|>


<commit_before>#![feature(conservative_impl_trait)]

extern crate cgmath;
extern crate ordered_float;
extern crate png;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;
use png::HasParameters;

use camera::Camera;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;
use texture::checkerboard;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
#[macro_use] mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let raytracer = Raytracer {
        scene: example_scene(),
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let (w, h) = (512, 512);
    let mut output_data = Vec::with_capacity(w * h);
    let primary_rays = raytracer.camera.primary_rays();
    for y in 0 .. h {
        for x in 0 .. w {
            let screen_coords = (x as f32 / w as f32, y as f32 / h as f32);
            let ray = primary_rays.at(screen_coords);
            let result = raytracer.trace(ray, 10);

            let (r, g, b) = result.as_bytes();
            output_data.push(r);
            output_data.push(g);
            output_data.push(b);
        }
    }

    // TODO: add command line options to configure this.
    let output = File::create("output.png").expect("Couldn't create output file.");

    let mut encoder = png::Encoder::new(output, w as u32, h as u32);
    encoder.set(png::ColorType::RGB).set(png::BitDepth::Eight);
    encoder.write_header()
        .unwrap()
        .write_image_data(&output_data)
        .unwrap();
}

fn example_scene() -> Scene {
    let mut scene = Scene::new(color!(0.1, 0.1, 0.1));

    let white = color!(1.0, 1.0, 1.0);
    let red = color!(1.0, 0.0, 0.0);
    let green = color!(0.0, 1.0, 0.0);

    // floor
    scene.add_primitive(
        Primitive::plane(
            Material::solid(
                checkerboard(color!(1.0), color!(0.0), (0.5, 0.5)),
                0.0,
            ),
            vec3(0.0, -1.0, 0.0),
            Vector::unit_y(),
        )
    );

    // left
    scene.add_primitive(
        Primitive::plane(
            Material::solid(red, 0.0),
            vec3(-1.0, 0.0, 0.0),
            Vector::unit_x(),
        )
    );

    // right
    scene.add_primitive(
        Primitive::plane(
            Material::solid(green, 0.0),
            vec3(1.0, 0.0, 0.0),
            -Vector::unit_x(),
        )
    );

    // ceiling
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 1.0, 0.0),
            -Vector::unit_y(),
        )
    );

    // back
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 0.0, 2.0),
            -Vector::unit_z(),
        )
    );

    //front
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 0.0, -2.0),
            Vector::unit_z(),
        )
    );

    scene.add_primitive(
        Primitive::sphere(
            Material::solid(color!(0.1, 0.1, 0.1), 0.6),
            vec3(0.0, 0.0, 2.0),
            1.0,
        )
    );

    scene.add_light(
        Light::point(color!(4.0, 4.0, 4.0), vec3(0.0, 0.0, 0.0)),
    );

    scene
}
<commit_msg>Double output size<commit_after>#![feature(conservative_impl_trait)]

extern crate cgmath;
extern crate ordered_float;
extern crate png;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;
use png::HasParameters;

use camera::Camera;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;
use texture::checkerboard;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
#[macro_use] mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let raytracer = Raytracer {
        scene: example_scene(),
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let (w, h) = (1024, 1024);
    let mut output_data = Vec::with_capacity(w * h);
    let primary_rays = raytracer.camera.primary_rays();
    for y in 0 .. h {
        for x in 0 .. w {
            let screen_coords = (x as f32 / w as f32, y as f32 / h as f32);
            let ray = primary_rays.at(screen_coords);
            let result = raytracer.trace(ray, 10);

            let (r, g, b) = result.as_bytes();
            output_data.push(r);
            output_data.push(g);
            output_data.push(b);
        }
    }

    // TODO: add command line options to configure this.
    let output = File::create("output.png").expect("Couldn't create output file.");

    let mut encoder = png::Encoder::new(output, w as u32, h as u32);
    encoder.set(png::ColorType::RGB).set(png::BitDepth::Eight);
    encoder.write_header()
        .unwrap()
        .write_image_data(&output_data)
        .unwrap();
}

fn example_scene() -> Scene {
    let mut scene = Scene::new(color!(0.1, 0.1, 0.1));

    let white = color!(1.0, 1.0, 1.0);
    let red = color!(1.0, 0.0, 0.0);
    let green = color!(0.0, 1.0, 0.0);

    // floor
    scene.add_primitive(
        Primitive::plane(
            Material::solid(
                checkerboard(color!(1.0), color!(0.0), (0.5, 0.5)),
                0.0,
            ),
            vec3(0.0, -1.0, 0.0),
            Vector::unit_y(),
        )
    );

    // left
    scene.add_primitive(
        Primitive::plane(
            Material::solid(red, 0.0),
            vec3(-1.0, 0.0, 0.0),
            Vector::unit_x(),
        )
    );

    // right
    scene.add_primitive(
        Primitive::plane(
            Material::solid(green, 0.0),
            vec3(1.0, 0.0, 0.0),
            -Vector::unit_x(),
        )
    );

    // ceiling
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 1.0, 0.0),
            -Vector::unit_y(),
        )
    );

    // back
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 0.0, 2.0),
            -Vector::unit_z(),
        )
    );

    //front
    scene.add_primitive(
        Primitive::plane(
            Material::solid(white, 0.0),
            vec3(0.0, 0.0, -2.0),
            Vector::unit_z(),
        )
    );

    scene.add_primitive(
        Primitive::sphere(
            Material::solid(color!(0.1, 0.1, 0.1), 0.6),
            vec3(0.0, 0.0, 2.0),
            1.0,
        )
    );

    scene.add_light(
        Light::point(color!(4.0, 4.0, 4.0), vec3(0.0, 0.0, 0.0)),
    );

    scene
}
<|endoftext|>


<commit_before>use std::env;
use std::collections::HashMap;
#[allow(dead_code)]
struct Operator {
    precedence: i32,
    func: Box<Fn(f32, f32) -> f32>
}

fn get_operators () -> HashMap<char, Operator> {
    let multiply = Operator {
        precedence: 3,
        func: Box::new(move |a: f32, b:f32| a * b)
    };

    let divide = Operator {
        precedence: 3,
        func: Box::new(move |a: f32, b:f32| a / b)
    };

    let add = Operator {
        precedence: 4,
        func: Box::new(move |a: f32, b:f32| a + b)
    };

    let subtract = Operator {
        precedence: 4,
        func: Box::new(move |a: f32, b:f32| a - b)
    };

    let mut operators = HashMap::new();

    operators.insert('*', multiply);
    operators.insert('/', divide);
    operators.insert('+', add);
    operators.insert('-', subtract);

    operators
}

fn main () {
    let args: Vec<_> = env::args().collect();
    let tokens: Vec<&str> = args[1].split(" ").collect();
    let mut operator_stack: Vec<char> = vec![];
    let mut output: Vec<String> = vec![];
    let operators = get_operators();

    for token in tokens {
        let maybe_int = token.parse::<i32>();

        match maybe_int {
            Ok(_) => output.push(token.to_string()),
            Err(_) => {
                if let Some(o1_char) = token.chars().last() {
                    if let Some(o1) = operators.get(&o1_char) {
                        while !operator_stack.is_empty() {
                            if let Some(o2_char) = operator_stack.pop() {
                                if let Some(o2) = operators.get(&o2_char) {
                                    if o1.precedence >= o2.precedence {
                                        output.push(o2_char.to_string());
                                    } else {
                                        operator_stack.push(o2_char);
                                        break;
                                    }
                                }
                            }
                        }

                        operator_stack.push(o1_char);
                    }
                }
            }
        }
    }

    while !operator_stack.is_empty() {
        let op = operator_stack.pop().unwrap().to_string();
        output.push(op);
    }

    println!("{:?}", output);
}
<commit_msg>No, it's not<commit_after>use std::env;
use std::collections::HashMap;
#[allow(dead_code)]
struct Operator {
    precedence: i32,
    func: Box<Fn(f32, f32) -> f32>
}

fn get_operators () -> HashMap<char, Operator> {
    let multiply = Operator {
        precedence: 3,
        func: Box::new(move |a: f32, b:f32| a * b)
    };

    let divide = Operator {
        precedence: 3,
        func: Box::new(move |a: f32, b:f32| a / b)
    };

    let add = Operator {
        precedence: 4,
        func: Box::new(move |a: f32, b:f32| a + b)
    };

    let subtract = Operator {
        precedence: 4,
        func: Box::new(move |a: f32, b:f32| a - b)
    };

    let mut operators = HashMap::new();

    operators.insert('*', multiply);
    operators.insert('/', divide);
    operators.insert('+', add);
    operators.insert('-', subtract);

    operators
}

fn main () {
    let args: Vec<_> = env::args().collect();
    let tokens: Vec<&str> = args[1].split(" ").collect();
    let mut operator_stack: Vec<char> = vec![];
    let mut output: Vec<String> = vec![];
    let operators = get_operators();

    for token in tokens {
        let maybe_int = token.parse::<i32>();

        match maybe_int {
            Ok(_) => output.push(token.to_string()),
            Err(_) => {
                let o1_char = token.to_string().pop().unwrap();
                let o1 = operators.get(&o1_char).unwrap();

                while !operator_stack.is_empty() {
                    let o2_char = operator_stack[operator_stack.len() - 1];
                    let o2 = operators.get(&o2_char).unwrap();
                    if o1.precedence >= o2.precedence {
                        let popped_o2_char = operator_stack.pop().unwrap().to_string();
                        output.push(popped_o2_char);
                    } else {
                        break;
                    }
                }

                operator_stack.push(o1_char);
            }
        }
    }

    while !operator_stack.is_empty() {
        let op = operator_stack.pop().unwrap().to_string();
        output.push(op);
    }

    println!("{:?}", output);
}
<|endoftext|>


<commit_before>use core::cell::UnsafeCell;
use core::sync::atomic::{AtomicUsize, Ordering, spin_loop_hint as cpu_relax};

/// A synchronization primitive which can be used to run a one-time global
/// initialization. Unlike its std equivalent, this is generalized so that The
/// closure returns a value and it is stored. Once therefore acts something like
/// 1a future, too.
///
/// # Examples
///
/// ```
/// #![feature(const_fn)]
/// use spin;
///
/// static START: spin::Once<()> = spin::Once::new();
///
/// START.call_once(|| {
///     // run initialization here
/// });
/// ```
#[derive(Debug)]
pub struct Once<T> {
    state: AtomicUsize,
    data: UnsafeCell<Option<T>>, // TODO remove option and use mem::uninitialized
}

// Same unsafe impls as `std::sync::RwLock`, because this also allows for
// concurrent reads.
unsafe impl<T: Send + Sync> Sync for Once<T> {}
unsafe impl<T: Send> Send for Once<T> {}

// Four states that a Once can be in, encoded into the lower bits of `state` in
// the Once structure.
const INCOMPLETE: usize = 0x0;
const RUNNING: usize = 0x1;
const COMPLETE: usize = 0x2;
const PANICKED: usize = 0x3;

use core::hint::unreachable_unchecked as unreachable;

impl<T> Once<T> {
    /// Initialization constant of `Once`.
    pub const INIT: Self = Once {
        state: AtomicUsize::new(INCOMPLETE),
        data: UnsafeCell::new(None),
    };

    /// Creates a new `Once` value.
    #[cfg(feature = "const_fn")]
    pub const fn new() -> Once<T> {
        Self::INIT
    }

    /// Creates a new `Once` value.
    #[cfg(not(feature = "const_fn"))]
    pub fn new() -> Once<T> {
        Self::INIT
    }

    fn force_get<'a>(&'a self) -> &'a T {
        match unsafe { &*self.data.get() }.as_ref() {
            None    => unsafe { unreachable() },
            Some(p) => p,
        }
    }

    /// Performs an initialization routine once and only once. The given closure
    /// will be executed if this is the first time `call_once` has been called,
    /// and otherwise the routine will *not* be invoked.
    ///
    /// This method will block the calling thread if another initialization
    /// routine is currently running.
    ///
    /// When this function returns, it is guaranteed that some initialization
    /// has run and completed (it may not be the closure specified). The
    /// returned pointer will point to the result from the closure that was
    /// ran.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(const_fn)]
    /// use spin;
    ///
    /// static INIT: spin::Once<usize> = spin::Once::new();
    ///
    /// fn get_cached_val() -> usize {
    ///     *INIT.call_once(expensive_computation)
    /// }
    ///
    /// fn expensive_computation() -> usize {
    ///     // ...
    /// # 2
    /// }
    /// ```
    pub fn call_once<'a, F>(&'a self, builder: F) -> &'a T
        where F: FnOnce() -> T
    {
        let mut status = self.state.load(Ordering::SeqCst);

        if status == INCOMPLETE {
            status = self.state.compare_and_swap(INCOMPLETE,
                                                 RUNNING,
                                                 Ordering::SeqCst);
            if status == INCOMPLETE { // We init
                // We use a guard (Finish) to catch panics caused by builder
                let mut finish = Finish { state: &self.state, panicked: true };
                unsafe { *self.data.get() = Some(builder()) };
                finish.panicked = false;

                status = COMPLETE;
                self.state.store(status, Ordering::SeqCst);

                // This next line is strictly an optomization
                return self.force_get();
            }
        }

        loop {
            match status {
                INCOMPLETE => unreachable!(),
                RUNNING => { // We spin
                    cpu_relax();
                    status = self.state.load(Ordering::SeqCst)
                },
                PANICKED => panic!("Once has panicked"),
                COMPLETE => return self.force_get(),
                _ => unsafe { unreachable() },
            }
        }
    }

    /// Returns a pointer iff the `Once` was previously initialized
    pub fn try<'a>(&'a self) -> Option<&'a T> {
        match self.state.load(Ordering::SeqCst) {
            COMPLETE => Some(self.force_get()),
            _        => None,
        }
    }

    /// Like try, but will spin if the `Once` is in the process of being
    /// initialized
    pub fn wait<'a>(&'a self) -> Option<&'a T> {
        loop {
            match self.state.load(Ordering::SeqCst) {
                INCOMPLETE => return None,
                RUNNING    => cpu_relax(), // We spin
                COMPLETE   => return Some(self.force_get()),
                PANICKED   => panic!("Once has panicked"),
                _ => unsafe { unreachable() },
            }
        }
    }
}

struct Finish<'a> {
    state: &'a AtomicUsize,
    panicked: bool,
}

impl<'a> Drop for Finish<'a> {
    fn drop(&mut self) {
        if self.panicked {
            self.state.store(PANICKED, Ordering::SeqCst);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;

    use std::sync::mpsc::channel;
    use std::thread;
    use super::Once;

    #[test]
    fn smoke_once() {
        static O: Once<()> = Once::new();
        let mut a = 0;
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
    }

    #[test]
    fn smoke_once_value() {
        static O: Once<usize> = Once::new();
        let a = O.call_once(|| 1);
        assert_eq!(*a, 1);
        let b = O.call_once(|| 2);
        assert_eq!(*b, 1);
    }

    #[test]
    fn stampede_once() {
        static O: Once<()> = Once::new();
        static mut RUN: bool = false;

        let (tx, rx) = channel();
        for _ in 0..10 {
            let tx = tx.clone();
            thread::spawn(move|| {
                for _ in 0..4 { thread::yield_now() }
                unsafe {
                    O.call_once(|| {
                        assert!(!RUN);
                        RUN = true;
                    });
                    assert!(RUN);
                }
                tx.send(()).unwrap();
            });
        }

        unsafe {
            O.call_once(|| {
                assert!(!RUN);
                RUN = true;
            });
            assert!(RUN);
        }

        for _ in 0..10 {
            rx.recv().unwrap();
        }
    }

    #[test]
    fn try() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.try().is_none());
        INIT.call_once(|| 2);
        assert_eq!(INIT.try().map(|r| *r), Some(2));
    }

    #[test]
    fn try_no_wait() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.try().is_none());
        thread::spawn(move|| {
            INIT.call_once(|| loop { });
        });
        assert!(INIT.try().is_none());
    }

    #[test]
    fn wait() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.wait().is_none());
        INIT.call_once(|| 3);
        assert_eq!(INIT.wait().map(|r| *r), Some(3));
    }

    #[test]
    fn panic() {
        use ::std::panic;

        static INIT: Once<()> = Once::new();

        // poison the once
        let t = panic::catch_unwind(|| {
            INIT.call_once(|| panic!());
        });
        assert!(t.is_err());

        // poisoning propagates
        let t = panic::catch_unwind(|| {
            INIT.call_once(|| {});
        });
        assert!(t.is_err());
    }

    #[test]
    fn init_constant() {
        static O: Once<()> = Once::INIT;
        let mut a = 0;
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
    }
}
<commit_msg>Implement a more useful Debug for Once.<commit_after>use core::cell::UnsafeCell;
use core::sync::atomic::{AtomicUsize, Ordering, spin_loop_hint as cpu_relax};
use core::fmt;

/// A synchronization primitive which can be used to run a one-time global
/// initialization. Unlike its std equivalent, this is generalized so that The
/// closure returns a value and it is stored. Once therefore acts something like
/// 1a future, too.
///
/// # Examples
///
/// ```
/// #![feature(const_fn)]
/// use spin;
///
/// static START: spin::Once<()> = spin::Once::new();
///
/// START.call_once(|| {
///     // run initialization here
/// });
/// ```
pub struct Once<T> {
    state: AtomicUsize,
    data: UnsafeCell<Option<T>>, // TODO remove option and use mem::uninitialized
}

impl<T: fmt::Debug> fmt::Debug for Once<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.try() {
            Some(s) => write!(f, "Once {{ data: {:?} }}", s),
            None => write!(f, "Once {{ <uninitialized> }}")
        }
    }
}

// Same unsafe impls as `std::sync::RwLock`, because this also allows for
// concurrent reads.
unsafe impl<T: Send + Sync> Sync for Once<T> {}
unsafe impl<T: Send> Send for Once<T> {}

// Four states that a Once can be in, encoded into the lower bits of `state` in
// the Once structure.
const INCOMPLETE: usize = 0x0;
const RUNNING: usize = 0x1;
const COMPLETE: usize = 0x2;
const PANICKED: usize = 0x3;

use core::hint::unreachable_unchecked as unreachable;

impl<T> Once<T> {
    /// Initialization constant of `Once`.
    pub const INIT: Self = Once {
        state: AtomicUsize::new(INCOMPLETE),
        data: UnsafeCell::new(None),
    };

    /// Creates a new `Once` value.
    #[cfg(feature = "const_fn")]
    pub const fn new() -> Once<T> {
        Self::INIT
    }

    /// Creates a new `Once` value.
    #[cfg(not(feature = "const_fn"))]
    pub fn new() -> Once<T> {
        Self::INIT
    }

    fn force_get<'a>(&'a self) -> &'a T {
        match unsafe { &*self.data.get() }.as_ref() {
            None    => unsafe { unreachable() },
            Some(p) => p,
        }
    }

    /// Performs an initialization routine once and only once. The given closure
    /// will be executed if this is the first time `call_once` has been called,
    /// and otherwise the routine will *not* be invoked.
    ///
    /// This method will block the calling thread if another initialization
    /// routine is currently running.
    ///
    /// When this function returns, it is guaranteed that some initialization
    /// has run and completed (it may not be the closure specified). The
    /// returned pointer will point to the result from the closure that was
    /// ran.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(const_fn)]
    /// use spin;
    ///
    /// static INIT: spin::Once<usize> = spin::Once::new();
    ///
    /// fn get_cached_val() -> usize {
    ///     *INIT.call_once(expensive_computation)
    /// }
    ///
    /// fn expensive_computation() -> usize {
    ///     // ...
    /// # 2
    /// }
    /// ```
    pub fn call_once<'a, F>(&'a self, builder: F) -> &'a T
        where F: FnOnce() -> T
    {
        let mut status = self.state.load(Ordering::SeqCst);

        if status == INCOMPLETE {
            status = self.state.compare_and_swap(INCOMPLETE,
                                                 RUNNING,
                                                 Ordering::SeqCst);
            if status == INCOMPLETE { // We init
                // We use a guard (Finish) to catch panics caused by builder
                let mut finish = Finish { state: &self.state, panicked: true };
                unsafe { *self.data.get() = Some(builder()) };
                finish.panicked = false;

                status = COMPLETE;
                self.state.store(status, Ordering::SeqCst);

                // This next line is strictly an optomization
                return self.force_get();
            }
        }

        loop {
            match status {
                INCOMPLETE => unreachable!(),
                RUNNING => { // We spin
                    cpu_relax();
                    status = self.state.load(Ordering::SeqCst)
                },
                PANICKED => panic!("Once has panicked"),
                COMPLETE => return self.force_get(),
                _ => unsafe { unreachable() },
            }
        }
    }

    /// Returns a pointer iff the `Once` was previously initialized
    pub fn try<'a>(&'a self) -> Option<&'a T> {
        match self.state.load(Ordering::SeqCst) {
            COMPLETE => Some(self.force_get()),
            _        => None,
        }
    }

    /// Like try, but will spin if the `Once` is in the process of being
    /// initialized
    pub fn wait<'a>(&'a self) -> Option<&'a T> {
        loop {
            match self.state.load(Ordering::SeqCst) {
                INCOMPLETE => return None,
                RUNNING    => cpu_relax(), // We spin
                COMPLETE   => return Some(self.force_get()),
                PANICKED   => panic!("Once has panicked"),
                _ => unsafe { unreachable() },
            }
        }
    }
}

struct Finish<'a> {
    state: &'a AtomicUsize,
    panicked: bool,
}

impl<'a> Drop for Finish<'a> {
    fn drop(&mut self) {
        if self.panicked {
            self.state.store(PANICKED, Ordering::SeqCst);
        }
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;

    use std::sync::mpsc::channel;
    use std::thread;
    use super::Once;

    #[test]
    fn smoke_once() {
        static O: Once<()> = Once::new();
        let mut a = 0;
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
    }

    #[test]
    fn smoke_once_value() {
        static O: Once<usize> = Once::new();
        let a = O.call_once(|| 1);
        assert_eq!(*a, 1);
        let b = O.call_once(|| 2);
        assert_eq!(*b, 1);
    }

    #[test]
    fn stampede_once() {
        static O: Once<()> = Once::new();
        static mut RUN: bool = false;

        let (tx, rx) = channel();
        for _ in 0..10 {
            let tx = tx.clone();
            thread::spawn(move|| {
                for _ in 0..4 { thread::yield_now() }
                unsafe {
                    O.call_once(|| {
                        assert!(!RUN);
                        RUN = true;
                    });
                    assert!(RUN);
                }
                tx.send(()).unwrap();
            });
        }

        unsafe {
            O.call_once(|| {
                assert!(!RUN);
                RUN = true;
            });
            assert!(RUN);
        }

        for _ in 0..10 {
            rx.recv().unwrap();
        }
    }

    #[test]
    fn try() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.try().is_none());
        INIT.call_once(|| 2);
        assert_eq!(INIT.try().map(|r| *r), Some(2));
    }

    #[test]
    fn try_no_wait() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.try().is_none());
        thread::spawn(move|| {
            INIT.call_once(|| loop { });
        });
        assert!(INIT.try().is_none());
    }

    #[test]
    fn wait() {
        static INIT: Once<usize> = Once::new();

        assert!(INIT.wait().is_none());
        INIT.call_once(|| 3);
        assert_eq!(INIT.wait().map(|r| *r), Some(3));
    }

    #[test]
    fn panic() {
        use ::std::panic;

        static INIT: Once<()> = Once::new();

        // poison the once
        let t = panic::catch_unwind(|| {
            INIT.call_once(|| panic!());
        });
        assert!(t.is_err());

        // poisoning propagates
        let t = panic::catch_unwind(|| {
            INIT.call_once(|| {});
        });
        assert!(t.is_err());
    }

    #[test]
    fn init_constant() {
        static O: Once<()> = Once::INIT;
        let mut a = 0;
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
        O.call_once(|| a += 1);
        assert_eq!(a, 1);
    }
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]

extern crate rustbox;

use std::collections::dlist::DList;
use std::comm::{Receiver, Sender};
use std::io::{File, BufferedReader};
use std::str::from_utf8;

pub struct Editor {
    pub sender: Sender<rustbox::Event>,
    pub events: Receiver<rustbox::Event>,
    pub buffers: Vec<Buf>
}

pub struct Buf {
    pub lines: DList<Line>,
    pub active: bool,
    pub num_lines: int,
}

#[deriving(Clone)]
pub struct Line {
    pub data: String,
}

pub enum Response {
    Continue,
    Quit,
}

impl Buf {
    pub fn new() -> Buf {
        Buf {
            lines: DList::new(),
            active: false,
            num_lines: 0,
        }
    }

    pub fn new_from_file(filename: String) -> Buf {
        let path = Path::new(filename.to_string());

        let mut new_buffer = Buf::new();
        let mut file = BufferedReader::new(File::open(&path));
        let lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();

        for line in lines.iter() {
            new_buffer.lines.push(Line{data: line.clone()})
        }

        new_buffer
    }
}

impl Line {
    pub fn new() -> Line {
        Line {
            data: String::new(),
        }
    }
}

impl Editor {
    pub fn new(filenames: &[String]) -> Editor {
        let mut buffers = Vec::new();

        for filename in filenames.iter() {
            let mut b = Buf::new_from_file(filename.clone());
            b.active = true;
            buffers.push(b);
        }

        let (send, recv) = channel();
        Editor {
            sender: send,
            events: recv,
            buffers: buffers,
        }
    }

    pub fn handle_key_event(&self, ch: u32) -> Response {
        match std::char::from_u32(ch) {
            Some('q') => Quit,
            _ => Continue,
        }
    }

    pub fn draw(&mut self) {
        for buffer in self.buffers.iter() {
            if buffer.active {
                for (index, line) in buffer.lines.iter().enumerate() {
                    rustbox::print(1, index, rustbox::Bold, rustbox::White, rustbox::Black, line.data.clone());
                }
            }
        }
        rustbox::set_cursor(0, 1);
    }

    pub fn start(&mut self) -> bool {
        loop {
            self.draw();
            rustbox::present();
            let status = match self.events.recv() {
                rustbox::KeyEvent(_, _, ch) => {
                    let status = self.handle_key_event(ch);
                    match status {
                        Quit => { false },
                        _ => { true },
                    }
                },
                _ => { true }
            };
            if status == false {
                return false;
            }
        }
    }

}

<commit_msg>Use try_recv instead of recv for getting key events<commit_after>#![feature(macro_rules)]

extern crate rustbox;

use std::collections::dlist::DList;
use std::comm::{Receiver, Sender};
use std::io::{File, BufferedReader};
use std::str::from_utf8;

pub struct Editor {
    pub sender: Sender<rustbox::Event>,
    pub events: Receiver<rustbox::Event>,
    pub buffers: Vec<Buf>
}

pub struct Buf {
    pub lines: DList<Line>,
    pub active: bool,
    pub num_lines: int,
}

#[deriving(Clone)]
pub struct Line {
    pub data: String,
}

pub enum Response {
    Continue,
    Quit,
}

impl Buf {
    pub fn new() -> Buf {
        Buf {
            lines: DList::new(),
            active: false,
            num_lines: 0,
        }
    }

    pub fn new_from_file(filename: String) -> Buf {
        let path = Path::new(filename.to_string());

        let mut new_buffer = Buf::new();
        let mut file = BufferedReader::new(File::open(&path));
        let lines: Vec<String> = file.lines().map(|x| x.unwrap()).collect();

        for line in lines.iter() {
            new_buffer.lines.push(Line{data: line.clone()})
        }

        new_buffer
    }
}

impl Line {
    pub fn new() -> Line {
        Line {
            data: String::new(),
        }
    }
}

impl Editor {
    pub fn new(filenames: &[String]) -> Editor {
        let mut buffers = Vec::new();

        for filename in filenames.iter() {
            let mut b = Buf::new_from_file(filename.clone());
            b.active = true;
            buffers.push(b);
        }

        let (send, recv) = channel();
        Editor {
            sender: send,
            events: recv,
            buffers: buffers,
        }
    }

    pub fn handle_key_event(&self, ch: u32) -> Response {
        match std::char::from_u32(ch) {
            Some('q') => Quit,
            _ => Continue,
        }
    }

    pub fn draw(&mut self) {
        for buffer in self.buffers.iter() {
            if buffer.active {
                for (index, line) in buffer.lines.iter().enumerate() {
                    rustbox::print(0, index, rustbox::Bold, rustbox::White, rustbox::Black, line.data.clone());
                }
            }
        }
        rustbox::set_cursor(0, 0);
    }

    pub fn start(&mut self) -> bool {
        loop {
            self.draw();
            rustbox::present();
            match self.events.try_recv() {
                Ok(rustbox::KeyEvent(_, _, ch)) => {
                    match self.handle_key_event(ch) {
                        Quit => break,
                        _ => {}
                    }
                },
                TryRecvError => {}
            }
        }
        return false
    }

}

<|endoftext|>


<commit_before>fn cleanup(mut c: ::RedisContext){
  let r = c.command("DEL", ["mykey"]);

  match r {
    Ok(i) => match i {
      Some(i) => match i {
        ::RedisInteger(_) => (),
        _ => fail!("Failed to clean up")
      },
      None => fail!("Failed to clean up")
    },
    Err(_) => fail!("Failed to cleanup")
  }

  c.close();
}

fn check_append(r: Result<Option<::RedisObject>, &'static str>){
  match r {
    Ok(i) => match i {
      Some(i) => match i {
        ::RedisInteger(i) => assert!(i == 5),
        _ => fail!("INTEGER: Didn't return correct reply type.")
      },
      None => fail!("INTEGER: Didn't return anything.")
    },
    Err(e) => fail!("INTEGER: {}", e)
  }
}

#[test]
fn test_connect(){
  let c = ::RedisContext::connect("127.0.0.1", 6379);
  c.close();
}

#[test]
fn test_command(){
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("PING", []);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisStatus(s) => assert!(s.eq(&"PONG".to_string())),
        _ => fail!("Didn't return correct reply type.")
      },
      None => fail!("Didn't return anything.")
    },
    Err(e) => fail!("{}", e)
  }
  c.close();
}

#[test]
fn test_line_item_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("APPEND", ["mykey", "te\nst"]);

  check_append(r);
  cleanup(c);
}

#[test]
fn test_bulk_item_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("APPEND", ["mykey", "te\nst"]);

  check_append(r);

  // String
  let r = c.command("GET", ["mykey"]);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisString(s) => assert!(s.eq(&"te\nst".to_string())),
        _ => fail!("STRING: Didn't return correct reply type.")
      },
      None => fail!("STRING: Didn't return anything.")
    },
    Err(e) => fail!("{}", e)
  }

  cleanup(c);
}

#[test]
fn test_nil_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("GET", ["notmykey"]);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisNil => return,
        _ => fail!("NIL: Didn't return correct reply type.")
      },
      None => fail!("NIL: Didn't return anything."),
    },
    Err(e) => fail!("{}", e)
  }
  c.close();
}
<commit_msg>fix warning in test file<commit_after>fn cleanup(mut c: ::RedisContext){
  let r = c.command("DEL", ["mykey"]);

  match r {
    Ok(i) => match i {
      Some(i) => match i {
        ::RedisInteger(_) => (),
        _ => fail!("Failed to clean up")
      },
      None => fail!("Failed to clean up")
    },
    Err(_) => fail!("Failed to cleanup")
  }

  c.close();
}

fn check_append(r: Result<Option<::RedisObject>, &'static str>){
  match r {
    Ok(i) => match i {
      Some(i) => match i {
        ::RedisInteger(i) => assert!(i == 5),
        _ => fail!("INTEGER: Didn't return correct reply type.")
      },
      None => fail!("INTEGER: Didn't return anything.")
    },
    Err(e) => fail!("INTEGER: {}", e)
  }
}

#[test]
fn test_connect(){
  let c = ::RedisContext::connect("127.0.0.1", 6379);
  c.close();
}

#[test]
fn test_command(){
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("PING", []);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisStatus(s) => assert!(s.eq(&"PONG".to_string())),
        _ => fail!("Didn't return correct reply type.")
      },
      None => fail!("Didn't return anything.")
    },
    Err(e) => fail!("{}", e)
  }
  c.close();
}

#[test]
fn test_line_item_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("APPEND", ["mykey", "te\nst"]);

  check_append(r);
  cleanup(c);
}

#[test]
fn test_bulk_item_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("APPEND", ["mykey", "te\nst"]);

  check_append(r);

  // String
  let r = c.command("GET", ["mykey"]);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisString(s) => assert!(s.eq(&"te\nst".to_string())),
        _ => fail!("STRING: Didn't return correct reply type.")
      },
      None => fail!("STRING: Didn't return anything.")
    },
    Err(e) => fail!("{}", e)
  }

  cleanup(c);
}

#[test]
fn test_nil_reply() {
  let mut c = ::RedisContext::connect("127.0.0.1", 6379);
  let r = c.command("GET", ["notmykey"]);

  match r {
    Ok(s) => match s {
      Some(s) => match s {
        ::RedisNil => (),
        _ => fail!("NIL: Didn't return correct reply type.")
      },
      None => fail!("NIL: Didn't return anything."),
    },
    Err(e) => fail!("{}", e)
  }
  c.close();
}
<|endoftext|>