mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #1185 from Arcterus/du-cleanup
du: clean up block size parsing code
This commit is contained in:
commit
cc51fdb7a1
1 changed files with 96 additions and 102 deletions
198
src/du/du.rs
198
src/du/du.rs
|
@ -14,6 +14,8 @@ extern crate time;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
// XXX: remove when we no longer support 1.22.0
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -37,7 +39,7 @@ const LONG_HELP: &'static str = "
|
||||||
";
|
";
|
||||||
|
|
||||||
// TODO: Suport Z & Y (currently limited by size of u64)
|
// TODO: Suport Z & Y (currently limited by size of u64)
|
||||||
static UNITS: [(char, u32); 6] = [('E', 6), ('P', 5), ('T', 4), ('G', 3), ('M', 2), ('K', 1)];
|
const UNITS: [(char, u32); 6] = [('K', 1), ('M', 2), ('G', 3), ('T', 4), ('P', 5), ('E', 6)];
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
all: bool,
|
all: bool,
|
||||||
|
@ -76,47 +78,39 @@ impl Stat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unit_string_to_number(s: &str) -> Option<u64> {
|
||||||
|
let mut offset = 0;
|
||||||
|
let mut s_chars = s.chars().rev();
|
||||||
|
|
||||||
|
let (mut ch, multiple) = match s_chars.next() {
|
||||||
|
Some('B') | Some('b') => ('B', 1000u64),
|
||||||
|
Some(ch) => (ch, 1024u64),
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
if ch == 'B' {
|
||||||
|
ch = s_chars.next()?;
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
ch = ch.to_ascii_uppercase();
|
||||||
|
|
||||||
|
let unit = UNITS
|
||||||
|
.iter()
|
||||||
|
.find(|&&(unit_ch, _)| unit_ch == ch)
|
||||||
|
.map(|&(_, val)| {
|
||||||
|
// we found a match, so increment offset
|
||||||
|
offset += 1;
|
||||||
|
val
|
||||||
|
})
|
||||||
|
.or_else(|| if multiple == 1024 { Some(0) } else { None })?;
|
||||||
|
|
||||||
|
let number = s[..s.len() - offset].parse::<u64>().ok()?;
|
||||||
|
|
||||||
|
Some(number * multiple.pow(unit))
|
||||||
|
}
|
||||||
|
|
||||||
fn translate_to_pure_number(s: &Option<String>) -> Option<u64> {
|
fn translate_to_pure_number(s: &Option<String>) -> Option<u64> {
|
||||||
match s {
|
match s {
|
||||||
&Some(ref s) => {
|
&Some(ref s) => unit_string_to_number(s),
|
||||||
let mut found_number = false;
|
|
||||||
let mut found_letter = false;
|
|
||||||
let mut numbers = String::new();
|
|
||||||
let mut letters = String::new();
|
|
||||||
for c in s.trim().chars() {
|
|
||||||
if found_letter && c.is_digit(10) || !found_number && !c.is_digit(10) {
|
|
||||||
return None;
|
|
||||||
} else if c.is_digit(10) {
|
|
||||||
found_number = true;
|
|
||||||
numbers.push(c);
|
|
||||||
} else if c.is_alphabetic() {
|
|
||||||
found_letter = true;
|
|
||||||
letters.push(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let number = numbers.parse::<u64>().unwrap();
|
|
||||||
let multiple = match letters[..].to_uppercase().as_str() {
|
|
||||||
"" => 1,
|
|
||||||
"K" => 1024u64.pow(1),
|
|
||||||
"M" => 1024u64.pow(2),
|
|
||||||
"G" => 1024u64.pow(3),
|
|
||||||
"T" => 1024u64.pow(4),
|
|
||||||
"P" => 1024u64.pow(5),
|
|
||||||
"E" => 1024u64.pow(6),
|
|
||||||
"Z" => 1024u64.pow(7),
|
|
||||||
"Y" => 1024u64.pow(8),
|
|
||||||
"KB" => 1000u64.pow(1),
|
|
||||||
"MB" => 1000u64.pow(2),
|
|
||||||
"GB" => 1000u64.pow(3),
|
|
||||||
"TB" => 1000u64.pow(4),
|
|
||||||
"PB" => 1000u64.pow(5),
|
|
||||||
"EB" => 1000u64.pow(6),
|
|
||||||
"ZB" => 1000u64.pow(7),
|
|
||||||
"YB" => 1000u64.pow(8),
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
Some(number * multiple)
|
|
||||||
}
|
|
||||||
&None => None,
|
&None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,15 +119,13 @@ fn read_block_size(s: Option<String>) -> u64 {
|
||||||
match translate_to_pure_number(&s) {
|
match translate_to_pure_number(&s) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
match s {
|
if let Some(value) = s {
|
||||||
Some(value) => show_error!("invalid --block-size argument '{}'", value),
|
show_error!("invalid --block-size argument '{}'", value);
|
||||||
_ => (),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for env_var in ["DU_BLOCK_SIZE", "BLOCK_SIZE", "BLOCKSIZE"].into_iter() {
|
for env_var in &["DU_BLOCK_SIZE", "BLOCK_SIZE", "BLOCKSIZE"] {
|
||||||
match translate_to_pure_number(&env::var(env_var).ok()) {
|
if let Some(quantity) = translate_to_pure_number(&env::var(env_var).ok()) {
|
||||||
Some(quantity) => return quantity,
|
return quantity;
|
||||||
None => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,46 +166,44 @@ fn du(
|
||||||
|
|
||||||
for f in read.into_iter() {
|
for f in read.into_iter() {
|
||||||
match f {
|
match f {
|
||||||
Ok(entry) => match Stat::new(entry.path()) {
|
Ok(entry) => {
|
||||||
Ok(this_stat) => {
|
match Stat::new(entry.path()) {
|
||||||
if this_stat.is_dir {
|
Ok(this_stat) => {
|
||||||
futures.push(du(this_stat, options, depth + 1, inodes));
|
if this_stat.is_dir {
|
||||||
} else {
|
futures.push(du(this_stat, options, depth + 1, inodes));
|
||||||
if inodes.contains(&this_stat.inode) {
|
} else {
|
||||||
continue;
|
if inodes.contains(&this_stat.inode) {
|
||||||
}
|
continue;
|
||||||
inodes.insert(this_stat.inode);
|
}
|
||||||
my_stat.size += this_stat.size;
|
inodes.insert(this_stat.inode);
|
||||||
my_stat.blocks += this_stat.blocks;
|
my_stat.size += this_stat.size;
|
||||||
if options.all {
|
my_stat.blocks += this_stat.blocks;
|
||||||
stats.push(this_stat);
|
if options.all {
|
||||||
|
stats.push(this_stat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(error) => show_error!("{}", error),
|
||||||
}
|
}
|
||||||
Err(error) => show_error!("{}", error),
|
}
|
||||||
},
|
|
||||||
Err(error) => show_error!("{}", error),
|
Err(error) => show_error!("{}", error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.extend(
|
stats.extend(futures.into_iter().flat_map(|val| val).rev().filter_map(
|
||||||
futures
|
|stat| {
|
||||||
.into_iter()
|
if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path {
|
||||||
.flat_map(|val| val)
|
my_stat.size += stat.size;
|
||||||
.rev()
|
my_stat.blocks += stat.blocks;
|
||||||
.filter_map(|stat| {
|
}
|
||||||
if !options.separate_dirs && stat.path.parent().unwrap() == my_stat.path {
|
if options.max_depth == None || depth < options.max_depth.unwrap() {
|
||||||
my_stat.size += stat.size;
|
Some(stat)
|
||||||
my_stat.blocks += stat.blocks;
|
} else {
|
||||||
}
|
None
|
||||||
if options.max_depth == None || depth < options.max_depth.unwrap() {
|
}
|
||||||
Some(stat)
|
},
|
||||||
} else {
|
));
|
||||||
None
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
stats.push(my_stat);
|
stats.push(my_stat);
|
||||||
Box::new(stats.into_iter())
|
Box::new(stats.into_iter())
|
||||||
}
|
}
|
||||||
|
@ -344,24 +334,26 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
let time_format_str = match matches.opt_str("time-style") {
|
let time_format_str = match matches.opt_str("time-style") {
|
||||||
Some(s) => match &s[..] {
|
Some(s) => {
|
||||||
"full-iso" => "%Y-%m-%d %H:%M:%S.%f %z",
|
match &s[..] {
|
||||||
"long-iso" => "%Y-%m-%d %H:%M",
|
"full-iso" => "%Y-%m-%d %H:%M:%S.%f %z",
|
||||||
"iso" => "%Y-%m-%d",
|
"long-iso" => "%Y-%m-%d %H:%M",
|
||||||
_ => {
|
"iso" => "%Y-%m-%d",
|
||||||
show_error!(
|
_ => {
|
||||||
"invalid argument '{}' for 'time style'
|
show_error!(
|
||||||
|
"invalid argument '{}' for 'time style'
|
||||||
Valid arguments are:
|
Valid arguments are:
|
||||||
- 'full-iso'
|
- 'full-iso'
|
||||||
- 'long-iso'
|
- 'long-iso'
|
||||||
- 'iso'
|
- 'iso'
|
||||||
Try '{} --help' for more information.",
|
Try '{} --help' for more information.",
|
||||||
s,
|
s,
|
||||||
NAME
|
NAME
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => "%Y-%m-%d %H:%M",
|
None => "%Y-%m-%d %H:%M",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -389,21 +381,23 @@ Try '{} --help' for more information.",
|
||||||
let tm = {
|
let tm = {
|
||||||
let (secs, nsecs) = {
|
let (secs, nsecs) = {
|
||||||
let time = match matches.opt_str("time") {
|
let time = match matches.opt_str("time") {
|
||||||
Some(s) => match &s[..] {
|
Some(s) => {
|
||||||
"accessed" => stat.accessed,
|
match &s[..] {
|
||||||
"created" => stat.created,
|
"accessed" => stat.accessed,
|
||||||
"modified" => stat.modified,
|
"created" => stat.created,
|
||||||
_ => {
|
"modified" => stat.modified,
|
||||||
show_error!(
|
_ => {
|
||||||
"invalid argument 'modified' for '--time'
|
show_error!(
|
||||||
|
"invalid argument 'modified' for '--time'
|
||||||
Valid arguments are:
|
Valid arguments are:
|
||||||
- 'accessed', 'created', 'modified'
|
- 'accessed', 'created', 'modified'
|
||||||
Try '{} --help' for more information.",
|
Try '{} --help' for more information.",
|
||||||
NAME
|
NAME
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => stat.modified,
|
None => stat.modified,
|
||||||
};
|
};
|
||||||
((time / 1000) as i64, (time % 1000 * 1000000) as i32)
|
((time / 1000) as i64, (time % 1000 * 1000000) as i32)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue