diff --git a/src/main.rs b/src/main.rs index 1643de2..6d57d2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -107,7 +107,14 @@ fn uu_main() -> Result<(), Box> { writeln!(out, "{table}")?; } - let intrp = Interpreter::new(ExecMode::Uu, cg, metadata); + // `--posix` / `--traditional` select ExecMode::Posix (RS first-char-only, + // FS="" whole-record field, stricter regex). Keep this mapping out of RS-only PRs. + let mode = if args.posix || args.traditional { + ExecMode::Posix + } else { + ExecMode::Uu + }; + let intrp = Interpreter::new(mode, cg, metadata); AwkRt::new(intrp, bc, &args.read_queue, diagnostics).main_event_loop()?; Ok(()) diff --git a/tests/by-util/test_awk.rs b/tests/by-util/test_awk.rs index 481b35c..f4a8b1f 100644 --- a/tests/by-util/test_awk.rs +++ b/tests/by-util/test_awk.rs @@ -602,6 +602,35 @@ fn ascii_char_fs_field_split() { .stdout_is("foo bar baz\n"); } +/// gawk `rscompat`: under `--traditional`, multi-character `RS` uses only the +/// first character (not a regexp). Requires `ExecMode::Posix` from `-c`. +#[test] +fn traditional_rs_uses_first_character_only() { + ucmd() + .args(&["-c", r#"BEGIN { RS = "bar" } { print $1, $2 }"#]) + .pipe_in("0foobar0faz\n1foobar1faz") + .succeeds() + .stdout_is("0foo \nar0faz 1foo\nar1faz \n"); +} + +#[test] +fn posix_rs_uses_first_character_only() { + ucmd() + .args(&["-P", r#"BEGIN { RS = "bar" } { print $1, $2 }"#]) + .pipe_in("0foobar0faz\n1foobar1faz") + .succeeds() + .stdout_is("0foo \nar0faz 1foo\nar1faz \n"); +} + +/// POSIX `FS = ""`: the whole record is `$1` (not per-character fields). +#[test] +fn posix_empty_fs_is_whole_record_field() { + ucmd() + .args(&["-P", r#"BEGIN { FS = ""; $0 = "abc"; print NF, $1 }"#]) + .succeeds() + .stdout_is("1 abc\n"); +} + #[test] fn return_stmnt_sets_typedness_eagerly() { ucmd()