Skip to content

Commit 6ca4b80

Browse files
committed
Add stdin support to wc
1 parent 02cc8dd commit 6ca4b80

File tree

2 files changed

+42
-43
lines changed

2 files changed

+42
-43
lines changed

docs/wc.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ or end of input.
99
-w, --words print the word counts
1010
--help display this help and exit
1111
--version output version information and exit
12+
13+
With no FILE, or when FILE is -, read standard input.

src/bin/wc.rs

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
22
fs::File,
3-
io::{BufRead, BufReader, BufWriter, Write, stdout},
3+
io::{BufRead, BufReader, BufWriter, Write, stdin, stdout},
44
};
55

66
use puppyutils::{Result, cli};
@@ -14,6 +14,30 @@ bitflags::bitflags! {
1414
}
1515
}
1616

17+
fn count_lines<R: BufRead>(mut reader: R) -> Result<(usize, usize, usize, usize)> {
18+
let mut lines = 0usize;
19+
let mut words = 0usize;
20+
let mut chars = 0usize;
21+
let mut bytes = 0usize;
22+
let mut line = String::new();
23+
24+
loop {
25+
let read_bytes = reader.read_line(&mut line)?;
26+
27+
if read_bytes == 0 {
28+
break;
29+
}
30+
31+
bytes += read_bytes;
32+
lines += 1;
33+
words += line.split_whitespace().count();
34+
chars += line.chars().count();
35+
line.clear();
36+
}
37+
38+
Ok((lines, words, chars, bytes))
39+
}
40+
1741
pub fn main() -> Result {
1842
let mut stdout = stdout();
1943
let mut files = Vec::new();
@@ -31,46 +55,25 @@ pub fn main() -> Result {
3155
}
3256
};
3357

34-
#[allow(unused)]
3558
if flags.is_empty() {
3659
flags = Flags::LINES | Flags::WORDS | Flags::BYTES;
3760
}
3861

3962
let mut stdout = BufWriter::new(stdout);
4063

41-
for path in files {
42-
let file = File::open(&path)?;
43-
44-
let mut bytes = file.metadata().map(|m| m.len()).unwrap_or(0) as usize;
45-
46-
let mut lines = 0usize;
47-
let mut words = 0usize;
48-
let mut chars = 0usize;
49-
50-
let mut reader = BufReader::new(file);
51-
52-
let mut line = String::new();
53-
54-
loop {
55-
let read_bytes = reader.read_line(&mut line)?;
56-
57-
if read_bytes == 0 {
58-
break;
59-
}
60-
61-
if bytes == 0 {
62-
bytes += read_bytes;
63-
}
64-
65-
lines += 1;
66-
words += line.split_whitespace().count();
67-
chars += line.chars().count();
64+
// If no files, read from stdin
65+
if files.is_empty() {
66+
files.push("-".to_string());
67+
}
6868

69-
line.clear();
70-
}
69+
for path in files {
70+
let (lines, words, chars, bytes) = if path == "-" {
71+
count_lines(BufReader::new(stdin()))?
72+
} else {
73+
count_lines(BufReader::new(File::open(&path)?))?
74+
};
7175

7276
let mut first = true;
73-
7477
let mut write_num = |num: usize| -> Result<()> {
7578
if !first {
7679
stdout.write_all(b" ")?;
@@ -96,19 +99,13 @@ pub fn main() -> Result {
9699
write_num(bytes)?;
97100
}
98101

99-
stdout.write_all(b" ")?;
100-
stdout.write_all(path.as_bytes())?;
102+
if path != "-" {
103+
stdout.write_all(b" ")?;
104+
stdout.write_all(path.as_bytes())?;
105+
}
106+
101107
stdout.write_all(b"\n")?;
102108
}
103109

104110
Ok(())
105111
}
106-
107-
fn _count_padding(mut n: usize) -> usize {
108-
let mut count = 0;
109-
while n % 10 == 0 {
110-
n /= 10;
111-
count += 1;
112-
}
113-
count
114-
}

0 commit comments

Comments
 (0)