Skip to content

Commit 3f39d71

Browse files
committed
free: use no empty line as delimiter with --line
1 parent 005c7ea commit 3f39d71

File tree

2 files changed

+65
-43
lines changed

2 files changed

+65
-43
lines changed

src/uu/free/src/free.rs

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -150,55 +150,60 @@ where
150150
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
151151
let matches = uu_app().try_get_matches_from(args)?;
152152

153-
let count_flag = matches.get_one("count");
154-
let mut count: u64 = match count_flag {
155-
Some(0) => {
156-
return Err(USimpleError::new(
157-
1,
158-
"count argument must be greater than 0",
159-
))
160-
}
161-
Some(c) => *c,
162-
None => 1,
163-
};
164-
let seconds_flag = matches.get_one("seconds");
165-
let seconds: f64 = match seconds_flag {
166-
Some(0.0) => {
167-
return Err(USimpleError::new(
168-
1,
169-
"seconds argument must be greater than 0",
170-
))
171-
}
172-
Some(s) => *s,
173-
None => 1.0,
174-
};
153+
let count: Option<u64> = matches.get_one("count").copied();
154+
let seconds: Option<f64> = matches.get_one("seconds").copied();
155+
156+
if count == Some(0) {
157+
return Err(USimpleError::new(
158+
1,
159+
"count argument must be greater than 0",
160+
));
161+
}
175162

176-
let dur = Duration::from_nanos(seconds.mul(1_000_000_000.0).round() as u64);
163+
if seconds == Some(0.0) {
164+
return Err(USimpleError::new(
165+
1,
166+
"seconds argument must be greater than 0",
167+
));
168+
}
177169

178-
let infinite: bool = count_flag.is_none() && seconds_flag.is_some();
170+
let (count, seconds) = match (count, seconds) {
171+
(None, None) => (Some(1), 1.0),
172+
(None, Some(s)) => (None, s),
173+
(Some(c), None) => (Some(c), 1.0),
174+
(Some(c), Some(s)) => (Some(c), s),
175+
};
179176

180-
let construct_str = parse_output_format(matches);
177+
let duration = Duration::from_nanos(seconds.mul(1_000_000_000.0).round() as u64);
178+
let construct_str = parse_output_format(&matches);
181179

182-
while count > 0 || infinite {
183-
// prevent underflow
184-
if !infinite {
185-
count -= 1;
180+
let output_meminfo = || match parse_meminfo() {
181+
Ok(mem_info) => {
182+
print!("{}", construct_str(&mem_info));
186183
}
187-
188-
match parse_meminfo() {
189-
Ok(mem_info) => {
190-
print!("{}", construct_str(&mem_info));
191-
}
192-
Err(e) => {
193-
eprintln!("free: failed to read memory info: {}", e);
194-
process::exit(1);
195-
}
184+
Err(e) => {
185+
eprintln!("free: failed to read memory info: {}", e);
186+
process::exit(1);
196187
}
188+
};
197189

198-
if count > 0 || infinite {
199-
// the original free prints a newline everytime before waiting for the next round
190+
let do_sleep = || {
191+
if !matches.get_flag("line") {
200192
println!();
201-
sleep(dur);
193+
}
194+
sleep(duration);
195+
};
196+
197+
if let Some(c) = count {
198+
for _ in 0..c - 1 {
199+
output_meminfo();
200+
do_sleep();
201+
}
202+
output_meminfo();
203+
} else {
204+
loop {
205+
output_meminfo();
206+
do_sleep();
202207
}
203208
}
204209

@@ -273,7 +278,7 @@ fn parse_meminfo_value(value: &str) -> Result<u64, std::io::Error> {
273278
})
274279
}
275280

276-
fn parse_output_format(matches: ArgMatches) -> impl Fn(&MemInfo) -> String {
281+
fn parse_output_format(matches: &ArgMatches) -> impl Fn(&MemInfo) -> String {
277282
let wide = matches.get_flag("wide");
278283
let human = matches.get_flag("human");
279284
let si = matches.get_flag("si");
@@ -282,7 +287,7 @@ fn parse_output_format(matches: ArgMatches) -> impl Fn(&MemInfo) -> String {
282287
let committed = matches.get_flag("committed");
283288
let one_line = matches.get_flag("line");
284289

285-
let convert = detect_unit(&matches);
290+
let convert = detect_unit(matches);
286291

287292
// function that converts the number to the correct string
288293
let n2s = move |x| {

tests/by-util/test_free.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,23 @@ fn test_count() {
101101
}
102102
}
103103

104+
#[test]
105+
fn test_count_line() {
106+
let re = Regex::new(r"^SwapUse +\d+ CachUse +\d+ {2}MemUse +\d+ MemFree +\d+$").unwrap();
107+
108+
let output = new_ucmd!()
109+
.args(&["--count", "2", "--line", "-s", "0.00001"])
110+
.succeeds()
111+
.stdout_move_str();
112+
113+
let lines: Vec<&str> = output.lines().collect();
114+
115+
assert_eq!(2, lines.len());
116+
117+
assert!(re.is_match(lines[0]));
118+
assert!(re.is_match(lines[1]));
119+
}
120+
104121
#[test]
105122
fn test_count_zero() {
106123
new_ucmd!()

0 commit comments

Comments
 (0)