diff --git a/src/sed/command.rs b/src/sed/command.rs index 250bcbc..c483242 100644 --- a/src/sed/command.rs +++ b/src/sed/command.rs @@ -42,6 +42,9 @@ pub struct ProcessingContext { // Other context /// Currently processed input file name (not script) in quoted form pub input_name: String, + /// Currently processed input file name as supplied, for commands that + /// print it directly. + pub raw_input_name: String, /// Current input line number pub line_number: usize, /// True if this is the last address of a range diff --git a/src/sed/compiler.rs b/src/sed/compiler.rs index bcfff31..4c32fcd 100644 --- a/src/sed/compiler.rs +++ b/src/sed/compiler.rs @@ -1327,6 +1327,10 @@ fn get_cmd_spec( n_addr: 2, handler: compile_empty_command, }), + 'F' if !posix => Ok(CommandSpec { + n_addr: 2, + handler: compile_empty_command, + }), 'l' => Ok(CommandSpec { n_addr: 2, handler: compile_number_command, diff --git a/src/sed/mod.rs b/src/sed/mod.rs index 1206140..c1be98c 100644 --- a/src/sed/mod.rs +++ b/src/sed/mod.rs @@ -204,6 +204,7 @@ fn build_context(matches: &ArgMatches) -> ProcessingContext { // Other context input_name: "".to_string(), + raw_input_name: "-".to_string(), line_number: 0, last_address: false, last_line: false, diff --git a/src/sed/processor.rs b/src/sed/processor.rs index 45d6b26..465a8f2 100644 --- a/src/sed/processor.rs +++ b/src/sed/processor.rs @@ -508,6 +508,10 @@ fn process_file( pattern.clear(); break; } + 'F' => { + let separator = if context.null_data { '\0' } else { '\n' }; + output.write_str(format!("{}{}", context.raw_input_name, separator))?; + } 'g' => { // Replace pattern with the contents of the hold space. pattern.set_to_string(context.hold.content.clone(), context.hold.has_newline); @@ -705,6 +709,7 @@ pub fn process_all_files( } context.input_name = path.quote().to_string(); + context.raw_input_name = path.to_string_lossy().to_string(); process_file(commands.clone(), &mut reader, output, context)?; // Handle any N command remains. diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index b31fed7..fb4e268 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -388,6 +388,41 @@ check_output!(pattern_next_output, ["-e", r"4n", LINES1]); check_output!(pattern_next_no_output, ["-n", "-e", r"4n", LINES1]); check_output!(pattern_next_print_output, ["-e", r"4n;p", LINES1]); check_output!(pattern_next_print_no_output, ["-n", "-e", r"4n;p", LINES1]); + +#[test] +fn pattern_print_filename_with_f_command() { + new_ucmd!() + .args(&["-n", "F", LINES1]) + .succeeds() + .stdout_is("input/lines1\n".repeat(14)); +} + +#[test] +fn pattern_print_filename_with_f_command_stdin() { + new_ucmd!() + .args(&["-n", "F"]) + .pipe_in("a\nb\n") + .succeeds() + .stdout_is("-\n-\n"); +} + +#[test] +fn pattern_print_filename_with_f_command_null_data() { + new_ucmd!() + .args(&["-z", "-n", "F"]) + .pipe_in("a\0b\0") + .succeeds() + .stdout_is("-\0"); +} + +#[test] +fn pattern_print_filename_with_f_command_is_non_posix() { + new_ucmd!() + .args(&["--posix", "F"]) + .fails() + .code_is(1) + .stderr_is("sed: