<commit_before>/*
 *  This source code is subject to the terms of the 2-clause BSD license (FreeBSD License).
 *  If a copy of the 2-clause BSD license was not included with this file,
 *  you can refer to http://en.wikipedia.org/wiki/BSD_licenses#2-clause_license_.28.22Simplified_BSD_License.22_or_.22FreeBSD_License.22.29
 *  or http://opensource.org/licenses/BSD-2-Clause
 * */

#![feature(fs_walk)]
#![feature(path_ext)]

extern crate rustc_serialize;

use std::env;
use std::process;
use std::fs;
use std::path::Path;
use std::fs::PathExt;
use std::fs::File;
use std::io::Write;
use std::io::Read;

use rustc_serialize::json;

const URL : &'static str = "http://uguu.se/api.php?d=upload";

#[derive(RustcDecodable, RustcEncodable)]
pub struct Config {
    links: bool,
}

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

    let config = first_run();

    if args.len() == 1 {
        panic!("\n\n    Not enough arguments were supplied!\n\n")
    }

    handle_arguments(args, config);
}

fn first_run() -> Config {
    let home = env::home_dir().unwrap();
    let home_dir = Path::new(&home);

    let config_dir = home_dir.join(".uguupload");
    let config_dir_path = Path::new(&config_dir);

    let config_file = config_dir.join("uguuconfig");

    if config_dir_path.is_dir() == false {
        // Create the initial config file
        match fs::create_dir(config_dir_path) {
            Ok(_)   => (),
            Err(e)  => panic!("Failed to create ~/.uguupload! Error: {}", e),
        }

        let default_config = Config {
            links: false,
        };

        let config_file = File::create(config_dir_path.join("uguuconfig"));

        config_file.unwrap().write_all(json::encode(&default_config).unwrap().as_bytes());
    }

    // Load the config file
    let mut boop = File::open(&config_file).unwrap();
    let mut output_from_config = "".to_string();

    let content = match File::read_to_string(&mut boop, &mut output_from_config) {
        Ok(o)   => o,
        Err(e)  => panic!("HELP: {}", e),
    };

    let current_config: Config = json::decode(&output_from_config).unwrap();

    return current_config;
}

fn handle_arguments(args: Vec<String>, config: Config) {
    // Handles command-line arguments

    let arg = args[1].clone();

    match arg.as_ref() {
        "-h"  | "--help"        => help(),
        "-f"  | "--filename"    => upload_f(args, config),
        "-r"  | "--random"      => upload_r(args, config),
        "-d"  | "--dir"         => upload_d(args, config),
        "-dr" | "--dir-rec"     => upload_dr(args, config),
        _                       => upload_n(args, config),
    }
}

fn upload(f: &String, file: String, filename: String, random: bool, config: &Config) {
    // Handles the uploading of files.

    let mut curl = process::Command::new("curl");
            curl.args(&["-F", filename.as_ref()]);
            curl.args(&["-F", file.as_ref()]);
            if random == true {
                curl.args(&["-F", "randomname=true"]);
            }
            curl.arg(URL);

    match curl.output() {
        Ok(r)   => {
            if String::from_utf8_lossy(r.stdout.as_ref()) == "" {
                println!("Failed to upload: {}", f);
            } else {
                if config.links == true {
                    println!("{}", String::from_utf8_lossy(r.stdout.as_ref()));
                } else {
                    println!("{}\n{}", f, String::from_utf8_lossy(r.stdout.as_ref()));
                }
            }
        },
        Err(e)  => panic!("Failed to upload: {}", e),
    }
}

fn upload_n(args: Vec<String>, config: Config) {
    // NORMAL
    // Handles what files should be uploaded along with what filename the file should have.

    let files = &args[1..args.len()];

    for f in files {
        let filename = format!("name={}", f);
        let file = format!("file=@{}", f);

        upload(f, file, filename, false, &config);
    }
}

fn upload_f(args: Vec<String>, config: Config) {
    // FILENAME
    // Handles what files should be uploaded along with that filename the file should have.
    // -f was used here.
    let files = &args[2..args.len()];
    let mut counter = 0;

    for x in 0..files.len() {
        if x + 1 + counter < files.len() {
            let filename = format!("name={}", files[x + 1 + counter]);
            let file = format!("file=@{}", files[x + counter]);

            upload(&files[x + counter], file, filename, false, &config);
        }

        counter += 1;
    }
}

fn upload_r(args: Vec<String>, config: Config) {
    // RANDOM
    // Handles what files should be uploaded. Filenames are random.
    // -r was used here
    let files = &args[2..args.len()];

    for f in files {
        let filename = format!("name={}", f);
        let file = format!("file=@{}", f);

        upload(f, file, filename, true, &config);
    }
}

fn upload_d(args: Vec<String>, config: Config) {
    // DIRECTORY
    // Handles what files in the directory should be uploaded.
    // -d was used here.

    let directories = &args[2..args.len()];

    for d in directories {
        let path = Path::new(d);
        let mut fls: Vec<_> = vec!();

        if path.is_dir() == true {
            match fs::read_dir(&path) {
                Err(why) => println!("! {:?}", why.kind()),
                Ok(paths) => for path in paths {
                    fls.push(path.unwrap().path());
                },
            }

            for x in fls {
                let filename_processed = x.as_path().file_name().unwrap().to_str().unwrap().to_string();
                let file_processed = x.as_path().to_str().unwrap().to_string();

                let filename = format!("name={}", filename_processed);
                let file = format!("file=@{}", file_processed);

                upload(&file_processed, file, filename, false, &config);
            }
        }
    }
}

fn upload_dr(args: Vec<String>, config: Config) {
    // DIRECTORY
    // Handles what files in the directory should be uploaded.
    // -d was used here.

    let directories = &args[2..args.len()];

    for d in directories {
        let path = Path::new(d);
        let mut fls: Vec<_> = vec!();

        if path.is_dir() == true {
            match fs::walk_dir(&path) {
                Err(why) => println!("! {:?}", why.kind()),
                Ok(paths) => for path in paths {
                    fls.push(path.unwrap().path());
                },
            }

            for x in fls {
                let filename_processed = x.as_path().file_name().unwrap().to_str().unwrap().to_string();
                let file_processed = x.as_path().to_str().unwrap().to_string();

                let filename = format!("name={}", filename_processed);
                let file = format!("file=@{}", file_processed);

                upload(&file_processed, file, filename, false, &config);
            }
        }
    }
}

fn help() {
    println!("Usage: ./uguupload [option] [FILE]

[FILE] is the path to the file you want to upload.

OPTIONS
    -h, --help
        Prints out this help message.

    -f, --filename
        Allows you to specify custom filenames for files.
        See Example 2.

    -r, --random
        Gives files random filenames.
        See Example 3.

    -d, --dir
        Uploads everything in the specified directory.
        This is not recursive.
        See Example 4.

    -dr, --dir-rec
        Uploads everything in the specified directory.
        This is recursive. Files in sub-directories will be uploaded.
        See Example 4. This works exactly like -d.

EXAMPLES
    Example 1:
        ./uguupload [FILE]
        ./uguupload foo.txt

        You can also upload several files.
        ./uguupload foo.txt bar.txt foobar.txt

    Example 2:
        ./uguupload -f [FILE] [FILENAME]
        ./uguupload -f foo.txt foo.txt bar.txt foo.txt foobar.txt foo.txt

        The first argument, foo.txt is the filename and the second argument, foo.txt, is the file and so on.
        bar.txt is the filename and foo.txt is the file. Same for foobar.txt and foo.txt

    Example 3:
        ./uguupload -r [FILE]
        ./uguupload -r foo.txt

        This will return http://a.uguu.se/asdfghjkl.ext where .ext is the file extension/type

    Example 4:
        ./uguupload -d [DIRECTORY]
        This will upload everything in the specified directory. You can add several directories");

    return;
}
<commit_msg>Fixed the --help flag and changed the name of the config file.<commit_after>/*
 *  This source code is subject to the terms of the 2-clause BSD license (FreeBSD License).
 *  If a copy of the 2-clause BSD license was not included with this file,
 *  you can refer to http://en.wikipedia.org/wiki/BSD_licenses#2-clause_license_.28.22Simplified_BSD_License.22_or_.22FreeBSD_License.22.29
 *  or http://opensource.org/licenses/BSD-2-Clause
 * */

#![feature(fs_walk)]
#![feature(path_ext)]

extern crate rustc_serialize;

use std::env;
use std::process;
use std::fs;
use std::path::Path;
use std::fs::PathExt;
use std::fs::File;
use std::io::Write;
use std::io::Read;

use rustc_serialize::json;

const URL : &'static str = "http://uguu.se/api.php?d=upload";

#[derive(RustcDecodable, RustcEncodable)]
pub struct Config {
    links_only: bool,
}

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

    let config = first_run();

    if args.len() == 1 {
        panic!("\n\n    Not enough arguments were supplied!\n\n")
    }

    handle_arguments(args, config);
}

fn first_run() -> Config {
    let home = env::home_dir().unwrap();
    let home_dir = Path::new(&home);

    let config_dir = home_dir.join(".uguupload");
    let config_dir_path = Path::new(&config_dir);

    let config_file = config_dir.join("config");

    if config_dir_path.is_dir() == false {
        // Create the initial config file
        match fs::create_dir(config_dir_path) {
            Ok(_)   => (),
            Err(e)  => panic!("Failed to create ~/.uguupload! Error: {}", e),
        }

        let default_config = Config {
            links_only: false,
        };

        let conf_file = File::create(&config_file);

        conf_file.unwrap().write_all(json::encode(&default_config).unwrap().as_bytes());
    }

    // Load the config file
    let mut boop = File::open(&config_file).unwrap();
    let mut output_from_config = "".to_string();

    let content = match File::read_to_string(&mut boop, &mut output_from_config) {
        Ok(o)   => o,
        Err(e)  => panic!("HELP: {}", e),
    };

    let current_config: Config = json::decode(&output_from_config).unwrap();

    return current_config;
}

fn handle_arguments(args: Vec<String>, config: Config) {
    // Handles command-line arguments

    let arg = args[1].clone();

    match arg.as_ref() {
        "-h"  | "--help"        => help(),
        "-f"  | "--filename"    => upload_f(args, config),
        "-r"  | "--random"      => upload_r(args, config),
        "-d"  | "--dir"         => upload_d(args, config),
        "-dr" | "--dir-rec"     => upload_dr(args, config),
        _                       => upload_n(args, config),
    }
}

fn upload(f: &String, file: String, filename: String, random: bool, config: &Config) {
    // Handles the uploading of files.

    let mut curl = process::Command::new("curl");
            curl.args(&["-F", filename.as_ref()]);
            curl.args(&["-F", file.as_ref()]);
            if random == true {
                curl.args(&["-F", "randomname=true"]);
            }
            curl.arg(URL);

    match curl.output() {
        Ok(r)   => {
            if String::from_utf8_lossy(r.stdout.as_ref()) == "" {
                println!("Failed to upload: {}", f);
            } else {
                if config.links_only == true {
                    println!("{}", String::from_utf8_lossy(r.stdout.as_ref()));
                } else {
                    println!("{}\n{}", f, String::from_utf8_lossy(r.stdout.as_ref()));
                }
            }
        },
        Err(e)  => panic!("Failed to upload: {}", e),
    }
}

fn upload_n(args: Vec<String>, config: Config) {
    // NORMAL
    // Handles what files should be uploaded along with what filename the file should have.

    let files = &args[1..args.len()];

    for f in files {
        let filename = format!("name={}", f);
        let file = format!("file=@{}", f);

        upload(f, file, filename, false, &config);
    }
}

fn upload_f(args: Vec<String>, config: Config) {
    // FILENAME
    // Handles what files should be uploaded along with that filename the file should have.
    // -f was used here.
    let files = &args[2..args.len()];
    let mut counter = 0;

    for x in 0..files.len() {
        if x + 1 + counter < files.len() {
            let filename = format!("name={}", files[x + 1 + counter]);
            let file = format!("file=@{}", files[x + counter]);

            upload(&files[x + counter], file, filename, false, &config);
        }

        counter += 1;
    }
}

fn upload_r(args: Vec<String>, config: Config) {
    // RANDOM
    // Handles what files should be uploaded. Filenames are random.
    // -r was used here
    let files = &args[2..args.len()];

    for f in files {
        let filename = format!("name={}", f);
        let file = format!("file=@{}", f);

        upload(f, file, filename, true, &config);
    }
}

fn upload_d(args: Vec<String>, config: Config) {
    // DIRECTORY
    // Handles what files in the directory should be uploaded.
    // -d was used here.

    let directories = &args[2..args.len()];

    for d in directories {
        let path = Path::new(d);
        let mut fls: Vec<_> = vec!();

        if path.is_dir() == true {
            match fs::read_dir(&path) {
                Err(why) => println!("! {:?}", why.kind()),
                Ok(paths) => for path in paths {
                    fls.push(path.unwrap().path());
                },
            }

            for x in fls {
                let filename_processed = x.as_path().file_name().unwrap().to_str().unwrap().to_string();
                let file_processed = x.as_path().to_str().unwrap().to_string();

                let filename = format!("name={}", filename_processed);
                let file = format!("file=@{}", file_processed);

                upload(&file_processed, file, filename, false, &config);
            }
        }
    }
}

fn upload_dr(args: Vec<String>, config: Config) {
    // DIRECTORY
    // Handles what files in the directory should be uploaded.
    // -d was used here.

    let directories = &args[2..args.len()];

    for d in directories {
        let path = Path::new(d);
        let mut fls: Vec<_> = vec!();

        if path.is_dir() == true {
            match fs::walk_dir(&path) {
                Err(why) => println!("! {:?}", why.kind()),
                Ok(paths) => for path in paths {
                    fls.push(path.unwrap().path());
                },
            }

            for x in fls {
                let filename_processed = x.as_path().file_name().unwrap().to_str().unwrap().to_string();
                let file_processed = x.as_path().to_str().unwrap().to_string();

                let filename = format!("name={}", filename_processed);
                let file = format!("file=@{}", file_processed);

                upload(&file_processed, file, filename, false, &config);
            }
        }
    }
}

fn help() {
    println!("Usage: ./uguupload [option] [FILE]

[FILE] is the path to the file you want to upload.

OPTIONS
    -h, --help
        Prints out this help message.

    -f, --filename
        Allows you to specify custom filenames for files.
        See Example 2.

    -r, --random
        Gives files random filenames.
        See Example 3.

    -d, --dir
        Uploads everything in the specified directory.
        This is not recursive.
        See Example 4.

    -dr, --dir-rec
        Uploads everything in the specified directory.
        This is recursive. Files in sub-directories will be uploaded.
        See Example 4. This works exactly like -d.

EXAMPLES
    Example 1:
        ./uguupload [FILE]
        ./uguupload foo.txt

        You can also upload several files.
        ./uguupload foo.txt bar.txt foobar.txt

    Example 2:
        ./uguupload -f [FILE] [FILENAME]
        ./uguupload -f foo.txt foo.txt bar.txt foo.txt foobar.txt foo.txt

        The first argument, foo.txt is the filename and the second argument, foo.txt, is the file and so on.
        bar.txt is the filename and foo.txt is the file. Same for foobar.txt and foo.txt

    Example 3:
        ./uguupload -r [FILE]
        ./uguupload -r foo.txt

        This will return http://a.uguu.se/asdfghjkl.ext where .ext is the file extension/type

    Example 4:
        ./uguupload -d [DIRECTORY]
        This will upload everything in the specified directory. You can add several directories

CONFIGURATION
    links_only:
        Type: boolean. This can be either true or false. Nothing else.

        If true, only links will be outputted, no filename.
        If false, the filename and the uguu.se link will outputted.

        Default is false.");

    return;
}
<|endoftext|>


<commit_before>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(io)]
#![feature(path)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate chip8_vm;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::env;
use std::io::{Read, BufReader};
use std::fs::File;
use std::path::Path;
use quack::Set;
use input::Button;

use chip8_vm::vm::Vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

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

    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if let Some(rom_path) = env::args().skip(1).next() {
        if let Ok(f) = File::open(&Path::new(&rom_path)) {
            rom = Some(f);
        } else {
            error!("Could not open ROM {}", rom_path);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Read;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Read,
        _ => {
            info!("You can provide a path to a CHIP-8 ROM to run it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => debug!("Loaded ROM of size: {}", size),
        Err(e) => {
            error!("Error loading ROM: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE).unwrap();
            } else {
                (*window.borrow_mut()).window.set_title(TITLE).unwrap();
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<commit_msg>Fix invocation of graphics::Rectangle::draw()<commit_after>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(io)]
#![feature(path)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

#[macro_use]
extern crate log;
extern crate env_logger;

extern crate chip8_vm;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::env;
use std::io::{Read, BufReader};
use std::fs::File;
use std::path::Path;
use quack::Set;
use input::Button;

use chip8_vm::vm::Vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

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

    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if let Some(rom_path) = env::args().skip(1).next() {
        if let Ok(f) = File::open(&Path::new(&rom_path)) {
            rom = Some(f);
        } else {
            error!("Could not open ROM {}", rom_path);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Read;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Read,
        _ => {
            info!("You can provide a path to a CHIP-8 ROM to run it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => debug!("Loaded ROM of size: {}", size),
        Err(e) => {
            error!("Error loading ROM: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE).unwrap();
            } else {
                (*window.borrow_mut()).window.set_title(TITLE).unwrap();
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c.draw_state, c.transform, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<|endoftext|>


<commit_before>extern crate rand;
#[macro_use]
extern crate clap;
extern crate image;

use std::path::Path;
use rand::Rng;
use clap::{Arg, App};
use image::{DynamicImage, GenericImage, RgbaImage};

arg_enum!{
    enum Mode {
        Brute
    }
}

fn main() {
    let matches = App::new("asami")
        .version("0.1.0")
        .author("Sebastian Schulz <mail@sesc.me>")
        .about("pixel sorter")
        .args_from_usage(
            "<INPUT> 'The input file to use'
             <OUTPUT> 'The output file to use'")
        .arg(Arg::from_usage("-m --mode <MODE> 'The mode to use")
            .possible_values(&Mode::variants())
            .default_value("Brute"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap();
    let output = matches.value_of("OUTPUT").unwrap();

    let mode = matches.value_of("mode").unwrap();
    println!("{}", mode);

    handle_request(input, output);
}

fn handle_request(input: &str, output: &str) {
    println!("input: {}, output: {}", input, output);

    let ref in_img = image::open(&Path::new(input)).unwrap();

    println!("dimensions {:?}", in_img.dimensions());
    println!("{:?}", in_img.color());

    let out_img = brute_sort(in_img, 32, 64);

    let _ = out_img.save(output).unwrap();
}

fn brute_sort(input: &DynamicImage, chunk_min_length: u32, chunk_max_length: u32) -> RgbaImage {
    let mut output = RgbaImage::new(input.width(), input.height());

    let mut out_x = 0;
    let mut out_y = 0;

    let mut tmp = Vec::new();

    let mut threshold = calculate_chunk_threshold(chunk_min_length, chunk_max_length);

    for (_, _, pixel) in input.pixels() {
        tmp.push(pixel);
        if tmp.len() > threshold as usize {
            threshold = calculate_chunk_threshold(chunk_min_length, chunk_max_length);
            tmp.sort_by(|a, b| (a[3]).cmp(&b[1]));
            write_pixel_to_image(&mut output, &mut out_x, &mut out_y, &mut tmp);
        }
    }
    output
}

fn calculate_chunk_threshold(chunk_min_length: u32, chunk_max_length: u32) -> u32 {
    rand::thread_rng().gen_range(chunk_min_length, chunk_max_length + 1)
}

fn write_pixel_to_image(image: &mut RgbaImage, x: &mut u32, y: &mut u32, pixels: &mut Vec<image::Rgba<u8>>){
    while !pixels.is_empty() {
        image.put_pixel(*x, *y, pixels.pop().unwrap());
        *y = *y + (*x + 1) / image.width();
        *x = (*x + 1) % image.width();
    }
}
<commit_msg>chunk size can now be set via cli arguments<commit_after>extern crate rand;
#[macro_use]
extern crate clap;
extern crate image;

use std::path::Path;
use rand::Rng;
use clap::{Arg, App};
use image::{DynamicImage, GenericImage, RgbaImage};

arg_enum!{
    enum Mode {
        Brute
    }
}

fn main() {
    let matches = App::new("asami")
        .version("0.1.0")
        .author("Sebastian Schulz <mail@sesc.me>")
        .about("pixel sorter")
        .args_from_usage(
            "<INPUT> 'The input file to use'
             <OUTPUT> 'The output file to use'")
        .arg(Arg::from_usage("-m --mode <MODE> 'The mode to use'")
            .possible_values(&Mode::variants())
            .default_value("Brute"))
        .arg(Arg::from_usage("--min <MIN> 'The minimum chunk size to sort'")
            .default_value("32"))
        .arg(Arg::from_usage("--max <MAX> 'The maximum chunk size to sort'")
            .default_value("64"))
        .get_matches();

    let input = matches.value_of("INPUT").unwrap();
    let output = matches.value_of("OUTPUT").unwrap();

    let min = value_t!(matches, "min", u32).expect("the minimum chunk size has to be a number");
    let max = value_t!(matches, "max", u32).expect("the maximum chunk size has to be a number");

    let mode = matches.value_of("mode").unwrap();

    println!("mode: {}", mode);

    handle_request(input, output, min, max);
}

fn handle_request(input: &str, output: &str, chunk_min_length: u32, chunk_max_length: u32) {
    println!("input: {}, output: {}", input, output);
    println!("minimum chunk size: {}, maximum chunk size: {}", chunk_min_length, chunk_max_length);

    let ref in_img = image::open(&Path::new(input)).unwrap();

    println!("dimensions {:?}", in_img.dimensions());
    println!("{:?}", in_img.color());

    let out_img = brute_sort(in_img, chunk_min_length, chunk_max_length);

    let _ = out_img.save(output).unwrap();
}

fn brute_sort(input: &DynamicImage, chunk_min_length: u32, chunk_max_length: u32) -> RgbaImage {
    let mut output = RgbaImage::new(input.width(), input.height());

    let mut out_x = 0;
    let mut out_y = 0;

    let mut tmp = Vec::new();

    let mut threshold = calculate_chunk_threshold(chunk_min_length, chunk_max_length);

    for (_, _, pixel) in input.pixels() {
        tmp.push(pixel);
        if tmp.len() > threshold as usize {
            threshold = calculate_chunk_threshold(chunk_min_length, chunk_max_length);
            tmp.sort_by(|a, b| (a[3]).cmp(&b[1]));
            write_pixel_to_image(&mut output, &mut out_x, &mut out_y, &mut tmp);
        }
    }
    output
}

fn calculate_chunk_threshold(chunk_min_length: u32, chunk_max_length: u32) -> u32 {
    rand::thread_rng().gen_range(chunk_min_length, chunk_max_length + 1)
}

fn write_pixel_to_image(image: &mut RgbaImage, x: &mut u32, y: &mut u32, pixels: &mut Vec<image::Rgba<u8>>){
    while !pixels.is_empty() {
        image.put_pixel(*x, *y, pixels.pop().unwrap());
        *y = *y + (*x + 1) / image.width();
        *x = (*x + 1) % image.width();
    }
}
<|endoftext|>


<commit_before>extern crate bindgen;
#[cfg(feature = "logging")]
extern crate env_logger;
#[macro_use]
#[cfg(feature = "logging")]
extern crate log;
extern crate clap;

use bindgen::clang_version;
use std::env;
use std::panic;

#[macro_use]
#[cfg(not(feature = "logging"))]
mod log_stubs;

mod options;
use crate::options::builder_from_flags;

fn clang_version_check() {
    let version = clang_version();
    let expected_version = if cfg!(feature = "testing_only_libclang_9") {
        Some((9, 0))
    } else if cfg!(feature = "testing_only_libclang_5") {
        Some((5, 0))
    } else if cfg!(feature = "testing_only_libclang_4") {
        Some((4, 0))
    } else if cfg!(feature = "testing_only_libclang_3_9") {
        Some((3, 9))
    } else if cfg!(feature = "testing_only_libclang_3_8") {
        Some((3, 8))
    } else {
        None
    };

    info!(
        "Clang Version: {}, parsed: {:?}",
        version.full, version.parsed
    );

    if expected_version.is_some() {
        assert_eq!(version.parsed, version.parsed);
    }
}

pub fn main() {
    #[cfg(feature = "logging")]
    env_logger::init();

    let bind_args: Vec<_> = env::args().collect();

    match builder_from_flags(bind_args.into_iter()) {
        Ok((builder, output, verbose)) => {
            clang_version_check();
            let builder_result = panic::catch_unwind(|| {
                builder.generate().expect("Unable to generate bindings")
            });

            if builder_result.is_err() {
                if verbose {
                    print_verbose_err();
                }
                std::process::exit(1);
            }

            let bindings = builder_result.unwrap();
            bindings.write(output).expect("Unable to write output");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}

fn print_verbose_err() {
    println!("Bindgen unexpectedly panicked");
    println!(
        "This may be caused by one of the known-unsupported \
         things (https://rust-lang.github.io/rust-bindgen/cpp.html), \
         please modify the bindgen flags to work around it as \
         described in https://rust-lang.github.io/rust-bindgen/cpp.html"
    );
    println!(
        "Otherwise, please file an issue at \
         https://github.com/rust-lang/rust-bindgen/issues/new"
    );
}

#[cfg(test)]
mod test {
    use std::path::PathBuf;

    fn build_flags_output_helper(builder: &bindgen::Builder) {
        let mut command_line_flags = builder.command_line_flags();
        command_line_flags.insert(0, "bindgen".to_string());

        let flags_quoted: Vec<String> = command_line_flags
            .iter()
            .map(|x| format!("{}", shlex::quote(x)))
            .collect();
        let flags_str = flags_quoted.join(" ");
        println!("{}", flags_str);

        let (builder, _output, _verbose) =
            crate::options::builder_from_flags(command_line_flags.into_iter())
                .unwrap();
        builder.generate().expect("failed to generate bindings");
    }

    #[test]
    fn commandline_multiple_headers() {
        let bindings = bindgen::Builder::default()
            .header("tests/headers/char.h")
            .header("tests/headers/func_ptr.h")
            .header("tests/headers/16-byte-alignment.h");
        build_flags_output_helper(&bindings);
    }
}
<commit_msg>main: Remove unused use statement.<commit_after>extern crate bindgen;
#[cfg(feature = "logging")]
extern crate env_logger;
#[macro_use]
#[cfg(feature = "logging")]
extern crate log;
extern crate clap;

use bindgen::clang_version;
use std::env;
use std::panic;

#[macro_use]
#[cfg(not(feature = "logging"))]
mod log_stubs;

mod options;
use crate::options::builder_from_flags;

fn clang_version_check() {
    let version = clang_version();
    let expected_version = if cfg!(feature = "testing_only_libclang_9") {
        Some((9, 0))
    } else if cfg!(feature = "testing_only_libclang_5") {
        Some((5, 0))
    } else if cfg!(feature = "testing_only_libclang_4") {
        Some((4, 0))
    } else if cfg!(feature = "testing_only_libclang_3_9") {
        Some((3, 9))
    } else if cfg!(feature = "testing_only_libclang_3_8") {
        Some((3, 8))
    } else {
        None
    };

    info!(
        "Clang Version: {}, parsed: {:?}",
        version.full, version.parsed
    );

    if expected_version.is_some() {
        assert_eq!(version.parsed, version.parsed);
    }
}

pub fn main() {
    #[cfg(feature = "logging")]
    env_logger::init();

    let bind_args: Vec<_> = env::args().collect();

    match builder_from_flags(bind_args.into_iter()) {
        Ok((builder, output, verbose)) => {
            clang_version_check();
            let builder_result = panic::catch_unwind(|| {
                builder.generate().expect("Unable to generate bindings")
            });

            if builder_result.is_err() {
                if verbose {
                    print_verbose_err();
                }
                std::process::exit(1);
            }

            let bindings = builder_result.unwrap();
            bindings.write(output).expect("Unable to write output");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}

fn print_verbose_err() {
    println!("Bindgen unexpectedly panicked");
    println!(
        "This may be caused by one of the known-unsupported \
         things (https://rust-lang.github.io/rust-bindgen/cpp.html), \
         please modify the bindgen flags to work around it as \
         described in https://rust-lang.github.io/rust-bindgen/cpp.html"
    );
    println!(
        "Otherwise, please file an issue at \
         https://github.com/rust-lang/rust-bindgen/issues/new"
    );
}

#[cfg(test)]
mod test {
    fn build_flags_output_helper(builder: &bindgen::Builder) {
        let mut command_line_flags = builder.command_line_flags();
        command_line_flags.insert(0, "bindgen".to_string());

        let flags_quoted: Vec<String> = command_line_flags
            .iter()
            .map(|x| format!("{}", shlex::quote(x)))
            .collect();
        let flags_str = flags_quoted.join(" ");
        println!("{}", flags_str);

        let (builder, _output, _verbose) =
            crate::options::builder_from_flags(command_line_flags.into_iter())
                .unwrap();
        builder.generate().expect("failed to generate bindings");
    }

    #[test]
    fn commandline_multiple_headers() {
        let bindings = bindgen::Builder::default()
            .header("tests/headers/char.h")
            .header("tests/headers/func_ptr.h")
            .header("tests/headers/16-byte-alignment.h");
        build_flags_output_helper(&bindings);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate gitjournal;
extern crate term;

use std::process::exit;
use clap::App;
use gitjournal::GitJournal;

fn print(string: &str, color: term::color::Color) -> Result<(), term::Error> {
    let mut t = try!(term::stderr().ok_or(term::Error::NotSupported));
    try!(t.fg(color));
    try!(writeln!(t, "[git-journal] {}", string));
    try!(t.reset());
    Ok(())
}

fn print_ok(string: &str) -> Result<(), term::Error> {
    try!(print(string, term::color::GREEN));
    Ok(())
}

fn print_err(string: &str) -> Result<(), term::Error> {
    try!(print(string, term::color::RED));
    exit(1);
}

static TERM_ERR: &'static str = "Could not write to terminal";
static PATH_ERR: &'static str = "Could not parse 'path' parameter";
static VERI_ERR: &'static str = "Could not parse 'verify' value";
static TAGS_ERR: &'static str = "Could not parse 'tags count' parameter";
static CONV_ERR: &'static str = "Could not parse 'tags count' to integer";
static REVR_ERR: &'static str = "Could not parse 'revision range' parameter";
static SKIP_ERR: &'static str = "Could not parse 'skip pattern' parameter";
static PREP_ERR: &'static str = "Could not parse 'prepare' parameter";
static JOUR_ERR: &'static str = "Could not initialize git-journal";

fn main() {
    // Load the CLI parameters from the yaml file
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml).get_matches();
    let path = matches.value_of("path").expect(PATH_ERR);

    if matches.is_present("verify") {
        // Verify a commit message and panic! if verification failed.
        match GitJournal::verify(matches.value_of("verify").expect(VERI_ERR)) {
            Ok(()) => print_ok("Commit message valid.").expect(TERM_ERR),
            Err(error) => print_err(&format!("Commit message invalid: {}", error)).expect(TERM_ERR),
        }
    } else if matches.is_present("prepare") {
        // Prepare a commit message before editing by the user
        match GitJournal::prepare(matches.value_of("prepare").expect(PREP_ERR)) {
            Ok(()) => print_ok("Commit message prepared.").expect(TERM_ERR),
            Err(error) => print_err(&format!("Commit message preparation failed: {}", error)).expect(TERM_ERR),
        }
    } else {
        // Create the journal
        let mut journal = GitJournal::new(path).expect(JOUR_ERR);

        if matches.is_present("setup") {
            journal.setup().expect("Setup error");
        } else {
            // Get all values of the given CLI parameters
            let revision_range = matches.value_of("revision_range").expect(REVR_ERR);
            let tag_skip_pattern = matches.value_of("tag_skip_pattern").expect(SKIP_ERR);
            let tags_count = matches.value_of("tags_count").expect(TAGS_ERR);
            let max_tags = tags_count.parse::<u32>().expect(CONV_ERR);

            // Parse the log
            journal.parse_log(revision_range,
                           tag_skip_pattern,
                           &max_tags,
                           &matches.is_present("all"),
                           &matches.is_present("skip_unreleased"))
                .expect("Log parsing error");
            journal.print_log(matches.is_present("short")).expect("Could not print log.");
        }
    }
}
<commit_msg>Added even more colors :)<commit_after>#[macro_use]
extern crate clap;
extern crate gitjournal;
extern crate term;

use std::process::exit;
use clap::App;
use gitjournal::GitJournal;

fn print(string: &str, color: term::color::Color) -> Result<(), term::Error> {
    let mut t = try!(term::stderr().ok_or(term::Error::NotSupported));
    try!(t.fg(term::color::YELLOW));
    try!(write!(t, "[git-journal] "));
    try!(t.fg(color));
    try!(writeln!(t, "{}", string));
    try!(t.reset());
    Ok(())
}

fn print_ok(string: &str) -> Result<(), term::Error> {
    try!(print(string, term::color::GREEN));
    Ok(())
}

fn print_err(string: &str) -> Result<(), term::Error> {
    try!(print(string, term::color::RED));
    exit(1);
}

static TERM_ERR: &'static str = "Could not write to terminal";
static PATH_ERR: &'static str = "Could not parse 'path' parameter";
static VERI_ERR: &'static str = "Could not parse 'verify' value";
static TAGS_ERR: &'static str = "Could not parse 'tags count' parameter";
static CONV_ERR: &'static str = "Could not parse 'tags count' to integer";
static REVR_ERR: &'static str = "Could not parse 'revision range' parameter";
static SKIP_ERR: &'static str = "Could not parse 'skip pattern' parameter";
static PREP_ERR: &'static str = "Could not parse 'prepare' parameter";
static JOUR_ERR: &'static str = "Could not initialize git-journal";

fn main() {
    // Load the CLI parameters from the yaml file
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml).get_matches();
    let path = matches.value_of("path").expect(PATH_ERR);

    if matches.is_present("verify") {
        // Verify a commit message and panic! if verification failed.
        match GitJournal::verify(matches.value_of("verify").expect(VERI_ERR)) {
            Ok(()) => print_ok("Commit message valid.").expect(TERM_ERR),
            Err(error) => print_err(&format!("Commit message invalid: {}", error)).expect(TERM_ERR),
        }
    } else if matches.is_present("prepare") {
        // Prepare a commit message before editing by the user
        match GitJournal::prepare(matches.value_of("prepare").expect(PREP_ERR)) {
            Ok(()) => print_ok("Commit message prepared.").expect(TERM_ERR),
            Err(error) => print_err(&format!("Commit message preparation failed: {}", error)).expect(TERM_ERR),
        }
    } else {
        // Create the journal
        let mut journal = GitJournal::new(path).expect(JOUR_ERR);

        if matches.is_present("setup") {
            journal.setup().expect("Setup error");
        } else {
            // Get all values of the given CLI parameters
            let revision_range = matches.value_of("revision_range").expect(REVR_ERR);
            let tag_skip_pattern = matches.value_of("tag_skip_pattern").expect(SKIP_ERR);
            let tags_count = matches.value_of("tags_count").expect(TAGS_ERR);
            let max_tags = tags_count.parse::<u32>().expect(CONV_ERR);

            // Parse the log
            journal.parse_log(revision_range,
                           tag_skip_pattern,
                           &max_tags,
                           &matches.is_present("all"),
                           &matches.is_present("skip_unreleased"))
                .expect("Log parsing error");
            journal.print_log(matches.is_present("short")).expect("Could not print log.");
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::OsString;
use std::fs::File;
use std::io::{self, BufRead, Write};
use std::path::PathBuf;
use std::process::{self, Command, Stdio};

extern crate isatty;
use isatty::{stderr_isatty, stdout_isatty};

extern crate tempfile;

fn main() {
    if env::args_os().any(|arg| arg.to_str() == Some("--version")) {
        println!(concat!("cargo-expand ", env!("CARGO_PKG_VERSION")));
        return;
    }

    let result = cargo_expand_or_run_nightly();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

fn cargo_expand_or_run_nightly() -> io::Result<i32> {
    const NO_RUN_NIGHTLY: &str = "CARGO_EXPAND_NO_RUN_NIGHTLY";

    let maybe_nightly = !definitely_not_nightly();
    if maybe_nightly || env::var_os(NO_RUN_NIGHTLY).is_some() {
        return cargo_expand();
    }

    let mut nightly = Command::new("cargo");
    nightly.arg("+nightly");
    nightly.arg("expand");

    let mut args = env::args_os().peekable();
    args.next().unwrap(); // cargo
    if args.peek().and_then(|arg| arg.to_str()) == Some("expand") {
        args.next().unwrap(); // expand
    }
    nightly.args(args);

    // Hopefully prevent infinite re-run loop.
    nightly.env(NO_RUN_NIGHTLY, "");

    let status = nightly.status()?;

    Ok(match status.code() {
        Some(code) => code,
        None => if status.success() { 0 } else { 1 },
    })
}

fn definitely_not_nightly() -> bool {
    let mut cmd = Command::new(cargo_binary());
    cmd.arg("--version");

    let output = match cmd.output() {
        Ok(output) => output,
        Err(_) => return false,
    };

    let version = match String::from_utf8(output.stdout) {
        Ok(version) => version,
        Err(_) => return false,
    };

    version.starts_with("cargo 1") && !version.contains("nightly")
}

fn cargo_binary() -> OsString {
    env::var_os("CARGO").unwrap_or_else(|| "cargo".to_owned().into())
}

fn cargo_expand() -> io::Result<i32> {
    let args: Vec<_> = env::args_os().collect();

    let which_rustfmt = which(&["rustfmt"]);
    let which_pygmentize = if !color_never(&args) && stdout_isatty() {
        which(&["pygmentize", "-l", "rust"])
    } else {
        None
    };

    let outdir = if which_rustfmt.is_some() || which_pygmentize.is_some() {
        let mut builder = tempfile::Builder::new();
        builder.prefix("cargo-expand");
        Some(builder.tempdir().expect("failed to create tmp file"))
    } else {
        None
    };
    let outfile = outdir.as_ref().map(|dir| dir.path().join("expanded"));

    // Run cargo
    let mut cmd = Command::new(cargo_binary());
    cmd.args(&wrap_args(args.clone(), outfile.as_ref()));
    let code = filter_err(&mut cmd, ignore_cargo_err)?;
    if code != 0 {
        return Ok(code);
    }

    // Run rustfmt
    if let Some(fmt) = which_rustfmt {
        // Ignore any errors.
        let _status = Command::new(fmt)
            .arg(outfile.as_ref().unwrap())
            .stderr(Stdio::null())
            .status();
    }

    // Run pygmentize
    if let Some(pyg) = which_pygmentize {
        let _status = Command::new(pyg)
            .args(&["-l", "rust", "-O", "encoding=utf8"])
            .arg(outfile.as_ref().unwrap())
            .status();
    } else if let Some(outfile) = outfile {
        // Cat outfile if rustfmt was used.
        let mut reader = File::open(outfile)?;
        io::copy(&mut reader, &mut io::stdout())?;
    }
    Ok(0)
}

// Based on https://github.com/rsolomo/cargo-check
fn wrap_args<I>(it: I, outfile: Option<&PathBuf>) -> Vec<OsString>
where
    I: IntoIterator<Item = OsString>,
{
    let mut args = vec!["rustc".into(), "--profile=check".into()];
    let mut ends_with_test = false;
    let mut ends_with_example = false;
    let mut has_color = false;

    let mut it = it.into_iter().skip(2);
    for arg in &mut it {
        if arg == *"--" {
            break;
        }
        ends_with_test = arg == *"--test";
        ends_with_example = arg == *"--example";
        has_color |= arg.to_str().unwrap_or("").starts_with("--color");
        args.push(arg.into());
    }

    if ends_with_test {
        // Expand the `test.rs` test by default.
        args.push("test".into());
    }

    if ends_with_example {
        // Expand the `example.rs` example by default.
        args.push("example".into());
    }

    if !has_color {
        let color = stderr_isatty();
        let setting = if color { "always" } else { "never" };
        args.push(format!("--color={}", setting).into());
    }

    args.push("--".into());
    if let Some(path) = outfile {
        args.push("-o".into());
        args.push(path.into());
    }
    args.push("-Zunstable-options".into());
    args.push("--pretty=expanded".into());
    args.extend(it);
    args
}

fn color_never(args: &Vec<OsString>) -> bool {
    args.windows(2).any(|pair| pair[0] == *"--color" && pair[1] == *"never")
        || args.iter().any(|arg| *arg == *"--color=never")
}

fn which(cmd: &[&str]) -> Option<OsString> {
    if env::args_os().find(|arg| arg == "--help").is_some() {
        return None;
    }

    if let Some(which) = env::var_os(&cmd[0].to_uppercase()) {
        return if which.is_empty() { None } else { Some(which) };
    }

    let spawn = Command::new(cmd[0])
        .args(&cmd[1..])
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn();
    let mut child = match spawn {
        Ok(child) => child,
        Err(_) => {
            return None;
        }
    };

    let exit = match child.wait() {
        Ok(exit) => exit,
        Err(_) => {
            return None;
        }
    };

    if exit.success() {
        Some(cmd[0].into())
    } else {
        None
    }
}

fn filter_err(cmd: &mut Command, ignore: fn(&str) -> bool) -> io::Result<i32> {
    let mut child = cmd.stderr(Stdio::piped()).spawn()?;
    let mut stderr = io::BufReader::new(child.stderr.take().unwrap());
    let mut line = String::new();
    while let Ok(n) = stderr.read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    let code = child.wait()?.code().unwrap_or(1);
    Ok(code)
}

fn ignore_cargo_err(line: &str) -> bool {
    if line.trim().is_empty() {
        return true;
    }

    let blacklist = [
        "ignoring specified output filename because multiple outputs were \
         requested",
        "ignoring specified output filename for 'link' output because multiple \
         outputs were requested",
        "ignoring --out-dir flag due to -o flag",
        "ignoring -C extra-filename flag due to -o flag",
        "due to multiple output types requested, the explicitly specified \
         output file name will be adapted for each output type",
    ];
    for s in &blacklist {
        if line.contains(s) {
            return true;
        }
    }

    false
}
<commit_msg>Simplify comparisons against os string<commit_after>use std::env;
use std::ffi::OsString;
use std::fs::File;
use std::io::{self, BufRead, Write};
use std::path::PathBuf;
use std::process::{self, Command, Stdio};

extern crate isatty;
use isatty::{stderr_isatty, stdout_isatty};

extern crate tempfile;

fn main() {
    if env::args_os().any(|arg| arg == *"--version") {
        println!(concat!("cargo-expand ", env!("CARGO_PKG_VERSION")));
        return;
    }

    let result = cargo_expand_or_run_nightly();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

fn cargo_expand_or_run_nightly() -> io::Result<i32> {
    const NO_RUN_NIGHTLY: &str = "CARGO_EXPAND_NO_RUN_NIGHTLY";

    let maybe_nightly = !definitely_not_nightly();
    if maybe_nightly || env::var_os(NO_RUN_NIGHTLY).is_some() {
        return cargo_expand();
    }

    let mut nightly = Command::new("cargo");
    nightly.arg("+nightly");
    nightly.arg("expand");

    let mut args = env::args_os().peekable();
    args.next().unwrap(); // cargo
    if args.peek().map_or(false, |arg| arg == "expand") {
        args.next().unwrap(); // expand
    }
    nightly.args(args);

    // Hopefully prevent infinite re-run loop.
    nightly.env(NO_RUN_NIGHTLY, "");

    let status = nightly.status()?;

    Ok(match status.code() {
        Some(code) => code,
        None => if status.success() { 0 } else { 1 },
    })
}

fn definitely_not_nightly() -> bool {
    let mut cmd = Command::new(cargo_binary());
    cmd.arg("--version");

    let output = match cmd.output() {
        Ok(output) => output,
        Err(_) => return false,
    };

    let version = match String::from_utf8(output.stdout) {
        Ok(version) => version,
        Err(_) => return false,
    };

    version.starts_with("cargo 1") && !version.contains("nightly")
}

fn cargo_binary() -> OsString {
    env::var_os("CARGO").unwrap_or_else(|| "cargo".to_owned().into())
}

fn cargo_expand() -> io::Result<i32> {
    let args: Vec<_> = env::args_os().collect();

    let which_rustfmt = which(&["rustfmt"]);
    let which_pygmentize = if !color_never(&args) && stdout_isatty() {
        which(&["pygmentize", "-l", "rust"])
    } else {
        None
    };

    let outdir = if which_rustfmt.is_some() || which_pygmentize.is_some() {
        let mut builder = tempfile::Builder::new();
        builder.prefix("cargo-expand");
        Some(builder.tempdir().expect("failed to create tmp file"))
    } else {
        None
    };
    let outfile = outdir.as_ref().map(|dir| dir.path().join("expanded"));

    // Run cargo
    let mut cmd = Command::new(cargo_binary());
    cmd.args(&wrap_args(args.clone(), outfile.as_ref()));
    let code = filter_err(&mut cmd, ignore_cargo_err)?;
    if code != 0 {
        return Ok(code);
    }

    // Run rustfmt
    if let Some(fmt) = which_rustfmt {
        // Ignore any errors.
        let _status = Command::new(fmt)
            .arg(outfile.as_ref().unwrap())
            .stderr(Stdio::null())
            .status();
    }

    // Run pygmentize
    if let Some(pyg) = which_pygmentize {
        let _status = Command::new(pyg)
            .args(&["-l", "rust", "-O", "encoding=utf8"])
            .arg(outfile.as_ref().unwrap())
            .status();
    } else if let Some(outfile) = outfile {
        // Cat outfile if rustfmt was used.
        let mut reader = File::open(outfile)?;
        io::copy(&mut reader, &mut io::stdout())?;
    }
    Ok(0)
}

// Based on https://github.com/rsolomo/cargo-check
fn wrap_args<I>(it: I, outfile: Option<&PathBuf>) -> Vec<OsString>
where
    I: IntoIterator<Item = OsString>,
{
    let mut args = vec!["rustc".into(), "--profile=check".into()];
    let mut ends_with_test = false;
    let mut ends_with_example = false;
    let mut has_color = false;

    let mut it = it.into_iter().skip(2);
    for arg in &mut it {
        if arg == *"--" {
            break;
        }
        ends_with_test = arg == *"--test";
        ends_with_example = arg == *"--example";
        has_color |= arg.to_str().unwrap_or("").starts_with("--color");
        args.push(arg.into());
    }

    if ends_with_test {
        // Expand the `test.rs` test by default.
        args.push("test".into());
    }

    if ends_with_example {
        // Expand the `example.rs` example by default.
        args.push("example".into());
    }

    if !has_color {
        let color = stderr_isatty();
        let setting = if color { "always" } else { "never" };
        args.push(format!("--color={}", setting).into());
    }

    args.push("--".into());
    if let Some(path) = outfile {
        args.push("-o".into());
        args.push(path.into());
    }
    args.push("-Zunstable-options".into());
    args.push("--pretty=expanded".into());
    args.extend(it);
    args
}

fn color_never(args: &Vec<OsString>) -> bool {
    args.windows(2).any(|pair| pair[0] == *"--color" && pair[1] == *"never")
        || args.iter().any(|arg| *arg == *"--color=never")
}

fn which(cmd: &[&str]) -> Option<OsString> {
    if env::args_os().find(|arg| arg == "--help").is_some() {
        return None;
    }

    if let Some(which) = env::var_os(&cmd[0].to_uppercase()) {
        return if which.is_empty() { None } else { Some(which) };
    }

    let spawn = Command::new(cmd[0])
        .args(&cmd[1..])
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn();
    let mut child = match spawn {
        Ok(child) => child,
        Err(_) => {
            return None;
        }
    };

    let exit = match child.wait() {
        Ok(exit) => exit,
        Err(_) => {
            return None;
        }
    };

    if exit.success() {
        Some(cmd[0].into())
    } else {
        None
    }
}

fn filter_err(cmd: &mut Command, ignore: fn(&str) -> bool) -> io::Result<i32> {
    let mut child = cmd.stderr(Stdio::piped()).spawn()?;
    let mut stderr = io::BufReader::new(child.stderr.take().unwrap());
    let mut line = String::new();
    while let Ok(n) = stderr.read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    let code = child.wait()?.code().unwrap_or(1);
    Ok(code)
}

fn ignore_cargo_err(line: &str) -> bool {
    if line.trim().is_empty() {
        return true;
    }

    let blacklist = [
        "ignoring specified output filename because multiple outputs were \
         requested",
        "ignoring specified output filename for 'link' output because multiple \
         outputs were requested",
        "ignoring --out-dir flag due to -o flag",
        "ignoring -C extra-filename flag due to -o flag",
        "due to multiple output types requested, the explicitly specified \
         output file name will be adapted for each output type",
    ];
    for s in &blacklist {
        if line.contains(s) {
            return true;
        }
    }

    false
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

pub struct App {
    gl: GlGraphics, // OpenGL drawing backend.
    rotation: f64   // Rotation for the square.
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
        const RED:   [f32; 4] = [1.0, 0.0, 0.0, 1.0];

        let square = rectangle::square(0.0, 0.0, 50.0);
        let rotation = self.rotation;
        let (x, y) = ((args.width / 2) as f64, (args.height / 2) as f64);

        self.gl.draw(args.viewport(), |c, gl| {
            // Clear the screen.
            clear(GREEN, gl);

            let transform = c.transform.trans(x, y)
                                       .rot_rad(rotation)
                                       .trans(-25.0, -25.0);

            // Draw a box rotating around the middle of the screen.
            rectangle(RED, square, transform, gl);
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        // Rotate 2 radians per second.
        self.rotation += 2.0 * args.dt;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;

    // Create an Glutin window.
    let window = Window::new(
        WindowSettings::new(
            "spinning-square",
            [200, 200]
        )
        .exit_on_esc(true)
    );

    // Create a new game and run it.
    let mut app = App {
        gl: GlGraphics::new(opengl),
        rotation: 0.0
    };

    for e in window.events() {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }

        if let Some(u) = e.update_args() {
            app.update(&u);
        }
    }
}

<commit_msg>add some cursor handling<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };
use piston::input::{ Button };

pub struct App {
    gl: GlGraphics, // OpenGL drawing backend.
    rotation: f64,   // Rotation for the square.
    position: [f64; 2],
    target: [f64; 2],
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0];
        const RED:   [f32; 4] = [1.0, 0.0, 0.0, 1.0];

        let square = rectangle::square(0.0, 0.0, 50.0);
        let rotation = self.rotation;
        let pos = self.position;

        self.gl.draw(args.viewport(), |c, gl| {
            // Clear the screen.
            clear(GREEN, gl);

            let transform = c.transform.trans(pos[0], pos[1])
                                       .rot_rad(rotation)
                                       .trans(-25.0, -25.0);

            // Draw a box rotating around the middle of the screen.
            rectangle(RED, square, transform, gl);
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        // Rotate 2 radians per second.
        self.rotation += 2.0 * args.dt;

        let diff = [self.target[0]-self.position[0], self.target[1]-self.position[1]];
        self.position[0] += diff[0]/2.0*args.dt;
        self.position[1] += diff[1]/2.0*args.dt;
    }
}

fn main() {
    let opengl = OpenGL::_3_2;

    // Create an Glutin window.
    let window = Window::new(
        WindowSettings::new(
            "spinning-square",
            [200, 200]
        )
        .exit_on_esc(true)
    );

    // Create a new game and run it.
    let mut app = App {
        gl: GlGraphics::new(opengl),
        rotation: 0.0,
        position: [50.0, 50.0],
        target: [50.0, 50.0],
    };

    let mut cursor = [0.0,0.0];

    for e in window.events() {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
        if let Some(Button::Mouse(button)) = e.press_args() {
            println!("Pressed mouse button '{:?}'", button);
            app.target = cursor;
        }
        e.mouse_cursor(|x, y| {
            cursor = [x, y];
            println!("Mouse moved '{} {}'", x, y);
        });

        if let Some(u) = e.update_args() {
            app.update(&u);
        }
    }
}

<|endoftext|>


<commit_before>extern crate docopt;
extern crate rustc_serialize;

use docopt::Docopt;

const USAGE: &'static str = "
Usage: bittles <torrent>
";

#[derive(RustcDecodable)]
struct Args {
    arg_torrent: String,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    println!("torrent: {}", args.arg_torrent);
}
<commit_msg>ooh read a file<commit_after>extern crate docopt;
extern crate rustc_serialize;
extern crate bip_bencode;

use std::error::Error;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;
use docopt::Docopt;
// use bip_bencode::{BencodeRef, BRefAccess, BDecodeOpt};

const USAGE: &'static str = "
Usage: bittles <torrent>
";

#[derive(RustcDecodable)]
struct Args {
    arg_torrent: String,
}

fn main() {
    match inner() {
        Ok(_) => {}
        Err(e) => println!("ERROR: {}", e)
    }
}

fn inner() -> Result<(),Box<Error>> {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let cwd = std::env::current_dir()?;
    println!("cwd: {}", cwd.display());
    println!("torrent: {}", args.arg_torrent);

    let torrent_path = Path::new(&args.arg_torrent);
    let mut buf = vec![0;0];
    let mut f = File::open(torrent_path)?;
    f.read_to_end(&mut buf).unwrap();

    for x in buf {
        println!("{}", x);
    }
    Ok(())
}
<|endoftext|>


<commit_before>use std::env;
use std::process::{exit, Command, Stdio};

use self::State::{Quoted, Escaped, Normal};

enum State {
    Quoted(char),
    Escaped,
    Normal
}

fn trimmed(s: &str) -> String {
    s.trim().to_string()
}

fn extract_commands(input: &str) -> Vec<String> {
    let mut state: State = Normal;
    let mut commands: Vec<String> = vec![];
    let mut it = input.chars();
    let mut s = String::new();
    loop {
        let c = match it.next() {
            Some(ch) => {
                ch.clone()
            }
            None => {
                commands.push(trimmed(&s));
                return commands;
            }
        };
        match state {
            Normal => {
                match c {
                    '\\' => {
                        state = Escaped;
                    },
                    '\'' | '"' => {
                        state = Quoted(c);
                        s.push(c);
                    },
                    ',' => {
                        commands.push(trimmed(&s));
                        s.clear();
                    },
                    _ => {
                        s.push(c);
                    },
                }
            },
            Quoted(terminator) => {
                if c == terminator {
                    state = Normal;
                }
                s.push(c);
            },
            Escaped => {
                state = Normal;
                s.push(c);
            },
        }
    }
}

fn main() {
    // this gets invoked like this:
    //
    //   $ cargo-do do [args]
    //
    // so we throw away the `cargo-do` and the `do`.
    let args = env::args();
    let args = args.skip(2).collect::<Vec<_>>().connect(" ");

    for command in extract_commands(&args).iter() {
        let command: Vec<_> = command.split(' ').map(|s| s.trim()).collect();
        let status = Command::new("cargo")
                        .args(&command)
                        .stdin(Stdio::inherit())
                        .stdout(Stdio::inherit())
                        .stderr(Stdio::inherit())
                        .status();
        match status {
            Ok(st) => {
                if !st.success() {
                    match st.code() {
                        Some(0) => (),
                        Some(i) => { exit(i); },
                        None => { exit(127); }
                    }
                }
            },
            Err(_) => {
                exit(127);
            },
        }
    }

    exit(0);
}

<commit_msg>Use join instead of connect<commit_after>use std::env;
use std::process::{exit, Command, Stdio};

use self::State::{Quoted, Escaped, Normal};

enum State {
    Quoted(char),
    Escaped,
    Normal
}

fn trimmed(s: &str) -> String {
    s.trim().to_string()
}

fn extract_commands(input: &str) -> Vec<String> {
    let mut state: State = Normal;
    let mut commands: Vec<String> = vec![];
    let mut it = input.chars();
    let mut s = String::new();
    loop {
        let c = match it.next() {
            Some(ch) => {
                ch.clone()
            }
            None => {
                commands.push(trimmed(&s));
                return commands;
            }
        };
        match state {
            Normal => {
                match c {
                    '\\' => {
                        state = Escaped;
                    },
                    '\'' | '"' => {
                        state = Quoted(c);
                        s.push(c);
                    },
                    ',' => {
                        commands.push(trimmed(&s));
                        s.clear();
                    },
                    _ => {
                        s.push(c);
                    },
                }
            },
            Quoted(terminator) => {
                if c == terminator {
                    state = Normal;
                }
                s.push(c);
            },
            Escaped => {
                state = Normal;
                s.push(c);
            },
        }
    }
}

fn main() {
    // this gets invoked like this:
    //
    //   $ cargo-do do [args]
    //
    // so we throw away the `cargo-do` and the `do`.
    let args = env::args();
    let args = args.skip(2).collect::<Vec<_>>().join(" ");

    for command in extract_commands(&args).iter() {
        let command: Vec<_> = command.split(' ').map(|s| s.trim()).collect();
        let status = Command::new("cargo")
                        .args(&command)
                        .stdin(Stdio::inherit())
                        .stdout(Stdio::inherit())
                        .stderr(Stdio::inherit())
                        .status();
        match status {
            Ok(st) => {
                if !st.success() {
                    match st.code() {
                        Some(0) => (),
                        Some(i) => { exit(i); },
                        None => { exit(127); }
                    }
                }
            },
            Err(_) => {
                exit(127);
            },
        }
    }

    exit(0);
}

<|endoftext|>


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

use std::collections::HashMap;
use std::process;
use std::io::{self, Write};

extern crate cargo_metadata;

use std::path::Path;

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

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

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit
    --all                    Run over all packages in the current workspace

Other options are the same as `cargo rustc`.

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

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

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

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

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

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

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

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

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

    let manifest_path = manifest_path_arg.map(|arg| {
        Path::new(&arg["--manifest-path=".len()..])
            .canonicalize()
            .expect("manifest path could not be canonicalized")
    });

    let packages = if std::env::args().any(|a| a == "--all") {
        metadata.packages
    } else {
        let package_index = {
            if let Some(manifest_path) = manifest_path {
                metadata.packages.iter().position(|package| {
                    let package_manifest_path = Path::new(&package.manifest_path)
                        .canonicalize()
                        .expect("package manifest path could not be canonicalized");
                    package_manifest_path == manifest_path
                })
            } else {
                let package_manifest_paths: HashMap<_, _> = metadata
                    .packages
                    .iter()
                    .enumerate()
                    .map(|(i, package)| {
                        let package_manifest_path = Path::new(&package.manifest_path)
                            .parent()
                            .expect("could not find parent directory of package manifest")
                            .canonicalize()
                            .expect("package directory cannot be canonicalized");
                        (package_manifest_path, i)
                    })
                    .collect();

                let current_dir = std::env::current_dir()
                    .expect("could not read current directory")
                    .canonicalize()
                    .expect("current directory cannot be canonicalized");

                let mut current_path: &Path = &current_dir;

                // This gets the most-recent parent (the one that takes the fewest `cd ..`s to
                // reach).
                loop {
                    if let Some(&package_index) = package_manifest_paths.get(current_path) {
                        break Some(package_index);
                    } else {
                        // We'll never reach the filesystem root, because to get to this point in the
                        // code
                        // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
                        // unwrap the current path's parent.
                        current_path = current_path
                            .parent()
                            .unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display()));
                    }
                }
            }
        }.expect("could not find matching package");

        vec![metadata.packages.remove(package_index)]
    };

    for package in packages {
        let manifest_path = package.manifest_path;

        for target in package.targets {
            let args = std::env::args()
                .skip(2)
                .filter(|a| a != "--all" && !a.starts_with("--manifest-path="));

            let args = std::iter::once(format!("--manifest-path={}", manifest_path)).chain(args);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    println!("lib: {}", target.name);
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    println!("{}: {}", first, target.name);
                    if let Err(code) = process(
                        vec![format!("--{}", first), target.name]
                            .into_iter()
                            .chain(args),
                    ) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    }
}

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

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("--emit=metadata".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

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

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Readd the .exe extension on windows<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

use std::collections::HashMap;
use std::process;
use std::io::{self, Write};

extern crate cargo_metadata;

use std::path::Path;

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

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

Common options:
    -h, --help               Print this message
    --features               Features to compile for the package
    -V, --version            Print version info and exit
    --all                    Run over all packages in the current workspace

Other options are the same as `cargo rustc`.

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

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

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

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

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

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

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

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

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

    let manifest_path = manifest_path_arg.map(|arg| {
        Path::new(&arg["--manifest-path=".len()..])
            .canonicalize()
            .expect("manifest path could not be canonicalized")
    });

    let packages = if std::env::args().any(|a| a == "--all") {
        metadata.packages
    } else {
        let package_index = {
            if let Some(manifest_path) = manifest_path {
                metadata.packages.iter().position(|package| {
                    let package_manifest_path = Path::new(&package.manifest_path)
                        .canonicalize()
                        .expect("package manifest path could not be canonicalized");
                    package_manifest_path == manifest_path
                })
            } else {
                let package_manifest_paths: HashMap<_, _> = metadata
                    .packages
                    .iter()
                    .enumerate()
                    .map(|(i, package)| {
                        let package_manifest_path = Path::new(&package.manifest_path)
                            .parent()
                            .expect("could not find parent directory of package manifest")
                            .canonicalize()
                            .expect("package directory cannot be canonicalized");
                        (package_manifest_path, i)
                    })
                    .collect();

                let current_dir = std::env::current_dir()
                    .expect("could not read current directory")
                    .canonicalize()
                    .expect("current directory cannot be canonicalized");

                let mut current_path: &Path = &current_dir;

                // This gets the most-recent parent (the one that takes the fewest `cd ..`s to
                // reach).
                loop {
                    if let Some(&package_index) = package_manifest_paths.get(current_path) {
                        break Some(package_index);
                    } else {
                        // We'll never reach the filesystem root, because to get to this point in the
                        // code
                        // the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
                        // unwrap the current path's parent.
                        current_path = current_path
                            .parent()
                            .unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display()));
                    }
                }
            }
        }.expect("could not find matching package");

        vec![metadata.packages.remove(package_index)]
    };

    for package in packages {
        let manifest_path = package.manifest_path;

        for target in package.targets {
            let args = std::env::args()
                .skip(2)
                .filter(|a| a != "--all" && !a.starts_with("--manifest-path="));

            let args = std::iter::once(format!("--manifest-path={}", manifest_path)).chain(args);
            if let Some(first) = target.kind.get(0) {
                if target.kind.len() > 1 || first.ends_with("lib") {
                    println!("lib: {}", target.name);
                    if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
                        std::process::exit(code);
                    }
                } else if ["bin", "example", "test", "bench"].contains(&&**first) {
                    println!("{}: {}", first, target.name);
                    if let Err(code) = process(
                        vec![format!("--{}", first), target.name]
                            .into_iter()
                            .chain(args),
                    ) {
                        std::process::exit(code);
                    }
                }
            } else {
                panic!("badly formatted cargo metadata: target::kind is an empty array");
            }
        }
    }
}

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

    let mut found_dashes = false;
    for arg in old_args {
        found_dashes |= arg == "--";
        args.push(arg);
    }
    if !found_dashes {
        args.push("--".to_owned());
    }
    args.push("--emit=metadata".to_owned());
    args.push("--cfg".to_owned());
    args.push(r#"feature="cargo-clippy""#.to_owned());

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }
    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

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