diff --git a/text/sed.rs b/text/sed.rs index 7c4376c9..0d3feef1 100644 --- a/text/sed.rs +++ b/text/sed.rs @@ -25,6 +25,8 @@ use std::{ path::PathBuf, }; +const DEFAULT_TMP_DIR: &str = "../target/tmp"; + static ERE: Mutex = Mutex::new(false); #[derive(Parser, Debug, Clone)] @@ -1346,7 +1348,7 @@ fn print_multiline_binary(line: &str) { } } } - } else if let Some(line) = line.strip_suffix(&['\n']) { + } else if let Some(line) = line.strip_suffix(['\n']) { println!("{}$", line); } else { print!("{}$", line); @@ -1416,6 +1418,16 @@ fn filter_comments(raw_script: impl AsRef) -> String { raw_script_without_comments } +/// Get path to [`wfile`] in tmp dir +fn get_tmp_path(wfile: PathBuf) -> PathBuf { + let mut tmp_path = + PathBuf::from(std::env::var("CARGO_TARGET_TMPDIR").unwrap_or(DEFAULT_TMP_DIR.to_string())); + + tmp_path.extend(&wfile); + + tmp_path +} + /// Contains [`Command`] sequence of all [`Sed`] session /// that applied all to every line of input files #[derive(Debug)] @@ -1821,6 +1833,15 @@ fn execute_replace( Some(wfile) }) { if replace && wfile.components().next().is_some() { + let mut wfile = wfile.clone(); + if !(wfile.is_absolute() + || wfile.starts_with("./") + || wfile.starts_with("../") + || wfile.exists()) + { + wfile = get_tmp_path(wfile); + } + if let Ok(mut file) = std::fs::OpenOptions::new() .append(true) .create(true) @@ -2213,6 +2234,15 @@ impl Sed { } fn execute_w(&mut self, wfile: PathBuf) -> Result<(), SedError> { + let mut wfile = wfile.clone(); + if !(wfile.is_absolute() + || wfile.starts_with("./") + || wfile.starts_with("../") + || wfile.exists()) + { + wfile = get_tmp_path(wfile); + } + let _ = match std::fs::OpenOptions::new() .append(true) .create(true) diff --git a/text/tests/sed/mod.rs b/text/tests/sed/mod.rs index 8f4048d5..c0aff379 100644 --- a/text/tests/sed/mod.rs +++ b/text/tests/sed/mod.rs @@ -1825,12 +1825,17 @@ mod tests { fn test_w() { let test_data = [ // correct - ("w ./tests/sed/assets/newfile", "abc\ncdf\n", "abc\ncdf\n", ""), ("w atyfv", "abc\ncdf\n", "abc\ncdf\n", ""), ("w./tests/sed/assets/r", "", "", ""), - ("w./tests/sed/assets/newfile", "a\n", "a\n", ""), + ("w newfile", "a\n", "a\n", ""), ("w ; h", "abc\ncdf\n", "abc\ncdf\n", ""), // wrong + ( + "w ./dir/newfile", + "abc\ncdf\n", + "", + "sed: read stdin: can't find './dir/newfile': no such file or directory (os error 2)\n", + ), ( "w./tests/s\x04ed/assets/abc", "a\n",