Charles.Forsyth20060303a828770d19 years agoHistory
625 lines · 16.0 KB · Brainfuck
RawDownload
implement dd; include "sys.m";	sys: Sys;	stderr: ref Sys->FD; include "draw.m"; dd: module{	init: fn(nil: ref Draw->Context, argv: list of string);}; BIG:	con 2147483647;LCASE,UCASE,SWAB,NERR	,SYNC	:	con (1<<iota); NULL,CNULL,EBCDIC,IBM,ASCII,BLOCK,UNBLOCK:	con iota; cflag:		int;ctype:	int; fflag:		int;arg:		string;ifile:		string;ofile:		string;ibuf:		array of byte;obuf:		array of byte;op:		int;skip:		int;oseekn:	int;iseekn:	int;count:	int;files:=	1;ibs:=		512;obs:=		512;bs:		int;cbs:		int;ibc:		int;obc:		int;cbc:		int;nifr:		int;nipr:		int;nofr:		int;nopr:		int;ntrunc:	int;ibf:		ref Sys->FD;obf:		ref Sys->FD;nspace:	int; iskey(key:string, s: string): int{	return key[0] == '-' && key[1:] ==  s;} exits(msg: string){	if(msg == nil)		exit; 	raise "fail:"+msg;} perror(msg: string){	sys->fprint(stderr, "%s: %r\n", msg);} init(nil: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	if(sys == nil)		return;	stderr = sys->fildes(2); 	ctype = NULL;	argv = tl argv;	while(argv != nil) {		key := hd argv;		argv = tl argv;		if(argv == nil){			sys->fprint(stderr, "dd: arg %s needs a value\n", key);			exits("arg");		}		arg = hd argv;		argv = tl argv;		if(iskey(key, "ibs")) {			ibs = number(BIG);			continue;		}		if(iskey(key, "obs")) {			obs = number(BIG);			continue;		}		if(iskey(key, "cbs")) {			cbs = number(BIG);			continue;		}		if(iskey(key, "bs")) {			bs = number(BIG);			continue;		}		if(iskey(key, "if")) {			ifile = arg[0:];			continue;		}		if(iskey(key, "of")) {			ofile = arg[0:];			continue;		}		if(iskey(key, "skip")) {			skip = number(BIG);			continue;		}		if(iskey(key, "seek") || iskey(key, "oseek")) {			oseekn = number(BIG);			continue;		}		if(iskey(key, "iseek")) {			iseekn = number(BIG);			continue;		}		if(iskey(key, "count")) {			count = number(BIG);			continue;		}		if(iskey(key, "files")) {			files = number(BIG);			continue;		}		if(iskey(key, "conv")) {			do {				if(arg == nil)					break;				if(match(","))					continue;				if(match("ebcdic")) {					ctype = EBCDIC;					continue;				}				if(match("ibm")) {					ctype = IBM;					continue;				}				if(match("ascii")) {					ctype = ASCII;					continue;				}				if(match("block")) {					ctype = BLOCK;					continue;				}				if(match("unblock")) {					ctype = UNBLOCK;					continue;				}				if(match("lcase")) {					cflag |= LCASE;					continue;				}				if(match("ucase")) {					cflag |= UCASE;					continue;				}				if(match("swab")) {					cflag |= SWAB;					continue;				}				if(match("noerror")) {					cflag |= NERR;					continue;				}				if(match("sync")) {					cflag |= SYNC;					continue;				}			} while(1);			continue;		}		sys->fprint(stderr, "dd: bad arg: %s\n", key);		exits("arg");	}	if(ctype == NULL && cflag&(LCASE|UCASE))		ctype = CNULL;	if(ifile != nil)		ibf = sys->open(ifile, Sys->OREAD);	else		ibf = sys->fildes(sys->dup(0, -1)); 	if(ibf == nil) {		sys->fprint(stderr, "dd: open %s: %r\n", ifile);		exits("open");	} 	if(ofile != nil){		obf = sys->create(ofile, Sys->OWRITE, 8r664);		if(obf == nil) {			sys->fprint(stderr, "dd: create %s: %r\n", ofile);			exits("create");		}	}else{		obf = sys->fildes(sys->dup(1, -1));		if(obf == nil) {			sys->fprint(stderr, "dd: can't dup file descriptor: %r\n");			exits("dup");		}	}	if(bs)		ibs = obs = bs;	if(ibs == obs && ctype == NULL)		fflag++;	if(ibs == 0 || obs == 0) {		sys->fprint(stderr, "dd: counts: cannot be zero\n");		exits("counts");	}	ibuf = array[ibs] of byte;	obuf = array[obs] of byte; 	if(fflag)		obuf = ibuf; 	sys->seek(obf, big obs*big oseekn, Sys->SEEKRELA);	sys->seek(ibf, big ibs*big iseekn,  Sys->SEEKRELA);	while(skip) {		sys->read(ibf, ibuf, ibs);		skip--;	} 	ibc = 0;	obc = 0;	cbc = 0;	op = 0;	ip := 0;	do {		if(ibc-- == 0) {			ibc = 0;			if(count==0 || nifr+nipr!=count) {				if(cflag&(NERR|SYNC))					for(ip=0; ip < len ibuf; ip++)						ibuf[ip] = byte 0;				ibc = sys->read(ibf, ibuf, ibs);			}			if(ibc == -1) {				perror("read");				if((cflag&NERR) == 0) {					flsh();					term();				}				ibc = 0;				for(c:=0; c<ibs; c++)					if(ibuf[c] != byte 0)						ibc = c;				stats();			}			if(ibc == 0 && --files<=0) {				flsh();				term();			}			if(ibc != ibs) {				nipr++;				if(cflag&SYNC)					ibc = ibs;			} else				nifr++;			ip = 0;			c := (ibc>>1) & ~1;			if(cflag&SWAB && c) do {				a := ibuf[ip++];				ibuf[ip-1] = ibuf[ip];				ibuf[ip++] = a;			} while(--c);			if(fflag) {				obc = ibc;				flsh();				ibc = 0;			}			continue;		}		c := 0;		c |= int ibuf[ip++];		c &= 8r377;		conv(c);	} while(1);} conv(c: int){	case ctype {	NULL => null(c);	CNULL => cnull(c);	EBCDIC => ebcdic(c);	IBM => ibm(c);	ASCII => ascii(c);	BLOCK => block(c);	UNBLOCK => unblock(c);	}} flsh(){	if(obc) {		if(obc == obs)			nofr++;		else			nopr++;		c := sys->write(obf, obuf, obc);		if(c != obc) {			perror("write");			term();		}		obc = 0;	}} match(s: string): int{	if(len s > len arg)		return 0;	if(arg[:len s] == s) {		arg = arg[len s:];		return 1;	}	return 0;}  number(bignum: int): int{	n := 0;	i := 0;	while(i < len arg && arg[i] >= '0' && arg[i] <= '9')		n = n*10 + arg[i++] - '0';	for(;i<len arg; i++) case(arg[i]) {		'k' =>			n *= 1024;		'b' =>			n *= 512;		'x' =>			arg = arg[i:];			n *= number(BIG);	}	if(n>=bignum || n<0) {		sys->fprint(stderr, "dd: argument out of range\n");		exits("range");	}	return n;} cnull(cc: int){	c := cc;	if((cflag&UCASE) && c>='a' && c<='z')		c += 'A'-'a';	if((cflag&LCASE) && c>='A' && c<='Z')		c += 'a'-'A';	null(c);} null(c: int){	obuf[op++] = byte c;	if(++obc >= obs) {		flsh();		op = 0;	}} ascii(cc: int){	c := etoa[cc];	if(cbs == 0) {		cnull(int c);		return;	}	if(c == byte ' ')		nspace++;	else {		while(nspace > 0) {			null(' ');			nspace--;		}		cnull(int c);	} 	if(++cbc >= cbs) {		null('\n');		cbc = 0;		nspace = 0;	}} unblock(cc: int){	c := cc & 8r377;	if(cbs == 0) {		cnull(c);		return;	}	if(c == ' ')		nspace++;	else {		while(nspace > 0) {			null(' ');			nspace--;		}		cnull(c);	} 	if(++cbc >= cbs) {		null('\n');		cbc = 0;		nspace = 0;	}} ebcdic(cc: int){ 	c := cc;	if(cflag&UCASE && c>='a' && c<='z')		c += 'A'-'a';	if(cflag&LCASE && c>='A' && c<='Z')		c += 'a'-'A';	c = int atoe[c];	if(cbs == 0) {		null(c);		return;	}	if(cc == '\n') {		while(cbc < cbs) {			null(int atoe[' ']);			cbc++;		}		cbc = 0;		return;	}	if(cbc == cbs)		ntrunc++;	cbc++;	if(cbc <= cbs)		null(c);} ibm(cc: int){	c := cc;	if(cflag&UCASE && c>='a' && c<='z')		c += 'A'-'a';	if(cflag&LCASE && c>='A' && c<='Z')		c += 'a'-'A';	c = int atoibm[c] & 8r377;	if(cbs == 0) {		null(c);		return;	}	if(cc == '\n') {		while(cbc < cbs) {			null(int atoibm[' ']);			cbc++;		}		cbc = 0;		return;	}	if(cbc == cbs)		ntrunc++;	cbc++;	if(cbc <= cbs)		null(c);} block(cc: int){	c := cc;	if(cflag&UCASE && c>='a' && c<='z')		c += 'A'-'a';	if(cflag&LCASE && c>='A' && c<='Z')		c += 'a'-'A';	c &= 8r377;	if(cbs == 0) {		null(c);		return;	}	if(cc == '\n') {		while(cbc < cbs) {			null(' ');			cbc++;		}		cbc = 0;		return;	}	if(cbc == cbs)

Lines 1–500 of 625.