<commit_before>use std::path::MAIN_SEPARATOR;
use std::process::Command;

use clap::{App, Arg, Error};

#[derive(Debug)]
pub struct Args {
    pub cmd: String,
    pub paths: Vec<String>,
    pub filters: Vec<String>,
    pub ignores: Vec<String>,
    pub clear_screen: bool,
    pub signal: Option<String>,
    pub restart: bool,
    pub debounce: u64,
    pub debug: bool,
    pub run_initially: bool,
    pub no_shell: bool,
    pub no_vcs_ignore: bool,
    pub once: bool,
    pub poll: bool,
    pub poll_interval: u32,
}

#[cfg(target_family = "windows")]
pub fn clear_screen() {
    let _ = Command::new("cls").status();
}

#[cfg(target_family = "unix")]
pub fn clear_screen() {
    let _ = Command::new("tput").arg("reset").status();
}

#[allow(unknown_lints)]
#[allow(or_fun_call)]
pub fn get_args() -> Args {
    let args = App::new("watchexec")
        .version(crate_version!())
        .about("Execute commands when watched files change")
        .arg(Arg::with_name("command")
                 .help("Command to execute")
                 .multiple(true)
                 .required(true))
        .arg(Arg::with_name("extensions")
                 .help("Comma-separated list of file extensions to watch (js,css,html)")
                 .short("e")
                 .long("exts")
                 .takes_value(true))
        .arg(Arg::with_name("path")
                 .help("Watch a specific directory")
                 .short("w")
                 .long("watch")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true))
        .arg(Arg::with_name("clear")
                 .help("Clear screen before executing command")
                 .short("c")
                 .long("clear"))
        .arg(Arg::with_name("restart")
                 .help("Restart the process if it's still running")
                 .short("r")
                 .long("restart"))
        .arg(Arg::with_name("signal")
                 .help("Send signal to process upon changes, e.g. SIGHUP")
                 .short("s")
                 .long("signal")
                 .takes_value(true)
                 .number_of_values(1)
                 .value_name("signal"))
        .arg(Arg::with_name("kill")
                 .help("Send SIGKILL to child processes (deprecated, use -s SIGKILL instead)")
                 .short("k")
                 .long("kill"))
        .arg(Arg::with_name("debounce")
                 .help("Set the timeout between detected change and command execution, defaults to 500ms")
                 .takes_value(true)
                 .value_name("milliseconds")
                 .short("d")
                 .long("debounce"))
        .arg(Arg::with_name("verbose")
                 .help("Print debugging messages to stderr")
                 .short("v")
                 .long("verbose"))
        .arg(Arg::with_name("filter")
                 .help("Ignore all modifications except those matching the pattern")
                 .short("f")
                 .long("filter")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("ignore")
                 .help("Ignore modifications to paths matching the pattern")
                 .short("i")
                 .long("ignore")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("no-vcs-ignore")
                 .help("Skip auto-loading of .gitignore files for filtering")
                 .long("no-vcs-ignore"))
        .arg(Arg::with_name("no-default-ignore")
                 .help("Skip auto-ignoring of commonly ignored globs")
                 .long("no-default-ignore"))
        .arg(Arg::with_name("postpone")
                 .help("Wait until first change to execute command")
                 .short("p")
                 .long("postpone"))
        .arg(Arg::with_name("poll")
                 .help("Forces polling mode")
                 .long("force-poll")
                 .value_name("interval"))
        .arg(Arg::with_name("no-shell")
                 .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'")
                 .short("n")
                 .long("no-shell"))
        .arg(Arg::with_name("once").short("1").hidden(true))
        .get_matches();

    let cmd = values_t!(args.values_of("command"), String)
        .unwrap()
        .join(" ");
    let paths = values_t!(args.values_of("path"), String).unwrap_or(vec![String::from(".")]);

    // Treat --kill as --signal SIGKILL (for compatibility with older syntax)
    let signal = if args.is_present("kill") {
        Some("SIGKILL".to_string())
    } else {
        // Convert Option<&str> to Option<String>
        args.value_of("signal").map(str::to_string)
    };

    let mut filters = values_t!(args.values_of("filter"), String).unwrap_or(vec![]);

    if let Some(extensions) = args.values_of("extensions") {
        for exts in extensions {
            filters.extend(exts.split(',')
                               .filter(|ext| !ext.is_empty())
                               .map(|ext| format!("*.{}", ext.replace(".", ""))));

        }
    }

    let mut ignores = vec![];
    let default_ignores = vec![format!("**{}.DS_Store", MAIN_SEPARATOR),
                               String::from("*.pyc"),
                               String::from("*.swp"),
                               format!("**{}.git{}**", MAIN_SEPARATOR, MAIN_SEPARATOR),
                               format!("**{}.hg{}**", MAIN_SEPARATOR, MAIN_SEPARATOR),
                               format!("**{}.svn{}**", MAIN_SEPARATOR, MAIN_SEPARATOR)];

    if args.occurrences_of("no-default-ignore") == 0 {
        ignores.extend(default_ignores)
    };
    ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or(vec![]));

    let poll_interval = if args.occurrences_of("poll") > 0 {
        value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit())
    } else {
        1000
    };

    let debounce = if args.occurrences_of("debounce") > 0 {
        value_t!(args.value_of("debounce"), u64).unwrap_or_else(|e| e.exit())
     } else {
         500
     };

    if signal.is_some() && args.is_present("postpone") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--postpone and --signal are mutually exclusive".to_string())
            .exit();
    }

    if signal.is_some() && args.is_present("kill") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--kill and --signal is ambiguous.\n       Hint: Use only '--signal SIGKILL' without --kill".to_string())
            .exit();
    }

    Args {
        cmd: cmd,
        paths: paths,
        filters: filters,
        ignores: ignores,
        signal: signal,
        clear_screen: args.is_present("clear"),
        restart: args.is_present("restart"),
        debounce: debounce,
        debug: args.is_present("verbose"),
        run_initially: !args.is_present("postpone"),
        no_shell: args.is_present("no-shell"),
        no_vcs_ignore: args.is_present("no-vcs-ignore"),
        once: args.is_present("once"),
        poll: args.occurrences_of("poll") > 0,
        poll_interval: poll_interval,
    }
}
<commit_msg>fix screen clearing on windows<commit_after>use std::path::MAIN_SEPARATOR;
use std::process::Command;

use clap::{App, Arg, Error};

#[derive(Debug)]
pub struct Args {
    pub cmd: String,
    pub paths: Vec<String>,
    pub filters: Vec<String>,
    pub ignores: Vec<String>,
    pub clear_screen: bool,
    pub signal: Option<String>,
    pub restart: bool,
    pub debounce: u64,
    pub debug: bool,
    pub run_initially: bool,
    pub no_shell: bool,
    pub no_vcs_ignore: bool,
    pub once: bool,
    pub poll: bool,
    pub poll_interval: u32,
}

#[cfg(target_family = "windows")]
pub fn clear_screen() {
    let _ = Command::new("cmd").arg("/c").arg("cls").status();
}

#[cfg(target_family = "unix")]
pub fn clear_screen() {
    let _ = Command::new("tput").arg("reset").status();
}

#[allow(unknown_lints)]
#[allow(or_fun_call)]
pub fn get_args() -> Args {
    let args = App::new("watchexec")
        .version(crate_version!())
        .about("Execute commands when watched files change")
        .arg(Arg::with_name("command")
                 .help("Command to execute")
                 .multiple(true)
                 .required(true))
        .arg(Arg::with_name("extensions")
                 .help("Comma-separated list of file extensions to watch (js,css,html)")
                 .short("e")
                 .long("exts")
                 .takes_value(true))
        .arg(Arg::with_name("path")
                 .help("Watch a specific directory")
                 .short("w")
                 .long("watch")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true))
        .arg(Arg::with_name("clear")
                 .help("Clear screen before executing command")
                 .short("c")
                 .long("clear"))
        .arg(Arg::with_name("restart")
                 .help("Restart the process if it's still running")
                 .short("r")
                 .long("restart"))
        .arg(Arg::with_name("signal")
                 .help("Send signal to process upon changes, e.g. SIGHUP")
                 .short("s")
                 .long("signal")
                 .takes_value(true)
                 .number_of_values(1)
                 .value_name("signal"))
        .arg(Arg::with_name("kill")
                 .help("Send SIGKILL to child processes (deprecated, use -s SIGKILL instead)")
                 .short("k")
                 .long("kill"))
        .arg(Arg::with_name("debounce")
                 .help("Set the timeout between detected change and command execution, defaults to 500ms")
                 .takes_value(true)
                 .value_name("milliseconds")
                 .short("d")
                 .long("debounce"))
        .arg(Arg::with_name("verbose")
                 .help("Print debugging messages to stderr")
                 .short("v")
                 .long("verbose"))
        .arg(Arg::with_name("filter")
                 .help("Ignore all modifications except those matching the pattern")
                 .short("f")
                 .long("filter")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("ignore")
                 .help("Ignore modifications to paths matching the pattern")
                 .short("i")
                 .long("ignore")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("no-vcs-ignore")
                 .help("Skip auto-loading of .gitignore files for filtering")
                 .long("no-vcs-ignore"))
        .arg(Arg::with_name("no-default-ignore")
                 .help("Skip auto-ignoring of commonly ignored globs")
                 .long("no-default-ignore"))
        .arg(Arg::with_name("postpone")
                 .help("Wait until first change to execute command")
                 .short("p")
                 .long("postpone"))
        .arg(Arg::with_name("poll")
                 .help("Forces polling mode")
                 .long("force-poll")
                 .value_name("interval"))
        .arg(Arg::with_name("no-shell")
                 .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'")
                 .short("n")
                 .long("no-shell"))
        .arg(Arg::with_name("once").short("1").hidden(true))
        .get_matches();

    let cmd = values_t!(args.values_of("command"), String)
        .unwrap()
        .join(" ");
    let paths = values_t!(args.values_of("path"), String).unwrap_or(vec![String::from(".")]);

    // Treat --kill as --signal SIGKILL (for compatibility with older syntax)
    let signal = if args.is_present("kill") {
        Some("SIGKILL".to_string())
    } else {
        // Convert Option<&str> to Option<String>
        args.value_of("signal").map(str::to_string)
    };

    let mut filters = values_t!(args.values_of("filter"), String).unwrap_or(vec![]);

    if let Some(extensions) = args.values_of("extensions") {
        for exts in extensions {
            filters.extend(exts.split(',')
                               .filter(|ext| !ext.is_empty())
                               .map(|ext| format!("*.{}", ext.replace(".", ""))));

        }
    }

    let mut ignores = vec![];
    let default_ignores = vec![format!("**{}.DS_Store", MAIN_SEPARATOR),
                               String::from("*.pyc"),
                               String::from("*.swp"),
                               format!("**{}.git{}**", MAIN_SEPARATOR, MAIN_SEPARATOR),
                               format!("**{}.hg{}**", MAIN_SEPARATOR, MAIN_SEPARATOR),
                               format!("**{}.svn{}**", MAIN_SEPARATOR, MAIN_SEPARATOR)];

    if args.occurrences_of("no-default-ignore") == 0 {
        ignores.extend(default_ignores)
    };
    ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or(vec![]));

    let poll_interval = if args.occurrences_of("poll") > 0 {
        value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit())
    } else {
        1000
    };

    let debounce = if args.occurrences_of("debounce") > 0 {
        value_t!(args.value_of("debounce"), u64).unwrap_or_else(|e| e.exit())
     } else {
         500
     };

    if signal.is_some() && args.is_present("postpone") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--postpone and --signal are mutually exclusive".to_string())
            .exit();
    }

    if signal.is_some() && args.is_present("kill") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--kill and --signal is ambiguous.\n       Hint: Use only '--signal SIGKILL' without --kill".to_string())
            .exit();
    }

    Args {
        cmd: cmd,
        paths: paths,
        filters: filters,
        ignores: ignores,
        signal: signal,
        clear_screen: args.is_present("clear"),
        restart: args.is_present("restart"),
        debounce: debounce,
        debug: args.is_present("verbose"),
        run_initially: !args.is_present("postpone"),
        no_shell: args.is_present("no-shell"),
        no_vcs_ignore: args.is_present("no-vcs-ignore"),
        once: args.is_present("once"),
        poll: args.occurrences_of("poll") > 0,
        poll_interval: poll_interval,
    }
}
<|endoftext|>


<commit_before>use oak_runtime::stream::*;

use getopts::Options;
use std::path::Path;

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

use parser::bailey;
use ast::PNode;

fn print_usage(program: &String, opts: &Options) {
    let brief = format!("Usage: {} FILE [options]", program);
    print!("{}", opts.usage(&brief));
}

pub fn run(args: Vec<String>) {
    let program = &args[0].clone();

    let mut opts = &mut Options::new();

    opts.optopt("e", "", "evaluate expression", "EXP");
    opts.optflag("h", "help", "print this help menu");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(program, opts);
        return;
    }

    if matches.opt_present("e") {
        match matches.opt_str("e") {
            Some(e) => {
                println!("{:#?}", parse(e));
                return
            },
            None => print_usage(program, opts)
        }
    }

    if args.len() < 2 {
        print_usage(program, opts);
        return;
    }

    let file_path = args[1].clone();
    if Path::new(&file_path).exists() {
        println!("{:#?}", parse_file(file_path));
        return
    };
}

pub fn parse_file(file_path: String) -> Result<Vec<PNode>, String> {
    let f = File::open(file_path).ok().expect("failed to open file");
    let mut reader = BufReader::new(f);
    let mut code = String::new();
    reader.read_to_string(&mut code);
    parse(code)
}

pub fn parse(code: String) -> Result<Vec<PNode>, String> {
    let state = bailey::parse_program(code.stream());

    match state.into_result() {
      Ok((success, error)) => {
        if success.partial_read() {
          Err(format!("Partial match: {:#?} because: {}", success.data, error))
        }
        else {
          Ok(success.data)
        }
      }
      Err(error) => {
          Err(format!("Error: {}", error))
      }
    }
}
<commit_msg>Improved CLI for parsing file codez.<commit_after>use oak_runtime::stream::*;

use getopts::Options;

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

use parser::bailey;
use ast::PNode;

fn print_usage(program: &String, opts: &Options) {
    let brief = format!("Usage: {} FILE [options]", program);
    print!("{}", opts.usage(&brief));
}

pub fn run(args: Vec<String>) {
    let program = &args[0].clone();

    let mut opts = &mut Options::new();

    opts.optopt("e", "", "evaluate expression", "EXP");
    opts.optflag("h", "help", "print this help menu");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    if matches.opt_present("h") {
        print_usage(program, opts);
        return;
    }

    if matches.opt_present("e") {
        match matches.opt_str("e") {
            Some(e) => {
                println!("{:#?}", parse(e));
                return
            },
            None => print_usage(program, opts)
        }
    }

    if args.len() < 2 {
        print_usage(program, opts);
        return;
    }

    let file_path = args[1].clone();
    println!("{:#?}", parse_file(file_path));
}

pub fn parse_file(file_path: String) -> Result<Vec<PNode>, String> {
    match File::open(file_path) {
        Ok(file) => {
            let mut reader = BufReader::new(file);
            let mut code = String::new();
            reader.read_to_string(&mut code);
            parse(code)
        }
        Err(error) => Err(format!("Error: {}", error))
    }
}

pub fn parse(code: String) -> Result<Vec<PNode>, String> {
    let state = bailey::parse_program(code.stream());

    match state.into_result() {
      Ok((success, error)) => {
        if success.partial_read() {
          Err(format!("Partial match: {:#?} because: {}", success.data, error))
        }
        else {
          Ok(success.data)
        }
      }
      Err(error) => {
          Err(format!("Error: {}", error))
      }
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;

use rayon::prelude::*;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T> where T: Debug {
    data: Vec<T>,
}

impl<T> VecResource<T> where T: Debug {
    pub fn new() -> Self {
        VecResource {
            data: Vec::new(),
        }
    }
}

pub struct Entity((u32, u32));

pub struct World {
    entities: Vec<Entity>,
    components: anymap::AnyMap,
}

impl World {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            components: anymap::AnyMap::new(),
        }
    }

    fn register<T>(&mut self) where T: Default + 'static {
        self.components.insert(T::default());
    }

    fn run<F, T>(&mut self, f: F) where F: Fn(&T) + Sync, T: Debug + Send {
        println!("Foo");
        // if let Some(resource) = self.components.get::<VecResource<T>>() {
        //     for x in  resource.data
        //         .iter() {
        //              println!("{:?}", x);
        //         }

        //     let d: &[T] = &resource.data;
        //     // d.par_iter();
        // } else {
        //     panic!("Tried to run a system on an unknown component type");
        // }

        let v: &Vec<u32> = &Vec::new();
        v.par_iter();
    }

    fn create_entity(&mut self) {
        self.entities.push(Entity((0, 0)));
        let vr: &mut VecResource<u32> = self.components.entry().or_insert_with(VecResource::new);
        vr.data.push(self.entities.len() as u32);

    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_world_thingy() {
        let mut w = World::new();
        for i in 0..10 {
            w.create_entity();
        }
        println!("Bar");
        w.run(|x:&u32| ());
        assert!(false);
    }
}<commit_msg>Messing about with ECS more, now takes events and returns new events<commit_after>use std::fmt::Debug;

use rayon::prelude::*;
use rayon;
use anymap;

#[derive(Clone, Default, Debug)]
pub struct Component {
    data: i32,
}

// #[derive(Clone, Default)]
// pub struct VecResource<T> {
//     data: Vec<T>,
// }

#[derive(Clone, Default, Debug)]
pub struct VecResource<T>
    where T: Debug
{
    data: Vec<T>,
}

impl<T> VecResource<T>
    where T: Debug
{
    pub fn new() -> Self {
        VecResource { data: Vec::new() }
    }
}

pub struct Entity((u32, u32));

pub struct World {
    entities: Vec<Entity>,
    components: anymap::AnyMap,
}

impl World {
    pub fn new() -> Self {
        World {
            entities: Vec::new(),
            components: anymap::AnyMap::new(),
        }
    }

    fn register<T>(&mut self)
        where T: Default + 'static
    {
        self.components.insert(T::default());
    }

    fn run<F, T, Eoutput, Einput>(&mut self, inputs: Vec<Einput>, f: F) -> Vec<Eoutput>
        where F: Fn((&T, &Einput)) -> Eoutput + Sync,
              T: Debug + Send + Sync + 'static,
              Eoutput: Send + Sync,
              Einput: Send + Sync
    {
        if let Some(resource) = self.components.get::<VecResource<T>>() {
            let d: &[T] = &resource.data;
            let mut v = Vec::new();
            d.par_iter().zip(&inputs).map(f).collect_into(&mut v);
            v
        } else {
            panic!("Tried to run a system on an unknown component type");
        }
    }

    fn create_entity(&mut self) {
        self.entities.push(Entity((0, 0)));
        let vr: &mut VecResource<u32> = self.components.entry().or_insert_with(VecResource::new);
        vr.data.push(self.entities.len() as u32);
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn test_world_thingy() {
        let entity_count = 10;
        let mut w = World::new();
        for i in 0..entity_count {
            w.create_entity();
        }
        println!("Bar");
        let mut inputs = Vec::new();
        inputs.resize(entity_count, 1u32);
        let results = w.run(inputs, |(x1, x2): (&u32, &u32)| {
            println!("Xs are is {:?} {:?}", x1, x1);
            x1 + x2
        });
        println!("Results are {:?}", results);
        assert!(false);
    }
}
<|endoftext|>


<commit_before>use raw::*;
use context::Context;
use function::CompiledFunction;
use libc::c_uint;
use util::NativeRef;
use std::ffi::{self, CString};
use std::fmt;
use std::marker::ContravariantLifetime;
use std::{mem, ptr};
use std::iter::Iterator;
use std::error::Error;
/// An ELF dependency iterator
pub struct Needed<'a> {
    _reader: jit_readelf_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Needed<'a> {
    #[inline(always)]
    fn new(read:&'a ReadElf) -> Needed<'a> {
        unsafe {
            Needed {
                _reader: read.as_ptr(),
                index: 0 as c_uint,
                length: jit_readelf_num_needed(read.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator for Needed<'a> {
    type Item = String;
    fn next(&mut self) -> Option<String> {
        let index = self.index;
        self.index += 1;
        unsafe {
            if index < self.length {
                let c_name = jit_readelf_get_needed(self._reader, index);
                let bytes = ffi::c_str_to_bytes(&c_name);
                Some(String::from_utf8_lossy(bytes).into_owned())
            } else {
                None
            }
        }
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        ((self.length - self.index) as usize, None)
    }
}
/// An ELF binary reader
native_ref!(ReadElf {
    _reader: jit_readelf_t
});
#[repr(i32)]
/// An error from trying to open the ELF
pub enum ReadElfErrorCode {
    /// The file couldn't be opened
    CannotOpen,
    /// The file isn't an ELF
    NotElf,
    /// The ELF is for a different architecture
    WrongArch,
    /// The ELF is badly formatted
    BadFormat,
    /// The ELF is too big to be loaded
    Memory
}
impl Copy for ReadElfErrorCode {}
impl fmt::Display for ReadElfErrorCode {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}
impl Error for ReadElfErrorCode {
    fn description(&self) -> &'static str {
        match *self {
            ReadElfErrorCode::CannotOpen => "Could not open the file",
            ReadElfErrorCode::NotElf => "Not an ELF-format binary",
            ReadElfErrorCode::WrongArch => "Wrong architecture for local system",
            ReadElfErrorCode::BadFormat => "ELF file, but badly formatted",
            ReadElfErrorCode::Memory => "Insufficient memory to load the file"
        }
    }
}
#[deriving(Copy)]
/// An error from trying to open the ELF, including the filename
pub struct ReadElfError<'a> {
    filename: &'a str,
    error: ReadElfErrorCode
}
impl<'a> fmt::Display for ReadElfError<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "'{}': {}", self.filename, self.error.description())
    }
}
impl ReadElf {
    /// Open a new ELF binary
    pub fn new(filename:&str) -> Result<ReadElf, ReadElfError> {
        unsafe {
            let c_name = CString::from_slice(filename.as_bytes());
            let mut this = ptr::null_mut();
            let code = jit_readelf_open(&mut this, mem::transmute(c_name.as_ptr()), 0);
            if code == 0 {
                Ok(NativeRef::from_ptr(this))
            } else {
                Err(ReadElfError {
                    filename: filename,
                    error: mem::transmute(code)
                })
            }
        }
    }
    #[inline]
    /// Get the name of this ELF binary
    pub fn get_name(&self) -> String {
        unsafe {
            let c_name = jit_readelf_get_name(self.as_ptr());
            let bytes = ffi::c_str_to_bytes(&c_name);
            String::from_utf8_lossy(bytes).into_owned()
        }
    }
    #[inline]
    pub fn add_to_context(&self, ctx:&Context) {
        unsafe {
            jit_readelf_add_to_context(self.as_ptr(), ctx.as_ptr())
        }
    }
    #[inline]
    /// Get a symbol in the ELF binary
    pub unsafe fn get_symbol<T>(&self, symbol:&str) -> &mut T {
        let c_sym = CString::from_slice(symbol.as_bytes());
        mem::transmute(jit_readelf_get_symbol(self.as_ptr(), mem::transmute(c_sym.as_ptr())))
    }
    #[inline]
    /// Iterate over the needed libraries
    pub fn needed(&self) -> Needed {
        Needed::new(self)
    }
}
#[unsafe_destructor]
impl Drop for ReadElf {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_readelf_close(self.as_ptr())
        }
    }
}

/// An ELF binary reader
native_ref!(WriteElf {
    _writer: jit_writeelf_t
});
impl WriteElf {
    #[inline]
    /// Create a new ELF binary reader
    pub fn new(lib_name:&str) -> WriteElf {
        unsafe {
            let c_lib = CString::from_slice(lib_name.as_bytes());
            NativeRef::from_ptr(jit_writeelf_create(mem::transmute(c_lib.as_ptr())))
        }
    }
    #[inline]
    /// Write to the filename given (not implemented by LibJIT yet, so there's no point to this yet
    /// but I'm sure GNU will hear the people sing the songs of angry men soon enough)
    pub fn write(&self, filename:&str) -> bool {
        unsafe {
            let c_filename = CString::from_slice(filename.as_bytes());
            jit_writeelf_write(self.as_ptr(), mem::transmute(c_filename.as_ptr())) != 0
        }
    }
    #[inline]
    /// Add a function to the ELF
    pub fn add_function(&self, func:&CompiledFunction, name:&str) -> bool {
        unsafe {
            let c_name = CString::from_slice(name.as_bytes());
            jit_writeelf_add_function(self.as_ptr(), func.as_ptr(), mem::transmute(c_name.as_ptr())) != 0
        }
    }
    #[inline]
    /// Add a dependency to the ELF
    pub fn add_needed(&self, lib_name:&str) -> bool {
        unsafe {
            let c_lib = CString::from_slice(lib_name.as_bytes());
            jit_writeelf_add_needed(self.as_ptr(), mem::transmute(c_lib.as_ptr())) != 0
        }
    }
}
#[unsafe_destructor]
impl Drop for WriteElf {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_writeelf_destroy(self.as_ptr())
        }
    }
}<commit_msg>Use `&str` in elf iterators etc<commit_after>use raw::*;
use context::Context;
use function::CompiledFunction;
use libc::c_uint;
use util::NativeRef;
use std::ffi::{self, CString};
use std::{fmt, str};
use std::marker::ContravariantLifetime;
use std::{mem, ptr};
use std::iter::Iterator;
use std::error::Error;
/// An ELF dependency iterator
pub struct Needed<'a> {
    _reader: jit_readelf_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Needed<'a> {
    #[inline(always)]
    fn new(read:&'a ReadElf) -> Needed<'a> {
        unsafe {
            Needed {
                _reader: read.as_ptr(),
                index: 0 as c_uint,
                length: jit_readelf_num_needed(read.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator for Needed<'a> {
    type Item = &'a str;
    fn next(&mut self) -> Option<&'a str> {
        let index = self.index;
        self.index += 1;
        unsafe {
            if index < self.length {
                let c_name = jit_readelf_get_needed(self._reader, index);
                let name: &*const i8 = mem::transmute(&c_name);
                Some(str::from_utf8(ffi::c_str_to_bytes(name)).unwrap())
            } else {
                None
            }
        }
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        ((self.length - self.index) as usize, None)
    }
}
/// An ELF binary reader
native_ref!(ReadElf {
    _reader: jit_readelf_t
});
#[repr(i32)]
/// An error from trying to open the ELF
pub enum ReadElfErrorCode {
    /// The file couldn't be opened
    CannotOpen,
    /// The file isn't an ELF
    NotElf,
    /// The ELF is for a different architecture
    WrongArch,
    /// The ELF is badly formatted
    BadFormat,
    /// The ELF is too big to be loaded
    Memory
}
impl Copy for ReadElfErrorCode {}
impl fmt::Display for ReadElfErrorCode {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}
impl Error for ReadElfErrorCode {
    fn description(&self) -> &'static str {
        match *self {
            ReadElfErrorCode::CannotOpen => "Could not open the file",
            ReadElfErrorCode::NotElf => "Not an ELF-format binary",
            ReadElfErrorCode::WrongArch => "Wrong architecture for local system",
            ReadElfErrorCode::BadFormat => "ELF file, but badly formatted",
            ReadElfErrorCode::Memory => "Insufficient memory to load the file"
        }
    }
}
#[deriving(Copy)]
/// An error from trying to open the ELF, including the filename
pub struct ReadElfError<'a> {
    filename: &'a str,
    error: ReadElfErrorCode
}
impl<'a> fmt::Display for ReadElfError<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "'{}': {}", self.filename, self.error.description())
    }
}
impl ReadElf {
    /// Open a new ELF binary
    pub fn new(filename:&str) -> Result<ReadElf, ReadElfError> {
        unsafe {
            let mut this = ptr::null_mut();
            let c_name = CString::from_slice(filename.as_bytes());
            let code = jit_readelf_open(&mut this, mem::transmute(c_name.as_ptr()), 0);
            if code == 0 {
                Ok(NativeRef::from_ptr(this))
            } else {
                Err(ReadElfError {
                    filename: filename,
                    error: mem::transmute(code)
                })
            }
        }
    }
    #[inline]
    /// Get the name of this ELF binary
    pub fn get_name(&self) -> &str {
        unsafe {
            let c_name = jit_readelf_get_name(self.as_ptr());
            let name: &*const i8 = mem::transmute(&c_name);
            str::from_utf8(ffi::c_str_to_bytes(name)).unwrap()
        }
    }
    #[inline]
    pub fn add_to_context(&self, ctx:&Context) {
        unsafe {
            jit_readelf_add_to_context(self.as_ptr(), ctx.as_ptr())
        }
    }
    #[inline]
    /// Get a symbol in the ELF binary
    pub unsafe fn get_symbol<T>(&self, symbol:&str) -> &mut T {
        let c_sym = CString::from_slice(symbol.as_bytes());
        mem::transmute(jit_readelf_get_symbol(self.as_ptr(), mem::transmute(c_sym.as_ptr())))
    }
    #[inline]
    /// Iterate over the needed libraries
    pub fn needed(&self) -> Needed {
        Needed::new(self)
    }
}
#[unsafe_destructor]
impl Drop for ReadElf {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_readelf_close(self.as_ptr())
        }
    }
}

/// An ELF binary reader
native_ref!(WriteElf {
    _writer: jit_writeelf_t
});
impl WriteElf {
    #[inline]
    /// Create a new ELF binary reader
    pub fn new(lib_name:&str) -> WriteElf {
        unsafe {
            let c_lib = CString::from_slice(lib_name.as_bytes());
            NativeRef::from_ptr(jit_writeelf_create(mem::transmute(c_lib.as_ptr())))
        }
    }
    #[inline]
    /// Write to the filename given (not implemented by LibJIT yet, so there's no point to this yet
    /// but I'm sure GNU will hear the people sing the songs of angry men soon enough)
    pub fn write(&self, filename:&str) -> bool {
        unsafe {
            let c_filename = CString::from_slice(filename.as_bytes());
            jit_writeelf_write(self.as_ptr(), mem::transmute(c_filename.as_ptr())) != 0
        }
    }
    #[inline]
    /// Add a function to the ELF
    pub fn add_function(&self, func:&CompiledFunction, name:&str) -> bool {
        unsafe {
            let c_name = CString::from_slice(name.as_bytes());
            jit_writeelf_add_function(self.as_ptr(), func.as_ptr(), mem::transmute(c_name.as_ptr())) != 0
        }
    }
    #[inline]
    /// Add a dependency to the ELF
    pub fn add_needed(&self, lib_name:&str) -> bool {
        unsafe {
            let c_lib = CString::from_slice(lib_name.as_bytes());
            jit_writeelf_add_needed(self.as_ptr(), mem::transmute(c_lib.as_ptr())) != 0
        }
    }
}
#[unsafe_destructor]
impl Drop for WriteElf {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_writeelf_destroy(self.as_ptr())
        }
    }
}<|endoftext|>


<commit_before>use implicit;
use explicit;
use typed;

use std::collections::HashMap;
use explicit::Type;

fn convert(n: i32, env: &mut HashMap<String, Type>, renamed: &HashMap<String, String>, expr: &explicit::Expr) -> (i32, implicit::Expr, Type) {
    use common::Const;
    use implicit::Expr as I;
    use typed::Expr as E;
    match *expr {
        E::Const(Const::Int(c)) => (n, I::Const(Const::Int(c)), Type::TInt),
        E::Const(Const::Bool(c)) => (n, I::Const(Const::Bool(c)), Type::TBool),
        E::Op2(op, ref e1, ref e2) => {
            let (n, e1, _) = convert(n, env, renamed, e1);
            let (n, e2, _) = convert(n, env, renamed, e2);
            (n, I::Op2(op, box e1, box e2), explicit::opty(op))
        }
        E::If(ref e1, ref e2, ref e3) => {
            let (n, e1, _) = convert(n, env, renamed, e1);
            let (n, e2, t) = convert(n, env, renamed, e2);
            let (n, e3, _) = convert(n, env, renamed, e3);
            (n, I::If(box e1, box e2, box e3), t)
        }
        E::Var(ref x) => {
            let αx = renamed.get(x).unwrap();
            (n, I::Var(αx.clone()), env.get(αx).unwrap().clone())
        }
        E::Let(ref id, ref e1, ref e2) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            let (n, e1, t1) = convert(n, env, &renamed, e1);

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1);

            let (n, e2, t2) = convert(n, env, &renamed, e2);
            (n, I::Let(αid, box e1, box e2), t2)
        }
        E::Fun(ref id, ref t1, ref e) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1.clone());

            let (n, e, t2) = convert(n, env, &renamed, e);

            (n, I::Fun(αid, box e), Type::TFun(box t1.clone(), box t2))
        }
        E::Fix(ref id, ref t1, ref e) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1.clone());

            let (n, e, t2) = convert(n, env, &renamed, e);

            (n, I::Fix(αid, box e), t2)
        }
        E::App(ref e1, ref e2) => {
            let (n, e1, t1) = convert(n, env, renamed, e1);
            let (n, e2, _) = convert(n, env, renamed, e2);
            let t = match t1 {
                Type::TFun(_, t2) => *t2,
                _ => panic!("expected TFun, not {:?}", t1),
            };
            (n, I::App(box e1, box e2), t)
        }
        E::Empty(ref t1) => (n, I::Empty, t1.clone()),
        // E::Cons(ref e1, ref e2) => {
        //     let mv = m.alloc_empty();
        //     let (mut c1, t1) = gen_constraints(m, env, e1)?;
        //     let (mut c2, t2) = gen_constraints(m, env, e2)?;
        //     c1.append(&mut c2);
        //     c1.push((t1, mv.clone()));
        //     c1.push((t2, Type::TList(box mv.clone())));
        //     (c1, Type::TList(box mv))
        // }
        // E::Head(ref e) => {
        //     let mv = m.alloc_empty();
        //     let (mut c, t) = gen_constraints(m, env, e)?;
        //     c.push((t, Type::TList(box mv.clone())));
        //     (c, mv)
        // }
        // E::Tail(ref e) => {
        //     let mv = m.alloc_empty();
        //     let (mut c, t) = gen_constraints(m, env, e)?;
        //     c.push((t, Type::TList(box mv.clone())));
        //     (c, Type::TList(box mv))
        // }
        // E::IsEmpty(ref e) => {
        //     let mv = m.alloc_empty();
        //     let (mut c, t) = gen_constraints(m, env, e)?;
        //     c.push((t, Type::TList(box mv.clone())));
        //     (c, Type::TBool)
        // }
        // E::MkArray(ref sz, ref n) => {
        //     let (mut c1, t1) = gen_constraints(m, env, sz)?;
        //     let (mut c2, t2) = gen_constraints(m, env, n)?;
        //     c1.append(&mut c2);
        //     c1.push((t1, Type::TInt));
        //     c1.push((t2, Type::TInt));
        //     (c1, Type::TIntArray)
        // }
        // E::GetArray(ref id, ref idx) => {
        //     let (mut c1, t1) = gen_constraints(m, env, id)?;
        //     let (mut c2, t2) = gen_constraints(m, env, idx)?;
        //     c1.append(&mut c2);
        //     c1.push((t1, Type::TIntArray));
        //     c1.push((t2, Type::TInt));
        //     (c1, Type::TInt)
        // }
        // E::SetArray(ref id, ref idx, ref v) => {
        //     let (mut c1, t1) = gen_constraints(m, env, id)?;
        //     let (mut c2, t2) = gen_constraints(m, env, idx)?;
        //     let (mut c3, t3) = gen_constraints(m, env, v)?;
        //     c1.append(&mut c2);
        //     c1.append(&mut c3);
        //     c1.push((t1, Type::TIntArray));
        //     c1.push((t2, Type::TInt));
        //     c1.push((t3, Type::TInt));
        //     (c1, Type::TIntArray)
        // }
        E::Star => panic!("star found when it shouldn't be"),
        E::V => panic!("v found when it shouldn't be"),
        E::WellFormed(_) => panic!("wellformed found when it shouldn't be"),
        _ => panic!("! fixme"),
    }
}

pub fn extract(expr: &explicit::Expr) -> (implicit::Expr, HashMap<String, Type>) {
    let mut env: HashMap<String, Type> = HashMap::new();
    // keep track of α-renaming
    let mut renamed: HashMap<String, String> = HashMap::new();

    let (_, iexpr, _) = convert(1, &mut env, &renamed, expr);

    (iexpr, env)
}
<commit_msg>env: implement array ops<commit_after>use implicit;
use explicit;
use typed;

use std::collections::HashMap;
use explicit::Type;

fn convert(n: i32, env: &mut HashMap<String, Type>, renamed: &HashMap<String, String>, expr: &explicit::Expr) -> (i32, implicit::Expr, Type) {
    use common::Const;
    use implicit::Expr as I;
    use typed::Expr as E;
    match *expr {
        E::Const(Const::Int(c)) => (n, I::Const(Const::Int(c)), Type::TInt),
        E::Const(Const::Bool(c)) => (n, I::Const(Const::Bool(c)), Type::TBool),
        E::Op2(op, ref e1, ref e2) => {
            let (n, e1, _) = convert(n, env, renamed, e1);
            let (n, e2, _) = convert(n, env, renamed, e2);
            (n, I::Op2(op, box e1, box e2), explicit::opty(op))
        }
        E::If(ref e1, ref e2, ref e3) => {
            let (n, e1, _) = convert(n, env, renamed, e1);
            let (n, e2, t) = convert(n, env, renamed, e2);
            let (n, e3, _) = convert(n, env, renamed, e3);
            (n, I::If(box e1, box e2, box e3), t)
        }
        E::Var(ref x) => {
            let αx = renamed.get(x).unwrap();
            (n, I::Var(αx.clone()), env.get(αx).unwrap().clone())
        }
        E::Let(ref id, ref e1, ref e2) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            let (n, e1, t1) = convert(n, env, &renamed, e1);

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1);

            let (n, e2, t2) = convert(n, env, &renamed, e2);
            (n, I::Let(αid, box e1, box e2), t2)
        }
        E::Fun(ref id, ref t1, ref e) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1.clone());

            let (n, e, t2) = convert(n, env, &renamed, e);

            (n, I::Fun(αid, box e), Type::TFun(box t1.clone(), box t2))
        }
        E::Fix(ref id, ref t1, ref e) => {
            let mut renamed = renamed.clone();
            let (n, αid) = (n+1, format!("{}-α{}", id, n));

            renamed.insert(id.clone(), αid.clone());
            env.insert(αid.clone(), t1.clone());

            let (n, e, t2) = convert(n, env, &renamed, e);

            (n, I::Fix(αid, box e), t2)
        }
        E::App(ref e1, ref e2) => {
            let (n, e1, t1) = convert(n, env, renamed, e1);
            let (n, e2, _) = convert(n, env, renamed, e2);
            let t = match t1 {
                Type::TFun(_, t2) => *t2,
                _ => panic!("expected TFun, not {:?}", t1),
            };
            (n, I::App(box e1, box e2), t)
        }
        E::MkArray(ref sz, ref val) => {
            let (n, sz, _) = convert(n, env, renamed, sz);
            let (n, val, _) = convert(n, env, renamed, val);
            (n, I::MkArray(box sz, box val), Type::TIntArray)
        }
        E::GetArray(ref id, ref idx) => {
            let (n, id, _) = convert(n, env, renamed, id);
            let (n, idx, _) = convert(n, env, renamed, idx);
            (n, I::GetArray(box id, box idx), Type::TInt)
        }
        E::SetArray(ref id, ref idx, ref v) => {
            let (n, id, _) = convert(n, env, renamed, id);
            let (n, idx, _) = convert(n, env, renamed, idx);
            let (n, v, _) = convert(n, env, renamed, v);
            (n, I::SetArray(box id, box idx, box v), Type::TIntArray)
        }
        E::Star => panic!("star found when it shouldn't be"),
        E::V => panic!("v found when it shouldn't be"),
        E::WellFormed(_) => panic!("wellformed found when it shouldn't be"),
        _ => panic!("! fixme"),
    }
}

pub fn extract(expr: &explicit::Expr) -> (implicit::Expr, HashMap<String, Type>) {
    let mut env: HashMap<String, Type> = HashMap::new();
    // keep track of α-renaming
    let mut renamed: HashMap<String, String> = HashMap::new();

    let (_, iexpr, _) = convert(1, &mut env, &renamed, expr);

    (iexpr, env)
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate arg_parser;
extern crate extra;
extern crate walkdir;

use std::env;
use std::fs;
use std::io::{stderr, stdout, Write};
use std::path;
use std::process::exit;
use arg_parser::ArgParser;
use extra::io::fail;
use extra::option::OptionalExt;
use walkdir::WalkDir;

const MAN_PAGE: &'static str = /* @MANSTART{mv} */ r#"
NAME
    mv - move files

SYNOPSIS
    mv [ -h | --help ] SOURCE_FILE(S) DESTINATION_FILE

DESCRIPTION
    The mv utility renames the file named by the SOURCE_FILE operand to the destination path
    named by the DESTINATION_FILE operand. Otherwise moves files to new destination.

OPTIONS
    --help, -h
        print this message
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();
    let mut parser = ArgParser::new(1)
        .add_flag(&["r", "recursive"])
        .add_flag(&["n", "no-action"])
        .add_flag(&["v", "verbose"])
        .add_flag(&["h", "help"]);
    parser.parse(env::args());

    if parser.found("help") {
        stdout.write_all(MAN_PAGE.as_bytes()).try(&mut stderr);
        stdout.flush().try(&mut stderr);
        exit(0);
    }

    let recurse = parser.found("recursive");
    let verbose = parser.found("verbose");
    let execute = ! parser.found("no-action");

    if parser.args.is_empty() {
        fail("No source argument. Use --help to see the usage.", &mut stderr);
    }
    else if parser.args.len() == 1 {
        fail("No destination argument. Use --help to see the usage.", &mut stderr);
    }
    else if parser.args.len() == 2 && ! recurse {
        let src = path::Path::new(&parser.args[0]);
        let mut dst = path::PathBuf::from(&parser.args[1]);
        if dst.is_dir() {
            dst.push(src.file_name().try(&mut stderr))
        }
        if execute {
            fs::rename(src, dst).try(&mut stderr);
        }
        if verbose {
            println!("{}", src.display());
        }
    }
    else {
        // This unwrap won't panic since it's been verified not to be empty
        let dst = parser.args.pop().unwrap();
        let dst = path::PathBuf::from(dst);
        if dst.is_dir() {
            for ref arg in parser.args {
                let src = path::Path::new(arg);
                if src.is_dir() && ! recurse {
                    fail("Can not move directories non-recursive", &mut stderr);
                }
                if recurse {
                    for entry in WalkDir::new(arg) {
                        let entry = entry.unwrap();
                        let src = path::Path::new(entry.path());
                        if execute {
                            if src.is_dir() {
                                fs::create_dir(dst.join(src)).try(&mut stderr);
                            } else if src.is_file() {
                                fs::rename(src, dst.join(src)).try(&mut stderr);
                            } // here we might also want to check for symlink, hardlink, socket, block, char, ...?
                        }
                        if verbose {
                            println!("{}", src.display());
                        }
                    }
                } else {
                    if execute {
                        fs::rename(src, dst.join(src.file_name().try(&mut stderr))).try(&mut stderr);
                    }
                    if verbose {
                        println!("{}", src.display());
                    }
                }
            }
        }
        else if dst.is_file() {
            fail("Destination should be a path, not a file. Use --help to see the usage.", &mut stderr);
        }
        else {
            fail("No destination found. Use --help to see the usage.", &mut stderr);
        }
    }
}
<commit_msg>Reformatted, Restructured, Fix few bugs<commit_after>#![deny(warnings)]

extern crate arg_parser;
extern crate extra;
extern crate walkdir;

use std::env;
use std::fs;
use std::io::{stderr, stdout, Write};
use std::path;
use std::process::exit;
use arg_parser::ArgParser;
use extra::io::fail;
use extra::option::OptionalExt;
use walkdir::WalkDir;

const MAN_PAGE: &'static str = /* @MANSTART{mv} */ r#"
NAME
    mv - move files

SYNOPSIS
    mv [ -h | --help ] SOURCE_FILE(S) DESTINATION_FILE

DESCRIPTION
    The mv utility renames the file named by the SOURCE_FILE operand to the destination path
    named by the DESTINATION_FILE operand. Otherwise moves files to new destination.

OPTIONS
    --help, -h
        print this message
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();
    let mut parser = ArgParser::new(1)
        .add_flag(&["r", "recursive"])
        .add_flag(&["n", "no-action"])
        .add_flag(&["v", "verbose"])
        .add_flag(&["h", "help"]);
    parser.parse(env::args());

    if parser.found("help") {
        stdout.write_all(MAN_PAGE.as_bytes()).try(&mut stderr);
        stdout.flush().try(&mut stderr);
        exit(0);
    }

    let recurse = parser.found("recursive");
    let verbose = parser.found("verbose");
    let execute = ! parser.found("no-action");

    if parser.args.is_empty() {
        fail("No source argument. Use --help to see the usage.", &mut stderr);
    } else if parser.args.len() == 1 {
        fail("No destination argument. Use --help to see the usage.", &mut stderr);
    } else {
        // This unwrap won't panic since it's been verified not to be empty
        let dst = parser.args.pop().unwrap();
        let dst = path::PathBuf::from(dst);
        if dst.is_file() {
            if parser.args.len() == 2 {
                let src = path::Path::new(&parser.args[0]);
                if src.is_file() {
                    if execute {
                        fs::rename(src, dst).try(&mut stderr);
                    }
                    if verbose {
                        println!("{}", src.display());
                    }
                } else {
                    fail("Cannot move directory unto a file. Use --help to see the usage.", &mut stderr)
                }
            } else {
                fail("When moving multiple objects, destination should be to a path, not a file. Use --help to see the usage.", &mut stderr);
            }
        } else if dst.is_dir() {
            for ref arg in parser.args {
                let src = path::Path::new(arg);
                if src.is_dir() && !recurse {
                    fail("Can not move directories non-recursive", &mut stderr);
                }
                if recurse {
                    for entry in WalkDir::new(arg) {
                        let entry = entry.unwrap();
                        let src = path::Path::new(entry.path());
                        if execute {
                            if src.is_dir() {
                                fs::create_dir(dst.join(src)).try(&mut stderr);
                            } else if src.is_file() {
                                fs::rename(src, dst.join(src)).try(&mut stderr);
                            } // here we might also want to check for symlink, hardlink, socket, block, char, ...?
                        }
                        if verbose {
                            println!("{}", src.display());
                        }
                    }
                } else {
                    if execute {
                        fs::rename(src, dst.join(src.file_name().try(&mut stderr))).try(&mut stderr);
                    }
                    if verbose {
                        println!("{}", src.display());
                    }
                }
            }
        } else {
            fail("No destination found. Use --help to see the usage.", &mut stderr);
        }
    }
}
<|endoftext|>


<commit_before>use byteorder::{BigEndian, ByteOrder};
use aes;
use ghash;

pub struct GCM {
    cipher: aes::AES,
    hash_key: [u8; 16],
}

impl GCM {
    pub fn new(key: &[u8]) -> Self {
        let cipher = aes::AES::new(key);
        let hash_key = cipher.cipher(&[0; 16]);
        Self {
            cipher: cipher,
            hash_key: hash_key,
        }
    }

    pub fn auth_encrypt(&self, message: &[u8], data: &[u8], nonce: &[u8]) -> (Vec<u8>, [u8; 16]) {
        assert!(1 << 39 >= message.len() + 256);
        let y0 = self.get_y0(nonce);
        let ciphertext = self.encrypt(&message, &y0);
        let tag = self.tag(&ciphertext, data, &y0);
        (ciphertext, tag)
    }

    pub fn auth_decrypt(
        &self,
        ciphertext: &[u8],
        tag: &[u8],
        data: &[u8],
        nonce: &[u8],
    ) -> Result<Vec<u8>, ()> {
        assert_eq!(16, tag.len());
        let y0 = self.get_y0(nonce);
        let expected_tag = self.tag(ciphertext, data, &y0);
        self.check_tag(&expected_tag, tag)?;
        let message = self.encrypt(&ciphertext, &y0);
        Ok(message)
    }

    fn get_y0(&self, nonce: &[u8]) -> [u8; 16] {
        if nonce.len() == 12 {
            let mut y0 = [0; 16];
            y0[..12].copy_from_slice(nonce);
            y0[15] = 1;
            y0
        } else {
            ghash::ghash(&self.hash_key, &[], nonce)
        }
    }

    fn encrypt(&self, message: &[u8], y0: &[u8; 16]) -> Vec<u8> {
        let mut ciphertext = vec![];
        let y = (&y0[..12], BigEndian::read_u32(&y0[12..]));
        for (i, mi) in (1..).zip(message.chunks(16)) {
            let yi = Self::incr(y, i);
            ciphertext.extend(mi.iter().zip(&self.cipher.cipher(&yi)).map(|(x, y)| x ^ y));
        }
        ciphertext.truncate(message.len());
        ciphertext
    }

    fn tag(&self, ciphertext: &[u8], data: &[u8], y0: &[u8; 16]) -> [u8; 16] {
        let mut tag = ghash::ghash(&self.hash_key, data, &ciphertext);
        for (t, &x) in tag.iter_mut().zip(&self.cipher.cipher(y0)) {
            *t ^= x;
        }
        tag
    }

    /// Meant to check tag without early returns
    fn check_tag(&self, expected: &[u8], tag: &[u8]) -> Result<(), ()> {
        let valid = expected.iter().zip(tag).fold(
            true,
            |acc, (x, y)| acc && x == y,
        );
        if valid { Ok(()) } else { Err(()) }
    }
    fn incr((f, w): (&[u8], u32), i: u32) -> [u8; 16] {
        let mut y = [0; 16];
        y[..12].copy_from_slice(f);
        BigEndian::write_u32(&mut y[12..], w.wrapping_add(i));
        y
    }
}

#[cfg(test)]
mod tests {
    use gcm::*;

    fn check(k: &[u8], m: &Vec<u8>, a: &[u8], n: &[u8], c: &Vec<u8>, t: &[u8]) {
        let gcm = GCM::new(&k);
        let actual = gcm.auth_encrypt(&m, &a, &n);
        assert_eq!(c, &actual.0);
        assert_eq!(t, actual.1);
        assert_eq!(m, &gcm.auth_decrypt(&c, &t, &a, &n).unwrap());
    }

    #[test]
    fn test_case_13_14() {
        let key = [0; 32];
        let nonce = [0; 12];
        let tag = [
            0x53,
            0x0f,
            0x8a,
            0xfb,
            0xc7,
            0x45,
            0x36,
            0xb9,
            0xa9,
            0x63,
            0xb4,
            0xf1,
            0xc4,
            0xcb,
            0x73,
            0x8b,
        ];
        check(&key, &vec![], &[], &nonce, &vec![], &tag);

        let message = vec![0; 16];
        let ciphertext = vec![
            0xce,
            0xa7,
            0x40,
            0x3d,
            0x4d,
            0x60,
            0x6b,
            0x6e,
            0x07,
            0x4e,
            0xc5,
            0xd3,
            0xba,
            0xf3,
            0x9d,
            0x18,
        ];
        let tag = [
            0xd0,
            0xd1,
            0xc8,
            0xa7,
            0x99,
            0x99,
            0x6b,
            0xf0,
            0x26,
            0x5b,
            0x98,
            0xb5,
            0xd4,
            0x8a,
            0xb9,
            0x19,
        ];
        check(&key, &message, &[], &nonce, &ciphertext, &tag);
    }

    #[test]
    fn test_case_15_16_17_18() {
        let key = [
            0xfe,
            0xff,
            0xe9,
            0x92,
            0x86,
            0x65,
            0x73,
            0x1c,
            0x6d,
            0x6a,
            0x8f,
            0x94,
            0x67,
            0x30,
            0x83,
            0x08,
            0xfe,
            0xff,
            0xe9,
            0x92,
            0x86,
            0x65,
            0x73,
            0x1c,
            0x6d,
            0x6a,
            0x8f,
            0x94,
            0x67,
            0x30,
            0x83,
            0x08,
        ];
        let mut message = vec![
            0xd9,
            0x31,
            0x32,
            0x25,
            0xf8,
            0x84,
            0x06,
            0xe5,
            0xa5,
            0x59,
            0x09,
            0xc5,
            0xaf,
            0xf5,
            0x26,
            0x9a,
            0x86,
            0xa7,
            0xa9,
            0x53,
            0x15,
            0x34,
            0xf7,
            0xda,
            0x2e,
            0x4c,
            0x30,
            0x3d,
            0x8a,
            0x31,
            0x8a,
            0x72,
            0x1c,
            0x3c,
            0x0c,
            0x95,
            0x95,
            0x68,
            0x09,
            0x53,
            0x2f,
            0xcf,
            0x0e,
            0x24,
            0x49,
            0xa6,
            0xb5,
            0x25,
            0xb1,
            0x6a,
            0xed,
            0xf5,
            0xaa,
            0x0d,
            0xe6,
            0x57,
            0xba,
            0x63,
            0x7b,
            0x39,
            0x1a,
            0xaf,
            0xd2,
            0x55,
        ];
        let nonce = [
            0xca,
            0xfe,
            0xba,
            0xbe,
            0xfa,
            0xce,
            0xdb,
            0xad,
            0xde,
            0xca,
            0xf8,
            0x88,
        ];
        let mut ciphertext = vec![
            0x52,
            0x2d,
            0xc1,
            0xf0,
            0x99,
            0x56,
            0x7d,
            0x07,
            0xf4,
            0x7f,
            0x37,
            0xa3,
            0x2a,
            0x84,
            0x42,
            0x7d,
            0x64,
            0x3a,
            0x8c,
            0xdc,
            0xbf,
            0xe5,
            0xc0,
            0xc9,
            0x75,
            0x98,
            0xa2,
            0xbd,
            0x25,
            0x55,
            0xd1,
            0xaa,
            0x8c,
            0xb0,
            0x8e,
            0x48,
            0x59,
            0x0d,
            0xbb,
            0x3d,
            0xa7,
            0xb0,
            0x8b,
            0x10,
            0x56,
            0x82,
            0x88,
            0x38,
            0xc5,
            0xf6,
            0x1e,
            0x63,
            0x93,
            0xba,
            0x7a,
            0x0a,
            0xbc,
            0xc9,
            0xf6,
            0x62,
            0x89,
            0x80,
            0x15,
            0xad,
        ];
        let tag = [
            0xb0,
            0x94,
            0xda,
            0xc5,
            0xd9,
            0x34,
            0x71,
            0xbd,
            0xec,
            0x1a,
            0x50,
            0x22,
            0x70,
            0xe3,
            0xcc,
            0x6c,
        ];
        check(&key, &message, &[], &nonce, &ciphertext, &tag);

        message.truncate(60);
        ciphertext.truncate(60);
        let data = [
            0xfe,
            0xed,
            0xfa,
            0xce,
            0xde,
            0xad,
            0xbe,
            0xef,
            0xfe,
            0xed,
            0xfa,
            0xce,
            0xde,
            0xad,
            0xbe,
            0xef,
            0xab,
            0xad,
            0xda,
            0xd2,
        ];
        let tag = [
            0x76,
            0xfc,
            0x6e,
            0xce,
            0x0f,
            0x4e,
            0x17,
            0x68,
            0xcd,
            0xdf,
            0x88,
            0x53,
            0xbb,
            0x2d,
            0x55,
            0x1b,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);

        let nonce = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
        let ciphertext = vec![
            0xc3,
            0x76,
            0x2d,
            0xf1,
            0xca,
            0x78,
            0x7d,
            0x32,
            0xae,
            0x47,
            0xc1,
            0x3b,
            0xf1,
            0x98,
            0x44,
            0xcb,
            0xaf,
            0x1a,
            0xe1,
            0x4d,
            0x0b,
            0x97,
            0x6a,
            0xfa,
            0xc5,
            0x2f,
            0xf7,
            0xd7,
            0x9b,
            0xba,
            0x9d,
            0xe0,
            0xfe,
            0xb5,
            0x82,
            0xd3,
            0x39,
            0x34,
            0xa4,
            0xf0,
            0x95,
            0x4c,
            0xc2,
            0x36,
            0x3b,
            0xc7,
            0x3f,
            0x78,
            0x62,
            0xac,
            0x43,
            0x0e,
            0x64,
            0xab,
            0xe4,
            0x99,
            0xf4,
            0x7c,
            0x9b,
            0x1f,
        ];
        let tag = [
            0x3a,
            0x33,
            0x7d,
            0xbf,
            0x46,
            0xa7,
            0x92,
            0xc4,
            0x5e,
            0x45,
            0x49,
            0x13,
            0xfe,
            0x2e,
            0xa8,
            0xf2,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);

        let nonce = [
            0x93,
            0x13,
            0x22,
            0x5d,
            0xf8,
            0x84,
            0x06,
            0xe5,
            0x55,
            0x90,
            0x9c,
            0x5a,
            0xff,
            0x52,
            0x69,
            0xaa,
            0x6a,
            0x7a,
            0x95,
            0x38,
            0x53,
            0x4f,
            0x7d,
            0xa1,
            0xe4,
            0xc3,
            0x03,
            0xd2,
            0xa3,
            0x18,
            0xa7,
            0x28,
            0xc3,
            0xc0,
            0xc9,
            0x51,
            0x56,
            0x80,
            0x95,
            0x39,
            0xfc,
            0xf0,
            0xe2,
            0x42,
            0x9a,
            0x6b,
            0x52,
            0x54,
            0x16,
            0xae,
            0xdb,
            0xf5,
            0xa0,
            0xde,
            0x6a,
            0x57,
            0xa6,
            0x37,
            0xb3,
            0x9b,
        ];
        let ciphertext = vec![
            0x5a,
            0x8d,
            0xef,
            0x2f,
            0x0c,
            0x9e,
            0x53,
            0xf1,
            0xf7,
            0x5d,
            0x78,
            0x53,
            0x65,
            0x9e,
            0x2a,
            0x20,
            0xee,
            0xb2,
            0xb2,
            0x2a,
            0xaf,
            0xde,
            0x64,
            0x19,
            0xa0,
            0x58,
            0xab,
            0x4f,
            0x6f,
            0x74,
            0x6b,
            0xf4,
            0x0f,
            0xc0,
            0xc3,
            0xb7,
            0x80,
            0xf2,
            0x44,
            0x45,
            0x2d,
            0xa3,
            0xeb,
            0xf1,
            0xc5,
            0xd8,
            0x2c,
            0xde,
            0xa2,
            0x41,
            0x89,
            0x97,
            0x20,
            0x0e,
            0xf8,
            0x2e,
            0x44,
            0xae,
            0x7e,
            0x3f,
        ];
        let tag = [
            0xa4,
            0x4a,
            0x82,
            0x66,
            0xee,
            0x1c,
            0x8e,
            0xb0,
            0xc8,
            0xb5,
            0xd4,
            0xcf,
            0x5a,
            0xe9,
            0xf1,
            0x9a,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);
    }
}
<commit_msg>gcm: encrypt() -> counter_mode()<commit_after>use byteorder::{BigEndian, ByteOrder};
use aes;
use ghash;

pub struct GCM {
    cipher: aes::AES,
    hash_key: [u8; 16],
}

impl GCM {
    pub fn new(key: &[u8]) -> Self {
        let cipher = aes::AES::new(key);
        let hash_key = cipher.cipher(&[0; 16]);
        Self {
            cipher: cipher,
            hash_key: hash_key,
        }
    }

    pub fn auth_encrypt(&self, message: &[u8], data: &[u8], nonce: &[u8]) -> (Vec<u8>, [u8; 16]) {
        assert!(1 << 39 >= message.len() + 256);
        let y0 = self.get_y0(nonce);
        let ciphertext = self.counter_mode(&message, &y0);
        let tag = self.tag(&ciphertext, data, &y0);
        (ciphertext, tag)
    }

    pub fn auth_decrypt(
        &self,
        ciphertext: &[u8],
        tag: &[u8],
        data: &[u8],
        nonce: &[u8],
    ) -> Result<Vec<u8>, ()> {
        assert_eq!(16, tag.len());
        let y0 = self.get_y0(nonce);
        let expected_tag = self.tag(ciphertext, data, &y0);
        self.check_tag(&expected_tag, tag)?;
        let message = self.counter_mode(&ciphertext, &y0);
        Ok(message)
    }

    fn get_y0(&self, nonce: &[u8]) -> [u8; 16] {
        if nonce.len() == 12 {
            let mut y0 = [0; 16];
            y0[..12].copy_from_slice(nonce);
            y0[15] = 1;
            y0
        } else {
            ghash::ghash(&self.hash_key, &[], nonce)
        }
    }

    fn counter_mode(&self, input: &[u8], y0: &[u8; 16]) -> Vec<u8> {
        let mut output = vec![];
        let y = (&y0[..12], BigEndian::read_u32(&y0[12..]));
        for (i, mi) in (1..).zip(input.chunks(16)) {
            let yi = Self::incr(y, i);
            output.extend(mi.iter().zip(&self.cipher.cipher(&yi)).map(|(x, y)| x ^ y));
        }
        output.truncate(input.len());
        output
    }

    fn tag(&self, ciphertext: &[u8], data: &[u8], y0: &[u8; 16]) -> [u8; 16] {
        let mut tag = ghash::ghash(&self.hash_key, data, &ciphertext);
        for (t, &x) in tag.iter_mut().zip(&self.cipher.cipher(y0)) {
            *t ^= x;
        }
        tag
    }

    /// Meant to check tag without early returns
    fn check_tag(&self, expected: &[u8], tag: &[u8]) -> Result<(), ()> {
        let valid = expected.iter().zip(tag).fold(
            true,
            |acc, (x, y)| acc && x == y,
        );
        if valid { Ok(()) } else { Err(()) }
    }
    fn incr((f, w): (&[u8], u32), i: u32) -> [u8; 16] {
        let mut y = [0; 16];
        y[..12].copy_from_slice(f);
        BigEndian::write_u32(&mut y[12..], w.wrapping_add(i));
        y
    }
}

#[cfg(test)]
mod tests {
    use gcm::*;

    fn check(k: &[u8], m: &Vec<u8>, a: &[u8], n: &[u8], c: &Vec<u8>, t: &[u8]) {
        let gcm = GCM::new(&k);
        let actual = gcm.auth_encrypt(&m, &a, &n);
        assert_eq!(c, &actual.0);
        assert_eq!(t, actual.1);
        assert_eq!(m, &gcm.auth_decrypt(&c, &t, &a, &n).unwrap());
    }

    #[test]
    fn test_case_13_14() {
        let key = [0; 32];
        let nonce = [0; 12];
        let tag = [
            0x53,
            0x0f,
            0x8a,
            0xfb,
            0xc7,
            0x45,
            0x36,
            0xb9,
            0xa9,
            0x63,
            0xb4,
            0xf1,
            0xc4,
            0xcb,
            0x73,
            0x8b,
        ];
        check(&key, &vec![], &[], &nonce, &vec![], &tag);

        let message = vec![0; 16];
        let ciphertext = vec![
            0xce,
            0xa7,
            0x40,
            0x3d,
            0x4d,
            0x60,
            0x6b,
            0x6e,
            0x07,
            0x4e,
            0xc5,
            0xd3,
            0xba,
            0xf3,
            0x9d,
            0x18,
        ];
        let tag = [
            0xd0,
            0xd1,
            0xc8,
            0xa7,
            0x99,
            0x99,
            0x6b,
            0xf0,
            0x26,
            0x5b,
            0x98,
            0xb5,
            0xd4,
            0x8a,
            0xb9,
            0x19,
        ];
        check(&key, &message, &[], &nonce, &ciphertext, &tag);
    }

    #[test]
    fn test_case_15_16_17_18() {
        let key = [
            0xfe,
            0xff,
            0xe9,
            0x92,
            0x86,
            0x65,
            0x73,
            0x1c,
            0x6d,
            0x6a,
            0x8f,
            0x94,
            0x67,
            0x30,
            0x83,
            0x08,
            0xfe,
            0xff,
            0xe9,
            0x92,
            0x86,
            0x65,
            0x73,
            0x1c,
            0x6d,
            0x6a,
            0x8f,
            0x94,
            0x67,
            0x30,
            0x83,
            0x08,
        ];
        let mut message = vec![
            0xd9,
            0x31,
            0x32,
            0x25,
            0xf8,
            0x84,
            0x06,
            0xe5,
            0xa5,
            0x59,
            0x09,
            0xc5,
            0xaf,
            0xf5,
            0x26,
            0x9a,
            0x86,
            0xa7,
            0xa9,
            0x53,
            0x15,
            0x34,
            0xf7,
            0xda,
            0x2e,
            0x4c,
            0x30,
            0x3d,
            0x8a,
            0x31,
            0x8a,
            0x72,
            0x1c,
            0x3c,
            0x0c,
            0x95,
            0x95,
            0x68,
            0x09,
            0x53,
            0x2f,
            0xcf,
            0x0e,
            0x24,
            0x49,
            0xa6,
            0xb5,
            0x25,
            0xb1,
            0x6a,
            0xed,
            0xf5,
            0xaa,
            0x0d,
            0xe6,
            0x57,
            0xba,
            0x63,
            0x7b,
            0x39,
            0x1a,
            0xaf,
            0xd2,
            0x55,
        ];
        let nonce = [
            0xca,
            0xfe,
            0xba,
            0xbe,
            0xfa,
            0xce,
            0xdb,
            0xad,
            0xde,
            0xca,
            0xf8,
            0x88,
        ];
        let mut ciphertext = vec![
            0x52,
            0x2d,
            0xc1,
            0xf0,
            0x99,
            0x56,
            0x7d,
            0x07,
            0xf4,
            0x7f,
            0x37,
            0xa3,
            0x2a,
            0x84,
            0x42,
            0x7d,
            0x64,
            0x3a,
            0x8c,
            0xdc,
            0xbf,
            0xe5,
            0xc0,
            0xc9,
            0x75,
            0x98,
            0xa2,
            0xbd,
            0x25,
            0x55,
            0xd1,
            0xaa,
            0x8c,
            0xb0,
            0x8e,
            0x48,
            0x59,
            0x0d,
            0xbb,
            0x3d,
            0xa7,
            0xb0,
            0x8b,
            0x10,
            0x56,
            0x82,
            0x88,
            0x38,
            0xc5,
            0xf6,
            0x1e,
            0x63,
            0x93,
            0xba,
            0x7a,
            0x0a,
            0xbc,
            0xc9,
            0xf6,
            0x62,
            0x89,
            0x80,
            0x15,
            0xad,
        ];
        let tag = [
            0xb0,
            0x94,
            0xda,
            0xc5,
            0xd9,
            0x34,
            0x71,
            0xbd,
            0xec,
            0x1a,
            0x50,
            0x22,
            0x70,
            0xe3,
            0xcc,
            0x6c,
        ];
        check(&key, &message, &[], &nonce, &ciphertext, &tag);

        message.truncate(60);
        ciphertext.truncate(60);
        let data = [
            0xfe,
            0xed,
            0xfa,
            0xce,
            0xde,
            0xad,
            0xbe,
            0xef,
            0xfe,
            0xed,
            0xfa,
            0xce,
            0xde,
            0xad,
            0xbe,
            0xef,
            0xab,
            0xad,
            0xda,
            0xd2,
        ];
        let tag = [
            0x76,
            0xfc,
            0x6e,
            0xce,
            0x0f,
            0x4e,
            0x17,
            0x68,
            0xcd,
            0xdf,
            0x88,
            0x53,
            0xbb,
            0x2d,
            0x55,
            0x1b,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);

        let nonce = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
        let ciphertext = vec![
            0xc3,
            0x76,
            0x2d,
            0xf1,
            0xca,
            0x78,
            0x7d,
            0x32,
            0xae,
            0x47,
            0xc1,
            0x3b,
            0xf1,
            0x98,
            0x44,
            0xcb,
            0xaf,
            0x1a,
            0xe1,
            0x4d,
            0x0b,
            0x97,
            0x6a,
            0xfa,
            0xc5,
            0x2f,
            0xf7,
            0xd7,
            0x9b,
            0xba,
            0x9d,
            0xe0,
            0xfe,
            0xb5,
            0x82,
            0xd3,
            0x39,
            0x34,
            0xa4,
            0xf0,
            0x95,
            0x4c,
            0xc2,
            0x36,
            0x3b,
            0xc7,
            0x3f,
            0x78,
            0x62,
            0xac,
            0x43,
            0x0e,
            0x64,
            0xab,
            0xe4,
            0x99,
            0xf4,
            0x7c,
            0x9b,
            0x1f,
        ];
        let tag = [
            0x3a,
            0x33,
            0x7d,
            0xbf,
            0x46,
            0xa7,
            0x92,
            0xc4,
            0x5e,
            0x45,
            0x49,
            0x13,
            0xfe,
            0x2e,
            0xa8,
            0xf2,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);

        let nonce = [
            0x93,
            0x13,
            0x22,
            0x5d,
            0xf8,
            0x84,
            0x06,
            0xe5,
            0x55,
            0x90,
            0x9c,
            0x5a,
            0xff,
            0x52,
            0x69,
            0xaa,
            0x6a,
            0x7a,
            0x95,
            0x38,
            0x53,
            0x4f,
            0x7d,
            0xa1,
            0xe4,
            0xc3,
            0x03,
            0xd2,
            0xa3,
            0x18,
            0xa7,
            0x28,
            0xc3,
            0xc0,
            0xc9,
            0x51,
            0x56,
            0x80,
            0x95,
            0x39,
            0xfc,
            0xf0,
            0xe2,
            0x42,
            0x9a,
            0x6b,
            0x52,
            0x54,
            0x16,
            0xae,
            0xdb,
            0xf5,
            0xa0,
            0xde,
            0x6a,
            0x57,
            0xa6,
            0x37,
            0xb3,
            0x9b,
        ];
        let ciphertext = vec![
            0x5a,
            0x8d,
            0xef,
            0x2f,
            0x0c,
            0x9e,
            0x53,
            0xf1,
            0xf7,
            0x5d,
            0x78,
            0x53,
            0x65,
            0x9e,
            0x2a,
            0x20,
            0xee,
            0xb2,
            0xb2,
            0x2a,
            0xaf,
            0xde,
            0x64,
            0x19,
            0xa0,
            0x58,
            0xab,
            0x4f,
            0x6f,
            0x74,
            0x6b,
            0xf4,
            0x0f,
            0xc0,
            0xc3,
            0xb7,
            0x80,
            0xf2,
            0x44,
            0x45,
            0x2d,
            0xa3,
            0xeb,
            0xf1,
            0xc5,
            0xd8,
            0x2c,
            0xde,
            0xa2,
            0x41,
            0x89,
            0x97,
            0x20,
            0x0e,
            0xf8,
            0x2e,
            0x44,
            0xae,
            0x7e,
            0x3f,
        ];
        let tag = [
            0xa4,
            0x4a,
            0x82,
            0x66,
            0xee,
            0x1c,
            0x8e,
            0xb0,
            0xc8,
            0xb5,
            0xd4,
            0xcf,
            0x5a,
            0xe9,
            0xf1,
            0x9a,
        ];
        check(&key, &message, &data, &nonce, &ciphertext, &tag);
    }
}
<|endoftext|>


<commit_before>use std::io::Result;
use std::path::Path;
use std::process::{Command, Output};

fn git_command(path: impl AsRef<Path>, subcommand: &[&str]) -> Result<Output> {
    let git_path = path
        .as_ref()
        .to_str()
        .expect("Repository path must be a valid UTF-8 string");

    let mut args = vec!["-C", git_path];
    args.extend(subcommand);

    Command::new("git").args(&args).output()
}

pub fn repo_hash(path: impl AsRef<Path>) -> Option<String> {
    let output = git_command(path.as_ref(), &["rev-parse", "--short", "HEAD"]).ok()?;
    if !output.status.success() {
        return None;
    }
    let hash = String::from_utf8(output.stdout).ok()?;
    let hash = hash.trim_end_matches('\n');

    if dirty(path) {
        Some(format!("{}+", hash))
    } else {
        Some(hash.into())
    }
}

fn dirty(path: impl AsRef<Path>) -> bool {
    match git_command(path.as_ref(), &["ls-files", "-m"]) {
        Ok(modified_files) => !modified_files.stdout.is_empty(),
        Err(_) => false,
    }
}

// This file is also compiled from build.rs where this function is unused
#[allow(dead_code)]
pub(crate) fn repo_remote_url(path: impl AsRef<Path>) -> Option<String> {
    let output = ["upstream", "origin"].iter().find_map(|remote| {
        let output = git_command(path.as_ref(), &["remote", "get-url", remote]).ok()?;
        // XXX: Use `.then_some` when it is stabilized
        output.status.success().then(|| output)
    })?;
    String::from_utf8(output.stdout)
        .ok()
        .map(|s| s.trim_end_matches('\n').into())
}
<commit_msg>git: Read URL for submodules from .gitmodules<commit_after>use std::io::Result;
use std::path::Path;
use std::process::{Command, Output};

fn git_command(path: impl AsRef<Path>, subcommand: &[&str]) -> Result<Output> {
    let git_path = path
        .as_ref()
        .to_str()
        .expect("Repository path must be a valid UTF-8 string");

    let mut args = vec!["-C", git_path];
    args.extend(subcommand);

    Command::new("git").args(&args).output()
}

pub fn repo_hash(path: impl AsRef<Path>) -> Option<String> {
    let output = git_command(path.as_ref(), &["rev-parse", "--short", "HEAD"]).ok()?;
    if !output.status.success() {
        return None;
    }
    let hash = String::from_utf8(output.stdout).ok()?;
    let hash = hash.trim_end_matches('\n');

    if dirty(path) {
        Some(format!("{}+", hash))
    } else {
        Some(hash.into())
    }
}

fn dirty(path: impl AsRef<Path>) -> bool {
    match git_command(path.as_ref(), &["ls-files", "-m"]) {
        Ok(modified_files) => !modified_files.stdout.is_empty(),
        Err(_) => false,
    }
}

fn gitmodules_config(subcommand: &[&str]) -> Option<String> {
    let mut args = vec!["config", "-f", ".gitmodules", "-z"];
    args.extend(subcommand);
    let output = git_command(Path::new("."), &args).ok()?;

    if !output.status.success() {
        return None;
    }

    let mut result = String::from_utf8(output.stdout).ok()?;
    assert_eq!(result.pop(), Some('\0'));
    Some(result)
}

// This file is also compiled from build.rs where this function is unused
#[allow(dead_code)]
pub(crate) fn repo_remote_url(path: impl AsRef<Path>) -> Option<String> {
    // Find the subsection that defines the module for the given path:
    let key_for_path = gitmodules_config(&[
        "--name-only",
        "--get-regexp",
        r"submodule\..+\.path",
        &format!("^{}$", path.as_ref().display()),
    ])?;

    let subsection = key_for_path
        .strip_suffix(".path")
        .expect("submodule.<subsection>.path should end with '.path'");

    gitmodules_config(&["--get", &format!("{}.url", subsection)])
}
<|endoftext|>