From 0101bb5c5f0d293498b3194ab3e2ee24c78371e5 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 25 May 2020 08:29:05 +0100 Subject: [PATCH] opt system --- generator-native/src/arg.rs | 63 +++++++++++++++++ generator-native/src/main.rs | 29 +++++++- generator-native/src/opt/mod.rs | 119 ++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 generator-native/src/arg.rs create mode 100644 generator-native/src/opt/mod.rs diff --git a/generator-native/src/arg.rs b/generator-native/src/arg.rs new file mode 100644 index 0000000..325da44 --- /dev/null +++ b/generator-native/src/arg.rs @@ -0,0 +1,63 @@ +use crate::{ + opt::{Opt, Options}, +}; + +pub enum OperationMode { + Normal(Options, Vec), + Help, +} + +pub fn parse() -> Result +{ + let mut opt = Options::new(); + let mut files = Vec::new(); + let mut look = true; + + let args: Vec = std::env::args().collect(); + let mut i=1; + while i < args.len() + { + let arg = &args[i]; + match arg.as_str() { + "-h" if i == 1 => { + return Ok(OperationMode::Help); + }, + "-s" if look => { + opt |= Opt::Silent; + }, + "-e" if look => { + if i < args.len() - 1 { + opt |= Opt::Execute(args[i+1].to_owned()); + } else { + return Err("-e expects an argument that wasn't given."); + } + i += 1; + }, + "-o" if look => { + if i < args.len() - 1 { + opt |= Opt::Output(args[i+1].to_owned()); + } else { + return Err("-o expects an argument that wasn't given."); + } + i += 1; + }, + "-" if look => look=false, + other => { + files.push(other.to_owned()); + look=false; + }, + } + i += 1; + } + + if files.len() < 1 { + return Err("No files specified. For help run with `-h`"); + } + + Ok(OperationMode::Normal(opt, files)) +} + +pub fn program_name() -> String +{ + std::env::args().next().unwrap() +} diff --git a/generator-native/src/main.rs b/generator-native/src/main.rs index 02d4a1a..94196ed 100644 --- a/generator-native/src/main.rs +++ b/generator-native/src/main.rs @@ -15,12 +15,28 @@ use iter::prelude::*; mod translate; +mod opt; +mod arg; + +fn usage() -> ! { + let prog = &arg::program_name(); + println!("Usage: {} [-s] [-e ] [-o ] ", prog); + println!("Usage: {} -h", prog); + println!(); + println!(" -h\t\tPrint this message."); + println!(" -s\t\tSilent mode."); + println!(" -e \tScript to run after extraction."); + println!(" -o \tOutput filename."); + std::process::exit(1); +} + fn main() -> Result<(), Box>{ - let file = OpenOptions::new() + /*let file = OpenOptions::new() .read(true) .open("test.txt")?; + println!("{{"); for buf in file.into_iter(4) .map(|byte| format!("0x{:02x},", byte)) @@ -29,7 +45,16 @@ fn main() -> Result<(), Box>{ { println!("{}", buf); } - println!("}}"); + println!("}}");*/ + + match arg::parse()? { + arg::OperationMode::Normal(options, files) => { + //TODO: Operations + }, + arg::OperationMode::Help => { + usage(); + }, + }; Ok(()) } diff --git a/generator-native/src/opt/mod.rs b/generator-native/src/opt/mod.rs new file mode 100644 index 0000000..9e46baf --- /dev/null +++ b/generator-native/src/opt/mod.rs @@ -0,0 +1,119 @@ +use std::{ + collections::HashSet, + iter::FromIterator, +}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Opt +{ + Silent, + Execute(String), + Output(String), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Options(HashSet); + +impl Options +{ + pub fn new() -> Self + { + Self(HashSet::new()) + } + + pub fn has_tag(&self, opt: &Opt) -> bool { + for x in self.0.iter() { + if x == opt { + return true; + } + } + false + } +} + +//operators + +use std::ops; +// opts |= opt +impl ops::BitOrAssign for Options +{ + fn bitor_assign(&mut self, rhs: Opt) + { + self.0.insert(rhs); + } +} +// opts |= other_opts +impl ops::BitOrAssign for Options +{ + fn bitor_assign(&mut self, other: Self) + { + self.0.extend(other.0) + } +} + +// opt1 | opt2 +impl ops::BitOr for Opt +{ + type Output = Options; + + fn bitor(self, other: Self) -> ::Output + { + Options::from([self, other].to_vec()) + } +} + +impl ops::BitAnd for Options +{ + type Output = bool; + + fn bitand(self, other: Opt) -> bool + { + self.has_tag(&other) + } +} +impl ops::BitAnd for Options +{ + type Output = bool; + fn bitand(self, other: Self) -> bool + { + for x in other.0.iter() + { + if !self.has_tag(x) { + return false; + } + } + + true + } +} + +impl From> for Options +{ + fn from(other: Vec) -> Self{ + let mut hs = HashSet::new(); + for x in other.into_iter() + { + hs.insert(x); + } + Self(hs) + } +} + +impl From for Vec +{ + fn from(other: Options) -> Vec + { + Vec::from_iter(other.0.into_iter()) + } +} + +impl IntoIterator for Options +{ + type Item = Opt; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter + { + Vec::from(self).into_iter() + } +}