aboutsummaryrefslogtreecommitdiffstats
path: root/c/wc.c
blob: 4fa48ee0347dceffc7d48f6e04f9470ac3f9cd42 (plain) (blame)
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
#include "gbos.h"
/* wc [-l][-w][-c] [file]: count lines/words/chars of a file or stdin. */
void main(void) {
    char *argv[8];
    unsigned char argc = argv_parse(argv, 8);
    unsigned char wl = hasflag(argv, argc, 'l');
    unsigned char ww = hasflag(argv, argc, 'w');
    unsigned char wch = hasflag(argv, argc, 'c');
    unsigned int lines = 0, words = 0, chars = 0;
    unsigned char inword = 0, first = 1, i, fd = NOFD;
    char *fname = 0;
    int ch;
    if (!wl && !ww && !wch) { wl = ww = wch = 1; }
    for (i = 0; i < argc; i++) if (argv[i][0] != '-') { fname = argv[i]; break; }
    if (fname) {
        fd = open(fname, O_READ);
        if (fd > 3) { puts("wc: no such file"); nl(); return; }
    }
    for (;;) {
        if (fd > 3) { char c = readc(); if (c == EOF) break; ch = c; }
        else { ch = fgetc(fd); if (ch < 0) break; }
        chars++;
        if (ch == '\n') lines++;
        if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') inword = 0;
        else if (!inword) { inword = 1; words++; }
    }
    if (fd != NOFD) close(fd);
    if (wl)  { putu(lines); first = 0; }
    if (ww)  { if (!first) putc(' '); putu(words); first = 0; }
    if (wch) { if (!first) putc(' '); putu(chars); }
    nl();
}