<commit_before>//! A Rust snippet runner.
//!
//! Please see [readme](https://github.com/stevedonovan/runner/blob/master/readme.md)
extern crate easy_shortcuts as es;
extern crate lapp;
use es::traits::*;
use std::process;
use std::env;
use std::fs;
use std::path::PathBuf;

mod crate_utils;
mod platform;

use platform::{open,edit,EXE};

fn rustup_lib() -> String {
    es::shell("rustc --print sysroot") + "/lib"
}

// this will be initially written to ~/.cargo/.runner/prelude and
// can then be edited.
const PRELUDE: &'static str = "
#![allow(unused_imports)]
#![allow(dead_code)]
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;
use std::path::{PathBuf,Path};
#[allow(unused_macros)]
macro_rules! debug {
    ($x:expr) => {
        println!(\"{} = {:?}\",stringify!($x),$x);
    }
}

";

fn runner_directory() -> PathBuf {
    let mut home = env::home_dir().or_die("no home!");
    home.push(".cargo");
    home.push(".runner");
    home
}

fn cargo(args: &[&str]) {
    let res = process::Command::new("cargo")
        .args(args)
        .status()
        .or_die("can't run cargo");
    if ! res.success() {
        es::quit("cargo failed");
    }
}

const STATIC_CACHE: &str = "static-cache";
const DYNAMIC_CACHE: &str = "dy-cache";

fn static_cache_dir() -> PathBuf {
    runner_directory().join(STATIC_CACHE)
}

fn static_cache_dir_check(args: &lapp::Args) -> PathBuf {
    let static_cache = static_cache_dir();
    if ! static_cache.exists() {
        args.quit("please build static cache with --create first");
    }
    static_cache
}

fn build_static_cache() {
    cargo(&["build"]);
    cargo(&["build","--release"]);
    cargo(&["doc"]);
}

fn create_static_cache(crates: &[String], create: bool) {
    use std::io::prelude::*;
    let mut home = runner_directory();
    env::set_current_dir(&home).or_die("cannot change to home directory");
    if create {
        cargo(&["new","--bin",STATIC_CACHE]);
    }
    home.push(STATIC_CACHE);
    env::set_current_dir(&home).or_die("could not create static cache");
    {
        let mut deps = fs::OpenOptions::new().append(true)
            .open("Cargo.toml").or_die("could not append to cargo.toml");
        for c in crates {
            write!(deps,"{}=\"*\"\n",c).or_die("could not modify cargo.toml");
        }
    }
    build_static_cache();
}

// this is always called first and has the important role to ensure that
// runner's directory structure is created properly.
fn get_prelude() -> String {
    let home = runner_directory();
    let pristine = ! home.is_dir();
    if pristine {
        fs::create_dir(&home).or_die("cannot create runner directory");
    }
    let prelude = home.join("prelude");
    let bin = home.join("bin");
    if pristine {
        es::write_all(&prelude,PRELUDE);
        fs::create_dir(&home.join(DYNAMIC_CACHE)).or_die("cannot create dynamic cache");
    }
    if pristine || ! bin.is_dir() {
        fs::create_dir(&bin).or_die("cannot create output directory");
    }
    es::read_to_string(&prelude)
}

fn get_cache(build_static: bool, optimize: bool) -> PathBuf {
    let mut home = runner_directory();
    let scache;
    let cache = if build_static {
        let dir = if optimize {"release"} else {"debug"};
        scache = format!("{}/target/{}/deps",STATIC_CACHE,dir);
        &scache
    } else {DYNAMIC_CACHE};
    home.push(cache);
    home
}

fn massage_snippet(code: String, prelude: String, extern_crates: Vec<String>) -> String {
    fn indent_line(line: &str) -> String {
        format!("    {}\n",line)
    }
    let mut prefix = prelude;
    let mut body = String::new();
    {
        for c in extern_crates {
            body += &format!("extern crate {};",c);
        }
        let mut lines = code.lines();
        for line in lines.by_ref() {
            let line = line.trim_left();
            if line.starts_with("//") || line.starts_with("#[") ||
                line.starts_with("extern ") || line.starts_with("use ") {
                prefix += line;
                prefix.push('\n');
            } else {
                body += &indent_line(line);
                break;
            }
        }
        // and indent the rest!
        body.extend(lines.map(indent_line));
    }

    format!("{}
use std::error::Error;
fn run() -> Result<(),Box<Error>> {{
{}    Ok(())
}}
fn main() {{
    run().unwrap();
}}
        ",prefix,body)

}

const USAGE: &str = "
Compile and run small Rust snippets
  -s, --static build statically (default is dynamic)
  -O, --optimize optimized static build
  -e, --expression evaluate an expression
  -i, --iterator evaluate an iterator
  -n, --lines evaluate expression over stdin; 'line' is defined
  -x, --extern... (string) add an extern crate to the snippet

  Cache Management:
  --create (string...) initialize the static cache with crates
  --add  (string...) add new crates to the cache (after --create)
  --edit  edit the static cache Cargo.toml
  --build rebuild the static cache
  --doc  display
  --edit-prelude edit the default prelude for snippets

  Dynamic compilation:
  -P, --crate-path show path of crate source in Cargo cache
  -C, --compile  compile crate dynamically (limited)

  <program> (string) Rust program, snippet or expression
  <args> (string...) arguments to pass to program
";

fn main() {
    let args = lapp::parse_args(USAGE);
    let prelude = get_prelude();

    if args.get_bool("edit-prelude") {
        let rdir = runner_directory().join("prelude");
        edit(&rdir);
        return;
    }

    // Static Cache Management
    let crates = args.get_strings("create");
    if crates.len() > 0 {
        create_static_cache(&crates,true);
        return;
    }
    let crates = args.get_strings("add");
    if crates.len() > 0 {
        static_cache_dir_check(&args);
        create_static_cache(&crates,false);
        return;
    }

    if args.get_bool("edit") || args.get_bool("build") || args.get_bool("doc") {
        let static_cache = static_cache_dir_check(&args);
        if args.get_bool("build") {
            env::set_current_dir(&static_cache).or_die("static cache wasn't a directory?");
            build_static_cache();
        } else
        if args.get_bool("doc") {
            let docs = static_cache.join("target/doc/static_cache/index.html");
            open(&docs);
        } else {
            let toml = static_cache.join("Cargo.toml");
            edit(&toml);
        }
        return;
    }

    let first_arg = args.get_string("program");
    let file = PathBuf::from(&first_arg);

    // Dynamically linking crates (experimental!)
    if args.get_bool("crate-path") || args.get_bool("compile") {
        let (crate_path,crate_name) = if file.exists() {
            let filename = crate_utils::path_file_name(&file);
            (file, filename)
        } else {
            (crate_utils::cache_path(&first_arg), first_arg)
        };
        if args.get_bool("crate-path") {
            println!("{}",crate_path.display());
        } else {
            let valid_crate_name = crate_name.replace('-',"_");
            let cache = get_cache(false, false);
            process::Command::new("rustc")
                .args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"])
                .arg("-L").arg(&cache)
                .args(&["--crate-type","dylib"])
                .arg("--out-dir").arg(&cache)
                .arg("--crate-name").arg(&valid_crate_name)
                .arg(crate_path.join("src/lib.rs"))
           .status().or_die("can't run rustc");
        }
        return;
    }

    let build_static = args.get_bool("static");
    let optimize = args.get_bool("optimize");

    // we'll pass rest of arguments to program
    let program_args = args.get_strings("args");

    let cache = get_cache(build_static, optimize);

    let mut snippet = false;
    let mut code = if args.get_bool("expression") {
        // Evaluating an expression: just print it out.
        format!("let res = {};\nprintln!(\"{{:?}}\",res);", first_arg)
    } else
    if args.get_bool("iterator") {
        // The expression is anything that implements IntoIterator
        format!("let iter = {};\n for val in iter {{ println!(\"{{:?}}\",val);}}", first_arg)
    } else
    if args.get_bool("lines") {
        // The variable 'line' is available to an expression, evaluated for each line in stdin
        format!("
            let stdin = io::stdin();
            for line in stdin.lock().lines() {{
                let line = line?;
                let val = {};
                println!(\"{{:?}}\",val);
            }}
            ", first_arg)
    } else { // otherwise, just a file
        // for now, we insist it has the usual Rust extension...
        let ext = file.extension().or_die("no file extension");
        if ext != "rs" {
            es::quit("file extension must be .rs");
        }
        snippet = true;
        es::read_to_string(&file)
    };

    // proper Rust programs are accepted (this is a bit rough)
    if code.find("fn main").is_none() {
        code = massage_snippet(code,prelude, args.get_strings("extern"));
    }

    // we are going to put the expanded source and resulting exe in the runner bin dir
    let mut out_file = runner_directory().join("bin");
    if snippet {
        out_file.push(&file);
    } else {
        out_file.push("tmp.rs");
    }
    let mut program = out_file.clone();
    program.set_extension(EXE);

    es::write_all(&out_file,&code);

    let mut builder = process::Command::new("rustc");
    if ! build_static {
        builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"]);
    } else {
        builder.arg(if optimize {"-O"} else {"-g"});
    }
    builder.arg("-L").arg(&cache);
    let status = builder.arg("-o").arg(&program)
        .arg(&out_file)
        .status().or_die("can't run rustc");
    if ! status.success() {
        return;
    }

    let mut builder = process::Command::new(&program);
    if ! build_static {
        builder.env("LD_LIBRARY_PATH",format!("{}:{}",rustup_lib(),cache.display()));
    }
    builder.args(&program_args)
        .status()
        .or_die(&format!("can't run program {:?}",program));

}

<commit_msg>--compile will also work with a plain Rust source file<commit_after>//! A Rust snippet runner.
//!
//! Please see [readme](https://github.com/stevedonovan/runner/blob/master/readme.md)
extern crate easy_shortcuts as es;
extern crate lapp;
use es::traits::*;
use std::process;
use std::env;
use std::fs;
use std::path::PathBuf;

mod crate_utils;
mod platform;

use platform::{open,edit,EXE};

fn rustup_lib() -> String {
    es::shell("rustc --print sysroot") + "/lib"
}

// this will be initially written to ~/.cargo/.runner/prelude and
// can then be edited.
const PRELUDE: &'static str = "
#![allow(unused_imports)]
#![allow(dead_code)]
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;
use std::path::{PathBuf,Path};
#[allow(unused_macros)]
macro_rules! debug {
    ($x:expr) => {
        println!(\"{} = {:?}\",stringify!($x),$x);
    }
}

";

fn runner_directory() -> PathBuf {
    let mut home = env::home_dir().or_die("no home!");
    home.push(".cargo");
    home.push(".runner");
    home
}

fn cargo(args: &[&str]) {
    let res = process::Command::new("cargo")
        .args(args)
        .status()
        .or_die("can't run cargo");
    if ! res.success() {
        es::quit("cargo failed");
    }
}

const STATIC_CACHE: &str = "static-cache";
const DYNAMIC_CACHE: &str = "dy-cache";

fn static_cache_dir() -> PathBuf {
    runner_directory().join(STATIC_CACHE)
}

fn static_cache_dir_check(args: &lapp::Args) -> PathBuf {
    let static_cache = static_cache_dir();
    if ! static_cache.exists() {
        args.quit("please build static cache with --create first");
    }
    static_cache
}

fn build_static_cache() {
    cargo(&["build"]);
    cargo(&["build","--release"]);
    cargo(&["doc"]);
}

fn create_static_cache(crates: &[String], create: bool) {
    use std::io::prelude::*;
    let mut home = runner_directory();
    env::set_current_dir(&home).or_die("cannot change to home directory");
    if create {
        cargo(&["new","--bin",STATIC_CACHE]);
    }
    home.push(STATIC_CACHE);
    env::set_current_dir(&home).or_die("could not create static cache");
    {
        let mut deps = fs::OpenOptions::new().append(true)
            .open("Cargo.toml").or_die("could not append to cargo.toml");
        for c in crates {
            write!(deps,"{}=\"*\"\n",c).or_die("could not modify cargo.toml");
        }
    }
    build_static_cache();
}

// this is always called first and has the important role to ensure that
// runner's directory structure is created properly.
fn get_prelude() -> String {
    let home = runner_directory();
    let pristine = ! home.is_dir();
    if pristine {
        fs::create_dir(&home).or_die("cannot create runner directory");
    }
    let prelude = home.join("prelude");
    let bin = home.join("bin");
    if pristine {
        es::write_all(&prelude,PRELUDE);
        fs::create_dir(&home.join(DYNAMIC_CACHE)).or_die("cannot create dynamic cache");
    }
    if pristine || ! bin.is_dir() {
        fs::create_dir(&bin).or_die("cannot create output directory");
    }
    es::read_to_string(&prelude)
}

fn get_cache(build_static: bool, optimize: bool) -> PathBuf {
    let mut home = runner_directory();
    let scache;
    let cache = if build_static {
        let dir = if optimize {"release"} else {"debug"};
        scache = format!("{}/target/{}/deps",STATIC_CACHE,dir);
        &scache
    } else {DYNAMIC_CACHE};
    home.push(cache);
    home
}

fn massage_snippet(code: String, prelude: String, extern_crates: Vec<String>) -> String {
    fn indent_line(line: &str) -> String {
        format!("    {}\n",line)
    }
    let mut prefix = prelude;
    let mut body = String::new();
    {
        for c in extern_crates {
            body += &format!("extern crate {};",c);
        }
        let mut lines = code.lines();
        for line in lines.by_ref() {
            let line = line.trim_left();
            if line.starts_with("//") || line.starts_with("#[") ||
                line.starts_with("extern ") || line.starts_with("use ") {
                prefix += line;
                prefix.push('\n');
            } else {
                body += &indent_line(line);
                break;
            }
        }
        // and indent the rest!
        body.extend(lines.map(indent_line));
    }

    format!("{}
use std::error::Error;
fn run() -> Result<(),Box<Error>> {{
{}    Ok(())
}}
fn main() {{
    run().unwrap();
}}
        ",prefix,body)

}

const USAGE: &str = "
Compile and run small Rust snippets
  -s, --static build statically (default is dynamic)
  -O, --optimize optimized static build
  -e, --expression evaluate an expression
  -i, --iterator evaluate an iterator
  -n, --lines evaluate expression over stdin; 'line' is defined
  -x, --extern... (string) add an extern crate to the snippet

  Cache Management:
  --create (string...) initialize the static cache with crates
  --add  (string...) add new crates to the cache (after --create)
  --edit  edit the static cache Cargo.toml
  --build rebuild the static cache
  --doc  display
  --edit-prelude edit the default prelude for snippets

  Dynamic compilation:
  -P, --crate-path show path of crate source in Cargo cache
  -C, --compile  compile crate dynamically (limited)

  <program> (string) Rust program, snippet or expression
  <args> (string...) arguments to pass to program
";

fn main() {
    let args = lapp::parse_args(USAGE);
    let prelude = get_prelude();

    if args.get_bool("edit-prelude") {
        let rdir = runner_directory().join("prelude");
        edit(&rdir);
        return;
    }

    // Static Cache Management
    let crates = args.get_strings("create");
    if crates.len() > 0 {
        create_static_cache(&crates,true);
        return;
    }
    let crates = args.get_strings("add");
    if crates.len() > 0 {
        static_cache_dir_check(&args);
        create_static_cache(&crates,false);
        return;
    }

    if args.get_bool("edit") || args.get_bool("build") || args.get_bool("doc") {
        let static_cache = static_cache_dir_check(&args);
        if args.get_bool("build") {
            env::set_current_dir(&static_cache).or_die("static cache wasn't a directory?");
            build_static_cache();
        } else
        if args.get_bool("doc") {
            let docs = static_cache.join("target/doc/static_cache/index.html");
            open(&docs);
        } else {
            let toml = static_cache.join("Cargo.toml");
            edit(&toml);
        }
        return;
    }

    let first_arg = args.get_string("program");
    let file = PathBuf::from(&first_arg);

    // Dynamically linking crates (experimental!)
    if args.get_bool("crate-path") || args.get_bool("compile") {
        let (crate_path,crate_name) = if file.exists() {
            let filename = crate_utils::path_file_name(&file);
            if file.is_dir() { // assumed to be Cargo directory
                if ! file.join("Cargo.toml").exists() {
                    args.quit("not a Cargo project directory");
                }
                (file.join("src/lib.rs"), filename)
            } else { // should be just a Rust source file
                if file.extension().or_die("expecting extension") != "rs" {
                    args.quit("expecting Rust source file");
                }
                let name = crate_utils::path_file_name(&file.with_extension(""));
                (file, name)
            }
        } else {
            (crate_utils::cache_path(&first_arg).join("src/lib.rs"), first_arg)
        };
        if args.get_bool("crate-path") {
            println!("{}",crate_path.display());
        } else {
            let valid_crate_name = crate_name.replace('-',"_");
            let cache = get_cache(false, false);
            process::Command::new("rustc")
                .args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"])
                .arg("-L").arg(&cache)
                .args(&["--crate-type","dylib"])
                .arg("--out-dir").arg(&cache)
                .arg("--crate-name").arg(&valid_crate_name)
                .arg(crate_path)
           .status().or_die("can't run rustc");
        }
        return;
    }

    let build_static = args.get_bool("static");
    let optimize = args.get_bool("optimize");

    // we'll pass rest of arguments to program
    let program_args = args.get_strings("args");

    let cache = get_cache(build_static, optimize);

    let mut snippet = false;
    let mut code = if args.get_bool("expression") {
        // Evaluating an expression: just print it out.
        format!("let res = {};\nprintln!(\"{{:?}}\",res);", first_arg)
    } else
    if args.get_bool("iterator") {
        // The expression is anything that implements IntoIterator
        format!("let iter = {};\n for val in iter {{ println!(\"{{:?}}\",val);}}", first_arg)
    } else
    if args.get_bool("lines") {
        // The variable 'line' is available to an expression, evaluated for each line in stdin
        format!("
            let stdin = io::stdin();
            for line in stdin.lock().lines() {{
                let line = line?;
                let val = {};
                println!(\"{{:?}}\",val);
            }}
            ", first_arg)
    } else { // otherwise, just a file
        // for now, we insist it has the usual Rust extension...
        let ext = file.extension().or_die("no file extension");
        if ext != "rs" {
            es::quit("file extension must be .rs");
        }
        snippet = true;
        es::read_to_string(&file)
    };

    // proper Rust programs are accepted (this is a bit rough)
    if code.find("fn main").is_none() {
        code = massage_snippet(code,prelude, args.get_strings("extern"));
    }

    // we are going to put the expanded source and resulting exe in the runner bin dir
    let mut out_file = runner_directory().join("bin");
    if snippet {
        out_file.push(&file);
    } else {
        out_file.push("tmp.rs");
    }
    let mut program = out_file.clone();
    program.set_extension(EXE);

    es::write_all(&out_file,&code);

    let mut builder = process::Command::new("rustc");
    if ! build_static {
        builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"]);
    } else {
        builder.arg(if optimize {"-O"} else {"-g"});
    }
    builder.arg("-L").arg(&cache);
    let status = builder.arg("-o").arg(&program)
        .arg(&out_file)
        .status().or_die("can't run rustc");
    if ! status.success() {
        return;
    }

    let mut builder = process::Command::new(&program);
    if ! build_static {
        builder.env("LD_LIBRARY_PATH",format!("{}:{}",rustup_lib(),cache.display()));
    }
    builder.args(&program_args)
        .status()
        .or_die(&format!("can't run program {:?}",program));

}

<|endoftext|>


<commit_before>extern crate serde_json;
extern crate clap;

use serde_json::Value;
use serde_json::Deserializer;
use std::io::{self, Write};
use clap::{App, Arg};
use std::fs;
use std::result;
use std::error::Error;
use std::vec::Vec;
use std::string::String;

type Result<T> = result::Result<T, Box<Error>>;

fn run() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about("Extract JSON elements from a stream")
        .arg(Arg::with_name("INPUT")
            .short("i")
            .long("input")
            .takes_value(true)
            .help("input file to use if not receiving on stdin"))
        .arg(Arg::with_name("POINTER")
            .index(1)
            .required(true)
            .multiple(true)
            .help("JSON Pointer expressions to match on input"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap_or("-");
    let rdr: Box<io::Read> = match input {
        "-" => Box::new(io::stdin()),
        _ => Box::new(try!(fs::File::open(input))),
    };

    // unwrap is safe because POINTER is required
    let pointers_in = matches.values_of("POINTER").unwrap();
    let mut pointers = Vec::new();
    for p in pointers_in {
        pointers.push(p);
    }

    let iter = Deserializer::from_reader(rdr).into_iter::<Value>();
    for rv in iter {
        let v: Value = try!(rv);
        let mut line = String::new();
        for p in &pointers {
            line.push_str(&render(v.pointer(p).unwrap_or(&Value::Null)));
            line.push('\t');
        }
        line.pop();
        println!("{}", line);
    }
    Ok(())
}

fn main() {
    match run() {
        Ok(_) => {}
        Err(e) => {
            writeln!(&mut io::stderr(), "error: {}", e).unwrap();
            std::process::exit(1);
        }
    }
}

fn render(v: &Value) -> String {
    match v {
        &Value::Null => String::new(),
        &Value::Bool(ref b) => format!("{}", b),
        &Value::Number(ref b) => format!("{}", b),
        &Value::String(ref s) => format!("{}", s),
        &Value::Array(_) => format!("{}", v),
        &Value::Object(_) => format!("{}", v),
    }
}
<commit_msg>minor cleanups;<commit_after>extern crate serde_json;
extern crate clap;

use serde_json::Value;
use serde_json::Deserializer;
use std::io::{self, Write};
use clap::{App, Arg};
use std::fs;
use std::result;
use std::error::Error;
use std::vec::Vec;
use std::string::String;

type Result<T> = result::Result<T, Box<Error>>;

fn run() -> Result<()> {
    let matches = App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .about("Extract JSON elements from a stream via JSON Pointers")
        .arg(Arg::with_name("INPUT")
            .short("i")
            .long("input")
            .takes_value(true)
            .help("input file to use if not receiving on stdin"))
        .arg(Arg::with_name("POINTER")
            .required(true)
            .multiple(true)
            .help("JSON Pointer expressions to match on input"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap_or("-");
    let rdr: Box<io::Read> = match input {
        "-" => Box::new(io::stdin()),
        _ => Box::new(try!(fs::File::open(input))),
    };

    let mut pointers = Vec::new();
    // unwrap is safe as POINTER is required
    for p in matches.values_of("POINTER").unwrap() {
        pointers.push(p);
    }

    let iter = Deserializer::from_reader(rdr).into_iter::<Value>();
    for rv in iter {
        let v: Value = try!(rv);
        let mut line = String::new();
        for p in &pointers {
            line.push_str(&render(v.pointer(p).unwrap_or(&Value::Null)));
            line.push('\t');
        }
        line.pop();
        println!("{}", line);
    }
    Ok(())
}

fn main() {
    match run() {
        Ok(_) => {}
        Err(e) => {
            writeln!(&mut io::stderr(), "error: {}", e).unwrap();
            std::process::exit(1);
        }
    }
}

fn render(v: &Value) -> String {
    match v {
        &Value::Null => String::new(),
        &Value::Bool(ref b) => format!("{}", b),
        &Value::Number(ref b) => format!("{}", b),
        &Value::String(ref s) => format!("{}", s),
        &Value::Array(_) => format!("{}", v),
        &Value::Object(_) => format!("{}", v),
    }
}
<|endoftext|>


<commit_before>extern crate getopts;

use std::io::fs::File;
use std::os;
use getopts::{optopt,optflag, getopts,OptGroup,usage};
use std::io::Command;

mod tokenizer;

fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options] INPUT_FILE", program);
    print!("{}", usage(brief.as_slice(), opts));
}

fn main() {
    let args = os::args();
    let program = args[0].clone();
    let opts = &[
        optflag("h", "help", "print this help menu"),
        optopt("o", "output", "set output filename", "OUTPUT"),
    ];

    macro_rules! u {
        () => {
            {
                print_usage(program.as_slice(), opts);
                return;
            }
        }
    };

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            u!();
        }
    };

    if matches.opt_present("h") { u!(); }
    if matches.free.is_empty() { u!(); }

    let path = Path::new(&matches.free[0]);

    let outname = match matches.opt_str("o") {
        Some(o) => o,
        None => path.filestem_str().unwrap_or("a.out").to_string()
    };
    let file = File::open(&path).read_to_string().unwrap_or("".to_string());

    let indent_by = "    ";
    let mut indent = indent_by.to_string();

    let mut commands = String::new();
    let buffer_size = 50_000;

    for tok in tokenizer::BFToken::parse_file(&path).iter() {
        use tokenizer::BFToken::*;

        let mut level = indent.clone();
        let line = match *tok {
            RShift(count) =>
                format!("ptr += {c}; if ptr >= {bs} {{ ptr = 0; }}", c=count, bs=buffer_size),
            LShift(count) =>
                format!("if ptr == 0 {{ ptr = {bs} - 1; }} else {{ ptr -= {c} }}", c=count, bs=buffer_size),
            Increment(count) =>
                format!("array[ptr] += {count};", count=count),
            Decrement(count) =>
                format!("array[ptr] -= {count};", count=count),
            Comment(ref val) =>
                format!("// {}", val),
            WriteChar =>
                "print!(\"{}\", array[ptr] as char);".to_string(),
            ReadChar =>
                "array[ptr] = io::stdin().read_char().unwrap_or('\0') as u8;".to_string(),
            StartLoop => {
                indent.push_str(indent_by);
                "while array[ptr] > 0 {".to_string()
            },
            EndLoop => {
                for _ in indent_by.chars() {
                    indent.pop();
                }
                level = indent.clone();
                "}".to_string()
            }
        };

        commands = format!("{}{}{};\n", commands, level, line);
    }

    let mut child = match Command::new("rustc")
                                  .arg("-o").arg(outname)
                                  .arg("-").spawn() {
        Ok(child) => child,
        Err(e) => panic!("Failed to execute child: {:?}", e)
    };

    macro_rules! src {
        ($($arg:tt)*) => { write!(&mut child.stdin.as_mut().unwrap(), $($arg)*) }
    }

    src!("use std::io;");
    src!("fn main() {{");
    src!("{}let mut array = [0u8; {}];", indent_by, buffer_size);
    src!("{}let mut ptr = {};", indent_by, buffer_size / 2);
    src!("{}", commands);
    src!("}}");

    match child.wait_with_output() {
        Ok(out) => {
            println!("{}", String::from_utf8_lossy(out.output.as_slice()));
        },
        Err(_) => {}
    }
}
<commit_msg>Allow printing compiled rust code<commit_after>extern crate getopts;

use std::io::fs::File;
use std::io;
use std::os;
use getopts::{optopt,optflag, getopts,OptGroup,usage};
use std::io::Command;

mod tokenizer;

fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options] INPUT_FILE", program);
    print!("{}", usage(brief.as_slice(), opts));
}

fn main() {
    let args = os::args();
    let program = args[0].clone();
    let opts = &[
        optflag("h", "help", "print this help menu"),
        optopt("o", "output", "set output filename", "OUTPUT"),
        optflag("r", "rust", "print out rust source"),
    ];

    macro_rules! u {
        () => {
            {
                print_usage(program.as_slice(), opts);
                return;
            }
        }
    };

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            u!();
        }
    };

    if matches.opt_present("h") { u!(); }
    if matches.free.is_empty() { u!(); }

    let path = Path::new(&matches.free[0]);

    let outname = match matches.opt_str("o") {
        Some(o) => o,
        None => path.filestem_str().unwrap_or("a.out").to_string()
    };
    let file = File::open(&path).read_to_string().unwrap_or("".to_string());

    let indent_by = "    ";
    let mut indent = indent_by.to_string();

    let mut commands = String::new();
    let buffer_size = 50_000;

    for tok in tokenizer::BFToken::parse_file(&path).iter() {
        use tokenizer::BFToken::*;

        let mut level = indent.clone();
        let line = match *tok {
            RShift(count) =>
                format!("ptr += {c}; if ptr >= {bs} {{ ptr = 0; }}", c=count, bs=buffer_size),
            LShift(count) =>
                format!("if ptr == 0 {{ ptr = {bs} - 1; }} else {{ ptr -= {c} }}", c=count, bs=buffer_size),
            Increment(count) =>
                format!("array[ptr] += {count};", count=count),
            Decrement(count) =>
                format!("array[ptr] -= {count};", count=count),
            Comment(ref val) => {
                let val = val.clone();
                let v = val.replace("\n", " ")
                           .replace("\r", " ");
                let v = v.trim_matches(|&: c: char| c == ' ');
                if v.len() > 0 {
                    format!("// {}", v)
                } else {
                    "".to_string()
                }
            },
            WriteChar =>
                "print!(\"{}\", array[ptr] as char);".to_string(),
            ReadChar =>
                "array[ptr] = io::stdin().read_char().unwrap_or('\\0') as u8;".to_string(),
            StartLoop => {
                indent.push_str(indent_by);
                "while array[ptr] > 0 {".to_string()
            },
            EndLoop => {
                for _ in indent_by.chars() {
                    indent.pop();
                }
                level = indent.clone();
                "}".to_string()
            }
        };

        if line.len() > 0 {
            commands = format!("{}{}{}\n", commands, level, line);
        }
    }

    let compile = !matches.opt_present("r");

    let mut child = if compile {
        Some(match Command::new("rustc")
                      .arg("-o").arg(outname)
                      .arg("-").spawn() {
            Ok(child) => child,
            Err(e) => panic!("Failed to execute child: {:?}", e)
        })
    } else {
        None
    };

    macro_rules! src {
        ($($arg:tt)*) => {
            if compile {
                match child.as_mut() {
                    Some(child) => {
                        write!(child.stdin.as_mut().unwrap(), $($arg)*);
                    },
                    None => unreachable!()
                }
            } else {
                write!(&mut io::stdout(), $($arg)*);
            }
        }
    }

    src!("use std::io;\n");
    src!("fn main() {{\n");
    src!("{}let mut array = [0u8; {}];\n", indent_by, buffer_size);
    src!("{}let mut ptr = {};\n", indent_by, buffer_size / 2);
    src!("{}", commands);
    src!("}}\n");

    if compile {
        match child.unwrap().wait_with_output() {
            Ok(out) => {
                println!("{}", String::from_utf8_lossy(out.output.as_slice()));
            },
            Err(_) => {}
        }
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate nalgebra as na;
extern crate rustracer as rt;
#[macro_use]
extern crate clap;
extern crate rustc_serialize;
extern crate num_cpus;
#[macro_use(o, slog_info, slog_debug, slog_warn, slog_error, slog_trace, slog_log)]
extern crate slog;
#[macro_use]
extern crate slog_scope;
extern crate slog_stream;
extern crate thread_id;

use std::sync::Arc;
use std::num::ParseIntError;
use std::fs::OpenOptions;
use std::path::Path;
use std::io;
use std::process;

use chrono::Local;
use clap::{Arg, ArgMatches, App};
use slog::*;

use rt::bvh::BVH;
use rt::camera::Camera;
use rt::integrator::{SamplerIntegrator, Whitted, Normal, AmbientOcclusion};
use rt::light::{Light, DistantLight, DiffuseAreaLight};
use rt::material::matte::MatteMaterial;
use rt::material::plastic::Plastic;
use rt::material::metal::Metal;
use rt::{Point, Vector, Dim};
use rt::primitive::{Primitive, GeometricPrimitive};
use rt::renderer;
use rt::scene::Scene;
use rt::shapes::disk::Disk;
use rt::shapes::sphere::Sphere;
use rt::spectrum::Spectrum;
use rt::transform;

arg_enum! {
  #[derive(Debug)]
  enum SamplerIntegratorType {
      Whitted,
      Ao,
      Normal
  }
}

fn main() {
    // configure logger
    configure_logger();

    let matches = parse_args();
    if let Err(e) = run(matches) {
        println!("Application error: {}", e);
        process::exit(1);
    }
}

fn run(matches: ArgMatches) -> Result<(), String> {
    let parsed_dims: Result<Vec<u32>, ParseIntError> =
        matches.value_of("dim").unwrap().split('x').map(|s| s.parse::<u32>()).collect();
    let dims = parsed_dims.expect("Invalid dimensions");
    if dims.len() != 2 {
        panic!("Error: invalid dimension specification");
    }
    let dim = (dims[0], dims[1]);

    let integrator: Box<SamplerIntegrator + Send + Sync> =
        match value_t!(matches.value_of("integrator"), SamplerIntegratorType)
            .unwrap_or(SamplerIntegratorType::Whitted) {
            SamplerIntegratorType::Whitted => {
                info!("Using Whitted integrator with max ray depth of {}", 8);
                // Box::new(Whitted::new(args.flag_whitted_max_ray_depth))
                Box::new(Whitted::new(8))
            }
            SamplerIntegratorType::Ao => {
                info!("Using Ambient Occlusion integrator with {} samples", 32);
                Box::new(AmbientOcclusion::new(32))
            }
            SamplerIntegratorType::Normal => {
                info!("Using normal facing ratio integrator");
                Box::new(Normal {})
            }
        };

    let scene = build_scene(dim, integrator);

    let start_time = std::time::Instant::now();
    let stats =
        renderer::render(scene,
                         dim,
                         matches.value_of("output").unwrap(),
                         matches.value_of("threads")
                             .and_then(|s| s.parse::<usize>().ok())
                             .unwrap_or_else(num_cpus::get),
                         matches.value_of("spp").and_then(|s| s.parse::<usize>().ok()).unwrap(),
                         32);
    // args.flag_block_size);
    let duration = start_time.elapsed();
    println!("Render time                : {}", duration.human_display());
    println!("Primary rays               : {}", stats.primary_rays);
    println!("Secondary rays             : {}", stats.secondary_rays);
    println!("Num triangles              : {}", stats.triangles);
    println!("Ray-triangle tests         : {}", stats.ray_triangle_tests);
    println!("Ray-triangle intersections : {}", stats.ray_triangle_isect);
    println!("Fast bounding-box test     : {}", stats.fast_bbox_isect);

    Ok(())
}

fn build_scene(dim: Dim, integrator: Box<SamplerIntegrator + Send + Sync>) -> Scene {
    info!("Building scene");
    let camera = Camera::new(Point::new(0.0, 0.0, 5.0), dim, 50.0);
    let mut lights: Vec<Arc<Light + Send + Sync>> = Vec::new();

    let disk = Arc::new(Disk::new(-2.0, 0.5, 0.0, 360.0, transform::rot_x(90.0)));
    let area_light =
        Arc::new(DiffuseAreaLight::new(Spectrum::rgb(2.0, 2.0, 2.0), disk.clone(), 16));
    let area_light_prim = Box::new(GeometricPrimitive {
        shape: disk.clone(),
        area_light: Some(area_light.clone()),
        material: Some(Arc::new(MatteMaterial::default())),
    });

    let bronze = Arc::new(Metal::new());
    let sphere = Box::new(GeometricPrimitive {
        shape: Arc::new(Sphere::new().transform(transform::rot(45.0, 45.0, 0.0))),
        area_light: None,
        // material: Some(Arc::new(Plastic::new(Spectrum::red(), Spectrum::white()))),
        // material: Some(Arc::new(Plastic::new_tex("lines.png", Spectrum::white()))),
        material: Some(bronze.clone()),
    });
    let bunny =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(&Path::new("models/bunny.obj"),
                                                           "bunny",
                                                           bronze.clone(),
                                                           &na::one())) as Box<Primitive + Send + Sync>;
    let floor = Box::new(GeometricPrimitive {
        shape: Arc::new(Disk::new(-1.0, 20.0, 0.0, 360.0, transform::rot_x(-90.0))),
        area_light: None,
        // material: Some(Arc::new(MatteMaterial::checkerboard(0.0))),
        material: Some(Arc::new(MatteMaterial::new(Spectrum::red(), 0.0))),
    });

    let primitives: Vec<Box<Primitive + Sync + Send>> = vec![bunny, floor, area_light_prim];
    // Light
    lights.push(area_light);
    lights.push(Arc::new(DistantLight::new(Vector::new(0.0, -1.0, -5.0),
                                           Spectrum::rgb(1.0, 1.0, 1.0))));

    Scene::new(camera, integrator, primitives, lights)
}

fn parse_args<'a>() -> ArgMatches<'a> {
    // TODO add block-size and ao-samples and whitted-max-ray? Or maybe not since eventually it
    // will be read from the scene file...
    App::new("rustracer")
        .version("0.1")
        .author("Antoine Bűsch")
        .about("Toy raytracer in Rust based on PBRTv3")
        .arg(Arg::with_name("output")
            .long("output")
            .short("o")
            .help("Output file name")
            .default_value("image.png"))
        .arg(Arg::with_name("threads")
            .long("threads")
            .short("t")
            .help("Number of worker threads"))
        .arg(Arg::with_name("dim")
            .long("dim")
            .short("d")
            .help("Dimension of the output image")
            .default_value("800x600"))
        .arg(Arg::with_name("integrator")
            .long("integrator")
            .short("i")
            .help("SamplerIntegrator to use")
            .possible_values(&SamplerIntegratorType::variants()))
        .arg(Arg::with_name("spp")
            .long("spp")
            .help("Sample per pixels")
            .default_value("4"))
        .get_matches()
}

fn configure_logger() {
    let log_path = "/tmp/rustracer.log";
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(log_path)
        .unwrap();

    let drain = slog_stream::stream(file, MyFormat).fuse();
    let log = Logger::root(drain, o!());
    slog_scope::set_global_logger(log);

}

trait HumanDisplay {
    fn human_display(&self) -> String;
}
impl HumanDisplay for std::time::Duration {
    fn human_display(&self) -> String {
        let mut hours = 0;
        let mut minutes = 0;
        let mut seconds = self.as_secs();
        if seconds >= 60 {
            seconds %= 60;
            minutes = seconds / 60;
        }
        if minutes >= 60 {
            minutes %= 60;
            hours = minutes / 60;
        }
        let millis = self.subsec_nanos() / 1000000;
        format!("{}:{}:{}.{}", hours, minutes, seconds, millis)
    }
}

macro_rules! now {
    () => ( Local::now().format("%m-%d %H:%M:%S%.3f") )
}

struct MyFormat;

impl slog_stream::Format for MyFormat {
    fn format(&self,
              io: &mut io::Write,
              rinfo: &slog::Record,
              _logger_values: &slog::OwnedKeyValueList)
              -> io::Result<()> {
        let msg = format!("{} [{}][{:x}][{}:{} {}] - {}\n",
                          now!(),
                          rinfo.level(),
                          thread_id::get(),
                          rinfo.file(),
                          rinfo.line(),
                          rinfo.module(),
                          rinfo.msg());
        let _ = try!(io.write_all(msg.as_bytes()));
        Ok(())
    }
}
<commit_msg>Tweak sample scene<commit_after>extern crate chrono;
extern crate nalgebra as na;
extern crate rustracer as rt;
#[macro_use]
extern crate clap;
extern crate rustc_serialize;
extern crate num_cpus;
#[macro_use(o, slog_info, slog_debug, slog_warn, slog_error, slog_trace, slog_log)]
extern crate slog;
#[macro_use]
extern crate slog_scope;
extern crate slog_stream;
extern crate thread_id;

use std::sync::Arc;
use std::num::ParseIntError;
use std::fs::OpenOptions;
use std::path::Path;
use std::io;
use std::process;

use chrono::Local;
use clap::{Arg, ArgMatches, App};
use slog::*;

use rt::bvh::BVH;
use rt::camera::Camera;
use rt::integrator::{SamplerIntegrator, Whitted, Normal, AmbientOcclusion};
use rt::light::{Light, DistantLight, DiffuseAreaLight};
use rt::material::matte::MatteMaterial;
use rt::material::metal::Metal;
use rt::material::plastic::Plastic;
use rt::primitive::{Primitive, GeometricPrimitive};
use rt::renderer;
use rt::scene::Scene;
use rt::shapes::disk::Disk;
use rt::shapes::sphere::Sphere;
use rt::spectrum::Spectrum;
use rt::transform;
use rt::{Transform, Point, Vector3f, Dim};

arg_enum! {
  #[derive(Debug)]
  enum SamplerIntegratorType {
      Whitted,
      Ao,
      Normal
  }
}

fn main() {
    // configure logger
    configure_logger();

    let matches = parse_args();
    if let Err(e) = run(matches) {
        println!("Application error: {}", e);
        process::exit(1);
    }
}

fn run(matches: ArgMatches) -> Result<(), String> {
    let parsed_dims: Result<Vec<u32>, ParseIntError> =
        matches.value_of("dim").unwrap().split('x').map(|s| s.parse::<u32>()).collect();
    let dims = parsed_dims.expect("Invalid dimensions");
    if dims.len() != 2 {
        panic!("Error: invalid dimension specification");
    }
    let dim = (dims[0], dims[1]);

    let integrator: Box<SamplerIntegrator + Send + Sync> =
        match value_t!(matches.value_of("integrator"), SamplerIntegratorType)
            .unwrap_or(SamplerIntegratorType::Whitted) {
            SamplerIntegratorType::Whitted => {
                info!("Using Whitted integrator with max ray depth of {}", 8);
                // Box::new(Whitted::new(args.flag_whitted_max_ray_depth))
                Box::new(Whitted::new(8))
            }
            SamplerIntegratorType::Ao => {
                info!("Using Ambient Occlusion integrator with {} samples", 32);
                Box::new(AmbientOcclusion::new(32))
            }
            SamplerIntegratorType::Normal => {
                info!("Using normal facing ratio integrator");
                Box::new(Normal {})
            }
        };

    let scene = build_scene(dim, integrator);

    let start_time = std::time::Instant::now();
    let stats =
        renderer::render(scene,
                         dim,
                         matches.value_of("output").unwrap(),
                         matches.value_of("threads")
                             .and_then(|s| s.parse::<usize>().ok())
                             .unwrap_or_else(num_cpus::get),
                         matches.value_of("spp").and_then(|s| s.parse::<usize>().ok()).unwrap(),
                         32);
    // args.flag_block_size);
    let duration = start_time.elapsed();
    println!("Render time                : {}", duration.human_display());
    println!("Primary rays               : {}", stats.primary_rays);
    println!("Secondary rays             : {}", stats.secondary_rays);
    println!("Num triangles              : {}", stats.triangles);
    println!("Ray-triangle tests         : {}", stats.ray_triangle_tests);
    println!("Ray-triangle intersections : {}", stats.ray_triangle_isect);
    println!("Fast bounding-box test     : {}", stats.fast_bbox_isect);

    Ok(())
}

fn build_scene(dim: Dim, integrator: Box<SamplerIntegrator + Send + Sync>) -> Scene {
    info!("Building scene");
    let camera = Camera::new(Point::new(0.0, 0.0, 5.0), dim, 50.0);
    let mut lights: Vec<Arc<Light + Send + Sync>> = Vec::new();

    let disk = Arc::new(Disk::new(-2.0, 0.8, 0.0, 360.0, transform::rot_x(90.0)));
    let area_light =
        Arc::new(DiffuseAreaLight::new(Spectrum::rgb(2.0, 2.0, 2.0), disk.clone(), 16));
    let area_light_prim = Box::new(GeometricPrimitive {
        shape: disk.clone(),
        area_light: Some(area_light.clone()),
        material: Some(Arc::new(MatteMaterial::default())),
    });

    let bronze = Arc::new(Metal::new());
    let plastic = Arc::new(Plastic::new(Spectrum::green(), Spectrum::white()));
    let plastic_lines = Arc::new(Plastic::new_tex("lines.png", Spectrum::white()));
    let sphere = Box::new(GeometricPrimitive {
        shape: Arc::new(Sphere::new().radius(0.7).transform(transform::rot(45.0, 45.0, 0.0))),
        area_light: None,
        // material: Some(Arc::new(Plastic::new(Spectrum::red(), Spectrum::white()))),
        // material: Some(Arc::new(Plastic::new_tex("lines.png", Spectrum::white()))),
        material: Some(bronze.clone()),
    });
    let bunny =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(&Path::new("models/bunny.obj"),
                                                           "bunny",
                                                           plastic.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(2.0, -0.8, 0.0),
                                                             Vector3f::new(0.0, 20.0f32.to_radians(), 0.0),
                                                             0.5
                                                             ))) as Box<Primitive + Send + Sync>;
    let buddha =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(&Path::new("models/buddha.obj"),
                                                           "buddha",
                                                           bronze.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(-2.0, -0.1, 0.0),
                                                             Vector3f::new(0.0, 200.0f32.to_radians(), 0.0),
                                                             3.0
                                                             ))) as Box<Primitive + Send + Sync>;
    let floor = Box::new(GeometricPrimitive {
        shape: Arc::new(Disk::new(-1.0, 20.0, 0.0, 360.0, transform::rot_x(-90.0))),
        area_light: None,
        // material: Some(Arc::new(MatteMaterial::checkerboard(0.0))),
        // material: Some(Arc::new(MatteMaterial::new(Spectrum::red(), 0.0))),
        material: Some(plastic_lines.clone()),
    });

    let primitives: Vec<Box<Primitive + Sync + Send>> =
        vec![buddha, sphere, bunny, floor, area_light_prim];
    // Light
    lights.push(area_light);
    lights.push(Arc::new(DistantLight::new(Vector3f::new(0.0, -1.0, -5.0),
                                           Spectrum::rgb(0.7, 0.7, 0.7))));

    Scene::new(camera, integrator, primitives, lights)
}

fn parse_args<'a>() -> ArgMatches<'a> {
    // TODO add block-size and ao-samples and whitted-max-ray? Or maybe not since eventually it
    // will be read from the scene file...
    App::new("rustracer")
        .version("0.1")
        .author("Antoine Bűsch")
        .about("Toy raytracer in Rust based on PBRTv3")
        .arg(Arg::with_name("output")
            .long("output")
            .short("o")
            .help("Output file name")
            .default_value("image.png"))
        .arg(Arg::with_name("threads")
            .long("threads")
            .short("t")
            .help("Number of worker threads"))
        .arg(Arg::with_name("dim")
            .long("dim")
            .short("d")
            .help("Dimension of the output image")
            .default_value("800x600"))
        .arg(Arg::with_name("integrator")
            .long("integrator")
            .short("i")
            .help("SamplerIntegrator to use")
            .possible_values(&SamplerIntegratorType::variants()))
        .arg(Arg::with_name("spp")
            .long("spp")
            .help("Sample per pixels")
            .default_value("4"))
        .get_matches()
}

fn configure_logger() {
    let log_path = "/tmp/rustracer.log";
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(log_path)
        .unwrap();

    let drain = slog_stream::stream(file, MyFormat).fuse();
    let log = Logger::root(drain, o!());
    slog_scope::set_global_logger(log);

}

trait HumanDisplay {
    fn human_display(&self) -> String;
}
impl HumanDisplay for std::time::Duration {
    fn human_display(&self) -> String {
        let mut hours = 0;
        let mut minutes = 0;
        let mut seconds = self.as_secs();
        if seconds >= 60 {
            seconds %= 60;
            minutes = seconds / 60;
        }
        if minutes >= 60 {
            minutes %= 60;
            hours = minutes / 60;
        }
        let millis = self.subsec_nanos() / 1000000;
        format!("{}:{}:{}.{}", hours, minutes, seconds, millis)
    }
}

macro_rules! now {
    () => ( Local::now().format("%m-%d %H:%M:%S%.3f") )
}

struct MyFormat;

impl slog_stream::Format for MyFormat {
    fn format(&self,
              io: &mut io::Write,
              rinfo: &slog::Record,
              _logger_values: &slog::OwnedKeyValueList)
              -> io::Result<()> {
        let msg = format!("{} [{}][{:x}][{}:{} {}] - {}\n",
                          now!(),
                          rinfo.level(),
                          thread_id::get(),
                          rinfo.file(),
                          rinfo.line(),
                          rinfo.module(),
                          rinfo.msg());
        let _ = try!(io.write_all(msg.as_bytes()));
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::collections::HashMap;
use std::env;

include!("./sentiment.rs");

// Gets a normalized nick from a log nick.
// - Removes beginning '+' and '@'
// - Removes trailing '_' and '-'
fn get_nick(s: &str) -> &str {
    let ignored_prefixes: &[_] = &['+', '@', ' '];
    let ignored_suffixes: &[_] = &['_', '-', ' '];

    return &s.trim_left_matches(ignored_prefixes)
        .trim_right_matches(ignored_suffixes);
}

fn main() {
    // Parse arguments.
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
       panic!("Usage: {} [log file name]", args[0]);
    }
    let path = args[1].clone();

    let f = match File::open(&path) {
        Err(why) => panic!("Couldn't open {}: {}", path, why),
        Ok(f) => f,
    };
    let f = BufReader::new(f);

    let mut result = HashMap::new();

    let analizer = sentiment::new("./src/wordlist.txt".to_string());

    let mut i = 0;

    for line in f.lines() {
        // Parse lines.
        let l = line.unwrap();
        let parts = l.split("\t").collect::<Vec<&str>>();
        let who = get_nick(parts[1]).to_string();

        // Skip ignored names.
        if ["*", "**", "***", "--", "---", "-->", "<--", "-", "", "<-", "=!=", "<"]
            .contains(&who.as_str()) {
            continue;
        }
        i = i + 1;

        // Calculate new comment value.
        let comment_value = analizer.analyze(parts[2]);
        let sum_comment_value = match result.get(&who) {
            Some(existing_comment_value) => existing_comment_value + comment_value,
            None => comment_value,
        };
        result.insert(who, sum_comment_value);
    }

    for (key, value) in result {
        print!("{} {}\n", key, value);
    }

    print!("\n{} lines analyzed.\n", i);
}
<commit_msg>Refactor lines parsing to use map() and fold()<commit_after>use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::collections::HashMap;
use std::env;

include!("./sentiment.rs");

// Gets a normalized nick from a log nick.
// - Removes beginning '+' and '@'
// - Removes trailing '_' and '-'
fn get_nick(s: &str) -> &str {
    let ignored_prefixes: &[_] = &['+', '@', ' '];
    let ignored_suffixes: &[_] = &['_', '-', ' '];

    return &s.trim_left_matches(ignored_prefixes)
        .trim_right_matches(ignored_suffixes);
}

fn main() {
    // Parse arguments.
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
       panic!("Usage: {} [log file name]", args[0]);
    }
    let path = args[1].clone();

    let f = match File::open(&path) {
        Err(why) => panic!("Couldn't open {}: {}", path, why),
        Ok(f) => f,
    };
    let f = BufReader::new(f);

    //let mut result = HashMap::new();

    let analizer = sentiment::new("./src/wordlist.txt".to_string());

    let result = f.lines().map(|line| {
        let line = line.expect("Couldn't parse line");

        let parts = line.split("\t").collect::<Vec<&str>>();
        let who = get_nick(parts[1]).to_string();
        let comment_value = analizer.analyze(parts[2]);

        return (who, comment_value);
    }).fold(HashMap::new(), |mut res, curr| {
        if ["*", "**", "***", "--", "---", "-->", "<--", "-", "", "<-", "=!=", "<"]
            .contains(&curr.0.as_str()) {
                return res;
            }

        let val = match res.get(&curr.0) {
            Some(existing_comment_value) => existing_comment_value + curr.1,
            None => curr.1,
        };

        res.insert(curr.0, val);
        return res;
    });

    for (key, value) in result {
        print!("{} {}\n", key, value);
    }

    //print!("\n{} lines analyzed.\n", i);
}
<|endoftext|>


<commit_before>extern crate bitstream_io;
extern crate byteorder;
extern crate libc;
extern crate rand;
extern crate y4m;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use bitstream_io::{BE, BitWriter};
use byteorder::*;

mod ec;
mod partition;
mod context;
mod transform;
mod quantize;
mod predict;

use context::*;
use partition::*;
use transform::*;
use quantize::*;
use predict::*;

struct Plane {
    data: Vec<u16>,
    stride: usize
}

#[allow(dead_code)]
impl Plane {
    pub fn new(width: usize, height: usize) -> Plane {
        Plane {
            data: vec![128; width*height],
            stride: width
        }
    }
    pub fn slice<'a>(&'a mut self, x: usize, y: usize) -> PlaneMutSlice<'a> {
        PlaneMutSlice {
            p: self,
            x: x,
            y: y
        }
    }
    pub fn p(&self, x: usize, y: usize) -> u16 {
        self.data[y*self.stride+x]
    }
}

#[allow(dead_code)]
struct PlaneMutSlice<'a> {
    p: &'a mut Plane,
    x: usize,
    y: usize
}

#[allow(dead_code)]
impl<'a> PlaneMutSlice<'a> {
    pub fn as_slice(&mut self) -> &mut [u16] {
        let stride = self.p.stride;
        &mut self.p.data[self.y*stride+self.x..]
    }
}

struct Frame {
    planes: [Plane; 3]
}

impl Frame {
    pub fn new(width: usize, height:usize) -> Frame {
        Frame {
            planes: [
                Plane::new(width, height),
                Plane::new(width/2, height/2),
                Plane::new(width/2, height/2)
            ]
        }
    }
}

struct Sequence {
    profile: u8
}

impl Sequence {
    pub fn new() -> Sequence {
        Sequence {
            profile: 0
        }
    }
}

struct FrameState {
    input: Frame,
    rec: Frame
}

impl FrameState {
    pub fn new(fi: &FrameInvariants) -> FrameState {
        FrameState {
            input: Frame::new(fi.sb_width*64, fi.sb_height*64),
            rec: Frame::new(fi.sb_width*64, fi.sb_height*64),
        }
    }
}

struct FrameInvariants {
    qindex: usize,
    width: usize,
    height: usize,
    sb_width: usize,
    sb_height: usize
}

impl FrameInvariants {
    pub fn new(width: usize, height: usize) -> FrameInvariants {
        FrameInvariants {
            qindex: 200,
            width: width,
            height: height,
            sb_width: (width+63)/64,
            sb_height: (height+63)/64,
        }
    }
}

// TODO: possibly just use bitwriter instead of byteorder
fn write_ivf_header(output_file: &mut File, width: usize, height: usize) {
    output_file.write(b"DKIF").unwrap();
    output_file.write_u16::<LittleEndian>(0).unwrap(); // version
    output_file.write_u16::<LittleEndian>(32).unwrap(); // header length
    output_file.write(b"AV10").unwrap();
    output_file.write_u16::<LittleEndian>(width as u16).unwrap();
    output_file.write_u16::<LittleEndian>(height as u16).unwrap();
    output_file.write_u32::<LittleEndian>(60).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
}

fn write_ivf_frame(output_file: &mut File, pts: u64, data: &[u8]) {
    output_file.write_u32::<LittleEndian>(data.len() as u32).unwrap();
    output_file.write_u64::<LittleEndian>(pts).unwrap();
    output_file.write(data).unwrap();
}

fn write_uncompressed_header(packet: &mut Write, sequence: &Sequence, fi: &FrameInvariants, compressed_len: u32) -> Result<(), std::io::Error> {
    let mut uch = BitWriter::<BE>::new(packet);
    uch.write(2,2)?; // frame type
    uch.write(2,sequence.profile)?; // profile 0
    uch.write_bit(false)?; // show_existing_frame=0
    uch.write_bit(false)?; // keyframe
    uch.write_bit(true)?; // show frame
    uch.write_bit(true)?; // error resilient
    uch.write(8+7,0)?; // frame id
    uch.write(8,0x49)?; // sync codes
    uch.write(8,0x83)?;
    uch.write(8,0x43)?;
    uch.write(3,0)?; // colorspace
    uch.write(1,0)?; // color range
    uch.write(16,(fi.width-1) as u16)?; // width
    uch.write(16,(fi.height-1) as u16)?; // height
    uch.write_bit(false)?; // scaling active
    uch.write_bit(false)?; // screen content tools
    uch.write(3,0x0)?; // frame context
    uch.write(6,0)?; // loop filter level
    uch.write(3,0)?; // loop filter sharpness
    uch.write_bit(false)?; // loop filter deltas enabled
    uch.write(1,0)?; // cdef dering damping
    uch.write(2,0)?; // cdef clpf damping
    uch.write(2,0)?; // cdef bits
    for _ in 0..1 {
        uch.write(7,127)?; // cdef y strength
        uch.write(7,0)?; // cdef uv strength
    }
    uch.write(8,fi.qindex as u8)?; // qindex
    uch.write_bit(false)?; // y dc delta q
    uch.write_bit(false)?; // uv dc delta q
    uch.write_bit(false)?; // uv ac delta q
    //uch.write_bit(false)?; // using qmatrix
    uch.write_bit(false)?; // segmentation off
    uch.write_bit(false)?; // no delta q
    uch.write_bit(false)?; // tx mode select
    uch.write(2,0)?; // only 4x4 transforms
    //uch.write_bit(false)?; // use hybrid pred
    //uch.write_bit(false)?; // use compound pred
    uch.write_bit(true)?; // reduced tx

    //uch.write(1,0)?; // tile cols
    uch.write(1,0)?; // tile rows
    uch.write_bit(true)?; // loop filter across tiles
    uch.write(2,0)?; // tile_size_bytes
    //println!("compressed header length: {}", compressed_len);
    uch.write(16,compressed_len)?; // compressed header length
    uch.byte_align()?;
    Ok(())
}

fn get_compressed_header() -> Vec<u8> {
    let mut h = Vec::new();
    let mut w = ec::Writer::new();
    // zero length compressed header is invalid, write 1 bit of garbage
    w.bool(false,1024);
    h.write(w.done()).unwrap();
    h
}

fn write_sb(cw: &mut ContextWriter, fi: &FrameInvariants, fs: &mut FrameState, sbx: usize, sby: usize) {
    cw.write_partition(PartitionType::PARTITION_NONE);
    cw.write_skip(false);
    cw.write_intra_mode(PredictionMode::DC_PRED);
    cw.write_intra_uv_mode(PredictionMode::DC_PRED);
    cw.write_tx_type(TxType::DCT_DCT);
    for p in 0..1 {
        let stride = fs.input.planes[0].stride;
        for by in 0..16 {
            for bx in 0..16 {
                let mut above = [0 as u16; 4];
                let mut left = [0 as u16; 4];
                match (sby, by) {
                    (0,0) => above = [127; 4],
                    _ => {
                        for i in 0..4 {
                            above[i] = fs.rec.planes[0].data[(sby*64+by*4-1)*stride+sbx*64+bx*4+i];
                        }
                    }
                }
                match (sbx, bx) {
                    (0,0) => left = [129; 4],
                    _ => {
                        for i in 0..4 {
                            left[i] = fs.rec.planes[0].data[(sby*64+by*4+i)*stride+sbx*64+bx*4-1];
                        }
                    }
                }
                match (sbx, bx, sby, by) {
                    (_,_,0,0) => pred_dc_left_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                    (0,0,_,_) => pred_dc_top_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                    _ => pred_dc_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                }
                let mut coeffs = [0 as i32; 16];
                let mut residual = [0 as i16; 16];
                for y in 0..4 {
                    for x in 0..4 {
                        residual[y*4+x] = fs.input.planes[0].data[(sby*64+by*4+y)*stride+sbx*64+bx*4+x] as i16 - fs.rec.planes[0].data[(sby*64+by*4+y)*stride+sbx*64+bx*4+x] as i16;
                    }
                }
                fdct4x4(&residual, &mut coeffs, 4);
                quantize_in_place(fi.qindex, &mut coeffs);
                cw.mc.set_loc(sbx*16+bx, sby*16+by);
                cw.write_coeffs(p, &coeffs);
                //reconstruct
                let mut rcoeffs = [0 as i32; 16];
                dequantize(fi.qindex, &coeffs, &mut rcoeffs);
                idct4x4_add(&mut rcoeffs, &mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride);
            }
        }
    }
    // chroma all zeroes
    for p in 1..3 {
        for by in 0..8 {
            for bx in 0..8 {
                cw.mc.set_loc(bx, by);
                cw.write_token_block_zero(p);
            }
        }
    }
}

fn encode_tile(fi: &FrameInvariants, fs: &mut FrameState) -> Vec<u8> {
    let mut h = Vec::new();
    let mut w = ec::Writer::new();
    let mut fc = CDFContext::new();
    let mut mc = MIContext::new(fi.sb_width*16, fi.sb_height*16);
    {
        let mut cw = ContextWriter {
            w: &mut w,
            fc: &mut fc,
            mc: &mut mc,
        };
        for sby in 0..fi.sb_height {
            cw.reset_left_coeff_context(0);
            for sbx in 0..fi.sb_width {
                write_sb(&mut cw, fi, fs, sbx, sby);
            }
        }
    }
    h.write(w.done()).unwrap();
    h.write(&[0]).unwrap(); // superframe anti emulation
    h
}

fn encode_frame(sequence: &Sequence, fi: &FrameInvariants, fs: &mut FrameState) -> Vec<u8> {
    let mut packet = Vec::new();
    let compressed_header = get_compressed_header();
    write_uncompressed_header(&mut packet, sequence, fi, compressed_header.len() as u32).unwrap();
    packet.write(&compressed_header).unwrap();
    let tile = encode_tile(fi, fs);
    packet.write(&tile).unwrap();
    packet
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut input_file = File::open(&args[1]).unwrap();
    let mut output_file = File::create(&args[2]).unwrap();
    let mut rec_file = File::create("rec.y4m").unwrap();
    let mut y4m_dec = y4m::decode(&mut input_file).unwrap();
    let width = y4m_dec.get_width();
    let height = y4m_dec.get_height();
    let sequence = Sequence::new();
    let mut y4m_enc = y4m::encode(width,height,y4m::Ratio::new(30,1)).write_header(&mut rec_file).unwrap();
    println!("Writing file");
    write_ivf_header(&mut output_file, width, height);
    let mut i = 0;
    loop {
        match y4m_dec.read_frame() {
            Ok(y4m_frame) => {
                let fi = FrameInvariants::new(width, height);
                let y4m_y = y4m_frame.get_y_plane();
                println!("Frame {}", i);
                let mut fs = FrameState::new(&fi);
                for y in 0..height {
                    for x in 0..width {
                        let stride = fs.input.planes[0].stride;
                        fs.input.planes[0].data[y*stride+x] = y4m_y[y*width+x] as u16;
                    }
                }
                let packet = encode_frame(&sequence, &fi, &mut fs);
                write_ivf_frame(&mut output_file, i, packet.as_ref());
                let mut rec_y = vec![128 as u8; width*height];
                let rec_u = vec![128 as u8; width*height/4];
                let rec_v = vec![128 as u8; width*height/4];
                for y in 0..height {
                    for x in 0..width {
                        let stride = fs.rec.planes[0].stride;
                        rec_y[y*width+x] = fs.rec.planes[0].data[y*stride+x] as u8;
                    }
                }
                let rec_frame = y4m::Frame::new([&rec_y, &rec_u, &rec_v], None);
                y4m_enc.write_frame(&rec_frame).unwrap();
                i += 1;
            },
            _ => break
        }
    }
}
<commit_msg>Pad frames out to multiples of superblock size.<commit_after>extern crate bitstream_io;
extern crate byteorder;
extern crate libc;
extern crate rand;
extern crate y4m;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use bitstream_io::{BE, BitWriter};
use byteorder::*;

mod ec;
mod partition;
mod context;
mod transform;
mod quantize;
mod predict;

use context::*;
use partition::*;
use transform::*;
use quantize::*;
use predict::*;

struct Plane {
    data: Vec<u16>,
    stride: usize
}

#[allow(dead_code)]
impl Plane {
    pub fn new(width: usize, height: usize) -> Plane {
        Plane {
            data: vec![128; width*height],
            stride: width
        }
    }
    pub fn slice<'a>(&'a mut self, x: usize, y: usize) -> PlaneMutSlice<'a> {
        PlaneMutSlice {
            p: self,
            x: x,
            y: y
        }
    }
    pub fn p(&self, x: usize, y: usize) -> u16 {
        self.data[y*self.stride+x]
    }
}

#[allow(dead_code)]
struct PlaneMutSlice<'a> {
    p: &'a mut Plane,
    x: usize,
    y: usize
}

#[allow(dead_code)]
impl<'a> PlaneMutSlice<'a> {
    pub fn as_slice(&mut self) -> &mut [u16] {
        let stride = self.p.stride;
        &mut self.p.data[self.y*stride+self.x..]
    }
}

struct Frame {
    planes: [Plane; 3]
}

impl Frame {
    pub fn new(width: usize, height:usize) -> Frame {
        Frame {
            planes: [
                Plane::new(width, height),
                Plane::new(width/2, height/2),
                Plane::new(width/2, height/2)
            ]
        }
    }
}

struct Sequence {
    profile: u8
}

impl Sequence {
    pub fn new() -> Sequence {
        Sequence {
            profile: 0
        }
    }
}

struct FrameState {
    input: Frame,
    rec: Frame
}

impl FrameState {
    pub fn new(fi: &FrameInvariants) -> FrameState {
        FrameState {
            input: Frame::new(fi.sb_width*64, fi.sb_height*64),
            rec: Frame::new(fi.sb_width*64, fi.sb_height*64),
        }
    }
}

#[allow(dead_code)]
struct FrameInvariants {
    qindex: usize,
    width: usize,
    height: usize,
    sb_width: usize,
    sb_height: usize
}

impl FrameInvariants {
    pub fn new(width: usize, height: usize) -> FrameInvariants {
        FrameInvariants {
            qindex: 200,
            width: width,
            height: height,
            sb_width: (width+63)/64,
            sb_height: (height+63)/64,
        }
    }
}

// TODO: possibly just use bitwriter instead of byteorder
fn write_ivf_header(output_file: &mut File, width: usize, height: usize) {
    output_file.write(b"DKIF").unwrap();
    output_file.write_u16::<LittleEndian>(0).unwrap(); // version
    output_file.write_u16::<LittleEndian>(32).unwrap(); // header length
    output_file.write(b"AV10").unwrap();
    output_file.write_u16::<LittleEndian>(width as u16).unwrap();
    output_file.write_u16::<LittleEndian>(height as u16).unwrap();
    output_file.write_u32::<LittleEndian>(60).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
    output_file.write_u32::<LittleEndian>(0).unwrap();
}

fn write_ivf_frame(output_file: &mut File, pts: u64, data: &[u8]) {
    output_file.write_u32::<LittleEndian>(data.len() as u32).unwrap();
    output_file.write_u64::<LittleEndian>(pts).unwrap();
    output_file.write(data).unwrap();
}

fn write_uncompressed_header(packet: &mut Write, sequence: &Sequence, fi: &FrameInvariants, compressed_len: u32) -> Result<(), std::io::Error> {
    let mut uch = BitWriter::<BE>::new(packet);
    uch.write(2,2)?; // frame type
    uch.write(2,sequence.profile)?; // profile 0
    uch.write_bit(false)?; // show_existing_frame=0
    uch.write_bit(false)?; // keyframe
    uch.write_bit(true)?; // show frame
    uch.write_bit(true)?; // error resilient
    uch.write(8+7,0)?; // frame id
    uch.write(8,0x49)?; // sync codes
    uch.write(8,0x83)?;
    uch.write(8,0x43)?;
    uch.write(3,0)?; // colorspace
    uch.write(1,0)?; // color range
    uch.write(16,(fi.sb_width*64-1) as u16)?; // width
    uch.write(16,(fi.sb_height*64-1) as u16)?; // height
    uch.write_bit(false)?; // scaling active
    uch.write_bit(false)?; // screen content tools
    uch.write(3,0x0)?; // frame context
    uch.write(6,0)?; // loop filter level
    uch.write(3,0)?; // loop filter sharpness
    uch.write_bit(false)?; // loop filter deltas enabled
    uch.write(1,0)?; // cdef dering damping
    uch.write(2,0)?; // cdef clpf damping
    uch.write(2,0)?; // cdef bits
    for _ in 0..1 {
        uch.write(7,127)?; // cdef y strength
        uch.write(7,0)?; // cdef uv strength
    }
    uch.write(8,fi.qindex as u8)?; // qindex
    uch.write_bit(false)?; // y dc delta q
    uch.write_bit(false)?; // uv dc delta q
    uch.write_bit(false)?; // uv ac delta q
    //uch.write_bit(false)?; // using qmatrix
    uch.write_bit(false)?; // segmentation off
    uch.write_bit(false)?; // no delta q
    uch.write_bit(false)?; // tx mode select
    uch.write(2,0)?; // only 4x4 transforms
    //uch.write_bit(false)?; // use hybrid pred
    //uch.write_bit(false)?; // use compound pred
    uch.write_bit(true)?; // reduced tx

    //uch.write(1,0)?; // tile cols
    uch.write(1,0)?; // tile rows
    uch.write_bit(true)?; // loop filter across tiles
    uch.write(2,0)?; // tile_size_bytes
    //println!("compressed header length: {}", compressed_len);
    uch.write(16,compressed_len)?; // compressed header length
    uch.byte_align()?;
    Ok(())
}

fn get_compressed_header() -> Vec<u8> {
    let mut h = Vec::new();
    let mut w = ec::Writer::new();
    // zero length compressed header is invalid, write 1 bit of garbage
    w.bool(false,1024);
    h.write(w.done()).unwrap();
    h
}

fn write_sb(cw: &mut ContextWriter, fi: &FrameInvariants, fs: &mut FrameState, sbx: usize, sby: usize) {
    cw.write_partition(PartitionType::PARTITION_NONE);
    cw.write_skip(false);
    cw.write_intra_mode(PredictionMode::DC_PRED);
    cw.write_intra_uv_mode(PredictionMode::DC_PRED);
    cw.write_tx_type(TxType::DCT_DCT);
    for p in 0..1 {
        let stride = fs.input.planes[0].stride;
        for by in 0..16 {
            for bx in 0..16 {
                let mut above = [0 as u16; 4];
                let mut left = [0 as u16; 4];
                match (sby, by) {
                    (0,0) => above = [127; 4],
                    _ => {
                        for i in 0..4 {
                            above[i] = fs.rec.planes[0].data[(sby*64+by*4-1)*stride+sbx*64+bx*4+i];
                        }
                    }
                }
                match (sbx, bx) {
                    (0,0) => left = [129; 4],
                    _ => {
                        for i in 0..4 {
                            left[i] = fs.rec.planes[0].data[(sby*64+by*4+i)*stride+sbx*64+bx*4-1];
                        }
                    }
                }
                match (sbx, bx, sby, by) {
                    (_,_,0,0) => pred_dc_left_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                    (0,0,_,_) => pred_dc_top_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                    _ => pred_dc_4x4(&mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride, &above, &left),
                }
                let mut coeffs = [0 as i32; 16];
                let mut residual = [0 as i16; 16];
                for y in 0..4 {
                    for x in 0..4 {
                        residual[y*4+x] = fs.input.planes[0].data[(sby*64+by*4+y)*stride+sbx*64+bx*4+x] as i16 - fs.rec.planes[0].data[(sby*64+by*4+y)*stride+sbx*64+bx*4+x] as i16;
                    }
                }
                fdct4x4(&residual, &mut coeffs, 4);
                quantize_in_place(fi.qindex, &mut coeffs);
                cw.mc.set_loc(sbx*16+bx, sby*16+by);
                cw.write_coeffs(p, &coeffs);
                //reconstruct
                let mut rcoeffs = [0 as i32; 16];
                dequantize(fi.qindex, &coeffs, &mut rcoeffs);
                idct4x4_add(&mut rcoeffs, &mut fs.rec.planes[0].data[(sby*64+by*4)*stride+sbx*64+bx*4..fi.sb_width*fi.sb_height*64*64], stride);
            }
        }
    }
    // chroma all zeroes
    for p in 1..3 {
        for by in 0..8 {
            for bx in 0..8 {
                cw.mc.set_loc(bx, by);
                cw.write_token_block_zero(p);
            }
        }
    }
}

fn encode_tile(fi: &FrameInvariants, fs: &mut FrameState) -> Vec<u8> {
    let mut h = Vec::new();
    let mut w = ec::Writer::new();
    let mut fc = CDFContext::new();
    let mut mc = MIContext::new(fi.sb_width*16, fi.sb_height*16);
    {
        let mut cw = ContextWriter {
            w: &mut w,
            fc: &mut fc,
            mc: &mut mc,
        };
        for sby in 0..fi.sb_height {
            cw.reset_left_coeff_context(0);
            for sbx in 0..fi.sb_width {
                write_sb(&mut cw, fi, fs, sbx, sby);
            }
        }
    }
    h.write(w.done()).unwrap();
    h.write(&[0]).unwrap(); // superframe anti emulation
    h
}

fn encode_frame(sequence: &Sequence, fi: &FrameInvariants, fs: &mut FrameState) -> Vec<u8> {
    let mut packet = Vec::new();
    let compressed_header = get_compressed_header();
    write_uncompressed_header(&mut packet, sequence, fi, compressed_header.len() as u32).unwrap();
    packet.write(&compressed_header).unwrap();
    let tile = encode_tile(fi, fs);
    packet.write(&tile).unwrap();
    packet
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut input_file = File::open(&args[1]).unwrap();
    let mut output_file = File::create(&args[2]).unwrap();
    let mut rec_file = File::create("rec.y4m").unwrap();
    let mut y4m_dec = y4m::decode(&mut input_file).unwrap();
    let width = y4m_dec.get_width();
    let height = y4m_dec.get_height();
    let sequence = Sequence::new();
    let mut y4m_enc = y4m::encode(width,height,y4m::Ratio::new(30,1)).write_header(&mut rec_file).unwrap();
    println!("Writing file");
    let fi = FrameInvariants::new(width, height);
    write_ivf_header(&mut output_file, fi.sb_width*64, fi.sb_height*64);
    let mut i = 0;
    loop {
        match y4m_dec.read_frame() {
            Ok(y4m_frame) => {
                let y4m_y = y4m_frame.get_y_plane();
                println!("Frame {}", i);
                let mut fs = FrameState::new(&fi);
                for y in 0..height {
                    for x in 0..width {
                        let stride = fs.input.planes[0].stride;
                        fs.input.planes[0].data[y*stride+x] = y4m_y[y*width+x] as u16;
                    }
                }
                let packet = encode_frame(&sequence, &fi, &mut fs);
                write_ivf_frame(&mut output_file, i, packet.as_ref());
                let mut rec_y = vec![128 as u8; width*height];
                let rec_u = vec![128 as u8; width*height/4];
                let rec_v = vec![128 as u8; width*height/4];
                for y in 0..height {
                    for x in 0..width {
                        let stride = fs.rec.planes[0].stride;
                        rec_y[y*width+x] = fs.rec.planes[0].data[y*stride+x] as u8;
                    }
                }
                let rec_frame = y4m::Frame::new([&rec_y, &rec_u, &rec_v], None);
                y4m_enc.write_frame(&rec_frame).unwrap();
                i += 1;
            },
            _ => break
        }
    }
}
<|endoftext|>


<commit_before>//! Doc placeholder

extern crate opencl;
extern crate sdl2;

use sdl2::keyboard::Keycode;
use sdl2::pixels::{self, Color};
use sdl2::rect::Rect;

const KERNEL_SOURCE: &'static str = r"
__kernel void multiply_by_scalar(__global float const* const src_buf,
                                 __private float const coeff,
                                 __global float* dst_buf) {
    uint i = get_global_id(0);
    dst_buf[i] = src_buf[i] * coeff;
}
";

fn init_kernel() {
    let (device, ctx, queue) = opencl::util::create_compute_context()
                                   .expect("Could not initialise OpenCL");
    const COEFF: f32 = 5.4321;

    let vec_src = vec![1.0f32, 2.0, 3.0, 4.0, 5.0];

    let cl_src_buf = ctx.create_buffer::<f32>(vec_src.len(), opencl::cl::CL_MEM_READ_ONLY);
    let cl_dst_buf = ctx.create_buffer::<f32>(vec_src.len(), opencl::cl::CL_MEM_WRITE_ONLY);

    queue.write(&cl_src_buf, &&vec_src[..], ());

    let program = {
        let p = ctx.create_program_from_source(KERNEL_SOURCE);
        p.build(&device).expect("Could not build program");
        p
    };

    let kernel = program.create_kernel("multiply_by_scalar");
    kernel.set_arg(0, &cl_src_buf);
    kernel.set_arg(1, &COEFF);
    kernel.set_arg(2, &cl_dst_buf);

    let event = queue.enqueue_async_kernel(&kernel, vec_src.len(), None, ());

    let vec_dst: Vec<f32> = queue.get(&cl_dst_buf, &event);

    println!("  {:?}", &vec_src[..]);
    println!("* {:?}", COEFF);
    println!("= {:?}", &vec_dst[..]);
}

fn main() {
    init_kernel();

    let sdl = sdl2::init().expect("Could not intialise SDL library");
    let mut renderer = sdl.video()
                          .expect("Could not initialise video")
                          .window("mandlebrot", 800, 600)
                          .position_centered()
                          .build()
                          .expect("Could not create a window from the video subsystem")
                          .renderer()
                          .accelerated()
                          .present_vsync()
                          .target_texture()
                          .build()
                          .expect("Could not get renderer from window");

    renderer.set_draw_color(Color::RGB(255, 0, 0));

    let sz = renderer.window().map(|w| w.size()).unwrap_or((0, 0));
    let mut tex = renderer.create_texture_streaming(pixels::PixelFormatEnum::ARGB8888, sz).unwrap();

    let mut events = sdl.event_pump().expect("Could not initialise events");

    'mainloop: loop {
        for e in events.poll_iter() {
            use sdl2::event::Event;
            match e {
                Event::Quit {..} |
                Event::KeyDown {keycode: Some(Keycode::Escape), ..} => break 'mainloop,
                _ => {}
            }
        }
        renderer.clear();

        tex.with_lock(None, |pixels, pitch| {
               let (mut row, mut col) = (1, 1);
               for pixel in pixels {
                   if col >= pitch {
                       row += 1;
                       col = 1;
                   } else {
                       col += 1;
                   }
                   *pixel = (row * col) as u8;
               }
           })
           .expect("Could not write pixels to screen texture");

        renderer.copy(&tex, None, Some(Rect::new_unwrap(0, 0, 800, 600)));

        renderer.present();
    }
}
<commit_msg>Use the sz variable for deciding how much of the texture to copy to the renderer<commit_after>//! Doc placeholder

extern crate opencl;
extern crate sdl2;

use sdl2::keyboard::Keycode;
use sdl2::pixels::{self, Color};
use sdl2::rect::Rect;

const KERNEL_SOURCE: &'static str = r"
__kernel void multiply_by_scalar(__global float const* const src_buf,
                                 __private float const coeff,
                                 __global float* dst_buf) {
    uint i = get_global_id(0);
    dst_buf[i] = src_buf[i] * coeff;
}
";

fn init_kernel() {
    let (device, ctx, queue) = opencl::util::create_compute_context()
                                   .expect("Could not initialise OpenCL");
    const COEFF: f32 = 5.4321;

    let vec_src = vec![1.0f32, 2.0, 3.0, 4.0, 5.0];

    let cl_src_buf = ctx.create_buffer::<f32>(vec_src.len(), opencl::cl::CL_MEM_READ_ONLY);
    let cl_dst_buf = ctx.create_buffer::<f32>(vec_src.len(), opencl::cl::CL_MEM_WRITE_ONLY);

    queue.write(&cl_src_buf, &&vec_src[..], ());

    let program = {
        let p = ctx.create_program_from_source(KERNEL_SOURCE);
        p.build(&device).expect("Could not build program");
        p
    };

    let kernel = program.create_kernel("multiply_by_scalar");
    kernel.set_arg(0, &cl_src_buf);
    kernel.set_arg(1, &COEFF);
    kernel.set_arg(2, &cl_dst_buf);

    let event = queue.enqueue_async_kernel(&kernel, vec_src.len(), None, ());

    let vec_dst: Vec<f32> = queue.get(&cl_dst_buf, &event);

    println!("  {:?}", &vec_src[..]);
    println!("* {:?}", COEFF);
    println!("= {:?}", &vec_dst[..]);
}

fn main() {
    init_kernel();

    let sdl = sdl2::init().expect("Could not intialise SDL library");
    let mut renderer = sdl.video()
                          .expect("Could not initialise video")
                          .window("mandlebrot", 800, 600)
                          .position_centered()
                          .build()
                          .expect("Could not create a window from the video subsystem")
                          .renderer()
                          .accelerated()
                          .present_vsync()
                          .target_texture()
                          .build()
                          .expect("Could not get renderer from window");

    renderer.set_draw_color(Color::RGB(255, 0, 0));

    let sz = renderer.window().map(|w| w.size()).unwrap_or((0, 0));
    let mut tex = renderer.create_texture_streaming(pixels::PixelFormatEnum::ARGB8888, sz).unwrap();

    let mut events = sdl.event_pump().expect("Could not initialise events");

    'mainloop: loop {
        for e in events.poll_iter() {
            use sdl2::event::Event;
            match e {
                Event::Quit {..} |
                Event::KeyDown {keycode: Some(Keycode::Escape), ..} => break 'mainloop,
                _ => {}
            }
        }
        renderer.clear();

        tex.with_lock(None, |pixels, pitch| {
               let (mut row, mut col) = (1, 1);
               for pixel in pixels {
                   if col >= pitch {
                       row += 1;
                       col = 1;
                   } else {
                       col += 1;
                   }
                   *pixel = (row * col) as u8;
               }
           })
           .expect("Could not write pixels to screen texture");

        renderer.copy(&tex, None, Some(Rect::new_unwrap(0, 0, sz.0, sz.1)));

        renderer.present();
    }
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate serde_json;

use iron::prelude::*;
use iron::status;

mod user;

fn main() {
    fn hello_world(_: &mut Request) -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello, world!")))
    }

    println!("Starting up...");
    Iron::new(hello_world).http("localhost:3000").unwrap();
}
<commit_msg>Change to port 8344<commit_after>extern crate iron;
extern crate serde_json;

use iron::prelude::*;
use iron::status;

mod user;

fn main() {
    fn hello_world(_: &mut Request) -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello, world!")))
    }

    println!("Starting on port 8344...");
    Iron::new(hello_world).http("localhost:8344").unwrap();
}
<|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 };
}

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 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) {
    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 jar = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar.flush().unwrap();
}

fn exec_runner<S: AsRef<OsStr>>(args: &[S]) {
    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)
}

struct App<'a> {
           verbose: bool,
          java_cmd: &'a OsStr,
    extra_jvm_opts: Vec<&'a OsStr>,
         java_args: Vec<&'a OsStr>,
      sbt_commands: Vec<&'a OsStr>,
     residual_args: Vec<&'a OsStr>,
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
                 verbose: Default::default(),
                java_cmd: "java".as_ref(),
          extra_jvm_opts: vec!["-Xms512m".as_ref(), "-Xmx1536m".as_ref(), "-Xss2m".as_ref()],
               java_args: Default::default(),
            sbt_commands: Default::default(),
           residual_args: Default::default(),
        }
    }

    fn vlog(&self, s: &str) { if self.verbose { echoerr!("{}", s); } }

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

    fn run(&mut self) {
        let script_name = std::env::args().nth(0).unwrap();
        let script_name = Path::new(&script_name).file_name().unwrap().to_str().unwrap();

        for arg in std::env::args().skip(1) {
            match arg.as_ref() {
                "-v" => self.verbose = true,
                s    => panic!("fu"),
                // s    => self.add_residual(&s),
            }
        }

        let argument_count = std::env::args().len();
        if argument_count > 0 {
            self.vlog(&format!("Starting {}: invoke with -help for other options", script_name));
            self.residual_args = vec!["shell".as_ref()];
        }

        let sbt_version = build_props_sbt();
        let mut sbt_jar = jar_file(&sbt_version);
        if !sbt_jar.exists() {
            sbt_jar = PathBuf::from(&*HOME);
            sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", sbt_version));
        }
        if !sbt_jar.exists() {
            sbt_jar = jar_file(&sbt_version);
            download_url(&sbt_version, &make_url(&sbt_version), &sbt_jar);
        }
        let sbt_jar = sbt_jar.as_path();

        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(), 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());

        exec_runner(&exec_args)
    }
}

fn main() {
    App::new().run()
}
<commit_msg>Move script_name to lazy_static<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 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) {
    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 jar = std::io::BufWriter::new(File::create(jar).unwrap());
    while {
        let bc = r.read(&mut buf).unwrap();
        jar.write(&buf[0..bc]).unwrap();
        bc > 0
    } {}
    jar.flush().unwrap();
}

fn exec_runner<S: AsRef<OsStr>>(args: &[S]) {
    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)
}

struct App<'a> {
           verbose: bool,
          java_cmd: &'a OsStr,
    extra_jvm_opts: Vec<&'a OsStr>,
         java_args: Vec<&'a OsStr>,
      sbt_commands: Vec<&'a OsStr>,
     residual_args: Vec<&'a OsStr>,
}

impl<'a> App<'a> {
    fn new() -> App<'a> {
        App {
                 verbose: Default::default(),
                java_cmd: "java".as_ref(),
          extra_jvm_opts: vec!["-Xms512m".as_ref(), "-Xmx1536m".as_ref(), "-Xss2m".as_ref()],
               java_args: Default::default(),
            sbt_commands: Default::default(),
           residual_args: Default::default(),
        }
    }

    fn vlog(&self, s: &str) { if self.verbose { echoerr!("{}", s); } }

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

    fn run(&mut self) {
        for arg in std::env::args().skip(1) {
            match arg.as_ref() {
                "-v" => self.verbose = true,
                s    => panic!("fu"), // self.add_residual(&s),
            }
        }

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

        let sbt_version = build_props_sbt();
        let mut sbt_jar = jar_file(&sbt_version);
        if !sbt_jar.exists() {
            sbt_jar = PathBuf::from(&*HOME);
            sbt_jar.push(format!(".ivy2/local/org.scala-sbt/sbt-launch/{}/jars/sbt-launch.jar", sbt_version));
        }
        if !sbt_jar.exists() {
            sbt_jar = jar_file(&sbt_version);
            download_url(&sbt_version, &make_url(&sbt_version), &sbt_jar);
        }
        let sbt_jar = sbt_jar.as_path();

        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(), 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());

        exec_runner(&exec_args)
    }
}

fn main() {
    App::new().run()
}
<|endoftext|>