Skip to content

Commit 9661331

Browse files
committed
Add wc command
1 parent e754a5a commit 9661331

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

docs/wc.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Usage: wc [OPTION]... [FILE]...
2+
Print newline, word, and byte counts for each FILE, and a total line if
3+
more than one FILE is specified. A word is a nonempty sequence of non white
4+
space delimited by white space characters or by start or end of input.

src/bin/wc.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::{
2+
fs::File,
3+
io::{BufRead, BufReader, Write, stdout},
4+
};
5+
6+
use puppyutils::{Result, cli};
7+
8+
bitflags::bitflags! {
9+
struct Flags: u8 {
10+
const LINES = 1 << 0;
11+
const WORDS = 1 << 1;
12+
const CHARS = 1 << 2;
13+
const BYTES = 1 << 3;
14+
}
15+
}
16+
17+
pub fn main() -> Result {
18+
let mut stdout = stdout();
19+
let mut files = Vec::new();
20+
21+
let mut flags = Flags::empty();
22+
23+
cli! {
24+
"wc", stdout, #error
25+
Short('l') | Long("lines") => flags |= Flags::LINES
26+
Short('w') | Long("words") => flags |= Flags::WORDS
27+
Short('m') | Long("chars") => flags |= Flags::CHARS
28+
Short('c') | Long("bytes") => flags |= Flags::BYTES
29+
Value(value) => {
30+
files.push(value.to_owned());
31+
}
32+
};
33+
34+
#[allow(unused)]
35+
if flags.is_empty() {
36+
flags = Flags::LINES | Flags::WORDS | Flags::BYTES;
37+
}
38+
39+
for path in files {
40+
let file = File::open(&path)?;
41+
42+
let mut bytes = file.metadata().map(|m| m.len()).unwrap_or(0) as usize;
43+
44+
let mut lines = 0usize;
45+
let mut words = 0usize;
46+
let mut chars = 0usize;
47+
48+
let mut reader = BufReader::new(file);
49+
50+
let mut line = String::new();
51+
loop {
52+
let read_bytes = reader.read_line(&mut line)?;
53+
54+
if read_bytes == 0 {
55+
break;
56+
}
57+
58+
if bytes == 0 {
59+
bytes += read_bytes;
60+
}
61+
62+
lines += 1;
63+
words += line.split_whitespace().count();
64+
chars += line.chars().count();
65+
66+
line.clear();
67+
}
68+
69+
let out = format!(" {lines} {words} {chars} {bytes} {path}\n"); // FIXME: obv we dont wanna format but also this is temporary since we are ignoring the flags
70+
stdout.write_all(out.as_bytes())?;
71+
}
72+
73+
Ok(())
74+
}

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub mod bin {
1111
pub mod pwd;
1212
pub mod r#true;
1313
pub mod uname;
14+
pub mod wc;
1415
pub mod whoami;
1516
pub mod yes;
1617
}
@@ -33,6 +34,7 @@ fn main() -> Result {
3334
b"pwd" => bin::pwd::main(),
3435
b"true" => bin::r#true::main(),
3536
b"uname" => bin::uname::main(),
37+
b"wc" => bin::wc::main(),
3638
b"whoami" => bin::whoami::main(),
3739
b"yes" => bin::yes::main(),
3840
_ => Err(Exit::Custom(Cow::Owned(format!(

0 commit comments

Comments
 (0)