<commit_before>/*
* rust-clean - Copyright (c) 2014 Gomez Guillaume.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim
*    that you wrote the original software. If you use this software in a product,
*    an acknowledgment in the product documentation would be appreciated but is
*    not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/

use std::io::fs;
use std::os;
use std::path::posix::Path;
use std::io::fs::PathExtensions;

struct CleanOptions {
    recursive: bool,
    verbose: bool,
    confirmation: bool
}

fn ask_confirmation(file: &Path) -> bool {
    loop {
        print!("clean: remove \x1b[37;1m'{}'\x1b[0m (y/n) ? ", file.as_str().unwrap());
        match std::io::stdio::stdin().read_line() {
            Ok(s) => {
                let tmp_s = s.replace("\r\n", "").replace("\n", "");

                if tmp_s.as_slice() == "y" || tmp_s.as_slice() == "yes" {
                    return true;
                } else if tmp_s.as_slice() == "n" || tmp_s.as_slice() == "no" {
                    return false;
                }
            }
            Err(_) => {}
        }
    }
}

fn start_clean(options: &CleanOptions, entry: &Path) {
    if entry.exists() {
        if entry.is_dir() {
            if options.recursive || entry.as_str().unwrap() == "." {
                match fs::readdir(entry) {
                    Ok(res) => {
                        if options.verbose {
                            println!("\x1b[36;1m-> Entering {}\x1b[0m", entry.as_str().unwrap());
                        }
                        for tmp in res.iter() {
                            start_clean(options, tmp);
                        }
                        if options.verbose {
                            println!("\x1b[34;1m<- Leaving {}\x1b[0m", entry.as_str().unwrap());
                        }
                    }
                    Err(e) => {
                        println!("\x1b[31;1mProblem with this directory: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                    }
                }
            }
        } else {
            match entry.filename() {
                Some(s) => {
                    if s.last().unwrap() == &('~' as u8) {
                        if !options.confirmation || ask_confirmation(&Path::new(s)) {
                            match fs::unlink(entry) {
                                Ok(_) => {
                                    if options.verbose {
                                        println!("\x1b[32;1m{} deleted\x1b[0m", entry.as_str().unwrap());
                                    }
                                }
                                Err(e) => {
                                    println!("\x1b[31;1mProblem with this file: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                                }
                            }
                        }
                    }
                }
                None => {
                    println!("\x1b[31;1mProblem with this file: {}\x1b[0m", entry.as_str().unwrap());
                }
            }
        }
    } else {
        println!("\x1b[31;1mProblem with this entry: {}\x1b[0m", entry.as_str().unwrap());
    }
}

fn print_help() {
    println!("./clean [options] [files | dirs]");
    println!("    -r : recursive mode");
    println!("    -v : verbose mode");
    println!("    -i : prompt before every removal");
    println!("--help : print this help");
}

fn main() {
    let mut args = os::args().clone();
    let mut options = CleanOptions{recursive: false, verbose: false, confirmation: false};
    let mut files = Vec::new();

    args.remove(0);
    for tmp in args.iter() {
        if tmp.clone().into_bytes()[0] == '-' as u8 {
            let mut tmp_arg = String::from_str(tmp.as_slice());

            tmp_arg.remove(0);
            if tmp_arg.len() > 0 {
                for character in tmp_arg.into_bytes().iter() {
                    match *character as char {
                        '-' => {
                            if tmp.as_slice() == "--help" {
                                print_help();
                                return;
                            }
                        }
                        'r' => {
                            options.recursive = true;
                        }
                        'v' => {
                            options.verbose = true;
                        }
                        'i' => {
                            options.confirmation = true;
                        }
                        _ => {
                            panic!("Unknown option: '{}', to have the options list, please launch with '-h' option\n", character);
                        }
                    }
                }
            } else {
                files.push(Path::new(tmp.as_slice()));
            }
        }
    }
    if files.len() == 0 {
        files.push(Path::new(String::from_str(".").as_slice()));
    }
    if options.verbose {
        println!("\x1b[33;1m=== VERBOSE MODE ===\x1b[0m");
    }
    for tmp in files.iter() {
        start_clean(&options, tmp);
    }
    if options.verbose {
        println!("\x1b[33;1mEnd of execution\x1b[0m");
    }
}<commit_msg>Update to last rustc version<commit_after>/*
* rust-clean - Copyright (c) 2014 Gomez Guillaume.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim
*    that you wrote the original software. If you use this software in a product,
*    an acknowledgment in the product documentation would be appreciated but is
*    not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/

#![allow(unstable)]

use std::io::fs;
use std::os;
use std::path::posix::Path;
use std::io::fs::PathExtensions;

struct CleanOptions {
    recursive: bool,
    verbose: bool,
    confirmation: bool
}

fn ask_confirmation(file: &Path) -> bool {
    loop {
        print!("clean: remove \x1b[37;1m'{}'\x1b[0m (y/n) ? ", file.as_str().unwrap());
        match std::io::stdio::stdin().read_line() {
            Ok(s) => {
                let tmp_s = s.replace("\r\n", "").replace("\n", "");

                if tmp_s.as_slice() == "y" || tmp_s.as_slice() == "yes" {
                    return true;
                } else if tmp_s.as_slice() == "n" || tmp_s.as_slice() == "no" {
                    return false;
                }
            }
            Err(_) => {}
        }
    }
}

fn start_clean(options: &CleanOptions, entry: &Path) {
    if entry.exists() {
        if entry.is_dir() {
            if options.recursive || entry.as_str().unwrap() == "." {
                match fs::readdir(entry) {
                    Ok(res) => {
                        if options.verbose {
                            println!("\x1b[36;1m-> Entering {}\x1b[0m", entry.as_str().unwrap());
                        }
                        for tmp in res.iter() {
                            start_clean(options, tmp);
                        }
                        if options.verbose {
                            println!("\x1b[34;1m<- Leaving {}\x1b[0m", entry.as_str().unwrap());
                        }
                    }
                    Err(e) => {
                        println!("\x1b[31;1mProblem with this directory: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                    }
                }
            }
        } else {
            match entry.filename() {
                Some(s) => {
                    if s.last().unwrap() == &('~' as u8) {
                        if !options.confirmation || ask_confirmation(&Path::new(s)) {
                            match fs::unlink(entry) {
                                Ok(_) => {
                                    if options.verbose {
                                        println!("\x1b[32;1m{} deleted\x1b[0m", entry.as_str().unwrap());
                                    }
                                }
                                Err(e) => {
                                    println!("\x1b[31;1mProblem with this file: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                                }
                            }
                        }
                    }
                }
                None => {
                    println!("\x1b[31;1mProblem with this file: {}\x1b[0m", entry.as_str().unwrap());
                }
            }
        }
    } else {
        println!("\x1b[31;1mProblem with this entry: {}\x1b[0m", entry.as_str().unwrap());
    }
}

fn print_help() {
    println!("./clean [options] [files | dirs]");
    println!("    -r : recursive mode");
    println!("    -v : verbose mode");
    println!("    -i : prompt before every removal");
    println!("--help : print this help");
}

fn main() {
    let mut args = os::args().clone();
    let mut options = CleanOptions{recursive: false, verbose: false, confirmation: false};
    let mut files = Vec::new();

    args.remove(0);
    for tmp in args.iter() {
        if tmp.clone().into_bytes()[0] == '-' as u8 {
            let mut tmp_arg = String::from_str(tmp.as_slice());

            tmp_arg.remove(0);
            if tmp_arg.len() > 0 {
                for character in tmp_arg.into_bytes().iter() {
                    match *character as char {
                        '-' => {
                            if tmp.as_slice() == "--help" {
                                print_help();
                                return;
                            }
                        }
                        'r' => {
                            options.recursive = true;
                        }
                        'v' => {
                            options.verbose = true;
                        }
                        'i' => {
                            options.confirmation = true;
                        }
                        _ => {
                            panic!("Unknown option: '{}', to have the options list, please launch with '-h' option\n", character);
                        }
                    }
                }
            } else {
                files.push(Path::new(tmp.as_slice()));
            }
        }
    }
    if files.len() == 0 {
        files.push(Path::new(String::from_str(".").as_slice()));
    }
    if options.verbose {
        println!("\x1b[33;1m=== VERBOSE MODE ===\x1b[0m");
    }
    for tmp in files.iter() {
        start_clean(&options, tmp);
    }
    if options.verbose {
        println!("\x1b[33;1mEnd of execution\x1b[0m");
    }
}<|endoftext|>


<commit_before>// Copyright (c) 2017 Viorel Bota
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

extern crate rppal;

use std::env;
use std::ffi::OsString;
use rppal::gpio::{GPIO,Mode,Level};

const LAST_PIN_NUMBER: u8 = 27;
const HELP_CMD_STR: &'static str = "help";
const SET_CMD_STR: &'static str = "set";
const GET_CMD_STR: &'static str = "get";
const HIGH_PIN_STATE_STR: &'static str = "high";
const LOW_PIN_STATE_STR: &'static str = "low";
const ALL_PINS_STR: &'static str = "all";
const HELP_EXAMPLE_STR: &'static str = "sudo ./pi3gpio help";

fn main() {
	handle_cmd ( env::args_os() );
}

fn handle_cmd (mut cmd: env::ArgsOs) {
	match cmd.nth(1) {
		Some (action) => {
			if action == OsString::from(HELP_CMD_STR) {
				print_help_text ();
			}
			else if action == OsString::from(SET_CMD_STR) {
				set_pins (cmd);
			}
			else if action == OsString::from(GET_CMD_STR) {
				read_pins (cmd);
			}
			else {
				panic! ("Unknown command {:?}! \nFor help run \"{}\"", action, HELP_EXAMPLE_STR );
			}
		},
		None => panic! ("No command found! \nFor help run \"{}\"", HELP_EXAMPLE_STR ),
	}
}

fn print_help_text () {
	println! ("SYNTAX: sudo ./pi3gpio command [state] [pins]");
	println! ("	command: ");
	println! ("		{}	prints the help text", HELP_CMD_STR );
	println! ("		{}	sets the value of the indicated pins to the indicated value", SET_CMD_STR );
	println! ("		{}	prints the state of the indicated pins", GET_CMD_STR );
	println! ("	state: ");
	println! ("		{}	logical 1 for the indicated pins, equivalent voltage 3.3[V]", HIGH_PIN_STATE_STR );
	println! ("		{}	logical 0 for the indicated pins, equivalent voltage 0[V]", LOW_PIN_STATE_STR );
	println! ("	pins: ");
	println! ("		{}	BCM pins between 0 and {}", ALL_PINS_STR, LAST_PIN_NUMBER );
	println! ("Examples:");
	println! ("	sudo ./pi3gpio help ");
	println! ("	sudo ./pi3gpio get all");
	println! ("	sudo ./pi3gpio get 4");
	println! ("	sudo ./pi3gpio get 10 11");
	println! ("	sudo ./pi3gpio set low all");
	println! ("	sudo ./pi3gpio set high 12");
	println! ("	sudo ./pi3gpio set low 2 5 7");
}

trait ReadState{
	fn read_state (self, gpio: &mut GPIO);
}

impl ReadState for OsString {
	fn read_state (self, gpio: &mut GPIO) {
		match self.to_u8() {
			Ok (pin) => read_pin ( gpio, pin ),
			Err (e) => {
				panic! ("{} \nFor help run \"{}\"", e,  HELP_EXAMPLE_STR );
			},
		}
	}
}

fn read_all_pins ( gpio: &mut GPIO ) {
	for pin in 0..(LAST_PIN_NUMBER+1) {
		read_pin ( gpio, pin );
	}
}

fn read_pin ( gpio: &mut GPIO, pin: u8) {
	gpio.set_mode( pin, Mode::Input );
	match gpio.read(pin) {
		Ok(state) =>	println! ("Pin {} = {:?}", pin, state ),
		Err (_) => println! ("Could not read state of pin {}",pin),
	}
}

fn read_pins (mut cmd: env::ArgsOs) {
	let mut gpio = initiate_gpio_handle();

	match cmd.nth(0) {
		Some (pin_as_os_string) => {
			if pin_as_os_string == OsString::from(ALL_PINS_STR) {
				read_all_pins ( &mut gpio );
				return;
			}
			else {
				pin_as_os_string.read_state ( &mut gpio );
			}
		}
		None => panic! ("Pin not found! \nFor help run \"{}\"",  HELP_EXAMPLE_STR ),
	}

	for argument in cmd {
		argument.read_state ( &mut gpio );
	}

}

trait ToU8 {
	fn to_u8 (self) -> Result<u8, &'static str >;
}

impl ToU8 for OsString {
	fn to_u8 (self) -> Result<u8, &'static str> {
		match self.into_string() {
			Ok(x) => match x.parse::<u8>() {
				Ok (y) => return Ok (y),
				Err(_) => return Err("String indicating pin number could not be converted to u8!" ),
			},
			Err(_) => return Err("OsString indicating pin number could not be converted to String!" ),
		}
	}
}

fn initiate_gpio_handle () -> GPIO {
    let gpio: GPIO;
    match GPIO::new(){
	    Ok (x) => gpio = x,
	    Err (e) => panic! ("Could not access GPIO memory! {}",e),
    }

    gpio
}

fn get_pin_state ( argument: Option<OsString>  ) -> Level {
	let mut pin_state = Level::Low;
	match argument {
		Some (state) => {
			if state == OsString::from(HIGH_PIN_STATE_STR) {
				pin_state = Level::High;
			}
			else if state != OsString::from(LOW_PIN_STATE_STR) {
				panic! ("State {:?} is invalid! \nFor help run \"{}\"", state, HELP_EXAMPLE_STR );
			}
		},
		None => panic! ("State not found! \nFor help run \"{}\"",  HELP_EXAMPLE_STR ),
	}

    pin_state
}

trait SetState{
	fn set_state (self, pin_state: Level ,gpio: &mut GPIO);
}

impl SetState for OsString {
	fn set_state (self, pin_state: Level, gpio: &mut GPIO) {
		match self.to_u8() {
			Ok (pin) => set_pin ( gpio, pin, pin_state ),
			Err (e) => {
				panic! ("{} \nFor help run \"{}\"", e,  HELP_EXAMPLE_STR );
			},
		}
	}
}

fn set_all_pins ( gpio: &mut GPIO, pin_state: Level ) {
	for pin in 0..(LAST_PIN_NUMBER+1) {
		set_pin ( gpio, pin, pin_state );
	}
}

fn set_pin ( gpio: &mut GPIO, pin: u8, pin_state: Level ) {
	println! ("Set pin {} to {:?}", pin, pin_state);
	gpio.set_mode( pin, Mode::Output );
	gpio.write ( pin, pin_state );
}

fn set_pins (mut cmd: env::ArgsOs) {
	let mut gpio = initiate_gpio_handle();
	gpio.set_clear_on_drop ( false );

	let pin_state = get_pin_state( cmd.nth(0) );

	match cmd.nth(0) {
		Some (pin_as_os_string) => {
			if pin_as_os_string == OsString::from(ALL_PINS_STR) {
				set_all_pins ( &mut gpio, pin_state );
				return;
			}
			else {
				pin_as_os_string.set_state( pin_state, &mut gpio );
			}

		}
		None => panic! ("Pin not found! \nFor help run \"{}\"",  HELP_EXAMPLE_STR ),
	}

	for argument in cmd {
		argument.set_state( pin_state, &mut gpio );
	}
}

// For library "rppal" version "0.1.2" the following LICENSE (MIT) applyes:
// "
//   Copyright (c) 2017 Rene van der Meer
//
//   Permission is hereby granted, free of charge, to any person obtaining a
//   copy of this software and associated documentation files (the "Software"),
//   to deal in the Software without restriction, including without limitation
//   the rights to use, copy, modify, merge, publish, distribute, sublicense,
//   and/or sell copies of the Software, and to permit persons to whom the
//   Software is furnished to do so, subject to the following conditions:
//
//   The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//   DEALINGS IN THE SOFTWARE.
// "

// For the "std" rust library the following LINCESE (MIT) applyes:
// "
//   Copyright (c) 2010 The Rust Project Developers
//
//   Permission is hereby granted, free of charge, to any
//   person obtaining a copy of this software and associated
//   documentation files (the "Software"), to deal in the
//   Software without restriction, including without
//   limitation the rights to use, copy, modify, merge,
//   publish, distribute, sublicense, and/or sell copies of
//   the Software, and to permit persons to whom the Software
//   is furnished to do so, subject to the following
//   conditions:
//
//   The above copyright notice and this permission notice
//   shall be included in all copies or substantial portions
//   of the Software.
//
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
//   ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//   TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
//   SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
//   IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//   DEALINGS IN THE SOFTWARE.
// "
<commit_msg>vesrion 0.1.6<commit_after>// Copyright (c) 2017 Viorel Bota
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

extern crate rppal;

use std::env;
use std::ffi::OsString;
use rppal::gpio::{GPIO,Mode,Level};

const LAST_PIN_NUMBER: u8 = 27;
const HELP_CMD_STR: &'static str = "help";
const SET_CMD_STR: &'static str = "set";
const GET_CMD_STR: &'static str = "get";
const HIGH_PIN_STATE_STR: &'static str = "high";
const LOW_PIN_STATE_STR: &'static str = "low";
const ALL_PINS_STR: &'static str = "all";
#[cfg(ignore_PATH)]
const APP_CALL_STR: &'static str = "./pi3gpio";
#[cfg(not(ignore_PATH))]
const APP_CALL_STR: &'static str = "pi3gpio";
#[cfg(ignore_PATH)]
const HELP_SUGGEST_STR: &'static str = "For help run \"sudo ./pi3gpio help\"";
#[cfg(not(ignore_PATH))]
const HELP_SUGGEST_STR: &'static str = "For help run \"sudo pi3gpio help\"";

fn main() {
	handle_cmd ( env::args_os() );
}

fn handle_cmd (mut cmd: env::ArgsOs) {
	match cmd.nth(1) {
		Some (action) => {
			if action == OsString::from(HELP_CMD_STR) {
				print_help_text ();
			}
			else if action == OsString::from(SET_CMD_STR) {
				set_pins (cmd);
			}
			else if action == OsString::from(GET_CMD_STR) {
				read_pins (cmd);
			}
			else {
				panic! ("Unknown command {:?}! \n{}", action, HELP_SUGGEST_STR );
			}
		},
		None => panic! ("No command found! \n{}", HELP_SUGGEST_STR ),
	}
}

fn print_help_text () {
	println! ("SYNTAX: sudo {} command [state] [pins]", APP_CALL_STR );
	println! ("	command: ");
	println! ("		{}	prints the help text", HELP_CMD_STR );
	println! ("		{}	sets the value of the indicated pins to the indicated value", SET_CMD_STR );
	println! ("		{}	prints the state of the indicated pins", GET_CMD_STR );
	println! ("	state: ");
	println! ("		{}	logical 1 for the indicated pins, equivalent voltage 3.3[V]", HIGH_PIN_STATE_STR );
	println! ("		{}	logical 0 for the indicated pins, equivalent voltage 0[V]", LOW_PIN_STATE_STR );
	println! ("	pins: ");
	println! ("		{}	BCM pins between 0 and {}", ALL_PINS_STR, LAST_PIN_NUMBER );
	println! ("Examples:");
	println! ("	sudo {} help ", APP_CALL_STR );
	println! ("	sudo {} get all", APP_CALL_STR );
	println! ("	sudo {} get 4", APP_CALL_STR );
	println! ("	sudo {} get 10 11", APP_CALL_STR );
	println! ("	sudo {} set low all", APP_CALL_STR );
	println! ("	sudo {} set high 12", APP_CALL_STR );
	println! ("	sudo {} set low 2 5 7", APP_CALL_STR );
	#[cfg(not(ignore_PATH))]
	{
		println! ("Access:");
		println! ("	The application needs access to /dev/mem or /dev/gpiomem to control GPIO pins. This is why sudo is required.");
		println! ("	In order to gain access to /dev/mem you need run, only once after installantion, the following commands:");
		println! ("		sudo snap connect pi3gpio:physical-memory-control core:physical-memory-control");
		println! ("		sudo snap connect pi3gpio:physical-memory-observe core:physical-memory-observe");
	}
}

trait ReadState{
	fn read_state (self, gpio: &mut GPIO);
}

impl ReadState for OsString {
	fn read_state (self, gpio: &mut GPIO) {
		match self.to_u8() {
			Ok (pin) => read_pin ( gpio, pin ),
			Err (e) => {
				panic! ("{} \n{}", e,  HELP_SUGGEST_STR );
			},
		}
	}
}

fn read_all_pins ( gpio: &mut GPIO ) {
	for pin in 0..(LAST_PIN_NUMBER+1) {
		read_pin ( gpio, pin );
	}
}

fn read_pin ( gpio: &mut GPIO, pin: u8) {
	gpio.set_mode( pin, Mode::Input );
	match gpio.read(pin) {
		Ok(state) =>	println! ("Pin {} = {:?}", pin, state ),
		Err (_) => println! ("Could not read state of pin {}",pin),
	}
}

fn read_pins (mut cmd: env::ArgsOs) {
	let mut gpio = initiate_gpio_handle();

	match cmd.nth(0) {
		Some (pin_as_os_string) => {
			if pin_as_os_string == OsString::from(ALL_PINS_STR) {
				read_all_pins ( &mut gpio );
				return;
			}
			else {
				pin_as_os_string.read_state ( &mut gpio );
			}
		}
		None => panic! ("Pin not found! \n{}",  HELP_SUGGEST_STR ),
	}

	for argument in cmd {
		argument.read_state ( &mut gpio );
	}

}

trait ToU8 {
	fn to_u8 (self) -> Result<u8, &'static str >;
}

impl ToU8 for OsString {
	fn to_u8 (self) -> Result<u8, &'static str> {
		match self.into_string() {
			Ok(x) => match x.parse::<u8>() {
				Ok (y) => return Ok (y),
				Err(_) => return Err("String indicating pin number could not be converted to u8!" ),
			},
			Err(_) => return Err("OsString indicating pin number could not be converted to String!" ),
		}
	}
}

fn initiate_gpio_handle () -> GPIO {
    let gpio: GPIO;
    match GPIO::new(){
	    Ok (x) => gpio = x,
	    Err (e) => panic! ("Could not access GPIO memory! {}",e),
    }

    gpio
}

fn get_pin_state ( argument: Option<OsString>  ) -> Level {
	let mut pin_state = Level::Low;
	match argument {
		Some (state) => {
			if state == OsString::from(HIGH_PIN_STATE_STR) {
				pin_state = Level::High;
			}
			else if state != OsString::from(LOW_PIN_STATE_STR) {
				panic! ("State {:?} is invalid! \n{}", state, HELP_SUGGEST_STR );
			}
		},
		None => panic! ("State not found! \n{}",  HELP_SUGGEST_STR ),
	}

    pin_state
}

trait SetState{
	fn set_state (self, pin_state: Level ,gpio: &mut GPIO);
}

impl SetState for OsString {
	fn set_state (self, pin_state: Level, gpio: &mut GPIO) {
		match self.to_u8() {
			Ok (pin) => set_pin ( gpio, pin, pin_state ),
			Err (e) => {
				panic! ("{} \n{}", e,  HELP_SUGGEST_STR );
			},
		}
	}
}

fn set_all_pins ( gpio: &mut GPIO, pin_state: Level ) {
	for pin in 0..(LAST_PIN_NUMBER+1) {
		set_pin ( gpio, pin, pin_state );
	}
}

fn set_pin ( gpio: &mut GPIO, pin: u8, pin_state: Level ) {
	println! ("Set pin {} to {:?}", pin, pin_state);
	gpio.set_mode( pin, Mode::Output );
	gpio.write ( pin, pin_state );
}

fn set_pins (mut cmd: env::ArgsOs) {
	let mut gpio = initiate_gpio_handle();
	gpio.set_clear_on_drop ( false );

	let pin_state = get_pin_state( cmd.nth(0) );

	match cmd.nth(0) {
		Some (pin_as_os_string) => {
			if pin_as_os_string == OsString::from(ALL_PINS_STR) {
				set_all_pins ( &mut gpio, pin_state );
				return;
			}
			else {
				pin_as_os_string.set_state( pin_state, &mut gpio );
			}

		}
		None => panic! ("Pin not found! \n{}",  HELP_SUGGEST_STR ),
	}

	for argument in cmd {
		argument.set_state( pin_state, &mut gpio );
	}
}

// For library "rppal" version "0.1.2" the following LICENSE (MIT) applyes:
// "
//   Copyright (c) 2017 Rene van der Meer
//
//   Permission is hereby granted, free of charge, to any person obtaining a
//   copy of this software and associated documentation files (the "Software"),
//   to deal in the Software without restriction, including without limitation
//   the rights to use, copy, modify, merge, publish, distribute, sublicense,
//   and/or sell copies of the Software, and to permit persons to whom the
//   Software is furnished to do so, subject to the following conditions:
//
//   The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//   DEALINGS IN THE SOFTWARE.
// "

// For the "std" rust library the following LINCESE (MIT) applyes:
// "
//   Copyright (c) 2010 The Rust Project Developers
//
//   Permission is hereby granted, free of charge, to any
//   person obtaining a copy of this software and associated
//   documentation files (the "Software"), to deal in the
//   Software without restriction, including without
//   limitation the rights to use, copy, modify, merge,
//   publish, distribute, sublicense, and/or sell copies of
//   the Software, and to permit persons to whom the Software
//   is furnished to do so, subject to the following
//   conditions:
//
//   The above copyright notice and this permission notice
//   shall be included in all copies or substantial portions
//   of the Software.
//
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
//   ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//   TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
//   SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
//   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
//   IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//   DEALINGS IN THE SOFTWARE.
// "
<|endoftext|>


<commit_before>#![cfg_attr(all(windows, feature = "ui"), windows_subsystem = "windows")]
#![recursion_limit = "256"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;

use log::info;
use simplelog::{
	ColorChoice, CombinedLogger, LevelFilter, SharedLogger, TermLogger, TerminalMode, WriteLogger,
};
use std::fs;
use std::path::{Path, PathBuf};

mod app;
mod db;
mod options;
mod paths;
mod service;
#[cfg(test)]
mod test;
mod ui;
mod utils;

#[derive(thiserror::Error, Debug)]
pub enum Error {
	#[error(transparent)]
	App(#[from] app::Error),
	#[error("Could not parse command line arguments:\n\n{0}")]
	CliArgsParsing(getopts::Fail),
	#[cfg(unix)]
	#[error("Failed to turn polaris process into a daemon:\n\n{0}")]
	Daemonize(daemonize::DaemonizeError),
	#[error("Could not create log directory `{0}`:\n\n{1}")]
	LogDirectoryCreationError(PathBuf, std::io::Error),
	#[error("Could not create log file `{0}`:\n\n{1}")]
	LogFileCreationError(PathBuf, std::io::Error),
	#[error("Could not initialize log system:\n\n{0}")]
	LogInitialization(log::SetLoggerError),
	#[cfg(unix)]
	#[error("Could not create pid directory `{0}`:\n\n{1}")]
	PidDirectoryCreationError(PathBuf, std::io::Error),
	#[cfg(unix)]
	#[error("Could not notify systemd of initialization success:\n\n{0}")]
	SystemDNotify(std::io::Error),
}

#[cfg(unix)]
fn daemonize<T: AsRef<Path>>(foreground: bool, pid_file_path: T) -> Result<(), Error> {
	if foreground {
		return Ok(());
	}
	if let Some(parent) = pid_file_path.as_ref().parent() {
		fs::create_dir_all(parent)
			.map_err(|e| Error::PidDirectoryCreationError(parent.to_owned(), e))?;
	}
	let daemonize = daemonize::Daemonize::new()
		.pid_file(pid_file_path.as_ref())
		.working_directory(".");
	daemonize.start().map_err(Error::Daemonize)?;
	Ok(())
}

#[cfg(unix)]
fn notify_ready() -> Result<(), Error> {
	if let Ok(true) = sd_notify::booted() {
		sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).map_err(Error::SystemDNotify);
	}
	Ok(())
}

fn init_logging<T: AsRef<Path>>(
	log_level: LevelFilter,
	log_file_path: &Option<T>,
) -> Result<(), Error> {
	let log_config = simplelog::ConfigBuilder::new()
		.set_location_level(LevelFilter::Error)
		.build();

	let mut loggers: Vec<Box<dyn SharedLogger>> = vec![TermLogger::new(
		log_level,
		log_config.clone(),
		TerminalMode::Mixed,
		ColorChoice::Auto,
	)];

	if let Some(path) = log_file_path {
		if let Some(parent) = path.as_ref().parent() {
			fs::create_dir_all(parent)
				.map_err(|e| Error::LogDirectoryCreationError(parent.to_owned(), e))?;
		}
		loggers.push(WriteLogger::new(
			log_level,
			log_config,
			fs::File::create(path)
				.map_err(|e| Error::LogFileCreationError(path.as_ref().to_owned(), e))?,
		));
	}

	CombinedLogger::init(loggers).map_err(Error::LogInitialization)?;

	Ok(())
}

fn main() -> Result<(), Error> {
	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let options_manager = options::Manager::new();
	let cli_options = options_manager
		.parse(&args[1..])
		.map_err(Error::CliArgsParsing)?;

	if cli_options.show_help {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options_manager.usage(&brief));
		return Ok(());
	}

	let paths = paths::Paths::new(&cli_options);

	// Logging
	let log_level = cli_options.log_level.unwrap_or(LevelFilter::Info);
	init_logging(log_level, &paths.log_file_path)?;

	// Fork
	#[cfg(unix)]
	daemonize(cli_options.foreground, &paths.pid_file_path)?;

	info!("Cache files location is {:#?}", paths.cache_dir_path);
	info!("Config files location is {:#?}", paths.config_file_path);
	info!("Database file location is {:#?}", paths.db_file_path);
	info!("Log file location is {:#?}", paths.log_file_path);
	#[cfg(unix)]
	if !cli_options.foreground {
		info!("Pid file location is {:#?}", paths.pid_file_path);
	}
	info!("Swagger files location is {:#?}", paths.swagger_dir_path);
	info!("Web client files location is {:#?}", paths.web_dir_path);

	// Create and run app
	let app = app::App::new(cli_options.port.unwrap_or(5050), paths)?;
	app.index.begin_periodic_updates();
	app.ddns_manager.begin_periodic_updates();

	// Start server
	info!("Starting up server");
	std::thread::spawn(move || {
		let _ = service::run(app);
	});

	// Send readiness notification
	#[cfg(unix)]
	notify_ready()?;

	// Run UI
	ui::run();

	info!("Shutting down server");
	Ok(())
}
<commit_msg>Fixed a bug where systemd init error would not display<commit_after>#![cfg_attr(all(windows, feature = "ui"), windows_subsystem = "windows")]
#![recursion_limit = "256"]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;

use log::info;
use simplelog::{
	ColorChoice, CombinedLogger, LevelFilter, SharedLogger, TermLogger, TerminalMode, WriteLogger,
};
use std::fs;
use std::path::{Path, PathBuf};

mod app;
mod db;
mod options;
mod paths;
mod service;
#[cfg(test)]
mod test;
mod ui;
mod utils;

#[derive(thiserror::Error, Debug)]
pub enum Error {
	#[error(transparent)]
	App(#[from] app::Error),
	#[error("Could not parse command line arguments:\n\n{0}")]
	CliArgsParsing(getopts::Fail),
	#[cfg(unix)]
	#[error("Failed to turn polaris process into a daemon:\n\n{0}")]
	Daemonize(daemonize::DaemonizeError),
	#[error("Could not create log directory `{0}`:\n\n{1}")]
	LogDirectoryCreationError(PathBuf, std::io::Error),
	#[error("Could not create log file `{0}`:\n\n{1}")]
	LogFileCreationError(PathBuf, std::io::Error),
	#[error("Could not initialize log system:\n\n{0}")]
	LogInitialization(log::SetLoggerError),
	#[cfg(unix)]
	#[error("Could not create pid directory `{0}`:\n\n{1}")]
	PidDirectoryCreationError(PathBuf, std::io::Error),
	#[cfg(unix)]
	#[error("Could not notify systemd of initialization success:\n\n{0}")]
	SystemDNotify(std::io::Error),
}

#[cfg(unix)]
fn daemonize<T: AsRef<Path>>(foreground: bool, pid_file_path: T) -> Result<(), Error> {
	if foreground {
		return Ok(());
	}
	if let Some(parent) = pid_file_path.as_ref().parent() {
		fs::create_dir_all(parent)
			.map_err(|e| Error::PidDirectoryCreationError(parent.to_owned(), e))?;
	}
	let daemonize = daemonize::Daemonize::new()
		.pid_file(pid_file_path.as_ref())
		.working_directory(".");
	daemonize.start().map_err(Error::Daemonize)?;
	Ok(())
}

#[cfg(unix)]
fn notify_ready() -> Result<(), Error> {
	if let Ok(true) = sd_notify::booted() {
		sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).map_err(Error::SystemDNotify)?;
	}
	Ok(())
}

fn init_logging<T: AsRef<Path>>(
	log_level: LevelFilter,
	log_file_path: &Option<T>,
) -> Result<(), Error> {
	let log_config = simplelog::ConfigBuilder::new()
		.set_location_level(LevelFilter::Error)
		.build();

	let mut loggers: Vec<Box<dyn SharedLogger>> = vec![TermLogger::new(
		log_level,
		log_config.clone(),
		TerminalMode::Mixed,
		ColorChoice::Auto,
	)];

	if let Some(path) = log_file_path {
		if let Some(parent) = path.as_ref().parent() {
			fs::create_dir_all(parent)
				.map_err(|e| Error::LogDirectoryCreationError(parent.to_owned(), e))?;
		}
		loggers.push(WriteLogger::new(
			log_level,
			log_config,
			fs::File::create(path)
				.map_err(|e| Error::LogFileCreationError(path.as_ref().to_owned(), e))?,
		));
	}

	CombinedLogger::init(loggers).map_err(Error::LogInitialization)?;

	Ok(())
}

fn main() -> Result<(), Error> {
	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let options_manager = options::Manager::new();
	let cli_options = options_manager
		.parse(&args[1..])
		.map_err(Error::CliArgsParsing)?;

	if cli_options.show_help {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options_manager.usage(&brief));
		return Ok(());
	}

	let paths = paths::Paths::new(&cli_options);

	// Logging
	let log_level = cli_options.log_level.unwrap_or(LevelFilter::Info);
	init_logging(log_level, &paths.log_file_path)?;

	// Fork
	#[cfg(unix)]
	daemonize(cli_options.foreground, &paths.pid_file_path)?;

	info!("Cache files location is {:#?}", paths.cache_dir_path);
	info!("Config files location is {:#?}", paths.config_file_path);
	info!("Database file location is {:#?}", paths.db_file_path);
	info!("Log file location is {:#?}", paths.log_file_path);
	#[cfg(unix)]
	if !cli_options.foreground {
		info!("Pid file location is {:#?}", paths.pid_file_path);
	}
	info!("Swagger files location is {:#?}", paths.swagger_dir_path);
	info!("Web client files location is {:#?}", paths.web_dir_path);

	// Create and run app
	let app = app::App::new(cli_options.port.unwrap_or(5050), paths)?;
	app.index.begin_periodic_updates();
	app.ddns_manager.begin_periodic_updates();

	// Start server
	info!("Starting up server");
	std::thread::spawn(move || {
		let _ = service::run(app);
	});

	// Send readiness notification
	#[cfg(unix)]
	notify_ready()?;

	// Run UI
	ui::run();

	info!("Shutting down server");
	Ok(())
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate num;
// Couldn't find anything using this so ¯\_(ツ)_/¯
//extern crate native;
// This is grabbed from a .so file. When googling "librsfml" I literally
// got 6 results, 1 from this project. It seems to have been renamed
// so let's try to use that instead even if it looks like it will break
// many things.
//extern crate rsfml;
extern crate sfml;
extern crate collections;

// idk wth these lines were used for, couldn't find any other references
// and the compiler complained. If the code doesn't use it maybe the
// compiler does?
//#[feature(phase)]extern crate log;
//#[phase(syntax, link)]

use sfml::window::{event};

use engine::resource_loader;
//use engine::world;
use engine::settings;
use engine::rendering;
use engine::event_queue;
use engine::state;
use engine::state::EngineState::EngineShutdown;

//use engine::math;

pub mod engine;
pub mod game;
pub mod heart;

fn main () -> () {
    let mut settings = settings::Settings::new("settings".to_string());
    let mut window =  rendering::Window::new(800, 600, "equinox".to_string(), false);
    let mut event_queue = event_queue::EventQueue::new();
    let mut render_queue = rendering::RenderQueue::new();
    let mut resource_loader = resource_loader::ResourceLoader::new();
    let mut state_machine = state::StateMachine::uninitialized();

    //load all resources required by the game
    game::load_resources(&mut resource_loader);

    //create all states
    let render_context = window.get_context();
    game::init_states(&mut state_machine, &resource_loader, &render_context, &settings);

    while window.is_open() {
        loop {
            let event = window.poll();

            match event {
                //HACK - this should be removed..
                //event::Closed => window.close(),
                event::NoEvent => break,

                _ => { event_queue.send_event(&event) }
            }
        }

        let engine_state =  state_machine.tick(1.0 / 60.0, &mut event_queue, &mut render_queue);

        match engine_state {
            EngineShutdown => { window.close() }
            _ => {}
        }

        render_queue.render(&mut window);
        window.display();
    }

}
<commit_msg>Remove an old unused(?) crate<commit_after>extern crate rustc_serialize;
extern crate num;
// Couldn't find anything using this so ¯\_(ツ)_/¯
//extern crate native;
// This is grabbed from a .so file. When googling "librsfml" I literally
// got 6 results, 1 from this project. It seems to have been renamed
// so let's try to use that instead even if it looks like it will break
// many things.
//extern crate rsfml;
extern crate sfml;

// idk wth these lines were used for, couldn't find any other references
// and the compiler complained. If the code doesn't use it maybe the
// compiler does?
//#[feature(phase)]extern crate log;
//#[phase(syntax, link)]

use sfml::window::{event};

use engine::resource_loader;
//use engine::world;
use engine::settings;
use engine::rendering;
use engine::event_queue;
use engine::state;
use engine::state::EngineState::EngineShutdown;

use std::collections;

//use engine::math;

pub mod engine;
pub mod game;
pub mod heart;

fn main () -> () {
    let mut settings = settings::Settings::new("settings".to_string());
    let mut window =  rendering::Window::new(800, 600, "equinox".to_string(), false);
    let mut event_queue = event_queue::EventQueue::new();
    let mut render_queue = rendering::RenderQueue::new();
    let mut resource_loader = resource_loader::ResourceLoader::new();
    let mut state_machine = state::StateMachine::uninitialized();

    //load all resources required by the game
    game::load_resources(&mut resource_loader);

    //create all states
    let render_context = window.get_context();
    game::init_states(&mut state_machine, &resource_loader, &render_context, &settings);

    while window.is_open() {
        loop {
            let event = window.poll();

            match event {
                //HACK - this should be removed..
                //event::Closed => window.close(),
                event::NoEvent => break,

                _ => { event_queue.send_event(&event) }
            }
        }

        let engine_state =  state_machine.tick(1.0 / 60.0, &mut event_queue, &mut render_queue);

        match engine_state {
            EngineShutdown => { window.close() }
            _ => {}
        }

        render_queue.render(&mut window);
        window.display();
    }

}
<|endoftext|>


<commit_before>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::SSL_SUPPORT;
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("ssl_support")
                .long("ssl_support")
                .short("s")
                .help("Active the SSL Client to download files"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    // Get the URL as a Path structure
    let url = Path::new(argparse.value_of("url").unwrap());

    // Set the mirrors vectors
    let mut servers_urls: Vec<&str> = match url.parent() {
        Some(parent) => vec![parent.to_str().unwrap()],
        None => vec![],
    };
    // Set given mirrors
    if argparse.is_present("mirrors") {
        let mirrors_vec: Vec<&str> = argparse.values_of("mirrors").unwrap().collect();
        for mirror in mirrors_vec {
            servers_urls.push(mirror);
        }
    }

    // Get the path filename
    let filename = url.file_name().unwrap().to_str().unwrap();

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
            Ok(v)
        } else {
            Err(clap::Error::with_description(
                "Cannot download a file using 0 thread",
                clap::ErrorKind::InvalidValue,
            ))
        })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    unsafe {
        SSL_SUPPORT = argparse.is_present("ssl_support");
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!(
                "The local path to store the remote content is already exists, \
                        and is a directory!"
            );
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user(
                "The path to store the file already exists! \
                                          Do you want to override it? [y/N]",
            );
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!(
                "The path to store the file already exists! \
                                 It is going to be overriden."
            );
        }
    }

    let cargo_info = get_cargo_info(filename, servers_urls).expect("fail to parse url");
    info!(&format!(
        "Remote content length: {}",
        format_filesize(cargo_info.content_length)
    ));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file.set_len(cargo_info.content_length).expect(
        "Cannot extend local file !",
    );
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!(
            "The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread."
        );
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, filename) {
        ok!(&format!(
            "Your download is available in {}",
            local_path.to_str().unwrap()
        ));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<commit_msg>Remove SSL_SUPPORT static variable usage<commit_after>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("ssl_support")
                .long("ssl_support")
                .short("s")
                .help("Active the SSL Client to download files"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    // Get the URL as a Path structure
    let url = Path::new(argparse.value_of("url").unwrap());

    // Set the mirrors vectors
    let mut servers_urls: Vec<&str> = match url.parent() {
        Some(parent) => vec![parent.to_str().unwrap()],
        None => vec![],
    };
    // Set given mirrors
    if argparse.is_present("mirrors") {
        let mirrors_vec: Vec<&str> = argparse.values_of("mirrors").unwrap().collect();
        for mirror in mirrors_vec {
            servers_urls.push(mirror);
        }
    }

    // Get the path filename
    let filename = url.file_name().unwrap().to_str().unwrap();

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
            Ok(v)
        } else {
            Err(clap::Error::with_description(
                "Cannot download a file using 0 thread",
                clap::ErrorKind::InvalidValue,
            ))
        })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!(
                "The local path to store the remote content is already exists, \
                        and is a directory!"
            );
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user(
                "The path to store the file already exists! \
                                          Do you want to override it? [y/N]",
            );
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!(
                "The path to store the file already exists! \
                                 It is going to be overriden."
            );
        }
    }

    let cargo_info = get_cargo_info(filename, servers_urls).expect("fail to parse url");
    info!(&format!(
        "Remote content length: {}",
        format_filesize(cargo_info.content_length)
    ));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file.set_len(cargo_info.content_length).expect(
        "Cannot extend local file !",
    );
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!(
            "The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread."
        );
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, filename) {
        ok!(&format!(
            "Your download is available in {}",
            local_path.to_str().unwrap()
        ));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io;
use std::io::Read;
use std::env;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Instruction {
    Right,
    Left,
    Increment,
    Decrement,
    Output,
    Input,
    JumpOpen(usize),
    JumpClose(usize),
    Comment(char),
    End,
}

impl From<char> for Instruction {
    fn from(c: char) -> Instruction {
        match c {
            '>' => Instruction::Right,
            '<' => Instruction::Left,
            '+' => Instruction::Increment,
            '-' => Instruction::Decrement,
            '.' => Instruction::Output,
            ',' => Instruction::Input,
            '[' => Instruction::JumpOpen(0),
            ']' => Instruction::JumpClose(0),
            c => Instruction::Comment(c),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Programme {
    instructions: Vec<Instruction>,
    index: usize,
}

impl Programme {

    fn parse<S>(source: S) -> Programme
        where S: Into<String>
    {

        let s = source.into();

        let mut instructions = Vec::new();
        let mut braces = Vec::new();

        let mut instr_id = 0;
        for c in s.chars() {

            let mut instr = Instruction::from(c);

            match instr {
                Instruction::Comment(_) => continue,
                Instruction::JumpOpen(_) => braces.push(instr_id),
                Instruction::JumpClose(_) => {
                    let i_open = braces.pop().unwrap();
                    instructions[i_open] = Instruction::JumpOpen(instr_id - i_open);
                    instr = Instruction::JumpClose(instr_id - i_open);
                },
                _ => {},
            }
            instructions.push(instr);
            instr_id += 1;

        }

        instructions.push(Instruction::End);

        Programme{instructions: instructions, index: 0}

    }

    fn step(&mut self, ms: &mut MachineState) {
        match self.instructions[self.index] {
            Instruction::Right => ms.index += 1,
            Instruction::Left => ms.index -= 1,
            Instruction::Increment => ms.tape[ms.index] = ms.tape[ms.index].wrapping_add(1),
            Instruction::Decrement => ms.tape[ms.index] = ms.tape[ms.index].wrapping_sub(1),
            Instruction::Output => print!("{}", ms.tape[ms.index] as char),
            Instruction::Input => ms.tape[ms.index] = match io::stdin().bytes().next() {
                Some(r) => r.unwrap_or(0),
                None => 0,
            },
            Instruction::JumpOpen(offset) => if ms.tape[ms.index] == 0 {
                self.index += offset;
            },
            Instruction::JumpClose(offset) => if ms.tape[ms.index] != 0 {
                self.index -= offset + 1;
            },
            Instruction::Comment(_) => {},
            Instruction::End => return,
        }
        self.index += 1;
    }

    fn execute(&mut self, mut ms: &mut MachineState) {
        while self.instructions[self.index] != Instruction::End {
            self.step(&mut ms);
        }
    }

}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct MachineState {
    tape: Vec<u8>,
    index: usize,
}

fn main() {

    let argv: Vec<String> = env::args().collect();

    let mut file = File::open(&argv[1]).unwrap();
    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();

    let mut prgm = Programme::parse(buffer);

    let mut state = MachineState{
        tape: vec![0u8; 256],
        .. MachineState::default()
    };

    prgm.execute(&mut state);

}
<commit_msg>extend tape to 8k<commit_after>use std::fs::File;
use std::io;
use std::io::Read;
use std::env;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Instruction {
    Right,
    Left,
    Increment,
    Decrement,
    Output,
    Input,
    JumpOpen(usize),
    JumpClose(usize),
    Comment(char),
    End,
}

impl From<char> for Instruction {
    fn from(c: char) -> Instruction {
        match c {
            '>' => Instruction::Right,
            '<' => Instruction::Left,
            '+' => Instruction::Increment,
            '-' => Instruction::Decrement,
            '.' => Instruction::Output,
            ',' => Instruction::Input,
            '[' => Instruction::JumpOpen(0),
            ']' => Instruction::JumpClose(0),
            c => Instruction::Comment(c),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Programme {
    instructions: Vec<Instruction>,
    index: usize,
}

impl Programme {

    fn parse<S>(source: S) -> Programme
        where S: Into<String>
    {

        let s = source.into();

        let mut instructions = Vec::new();
        let mut braces = Vec::new();

        let mut instr_id = 0;
        for c in s.chars() {

            let mut instr = Instruction::from(c);

            match instr {
                Instruction::Comment(_) => continue,
                Instruction::JumpOpen(_) => braces.push(instr_id),
                Instruction::JumpClose(_) => {
                    let i_open = braces.pop().unwrap();
                    instructions[i_open] = Instruction::JumpOpen(instr_id - i_open);
                    instr = Instruction::JumpClose(instr_id - i_open);
                },
                _ => {},
            }
            instructions.push(instr);
            instr_id += 1;

        }

        instructions.push(Instruction::End);

        Programme{instructions: instructions, index: 0}

    }

    fn step(&mut self, ms: &mut MachineState) {
        match self.instructions[self.index] {
            Instruction::Right => ms.index += 1,
            Instruction::Left => ms.index -= 1,
            Instruction::Increment => ms.tape[ms.index] = ms.tape[ms.index].wrapping_add(1),
            Instruction::Decrement => ms.tape[ms.index] = ms.tape[ms.index].wrapping_sub(1),
            Instruction::Output => print!("{}", ms.tape[ms.index] as char),
            Instruction::Input => ms.tape[ms.index] = match io::stdin().bytes().next() {
                Some(r) => r.unwrap_or(0),
                None => 0,
            },
            Instruction::JumpOpen(offset) => if ms.tape[ms.index] == 0 {
                self.index += offset;
            },
            Instruction::JumpClose(offset) => if ms.tape[ms.index] != 0 {
                self.index -= offset + 1;
            },
            Instruction::Comment(_) => {},
            Instruction::End => return,
        }
        self.index += 1;
    }

    fn execute(&mut self, mut ms: &mut MachineState) {
        while self.instructions[self.index] != Instruction::End {
            self.step(&mut ms);
        }
    }

}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct MachineState {
    tape: Vec<u8>,
    index: usize,
}

fn main() {

    let argv: Vec<String> = env::args().collect();

    let mut file = File::open(&argv[1]).unwrap();
    let mut buffer = String::new();
    file.read_to_string(&mut buffer).unwrap();

    let mut prgm = Programme::parse(buffer);

    let mut state = MachineState{
        tape: vec![0u8; 8192],
        .. MachineState::default()
    };

    prgm.execute(&mut state);

}
<|endoftext|>


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

use std::sync::Arc;

use clap::{App, AppSettings, Arg, SubCommand};

const VERSION: &str = env!("CARGO_PKG_VERSION");

#[tokio::main]
async fn main() -> quilkin::Result<()> {
    let log = quilkin::logger();
    let version: std::borrow::Cow<'static, str> = if cfg!(debug_assertions) {
        format!("{}+debug", VERSION).into()
    } else {
        VERSION.into()
    };

    let config_arg = Arg::with_name("config")
        .short("c")
        .long("config")
        .value_name("CONFIG")
        .help("The YAML configuration file")
        .takes_value(true);

    let cli = App::new(clap::crate_name!())
        .version(&*version)
        .about(clap::crate_description!())
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(
            SubCommand::with_name("run")
                .about("Start Quilkin process.")
                .arg(config_arg.clone()),
        )
        .subcommand(
            SubCommand::with_name("test")
                .about("Execute one or more sets of tests.")
                .arg(config_arg),
        )
        .get_matches();

    slog::info!(log, "Starting Quilkin"; "version" => &*version);

    match cli.subcommand() {
        ("run", Some(matches)) => {
            let config =
                quilkin::config::Config::find(&log, matches.value_of("config")).map(Arc::new)?;

            quilkin::run_with_config(log, config, vec![]).await
        }

        ("test", Some(_matches)) => todo!(),

        (_, _) => unreachable!(),
    }
}
<commit_msg>Remove test subcommand from clap for 0.2 (#386)<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use std::sync::Arc;

use clap::{App, AppSettings, Arg, SubCommand};

const VERSION: &str = env!("CARGO_PKG_VERSION");

#[tokio::main]
async fn main() -> quilkin::Result<()> {
    let log = quilkin::logger();
    let version: std::borrow::Cow<'static, str> = if cfg!(debug_assertions) {
        format!("{}+debug", VERSION).into()
    } else {
        VERSION.into()
    };

    let config_arg = Arg::with_name("config")
        .short("c")
        .long("config")
        .value_name("CONFIG")
        .help("The YAML configuration file")
        .takes_value(true);

    let cli = App::new(clap::crate_name!())
        .version(&*version)
        .about(clap::crate_description!())
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(
            SubCommand::with_name("run")
                .about("Start Quilkin process.")
                .arg(config_arg.clone()),
        )
        .get_matches();

    slog::info!(log, "Starting Quilkin"; "version" => &*version);

    match cli.subcommand() {
        ("run", Some(matches)) => {
            let config =
                quilkin::config::Config::find(&log, matches.value_of("config")).map(Arc::new)?;

            quilkin::run_with_config(log, config, vec![]).await
        }

        (_, _) => unreachable!(),
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]

use rustc_tools_util::VersionInfo;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use std::process::{self, Command};

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

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

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

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

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

You can use tool lints to allow or deny lints from your code, eg.:

    #[allow(clippy::needless_lifetimes)]
"#;

fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

fn show_version() {
    let version_info = rustc_tools_util::get_version_info!();
    println!("{}", version_info);
}

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

    if env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

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

struct ClippyCmd {
    unstable_options: bool,
    cargo_subcommand: &'static str,
    args: Vec<String>,
    clippy_args: Vec<String>,
}

impl ClippyCmd {
    fn new<I>(mut old_args: I) -> Self
    where
        I: Iterator<Item = String>,
    {
        let mut cargo_subcommand = "check";
        let mut unstable_options = false;
        let mut args = vec![];

        for arg in old_args.by_ref() {
            match arg.as_str() {
                "--fix" => {
                    cargo_subcommand = "fix";
                    continue;
                },
                "--" => break,
                // Cover -Zunstable-options and -Z unstable-options
                s if s.ends_with("unstable-options") => unstable_options = true,
                _ => {},
            }

            args.push(arg);
        }

        if cargo_subcommand == "fix" && !unstable_options {
            panic!("Usage of `--fix` requires `-Z unstable-options`");
        }

        // Run the dogfood tests directly on nightly cargo. This is required due
        // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118.
        if env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) {
            args.insert(0, "+nightly".to_string());
        }

        let mut clippy_args: Vec<String> = old_args.collect();
        if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") {
            clippy_args.push("--no-deps".into());
        }

        ClippyCmd {
            unstable_options,
            cargo_subcommand,
            args,
            clippy_args,
        }
    }

    fn path_env(&self) -> &'static str {
        if self.unstable_options {
            "RUSTC_WORKSPACE_WRAPPER"
        } else {
            "RUSTC_WRAPPER"
        }
    }

    fn path() -> PathBuf {
        let mut path = env::current_exe()
            .expect("current executable path invalid")
            .with_file_name("clippy-driver");

        if cfg!(windows) {
            path.set_extension("exe");
        }

        path
    }

    fn target_dir() -> Option<(&'static str, OsString)> {
        env::var_os("CLIPPY_DOGFOOD")
            .map(|_| {
                env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                    || std::ffi::OsString::from("clippy_dogfood"),
                    |d| {
                        std::path::PathBuf::from(d)
                            .join("target")
                            .join("dogfood")
                            .into_os_string()
                    },
                )
            })
            .map(|p| ("CARGO_TARGET_DIR", p))
    }

    fn into_std_cmd(self) -> Command {
        let mut cmd = Command::new("cargo");
        let clippy_args: String = self
            .clippy_args
            .iter()
            .map(|arg| format!("{}__CLIPPY_HACKERY__", arg))
            .collect();

        cmd.env(self.path_env(), Self::path())
            .envs(ClippyCmd::target_dir())
            .env("CLIPPY_ARGS", clippy_args)
            .arg(self.cargo_subcommand)
            .args(&self.args);

        cmd
    }
}

fn process<I>(old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let cmd = ClippyCmd::new(old_args);

    let mut cmd = cmd.into_std_cmd();

    let exit_status = cmd
        .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))
    }
}

#[cfg(test)]
mod tests {
    use super::ClippyCmd;

    #[test]
    #[should_panic]
    fn fix_without_unstable() {
        let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
        let _ = ClippyCmd::new(args);
    }

    #[test]
    fn fix_unstable() {
        let args = "cargo clippy --fix -Zunstable-options"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!("fix", cmd.cargo_subcommand);
        assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
        assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
    }

    #[test]
    fn fix_implies_no_deps() {
        let args = "cargo clippy --fix -Zunstable-options"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps"));
    }

    #[test]
    fn no_deps_not_duplicated_with_fix() {
        let args = "cargo clippy --fix -Zunstable-options -- --no-deps"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1);
    }

    #[test]
    fn check() {
        let args = "cargo clippy".split_whitespace().map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!("check", cmd.cargo_subcommand);
        assert_eq!("RUSTC_WRAPPER", cmd.path_env());
    }

    #[test]
    fn check_unstable() {
        let args = "cargo clippy -Zunstable-options"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!("check", cmd.cargo_subcommand);
        assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
    }
}
<commit_msg>Stabilize workspace wrapper.<commit_after>#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
#![warn(rust_2018_idioms, unused_lifetimes)]

use rustc_tools_util::VersionInfo;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use std::process::{self, Command};

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

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

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

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

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

You can use tool lints to allow or deny lints from your code, eg.:

    #[allow(clippy::needless_lifetimes)]
"#;

fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

fn show_version() {
    let version_info = rustc_tools_util::get_version_info!();
    println!("{}", version_info);
}

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

    if env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

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

struct ClippyCmd {
    cargo_subcommand: &'static str,
    args: Vec<String>,
    clippy_args: Vec<String>,
}

impl ClippyCmd {
    fn new<I>(mut old_args: I) -> Self
    where
        I: Iterator<Item = String>,
    {
        let mut cargo_subcommand = "check";
        let mut unstable_options = false;
        let mut args = vec![];

        for arg in old_args.by_ref() {
            match arg.as_str() {
                "--fix" => {
                    cargo_subcommand = "fix";
                    continue;
                },
                "--" => break,
                // Cover -Zunstable-options and -Z unstable-options
                s if s.ends_with("unstable-options") => unstable_options = true,
                _ => {},
            }

            args.push(arg);
        }

        if cargo_subcommand == "fix" && !unstable_options {
            panic!("Usage of `--fix` requires `-Z unstable-options`");
        }

        // Run the dogfood tests directly on nightly cargo. This is required due
        // to a bug in rustup.rs when running cargo on custom toolchains. See issue #3118.
        if env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) {
            args.insert(0, "+nightly".to_string());
        }

        let mut clippy_args: Vec<String> = old_args.collect();
        if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") {
            clippy_args.push("--no-deps".into());
        }

        ClippyCmd {
            cargo_subcommand,
            args,
            clippy_args,
        }
    }

    fn path() -> PathBuf {
        let mut path = env::current_exe()
            .expect("current executable path invalid")
            .with_file_name("clippy-driver");

        if cfg!(windows) {
            path.set_extension("exe");
        }

        path
    }

    fn target_dir() -> Option<(&'static str, OsString)> {
        env::var_os("CLIPPY_DOGFOOD")
            .map(|_| {
                env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                    || std::ffi::OsString::from("clippy_dogfood"),
                    |d| {
                        std::path::PathBuf::from(d)
                            .join("target")
                            .join("dogfood")
                            .into_os_string()
                    },
                )
            })
            .map(|p| ("CARGO_TARGET_DIR", p))
    }

    fn into_std_cmd(self) -> Command {
        let mut cmd = Command::new("cargo");
        let clippy_args: String = self
            .clippy_args
            .iter()
            .map(|arg| format!("{}__CLIPPY_HACKERY__", arg))
            .collect();

        cmd.env("RUSTC_WORKSPACE_WRAPPER", Self::path())
            .envs(ClippyCmd::target_dir())
            .env("CLIPPY_ARGS", clippy_args)
            .arg(self.cargo_subcommand)
            .args(&self.args);

        cmd
    }
}

fn process<I>(old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let cmd = ClippyCmd::new(old_args);

    let mut cmd = cmd.into_std_cmd();

    let exit_status = cmd
        .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))
    }
}

#[cfg(test)]
mod tests {
    use super::ClippyCmd;

    #[test]
    #[should_panic]
    fn fix_without_unstable() {
        let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
        let _ = ClippyCmd::new(args);
    }

    #[test]
    fn fix_unstable() {
        let args = "cargo clippy --fix -Zunstable-options"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!("fix", cmd.cargo_subcommand);
        assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
    }

    #[test]
    fn fix_implies_no_deps() {
        let args = "cargo clippy --fix -Zunstable-options"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps"));
    }

    #[test]
    fn no_deps_not_duplicated_with_fix() {
        let args = "cargo clippy --fix -Zunstable-options -- --no-deps"
            .split_whitespace()
            .map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1);
    }

    #[test]
    fn check() {
        let args = "cargo clippy".split_whitespace().map(ToString::to_string);
        let cmd = ClippyCmd::new(args);
        assert_eq!("check", cmd.cargo_subcommand);
    }
}
<|endoftext|>


<commit_before>#[derive(Debug)]
#[derive(Clone)]
enum PBWireType {
    VarInt,
    Fixed64,
    LengthDelim,
    Fixed32,
    Reserved,
}

struct TagValue<'a> {
    tag: u8,
    value: &'a [u8],
}

#[derive(Clone)]
struct ParserPosition {
    position: usize,
    tag: u8,
    wire_type: PBWireType,
    cur_idx: u8,
    max_idx: u8,
}

fn PBParseNext<'a>(s: &'a [u8], pos: ParserPosition) -> (TagValue<'a>, ParserPosition) {
    let idx2wireType = vec![PBWireType::VarInt,
                            PBWireType::Fixed64,
                            PBWireType::LengthDelim,
                            PBWireType::Reserved,
                            PBWireType::Reserved,
                            PBWireType::Fixed32];

    let mut p = pos.clone();

    if p.cur_idx == p.max_idx {
        p.tag = s[p.position] >> 3;
        p.wire_type = idx2wireType[(s[p.position] & 7) as usize].clone();
        p.position += 1;
        p.cur_idx = 0;
        p.max_idx = 0;
    }
    else {
      p.cur_idx += 1;
    }
    let mut value = match p.wire_type {
        PBWireType::LengthDelim => {
            let offset = s[p.position] as usize;
            let start = p.position + 1;
            let end = p.position + offset;
            p.position = end + 1;
            &s[start..end + 1]
        }
        _ => &[],
    };
    (TagValue {
         value: value,
         tag: p.tag,
     },
     p.clone())
}

use std::str;

fn main() {
    let msg = vec![0x12, 0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67];

    let (x, pp) = PBParseNext(msg.as_slice(),
                              ParserPosition {
                                  position: 0,
                                  tag: 0,
                                  wire_type: PBWireType::Reserved,
                                  cur_idx: 0,
                                  max_idx: 0,
                              });

    print!("Tag   = {}\n", x.tag);
    print!("Value = {}\n", str::from_utf8(x.value).unwrap());
}
<commit_msg>comment<commit_after>#[derive(Debug)]
#[derive(Clone)]
enum PBWireType {
    VarInt,
    Fixed64,
    LengthDelim,
    Fixed32,
    Reserved,
}

struct TagValue<'a> {
    tag: u8,
    value: &'a [u8],
}

#[derive(Clone)]
struct ParserPosition {
    position: usize,
    tag: u8,
    wire_type: PBWireType,
    cur_idx: u8,
    max_idx: u8,
}

fn PBParseNext<'a>(s: &'a [u8], pos: ParserPosition) -> (TagValue<'a>, ParserPosition) {
    let idx2wireType = vec![PBWireType::VarInt,
                            PBWireType::Fixed64,
                            PBWireType::LengthDelim,
                            PBWireType::Reserved,
                            PBWireType::Reserved,
                            PBWireType::Fixed32];

    let mut p = pos.clone();

    if p.cur_idx == p.max_idx {
        p.tag = s[p.position] >> 3;
        p.wire_type = idx2wireType[(s[p.position] & 7) as usize].clone();
        p.position += 1;
        p.cur_idx = 0;
        p.max_idx = 0;
    }
    else {
      p.cur_idx += 1;
    }
    let mut value = match p.wire_type {
        PBWireType::LengthDelim => {
            let offset = s[p.position] as usize;
            let start = p.position + 1;
            let end = p.position + offset;
            p.position = end + 1;
            &s[start..end + 1]
        }
        _ => &[],
    };
    (TagValue {
         value: value,
         tag: p.tag,
     },
     p.clone())
}

use std::str;

fn main() {
    /*
     * Sample ProtocolBuffer message for schema:
     *
     *     message Test2 {
     *       required string b = 2;
     *     }
     *
     * with b = testing
     *
     * @see https://developers.google.com/protocol-buffers/docs/encoding
     */
    let msg = vec![0x12, 0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67];

    let (x, pp) = PBParseNext(msg.as_slice(),
                              ParserPosition {
                                  position: 0,
                                  tag: 0,
                                  wire_type: PBWireType::Reserved,
                                  cur_idx: 0,
                                  max_idx: 0,
                              });

    print!("Tag   = {}\n", x.tag);
    print!("Value = {}\n", str::from_utf8(x.value).unwrap());
}
<|endoftext|>


<commit_before>extern crate rsdocs2docset;
extern crate html5ever;
#[macro_use]
extern crate quick_error;
extern crate clap;
extern crate url;
extern crate sqlite;

use clap::{Arg, App};
use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::TreeBuilderOpts;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;
use std::string::String;

use rsdocs2docset::dom::{manipulator, parser};

type Result<T> = std::result::Result<T, RsDoc2DocsetError>;

static DB_PATH: &'static str = "/tmp/foo.dsidx";

// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Cloning iterators
// #### read https://thesquareplanet.com/blog/rust-tips-and-tricks/ Partial matching

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version("0.0.1")
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_db();

    if let Err(e) = docset_from_rs_doc_tree(Path::new(args.value_of("indir").unwrap()),
    format!("{}.docset/Contents/Resources/Documents/", &args.value_of("name").unwrap()).as_str(),
	&annotate_file) {
		println!{"error: {}", e}
	}

	let info_plist = format!(include_str!("Info.plist.tmpl"), name = args.value_of("name").unwrap(), identifier = String::from(args.value_of("name").unwrap()).replace(" ", "-").to_lowercase());

	let plist_path_str = format!("{}.docset/Contents/Info.plist", &args.value_of("name").unwrap());
    let plist_path = Path::new(&plist_path_str);
	if let Err(e) = File::create(plist_path).and_then(|mut x| x.write_all(info_plist.as_ref())) {
		println!{"error: {}", e}
	}

    let icon = include_bytes!("icon.png");
	let icon_path_str = format!("{}.docset/icon.png", &args.value_of("name").unwrap());
    let icon_path = Path::new(&icon_path_str);
	if let Err(e) = File::create(icon_path).and_then(|mut x| x.write_all(icon)) {
		println!{"error: {}", e}
	}

    let icon_2x = include_bytes!("icon@2x.png");
	let icon_2x_path_str = format!("{}.docset/icon_2x_.png", &args.value_of("name").unwrap());
    let icon_2x_path = Path::new(&icon_2x_path_str);
	if let Err(e) = File::create(icon_2x_path).and_then(|mut x| x.write_all(icon_2x)) {
		println!{"error: {}", e}
	}

	let db_path_str = format!("{}.docset/Contents/Resources/docSet.dsidx", &args.value_of("name").unwrap());
    if let Err(e) = fs::rename(DB_PATH, db_path_str) {
        panic!("error moving db: {}", e)
    }
}

fn create_db() {
    if let Err(e) = sqlite::open(Path::new(DB_PATH))
        .and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")) {
        panic!("error creating db: {}", e);
    }
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str,
                           annotate_file: &Fn(&DirEntry, &str) -> Result<()>)
    -> Result<()> {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, annotate_file));
                } else {
                    try!(annotate_file(&entry, &out_dir));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str) -> Result<()> {
    let out_dir = Path::new(output_prefix).join(in_file.path().parent().unwrap());
    let out_file = out_dir.join(in_file.file_name());

    try!(DirBuilder::new()
         .recursive(true)
         .create(out_dir));

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(fs::copy(in_file.path(), &out_file));
        println!("{:70} | ", in_file.path().display());
        //print!(".")
    } else {
        let opts = ParseOpts {
            tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
            ..Default::default()
        };

        let mut dom = parse_document(RcDom::default(), opts)
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            print!("{:70} | ", in_file.path().display());
            println!("{}", entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            if let Err(e) = sqlite::open(Path::new(DB_PATH))
                .and_then(|c| c.execute(&sql_cmd)) {
                    panic!("error executing {}: {}", &sql_cmd, e);
                }

        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));

        let result = String::from_utf8(bytes)?;

        File::create(&out_file)?.write_all(result.as_ref())?;

        //print!(".")
    }

    Ok(())
}
<commit_msg>Simplify main file<commit_after>extern crate rsdocs2docset;
extern crate html5ever;
#[macro_use]
extern crate quick_error;
extern crate clap;
extern crate url;
extern crate sqlite;

use clap::{Arg, App};
use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::TreeBuilderOpts;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;

use rsdocs2docset::dom::{manipulator, parser};

type Result<T> = std::result::Result<T, RsDoc2DocsetError>;

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
        Sqlite(err: sqlite::Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version("0.0.1")
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_docset(args.value_of("indir").unwrap(), args.value_of("name").unwrap()).expect("error creating docset");
    println!("\n{}.docset successfully created!", args.value_of("name").unwrap())
}

fn create_docset(indir: &str, name: &str) -> Result<()> {
    let db_filename = format!("{}.docset/Contents/Resources/docSet.dsidx", name);
    let db_path = Path::new(&db_filename);

    try!(write_file(Path::new(format!("{}.docset/Contents/Info.plist", name).as_str()), format!(include_str!("Info.plist.tmpl"), name = name, identifier = name.replace(" ", "-").to_lowercase()).as_ref()));
    try!(write_file(Path::new(format!("{}.docset/icon.png", name).as_str()), include_bytes!("icon.png")));
    try!(write_file(Path::new(format!("{}.docset/icon@2x.png", name).as_str()), include_bytes!("icon@2x.png")));

    try!(write_file(db_path, "".as_bytes()));
    try!(sqlite::open(db_path).and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")));

    try!(docset_from_rs_doc_tree(&Path::new(indir), format!("{}.docset/Contents/Resources/Documents/", name).as_str(), Path::new(db_path), &annotate_file));

    Ok(())
}

fn write_file(path: &Path, data: &[u8]) -> Result<()> {
    let dir = path.parent().unwrap();

    try!(DirBuilder::new()
         .recursive(true)
         .create(dir));

    try!(File::create(path).and_then(|mut f| f.write_all(data)));
    Ok(())
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str, db_path: &Path,
                           annotate_file: &Fn(&DirEntry, &str, &Path) -> Result<()>)
    -> Result<()> {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, &db_path, annotate_file));
                } else {
                    try!(annotate_file(&entry, &out_dir, &db_path));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str, db_path: &Path) -> Result<()> {
    let out_file = Path::new(output_prefix).join(in_file.path());

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(write_file(Path::new(&out_file), "".as_bytes()));
        try!(fs::copy(in_file.path(), &out_file));
        //println!("{:70} | ", in_file.path().display());
        print!("."); io::stdout().flush().unwrap();
    } else {
        let opts = ParseOpts { tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() }, ..Default::default() };

        let mut dom = parse_document(RcDom::default(), opts)
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            //println!("{:70} | {}", in_file.path().display(), entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            try!(sqlite::open(db_path).and_then(|c| c.execute(&sql_cmd)))
        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));
        try!(write_file(&out_file, bytes.as_ref()));

        print!("o"); io::stdout().flush().unwrap();
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate bamrescue;
extern crate docopt;
extern crate rustc_serialize;
#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_term;

use slog::Drain;

const USAGE: &'static str = "
Usage: bamrescue check <bamfile>
       bamrescue repair <bamfile> <output>
       bamrescue -h | --help
       bamrescue --version

Commands:
    check       Check BAM file for corruption.
    repair      Keep only non-corrupted blocks of BAM file.

Arguments:
    bamfile     BAM file to check or repair.
    output      Repaired BAM file.

Options:
    -h, --help  Show this screen.
    --version   Show version.
";

#[derive(RustcDecodable)]
struct Args {
    cmd_check: bool,
    cmd_repair: bool,
    arg_bamfile: String,
    arg_output: String,
    flag_version: bool,
}

fn main() {
    let decorator = slog_term::TermDecorator::new().build();
    let drain = slog_term::FullFormat::new(decorator).build().fuse();
    let drain = slog_async::Async::new(drain).build().fuse();
    let logger = slog::Logger::root(drain, o!());

    let args: Args =
        docopt::Docopt::new(USAGE)
            .and_then(|docopts|
                docopts.argv(std::env::args().into_iter())
                   .decode()
            )
            .unwrap_or_else(|error|
                error.exit()
            );

    if args.flag_version {
        println!("bamrescue v{}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"));
    } else if args.cmd_check {
        bamrescue::check(args.arg_bamfile, logger);
    } else if args.cmd_repair {
        bamrescue::repair(args.arg_bamfile, args.arg_output, logger);
    }
}
<commit_msg>Simplify the code a bit<commit_after>extern crate bamrescue;
extern crate docopt;
extern crate rustc_serialize;
#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_term;

use slog::Drain;

const USAGE: &str = "
Usage: bamrescue check <bamfile>
       bamrescue repair <bamfile> <output>
       bamrescue -h | --help
       bamrescue --version

Commands:
    check       Check BAM file for corruption.
    repair      Keep only non-corrupted blocks of BAM file.

Arguments:
    bamfile     BAM file to check or repair.
    output      Repaired BAM file.

Options:
    -h, --help  Show this screen.
    --version   Show version.
";

#[derive(RustcDecodable)]
struct Args {
    cmd_check: bool,
    cmd_repair: bool,
    arg_bamfile: String,
    arg_output: String,
    flag_version: bool,
}

fn main() {
    let decorator = slog_term::TermDecorator::new().build();
    let drain = slog_term::FullFormat::new(decorator).build().fuse();
    let drain = slog_async::Async::new(drain).build().fuse();
    let logger = slog::Logger::root(drain, o!());

    let args: Args =
        docopt::Docopt::new(USAGE)
            .and_then(|docopts|
                docopts.argv(std::env::args().into_iter())
                   .decode()
            )
            .unwrap_or_else(|error|
                error.exit()
            );

    if args.flag_version {
        println!("bamrescue v{}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"));
    } else if args.cmd_check {
        bamrescue::check(args.arg_bamfile, logger);
    } else if args.cmd_repair {
        bamrescue::repair(args.arg_bamfile, args.arg_output, logger);
    }
}
<|endoftext|>