aboutsummaryrefslogtreecommitdiff
path: root/crates/nasm/src
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-10 21:00:22 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-10 21:05:06 +0100
commitc20c991dded87e22f6cb657cc52a0a80ea23f902 (patch)
tree59107c79488ee2d42dae2aeed233c0a791a4ceb5 /crates/nasm/src
parent7c09adae9e2710aefccd25b2920ca684c714ef49 (diff)
downloadtools.nes-c20c991dded87e22f6cb657cc52a0a80ea23f902.tar.gz
tools.nes-c20c991dded87e22f6cb657cc52a0a80ea23f902.zip
Make errors from nasm itself more cohesive
The errors reported from the library had a slightly different format than those that happened in the main file for nasm. This is because in these cases we were just returning an Err type and Rust handles that through a special impl. Instead of going the route of type masturbation, let's go the C route and have a 'die' function that simply prints the message and calls exit(1), Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'crates/nasm/src')
-rw-r--r--crates/nasm/src/main.rs84
1 files changed, 44 insertions, 40 deletions
diff --git a/crates/nasm/src/main.rs b/crates/nasm/src/main.rs
index 0f65fbf..e757207 100644
--- a/crates/nasm/src/main.rs
+++ b/crates/nasm/src/main.rs
@@ -1,7 +1,6 @@
-use anyhow::{bail, Context, Result};
use clap::Parser as ClapParser;
use std::fs::File;
-use std::io::{self, Read, Write};
+use std::io::{self, Write};
use std::path::Path;
use xixanta::assembler::assemble;
use xixanta::SourceInfo;
@@ -10,9 +9,8 @@ use xixanta::SourceInfo;
#[derive(ClapParser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
- /// Assemble the instructions given on this file. The standard input is used
- /// when this argument is not given.
- file: Option<String>,
+ /// Assemble the instructions given on this file.
+ file: String,
/// Linker configuration to be used. This configuration can be an identifier
/// for the configurations already baked in into this application, or it can
@@ -36,50 +34,52 @@ struct Args {
stdout: bool,
}
-fn main() -> Result<()> {
- let args = Args::parse();
+// Print the given `message` and exit(1).
+fn die(message: String) {
+ eprintln!("error: {}", message);
+ std::process::exit(1);
+}
- // Select the input stream and the current working directory.
- let input: Box<dyn Read>;
- let source_info = match &args.file {
- Some(file) => {
- let path = Path::new(file);
- if !path.is_file() {
- bail!("Input file must be a valid file");
- }
- input = Box::new(File::open(file)?);
+fn main() {
+ let args = Args::parse();
- SourceInfo {
- directory: path
- .parent()
- .with_context(|| String::from("Failed to find directory for given file"))?
- .to_path_buf(),
- name: path.file_name().unwrap().to_str().unwrap().to_string(),
- }
- }
+ // Select the input stream and build the source object.
+ let path = Path::new(&args.file);
+ let Ok(input) = File::open(path) else {
+ die(format!("failed to open the given file '{}'", &args.file));
+ return;
+ };
+ let source = match path.parent() {
+ Some(parent) => SourceInfo {
+ directory: parent.to_path_buf(),
+ name: path.file_name().unwrap().to_str().unwrap().to_string(),
+ },
None => {
- input = Box::new(std::io::stdin());
- SourceInfo {
- directory: std::env::current_dir()
- .with_context(|| String::from("Could not fetch current directory"))?
- .to_path_buf(),
- name: "<stdin>".to_string(),
- }
+ die("failed to find directory for the given file".to_string());
+ return;
}
};
// Select the output stream.
- let mut output: Box<dyn Write> = if args.stdout {
- Box::new(io::stdout())
+ let (mut output, output_name): (Box<dyn Write>, &str) = if args.stdout {
+ (Box::new(io::stdout()), "<stdout>")
} else {
- Box::new(File::create(args.out.unwrap_or(String::from("out.nes")))?)
+ let name = args.out.unwrap_or(String::from("out.nes"));
+ match File::create(&name) {
+ Ok(f) => (Box::new(f), args.file.as_str()),
+ Err(_) => {
+ die(format!("could not create file '{}'", name));
+ return;
+ }
+ }
};
// Check if warnings have to be treated as errors.
let warn_as_errors = match args.w {
Some(value) => {
if value.to_lowercase() != "error" {
- bail!("The '-W' flag can only be used as '-Werror'");
+ die("the '-W' flag can only be used as '-Werror'".to_string());
+ return;
} else {
true
}
@@ -87,12 +87,13 @@ fn main() -> Result<()> {
None => false,
};
- // Select the linker configuration.
- let config = args.config.unwrap_or("nrom".to_string());
-
// And assemble.
let mut error_count = 0;
- let res = assemble(input, config.as_str(), source_info);
+ let res = assemble(
+ input,
+ args.config.unwrap_or("nrom".to_string()).as_str(),
+ source,
+ );
// Print warnings and errors first, while also computing the amount of them
// that exists.
@@ -113,7 +114,10 @@ fn main() -> Result<()> {
if error_count == 0 {
for b in res.bundles {
for i in 0..b.size {
- output.write_all(&[b.bytes[i as usize]])?;
+ if let Err(e) = output.write_all(&[b.bytes[i as usize]]) {
+ eprintln!("error: could not write result in '{}': {}", output_name, e);
+ std::process::exit(1);
+ }
}
}
}