diff options
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/init.rs | 108 | ||||
-rw-r--r-- | src/app/main.rs | 48 | ||||
-rw-r--r-- | src/app/print_help.rs | 50 | ||||
-rw-r--r-- | src/app/print_version.rs | 35 | ||||
-rw-r--r-- | src/app/run.rs | 56 |
5 files changed, 297 insertions, 0 deletions
diff --git a/src/app/init.rs b/src/app/init.rs new file mode 100644 index 0000000..8ed43ac --- /dev/null +++ b/src/app/init.rs @@ -0,0 +1,108 @@ +/* + Copyright 2023 Gabriel Jensen. + + This file is part of aas. + + aas is free software: you can redistribute it + and/or modify it under the terms of the GNU + General Public License as published by the Free + Software Foundation, either version 3 of the + License, or (at your option) any later version. + + aas is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU + General Public License along with aas. If not, + see <https://www.gnu.org/licenses/>. +*/ + +use crate::app::App; +use crate::cpu::Cpu; +use crate::format::Format; + +use std::env::args; +use std::str::FromStr; + +macro_rules! use_remainder { + ($destination: ident, $argument: expr, $index: expr) => {{ + let argument: &[char] = $argument; + let index: usize = $index + 0x1; + + if argument.len() <= index { + let c = argument[index - 0x1]; + Err(format!("missing value for short '{}'", c)) + } else { + let value: String = argument[$index + 0x1..].iter().collect(); + $destination = Some(value); + + break; + } + }}; +} + +impl App { + pub fn init() -> Result<Self, String> { + if args().len() < 0x2 { Self::print_help() }; + + let mut input: Option<String> = None; + let mut output: Option<String> = None; + let mut cpu: Option<String> = None; + let mut format: Option<String> = None; + + let mut handle_short = |argument: &String| -> Result<(), String> { + let argument: Vec<char> = argument.chars().collect(); + + for (index, c) in argument.iter().enumerate().skip(0x1) { + match c { + 'f' => use_remainder!(format, &argument, index)?, + 'h' => Self::print_help(), + 'o' => use_remainder!(output, &argument, index)?, + 'm' => use_remainder!(cpu, &argument, index)?, + 'v' => Self::print_version(), + + _ => { return Err(format!("invalid short parameter '{c}'")) }, + }; + } + + return Ok(()); + }; + + for argument in args().skip(0x1) { + if argument.is_empty() { continue }; + + if argument.chars().nth(0x0) != Some('-') { + // This argument is the input path. + + if input.is_some() { return Err(format!("input pathy is already set (to \"{}\")", input.as_ref().unwrap())) }; + + input = Some(argument.to_owned()); + continue; + } + + handle_short(&argument)?; + } + + // Check if any of the mandatory parameters have + // been set. + if input.is_none() { return Err("missing input path".to_string()) }; + if output.is_none() { output = Some("a.out".to_string()) }; + if cpu.is_none() { return Err("missing cpu".to_string()) }; + + let format = match format { + Some(format) => Format::from_str(&format)?, + _ => Format::default(), + }; + + return Ok(Self { + input: input.unwrap(), + output: output.unwrap(), + + cpu: Cpu::from_str(&cpu.unwrap())?, + format, + }); + } +} diff --git a/src/app/main.rs b/src/app/main.rs new file mode 100644 index 0000000..bd82623 --- /dev/null +++ b/src/app/main.rs @@ -0,0 +1,48 @@ +/* + Copyright 2023 Gabriel Jensen. + + This file is part of aas. + + aas is free software: you can redistribute it + and/or modify it under the terms of the GNU + General Public License as published by the Free + Software Foundation, either version 3 of the + License, or (at your option) any later version. + + aas is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU + General Public License along with aas. If not, + see <https://www.gnu.org/licenses/>. +*/ + +use crate::log; +use crate::app::App; + +use std::process::exit; + +impl App { + pub fn main() -> ! { + let app = match App::init() { + Ok(app) => app, + + Err(message) => { + log!(error, "{message}"); + exit(0x1); + }, + }; + + exit(match app.run() { + Err(message) => { + log!(error, "{message}"); + 0x1 + }, + + _ => 0x0, + }); + } +} diff --git a/src/app/print_help.rs b/src/app/print_help.rs new file mode 100644 index 0000000..1df895e --- /dev/null +++ b/src/app/print_help.rs @@ -0,0 +1,50 @@ +/* + Copyright 2023 Gabriel Jensen. + + This file is part of aas. + + aas is free software: you can redistribute it + and/or modify it under the terms of the GNU + General Public License as published by the Free + Software Foundation, either version 3 of the + License, or (at your option) any later version. + + aas is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU + General Public License along with aas. If not, + see <https://www.gnu.org/licenses/>. +*/ + +use crate::app::App; +use crate::cpu::Cpu; +use crate::format::Format; + +use enum_iterator::all; +use std::process::exit; + +impl App { + pub fn print_help() -> ! { + println!("\u{1B}[1mUsage\u{1B}[0m: \u{1B}[1maas\u{1B}[0m \u{1B}[3m[options]\u{1B}[0m <input>"); + println!(); + println!("\u{1B}[1mOptions\u{1B}[0m:"); + println!(" \u{1B}[1m-f\u{1B}[0m\u{1B}[3m<format>\u{1B}[0m set the target executable format (see below)"); + println!(" \u{1B}[1m-h\u{1B}[0m print help"); + println!(" \u{1B}[1m-m\u{1B}[0m\u{1B}[3m<target>\u{1B}[0m set the target cpu (see below)"); + println!(" \u{1B}[1m-v\u{1B}[0m print version"); + + println!(); + println!("\u{1B}[1mCPUs\u{1B}[0m:"); + for cpu in all::<Cpu>() { println!(" \u{1B}[3m{cpu}\u{1B}[0m") } + + println!(); + println!("\u{1B}[1mFormats\u{1B}[0m:"); + for format in all::<Format>() { println!(" \u{1B}[3m{format}\u{1B}[0m") } + + exit(0x0); + } +} diff --git a/src/app/print_version.rs b/src/app/print_version.rs new file mode 100644 index 0000000..d28e457 --- /dev/null +++ b/src/app/print_version.rs @@ -0,0 +1,35 @@ +/* + Copyright 2023 Gabriel Jensen. + + This file is part of aas. + + aas is free software: you can redistribute it + and/or modify it under the terms of the GNU + General Public License as published by the Free + Software Foundation, either version 3 of the + License, or (at your option) any later version. + + aas is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU + General Public License along with aas. If not, + see <https://www.gnu.org/licenses/>. +*/ + +use crate::VERSION; +use crate::app::App; + +use std::process::exit; + +impl App { + pub fn print_version() -> ! { + println!("\u{1B}[1maas\u{1B}[0m {:X}.{:X}.{:X}", VERSION.0, VERSION.1, VERSION.2); + println!("\u{1B}[3mCopyright \u{A9} 2023 Gabriel Bj\u{F8}rnager Jensen\u{1B}[0m."); + + exit(0x0); + } +} diff --git a/src/app/run.rs b/src/app/run.rs new file mode 100644 index 0000000..88d0983 --- /dev/null +++ b/src/app/run.rs @@ -0,0 +1,56 @@ +/* + Copyright 2023 Gabriel Jensen. + + This file is part of aas. + + aas is free software: you can redistribute it + and/or modify it under the terms of the GNU + General Public License as published by the Free + Software Foundation, either version 3 of the + License, or (at your option) any later version. + + aas is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU + General Public License along with aas. If not, + see <https://www.gnu.org/licenses/>. +*/ + +use crate::app::App; +use crate::token::Token; + +use std::fs::read_to_string; + +impl App { + #[must_use] + pub fn run(self) -> Result<(), String> { + if cfg!(debug_assertions) { + println!("\u{1B}[1mSettings\u{1B}[0m:"); + println!("\u{B7} input \u{1B}[3m\"{}\"\u{1B}[0m", self.input); + println!("\u{B7} output \u{1B}[3m\"{}\"\u{1B}[0m", self.output); + println!(); + println!("\u{B7} cpu \u{1B}[3m{}\u{1B}[0m", self.cpu); + println!("\u{B7} format \u{1B}[3m{}\u{1B}[0m", self.format); + println!(); + } + + let input = match read_to_string(&self.input) { + Ok(content) => content, + + _ => return Err(format!("unable to read file \"{}\"", &self.input)), + }; + + let tokens = Token::tokenise(&input)?; + + eprintln!("\u{1B}[1mTokens\u{1B}[0m:"); + for token in &tokens { + eprintln!("\u{B7} {token:?}"); + } + + return Ok(()); + } +} |