xref: /inferno-os/appl/cmd/dd.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement dd;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth	sys: Sys;
5*37da2899SCharles.Forsyth	stderr: ref Sys->FD;
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsythinclude "draw.m";
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythdd: module
10*37da2899SCharles.Forsyth{
11*37da2899SCharles.Forsyth	init: fn(nil: ref Draw->Context, argv: list of string);
12*37da2899SCharles.Forsyth};
13*37da2899SCharles.Forsyth
14*37da2899SCharles.ForsythBIG:	con 2147483647;
15*37da2899SCharles.ForsythLCASE,
16*37da2899SCharles.ForsythUCASE,
17*37da2899SCharles.ForsythSWAB,
18*37da2899SCharles.ForsythNERR	,
19*37da2899SCharles.ForsythSYNC	:	con (1<<iota);
20*37da2899SCharles.Forsyth
21*37da2899SCharles.ForsythNULL,
22*37da2899SCharles.ForsythCNULL,
23*37da2899SCharles.ForsythEBCDIC,
24*37da2899SCharles.ForsythIBM,
25*37da2899SCharles.ForsythASCII,
26*37da2899SCharles.ForsythBLOCK,
27*37da2899SCharles.ForsythUNBLOCK:	con iota;
28*37da2899SCharles.Forsyth
29*37da2899SCharles.Forsythcflag:		int;
30*37da2899SCharles.Forsythctype:	int;
31*37da2899SCharles.Forsyth
32*37da2899SCharles.Forsythfflag:		int;
33*37da2899SCharles.Forsytharg:		string;
34*37da2899SCharles.Forsythifile:		string;
35*37da2899SCharles.Forsythofile:		string;
36*37da2899SCharles.Forsythibuf:		array of byte;
37*37da2899SCharles.Forsythobuf:		array of byte;
38*37da2899SCharles.Forsythop:		int;
39*37da2899SCharles.Forsythskip:		int;
40*37da2899SCharles.Forsythoseekn:	int;
41*37da2899SCharles.Forsythiseekn:	int;
42*37da2899SCharles.Forsythcount:	int;
43*37da2899SCharles.Forsythfiles:=	1;
44*37da2899SCharles.Forsythibs:=		512;
45*37da2899SCharles.Forsythobs:=		512;
46*37da2899SCharles.Forsythbs:		int;
47*37da2899SCharles.Forsythcbs:		int;
48*37da2899SCharles.Forsythibc:		int;
49*37da2899SCharles.Forsythobc:		int;
50*37da2899SCharles.Forsythcbc:		int;
51*37da2899SCharles.Forsythnifr:		int;
52*37da2899SCharles.Forsythnipr:		int;
53*37da2899SCharles.Forsythnofr:		int;
54*37da2899SCharles.Forsythnopr:		int;
55*37da2899SCharles.Forsythntrunc:	int;
56*37da2899SCharles.Forsythibf:		ref Sys->FD;
57*37da2899SCharles.Forsythobf:		ref Sys->FD;
58*37da2899SCharles.Forsythnspace:	int;
59*37da2899SCharles.Forsyth
60*37da2899SCharles.Forsythiskey(key:string, s: string): int
61*37da2899SCharles.Forsyth{
62*37da2899SCharles.Forsyth	return key[0] == '-' && key[1:] ==  s;
63*37da2899SCharles.Forsyth}
64*37da2899SCharles.Forsyth
65*37da2899SCharles.Forsythexits(msg: string)
66*37da2899SCharles.Forsyth{
67*37da2899SCharles.Forsyth	if(msg == nil)
68*37da2899SCharles.Forsyth		exit;
69*37da2899SCharles.Forsyth
70*37da2899SCharles.Forsyth	raise "fail:"+msg;
71*37da2899SCharles.Forsyth}
72*37da2899SCharles.Forsyth
73*37da2899SCharles.Forsythperror(msg: string)
74*37da2899SCharles.Forsyth{
75*37da2899SCharles.Forsyth	sys->fprint(stderr, "%s: %r\n", msg);
76*37da2899SCharles.Forsyth}
77*37da2899SCharles.Forsyth
78*37da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
79*37da2899SCharles.Forsyth{
80*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
81*37da2899SCharles.Forsyth	if(sys == nil)
82*37da2899SCharles.Forsyth		return;
83*37da2899SCharles.Forsyth	stderr = sys->fildes(2);
84*37da2899SCharles.Forsyth
85*37da2899SCharles.Forsyth	ctype = NULL;
86*37da2899SCharles.Forsyth	argv = tl argv;
87*37da2899SCharles.Forsyth	while(argv != nil) {
88*37da2899SCharles.Forsyth		key := hd argv;
89*37da2899SCharles.Forsyth		argv = tl argv;
90*37da2899SCharles.Forsyth		if(argv == nil){
91*37da2899SCharles.Forsyth			sys->fprint(stderr, "dd: arg %s needs a value\n", key);
92*37da2899SCharles.Forsyth			exits("arg");
93*37da2899SCharles.Forsyth		}
94*37da2899SCharles.Forsyth		arg = hd argv;
95*37da2899SCharles.Forsyth		argv = tl argv;
96*37da2899SCharles.Forsyth		if(iskey(key, "ibs")) {
97*37da2899SCharles.Forsyth			ibs = number(BIG);
98*37da2899SCharles.Forsyth			continue;
99*37da2899SCharles.Forsyth		}
100*37da2899SCharles.Forsyth		if(iskey(key, "obs")) {
101*37da2899SCharles.Forsyth			obs = number(BIG);
102*37da2899SCharles.Forsyth			continue;
103*37da2899SCharles.Forsyth		}
104*37da2899SCharles.Forsyth		if(iskey(key, "cbs")) {
105*37da2899SCharles.Forsyth			cbs = number(BIG);
106*37da2899SCharles.Forsyth			continue;
107*37da2899SCharles.Forsyth		}
108*37da2899SCharles.Forsyth		if(iskey(key, "bs")) {
109*37da2899SCharles.Forsyth			bs = number(BIG);
110*37da2899SCharles.Forsyth			continue;
111*37da2899SCharles.Forsyth		}
112*37da2899SCharles.Forsyth		if(iskey(key, "if")) {
113*37da2899SCharles.Forsyth			ifile = arg[0:];
114*37da2899SCharles.Forsyth			continue;
115*37da2899SCharles.Forsyth		}
116*37da2899SCharles.Forsyth		if(iskey(key, "of")) {
117*37da2899SCharles.Forsyth			ofile = arg[0:];
118*37da2899SCharles.Forsyth			continue;
119*37da2899SCharles.Forsyth		}
120*37da2899SCharles.Forsyth		if(iskey(key, "skip")) {
121*37da2899SCharles.Forsyth			skip = number(BIG);
122*37da2899SCharles.Forsyth			continue;
123*37da2899SCharles.Forsyth		}
124*37da2899SCharles.Forsyth		if(iskey(key, "seek") || iskey(key, "oseek")) {
125*37da2899SCharles.Forsyth			oseekn = number(BIG);
126*37da2899SCharles.Forsyth			continue;
127*37da2899SCharles.Forsyth		}
128*37da2899SCharles.Forsyth		if(iskey(key, "iseek")) {
129*37da2899SCharles.Forsyth			iseekn = number(BIG);
130*37da2899SCharles.Forsyth			continue;
131*37da2899SCharles.Forsyth		}
132*37da2899SCharles.Forsyth		if(iskey(key, "count")) {
133*37da2899SCharles.Forsyth			count = number(BIG);
134*37da2899SCharles.Forsyth			continue;
135*37da2899SCharles.Forsyth		}
136*37da2899SCharles.Forsyth		if(iskey(key, "files")) {
137*37da2899SCharles.Forsyth			files = number(BIG);
138*37da2899SCharles.Forsyth			continue;
139*37da2899SCharles.Forsyth		}
140*37da2899SCharles.Forsyth		if(iskey(key, "conv")) {
141*37da2899SCharles.Forsyth			do {
142*37da2899SCharles.Forsyth				if(arg == nil)
143*37da2899SCharles.Forsyth					break;
144*37da2899SCharles.Forsyth				if(match(","))
145*37da2899SCharles.Forsyth					continue;
146*37da2899SCharles.Forsyth				if(match("ebcdic")) {
147*37da2899SCharles.Forsyth					ctype = EBCDIC;
148*37da2899SCharles.Forsyth					continue;
149*37da2899SCharles.Forsyth				}
150*37da2899SCharles.Forsyth				if(match("ibm")) {
151*37da2899SCharles.Forsyth					ctype = IBM;
152*37da2899SCharles.Forsyth					continue;
153*37da2899SCharles.Forsyth				}
154*37da2899SCharles.Forsyth				if(match("ascii")) {
155*37da2899SCharles.Forsyth					ctype = ASCII;
156*37da2899SCharles.Forsyth					continue;
157*37da2899SCharles.Forsyth				}
158*37da2899SCharles.Forsyth				if(match("block")) {
159*37da2899SCharles.Forsyth					ctype = BLOCK;
160*37da2899SCharles.Forsyth					continue;
161*37da2899SCharles.Forsyth				}
162*37da2899SCharles.Forsyth				if(match("unblock")) {
163*37da2899SCharles.Forsyth					ctype = UNBLOCK;
164*37da2899SCharles.Forsyth					continue;
165*37da2899SCharles.Forsyth				}
166*37da2899SCharles.Forsyth				if(match("lcase")) {
167*37da2899SCharles.Forsyth					cflag |= LCASE;
168*37da2899SCharles.Forsyth					continue;
169*37da2899SCharles.Forsyth				}
170*37da2899SCharles.Forsyth				if(match("ucase")) {
171*37da2899SCharles.Forsyth					cflag |= UCASE;
172*37da2899SCharles.Forsyth					continue;
173*37da2899SCharles.Forsyth				}
174*37da2899SCharles.Forsyth				if(match("swab")) {
175*37da2899SCharles.Forsyth					cflag |= SWAB;
176*37da2899SCharles.Forsyth					continue;
177*37da2899SCharles.Forsyth				}
178*37da2899SCharles.Forsyth				if(match("noerror")) {
179*37da2899SCharles.Forsyth					cflag |= NERR;
180*37da2899SCharles.Forsyth					continue;
181*37da2899SCharles.Forsyth				}
182*37da2899SCharles.Forsyth				if(match("sync")) {
183*37da2899SCharles.Forsyth					cflag |= SYNC;
184*37da2899SCharles.Forsyth					continue;
185*37da2899SCharles.Forsyth				}
186*37da2899SCharles.Forsyth			} while(1);
187*37da2899SCharles.Forsyth			continue;
188*37da2899SCharles.Forsyth		}
189*37da2899SCharles.Forsyth		sys->fprint(stderr, "dd: bad arg: %s\n", key);
190*37da2899SCharles.Forsyth		exits("arg");
191*37da2899SCharles.Forsyth	}
192*37da2899SCharles.Forsyth	if(ctype == NULL && cflag&(LCASE|UCASE))
193*37da2899SCharles.Forsyth		ctype = CNULL;
194*37da2899SCharles.Forsyth	if(ifile != nil)
195*37da2899SCharles.Forsyth		ibf = sys->open(ifile, Sys->OREAD);
196*37da2899SCharles.Forsyth	else
197*37da2899SCharles.Forsyth		ibf = sys->fildes(sys->dup(0, -1));
198*37da2899SCharles.Forsyth
199*37da2899SCharles.Forsyth	if(ibf == nil) {
200*37da2899SCharles.Forsyth		sys->fprint(stderr, "dd: open %s: %r\n", ifile);
201*37da2899SCharles.Forsyth		exits("open");
202*37da2899SCharles.Forsyth	}
203*37da2899SCharles.Forsyth
204*37da2899SCharles.Forsyth	if(ofile != nil){
205*37da2899SCharles.Forsyth		obf = sys->create(ofile, Sys->OWRITE, 8r664);
206*37da2899SCharles.Forsyth		if(obf == nil) {
207*37da2899SCharles.Forsyth			sys->fprint(stderr, "dd: create %s: %r\n", ofile);
208*37da2899SCharles.Forsyth			exits("create");
209*37da2899SCharles.Forsyth		}
210*37da2899SCharles.Forsyth	}else{
211*37da2899SCharles.Forsyth		obf = sys->fildes(sys->dup(1, -1));
212*37da2899SCharles.Forsyth		if(obf == nil) {
213*37da2899SCharles.Forsyth			sys->fprint(stderr, "dd: can't dup file descriptor: %r\n");
214*37da2899SCharles.Forsyth			exits("dup");
215*37da2899SCharles.Forsyth		}
216*37da2899SCharles.Forsyth	}
217*37da2899SCharles.Forsyth	if(bs)
218*37da2899SCharles.Forsyth		ibs = obs = bs;
219*37da2899SCharles.Forsyth	if(ibs == obs && ctype == NULL)
220*37da2899SCharles.Forsyth		fflag++;
221*37da2899SCharles.Forsyth	if(ibs == 0 || obs == 0) {
222*37da2899SCharles.Forsyth		sys->fprint(stderr, "dd: counts: cannot be zero\n");
223*37da2899SCharles.Forsyth		exits("counts");
224*37da2899SCharles.Forsyth	}
225*37da2899SCharles.Forsyth	ibuf = array[ibs] of byte;
226*37da2899SCharles.Forsyth	obuf = array[obs] of byte;
227*37da2899SCharles.Forsyth
228*37da2899SCharles.Forsyth	if(fflag)
229*37da2899SCharles.Forsyth		obuf = ibuf;
230*37da2899SCharles.Forsyth
231*37da2899SCharles.Forsyth	sys->seek(obf, big obs*big oseekn, Sys->SEEKRELA);
232*37da2899SCharles.Forsyth	sys->seek(ibf, big ibs*big iseekn,  Sys->SEEKRELA);
233*37da2899SCharles.Forsyth	while(skip) {
234*37da2899SCharles.Forsyth		sys->read(ibf, ibuf, ibs);
235*37da2899SCharles.Forsyth		skip--;
236*37da2899SCharles.Forsyth	}
237*37da2899SCharles.Forsyth
238*37da2899SCharles.Forsyth	ibc = 0;
239*37da2899SCharles.Forsyth	obc = 0;
240*37da2899SCharles.Forsyth	cbc = 0;
241*37da2899SCharles.Forsyth	op = 0;
242*37da2899SCharles.Forsyth	ip := 0;
243*37da2899SCharles.Forsyth	do {
244*37da2899SCharles.Forsyth		if(ibc-- == 0) {
245*37da2899SCharles.Forsyth			ibc = 0;
246*37da2899SCharles.Forsyth			if(count==0 || nifr+nipr!=count) {
247*37da2899SCharles.Forsyth				if(cflag&(NERR|SYNC))
248*37da2899SCharles.Forsyth					for(ip=0; ip < len ibuf; ip++)
249*37da2899SCharles.Forsyth						ibuf[ip] = byte 0;
250*37da2899SCharles.Forsyth				ibc = sys->read(ibf, ibuf, ibs);
251*37da2899SCharles.Forsyth			}
252*37da2899SCharles.Forsyth			if(ibc == -1) {
253*37da2899SCharles.Forsyth				perror("read");
254*37da2899SCharles.Forsyth				if((cflag&NERR) == 0) {
255*37da2899SCharles.Forsyth					flsh();
256*37da2899SCharles.Forsyth					term();
257*37da2899SCharles.Forsyth				}
258*37da2899SCharles.Forsyth				ibc = 0;
259*37da2899SCharles.Forsyth				for(c:=0; c<ibs; c++)
260*37da2899SCharles.Forsyth					if(ibuf[c] != byte 0)
261*37da2899SCharles.Forsyth						ibc = c;
262*37da2899SCharles.Forsyth				stats();
263*37da2899SCharles.Forsyth			}
264*37da2899SCharles.Forsyth			if(ibc == 0 && --files<=0) {
265*37da2899SCharles.Forsyth				flsh();
266*37da2899SCharles.Forsyth				term();
267*37da2899SCharles.Forsyth			}
268*37da2899SCharles.Forsyth			if(ibc != ibs) {
269*37da2899SCharles.Forsyth				nipr++;
270*37da2899SCharles.Forsyth				if(cflag&SYNC)
271*37da2899SCharles.Forsyth					ibc = ibs;
272*37da2899SCharles.Forsyth			} else
273*37da2899SCharles.Forsyth				nifr++;
274*37da2899SCharles.Forsyth			ip = 0;
275*37da2899SCharles.Forsyth			c := (ibc>>1) & ~1;
276*37da2899SCharles.Forsyth			if(cflag&SWAB && c) do {
277*37da2899SCharles.Forsyth				a := ibuf[ip++];
278*37da2899SCharles.Forsyth				ibuf[ip-1] = ibuf[ip];
279*37da2899SCharles.Forsyth				ibuf[ip++] = a;
280*37da2899SCharles.Forsyth			} while(--c);
281*37da2899SCharles.Forsyth			if(fflag) {
282*37da2899SCharles.Forsyth				obc = ibc;
283*37da2899SCharles.Forsyth				flsh();
284*37da2899SCharles.Forsyth				ibc = 0;
285*37da2899SCharles.Forsyth			}
286*37da2899SCharles.Forsyth			continue;
287*37da2899SCharles.Forsyth		}
288*37da2899SCharles.Forsyth		c := 0;
289*37da2899SCharles.Forsyth		c |= int ibuf[ip++];
290*37da2899SCharles.Forsyth		c &= 8r377;
291*37da2899SCharles.Forsyth		conv(c);
292*37da2899SCharles.Forsyth	} while(1);
293*37da2899SCharles.Forsyth}
294*37da2899SCharles.Forsyth
295*37da2899SCharles.Forsythconv(c: int)
296*37da2899SCharles.Forsyth{
297*37da2899SCharles.Forsyth	case ctype {
298*37da2899SCharles.Forsyth	NULL => null(c);
299*37da2899SCharles.Forsyth	CNULL => cnull(c);
300*37da2899SCharles.Forsyth	EBCDIC => ebcdic(c);
301*37da2899SCharles.Forsyth	IBM => ibm(c);
302*37da2899SCharles.Forsyth	ASCII => ascii(c);
303*37da2899SCharles.Forsyth	BLOCK => block(c);
304*37da2899SCharles.Forsyth	UNBLOCK => unblock(c);
305*37da2899SCharles.Forsyth	}
306*37da2899SCharles.Forsyth}
307*37da2899SCharles.Forsyth
308*37da2899SCharles.Forsythflsh()
309*37da2899SCharles.Forsyth{
310*37da2899SCharles.Forsyth	if(obc) {
311*37da2899SCharles.Forsyth		if(obc == obs)
312*37da2899SCharles.Forsyth			nofr++;
313*37da2899SCharles.Forsyth		else
314*37da2899SCharles.Forsyth			nopr++;
315*37da2899SCharles.Forsyth		c := sys->write(obf, obuf, obc);
316*37da2899SCharles.Forsyth		if(c != obc) {
317*37da2899SCharles.Forsyth			perror("write");
318*37da2899SCharles.Forsyth			term();
319*37da2899SCharles.Forsyth		}
320*37da2899SCharles.Forsyth		obc = 0;
321*37da2899SCharles.Forsyth	}
322*37da2899SCharles.Forsyth}
323*37da2899SCharles.Forsyth
324*37da2899SCharles.Forsythmatch(s: string): int
325*37da2899SCharles.Forsyth{
326*37da2899SCharles.Forsyth	if(len s > len arg)
327*37da2899SCharles.Forsyth		return 0;
328*37da2899SCharles.Forsyth	if(arg[:len s] == s) {
329*37da2899SCharles.Forsyth		arg = arg[len s:];
330*37da2899SCharles.Forsyth		return 1;
331*37da2899SCharles.Forsyth	}
332*37da2899SCharles.Forsyth	return 0;
333*37da2899SCharles.Forsyth}
334*37da2899SCharles.Forsyth
335*37da2899SCharles.Forsyth
336*37da2899SCharles.Forsythnumber(bignum: int): int
337*37da2899SCharles.Forsyth{
338*37da2899SCharles.Forsyth	n := 0;
339*37da2899SCharles.Forsyth	i := 0;
340*37da2899SCharles.Forsyth	while(i < len arg && arg[i] >= '0' && arg[i] <= '9')
341*37da2899SCharles.Forsyth		n = n*10 + arg[i++] - '0';
342*37da2899SCharles.Forsyth	for(;i<len arg; i++) case(arg[i]) {
343*37da2899SCharles.Forsyth		'k' =>
344*37da2899SCharles.Forsyth			n *= 1024;
345*37da2899SCharles.Forsyth		'b' =>
346*37da2899SCharles.Forsyth			n *= 512;
347*37da2899SCharles.Forsyth		'x' =>
348*37da2899SCharles.Forsyth			arg = arg[i:];
349*37da2899SCharles.Forsyth			n *= number(BIG);
350*37da2899SCharles.Forsyth	}
351*37da2899SCharles.Forsyth	if(n>=bignum || n<0) {
352*37da2899SCharles.Forsyth		sys->fprint(stderr, "dd: argument out of range\n");
353*37da2899SCharles.Forsyth		exits("range");
354*37da2899SCharles.Forsyth	}
355*37da2899SCharles.Forsyth	return n;
356*37da2899SCharles.Forsyth}
357*37da2899SCharles.Forsyth
358*37da2899SCharles.Forsythcnull(cc: int)
359*37da2899SCharles.Forsyth{
360*37da2899SCharles.Forsyth	c := cc;
361*37da2899SCharles.Forsyth	if((cflag&UCASE) && c>='a' && c<='z')
362*37da2899SCharles.Forsyth		c += 'A'-'a';
363*37da2899SCharles.Forsyth	if((cflag&LCASE) && c>='A' && c<='Z')
364*37da2899SCharles.Forsyth		c += 'a'-'A';
365*37da2899SCharles.Forsyth	null(c);
366*37da2899SCharles.Forsyth}
367*37da2899SCharles.Forsyth
368*37da2899SCharles.Forsythnull(c: int)
369*37da2899SCharles.Forsyth{
370*37da2899SCharles.Forsyth	obuf[op++] = byte c;
371*37da2899SCharles.Forsyth	if(++obc >= obs) {
372*37da2899SCharles.Forsyth		flsh();
373*37da2899SCharles.Forsyth		op = 0;
374*37da2899SCharles.Forsyth	}
375*37da2899SCharles.Forsyth}
376*37da2899SCharles.Forsyth
377*37da2899SCharles.Forsythascii(cc: int)
378*37da2899SCharles.Forsyth{
379*37da2899SCharles.Forsyth	c := etoa[cc];
380*37da2899SCharles.Forsyth	if(cbs == 0) {
381*37da2899SCharles.Forsyth		cnull(int c);
382*37da2899SCharles.Forsyth		return;
383*37da2899SCharles.Forsyth	}
384*37da2899SCharles.Forsyth	if(c == byte ' ')
385*37da2899SCharles.Forsyth		nspace++;
386*37da2899SCharles.Forsyth	else {
387*37da2899SCharles.Forsyth		while(nspace > 0) {
388*37da2899SCharles.Forsyth			null(' ');
389*37da2899SCharles.Forsyth			nspace--;
390*37da2899SCharles.Forsyth		}
391*37da2899SCharles.Forsyth		cnull(int c);
392*37da2899SCharles.Forsyth	}
393*37da2899SCharles.Forsyth
394*37da2899SCharles.Forsyth	if(++cbc >= cbs) {
395*37da2899SCharles.Forsyth		null('\n');
396*37da2899SCharles.Forsyth		cbc = 0;
397*37da2899SCharles.Forsyth		nspace = 0;
398*37da2899SCharles.Forsyth	}
399*37da2899SCharles.Forsyth}
400*37da2899SCharles.Forsyth
401*37da2899SCharles.Forsythunblock(cc: int)
402*37da2899SCharles.Forsyth{
403*37da2899SCharles.Forsyth	c := cc & 8r377;
404*37da2899SCharles.Forsyth	if(cbs == 0) {
405*37da2899SCharles.Forsyth		cnull(c);
406*37da2899SCharles.Forsyth		return;
407*37da2899SCharles.Forsyth	}
408*37da2899SCharles.Forsyth	if(c == ' ')
409*37da2899SCharles.Forsyth		nspace++;
410*37da2899SCharles.Forsyth	else {
411*37da2899SCharles.Forsyth		while(nspace > 0) {
412*37da2899SCharles.Forsyth			null(' ');
413*37da2899SCharles.Forsyth			nspace--;
414*37da2899SCharles.Forsyth		}
415*37da2899SCharles.Forsyth		cnull(c);
416*37da2899SCharles.Forsyth	}
417*37da2899SCharles.Forsyth
418*37da2899SCharles.Forsyth	if(++cbc >= cbs) {
419*37da2899SCharles.Forsyth		null('\n');
420*37da2899SCharles.Forsyth		cbc = 0;
421*37da2899SCharles.Forsyth		nspace = 0;
422*37da2899SCharles.Forsyth	}
423*37da2899SCharles.Forsyth}
424*37da2899SCharles.Forsyth
425*37da2899SCharles.Forsythebcdic(cc: int)
426*37da2899SCharles.Forsyth{
427*37da2899SCharles.Forsyth
428*37da2899SCharles.Forsyth	c := cc;
429*37da2899SCharles.Forsyth	if(cflag&UCASE && c>='a' && c<='z')
430*37da2899SCharles.Forsyth		c += 'A'-'a';
431*37da2899SCharles.Forsyth	if(cflag&LCASE && c>='A' && c<='Z')
432*37da2899SCharles.Forsyth		c += 'a'-'A';
433*37da2899SCharles.Forsyth	c = int atoe[c];
434*37da2899SCharles.Forsyth	if(cbs == 0) {
435*37da2899SCharles.Forsyth		null(c);
436*37da2899SCharles.Forsyth		return;
437*37da2899SCharles.Forsyth	}
438*37da2899SCharles.Forsyth	if(cc == '\n') {
439*37da2899SCharles.Forsyth		while(cbc < cbs) {
440*37da2899SCharles.Forsyth			null(int atoe[' ']);
441*37da2899SCharles.Forsyth			cbc++;
442*37da2899SCharles.Forsyth		}
443*37da2899SCharles.Forsyth		cbc = 0;
444*37da2899SCharles.Forsyth		return;
445*37da2899SCharles.Forsyth	}
446*37da2899SCharles.Forsyth	if(cbc == cbs)
447*37da2899SCharles.Forsyth		ntrunc++;
448*37da2899SCharles.Forsyth	cbc++;
449*37da2899SCharles.Forsyth	if(cbc <= cbs)
450*37da2899SCharles.Forsyth		null(c);
451*37da2899SCharles.Forsyth}
452*37da2899SCharles.Forsyth
453*37da2899SCharles.Forsythibm(cc: int)
454*37da2899SCharles.Forsyth{
455*37da2899SCharles.Forsyth	c := cc;
456*37da2899SCharles.Forsyth	if(cflag&UCASE && c>='a' && c<='z')
457*37da2899SCharles.Forsyth		c += 'A'-'a';
458*37da2899SCharles.Forsyth	if(cflag&LCASE && c>='A' && c<='Z')
459*37da2899SCharles.Forsyth		c += 'a'-'A';
460*37da2899SCharles.Forsyth	c = int atoibm[c] & 8r377;
461*37da2899SCharles.Forsyth	if(cbs == 0) {
462*37da2899SCharles.Forsyth		null(c);
463*37da2899SCharles.Forsyth		return;
464*37da2899SCharles.Forsyth	}
465*37da2899SCharles.Forsyth	if(cc == '\n') {
466*37da2899SCharles.Forsyth		while(cbc < cbs) {
467*37da2899SCharles.Forsyth			null(int atoibm[' ']);
468*37da2899SCharles.Forsyth			cbc++;
469*37da2899SCharles.Forsyth		}
470*37da2899SCharles.Forsyth		cbc = 0;
471*37da2899SCharles.Forsyth		return;
472*37da2899SCharles.Forsyth	}
473*37da2899SCharles.Forsyth	if(cbc == cbs)
474*37da2899SCharles.Forsyth		ntrunc++;
475*37da2899SCharles.Forsyth	cbc++;
476*37da2899SCharles.Forsyth	if(cbc <= cbs)
477*37da2899SCharles.Forsyth		null(c);
478*37da2899SCharles.Forsyth}
479*37da2899SCharles.Forsyth
480*37da2899SCharles.Forsythblock(cc: int)
481*37da2899SCharles.Forsyth{
482*37da2899SCharles.Forsyth	c := cc;
483*37da2899SCharles.Forsyth	if(cflag&UCASE && c>='a' && c<='z')
484*37da2899SCharles.Forsyth		c += 'A'-'a';
485*37da2899SCharles.Forsyth	if(cflag&LCASE && c>='A' && c<='Z')
486*37da2899SCharles.Forsyth		c += 'a'-'A';
487*37da2899SCharles.Forsyth	c &= 8r377;
488*37da2899SCharles.Forsyth	if(cbs == 0) {
489*37da2899SCharles.Forsyth		null(c);
490*37da2899SCharles.Forsyth		return;
491*37da2899SCharles.Forsyth	}
492*37da2899SCharles.Forsyth	if(cc == '\n') {
493*37da2899SCharles.Forsyth		while(cbc < cbs) {
494*37da2899SCharles.Forsyth			null(' ');
495*37da2899SCharles.Forsyth			cbc++;
496*37da2899SCharles.Forsyth		}
497*37da2899SCharles.Forsyth		cbc = 0;
498*37da2899SCharles.Forsyth		return;
499*37da2899SCharles.Forsyth	}
500*37da2899SCharles.Forsyth	if(cbc == cbs)
501*37da2899SCharles.Forsyth		ntrunc++;
502*37da2899SCharles.Forsyth	cbc++;
503*37da2899SCharles.Forsyth	if(cbc <= cbs)
504*37da2899SCharles.Forsyth		null(c);
505*37da2899SCharles.Forsyth}
506*37da2899SCharles.Forsyth
507*37da2899SCharles.Forsythterm()
508*37da2899SCharles.Forsyth{
509*37da2899SCharles.Forsyth	stats();
510*37da2899SCharles.Forsyth	exits(nil);
511*37da2899SCharles.Forsyth}
512*37da2899SCharles.Forsyth
513*37da2899SCharles.Forsythstats()
514*37da2899SCharles.Forsyth{
515*37da2899SCharles.Forsyth	sys->fprint(stderr, "%ud+%ud records in\n", nifr, nipr);
516*37da2899SCharles.Forsyth	sys->fprint(stderr, "%ud+%ud records out\n", nofr, nopr);
517*37da2899SCharles.Forsyth	if(ntrunc)
518*37da2899SCharles.Forsyth		sys->fprint(stderr, "%ud truncated records\n", ntrunc);
519*37da2899SCharles.Forsyth}
520*37da2899SCharles.Forsyth
521*37da2899SCharles.Forsythetoa := array[] of
522*37da2899SCharles.Forsyth{
523*37da2899SCharles.Forsyth	byte 8r000,byte 8r001,byte 8r002,byte 8r003,byte 8r234,byte 8r011,byte 8r206,byte 8r177,
524*37da2899SCharles.Forsyth	byte 8r227,byte 8r215,byte 8r216,byte 8r013,byte 8r014,byte 8r015,byte 8r016,byte 8r017,
525*37da2899SCharles.Forsyth	byte 8r020,byte 8r021,byte 8r022,byte 8r023,byte 8r235,byte 8r205,byte 8r010,byte 8r207,
526*37da2899SCharles.Forsyth	byte 8r030,byte 8r031,byte 8r222,byte 8r217,byte 8r034,byte 8r035,byte 8r036,byte 8r037,
527*37da2899SCharles.Forsyth	byte 8r200,byte 8r201,byte 8r202,byte 8r203,byte 8r204,byte 8r012,byte 8r027,byte 8r033,
528*37da2899SCharles.Forsyth	byte 8r210,byte 8r211,byte 8r212,byte 8r213,byte 8r214,byte 8r005,byte 8r006,byte 8r007,
529*37da2899SCharles.Forsyth	byte 8r220,byte 8r221,byte 8r026,byte 8r223,byte 8r224,byte 8r225,byte 8r226,byte 8r004,
530*37da2899SCharles.Forsyth	byte 8r230,byte 8r231,byte 8r232,byte 8r233,byte 8r024,byte 8r025,byte 8r236,byte 8r032,
531*37da2899SCharles.Forsyth	byte 8r040,byte 8r240,byte 8r241,byte 8r242,byte 8r243,byte 8r244,byte 8r245,byte 8r246,
532*37da2899SCharles.Forsyth	byte 8r247,byte 8r250,byte 8r133,byte 8r056,byte 8r074,byte 8r050,byte 8r053,byte 8r041,
533*37da2899SCharles.Forsyth	byte 8r046,byte 8r251,byte 8r252,byte 8r253,byte 8r254,byte 8r255,byte 8r256,byte 8r257,
534*37da2899SCharles.Forsyth	byte 8r260,byte 8r261,byte 8r135,byte 8r044,byte 8r052,byte 8r051,byte 8r073,byte 8r136,
535*37da2899SCharles.Forsyth	byte 8r055,byte 8r057,byte 8r262,byte 8r263,byte 8r264,byte 8r265,byte 8r266,byte 8r267,
536*37da2899SCharles.Forsyth	byte 8r270,byte 8r271,byte 8r174,byte 8r054,byte 8r045,byte 8r137,byte 8r076,byte 8r077,
537*37da2899SCharles.Forsyth	byte 8r272,byte 8r273,byte 8r274,byte 8r275,byte 8r276,byte 8r277,byte 8r300,byte 8r301,
538*37da2899SCharles.Forsyth	byte 8r302,byte 8r140,byte 8r072,byte 8r043,byte 8r100,byte 8r047,byte 8r075,byte 8r042,
539*37da2899SCharles.Forsyth	byte 8r303,byte 8r141,byte 8r142,byte 8r143,byte 8r144,byte 8r145,byte 8r146,byte 8r147,
540*37da2899SCharles.Forsyth	byte 8r150,byte 8r151,byte 8r304,byte 8r305,byte 8r306,byte 8r307,byte 8r310,byte 8r311,
541*37da2899SCharles.Forsyth	byte 8r312,byte 8r152,byte 8r153,byte 8r154,byte 8r155,byte 8r156,byte 8r157,byte 8r160,
542*37da2899SCharles.Forsyth	byte 8r161,byte 8r162,byte 8r313,byte 8r314,byte 8r315,byte 8r316,byte 8r317,byte 8r320,
543*37da2899SCharles.Forsyth	byte 8r321,byte 8r176,byte 8r163,byte 8r164,byte 8r165,byte 8r166,byte 8r167,byte 8r170,
544*37da2899SCharles.Forsyth	byte 8r171,byte 8r172,byte 8r322,byte 8r323,byte 8r324,byte 8r325,byte 8r326,byte 8r327,
545*37da2899SCharles.Forsyth	byte 8r330,byte 8r331,byte 8r332,byte 8r333,byte 8r334,byte 8r335,byte 8r336,byte 8r337,
546*37da2899SCharles.Forsyth	byte 8r340,byte 8r341,byte 8r342,byte 8r343,byte 8r344,byte 8r345,byte 8r346,byte 8r347,
547*37da2899SCharles.Forsyth	byte 8r173,byte 8r101,byte 8r102,byte 8r103,byte 8r104,byte 8r105,byte 8r106,byte 8r107,
548*37da2899SCharles.Forsyth	byte 8r110,byte 8r111,byte 8r350,byte 8r351,byte 8r352,byte 8r353,byte 8r354,byte 8r355,
549*37da2899SCharles.Forsyth	byte 8r175,byte 8r112,byte 8r113,byte 8r114,byte 8r115,byte 8r116,byte 8r117,byte 8r120,
550*37da2899SCharles.Forsyth	byte 8r121,byte 8r122,byte 8r356,byte 8r357,byte 8r360,byte 8r361,byte 8r362,byte 8r363,
551*37da2899SCharles.Forsyth	byte 8r134,byte 8r237,byte 8r123,byte 8r124,byte 8r125,byte 8r126,byte 8r127,byte 8r130,
552*37da2899SCharles.Forsyth	byte 8r131,byte 8r132,byte 8r364,byte 8r365,byte 8r366,byte 8r367,byte 8r370,byte 8r371,
553*37da2899SCharles.Forsyth	byte 8r060,byte 8r061,byte 8r062,byte 8r063,byte 8r064,byte 8r065,byte 8r066,byte 8r067,
554*37da2899SCharles.Forsyth	byte 8r070,byte 8r071,byte 8r372,byte 8r373,byte 8r374,byte 8r375,byte 8r376,byte 8r377,
555*37da2899SCharles.Forsyth};
556*37da2899SCharles.Forsythatoe := array[] of
557*37da2899SCharles.Forsyth{
558*37da2899SCharles.Forsyth	byte 8r000,byte 8r001,byte 8r002,byte 8r003,byte 8r067,byte 8r055,byte 8r056,byte 8r057,
559*37da2899SCharles.Forsyth	byte 8r026,byte 8r005,byte 8r045,byte 8r013,byte 8r014,byte 8r015,byte 8r016,byte 8r017,
560*37da2899SCharles.Forsyth	byte 8r020,byte 8r021,byte 8r022,byte 8r023,byte 8r074,byte 8r075,byte 8r062,byte 8r046,
561*37da2899SCharles.Forsyth	byte 8r030,byte 8r031,byte 8r077,byte 8r047,byte 8r034,byte 8r035,byte 8r036,byte 8r037,
562*37da2899SCharles.Forsyth	byte 8r100,byte 8r117,byte 8r177,byte 8r173,byte 8r133,byte 8r154,byte 8r120,byte 8r175,
563*37da2899SCharles.Forsyth	byte 8r115,byte 8r135,byte 8r134,byte 8r116,byte 8r153,byte 8r140,byte 8r113,byte 8r141,
564*37da2899SCharles.Forsyth	byte 8r360,byte 8r361,byte 8r362,byte 8r363,byte 8r364,byte 8r365,byte 8r366,byte 8r367,
565*37da2899SCharles.Forsyth	byte 8r370,byte 8r371,byte 8r172,byte 8r136,byte 8r114,byte 8r176,byte 8r156,byte 8r157,
566*37da2899SCharles.Forsyth	byte 8r174,byte 8r301,byte 8r302,byte 8r303,byte 8r304,byte 8r305,byte 8r306,byte 8r307,
567*37da2899SCharles.Forsyth	byte 8r310,byte 8r311,byte 8r321,byte 8r322,byte 8r323,byte 8r324,byte 8r325,byte 8r326,
568*37da2899SCharles.Forsyth	byte 8r327,byte 8r330,byte 8r331,byte 8r342,byte 8r343,byte 8r344,byte 8r345,byte 8r346,
569*37da2899SCharles.Forsyth	byte 8r347,byte 8r350,byte 8r351,byte 8r112,byte 8r340,byte 8r132,byte 8r137,byte 8r155,
570*37da2899SCharles.Forsyth	byte 8r171,byte 8r201,byte 8r202,byte 8r203,byte 8r204,byte 8r205,byte 8r206,byte 8r207,
571*37da2899SCharles.Forsyth	byte 8r210,byte 8r211,byte 8r221,byte 8r222,byte 8r223,byte 8r224,byte 8r225,byte 8r226,
572*37da2899SCharles.Forsyth	byte 8r227,byte 8r230,byte 8r231,byte 8r242,byte 8r243,byte 8r244,byte 8r245,byte 8r246,
573*37da2899SCharles.Forsyth	byte 8r247,byte 8r250,byte 8r251,byte 8r300,byte 8r152,byte 8r320,byte 8r241,byte 8r007,
574*37da2899SCharles.Forsyth	byte 8r040,byte 8r041,byte 8r042,byte 8r043,byte 8r044,byte 8r025,byte 8r006,byte 8r027,
575*37da2899SCharles.Forsyth	byte 8r050,byte 8r051,byte 8r052,byte 8r053,byte 8r054,byte 8r011,byte 8r012,byte 8r033,
576*37da2899SCharles.Forsyth	byte 8r060,byte 8r061,byte 8r032,byte 8r063,byte 8r064,byte 8r065,byte 8r066,byte 8r010,
577*37da2899SCharles.Forsyth	byte 8r070,byte 8r071,byte 8r072,byte 8r073,byte 8r004,byte 8r024,byte 8r076,byte 8r341,
578*37da2899SCharles.Forsyth	byte 8r101,byte 8r102,byte 8r103,byte 8r104,byte 8r105,byte 8r106,byte 8r107,byte 8r110,
579*37da2899SCharles.Forsyth	byte 8r111,byte 8r121,byte 8r122,byte 8r123,byte 8r124,byte 8r125,byte 8r126,byte 8r127,
580*37da2899SCharles.Forsyth	byte 8r130,byte 8r131,byte 8r142,byte 8r143,byte 8r144,byte 8r145,byte 8r146,byte 8r147,
581*37da2899SCharles.Forsyth	byte 8r150,byte 8r151,byte 8r160,byte 8r161,byte 8r162,byte 8r163,byte 8r164,byte 8r165,
582*37da2899SCharles.Forsyth	byte 8r166,byte 8r167,byte 8r170,byte 8r200,byte 8r212,byte 8r213,byte 8r214,byte 8r215,
583*37da2899SCharles.Forsyth	byte 8r216,byte 8r217,byte 8r220,byte 8r232,byte 8r233,byte 8r234,byte 8r235,byte 8r236,
584*37da2899SCharles.Forsyth	byte 8r237,byte 8r240,byte 8r252,byte 8r253,byte 8r254,byte 8r255,byte 8r256,byte 8r257,
585*37da2899SCharles.Forsyth	byte 8r260,byte 8r261,byte 8r262,byte 8r263,byte 8r264,byte 8r265,byte 8r266,byte 8r267,
586*37da2899SCharles.Forsyth	byte 8r270,byte 8r271,byte 8r272,byte 8r273,byte 8r274,byte 8r275,byte 8r276,byte 8r277,
587*37da2899SCharles.Forsyth	byte 8r312,byte 8r313,byte 8r314,byte 8r315,byte 8r316,byte 8r317,byte 8r332,byte 8r333,
588*37da2899SCharles.Forsyth	byte 8r334,byte 8r335,byte 8r336,byte 8r337,byte 8r352,byte 8r353,byte 8r354,byte 8r355,
589*37da2899SCharles.Forsyth	byte 8r356,byte 8r357,byte 8r372,byte 8r373,byte 8r374,byte 8r375,byte 8r376,byte 8r377,
590*37da2899SCharles.Forsyth};
591*37da2899SCharles.Forsythatoibm := array[] of
592*37da2899SCharles.Forsyth{
593*37da2899SCharles.Forsyth	byte 8r000,byte 8r001,byte 8r002,byte 8r003,byte 8r067,byte 8r055,byte 8r056,byte 8r057,
594*37da2899SCharles.Forsyth	byte 8r026,byte 8r005,byte 8r045,byte 8r013,byte 8r014,byte 8r015,byte 8r016,byte 8r017,
595*37da2899SCharles.Forsyth	byte 8r020,byte 8r021,byte 8r022,byte 8r023,byte 8r074,byte 8r075,byte 8r062,byte 8r046,
596*37da2899SCharles.Forsyth	byte 8r030,byte 8r031,byte 8r077,byte 8r047,byte 8r034,byte 8r035,byte 8r036,byte 8r037,
597*37da2899SCharles.Forsyth	byte 8r100,byte 8r132,byte 8r177,byte 8r173,byte 8r133,byte 8r154,byte 8r120,byte 8r175,
598*37da2899SCharles.Forsyth	byte 8r115,byte 8r135,byte 8r134,byte 8r116,byte 8r153,byte 8r140,byte 8r113,byte 8r141,
599*37da2899SCharles.Forsyth	byte 8r360,byte 8r361,byte 8r362,byte 8r363,byte 8r364,byte 8r365,byte 8r366,byte 8r367,
600*37da2899SCharles.Forsyth	byte 8r370,byte 8r371,byte 8r172,byte 8r136,byte 8r114,byte 8r176,byte 8r156,byte 8r157,
601*37da2899SCharles.Forsyth	byte 8r174,byte 8r301,byte 8r302,byte 8r303,byte 8r304,byte 8r305,byte 8r306,byte 8r307,
602*37da2899SCharles.Forsyth	byte 8r310,byte 8r311,byte 8r321,byte 8r322,byte 8r323,byte 8r324,byte 8r325,byte 8r326,
603*37da2899SCharles.Forsyth	byte 8r327,byte 8r330,byte 8r331,byte 8r342,byte 8r343,byte 8r344,byte 8r345,byte 8r346,
604*37da2899SCharles.Forsyth	byte 8r347,byte 8r350,byte 8r351,byte 8r255,byte 8r340,byte 8r275,byte 8r137,byte 8r155,
605*37da2899SCharles.Forsyth	byte 8r171,byte 8r201,byte 8r202,byte 8r203,byte 8r204,byte 8r205,byte 8r206,byte 8r207,
606*37da2899SCharles.Forsyth	byte 8r210,byte 8r211,byte 8r221,byte 8r222,byte 8r223,byte 8r224,byte 8r225,byte 8r226,
607*37da2899SCharles.Forsyth	byte 8r227,byte 8r230,byte 8r231,byte 8r242,byte 8r243,byte 8r244,byte 8r245,byte 8r246,
608*37da2899SCharles.Forsyth	byte 8r247,byte 8r250,byte 8r251,byte 8r300,byte 8r117,byte 8r320,byte 8r241,byte 8r007,
609*37da2899SCharles.Forsyth	byte 8r040,byte 8r041,byte 8r042,byte 8r043,byte 8r044,byte 8r025,byte 8r006,byte 8r027,
610*37da2899SCharles.Forsyth	byte 8r050,byte 8r051,byte 8r052,byte 8r053,byte 8r054,byte 8r011,byte 8r012,byte 8r033,
611*37da2899SCharles.Forsyth	byte 8r060,byte 8r061,byte 8r032,byte 8r063,byte 8r064,byte 8r065,byte 8r066,byte 8r010,
612*37da2899SCharles.Forsyth	byte 8r070,byte 8r071,byte 8r072,byte 8r073,byte 8r004,byte 8r024,byte 8r076,byte 8r341,
613*37da2899SCharles.Forsyth	byte 8r101,byte 8r102,byte 8r103,byte 8r104,byte 8r105,byte 8r106,byte 8r107,byte 8r110,
614*37da2899SCharles.Forsyth	byte 8r111,byte 8r121,byte 8r122,byte 8r123,byte 8r124,byte 8r125,byte 8r126,byte 8r127,
615*37da2899SCharles.Forsyth	byte 8r130,byte 8r131,byte 8r142,byte 8r143,byte 8r144,byte 8r145,byte 8r146,byte 8r147,
616*37da2899SCharles.Forsyth	byte 8r150,byte 8r151,byte 8r160,byte 8r161,byte 8r162,byte 8r163,byte 8r164,byte 8r165,
617*37da2899SCharles.Forsyth	byte 8r166,byte 8r167,byte 8r170,byte 8r200,byte 8r212,byte 8r213,byte 8r214,byte 8r215,
618*37da2899SCharles.Forsyth	byte 8r216,byte 8r217,byte 8r220,byte 8r232,byte 8r233,byte 8r234,byte 8r235,byte 8r236,
619*37da2899SCharles.Forsyth	byte 8r237,byte 8r240,byte 8r252,byte 8r253,byte 8r254,byte 8r255,byte 8r256,byte 8r257,
620*37da2899SCharles.Forsyth	byte 8r260,byte 8r261,byte 8r262,byte 8r263,byte 8r264,byte 8r265,byte 8r266,byte 8r267,
621*37da2899SCharles.Forsyth	byte 8r270,byte 8r271,byte 8r272,byte 8r273,byte 8r274,byte 8r275,byte 8r276,byte 8r277,
622*37da2899SCharles.Forsyth	byte 8r312,byte 8r313,byte 8r314,byte 8r315,byte 8r316,byte 8r317,byte 8r332,byte 8r333,
623*37da2899SCharles.Forsyth	byte 8r334,byte 8r335,byte 8r336,byte 8r337,byte 8r352,byte 8r353,byte 8r354,byte 8r355,
624*37da2899SCharles.Forsyth	byte 8r356,byte 8r357,byte 8r372,byte 8r373,byte 8r374,byte 8r375,byte 8r376,byte 8r377,
625*37da2899SCharles.Forsyth};
626