1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

stat: use Flags struct instead of u8 bit manipulation

This commit is contained in:
Terts Diepraam 2022-11-16 21:12:40 +01:00
parent ad713fd1d9
commit 7e5b6400e3
2 changed files with 51 additions and 33 deletions

View file

@ -39,12 +39,15 @@ pub mod options {
static ARG_FILES: &str = "files"; static ARG_FILES: &str = "files";
pub const F_ALTER: u8 = 1; #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
pub const F_ZERO: u8 = 1 << 1; pub struct Flags {
pub const F_LEFT: u8 = 1 << 2; pub alter: bool,
pub const F_SPACE: u8 = 1 << 3; pub zero: bool,
pub const F_SIGN: u8 = 1 << 4; pub left: bool,
pub const F_GROUP: u8 = 1 << 5; pub space: bool,
pub sign: bool,
pub group: bool,
}
/// checks if the string is within the specified bound, /// checks if the string is within the specified bound,
/// if it gets out of bound, error out by printing sub-string from index `beg` to`end`, /// if it gets out of bound, error out by printing sub-string from index `beg` to`end`,
@ -138,7 +141,7 @@ pub enum OutputType {
pub enum Token { pub enum Token {
Char(char), Char(char),
Directive { Directive {
flag: u8, flag: Flags,
width: usize, width: usize,
precision: i32, precision: i32,
format: char, format: char,
@ -245,7 +248,7 @@ pub struct Stater {
} }
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precision: i32) { fn print_it(arg: &str, output_type: &OutputType, flags: Flags, width: usize, precision: i32) {
// If the precision is given as just '.', the precision is taken to be zero. // If the precision is given as just '.', the precision is taken to be zero.
// A negative precision is taken as if the precision were omitted. // A negative precision is taken as if the precision were omitted.
// This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions, // This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions,
@ -280,21 +283,19 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
return print!("?"); return print!("?");
} }
let left_align = has!(flag, F_LEFT); let padding_char: Padding = if flags.zero && !flags.left && precision == -1 {
let padding_char: Padding = if has!(flag, F_ZERO) && !left_align && precision == -1 {
Padding::Zero Padding::Zero
} else { } else {
Padding::Space Padding::Space
}; };
let has_sign = has!(flag, F_SIGN) || has!(flag, F_SPACE); let has_sign = flags.sign || flags.space;
let should_alter = has!(flag, F_ALTER);
let prefix = match output_type { let prefix = match output_type {
OutputType::UnsignedOct => "0", OutputType::UnsignedOct => "0",
OutputType::UnsignedHex => "0x", OutputType::UnsignedHex => "0x",
OutputType::Integer => { OutputType::Integer => {
if has!(flag, F_SIGN) { if flags.sign {
"+" "+"
} else { } else {
" " " "
@ -311,10 +312,10 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
} else { } else {
arg arg
}; };
print_adjusted(s, left_align, None, None, width, Padding::Space); print_adjusted(s, flags.left, None, None, width, Padding::Space);
} }
OutputType::Integer => { OutputType::Integer => {
let arg = if has!(flag, F_GROUP) { let arg = if flags.group {
group_num(arg) group_num(arg)
} else { } else {
Cow::Borrowed(arg) Cow::Borrowed(arg)
@ -323,7 +324,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits); let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits);
print_adjusted( print_adjusted(
extended.as_ref(), extended.as_ref(),
left_align, flags.left,
Some(has_sign), Some(has_sign),
Some(prefix), Some(prefix),
width, width,
@ -331,7 +332,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
); );
} }
OutputType::Unsigned => { OutputType::Unsigned => {
let arg = if has!(flag, F_GROUP) { let arg = if flags.group {
group_num(arg) group_num(arg)
} else { } else {
Cow::Borrowed(arg) Cow::Borrowed(arg)
@ -340,7 +341,7 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits); let extended: Cow<str> = extend_digits(arg.as_ref(), min_digits);
print_adjusted( print_adjusted(
extended.as_ref(), extended.as_ref(),
left_align, flags.left,
None, None,
None, None,
width, width,
@ -352,8 +353,8 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
let extended: Cow<str> = extend_digits(arg, min_digits); let extended: Cow<str> = extend_digits(arg, min_digits);
print_adjusted( print_adjusted(
extended.as_ref(), extended.as_ref(),
left_align, flags.left,
Some(should_alter), Some(flags.alter),
Some(prefix), Some(prefix),
width, width,
padding_char, padding_char,
@ -364,8 +365,8 @@ fn print_it(arg: &str, output_type: &OutputType, flag: u8, width: usize, precisi
let extended: Cow<str> = extend_digits(arg, min_digits); let extended: Cow<str> = extend_digits(arg, min_digits);
print_adjusted( print_adjusted(
extended.as_ref(), extended.as_ref(),
left_align, flags.left,
Some(should_alter), Some(flags.alter),
Some(prefix), Some(prefix),
width, width,
padding_char, padding_char,
@ -397,16 +398,16 @@ impl Stater {
continue; continue;
} }
let mut flag: u8 = 0; let mut flag = Flags::default();
while i < bound { while i < bound {
match chars[i] { match chars[i] {
'#' => flag |= F_ALTER, '#' => flag.alter = true,
'0' => flag |= F_ZERO, '0' => flag.zero = true,
'-' => flag |= F_LEFT, '-' => flag.left = true,
' ' => flag |= F_SPACE, ' ' => flag.space = true,
'+' => flag |= F_SIGN, '+' => flag.sign = true,
'\'' => flag |= F_GROUP, '\'' => flag.group = true,
'I' => unimplemented!(), 'I' => unimplemented!(),
_ => break, _ => break,
} }

View file

@ -58,14 +58,22 @@ mod test_generate_tokens {
let s = "%'010.2ac%-#5.w\n"; let s = "%'010.2ac%-#5.w\n";
let expected = vec![ let expected = vec![
Token::Directive { Token::Directive {
flag: F_GROUP | F_ZERO, flag: Flags {
group: true,
zero: true,
..Default::default()
},
width: 10, width: 10,
precision: 2, precision: 2,
format: 'a', format: 'a',
}, },
Token::Char('c'), Token::Char('c'),
Token::Directive { Token::Directive {
flag: F_LEFT | F_ALTER, flag: Flags {
left: true,
alter: true,
..Default::default()
},
width: 5, width: 5,
precision: 0, precision: 0,
format: 'w', format: 'w',
@ -80,7 +88,12 @@ mod test_generate_tokens {
let s = "%-# 15a\\t\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n"; let s = "%-# 15a\\t\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n";
let expected = vec![ let expected = vec![
Token::Directive { Token::Directive {
flag: F_LEFT | F_ALTER | F_SPACE, flag: Flags {
left: true,
alter: true,
space: true,
..Default::default()
},
width: 15, width: 15,
precision: -1, precision: -1,
format: 'a', format: 'a',
@ -95,7 +108,11 @@ mod test_generate_tokens {
Token::Char('\x0C'), Token::Char('\x0C'),
Token::Char('\x0B'), Token::Char('\x0B'),
Token::Directive { Token::Directive {
flag: F_SIGN | F_ZERO, flag: Flags {
sign: true,
zero: true,
..Default::default()
},
width: 20, width: 20,
precision: -1, precision: -1,
format: 'w', format: 'w',