Skip to content

Commit ddd9c88

Browse files
committed
fix a bug with the deletion pattern
1 parent 5d452d4 commit ddd9c88

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

src/sed/command.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ pub struct ProcessingContext {
6868
pub substitution_made: bool,
6969
/// Elements to append at the end of each command processing cycle
7070
pub append_elements: Vec<AppendElement>,
71+
/// True if a delete command was executed (prevents automatic printing)
72+
pub pattern_deleted: bool,
7173
}
7274

7375
#[derive(Clone, Debug)]

src/sed/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ fn build_context(matches: &ArgMatches) -> ProcessingContext {
218218
label_to_command_map: HashMap::new(),
219219
substitution_made: false,
220220
append_elements: Vec::new(),
221+
pattern_deleted: false,
221222
}
222223
}
223224

src/sed/processor.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ fn process_file(
435435
context.last_line = last_line;
436436
context.line_number += 1;
437437
context.substitution_made = false;
438+
context.pattern_deleted = false;
438439
// Set the script command from which to start.
439440
let mut current: Option<Rc<RefCell<Command>>> =
440441
if let Some(action) = context.input_action.take() {
@@ -494,6 +495,7 @@ fn process_file(
494495
// At range end replace pattern space with text and
495496
// start the next cycle.
496497
pattern.clear();
498+
context.pattern_deleted = true;
497499
if command.addr2.is_none() || context.last_address || context.last_line {
498500
let text = extract_variant!(command, Text);
499501
output.write_str(text.as_ref())?;
@@ -503,6 +505,7 @@ fn process_file(
503505
'd' => {
504506
// Delete the pattern space and start the next cycle.
505507
pattern.clear();
508+
context.pattern_deleted = true;
506509
break;
507510
}
508511
'D' => {
@@ -515,6 +518,7 @@ fn process_file(
515518
} else {
516519
// Same as d
517520
pattern.clear();
521+
context.pattern_deleted = true;
518522
break;
519523
}
520524
}
@@ -652,7 +656,7 @@ fn process_file(
652656
current = command.next.clone();
653657
}
654658

655-
if !context.quiet {
659+
if !context.quiet && !context.pattern_deleted {
656660
write_chunk(output, context, &pattern)?;
657661
}
658662

tests/by-util/test_sed.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,3 +1128,45 @@ fn test_print_command_adds_newline() {
11281128
.succeeds()
11291129
.stdout_is("foo\nfoo");
11301130
}
1131+
1132+
////////////////////////////////////////////////////////////
1133+
// Test for delete command preventing automatic pattern printing
1134+
#[test]
1135+
fn test_delete_command_prevents_automatic_printing() {
1136+
// Test 'd' command - delete line 2
1137+
new_ucmd!()
1138+
.args(&["2d"])
1139+
.pipe_in("line1\nline2\nline3")
1140+
.succeeds()
1141+
.stdout_is("line1\nline3");
1142+
}
1143+
1144+
#[test]
1145+
fn test_delete_range_prevents_automatic_printing() {
1146+
// Test 'd' command on range - delete lines 2-3
1147+
new_ucmd!()
1148+
.args(&["2,3d"])
1149+
.pipe_in("line1\nline2\nline3\nline4")
1150+
.succeeds()
1151+
.stdout_is("line1\nline4");
1152+
}
1153+
1154+
#[test]
1155+
fn test_change_command_prevents_automatic_printing() {
1156+
// Test 'c' command - change line 2
1157+
new_ucmd!()
1158+
.args(&["2c\\replaced"])
1159+
.pipe_in("line1\nline2\nline3")
1160+
.succeeds()
1161+
.stdout_is("line1\nreplaced\nline3");
1162+
}
1163+
1164+
#[test]
1165+
fn test_uppercase_delete_prevents_automatic_printing() {
1166+
// Test 'D' command - delete up to newline and restart
1167+
new_ucmd!()
1168+
.args(&["-e", "N", "-e", "D"])
1169+
.pipe_in("line1\nline2\nline3")
1170+
.succeeds()
1171+
.stdout_is("line3\n");
1172+
}

0 commit comments

Comments
 (0)