From f32918791325eb88cd7376bd836130f7ddd287cf Mon Sep 17 00:00:00 2001 From: Devel08 Date: Sat, 9 May 2026 14:01:15 +0300 Subject: [PATCH 1/3] implement version command --- src/sed/compiler.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/sed/compiler.rs b/src/sed/compiler.rs index bcfff31..6827834 100644 --- a/src/sed/compiler.rs +++ b/src/sed/compiler.rs @@ -1254,6 +1254,63 @@ fn compile_text_command_posix( Ok(CommandHandling::Continue) } +// Handle v +fn compile_version_command( + lines: &mut ScriptLineProvider, + line: &mut ScriptCharProvider, + _cmd: &mut Command, + _context: &mut ProcessingContext, +) -> UResult { + // GNU sed 4.9 + const GNU_MAJOR: u8 = 4; + const GNU_MINOR: u8 = 9; + const GNU_PATCH: u8 = 0; + + line.advance(); + line.eat_spaces(); // Skip any leading whitespace. + + let mut major = String::new(); + let mut minor = String::new(); + let mut patch = String::new(); + + let mut ver_semantic = 0; + + while !line.eol() { + if line.current() == '.' { + ver_semantic += 1; + line.advance(); + } else { + match ver_semantic { + 0 => major.push(line.current()), + 1 => minor.push(line.current()), + 2 => patch.push(line.current()), + _ => return compilation_error(lines, line, "invalid version of sed"), + } + line.advance(); + } + } + + if patch.is_empty() { + patch = "0".to_string(); + } + + match major.parse::() { + Ok(major_int) => match minor.parse::() { + Ok(minor_int) => match patch.parse::() { + Ok(patch_int) => { + if minor_int <= GNU_MINOR && major_int <= GNU_MAJOR && patch_int == GNU_PATCH { + return Ok(CommandHandling::Continue); + } + compilation_error(lines, line, "expected newer version of sed") + } + Err(_) => compilation_error(lines, line, "invalid version of sed"), + }, + Err(_) => compilation_error(lines, line, "invalid version of sed"), + }, + Err(_) => compilation_error(lines, line, "invalid version of sed"), + } +} + // Return the specification for the command letter at the current line position // checking for diverse errors. fn get_verified_cmd_spec( @@ -1356,6 +1413,10 @@ fn get_cmd_spec( n_addr: 2, handler: compile_trans_command, }), + 'v' => Ok(CommandSpec { + n_addr: 0, + handler: compile_version_command, + }), _ => compilation_error(lines, line, format!("invalid command code `{cmd_code}'")), } } From 10d7c3b422a42b686870da0d2b9c72203b680cd6 Mon Sep 17 00:00:00 2001 From: Devel08 Date: Sat, 9 May 2026 14:02:47 +0300 Subject: [PATCH 2/3] add tests for version option --- tests/by-util/test_sed.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index b31fed7..9fd589d 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -1303,3 +1303,19 @@ fn test_print_first_line_no_newline() { .succeeds() .stdout_is("foo"); } + +#[test] +fn test_expected_newer_version() { + new_ucmd!() + .args(&["v4.10"]) + .fails() + .stderr_is("sed: