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#define FOR_wc
28#include "toys.h"
29
30GLOBALS(
31 unsigned long totals[4];
32)
33
34static void show_lengths(unsigned long *lengths, char *name)
35{
36 int i, space = 7, first = 1;
37
38 for (i = 0; i<4; i++) if (toys.optflags == (1<<i)) space = 0;
39 for (i = 0; i<4; i++) {
40 if (toys.optflags&(1<<i)) {
41 printf(" %*ld"+first, space, lengths[i]);
42 first = 0;
43 }
44 TT.totals[i] += lengths[i];
45 }
46 if (*toys.optargs) printf(" %s", name);
47 xputc('\n');
48}
49
50static void do_wc(int fd, char *name)
51{
52 int len = 0, clen = 1, space = 0;
53 unsigned long word = 0, lengths[] = {0,0,0,0};
54
55
56 if (toys.optflags == FLAG_c) {
57 struct stat st;
58
59
60 if (!fstat(fd, &st) && S_ISREG(st.st_mode) && st.st_size) {
61 lengths[2] = st.st_size;
62 goto show;
63 }
64 }
65
66 for (;;) {
67 int pos, done = 0, len2 = read(fd, toybuf+len, sizeof(toybuf)-len);
68
69 if (len2<0) perror_msg_raw(name);
70 else len += len2;
71 if (len2<1) done++;
72
73 for (pos = 0; pos<len; pos++) {
74 if (toybuf[pos]=='\n') lengths[0]++;
75 lengths[2]++;
76 if (toys.optflags&FLAG_m) {
77
78 if (--clen<1) {
79 wchar_t wchar;
80
81
82 clen = utf8towc(&wchar, toybuf+pos, len-pos);
83 if (clen == -1) continue;
84 if (clen == -2 && !done) break;
85
86 lengths[3]++;
87 space = iswspace(wchar);
88 }
89 } else space = isspace(toybuf[pos]);
90
91 if (space) word=0;
92 else {
93 if (!word) lengths[1]++;
94 word=1;
95 }
96 }
97 if (done) break;
98 if (pos != len) memmove(toybuf, toybuf+pos, len-pos);
99 len -= pos;
100 }
101
102show:
103 show_lengths(lengths, name);
104}
105
106void wc_main(void)
107{
108 if (!toys.optflags) toys.optflags = FLAG_l|FLAG_w|FLAG_c;
109 loopfiles(toys.optargs, do_wc);
110 if (toys.optc>1) show_lengths(TT.totals, "total");
111}
112