diff --git a/src/args.rs b/src/args.rs index 12d797e..c23346e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -57,6 +57,10 @@ pub struct ArgWrite { #[argp(description = "Path to the source Intel HEX file.")] pub path: OsString, + #[argp(option)] + #[argp(description = "Where to run the command. Will be created if it doesn't exist.")] + pub cmd_path: Option, + #[argp(option)] #[argp(description = "Command to run before writing the file. Handy for compiling the program and running it at the same time.")] pub cmd: Option, @@ -102,7 +106,7 @@ pub struct ArgMonitor {} pub struct ArgRun { #[argp(positional)] #[argp(description = "Path to the source C file.")] - pub path: OsString + pub path: std::path::PathBuf } #[derive(FromArgs)] diff --git a/src/main.rs b/src/main.rs index 5a01d89..48feeb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -204,16 +204,23 @@ fn write_chip_data(args: &ArgWrite, target: &mut PhysicalTarget) -> Result<(), E fn write_chip(args: ArgWrite, target: &mut PhysicalTarget) -> Result<(), Error> { loop { if let Some(cmd) = args.cmd.as_ref() { + let cmd_path = &args.cmd_path; let mut args = shlex::bytes::split(cmd.as_encoded_bytes()) .ok_or(Error::other("Error parsing commandline arguments"))? .into_iter() .map(|x| unsafe { OsString::from_encoded_bytes_unchecked(x) }); + if let Some(cmd_path) = cmd_path { + if !cmd_path.is_dir() { + Err(Error::other("invalid cmd path (not a dir)"))? + } + } let Some(name) = args.next() else { Err(Error::other("No command provided"))? }; let out = std::process::Command::new(name) + .current_dir(cmd_path.as_ref().map(|p| p.as_path()).unwrap_or(&std::path::Path::new("."))) .args(args) .output()?; @@ -257,11 +264,21 @@ fn monitor_chip(_args: ArgMonitor, target: &mut PhysicalTarget) -> Result<(), Er } fn run_chip(args: ArgRun, target: &mut PhysicalTarget) -> Result<(), Error> { - let path = PathBuf::from(&args.path).with_extension("ihx").into_os_string(); - let cmd = Some(OsString::from(format!("sdcc \"{}\"", unsafe { String::from_utf8_unchecked(args.path.into_encoded_bytes()) }))); + let build_dir = args.path.parent().unwrap().join("tulflash"); + + let source_file_name = args.path.file_name().ok_or(Error::other("invalid path to compilation source"))?; + let source_file = build_dir.join(&source_file_name); + let output_file = source_file.with_extension("ihx"); + + let cmd = Some(OsString::from(format!("sdcc \"{}\"", source_file_name.to_string_lossy()))); + let cmd_path = Some(build_dir.clone()); + + std::fs::create_dir_all(build_dir)?; + std::fs::copy(args.path, &source_file)?; write_chip(ArgWrite { - path, + path: output_file.into_os_string(), + cmd_path, cmd, start: 0, end: 65535,