Skip to content

Commit 64d2aa4

Browse files
committed
Adding fix for parsing the baud values
1 parent 86bc17e commit 64d2aa4

File tree

2 files changed

+108
-13
lines changed

2 files changed

+108
-13
lines changed

src/uu/stty/src/stty.rs

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -564,19 +564,58 @@ fn string_to_combo(arg: &str) -> Option<&str> {
564564
}
565565

566566
fn string_to_baud(arg: &str) -> Option<AllFlags<'_>> {
567-
// BSDs use a u32 for the baud rate, so any decimal number applies.
568-
#[cfg(any(
569-
target_os = "freebsd",
570-
target_os = "dragonfly",
571-
target_os = "ios",
572-
target_os = "macos",
573-
target_os = "netbsd",
574-
target_os = "openbsd"
575-
))]
576-
if let Ok(n) = arg.parse::<u32>() {
577-
return Some(AllFlags::Baud(n));
567+
// Normalize the input: trim whitespace and leading '+'
568+
let normalized = arg.trim().trim_start_matches('+');
569+
570+
// Try to parse as a floating point number for rounding
571+
if let Ok(f) = normalized.parse::<f64>() {
572+
let rounded = f.round() as u32;
573+
574+
// BSDs use a u32 for the baud rate, so any decimal number applies.
575+
#[cfg(any(
576+
target_os = "freebsd",
577+
target_os = "dragonfly",
578+
target_os = "ios",
579+
target_os = "macos",
580+
target_os = "netbsd",
581+
target_os = "openbsd"
582+
))]
583+
return Some(AllFlags::Baud(rounded));
584+
585+
// On other platforms, find the closest valid baud rate
586+
#[cfg(not(any(
587+
target_os = "freebsd",
588+
target_os = "dragonfly",
589+
target_os = "ios",
590+
target_os = "macos",
591+
target_os = "netbsd",
592+
target_os = "openbsd"
593+
)))]
594+
{
595+
let rounded_str = rounded.to_string();
596+
// First try exact match
597+
for (text, baud_rate) in BAUD_RATES {
598+
if *text == rounded_str {
599+
return Some(AllFlags::Baud(*baud_rate));
600+
}
601+
}
602+
// If no exact match, find closest baud rate
603+
let mut closest: Option<(u32, nix::sys::termios::BaudRate)> = None;
604+
for (text, baud_rate) in BAUD_RATES {
605+
if let Ok(rate_val) = text.parse::<u32>() {
606+
let diff = rate_val.abs_diff(rounded);
607+
if closest.is_none() || diff < closest.unwrap().0 {
608+
closest = Some((diff, *baud_rate));
609+
}
610+
}
611+
}
612+
if let Some((_, baud_rate)) = closest {
613+
return Some(AllFlags::Baud(baud_rate));
614+
}
615+
}
578616
}
579-
617+
618+
// Fallback: try exact string match for non-numeric baud rate names
580619
#[cfg(not(any(
581620
target_os = "freebsd",
582621
target_os = "dragonfly",
@@ -586,10 +625,11 @@ fn string_to_baud(arg: &str) -> Option<AllFlags<'_>> {
586625
target_os = "openbsd"
587626
)))]
588627
for (text, baud_rate) in BAUD_RATES {
589-
if *text == arg {
628+
if *text == normalized {
590629
return Some(AllFlags::Baud(*baud_rate));
591630
}
592631
}
632+
593633
None
594634
}
595635

tests/by-util/test_stty.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,58 @@ fn non_negatable_combo() {
320320
.fails()
321321
.stderr_contains("invalid argument '-ek'");
322322
}
323+
324+
mod unit {
325+
use uu_stty::string_to_baud;
326+
327+
#[test]
328+
fn string_to_baud_exact_match() {
329+
assert!(string_to_baud("9600").is_some());
330+
assert!(string_to_baud("115200").is_some());
331+
}
332+
333+
#[test]
334+
fn string_to_baud_with_whitespace() {
335+
assert!(string_to_baud(" 9600 ").is_some());
336+
assert!(string_to_baud("\t115200\n").is_some());
337+
}
338+
339+
#[test]
340+
fn string_to_baud_with_plus_sign() {
341+
assert!(string_to_baud("+9600").is_some());
342+
assert!(string_to_baud(" +115200 ").is_some());
343+
}
344+
345+
#[test]
346+
fn string_to_baud_with_decimal() {
347+
assert!(string_to_baud("9600.0").is_some());
348+
assert!(string_to_baud("9600.4").is_some());
349+
}
350+
351+
#[test]
352+
fn string_to_baud_rounding() {
353+
assert!(string_to_baud("9600.5").is_some());
354+
assert!(string_to_baud("9599.6").is_some());
355+
}
356+
357+
#[cfg(not(any(
358+
target_os = "freebsd",
359+
target_os = "dragonfly",
360+
target_os = "ios",
361+
target_os = "macos",
362+
target_os = "netbsd",
363+
target_os = "openbsd"
364+
)))]
365+
#[test]
366+
fn string_to_baud_closest_match() {
367+
assert!(string_to_baud("9601").is_some());
368+
assert!(string_to_baud("115000").is_some());
369+
}
370+
371+
#[test]
372+
fn string_to_baud_invalid() {
373+
assert!(string_to_baud("invalid").is_none());
374+
assert!(string_to_baud("").is_none());
375+
assert!(string_to_baud("abc123").is_none());
376+
}
377+
}

0 commit comments

Comments
 (0)