-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
stty: set control characters #7931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
stty: set control characters #7931
Conversation
GNU testsuite comparison:
|
src/uu/stty/src/stty.rs
Outdated
match apply_char_mapping(&mut termios, char_index, new_cc) { | ||
Ok(_) => {} | ||
Err(e) => match e { | ||
ControlCharMappingError::IntOutOfRange => { | ||
return Err(USimpleError::new( | ||
1, | ||
format!( | ||
"invalid integer argument: '{new_cc}': Numerical result out of range" | ||
), | ||
)); | ||
} | ||
ControlCharMappingError::MultipleChars => { | ||
return Err(USimpleError::new( | ||
1, | ||
format!("invalid integer argument: '{new_cc}'"), | ||
)); | ||
} | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you only handle the error case, you can simplify it with map_err
:
match apply_char_mapping(&mut termios, char_index, new_cc) { | |
Ok(_) => {} | |
Err(e) => match e { | |
ControlCharMappingError::IntOutOfRange => { | |
return Err(USimpleError::new( | |
1, | |
format!( | |
"invalid integer argument: '{new_cc}': Numerical result out of range" | |
), | |
)); | |
} | |
ControlCharMappingError::MultipleChars => { | |
return Err(USimpleError::new( | |
1, | |
format!("invalid integer argument: '{new_cc}'"), | |
)); | |
} | |
}, | |
} | |
apply_char_mapping(&mut termios, char_index, new_cc).map_err(|e| { | |
let message = match e { | |
ControlCharMappingError::IntOutOfRange => format!( | |
"invalid integer argument: '{new_cc}': Numerical result out of range" | |
), | |
ControlCharMappingError::MultipleChars => { | |
format!("invalid integer argument: '{new_cc}'") | |
} | |
}; | |
USimpleError::new(1, message) | |
})?; |
src/uu/stty/src/stty.rs
Outdated
@@ -274,6 +307,15 @@ fn print_terminal_size(termios: &Termios, opts: &Options) -> nix::Result<()> { | |||
Ok(()) | |||
} | |||
|
|||
fn is_control_char(option: &str) -> Option<SpecialCharacterIndices> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function name is a bit misleading: functions starting with is_
usually return a bool
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initially i was returning a bool but then changed it to an option, good catch
9d0ca57
to
8a6e390
Compare
src/uu/stty/src/stty.rs
Outdated
match string_to_control_char(new_val) { | ||
Ok(val) => { | ||
termios.control_chars[control_char_index as usize] = val; | ||
Ok(()) | ||
} | ||
Err(e) => Err(e), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can simplify it to something like:
match string_to_control_char(new_val) { | |
Ok(val) => { | |
termios.control_chars[control_char_index as usize] = val; | |
Ok(()) | |
} | |
Err(e) => Err(e), | |
} | |
string_to_control_char(new_val).and_then(|val| { | |
termios.control_chars[control_char_index as usize] = val; | |
Ok(()) | |
}) |
src/uu/stty/src/stty.rs
Outdated
// c. decimal, no prefix | ||
// 3. Disabling the control character: '^-' or 'undef' | ||
// | ||
// This function returns the ascii value of valid control chars, or None if the input is invalid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function returns a ControlCharMappingError
in the error case, not None
.
src/uu/stty/src/stty.rs
Outdated
let mut ascii_num: Option<u32> = None; | ||
if let Some(hex) = s.strip_prefix("0x") { | ||
ascii_num = u32::from_str_radix(hex, 16).ok(); | ||
} else if let Some(octal) = s.strip_prefix("0") { | ||
ascii_num = u32::from_str_radix(octal, 8).ok(); | ||
} else if let Ok(decimal) = s.parse::<u32>() { | ||
ascii_num = Some(decimal); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ascii_num
doesn't have to be mutable. And you can get rid of the last if let
:
let mut ascii_num: Option<u32> = None; | |
if let Some(hex) = s.strip_prefix("0x") { | |
ascii_num = u32::from_str_radix(hex, 16).ok(); | |
} else if let Some(octal) = s.strip_prefix("0") { | |
ascii_num = u32::from_str_radix(octal, 8).ok(); | |
} else if let Ok(decimal) = s.parse::<u32>() { | |
ascii_num = Some(decimal); | |
} | |
let ascii_num = if let Some(hex) = s.strip_prefix("0x") { | |
u32::from_str_radix(hex, 16).ok() | |
} else if let Some(octal) = s.strip_prefix("0") { | |
u32::from_str_radix(octal, 8).ok() | |
} else { | |
s.parse::<u32>().ok() | |
}; |
GNU testsuite comparison:
|
anything else you'd like me to fix? i can push the final review commit now if we're all good |
@willshuttleworth from my side it looks good, maybe @tertsdiepraam has something to add as he wrote most of the current implementation. |
@cakebaker i have committed the final code review related changes |
GNU testsuite comparison:
|
b65870b
to
23f7c1b
Compare
…uped now, ie 'stty erase ^H'
23f7c1b
to
fdbd248
Compare
it would be nice to have tests |
the one issue with testing is that |
that would be ideal |
Added functionality to set mappings between control characters (erase, intr, kill, etc.) and specific characters given by the user (^C, for example).
I had to rework the argument processing as it was previously processing one flag at a time, but this feature requires processing of consecutive args (ie
stty erase ^C
). Addedstring_to_control_char()
to convert strings like "^C", "X", "0x7F" to their ASCII value if they are valid control char mappings. Also addedapply_char_mapping()
to set new control char mappings using termios.I'm a relatively new Rust programmer, so I'd love feedback on things that could be written more idiomatically or concisely. This PR is related to issue #7357.