<commit_before>// Copyright 2015 Corey Farwell
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* TODO:
 *  * redirect root url
 *  * add watermark? url to repo?
 *  * update git repo?
 *  * serverside caching? redis?
 */

use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{Write, Read};
use std::process::{Command, Stdio};

use tiny_http::{Header, Response};

extern crate crates_index;
extern crate tiny_http;

static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

struct DotBuilder {
    buf: String,
}

impl DotBuilder {
    fn new_digraph(name: &str) -> Self {
        DotBuilder{buf: format!("digraph \"{}\" {}", name, "{")}
    }

    fn set_ratio(&mut self, ratio: &str) {
        self.buf.push_str(&format!("ratio={};", ratio))
    }

    fn set_node_attrs(&mut self, node: &str, attrs: &str) {
        self.buf.push_str(&format!("\"{}\" [{}];", node, attrs));
    }

    fn add_edge(&mut self, from: &str, to: &str) {
        self.buf.push_str(&format!("\"{}\" -> \"{}\";", from, to));
    }

    fn finish(&mut self) {
        self.buf.push_str("}");
    }

    fn png_bytes(&self) -> Vec<u8> {
        let child = Command::new("dot").arg("-Tpng")
                                       .stdin(Stdio::piped()).stdout(Stdio::piped())
                                       .spawn().unwrap();
        child.stdin.unwrap().write_all(self.buf.as_bytes()).unwrap();
        let mut ret = vec![];
        child.stdout.unwrap().read_to_end(&mut ret).unwrap();
        ret
    }
}

fn build_dot_png(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = DotBuilder::new_digraph(crate_name);
    dot.set_ratio("0.75");
    dot.set_node_attrs(crate_name, "root=true,style=filled,fillcolor=grey");

    // Which dependencies we've already seen
    let mut seen_set = HashSet::new();

    while let Some(crate_name) = crate_names.pop() {
        if seen_set.contains(crate_name as &str) {
            continue;
        }
        seen_set.insert(crate_name);
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.add_edge(crate_name, crate_dep);
            if !seen_set.contains(crate_dep as &str) {
                crate_names.push(crate_dep);
            }
        }
    }
    dot.finish();

    dot.png_bytes()
}

fn main() {
    let index = crates_index::CratesIndex::new(INDEX_LOCAL_PATH.into());
    if !index.exists() {
        println!("Cloning crates.io-index");
        index.clone_index();
    }

    let dep_map = index.dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = {
            let crate_name = req.url().trim_left_matches("/");
            if dep_map.get(crate_name).is_some() {
                let data = build_dot_png(crate_name, &dep_map);
                let content_type_header = "Content-Type: image/png".parse::<Header>().unwrap();
                let cache_control_header = "cache-control: no-cache".parse::<Header>().unwrap();
                Response::from_data(data).with_header(content_type_header)
                                         .with_header(cache_control_header)
            } else {
                let error = format!("could not find crate (that has dependencies) titled: '{}'", crate_name);
                Response::from_string(error).with_status_code(400)
            }
        };
        req.respond(response);
    }
}
<commit_msg>Redirect if they try to access root url<commit_after>// Copyright 2015 Corey Farwell
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* TODO:
 *  * add watermark? url to repo?
 *  * update git repo?
 *  * serverside caching? redis?
 */

use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{Write, Read};
use std::process::{Command, Stdio};

use tiny_http::{Header, Response};

extern crate crates_index;
extern crate tiny_http;

static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

struct DotBuilder {
    buf: String,
}

impl DotBuilder {
    fn new_digraph(name: &str) -> Self {
        DotBuilder{buf: format!("digraph \"{}\" {}", name, "{")}
    }

    fn set_ratio(&mut self, ratio: &str) {
        self.buf.push_str(&format!("ratio={};", ratio))
    }

    fn set_node_attrs(&mut self, node: &str, attrs: &str) {
        self.buf.push_str(&format!("\"{}\" [{}];", node, attrs));
    }

    fn add_edge(&mut self, from: &str, to: &str) {
        self.buf.push_str(&format!("\"{}\" -> \"{}\";", from, to));
    }

    fn finish(&mut self) {
        self.buf.push_str("}");
    }

    fn png_bytes(&self) -> Vec<u8> {
        let child = Command::new("dot").arg("-Tpng")
                                       .stdin(Stdio::piped()).stdout(Stdio::piped())
                                       .spawn().unwrap();
        child.stdin.unwrap().write_all(self.buf.as_bytes()).unwrap();
        let mut ret = vec![];
        child.stdout.unwrap().read_to_end(&mut ret).unwrap();
        ret
    }
}

fn build_dot_png(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = DotBuilder::new_digraph(crate_name);
    dot.set_ratio("0.75");
    dot.set_node_attrs(crate_name, "root=true,style=filled,fillcolor=grey");

    // Which dependencies we've already seen
    let mut seen_set = HashSet::new();

    while let Some(crate_name) = crate_names.pop() {
        if seen_set.contains(crate_name as &str) {
            continue;
        }
        seen_set.insert(crate_name);
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.add_edge(crate_name, crate_dep);
            if !seen_set.contains(crate_dep as &str) {
                crate_names.push(crate_dep);
            }
        }
    }
    dot.finish();

    dot.png_bytes()
}

fn main() {
    let index = crates_index::CratesIndex::new(INDEX_LOCAL_PATH.into());
    if !index.exists() {
        println!("Cloning crates.io-index");
        index.clone_index();
    }

    let dep_map = index.dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = {
            let crate_name = req.url().trim_left_matches("/");
            if crate_name.is_empty() {
                let location_header = "Location: https://github.com/frewsxcv/crate-deps".parse::<Header>().unwrap();
                // FIXME: use Response::empty() instead of Response::from_string()
                Response::from_string("").with_status_code(302)
                                         .with_header(location_header)
            } else if dep_map.get(crate_name).is_some() {
                let data = build_dot_png(crate_name, &dep_map);
                let content_type_header = "Content-Type: image/png".parse::<Header>().unwrap();
                let cache_control_header = "cache-control: no-cache".parse::<Header>().unwrap();
                Response::from_data(data).with_header(content_type_header)
                                         .with_header(cache_control_header)
            } else {
                let error = format!("could not find crate (that has dependencies) titled: '{}'", crate_name);
                Response::from_string(error).with_status_code(400)
            }
        };
        req.respond(response);
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::os::unix::fs::PermissionsExt;
use std::process::{self, Command, Stdio};

extern crate clap;
use clap::{App, Arg, ArgGroup};

extern crate isbfc;

fn main() {
    let matches = App::new("isbfc")
        .version("0.0.1")
        .author("Ian D. Scott <ian@iandouglasscott.com>")
        .about("Brainfuck compiler")
        .arg(
            Arg::with_name("output_asm")
                .short("S")
                .help("Assemble but do not link"),
        )
        .arg(
            Arg::with_name("dump_ir")
                .long("dumpir")
                .help("Dump intermediate representation; for debugging"),
        )
        .group(ArgGroup::with_name("actions").args(&["output_asm", "dump_ir"]))
        .arg(
            Arg::with_name("debugging_symbols")
                .short("g")
                .help("Generate debugging information"),
        )
        .arg(
            Arg::with_name("out_name")
                .short("o")
                .help("Output file name")
                .takes_value(true)
                .empty_values(false)
                .value_name("file"),
        )
        .arg(
            Arg::with_name("tape_size")
                .long("tape-size")
                .help("Size of tape")
                .takes_value(true)
                .empty_values(false)
                .default_value("8192")
                .value_name("bytes"),
        )
        .arg(
            Arg::with_name("minimal_elf")
                .long("minimal-elf")
                .help("Generate minimal ELF executable"),
        )
        .arg(
            Arg::with_name("level")
                .short("O")
                .help("Optimization level")
                .takes_value(true)
                .empty_values(false)
                .default_value("1"),
        )
        .arg(
            Arg::with_name("FILENAME")
                .help("Source file to compile")
                .required(true)
                .index(1),
        )
        .get_matches();

    let tape_size = matches
        .value_of("tape_size")
        .unwrap()
        .parse::<i32>()
        .unwrap();

    let level = matches.value_of("level").unwrap().parse::<u32>().unwrap();

    let path = matches.value_of("FILENAME").unwrap();
    let name = path.rsplitn(2, '.').last().unwrap();
    let mut file = File::open(&path).unwrap();
    let mut code = Vec::new();
    file.read_to_end(&mut code).unwrap();

    let mut ir = match isbfc::parse(&code) {
        Ok(ir) => ir,
        Err(err) => {
            println!("Parsing error: {}", err);
            process::exit(1);
        }
    };
    if level > 0 {
        ir = ir.optimize();
    }

    if matches.is_present("dump_ir") {
        if let Some(out_name) = matches.value_of("out_name") {
            let mut irfile = File::create(out_name).unwrap();
            writeln!(irfile, "{:#?}", ir).unwrap();
        } else {
            println!("{:#?}", ir);
        }
    } else if matches.is_present("output_asm") {
        println!("Compiling...");
        let output = ir.compile(tape_size);
        let def_name = format!("{}.s", name);
        let out_name = matches.value_of("out_name").unwrap_or(&def_name);
        let mut asmfile = File::create(out_name).unwrap();
        asmfile.write_all(&output.into_bytes()).unwrap();
    } else {
        println!("Compiling...");
        let output = ir.compile(tape_size);
        let out_name = matches.value_of("out_name").unwrap_or(name);
        let debug = matches.is_present("debugging_symbols");
        let minimal = matches.is_present("minimal_elf");
        asm_and_link(&output, &name, &out_name, debug, minimal);
    }
}

fn object_to_binary(o_name: &str) -> (Vec<u8>, u64) {
    let mut o_file = File::open(o_name).unwrap();
    let text = isbfc::elf64_get_section(&mut o_file, b".text")
        .unwrap()
        .unwrap();
    let bss = isbfc::elf64_get_section(&mut o_file, b".bss")
        .unwrap()
        .unwrap();
    let bss_offset = (text.sh_size + 0x1000 - 1) & !(0x1000 - 1);
    let bss_size = bss.sh_size;

    let bin = Command::new("ld")
        .arg("--oformat")
        .arg("binary")
        .arg("-Ttext")
        .arg("0x401000")
        .arg("-Tbss")
        .arg(format!("0x{:x}", 0x401000 + bss_offset))
        .arg("-o")
        .arg("/dev/stdout")
        .arg(o_name)
        .output()
        .unwrap()
        .stdout;

    (bin, bss_size)
}

fn assemble(code: &str, out_name: &str, debug: bool) -> io::Result<Option<i32>> {
    let mut command = Command::new("as");
    if debug {
        command.arg("-g");
    }
    let mut child = command
        .arg("-o")
        .arg(out_name)
        .arg("-") // Standard input
        .stdin(Stdio::piped())
        .spawn()?;

    child
        .stdin
        .take()
        .unwrap()
        .write_all(code.as_bytes())?;

    Ok(child.wait()?.code())
}

fn asm_and_link(code: &str, name: &str, out_name: &str, debug: bool, minimal: bool) {
    println!("Assembling...");

    let code = assemble(code, &format!("{}.o", name), debug).unwrap();
    if code != Some(0) {
        process::exit(1);
    }

    println!("Linking...");

    let o_name = format!("{}.o", name);

    if minimal {
        let (bin, bss_size) = object_to_binary(&o_name);

        let mut file = File::create(out_name).unwrap();
        isbfc::elf64_write(&mut file, &bin, bss_size).unwrap();
        let mut permissions = file.metadata().unwrap().permissions();
        permissions.set_mode(permissions.mode() | 0o111);
        file.set_permissions(permissions).unwrap();
    } else {
        Command::new("ld")
            .arg("-o")
            .arg(out_name)
            .arg(o_name)
            .spawn()
            .unwrap();
    }
}
<commit_msg>Split linking into another function<commit_after>use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::os::unix::fs::PermissionsExt;
use std::process::{self, Command, Stdio};

extern crate clap;
use clap::{App, Arg, ArgGroup};

extern crate isbfc;

fn main() {
    let matches = App::new("isbfc")
        .version("0.0.1")
        .author("Ian D. Scott <ian@iandouglasscott.com>")
        .about("Brainfuck compiler")
        .arg(
            Arg::with_name("output_asm")
                .short("S")
                .help("Assemble but do not link"),
        )
        .arg(
            Arg::with_name("dump_ir")
                .long("dumpir")
                .help("Dump intermediate representation; for debugging"),
        )
        .group(ArgGroup::with_name("actions").args(&["output_asm", "dump_ir"]))
        .arg(
            Arg::with_name("debugging_symbols")
                .short("g")
                .help("Generate debugging information"),
        )
        .arg(
            Arg::with_name("out_name")
                .short("o")
                .help("Output file name")
                .takes_value(true)
                .empty_values(false)
                .value_name("file"),
        )
        .arg(
            Arg::with_name("tape_size")
                .long("tape-size")
                .help("Size of tape")
                .takes_value(true)
                .empty_values(false)
                .default_value("8192")
                .value_name("bytes"),
        )
        .arg(
            Arg::with_name("minimal_elf")
                .long("minimal-elf")
                .help("Generate minimal ELF executable"),
        )
        .arg(
            Arg::with_name("level")
                .short("O")
                .help("Optimization level")
                .takes_value(true)
                .empty_values(false)
                .default_value("1"),
        )
        .arg(
            Arg::with_name("FILENAME")
                .help("Source file to compile")
                .required(true)
                .index(1),
        )
        .get_matches();

    let tape_size = matches
        .value_of("tape_size")
        .unwrap()
        .parse::<i32>()
        .unwrap();

    let level = matches.value_of("level").unwrap().parse::<u32>().unwrap();

    let path = matches.value_of("FILENAME").unwrap();
    let name = path.rsplitn(2, '.').last().unwrap();
    let mut file = File::open(&path).unwrap();
    let mut code = Vec::new();
    file.read_to_end(&mut code).unwrap();

    let mut ir = match isbfc::parse(&code) {
        Ok(ir) => ir,
        Err(err) => {
            println!("Parsing error: {}", err);
            process::exit(1);
        }
    };
    if level > 0 {
        ir = ir.optimize();
    }

    if matches.is_present("dump_ir") {
        if let Some(out_name) = matches.value_of("out_name") {
            let mut irfile = File::create(out_name).unwrap();
            writeln!(irfile, "{:#?}", ir).unwrap();
        } else {
            println!("{:#?}", ir);
        }
    } else if matches.is_present("output_asm") {
        println!("Compiling...");
        let output = ir.compile(tape_size);
        let def_name = format!("{}.s", name);
        let out_name = matches.value_of("out_name").unwrap_or(&def_name);
        let mut asmfile = File::create(out_name).unwrap();
        asmfile.write_all(&output.into_bytes()).unwrap();
    } else {
        println!("Compiling...");
        let output = ir.compile(tape_size);
        let out_name = matches.value_of("out_name").unwrap_or(name);
        let debug = matches.is_present("debugging_symbols");
        let minimal = matches.is_present("minimal_elf");
        asm_and_link(&output, &name, &out_name, debug, minimal);
    }
}

fn object_to_binary(o_name: &str) -> (Vec<u8>, u64) {
    let mut o_file = File::open(o_name).unwrap();
    let text = isbfc::elf64_get_section(&mut o_file, b".text")
        .unwrap()
        .unwrap();
    let bss = isbfc::elf64_get_section(&mut o_file, b".bss")
        .unwrap()
        .unwrap();
    let bss_offset = (text.sh_size + 0x1000 - 1) & !(0x1000 - 1);
    let bss_size = bss.sh_size;

    let bin = Command::new("ld")
        .arg("--oformat")
        .arg("binary")
        .arg("-Ttext")
        .arg("0x401000")
        .arg("-Tbss")
        .arg(format!("0x{:x}", 0x401000 + bss_offset))
        .arg("-o")
        .arg("/dev/stdout")
        .arg(o_name)
        .output()
        .unwrap()
        .stdout;

    (bin, bss_size)
}

fn assemble(code: &str, out_name: &str, debug: bool) -> io::Result<Option<i32>> {
    let mut command = Command::new("as");
    if debug {
        command.arg("-g");
    }
    let mut child = command
        .arg("-o")
        .arg(out_name)
        .arg("-") // Standard input
        .stdin(Stdio::piped())
        .spawn()?;

    child
        .stdin
        .take()
        .unwrap()
        .write_all(code.as_bytes())?;

    Ok(child.wait()?.code())
}

fn link(o_name: &str, out_name: &str, minimal: bool) -> io::Result<Option<i32>> {
    if minimal {
        let (bin, bss_size) = object_to_binary(&o_name);

        let mut file = File::create(out_name)?;
        isbfc::elf64_write(&mut file, &bin, bss_size)?;
        let mut permissions = file.metadata().unwrap().permissions();
        permissions.set_mode(permissions.mode() | 0o111);
        file.set_permissions(permissions)?;
        Ok(Some(0))
    } else {
        Ok(Command::new("ld")
            .arg("-o")
            .arg(out_name)
            .arg(o_name)
            .spawn()?
            .wait()?
            .code())
    }
}

fn asm_and_link(code: &str, name: &str, out_name: &str, debug: bool, minimal: bool) {
    let o_name = format!("{}.o", name);

    println!("Assembling...");

    let code = assemble(code, &o_name, debug).unwrap();
    if code != Some(0) {
        process::exit(1);
    }

    println!("Linking...");

    let code = link(&o_name, out_name, minimal).unwrap();
    if code != Some(0) {
        process::exit(1);
    }
}
<|endoftext|>


<commit_before>extern crate nix;
extern crate ansi_term;
extern crate time;

use std::ffi::CString;
use std::io::{self, Write};
use nix::{unistd, sys};
use ansi_term::Colour::{Green, Red};
mod builtins;
mod commands;

use commands::Command;

fn main() {
    prompt(Ok(()));

    loop {
        let line = read_line().expect("can't read from stdin");
        let commands = commands::parse(&line);

        prompt(run(&commands));
    }
}

fn prompt(status: nix::Result<()>) {
    let time = time::now();
    let cwd = unistd::getcwd().unwrap();
    let icon = match status {
        Ok(_) => Green.paint("v"),
        Err(e) => Red.paint(format!("{}\nx", e.to_string())),
    };

    print!("{icon} {cwd} \n{time} $ ",
           icon=icon,
           time=time.strftime("%H:%M").unwrap(),
           cwd=cwd.to_str().unwrap());

    io::stdout().flush().unwrap()
}

fn read_line() -> io::Result<String> {
    let mut buffer = String::new();
    try!(io::stdin().read_line(&mut buffer));
    Ok(buffer)
}

fn run(commands: &[Command]) -> nix::Result<()> {
    for command in commands { exec(&command)? }
    sys::wait::wait().map(|_| ())
}

fn exec(command: &Command) -> nix::Result<()> {
    let result = try!(unistd::fork());
    if result.is_parent() { return Ok(()); }

    if command.fd.0 != 0 {
        unistd::dup2(command.fd.0, 0)?;
        unistd::close(command.fd.0)?;
    }

    if command.fd.1 != 1 {
        unistd::dup2(command.fd.1, 1)?;
        unistd::close(command.fd.1)?;
    }

    try!(match command.args.get(0) {
        Some(&"cd") => builtins::cd(&command.args),
        Some(&"echo") => builtins::echo(&command.args),
        _ => {
            let cargs: Vec<CString> = command.args.iter()
                .map(|s| CString::new(s.to_string()).unwrap())
                .collect();

            unistd::execvp(&cargs[0], &cargs)?;
            unreachable!()
        }
    });
    std::process::exit(0);
}
<commit_msg>Constantly use ? operator instead of try!<commit_after>#![feature(slice_patterns)]

extern crate nix;
extern crate ansi_term;
extern crate time;

use std::ffi::CString;
use std::io::{self, Write};
use nix::{unistd, sys};
use ansi_term::Colour::{Green, Red};
mod builtins;
mod commands;

use commands::Command;

fn main() {
    prompt(Ok(()));

    loop {
        let line = read_line().expect("can't read from stdin");
        let commands = commands::parse(&line);

        prompt(run(&commands));
    }
}

fn prompt(status: nix::Result<()>) {
    let time = time::now();
    let cwd = unistd::getcwd().unwrap();
    let icon = match status {
        Ok(_) => Green.paint("v"),
        Err(e) => Red.paint(format!("{}\nx", e.to_string())),
    };

    print!("{icon} {cwd} \n{time} $ ",
           icon=icon,
           time=time.strftime("%H:%M").unwrap(),
           cwd=cwd.to_str().unwrap());

    io::stdout().flush().unwrap()
}

fn read_line() -> io::Result<String> {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer)?;
    Ok(buffer)
}

fn run(commands: &[Command]) -> nix::Result<()> {
    for command in commands { exec(&command)? }
    sys::wait::wait().map(|_| ())
}

fn exec(command: &Command) -> nix::Result<()> {
    let result = unistd::fork()?;
    if result.is_parent() { return Ok(()); }

    if command.fd.0 != 0 {
        unistd::dup2(command.fd.0, 0)?;
        unistd::close(command.fd.0)?;
    }

    if command.fd.1 != 1 {
        unistd::dup2(command.fd.1, 1)?;
        unistd::close(command.fd.1)?;
    }

    match command.args.get(0) {
        Some(&"cd") => builtins::cd(&command.args),
        Some(&"echo") => builtins::echo(&command.args),
        _ => {
            let cargs: Vec<CString> = command.args.iter()
                .map(|s| CString::new(s.to_string()).unwrap())
                .collect();

            unistd::execvp(&cargs[0], &cargs)?;
            unreachable!()
        }
    }?;
    std::process::exit(0);
}
<|endoftext|>


<commit_before>extern crate cgmath;
extern crate image;

use std::io;

use cgmath::prelude::*;
use cgmath::vec3;

use camera::Camera;
use math::*;
use primitive::Sphere;
use ray::Ray;
use raytracer::Raytracer;
use scene::Scene;

mod camera;
mod color;
mod intersection;
mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;

fn main() {
    let mut scene = Scene::new();
    scene.add_primitive(Sphere::new(vec3(0.0, 0.0, 2.0), 1.0));
    let raytracer = Raytracer {
        scene: scene,
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0),
    };

    let size = (512, 512);
    let mut buffer = image::ImageBuffer::new(size.0, size.1);
    for (x, y, pixel) in buffer.enumerate_pixels_mut() {
        let (top_left, top_right, bottom_left) = raytracer.camera.screen_corners();

        let basis_x = top_right - top_left;
        let basis_y = bottom_left - top_left;
        let (u, v) = (x as f32 / size.0 as f32, y as f32 / size.1 as f32);

        let direction = top_left + u * basis_x + v * basis_y - raytracer.camera.position();

        let ray = Ray {
            origin: raytracer.camera.position(),
            direction: direction.normalize(),
        };
        let result = raytracer.trace(ray, 1);

        *pixel = result.color.into_pixel();
    }

    let mut output = io::stdout();
    image::ImageRgb8(buffer).save(&mut output, image::PNG);
}
<commit_msg>Remove redundant call to `Vector::normalize()`<commit_after>extern crate cgmath;
extern crate image;

use std::io;

use cgmath::prelude::*;
use cgmath::vec3;

use camera::Camera;
use math::*;
use primitive::Sphere;
use ray::Ray;
use raytracer::Raytracer;
use scene::Scene;

mod camera;
mod color;
mod intersection;
mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;

fn main() {
    let mut scene = Scene::new();
    scene.add_primitive(Sphere::new(vec3(0.0, 0.0, 2.0), 1.0));
    let raytracer = Raytracer {
        scene: scene,
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0),
    };

    let size = (512, 512);
    let mut buffer = image::ImageBuffer::new(size.0, size.1);
    for (x, y, pixel) in buffer.enumerate_pixels_mut() {
        let (top_left, top_right, bottom_left) = raytracer.camera.screen_corners();

        let basis_x = top_right - top_left;
        let basis_y = bottom_left - top_left;
        let (u, v) = (x as f32 / size.0 as f32, y as f32 / size.1 as f32);

        let ray = Ray {
            origin: raytracer.camera.position(),
            direction: top_left + u * basis_x + v * basis_y - raytracer.camera.position(),
        };
        let result = raytracer.trace(ray, 1);

        *pixel = result.color.into_pixel();
    }

    let mut output = io::stdout();
    image::ImageRgb8(buffer).save(&mut output, image::PNG);
}
<|endoftext|>


<commit_before>extern crate thoughtfuck;

use thoughtfuck::*;

use std::io::{Write, Read};
use std::env;
use std::path::Path;
use std::fs::File;

use vm::VM;
use program::Program;
use parse::parse;

fn main() {
    let vm = VM::new(None);
    let program = Program::new();
    match env::args().nth(1) {
        None => repl(vm, program),
        Some(arg) => interpreter(arg, vm, program),
    }
}

fn repl (mut vm: VM, mut program: Program) -> () {
    loop {
        print!("{}", if program.is_seeking {"... "} else {"tf> "});
        std::io::stdout().flush().unwrap();

        let mut line = String::new();
        let commands = match std::io::stdin().read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => parse(&line),
            Err(error) => panic!(error),
        };
        program.append(&commands);
        program.execute(&mut vm);
    }
}

fn interpreter(arg: String, mut vm: VM, mut program: Program) -> () {
    let path = Path::new(&arg);
    let mut contents = String::new();
    File::open(&path)
        .unwrap()
        .read_to_string(&mut contents)
        .unwrap();

    program.append(&parse(&contents));
    program.execute(&mut vm);
}
<commit_msg>Pass in stdout reference to VM in main<commit_after>extern crate thoughtfuck;

use thoughtfuck::*;

use std::io::{Write, Read};
use std::env;
use std::path::Path;
use std::fs::File;

use vm::VM;
use program::Program;
use parse::parse;

fn main() {
    let mut stdout = std::io::stdout();
    let vm = VM::new(&mut stdout);
    let program = Program::new();
    match env::args().nth(1) {
        None => repl(vm, program),
        Some(arg) => interpreter(arg, vm, program),
    }
}

fn repl (mut vm: VM, mut program: Program) -> () {
    loop {
        print!("{}", if program.is_seeking {"... "} else {"tf> "});
        std::io::stdout().flush().unwrap();

        let mut line = String::new();
        let commands = match std::io::stdin().read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => parse(&line),
            Err(error) => panic!(error),
        };
        program.append(&commands);
        program.execute(&mut vm);
    }
}

fn interpreter(arg: String, mut vm: VM, mut program: Program) -> () {
    let path = Path::new(&arg);
    let mut contents = String::new();
    File::open(&path)
        .unwrap()
        .read_to_string(&mut contents)
        .unwrap();

    program.append(&parse(&contents));
    program.execute(&mut vm);
}
<|endoftext|>


<commit_before>#![allow(unstable)]

extern crate image;

use display::Display;

mod display;
mod braille;

enum Args {
    NoSize(image::GreyImage),
    WithSize(image::GreyImage, (u32, u32)),
}

fn main() {
    let usage = "braillify image [size]\n\
                 \timage: Any image (example: image.png)\n\
                 \tsize: The desired output size. (example: 50x25)\n\
                 \t\tIf a size isn't given, it'll be guessed automatically.";
    match parse_args(std::os::args()) {
        Ok(args) => {
            let display = match args {
                Args::NoSize(img) => {
                    let (width, height) = img.dimensions();
                    Display::new(img, width/10, height/20)
                },
                Args::WithSize(img, (width, height)) => {
                    Display::new(img, width, height)
                },
            };
            println!("{}", display.render());
        },
        Err(err) => println!("{}\n\nUsage: {}", err, usage)
    };

}

fn parse_args(args: Vec<String>) -> Result<Args, &'static str> {
    assert!(args.len() > 1, "Too few arguments!");

    let img = match image::open(&Path::new(&args[1])) {
        Ok(image) => image.to_luma(),
        Err(_) => return Err("Couldn't open image!")
    };

    match args.len() {
        2 => Ok(Args::NoSize(img)),
        3 => Ok(Args::WithSize(img, match parse_size(args[2].as_slice()) {
            Some(x) => x,
            None => return Err("Couldn't parse size!")
        })),
        _ => Err("Bad arguments!")
    }
}

/// Parses something that looks like a size (50x50, etc)
///
/// Returns None if it can't be parsed
fn parse_size(size: &str) -> Option<(u32, u32)> {
    let splitted = size.splitn(1, 'x') // Only want at most two slices
        .filter_map(|s| s.parse::<u32>())
        .collect::<Vec<_>>();

    match splitted.len() {
        2 => Some((splitted[0], splitted[1])),
        _ => None
    }
}
<commit_msg>Get rid of a panic<commit_after>#![allow(unstable)]

extern crate image;

use display::Display;

mod display;
mod braille;

enum Args {
    NoSize(image::GreyImage),
    WithSize(image::GreyImage, (u32, u32)),
}

fn main() {
    let usage = "braillify image [size]\n\
                 \timage: Any image (example: image.png)\n\
                 \tsize: The desired output size. (example: 50x25)\n\
                 \t\tIf a size isn't given, it'll be guessed automatically.";
    match parse_args(std::os::args()) {
        Ok(args) => {
            let display = match args {
                Args::NoSize(img) => {
                    let (width, height) = img.dimensions();
                    Display::new(img, width/10, height/20)
                },
                Args::WithSize(img, (width, height)) => {
                    Display::new(img, width, height)
                },
            };
            println!("{}", display.render());
        },
        Err(err) => println!("{}\n\nUsage: {}", err, usage)
    };

}

fn parse_args(args: Vec<String>) -> Result<Args, &'static str> {
    if args.len() < 2 {
        return Err("Too few arguments!");
    }

    let img = match image::open(&Path::new(&args[1])) {
        Ok(image) => image.to_luma(),
        Err(_) => return Err("Couldn't open image!")
    };

    match args.len() {
        2 => Ok(Args::NoSize(img)),
        3 => Ok(Args::WithSize(img, match parse_size(args[2].as_slice()) {
            Some(x) => x,
            None => return Err("Couldn't parse size!")
        })),
        _ => Err("Bad arguments!")
    }
}

/// Parses something that looks like a size (50x50, etc)
///
/// Returns None if it can't be parsed
fn parse_size(size: &str) -> Option<(u32, u32)> {
    let splitted = size.splitn(1, 'x') // Only want at most two slices
        .filter_map(|s| s.parse::<u32>())
        .collect::<Vec<_>>();

    match splitted.len() {
        2 => Some((splitted[0], splitted[1])),
        _ => None
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Init commit test");
}
<commit_msg>Trying to read a file line by line...<commit_after>#![feature(old_path)]
#![feature(io)]

use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;

fn main() {

    // get the arguments
    let arguments: Vec<String> = env::args().collect();

    // csv file path
    let path_string: String = arguments[1].clone();
    let csv_path: Path = Path::new(path_string);

    // let's open an csv file
    let mut csv_file = match File::open(&csv_path) {
        Err(why)     => panic!("error openning csv file: {}", why.description()),
        Ok(csv_file) => csv_file,
    };

    // reader
    let mut csv_reader = BufReader::new(csv_file);
    let mut line_buffer: String = String::new();

    loop {
        match csv_reader.read_line(&mut line_buffer) {
            Err(why) => panic!("error reading from file: {}", why.description()),
            Ok(lines_read) =>   {
                                  println!("file has been read, lines read = {:?}", lines_read);
                                }
        };
        println!("{}", line_buffer);
    };
}
<|endoftext|>


<commit_before>mod domain;

use std::fs::File;
use std::io::prelude::*;

use chrono::prelude::*;
use dotenv::dotenv;
use serde_derive::{Deserialize, Serialize};

use self::domain::{
    Entry, EntryId, EntryKind, Project, ProjectHeadwayEntry, ProjectId, ProjectStatus,
};

#[derive(Serialize, Deserialize)]
pub struct Log {
    pub projects: Vec<Project>,
    pub entries: Vec<Entry>,
}

fn main() {
    dotenv().ok();

    let scribe_id = ProjectId::new();
    let hitheryon_id = ProjectId::new();

    let log = Log {
        projects: vec![
            Project {
                id: scribe_id,
                name: "scribe".into(),
                status: ProjectStatus::InProgress,
                started_at: Utc.ymd(2018, 12, 16).and_hms(12, 0, 0),
            },
            Project {
                id: hitheryon_id,
                name: "Hitheryon".into(),
                status: ProjectStatus::InProgress,
                started_at: Utc.ymd(2018, 8, 25).and_hms(15, 34, 27),
            },
        ],
        entries: vec![
            Entry {
                id: EntryId::new(),
                kind: EntryKind::ProjectHeadway(ProjectHeadwayEntry {
                    project_id: scribe_id,
                    hours_spent: 4.0,
                }),
                timestamp: Utc.ymd(2018, 12, 16).and_hms(12, 0, 0),
            },
            Entry {
                id: EntryId::new(),
                kind: EntryKind::ProjectHeadway(ProjectHeadwayEntry {
                    project_id: hitheryon_id,
                    hours_spent: 10.0,
                }),
                timestamp: Utc.ymd(2018, 8, 27).and_hms(3, 41, 29),
            },
            Entry {
                id: EntryId::new(),
                kind: EntryKind::ProjectHeadway(ProjectHeadwayEntry {
                    project_id: hitheryon_id,
                    hours_spent: 1.5,
                }),
                timestamp: Utc.ymd(2018, 8, 25).and_hms(16, 56, 41),
            },
        ],
    };

    let mut file = File::create("stats.yaml").unwrap();
    file.write_all(&serde_yaml::to_string(&log).unwrap().into_bytes())
        .unwrap();
}
<commit_msg>Add basic CLI<commit_after>mod domain;

use std::fs::File;
use std::io::prelude::*;

use chrono::prelude::*;
use clap::{App, Arg};
use dotenv::dotenv;
use serde_derive::{Deserialize, Serialize};

use self::domain::{
    Entry, EntryId, EntryKind, Project, ProjectHeadwayEntry, ProjectId, ProjectStatus,
};

#[derive(Serialize, Deserialize)]
pub struct Log {
    pub projects: Vec<Project>,
    pub entries: Vec<Entry>,
}

fn main() {
    dotenv().ok();

    let matches = App::new("scribe")
        .version("0.1.0")
        .author("Marshall Bowers <elliott.codes@gmail.com>")
        .arg(
            Arg::with_name("config")
                .short("c")
                .long("config")
                .value_name("FILE")
                .takes_value(true),
        )
        .get_matches();

    let config = matches.value_of("config").unwrap_or(".scribe");

    println!("{}", config);
}
<|endoftext|>


<commit_before>extern crate kafka;
use kafka::client::KafkaClient;
use kafka::protocol::*;
use kafka::codecs::*;

fn main() {

    let mut client = KafkaClient::new(&vec!("localhost:9092".to_string()));
    client.load_metadata_all();
    println!("{:?}", client.fetch_topic_offset(&"my-topic".to_string()));
    /*let p = ProduceRequest::new_single(&"my-topic".to_string(), 0, 1,
                      100, &"b".to_string().into_bytes(),
                      1, &"rust".to_string());
    println!("{:?}", p);
    let mut buf = vec!();
    p.encode(&mut buf);
    println!("{:?}", buf);
    client.send_message(&"my-topic".to_string(), 0, 1,
                      100, &"b".to_string().into_bytes());*/

    for om in client.fetch_messages(&"my-topic".to_string(), 0, 0) {
        println!("{:?}", om);
    };

}
<commit_msg>Remove build warning from main.rs<commit_after>extern crate kafka;
use kafka::client::KafkaClient;

fn main() {

    let mut client = KafkaClient::new(&vec!("localhost:9092".to_string()));
    client.load_metadata_all();
    println!("{:?}", client.fetch_topic_offset(&"my-topic".to_string()));
    /*let p = ProduceRequest::new_single(&"my-topic".to_string(), 0, 1,
                      100, &"b".to_string().into_bytes(),
                      1, &"rust".to_string());
    println!("{:?}", p);
    let mut buf = vec!();
    p.encode(&mut buf);
    println!("{:?}", buf);
    client.send_message(&"my-topic".to_string(), 0, 1,
                      100, &"b".to_string().into_bytes());*/

    for om in client.fetch_messages(&"my-topic".to_string(), 0, 0) {
        println!("{:?}", om);
    };

}
<|endoftext|>


<commit_before>extern crate discord;

use discord::{Discord, ChannelRef, State};
use discord::model::Event;

fn rot13(c: char) -> char {
    let base: u8 = match c {
        'a'...'z' => 'a' as u8,
        'A'...'Z' => 'A' as u8,
        _ => return c
    };

    let ordinal = c as u8 - base;
    let rot = (ordinal + 13) % 26;
    (rot + base) as char
}

fn main() {
    use std::env;
    println!("The Rotting 13!");

    let discord = Discord::from_bot_token(
        &env::var("DISCORD_TOKEN").expect("Expected token")
    ).expect("login failed!");

    let (mut connection, ready) = discord.connect().expect("connect failed");
    let mut state = State::new(ready);

    println!("Connected!");

    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(discord::Error::Closed(code, body)) => {
                println!("[Error] Connection closed with status {:?}: {}", code, body);
                break
            },
            Err(err) => {
                println!("[Warning] Receive error: {:?}", err);
                continue
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                if message.author.id != state.user().id {
                    continue
                }

                match state.find_channel(&message.channel_id) {
                    Some(ChannelRef::Private(channel)) => {
                        let original_message = message.content;
                        let mut new_message = String::new();
                        for chr in original_message.chars() {
                            new_message.push(rot13(chr));
                        }

                        let _ = discord.send_message(&message.channel_id, &new_message, "", false);
                    },
                    Some(ChannelRef::Public(server, channel)) => {

                    },
                    None => println!("Got a message from an unknown channel??? From {} saying {}", message.author.name, message.content),
                    _ => {},
                }
            },
            _ => {}
        }
    }
}<commit_msg>Added code for automatic reconnection<commit_after>extern crate discord;
extern crate websocket;

use discord::{Discord, ChannelRef, State};
use discord::model::Event;
use websocket::result::WebSocketError;

fn rot13(c: char) -> char {
    let base: u8 = match c {
        'a'...'z' => 'a' as u8,
        'A'...'Z' => 'A' as u8,
        _ => return c
    };

    let ordinal = c as u8 - base;
    let rot = (ordinal + 13) % 26;
    (rot + base) as char
}

fn main() {
    use std::env;
    println!("The Rotting 13!");

    let discord = Discord::from_bot_token(
        &env::var("DISCORD_TOKEN").expect("Expected token")
    ).expect("login failed!");

    let (mut connection, ready) = discord.connect().expect("Connection failed");
    let mut state = State::new(ready);

    println!("Connected!");

    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                if let discord::Error::WebSocket(ws_err) = err {
                    match ws_err {
                        WebSocketError::IoError(io) => {},
                        _ => {
                            // We were disconnected, try to reconnect
                            println!("Reconnecting...");
                            let (new_connection, ready) = discord.connect().expect("Reconnect failed");
                            connection = new_connection;
                            state = State::new(ready);
                            println!("Reconnected!");
                        },
                    }
                    continue
                }

                if let discord::Error::Closed(code, body) = err {
                    println!("[Error] Connection closed with status {:?}: {}", code, body);
                    break
                }

                println!("[Warning] Receive error: {:?}", err);
                continue
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                if message.author.id != state.user().id {
                    continue
                }

                match state.find_channel(&message.channel_id) {
                    Some(ChannelRef::Private(channel)) => {
                        let original_message = message.content;
                        let mut new_message = String::new();
                        for chr in original_message.chars() {
                            new_message.push(rot13(chr));
                        }

                        let _ = discord.send_message(&channel.id, &new_message, "", false);
                    },
                    Some(ChannelRef::Public(server, channel)) => {

                    },
                    None => println!("Got a message from an unknown channel??? From {} saying {}", message.author.name, message.content),
                    _ => {},
                }
            },
            _ => {}
        }
    }
}<|endoftext|>


<commit_before>
#[derive(Copy, Clone)]
enum InstructionSet {
	PSH,
	ADD,
	POP,
	SET,
	HLT,
	VAL(i32),
}

struct VM {
	ip: usize,
	program: Vec<InstructionSet>,
}

impl VM {
	pub fn new(prog: Vec<InstructionSet>) -> VM {
		VM {
			ip : 0,
			program: prog,
		}
	}

	fn fetch(&mut self) -> InstructionSet {
		let instr = self.program[self.ip];
		instr
	}
}

fn main() {
	let program = vec![
		InstructionSet::PSH, InstructionSet::VAL(5),
		InstructionSet::PSH, InstructionSet::VAL(6),
		InstructionSet::ADD,
		InstructionSet::POP,
		InstructionSet::HLT,
	];

	let mut vm = VM::new(program);
	let x = vm.fetch(); // PSH
	vm.ip += 1;
	let y = vm.fetch(); // VAL(5)
}
<commit_msg>automate instruction pointer increment<commit_after>
#[derive(Copy, Clone)]
enum InstructionSet {
	PSH,
	ADD,
	POP,
	SET,
	HLT,
	VAL(i32),
}

struct VM {
	ip: usize,
	program: Vec<InstructionSet>,
}

impl VM {
	pub fn new(prog: Vec<InstructionSet>) -> VM {
		VM {
			ip : 0,
			program: prog,
		}
	}

	fn fetch(&mut self) -> InstructionSet {
		let instr = self.program[self.ip];
		instr
	}
}

fn main() {
	let program = vec![
		InstructionSet::PSH, InstructionSet::VAL(5),
		InstructionSet::PSH, InstructionSet::VAL(6),
		InstructionSet::ADD,
		InstructionSet::POP,
		InstructionSet::HLT,
	];

	let mut vm = VM::new(program);
	loop {
		let x = vm.fetch();
		match x {
			InstructionSet::HLT => break,
			_ => {},
		}
		vm.ip += 1;
	}
}
<|endoftext|>


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

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
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

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() {
    // 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;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let mut extra_envs = vec![];
    if let Ok(_) = std::env::var("CLIPPY_DOGFOOD") {
        let target_dir = std::env::var("CARGO_MANIFEST_DIR")
            .map(|m| {
                std::path::PathBuf::from(m)
                    .join("target")
                    .join("dogfood")
                    .to_string_lossy()
                    .into_owned()
            })
            .unwrap_or("clippy_dogfood".to_string());

        extra_envs.push(("CARGO_TARGET_DIR", target_dir));
    };

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(extra_envs)
        .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 clippy warnings from last commit<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

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
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

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() {
    // 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;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let mut extra_envs = vec![];
    if std::env::var("CLIPPY_DOGFOOD").is_ok() {
        let target_dir = std::env::var("CARGO_MANIFEST_DIR")
            .map(|m| {
                std::path::PathBuf::from(m)
                    .join("target")
                    .join("dogfood")
                    .to_string_lossy()
                    .into_owned()
            })
            .unwrap_or_else(|_| "clippy_dogfood".to_string());

        extra_envs.push(("CARGO_TARGET_DIR", target_dir));
    };

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(extra_envs)
        .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>use std::num::Int;
use std::os;
use std::io::File;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::iter::range_step;

fn search(needle: String, haystack: Vec<char>) -> Vec<(usize, i64)> {
    let needle: Vec<char> = needle.chars().collect();
    let len_needle = needle.len() as i64;
    let mut results : Vec<(usize, i64)> = Vec::new();

    let mut indexed_haystack = HashMap::new();
    for (idx, c) in haystack.iter().enumerate() {
        match indexed_haystack.entry(c) {
            Vacant(entry) => { entry.insert(vec![idx]); },
            Occupied(mut entry) => { (*entry.get_mut()).push(idx); }
        }
    }

    let possible_starts: &Vec<usize>;
    match indexed_haystack.get(&needle[0]) {
        Some(ref entries) => {
            possible_starts = *entries;
        },
        None => {
            return results;
        }
    }

    let second_pos: &Vec<usize>;
    match indexed_haystack.get(&needle[1]) {
        None => { return results; }
        Some(ref entries) => {
            second_pos = *entries;
        }
    }
    let mut possible_steps: Vec<(usize, usize)> = Vec::new();
    for first_pos in possible_starts.iter() {
        for second_pos in second_pos.iter() {
            let start = *first_pos;
            let step: i64 = (*second_pos as i64) - (*first_pos as i64);
            let positions: Vec<i64> = range_step(start as i64, step*len_needle, step).collect();
            println!("Start {} step {}", start, step);
            if positions.iter().any(|&x| { x<0 }) {
                // TODO there's probably a better maths way to do this
                continue;
            }

            println!("Range {:?}", positions);
            if positions.iter().enumerate().all(|(needle_idx, haystack_idx)| { needle[needle_idx] == haystack[haystack_idx] } ) {
                println!("Found starting at {} with step of {}", start, step);
                results.push((start, step));
            }
        }
    }

    results
}

fn positions<T: Int>(start: T, step: T, len: T) -> Vec<T> {
    range(Int::zero(), len).map(|i| { start + step*i } ).collect()
}

fn main() {
    let file_to_search = &os::args()[1];
    println!("Reading in {}", file_to_search);
    let haystack: Vec<char> = File::open(&Path::new(file_to_search)).read_to_string().unwrap().chars().filter(|&x| { x.is_alphabetic() }).map(|x| { x.to_lowercase() }).collect();

    let needle = (&os::args()[2]).to_string();
    println!("Looking for {}", needle);
    for &(start, step) in search(needle, haystack).iter() {
        println!("Found starting at {} with step of {}", start, step);
    }
}
<commit_msg>initial<commit_after>#[macro_use] extern crate log;

use std::num::{Int, FromPrimitive};
use std::os;
use std::io::File;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::iter::range_step;

struct EDS {
    needle: Vec<char>,
    haystack: Vec<char>,
    indexed_haystack: HashMap<char, Vec<usize>>,
    first_pos: Vec<usize>,
    second_pos: Vec<usize>,
}

impl Iterator for EDS {
    type Item = (usize, i64);

    fn next(&mut self) -> Option<(usize, i64)> {
        None
    }
}

impl EDS {
    fn find_first_second_pos(&mut self) {
        self.indexed_haystack = HashMap::new();
        for (idx, &c) in self.haystack.iter().enumerate() {
            match self.indexed_haystack.entry(c) {
                Vacant(entry) => { entry.insert(vec![idx]); },
                Occupied(mut entry) => { (*entry.get_mut()).push(idx); }
            }
        }

        match self.indexed_haystack.get(&self.needle[0]) {
            Some(ref entries) => {
                self.first_pos = (**entries).clone();
            },
            None => {
                self.first_pos = vec![];
                return
            }
        }

        match self.indexed_haystack.get(&self.needle[1]) {
            None => { self.second_pos = vec![]; }
            Some(ref entries) => {
                self.second_pos = (**entries).clone();
            }
        }

    }
}

fn search(needle: String, haystack: Vec<char>) -> Vec<(usize, i64)> {
    let needle: Vec<char> = needle.chars().collect();
    let len_needle = needle.len() as i64;
    let len_haystack: usize = haystack.len();
    let mut results : Vec<(usize, i64)> = Vec::new();

    let mut indexed_haystack = HashMap::new();
    for (idx, c) in haystack.iter().enumerate() {
        match indexed_haystack.entry(c) {
            Vacant(entry) => { entry.insert(vec![idx]); },
            Occupied(mut entry) => { (*entry.get_mut()).push(idx); }
        }
    }

    let possible_starts: &Vec<usize>;
    match indexed_haystack.get(&needle[0]) {
        Some(ref entries) => {
            possible_starts = *entries;
        },
        None => {
            return results;
        }
    }

    let second_pos: &Vec<usize>;
    match indexed_haystack.get(&needle[1]) {
        None => { return results; }
        Some(ref entries) => {
            second_pos = *entries;
        }
    }
    for first_pos in possible_starts.iter() {
        for second_pos in second_pos.iter() {
            debug!("first_pos {} second_pos {}", first_pos, second_pos);
            let start = *first_pos;
            let step: i64 = (*second_pos as i64) - (*first_pos as i64);
            if step == 1 {
                continue;
            }
            let positions: Vec<i64> = range_step(start as i64, step*len_needle, step).collect();
            debug!("Start {} step {}", start, step);
            if positions.iter().any(|&x| { x<0 }) {
                // TODO there's probably a better maths way to do this
                break;
            }
            let positions: Vec<usize> = positions.iter().map(|&x| { FromPrimitive::from_i64(x).unwrap() }).collect();
            debug!("positions {:?}", positions);
            if positions.len() == 0 {
                // WTF
                continue;
            }

            if positions[positions.len()-1] > len_haystack - 1 {
                break;
            }
            if positions.iter().map(|&c| { &haystack[c] }).zip(needle.iter()).all(|(&a, &b)| { a == b }) {
                println!("Found starting at {} with step of {}", start, step);
                results.push((start, step));
            }
        }
    }

    results
}

fn positions<T: Int>(start: T, step: T, len: T) -> Vec<T> {
    range(Int::zero(), len).map(|i| { start + step*i } ).collect()
}

fn only_alphanumeric(input: Vec<char>) -> Vec<char> {
    input.iter().filter(|&c| { c.is_alphabetic() }).map(|&c| { c.to_lowercase() }).collect()
}

//fn only_constants(input: Vec<char>) -> Vec<char> {
    //input.filter(|&c| { c.is_alphabetic() && ! ( c }).collect()
//}

fn main() {
    let file_to_search = &os::args()[1];
    println!("Reading in {}", file_to_search);
    let haystack: Vec<char> = File::open(&Path::new(file_to_search)).read_to_string().unwrap().chars().filter(|&x| { x.is_alphabetic() }).map(|x| { x.to_lowercase() }).collect();

    let needle = (&os::args()[2]).to_string();
    println!("Looking for {}", needle);
    for &(start, step) in search(needle, haystack).iter() {
        println!("Found starting at {} with step of {}", start, step);
    }
}
<|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]

#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]

#[macro_use] extern crate lazy_static;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{ Path, PathBuf };

lazy_static! {
    static ref HOME: PathBuf = std::env::home_dir().unwrap();

    static ref build_props: PathBuf = PathBuf::from("project/build.properties");

    static ref sbt_launch_dir: PathBuf = { let mut p = PathBuf::from(&*HOME); p.push(".sbt/launchers"); p };

    static ref script_name: String = {
        let n = std::env::args().nth(0).unwrap();
        let n = Path::new(&n).file_name().unwrap().to_str().unwrap();
        n.to_string()
    };

}

const sbt_launch_ivy_release_repo: &'static str = "http://repo.typesafe.com/typesafe/ivy-releases";
const sbt_launch_mvn_release_repo: &'static str = "http://repo.scala-sbt.org/scalasbt/maven-releases";

macro_rules! echoerr(($($arg:tt)*) => (writeln!(&mut ::std::io::stderr(), $($arg)*).unwrap();));

fn die(s: &str) { println!("Aborting: {}", s); std::process::exit(1) }

fn build_props_sbt() -> String {
    if let Ok(f) = File::open(&*build_props) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line.unwrap();
            if line.starts_with("sbt.version") {
                let line = line.replace("=", " ");
                let line = line.replace("\r", " ");
                return line.split_whitespace().nth(1).unwrap().to_owned();
            }
        }
    }
    "".to_owned()
}

fn jar_file(version: &str) -> PathBuf {
    let mut p = PathBuf::from(&*sbt_launch_dir);
    p.push(version);
    p.push("sbt-launch.jar");
    p
}

fn url_base(version: &str) -> &'static str { match version {
    s if s.starts_with("0.7.")  => "http://simple-build-tool.googlecode.com",
    s if s.starts_with("0.10.") => sbt_launch_ivy_release_repo,
    "0.11.1" | "0.11.2"         => sbt_launch_ivy_release_repo,
 // "0.*-yyyymmdd-hhMMss"       => sbt_launch_ivy_snapshot_repo, // https://repo.scala-sbt.org/scalasbt/ivy-snapshots
    s if s.starts_with("0.")    => sbt_launch_ivy_release_repo,
 // "*-yyyymmdd-hhMMss"         => sbt_launch_mvn_snapshot_repo, // http://repo.scala-sbt.org/scalasbt/maven-snapshots
    _                           => sbt_launch_mvn_release_repo,
} }

fn make_url(version: &str) -> String {
    let base = url_base(version);
    match version {
        s if s.starts_with("0.7.")  => format!("{}/files/sbt-launch-0.7.7.jar", base),
        s if s.starts_with("0.10.") => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        "0.11.1" | "0.11.2"         => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        s if s.starts_with("0.")    => format!("{}/org.scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        _                           => format!("{}/org/scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
    }
}

fn download_url(sbt_version: &str, url: &str, jar: &Path) -> bool {
    echoerr!("Downloading sbt launcher for {}:", sbt_version);
    echoerr!("  From  {}", url);
    echoerr!("    To  {}", jar.display());

    std::fs::create_dir_all(jar.parent().unwrap()).unwrap();

    extern crate hyper;
    let mut r = BufReader::new(hyper::client::Client::new().get(url).send().unwrap());
    let mut buf = [0; 16384];
    let mut jar2 = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar2.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar2.flush().unwrap();
    File::open(jar).is_ok()
}

struct App {
           sbt_jar: PathBuf,
       sbt_version: String,
           verbose: bool,
          java_cmd: String,
    extra_jvm_opts: Vec<String>,
         java_args: Vec<String>,
      sbt_commands: Vec<String>,
     residual_args: Vec<String>,
}

impl App {
    fn new() -> App {
        App {
                 sbt_jar: PathBuf::new(),
             sbt_version: Default::default(),
                 verbose: Default::default(),
                java_cmd: "java".into(),
          extra_jvm_opts: vec!["-Xms512m".into(), "-Xmx1536m".into(), "-Xss2m".into()],
               java_args: Default::default(),
            sbt_commands: Default::default(),
           residual_args: Default::default(),
        }
    }

    fn vlog(&self, s: &str) -> bool { if self.verbose { echoerr!("{}", s); true } else { false } }

    fn set_sbt_version(&mut self) {
        self.sbt_version=build_props_sbt();
        // sbt_version="${sbt_explicit_version:-$(build_props_sbt)}"
        // [[ -n "$sbt_version" ]] || sbt_version=$sbt_release_version
    }

    fn add_java(&mut self, s: &str) {
        self.vlog(&format!("[add_java] arg = {}", s));
        self.java_args.push(s.into());
    }

    fn add_residual(&mut self, s: &str) {
        self.vlog(&format!("[residual] arg = {}", s));
        self.residual_args.push(s.into());
    }

    fn add_debugger(&mut self, port: u16) {
        self.add_java("-Xdebug");
        self.add_java(&format!("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address={}", port));
    }

    fn process_args(&mut self) {
        fn require_arg(tpe: &str, opt: &str, arg: &str) {
            if arg.is_empty() || &arg[0..1] == "-" {
                die(&format!("{} requires <{}> argument", opt, tpe));
            }
        }
        let args = std::env::args();
        let mut args = args.skip(1); // skip the path of the executable
        while let Some(arg) = args.next() {
            let mut next = || -> String { args.next().unwrap_or("".into()) };
            let arg = arg.as_ref();
            match arg {
                "-v"         => self.verbose = true,
                "-jvm-debug" => { let next = next(); require_arg("port", arg, &next); self.add_debugger(next.parse().unwrap()) },
                s            => panic!("fu"), // self.add_residual(&s),
            }
        }
    }

    fn acquire_sbt_jar(&mut self) -> bool {
        ({
            self.sbt_jar = jar_file(&self.sbt_version);
            File::open(self.sbt_jar.as_path()).is_ok()
        }) || ({
            self.sbt_jar = PathBuf::from(&*HOME);
            self.sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", self.sbt_version));
            File::open(self.sbt_jar.as_path()).is_ok()
        }) || ({
            self.sbt_jar = jar_file(&self.sbt_version);
            download_url(&self.sbt_version, &make_url(&self.sbt_version), &self.sbt_jar)
        })
    }

    fn exec_runner<S: AsRef<OsStr>>(&self, args: &[S]) {
        self.vlog("# Executing command line:") && {
            for arg in args {
                let arg = arg.as_ref();
                if !arg.is_empty() {
                    let arg = arg.to_string_lossy();
                    if arg.contains(" ") {
                        echoerr!("\"{}\"", arg);
                    } else {
                        echoerr!("{}", arg);
                    }
                }
            }
            self.vlog("")
        };

        use std::os::unix::process::CommandExt;
        let err = std::process::Command::new(&args[0]).args(&args[1..]).exec();
        println!("error: {}", err);
        if let Some(err) = err.raw_os_error() {
            std::process::exit(err);
        }
        std::process::exit(-1)
    }

    fn run(&mut self) {
        let argument_count = self.residual_args.len();

        self.set_sbt_version();

        if argument_count == 0 {
            self.vlog(&format!("Starting {}: invoke with -help for other options", *script_name));
            self.residual_args = vec!["shell".into()];
        }

        // no jar? download it.
        File::open(self.sbt_jar.as_path()).is_ok() || self.acquire_sbt_jar() || {
            // still no jar? uh-oh.
            println!("Download failed. Obtain the jar manually and place it at {}", self.sbt_jar.display());
            std::process::exit(1);
        };

        let mut exec_args: Vec<&OsStr> = Vec::new();
        exec_args.push(self.java_cmd.as_ref());
        exec_args.append(&mut self.extra_jvm_opts.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.java_args.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut vec!["-jar".as_ref(), self.sbt_jar.as_ref()]);
        exec_args.append(&mut self.sbt_commands.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.residual_args.iter().map(AsRef::as_ref).collect());

        self.exec_runner(&exec_args)
    }
}

fn main() {
    let mut app = App::new();
    app.process_args();
    app.run()
}
<commit_msg>Change default process args case to add_residual<commit_after>#![allow(non_upper_case_globals)]

#![allow(dead_code)]
#![allow(unused_assignments)]
#![allow(unused_variables)]

#[macro_use] extern crate lazy_static;

use std::ffi::OsStr;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{ Path, PathBuf };

lazy_static! {
    static ref HOME: PathBuf = std::env::home_dir().unwrap();

    static ref build_props: PathBuf = PathBuf::from("project/build.properties");

    static ref sbt_launch_dir: PathBuf = { let mut p = PathBuf::from(&*HOME); p.push(".sbt/launchers"); p };

    static ref script_name: String = {
        let n = std::env::args().nth(0).unwrap();
        let n = Path::new(&n).file_name().unwrap().to_str().unwrap();
        n.to_string()
    };

}

const sbt_launch_ivy_release_repo: &'static str = "http://repo.typesafe.com/typesafe/ivy-releases";
const sbt_launch_mvn_release_repo: &'static str = "http://repo.scala-sbt.org/scalasbt/maven-releases";

macro_rules! echoerr(($($arg:tt)*) => (writeln!(&mut ::std::io::stderr(), $($arg)*).unwrap();));

fn die(s: &str) { println!("Aborting: {}", s); std::process::exit(1) }

fn build_props_sbt() -> String {
    if let Ok(f) = File::open(&*build_props) {
        let f = BufReader::new(f);
        for line in f.lines() {
            let line = line.unwrap();
            if line.starts_with("sbt.version") {
                let line = line.replace("=", " ");
                let line = line.replace("\r", " ");
                return line.split_whitespace().nth(1).unwrap().to_owned();
            }
        }
    }
    "".to_owned()
}

fn jar_file(version: &str) -> PathBuf {
    let mut p = PathBuf::from(&*sbt_launch_dir);
    p.push(version);
    p.push("sbt-launch.jar");
    p
}

fn url_base(version: &str) -> &'static str { match version {
    s if s.starts_with("0.7.")  => "http://simple-build-tool.googlecode.com",
    s if s.starts_with("0.10.") => sbt_launch_ivy_release_repo,
    "0.11.1" | "0.11.2"         => sbt_launch_ivy_release_repo,
 // "0.*-yyyymmdd-hhMMss"       => sbt_launch_ivy_snapshot_repo, // https://repo.scala-sbt.org/scalasbt/ivy-snapshots
    s if s.starts_with("0.")    => sbt_launch_ivy_release_repo,
 // "*-yyyymmdd-hhMMss"         => sbt_launch_mvn_snapshot_repo, // http://repo.scala-sbt.org/scalasbt/maven-snapshots
    _                           => sbt_launch_mvn_release_repo,
} }

fn make_url(version: &str) -> String {
    let base = url_base(version);
    match version {
        s if s.starts_with("0.7.")  => format!("{}/files/sbt-launch-0.7.7.jar", base),
        s if s.starts_with("0.10.") => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        "0.11.1" | "0.11.2"         => format!("{}/org.scala-tools.sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        s if s.starts_with("0.")    => format!("{}/org.scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
        _                           => format!("{}/org/scala-sbt/sbt-launch/{}/sbt-launch.jar", base, version),
    }
}

fn download_url(sbt_version: &str, url: &str, jar: &Path) -> bool {
    echoerr!("Downloading sbt launcher for {}:", sbt_version);
    echoerr!("  From  {}", url);
    echoerr!("    To  {}", jar.display());

    std::fs::create_dir_all(jar.parent().unwrap()).unwrap();

    extern crate hyper;
    let mut r = BufReader::new(hyper::client::Client::new().get(url).send().unwrap());
    let mut buf = [0; 16384];
    let mut jar2 = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar2.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar2.flush().unwrap();
    File::open(jar).is_ok()
}

struct App {
           sbt_jar: PathBuf,
       sbt_version: String,
           verbose: bool,
          java_cmd: String,
    extra_jvm_opts: Vec<String>,
         java_args: Vec<String>,
      sbt_commands: Vec<String>,
     residual_args: Vec<String>,
}

impl App {
    fn new() -> App {
        App {
                 sbt_jar: PathBuf::new(),
             sbt_version: Default::default(),
                 verbose: Default::default(),
                java_cmd: "java".into(),
          extra_jvm_opts: vec!["-Xms512m".into(), "-Xmx1536m".into(), "-Xss2m".into()],
               java_args: Default::default(),
            sbt_commands: Default::default(),
           residual_args: Default::default(),
        }
    }

    fn vlog(&self, s: &str) -> bool { if self.verbose { echoerr!("{}", s); true } else { false } }

    fn set_sbt_version(&mut self) {
        self.sbt_version=build_props_sbt();
        // sbt_version="${sbt_explicit_version:-$(build_props_sbt)}"
        // [[ -n "$sbt_version" ]] || sbt_version=$sbt_release_version
    }

    fn add_java(&mut self, s: &str) {
        self.vlog(&format!("[add_java] arg = {}", s));
        self.java_args.push(s.into());
    }

    fn add_residual(&mut self, s: &str) {
        self.vlog(&format!("[residual] arg = {}", s));
        self.residual_args.push(s.into());
    }

    fn add_debugger(&mut self, port: u16) {
        self.add_java("-Xdebug");
        self.add_java(&format!("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address={}", port));
    }

    fn process_args(&mut self) {
        fn require_arg(tpe: &str, opt: &str, arg: &str) {
            if arg.is_empty() || &arg[0..1] == "-" {
                die(&format!("{} requires <{}> argument", opt, tpe));
            }
        }
        let args = std::env::args();
        let mut args = args.skip(1); // skip the path of the executable
        while let Some(arg) = args.next() {
            let mut next = || -> String { args.next().unwrap_or("".into()) };
            let arg = arg.as_ref();
            match arg {
                "-v"         => self.verbose = true,
                "-jvm-debug" => { let next = next(); require_arg("port", arg, &next); self.add_debugger(next.parse().unwrap()) },
                s            => self.add_residual(s),
            }
        }
    }

    fn acquire_sbt_jar(&mut self) -> bool {
        ({
            self.sbt_jar = jar_file(&self.sbt_version);
            File::open(self.sbt_jar.as_path()).is_ok()
        }) || ({
            self.sbt_jar = PathBuf::from(&*HOME);
            self.sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", self.sbt_version));
            File::open(self.sbt_jar.as_path()).is_ok()
        }) || ({
            self.sbt_jar = jar_file(&self.sbt_version);
            download_url(&self.sbt_version, &make_url(&self.sbt_version), &self.sbt_jar)
        })
    }

    fn exec_runner<S: AsRef<OsStr>>(&self, args: &[S]) {
        self.vlog("# Executing command line:") && {
            for arg in args {
                let arg = arg.as_ref();
                if !arg.is_empty() {
                    let arg = arg.to_string_lossy();
                    if arg.contains(" ") {
                        echoerr!("\"{}\"", arg);
                    } else {
                        echoerr!("{}", arg);
                    }
                }
            }
            self.vlog("")
        };

        use std::os::unix::process::CommandExt;
        let err = std::process::Command::new(&args[0]).args(&args[1..]).exec();
        println!("error: {}", err);
        if let Some(err) = err.raw_os_error() {
            std::process::exit(err);
        }
        std::process::exit(-1)
    }

    fn run(&mut self) {
        let argument_count = self.residual_args.len();

        self.set_sbt_version();

        if argument_count == 0 {
            self.vlog(&format!("Starting {}: invoke with -help for other options", *script_name));
            self.residual_args = vec!["shell".into()];
        }

        // no jar? download it.
        File::open(self.sbt_jar.as_path()).is_ok() || self.acquire_sbt_jar() || {
            // still no jar? uh-oh.
            println!("Download failed. Obtain the jar manually and place it at {}", self.sbt_jar.display());
            std::process::exit(1);
        };

        let mut exec_args: Vec<&OsStr> = Vec::new();
        exec_args.push(self.java_cmd.as_ref());
        exec_args.append(&mut self.extra_jvm_opts.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.java_args.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut vec!["-jar".as_ref(), self.sbt_jar.as_ref()]);
        exec_args.append(&mut self.sbt_commands.iter().map(AsRef::as_ref).collect());
        exec_args.append(&mut self.residual_args.iter().map(AsRef::as_ref).collect());

        self.exec_runner(&exec_args)
    }
}

fn main() {
    let mut app = App::new();
    app.process_args();
    app.run()
}
<|endoftext|>


<commit_before>#![feature(globs, macro_rules, phase)]

extern crate debug;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate image;
extern crate libc;
extern crate cgmath;
extern crate time;

extern crate flate;
extern crate native;
extern crate rustrt;
extern crate serialize;

use sdl2_game_window::GameWindowSDL2 as Window;
use piston::input;
use piston::cam;
use piston::vecmath::{vec3_add, vec3_scale, vec3_normalized};
use piston::{
    AssetStore,
    GameIterator,
    GameIteratorSettings,
    GameWindow,
    GameWindowSettings,
    Input,
    Render,
    Update
};

use array::*;

use std::f32::consts::PI;
use std::io::fs::File;

pub mod array;
pub mod chunk;
pub mod cube;
pub mod fps_counter;
pub mod shader;
pub mod texture;

pub mod minecraft {
    pub use self::data_1_8_pre2 as data;

    mod data_1_8_pre2;
    pub mod biome;
    pub mod block_state;
    pub mod model;
    pub mod nbt;
    pub mod region;
}

fn main() {
    let world = Path::new(std::os::args().as_slice().get(1).expect("Usage: ./hematite <path/to/world>").as_slice());

    let level = minecraft::nbt::Nbt::from_gzip(File::open(&world.join("level.dat")).read_to_end().unwrap().as_slice()).unwrap();
    println!("{}", level);
    let player_pos: [f32, ..3] = Array::from_iter(level["Data"]["Player"]["Pos"].as_double_list().unwrap().iter().map(|&x| x as f32));
    let player_rot = level["Data"]["Player"]["Rotation"].as_float_list().unwrap();
    let player_yaw = player_rot[0];
    let player_pitch = player_rot[1];

    let region = minecraft::region::Region::open(&world.join("region/r.0.0.mca"));

    let mut window = Window::new(
        piston::shader_version::opengl::OpenGL_3_3,
        GameWindowSettings {
            title: format!("Hematite - {}", world.display()),
            size: [854, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    );
    let (mut device, frame) = window.gfx();

    let assets = &AssetStore::from_folder("../assets");

    // Load biomes.
    let biomes = minecraft::biome::Biomes::load(assets);

    // Load block state definitions and models.
    let block_states = minecraft::block_state::BlockStates::load(assets, &mut device);

    let mut renderer = shader::Renderer::new(device, frame, block_states.texture().tex);

    let mut chunk_manager = chunk::ChunkManager::new();

    println!("Started loading chunks...");
    for cz in range(0, 16) {
        for cx in range(0, 16) {
            match region.get_chunk_column(cx, cz) {
                Some(column) => {
                    chunk_manager.add_chunk_column(cx as i32, cz as i32, column)
                }
                None => {}
            }
        }
    }
    println!("Finished loading chunks.");

    renderer.set_projection(cam::CameraPerspective {
        fov: 70.0,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: {
            let (w, h) = window.get_size();
            (w as f32) / (h as f32)
        }
    }.projection());

    let mut first_person_settings = cam::FirstPersonSettings::default();
    first_person_settings.speed_horizontal = 8.0;
    first_person_settings.speed_vertical = 4.0;
    let mut first_person = cam::FirstPerson::new(
        player_pos,
        first_person_settings
    );
    first_person.yaw = PI - player_yaw / 180.0 * PI;
    first_person.pitch = player_pitch / 180.0 * PI;

    let game_iter_settings = GameIteratorSettings {
        updates_per_second: 120,
        max_frames_per_second: 10000
    };

    // Disable V-Sync.
    sdl2::video::gl_set_swap_interval(0);

    let mut fps_counter = fps_counter::FPSCounter::new();

    let mut pending_chunks = vec![];
    chunk_manager.each_chunk_and_neighbors(|coords, buffer, chunks, column_biomes| {
        pending_chunks.push((coords, buffer, chunks, column_biomes));
    });

    let mut capture_cursor = false;
    println!("Press C to capture mouse");

    let mut staging_buffer = vec![];
    let mut last_render = time::precise_time_ns();
    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_) => {
                // Update camera.
                let now = time::precise_time_ns();
                let dt = (now - last_render) as f64 / 1_000_000_000.0f64;
                first_person.update(dt);
                last_render = now;

                // Apply the same y/z camera offset vanilla minecraft has.
                let mut camera = first_person.camera(0.0);
                camera.position[1] += 1.62;
                let mut xz_forward = camera.forward;
                xz_forward[1] = 0.0;
                xz_forward = vec3_normalized(xz_forward);
                camera.position = vec3_add(camera.position, vec3_scale(xz_forward, 0.1));

                renderer.set_view(camera.orthogonal());
                renderer.reset();
                chunk_manager.each_chunk(|_, _, _, _, buffer| {
                    match buffer {
                        Some(buffer) => renderer.render(buffer),
                        None => {}
                    }
                });
                renderer.end_frame();

                let fps = fps_counter.update();
                let title = format!("Hematite @ {}FPS - {}", fps, world.display());
                events.game_window.window.set_title(title.as_slice());
            }
            Update(_) => {
                // HACK(eddyb) find the closest chunk to the player.
                // The pending vector should be sorted instead.
                let closest = pending_chunks.iter().enumerate().min_by(|&(_, &([cx, cy, cz], _, _, _))| {
                    let [px, py, pz] = first_person.position.map(|x| (x / 16.0).floor() as i32);
                    let [x2, y2, z2] = [cx - px, cy - py, cz - pz].map(|x| x * x);
                    x2 + y2 + z2
                }).map(|(i, _)| i);

                let pending = closest.and_then(|i| pending_chunks.swap_remove(i));
                match pending {
                    Some((coords, buffer, chunks, column_biomes)) => {
                        match buffer.get() {
                            Some(buffer) => renderer.delete_buffer(buffer),
                            None => {}
                        }
                        minecraft::block_state::fill_buffer(&block_states, &biomes,
                                                            &mut staging_buffer,
                                                            coords, chunks,
                                                            column_biomes);
                        buffer.set(Some(renderer.create_buffer(staging_buffer.as_slice())));
                        staging_buffer.clear();

                        if pending_chunks.is_empty() {
                            println!("Finished filling chunk vertex buffers.");
                        }
                    }
                    None => {}
                }
            }
            Input(input::KeyPress { key: input::keyboard::C }) => {
                println!("Turned cursor capture {}",
                    if capture_cursor { "off" } else { "on" });
                capture_cursor = !capture_cursor;

                events.game_window.capture_cursor(capture_cursor);
            }
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => first_person.input(args),
            _ => {}
        }
    }
}
<commit_msg>Try to load a 16x16 chunk column area around the player.<commit_after>#![feature(globs, macro_rules, phase)]

extern crate debug;
extern crate piston;
extern crate sdl2;
extern crate sdl2_game_window;
extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate image;
extern crate libc;
extern crate cgmath;
extern crate time;

extern crate flate;
extern crate native;
extern crate rustrt;
extern crate serialize;

use sdl2_game_window::GameWindowSDL2 as Window;
use piston::input;
use piston::cam;
use piston::vecmath::{vec3_add, vec3_scale, vec3_normalized};
use piston::{
    AssetStore,
    GameIterator,
    GameIteratorSettings,
    GameWindow,
    GameWindowSettings,
    Input,
    Render,
    Update
};

use array::*;

use std::cmp::max;
use std::f32::consts::PI;
use std::io::fs::File;

pub mod array;
pub mod chunk;
pub mod cube;
pub mod fps_counter;
pub mod shader;
pub mod texture;

pub mod minecraft {
    pub use self::data_1_8_pre2 as data;

    mod data_1_8_pre2;
    pub mod biome;
    pub mod block_state;
    pub mod model;
    pub mod nbt;
    pub mod region;
}

fn main() {
    let world = Path::new(std::os::args().as_slice().get(1).expect("Usage: ./hematite <path/to/world>").as_slice());

    let level = minecraft::nbt::Nbt::from_gzip(File::open(&world.join("level.dat")).read_to_end().unwrap().as_slice()).unwrap();
    println!("{}", level);
    let player_pos: [f32, ..3] = Array::from_iter(level["Data"]["Player"]["Pos"].as_double_list().unwrap().iter().map(|&x| x as f32));
    let player_chunk = [player_pos.x(), player_pos.z()].map(|x| (x / 16.0).floor() as i32);
    let player_rot = level["Data"]["Player"]["Rotation"].as_float_list().unwrap();
    let player_yaw = player_rot[0];
    let player_pitch = player_rot[1];

    let [region_x, region_z] = player_chunk.map(|x| x >> 5);
    let region_file = world.join(format!("region/r.{}.{}.mca", region_x, region_z));
    let region = minecraft::region::Region::open(&region_file);

    let mut window = Window::new(
        piston::shader_version::opengl::OpenGL_3_3,
        GameWindowSettings {
            title: format!("Hematite - {}", world.display()),
            size: [854, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    );
    let (mut device, frame) = window.gfx();

    let assets = &AssetStore::from_folder("../assets");

    // Load biomes.
    let biomes = minecraft::biome::Biomes::load(assets);

    // Load block state definitions and models.
    let block_states = minecraft::block_state::BlockStates::load(assets, &mut device);

    let mut renderer = shader::Renderer::new(device, frame, block_states.texture().tex);

    let mut chunk_manager = chunk::ChunkManager::new();

    println!("Started loading chunks...");
    let [cx_base, cz_base] = player_chunk.map(|x| max(0, (x & 0x1f) - 8) as u8);
    for cz in range(cz_base, cz_base + 16) {
        for cx in range(cx_base, cx_base + 16) {
            match region.get_chunk_column(cx, cz) {
                Some(column) => {
                    let [cx, cz] = [cx as i32 + region_x * 32, cz as i32 + region_z * 32];
                    chunk_manager.add_chunk_column(cx, cz, column)
                }
                None => {}
            }
        }
    }
    println!("Finished loading chunks.");

    renderer.set_projection(cam::CameraPerspective {
        fov: 70.0,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: {
            let (w, h) = window.get_size();
            (w as f32) / (h as f32)
        }
    }.projection());

    let mut first_person_settings = cam::FirstPersonSettings::default();
    first_person_settings.speed_horizontal = 8.0;
    first_person_settings.speed_vertical = 4.0;
    let mut first_person = cam::FirstPerson::new(
        player_pos,
        first_person_settings
    );
    first_person.yaw = PI - player_yaw / 180.0 * PI;
    first_person.pitch = player_pitch / 180.0 * PI;

    let game_iter_settings = GameIteratorSettings {
        updates_per_second: 120,
        max_frames_per_second: 10000
    };

    // Disable V-Sync.
    sdl2::video::gl_set_swap_interval(0);

    let mut fps_counter = fps_counter::FPSCounter::new();

    let mut pending_chunks = vec![];
    chunk_manager.each_chunk_and_neighbors(|coords, buffer, chunks, column_biomes| {
        pending_chunks.push((coords, buffer, chunks, column_biomes));
    });

    let mut capture_cursor = false;
    println!("Press C to capture mouse");

    let mut staging_buffer = vec![];
    let mut last_render = time::precise_time_ns();
    let mut events = GameIterator::new(&mut window, &game_iter_settings);
    for e in events {
        match e {
            Render(_) => {
                // Update camera.
                let now = time::precise_time_ns();
                let dt = (now - last_render) as f64 / 1_000_000_000.0f64;
                first_person.update(dt);
                last_render = now;

                // Apply the same y/z camera offset vanilla minecraft has.
                let mut camera = first_person.camera(0.0);
                camera.position[1] += 1.62;
                let mut xz_forward = camera.forward;
                xz_forward[1] = 0.0;
                xz_forward = vec3_normalized(xz_forward);
                camera.position = vec3_add(camera.position, vec3_scale(xz_forward, 0.1));

                renderer.set_view(camera.orthogonal());
                renderer.reset();
                chunk_manager.each_chunk(|_, _, _, _, buffer| {
                    match buffer {
                        Some(buffer) => renderer.render(buffer),
                        None => {}
                    }
                });
                renderer.end_frame();

                let fps = fps_counter.update();
                let title = format!("Hematite @ {}FPS - {}", fps, world.display());
                events.game_window.window.set_title(title.as_slice());
            }
            Update(_) => {
                // HACK(eddyb) find the closest chunk to the player.
                // The pending vector should be sorted instead.
                let closest = pending_chunks.iter().enumerate().min_by(|&(_, &([cx, cy, cz], _, _, _))| {
                    let [px, py, pz] = first_person.position.map(|x| (x / 16.0).floor() as i32);
                    let [x2, y2, z2] = [cx - px, cy - py, cz - pz].map(|x| x * x);
                    x2 + y2 + z2
                }).map(|(i, _)| i);

                let pending = closest.and_then(|i| pending_chunks.swap_remove(i));
                match pending {
                    Some((coords, buffer, chunks, column_biomes)) => {
                        match buffer.get() {
                            Some(buffer) => renderer.delete_buffer(buffer),
                            None => {}
                        }
                        minecraft::block_state::fill_buffer(&block_states, &biomes,
                                                            &mut staging_buffer,
                                                            coords, chunks,
                                                            column_biomes);
                        buffer.set(Some(renderer.create_buffer(staging_buffer.as_slice())));
                        staging_buffer.clear();

                        if pending_chunks.is_empty() {
                            println!("Finished filling chunk vertex buffers.");
                        }
                    }
                    None => {}
                }
            }
            Input(input::KeyPress { key: input::keyboard::C }) => {
                println!("Turned cursor capture {}",
                    if capture_cursor { "off" } else { "on" });
                capture_cursor = !capture_cursor;

                events.game_window.capture_cursor(capture_cursor);
            }
            Input(input::MouseRelativeMove { .. }) => {
                if !capture_cursor {
                    // Don't send the mouse event to the FPS controller.
                    continue;
                }
            }
            _ => {}
        }

        // Camera controller.
        match e {
            Input(ref args) => first_person.input(args),
            _ => {}
        }
    }
}
<|endoftext|>