Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * Count bytes within runes, if it fits in a uvlong, and other things.
3
 */
4
#include <u.h>
5
#include <libc.h>
6
#include <bio.h>
7
 
8
/* flags, per-file counts, and total counts */
9
static int pline, pword, prune, pbadr, pchar;
10
static uvlong nline, nword, nrune, nbadr, nchar;
11
static uvlong tnline, tnword, tnrune, tnbadr, tnchar;
12
 
13
enum{Space, Word};
14
 
15
static void
16
wc(Biobuf *bin)
17
{
18
	int where;
19
	long r;
20
 
21
	nline = 0;
22
	nword = 0;
23
	nrune = 0;
24
	nbadr = 0;
25
	where = Space;
26
	while ((long)(r = Bgetrune(bin)) >= 0) {
27
		nrune++;
28
		if(r == Runeerror) {
29
			nbadr++;
30
			continue;
31
		}
32
		if(r == '\n')
33
			nline++;
34
		if(where == Word){
35
			if(isspacerune(r))
36
				where = Space;
37
		}else
38
			if(isspacerune(r) == 0){
39
				where = Word;
40
				nword++;
41
			}
42
	}
43
	nchar = Boffset(bin);
44
	tnline += nline;
45
	tnword += nword;
46
	tnrune += nrune;
47
	tnbadr += nbadr;
48
	tnchar += nchar;
49
}
50
 
51
static void
52
report(uvlong nline, uvlong nword, uvlong nrune, uvlong nbadr, uvlong nchar, char *fname)
53
{
54
	char line[1024], *s, *e;
55
 
56
	s = line;
57
	e = line + sizeof line;
58
	line[0] = 0;
59
	if(pline)
60
		s = seprint(s, e, " %7llud", nline);
61
	if(pword)
62
		s = seprint(s, e, " %7llud", nword);
63
	if(prune)
64
		s = seprint(s, e, " %7llud", nrune);
65
	if(pbadr)
66
		s = seprint(s, e, " %7llud", nbadr);
67
	if(pchar)
68
		s = seprint(s, e, " %7llud", nchar);
69
	if(fname != nil)
70
		seprint(s, e, " %s",   fname);
71
	print("%s\n", line+1);
72
}
73
 
74
void
75
main(int argc, char *argv[])
76
{
77
	char *sts;
78
	Biobuf sin, *bin;
79
	int i;
80
 
81
	sts = nil;
82
	ARGBEGIN {
83
	case 'l': pline++; break;
84
	case 'w': pword++; break;
85
	case 'r': prune++; break;
86
	case 'b': pbadr++; break;
87
	case 'c': pchar++; break;
88
	default:
89
		fprint(2, "Usage: %s [-lwrbc] [file ...]\n", argv0);
90
		exits("usage");
91
	} ARGEND
92
	if(pline+pword+prune+pbadr+pchar == 0){
93
		pline = 1;
94
		pword = 1;
95
		pchar = 1;
96
	}
97
	if(argc == 0){
98
		Binit(&sin, 0, OREAD);
99
		wc(&sin);
100
		report(nline, nword, nrune, nbadr, nchar, nil);
101
		Bterm(&sin);
102
	}else{
103
		for(i = 0; i < argc; i++){
104
			bin = Bopen(argv[i], OREAD);
105
			if(bin == nil){
106
				perror(argv[i]);
107
				sts = "can't open";
108
				continue;
109
			}
110
			wc(bin);
111
			report(nline, nword, nrune, nbadr, nchar, argv[i]);
112
			Bterm(bin);
113
		}
114
		if(argc>1)
115
			report(tnline, tnword, tnrune, tnbadr, tnchar, "total");
116
	}
117
	exits(sts);
118
}