xref: /inferno-os/appl/cmd/wc.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Wc;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsyth#
4*37da2899SCharles.Forsyth# wc -- count things in utf-encoded text files
5*37da2899SCharles.Forsyth# Bugs:
6*37da2899SCharles.Forsyth#	The only white space characters recognized are ' ', '\t' and '\n', even though
7*37da2899SCharles.Forsyth#	ISO 10646 has many more blanks scattered through it.
8*37da2899SCharles.Forsyth#	Should count characters that cannot occur in any rune (hex f0-ff) separately.
9*37da2899SCharles.Forsyth#	Should count non-canonical runes (e.g. hex c1,80 instead of hex 40).
10*37da2899SCharles.Forsyth#
11*37da2899SCharles.Forsyth
12*37da2899SCharles.Forsythinclude "sys.m";
13*37da2899SCharles.Forsyth	sys: Sys;
14*37da2899SCharles.Forsyth
15*37da2899SCharles.Forsythinclude "draw.m";
16*37da2899SCharles.Forsyth
17*37da2899SCharles.ForsythWc: module
18*37da2899SCharles.Forsyth{
19*37da2899SCharles.Forsyth	init:	fn(ctxt: ref Draw->Context, args: list of string);
20*37da2899SCharles.Forsyth};
21*37da2899SCharles.Forsyth
22*37da2899SCharles.ForsythNBUF:	con 8*1024;
23*37da2899SCharles.Forsyth
24*37da2899SCharles.Forsythstderr:	ref Sys->FD;
25*37da2899SCharles.Forsythnline, tnline, pline: int;
26*37da2899SCharles.Forsythnword, tnword, pword: int;
27*37da2899SCharles.Forsythnchar, tnchar, pchar: int;
28*37da2899SCharles.Forsythnbadr, tnbadr, pbadr: int;
29*37da2899SCharles.Forsythnbyte, tnbyte, pbyte: int;
30*37da2899SCharles.Forsyth
31*37da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
32*37da2899SCharles.Forsyth{
33*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
34*37da2899SCharles.Forsyth	stderr = sys->fildes(2);
35*37da2899SCharles.Forsyth
36*37da2899SCharles.Forsyth	for(argv = tl argv; argv != nil; argv = tl argv){
37*37da2899SCharles.Forsyth		arg := hd argv;
38*37da2899SCharles.Forsyth		if(len arg < 2 || arg[0] != '-' || arg[1] == '-')
39*37da2899SCharles.Forsyth			break;
40*37da2899SCharles.Forsyth		for(i := 1; i < len arg; i++){
41*37da2899SCharles.Forsyth			case arg[i]{
42*37da2899SCharles.Forsyth			'l' => pline++;
43*37da2899SCharles.Forsyth			'w' => pword++;
44*37da2899SCharles.Forsyth			'c' => pchar++;
45*37da2899SCharles.Forsyth			'e' => pbadr++;
46*37da2899SCharles.Forsyth			'b' => pbyte++;
47*37da2899SCharles.Forsyth			* =>
48*37da2899SCharles.Forsyth				sys->fprint(stderr, "usage: wc [-lwcbe] [file ...]\n");
49*37da2899SCharles.Forsyth				raise "fail:usage";
50*37da2899SCharles.Forsyth			}
51*37da2899SCharles.Forsyth		}
52*37da2899SCharles.Forsyth	}
53*37da2899SCharles.Forsyth	if(pline+pword+pchar+pbadr+pbyte == 0)
54*37da2899SCharles.Forsyth		pline = pword = pchar = 1;
55*37da2899SCharles.Forsyth	argc := len argv;
56*37da2899SCharles.Forsyth	if(argc == 0)
57*37da2899SCharles.Forsyth		count(sys->fildes(0), "");
58*37da2899SCharles.Forsyth	else{
59*37da2899SCharles.Forsyth		for(; argv != nil; argv = tl argv){
60*37da2899SCharles.Forsyth			name := hd argv;
61*37da2899SCharles.Forsyth			f := sys->open(name, sys->OREAD);
62*37da2899SCharles.Forsyth			if(f == nil)
63*37da2899SCharles.Forsyth				sys->fprint(stderr, "wc: can't open %s: %r\n", name);
64*37da2899SCharles.Forsyth			else{
65*37da2899SCharles.Forsyth				count(f, name);
66*37da2899SCharles.Forsyth				tnline += nline;
67*37da2899SCharles.Forsyth				tnword += nword;
68*37da2899SCharles.Forsyth				tnchar += nchar;
69*37da2899SCharles.Forsyth				tnbadr += nbadr;
70*37da2899SCharles.Forsyth				tnbyte += nbyte;
71*37da2899SCharles.Forsyth				f = nil;
72*37da2899SCharles.Forsyth			}
73*37da2899SCharles.Forsyth		}
74*37da2899SCharles.Forsyth		if(argc > 1)
75*37da2899SCharles.Forsyth			report(tnline, tnword, tnchar, tnbadr, tnbyte, "total");
76*37da2899SCharles.Forsyth	}
77*37da2899SCharles.Forsyth	exit;
78*37da2899SCharles.Forsyth}
79*37da2899SCharles.Forsythreport(nline, nword, nchar, nbadr, nbyte: int, fname: string)
80*37da2899SCharles.Forsyth{
81*37da2899SCharles.Forsyth	line := "";
82*37da2899SCharles.Forsyth	if(pline)
83*37da2899SCharles.Forsyth		line += sys->sprint(" %7d", nline);
84*37da2899SCharles.Forsyth	if(pword)
85*37da2899SCharles.Forsyth		line += sys->sprint(" %7d", nword);
86*37da2899SCharles.Forsyth	if(pchar)
87*37da2899SCharles.Forsyth		line += sys->sprint(" %7d", nchar);
88*37da2899SCharles.Forsyth	if(pbadr)
89*37da2899SCharles.Forsyth		line += sys->sprint(" %7d", nbadr);
90*37da2899SCharles.Forsyth	if(pbyte)
91*37da2899SCharles.Forsyth		line += sys->sprint(" %7d", nbyte);
92*37da2899SCharles.Forsyth	if(fname != nil)
93*37da2899SCharles.Forsyth		line += sys->sprint(" %s", fname);
94*37da2899SCharles.Forsyth	sys->print("%s\n", line[1:]);
95*37da2899SCharles.Forsyth}
96*37da2899SCharles.Forsyth#
97*37da2899SCharles.Forsyth# How it works.  Start in statesp.  Each time we read a character,
98*37da2899SCharles.Forsyth# increment various counts, and do state transitions according to the
99*37da2899SCharles.Forsyth# following table.  If we're not in statesp or statewd when done, the
100*37da2899SCharles.Forsyth# file ends with a partial rune.
101*37da2899SCharles.Forsyth#        |                character
102*37da2899SCharles.Forsyth#  state |09,20| 0a  |00-7f|80-bf|c0-df|e0-ef|f0-ff
103*37da2899SCharles.Forsyth# -------+-----+-----+-----+-----+-----+-----+-----
104*37da2899SCharles.Forsyth# statesp|ASP  |ASPN |AWDW |AWDWX|AC2W |AC3W |AWDWX
105*37da2899SCharles.Forsyth# statewd|ASP  |ASPN |AWD  |AWDX |AC2  |AC3  |AWDX
106*37da2899SCharles.Forsyth# statec2|ASPX |ASPNX|AWDX |AWDR |AC2X |AC3X |AWDX
107*37da2899SCharles.Forsyth# statec3|ASPX |ASPNX|AWDX |AC2R |AC2X |AC3X |AWDX
108*37da2899SCharles.Forsyth#
109*37da2899SCharles.Forsyth			# actions
110*37da2899SCharles.Forsyth	AC2,		# enter statec2
111*37da2899SCharles.Forsyth	AC2R,		# enter statec2, don't count a rune
112*37da2899SCharles.Forsyth	AC2W,		# enter statec2, count a word
113*37da2899SCharles.Forsyth	AC2X,		# enter statec2, count a bad rune
114*37da2899SCharles.Forsyth	AC3,		# enter statec3
115*37da2899SCharles.Forsyth	AC3W,		# enter statec3, count a word
116*37da2899SCharles.Forsyth	AC3X,		# enter statec3, count a bad rune
117*37da2899SCharles.Forsyth	ASP,		# enter statesp
118*37da2899SCharles.Forsyth	ASPN,		# enter statesp, count a newline
119*37da2899SCharles.Forsyth	ASPNX,		# enter statesp, count a newline, count a bad rune
120*37da2899SCharles.Forsyth	ASPX,		# enter statesp, count a bad rune
121*37da2899SCharles.Forsyth	AWD,		# enter statewd
122*37da2899SCharles.Forsyth	AWDR,		# enter statewd, don't count a rune
123*37da2899SCharles.Forsyth	AWDW,		# enter statewd, count a word
124*37da2899SCharles.Forsyth	AWDWX,		# enter statewd, count a word, count a bad rune
125*37da2899SCharles.Forsyth	AWDX:		# enter statewd, count a bad rune
126*37da2899SCharles.Forsyth		con byte iota;
127*37da2899SCharles.Forsyth
128*37da2899SCharles.Forsythstatesp := array[256] of{	# looking for the start of a word
129*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 00-07
130*37da2899SCharles.ForsythAWDW, ASP,  ASPN, AWDW, AWDW, AWDW, AWDW, AWDW,	# 08-0f
131*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 10-17
132*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 18-1f
133*37da2899SCharles.ForsythASP,  AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 20-27
134*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 28-2f
135*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 30-37
136*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 38-3f
137*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 40-47
138*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 48-4f
139*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 50-57
140*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 58-5f
141*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 60-67
142*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 68-6f
143*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 70-77
144*37da2899SCharles.ForsythAWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW, AWDW,	# 78-7f
145*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# 80-87
146*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# 88-8f
147*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# 90-97
148*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# 98-9f
149*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# a0-a7
150*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# a8-af
151*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# b0-b7
152*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# b8-bf
153*37da2899SCharles.ForsythAC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W,	# c0-c7
154*37da2899SCharles.ForsythAC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W,	# c8-cf
155*37da2899SCharles.ForsythAC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W,	# d0-d7
156*37da2899SCharles.ForsythAC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W, AC2W,	# d8-df
157*37da2899SCharles.ForsythAC3W, AC3W, AC3W, AC3W, AC3W, AC3W, AC3W, AC3W,	# e0-e7
158*37da2899SCharles.ForsythAC3W, AC3W, AC3W, AC3W, AC3W, AC3W, AC3W, AC3W,	# e8-ef
159*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# f0-f7
160*37da2899SCharles.ForsythAWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,AWDWX,# f8-ff
161*37da2899SCharles.Forsyth};
162*37da2899SCharles.Forsythstatewd := array[256] of {	# looking for the next character in a word
163*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 00-07
164*37da2899SCharles.ForsythAWD,  ASP,  ASPN, AWD,  AWD,  AWD,  AWD,  AWD,	# 08-0f
165*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 10-17
166*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 18-1f
167*37da2899SCharles.ForsythASP,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 20-27
168*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 28-2f
169*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 30-37
170*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 38-3f
171*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 40-47
172*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 48-4f
173*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 50-57
174*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 58-5f
175*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 60-67
176*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 68-6f
177*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 70-77
178*37da2899SCharles.ForsythAWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,  AWD,	# 78-7f
179*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 80-87
180*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 88-8f
181*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 90-97
182*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 98-9f
183*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# a0-a7
184*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# a8-af
185*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# b0-b7
186*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# b8-bf
187*37da2899SCharles.ForsythAC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,	# c0-c7
188*37da2899SCharles.ForsythAC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,	# c8-cf
189*37da2899SCharles.ForsythAC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,	# d0-d7
190*37da2899SCharles.ForsythAC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,  AC2,	# d8-df
191*37da2899SCharles.ForsythAC3,  AC3,  AC3,  AC3,  AC3,  AC3,  AC3,  AC3,	# e0-e7
192*37da2899SCharles.ForsythAC3,  AC3,  AC3,  AC3,  AC3,  AC3,  AC3,  AC3,	# e8-ef
193*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f0-f7
194*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f8-ff
195*37da2899SCharles.Forsyth};
196*37da2899SCharles.Forsythstatec2 := array[256] of {	# looking for 10xxxxxx to complete a rune
197*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 00-07
198*37da2899SCharles.ForsythAWDX, ASPX, ASPNX,AWDX, AWDX, AWDX, AWDX, AWDX,	# 08-0f
199*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 10-17
200*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 18-1f
201*37da2899SCharles.ForsythASPX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 20-27
202*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 28-2f
203*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 30-37
204*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 38-3f
205*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 40-47
206*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 48-4f
207*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 50-57
208*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 58-5f
209*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 60-67
210*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 68-6f
211*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 70-77
212*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 78-7f
213*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# 80-87
214*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# 88-8f
215*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# 90-97
216*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# 98-9f
217*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# a0-a7
218*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# a8-af
219*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# b0-b7
220*37da2899SCharles.ForsythAWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR, AWDR,	# b8-bf
221*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# c0-c7
222*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# c8-cf
223*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# d0-d7
224*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# d8-df
225*37da2899SCharles.ForsythAC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X,	# e0-e7
226*37da2899SCharles.ForsythAC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X,	# e8-ef
227*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f0-f7
228*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f8-ff
229*37da2899SCharles.Forsyth};
230*37da2899SCharles.Forsythstatec3 := array[256] of {	# looking for 10xxxxxx,10xxxxxx to complete a rune
231*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 00-07
232*37da2899SCharles.ForsythAWDX, ASPX, ASPNX,AWDX, AWDX, AWDX, AWDX, AWDX,	# 08-0f
233*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 10-17
234*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 18-1f
235*37da2899SCharles.ForsythASPX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 20-27
236*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 28-2f
237*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 30-37
238*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 38-3f
239*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 40-47
240*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 48-4f
241*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 50-57
242*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 58-5f
243*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 60-67
244*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 68-6f
245*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 70-77
246*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# 78-7f
247*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# 80-87
248*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# 88-8f
249*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# 90-97
250*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# 98-9f
251*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# a0-a7
252*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# a8-af
253*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# b0-b7
254*37da2899SCharles.ForsythAC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R, AC2R,	# b8-bf
255*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# c0-c7
256*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# c8-cf
257*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# d0-d7
258*37da2899SCharles.ForsythAC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X, AC2X,	# d8-df
259*37da2899SCharles.ForsythAC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X,	# e0-e7
260*37da2899SCharles.ForsythAC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X, AC3X,	# e8-ef
261*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f0-f7
262*37da2899SCharles.ForsythAWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX, AWDX,	# f8-ff
263*37da2899SCharles.Forsyth};
264*37da2899SCharles.Forsythbuf := array[NBUF] of byte;
265*37da2899SCharles.Forsythcount(f: ref Sys->FD, name: string)
266*37da2899SCharles.Forsyth{
267*37da2899SCharles.Forsyth	state := statesp;
268*37da2899SCharles.Forsyth	nline = nword = nchar = nbadr = nbyte = 0;
269*37da2899SCharles.Forsyth	n := 0;
270*37da2899SCharles.Forsyth	for(;;){
271*37da2899SCharles.Forsyth		n = sys->read(f, buf, NBUF);
272*37da2899SCharles.Forsyth		if(n <= 0)
273*37da2899SCharles.Forsyth			break;
274*37da2899SCharles.Forsyth		nbyte += n;
275*37da2899SCharles.Forsyth		nchar += n;	# might be too large, gets decreased later
276*37da2899SCharles.Forsyth		i := 0;
277*37da2899SCharles.Forsyth		do{
278*37da2899SCharles.Forsyth			case int state[int buf[i++]]{
279*37da2899SCharles.Forsyth			int AC2 =>   state = statec2;
280*37da2899SCharles.Forsyth			int AC2R =>  state = statec2; nchar--;
281*37da2899SCharles.Forsyth			int AC2W =>  state = statec2; nword++;
282*37da2899SCharles.Forsyth			int AC2X =>  state = statec2;          nbadr++;
283*37da2899SCharles.Forsyth			int AC3 =>   state = statec3;
284*37da2899SCharles.Forsyth			int AC3W =>  state = statec3; nword++;
285*37da2899SCharles.Forsyth			int AC3X =>  state = statec3;          nbadr++;
286*37da2899SCharles.Forsyth			int ASP =>   state = statesp;
287*37da2899SCharles.Forsyth			int ASPN =>  state = statesp; nline++;
288*37da2899SCharles.Forsyth			int ASPNX => state = statesp; nline++; nbadr++;
289*37da2899SCharles.Forsyth			int ASPX =>  state = statesp;          nbadr++;
290*37da2899SCharles.Forsyth			int AWD =>   state = statewd;
291*37da2899SCharles.Forsyth			int AWDR =>  state = statewd; nchar--;
292*37da2899SCharles.Forsyth			int AWDW =>  state = statewd; nword++;
293*37da2899SCharles.Forsyth			int AWDWX => state = statewd; nword++; nbadr++;
294*37da2899SCharles.Forsyth			int AWDX =>  state = statewd;          nbadr++;
295*37da2899SCharles.Forsyth			}
296*37da2899SCharles.Forsyth		}while(i < n);
297*37da2899SCharles.Forsyth	}
298*37da2899SCharles.Forsyth	if(state!=statesp && state!=statewd)
299*37da2899SCharles.Forsyth		nbadr++;
300*37da2899SCharles.Forsyth	if(n < 0)
301*37da2899SCharles.Forsyth		sys->fprint(stderr, "wc: error reading %s: %r\n", name);
302*37da2899SCharles.Forsyth	report(nline, nword, nchar, nbadr, nbyte, name);
303*37da2899SCharles.Forsyth}
304