forked from CS161/chickadee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp-wc.cc
92 lines (82 loc) · 2.62 KB
/
p-wc.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "p-lib.hh"
static int unparse_counts(char* buff, size_t buffsz, int mode,
const size_t* counts, const char* fname) {
const char* sep = strlen(fname) ? " " : "";
if (mode < 0) {
return snprintf(buff, buffsz, "%8zu %7zu %7zu%s%s\n",
counts[0], counts[1], counts[2], sep, fname);
} else if (*sep) {
return snprintf(buff, buffsz, "%8zu%s%s\n",
counts[mode], sep, fname);
} else {
return snprintf(buff, buffsz, "%zu\n", counts[mode]);
}
}
void process_main(int argc, char** argv) {
sys_kdisplay(KDISPLAY_NONE);
static char buff[4096];
int mode = -1;
int argno = 1;
if (argno < argc) {
if (strcmp(argv[argno], "-c") == 0) {
mode = 0;
++argno;
} else if (strcmp(argv[argno], "-w") == 0) {
mode = 1;
++argno;
} else if (strcmp(argv[argno], "-l") == 0) {
mode = 2;
++argno;
} else if (argv[argno][0] == '-' && argv[argno][1]) {
sys_write(2, "wc: bad argument\n", 17);
sys_exit(1);
}
}
size_t totals[3] = {0, 0, 0};
unsigned nfiles = 0;
while (argno < argc || nfiles == 0) {
int fd = 0;
bool newfd = false;
if (argno < argc && strcmp(argv[argno], "-") != 0) {
fd = sys_open(argv[argno], OF_READ);
if (fd < 0) {
dprintf(2, "%s: error %d\n", argv[argno], fd);
sys_exit(1);
}
newfd = true;
}
size_t counts[3] = {0, 0, 0};
bool inword = false;
while (1) {
ssize_t n = sys_read(fd, buff, sizeof(buff));
if (n == 0 || (n < 0 && n != E_AGAIN)) {
break;
}
for (ssize_t i = 0; i < n; ++i) {
++counts[0];
if (!inword && !isspace(buff[i])) {
++counts[1];
}
inword = !isspace(buff[i]);
if (buff[i] == '\n') {
++counts[2];
}
}
}
int n = unparse_counts(buff, sizeof(buff), mode, counts,
argno < argc ? argv[argno] : "");
ssize_t w = sys_write(1, buff, n);
assert(w == n);
for (int i = 0; i < 3; ++i) {
totals[i] += counts[i];
}
++nfiles;
++argno;
}
if (nfiles > 1) {
int n = unparse_counts(buff, sizeof(buff), mode, totals, "total");
ssize_t w = sys_write(1, buff, n);
assert(w == n);
}
sys_exit(0);
}