mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
stat: use Flags struct instead of u8 bit manipulation
This commit is contained in:
parent
ad713fd1d9
commit
7e5b6400e3
2 changed files with 51 additions and 33 deletions
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue