From 4a7e8db884fdaa80f6a026ec4c0c8409ea975d81 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Wed, 22 Jan 2025 21:46:03 +0100 Subject: nasm: Implement the -D flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows users to define variables directly from the command line, which is useful for testing purposes. Signed-off-by: Miquel Sabaté Solà --- crates/nasm/src/main.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'crates') diff --git a/crates/nasm/src/main.rs b/crates/nasm/src/main.rs index ef7c7d4..5179397 100644 --- a/crates/nasm/src/main.rs +++ b/crates/nasm/src/main.rs @@ -14,6 +14,7 @@ struct Args { out: Option, werror: bool, stdout: bool, + defines: Vec<(String, u8)>, } // Print the help message and quit. @@ -22,12 +23,46 @@ fn print_help() { println!("usage: nasm [OPTIONS] \n"); println!("Options:"); println!(" -c, --config \tLinker configuration to be used, whether an identifier or a file path."); + println!(" -D (=VALUE)\tDefine an 8-bit variable on the global scope (default: 1)"); println!(" -o, --out \tFile path where the output should be located after execution."); println!(" --stdout\t\tPrint the output binary to the standard output."); println!(" -Werror\t\tWarnings should be treated as errors."); std::process::exit(0); } +// Parse a value from the '-D' flag which is expected to be 'NAME(=VALUE)'. +fn parse_define(arg: &str) -> (String, u8) { + let mut key_value = arg.split('='); + + let Some(name) = key_value.next() else { + die(format!("bad format for define '{}'", arg)); + return (String::default(), 0); + }; + + if name + .chars() + .any(|c| !c.is_ascii_alphanumeric() && c != '_' && c != '@' && c != '.') + { + die(format!( + "trying to define '{}' which has invalid characters", + arg + )); + } + + let value = match key_value.next().unwrap_or("1").parse::() { + Ok(integer) => integer, + Err(_) => { + die(format!( + "value for define '{}' must be a valid 8-bit integer", + arg + )); + return (String::default(), 0); + } + }; + + (name.to_string(), value) +} + // Parse the arguments given to the program and returns an Args object with the // given information. fn parse_arguments() -> Args { @@ -48,6 +83,10 @@ fn parse_arguments() -> Args { } }, }, + "-D" => match args.next() { + Some(a) => res.defines.push(parse_define(&a)), + None => die("you need to provide a value for the '-D' flag".to_string()), + }, "-h" | "--help" => print_help(), "-o" | "--out" => match res.out { Some(_) => die("only specify the '-o/--out' flag once".to_string()), @@ -146,6 +185,7 @@ fn main() { let res = assemble( input, args.config.unwrap_or("nrom".to_string()).as_str(), + &args.defines, source, ); -- cgit v1.2.3