mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
extract Base enum
This commit is contained in:
parent
1ad10dd371
commit
45487d47b8
2 changed files with 26 additions and 10 deletions
|
@ -21,8 +21,24 @@ mod options {
|
||||||
pub const DISABLE_BACKSLASH_ESCAPE: &str = "disable_backslash_escape";
|
pub const DISABLE_BACKSLASH_ESCAPE: &str = "disable_backslash_escape";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum Base {
|
||||||
|
Oct = 8,
|
||||||
|
Hex = 16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Base {
|
||||||
|
fn max_digits(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
Self::Oct => 3,
|
||||||
|
Self::Hex => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse the numeric part of the `\xHHH` and `\0NNN` escape sequences
|
/// Parse the numeric part of the `\xHHH` and `\0NNN` escape sequences
|
||||||
fn parse_code(input: &mut Peekable<Chars>, base: u8, max_digits: u32) -> Option<char> {
|
fn parse_code(input: &mut Peekable<Chars>, base: Base) -> Option<char> {
|
||||||
// All arithmetic on `ret` needs to be wrapping, because octal input can
|
// All arithmetic on `ret` needs to be wrapping, because octal input can
|
||||||
// take 3 digits, which is 9 bits, and therefore more than what fits in a
|
// take 3 digits, which is 9 bits, and therefore more than what fits in a
|
||||||
// `u8`. GNU just seems to wrap these values.
|
// `u8`. GNU just seems to wrap these values.
|
||||||
|
@ -31,15 +47,15 @@ fn parse_code(input: &mut Peekable<Chars>, base: u8, max_digits: u32) -> Option<
|
||||||
// `u8::MAX` as unicode.
|
// `u8::MAX` as unicode.
|
||||||
let mut ret = input.peek().and_then(|c| c.to_digit(base as u32))? as u8;
|
let mut ret = input.peek().and_then(|c| c.to_digit(base as u32))? as u8;
|
||||||
|
|
||||||
// We can safely ifgnore the None case because we just peeked it.
|
// We can safely ignore the None case because we just peeked it.
|
||||||
let _ = input.next();
|
let _ = input.next();
|
||||||
|
|
||||||
for _ in 1..max_digits {
|
for _ in 1..base.max_digits() {
|
||||||
match input.peek().and_then(|c| c.to_digit(base as u32)) {
|
match input.peek().and_then(|c| c.to_digit(base as u32)) {
|
||||||
Some(n) => ret = ret.wrapping_mul(base).wrapping_add(n as u8),
|
Some(n) => ret = ret.wrapping_mul(base as u8).wrapping_add(n as u8),
|
||||||
None => break,
|
None => break,
|
||||||
}
|
}
|
||||||
// We can safely ifgnore the None case because we just peeked it.
|
// We can safely ignore the None case because we just peeked it.
|
||||||
let _ = input.next();
|
let _ = input.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +74,7 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
|
||||||
// Note that '0' is intentionally omitted because that
|
// Note that '0' is intentionally omitted because that
|
||||||
// would be the \0NNN syntax.
|
// would be the \0NNN syntax.
|
||||||
if let Some('1'..='8') = iter.peek() {
|
if let Some('1'..='8') = iter.peek() {
|
||||||
if let Some(parsed) = parse_code(&mut iter, 8, 3) {
|
if let Some(parsed) = parse_code(&mut iter, Base::Oct) {
|
||||||
write!(output, "{parsed}")?;
|
write!(output, "{parsed}")?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -77,14 +93,14 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
|
||||||
't' => '\t',
|
't' => '\t',
|
||||||
'v' => '\x0b',
|
'v' => '\x0b',
|
||||||
'x' => {
|
'x' => {
|
||||||
if let Some(c) = parse_code(&mut iter, 16, 2) {
|
if let Some(c) = parse_code(&mut iter, Base::Hex) {
|
||||||
c
|
c
|
||||||
} else {
|
} else {
|
||||||
write!(output, "\\")?;
|
write!(output, "\\")?;
|
||||||
'x'
|
'x'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'0' => parse_code(&mut iter, 8, 3).unwrap_or('\0'),
|
'0' => parse_code(&mut iter, Base::Oct).unwrap_or('\0'),
|
||||||
c => {
|
c => {
|
||||||
write!(output, "\\")?;
|
write!(output, "\\")?;
|
||||||
c
|
c
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue