Charles.Forsyth20060303a828770d19 years agoHistory
151 lines · 2.8 KB · Brainfuck
RawDownload
implement Cmp; include "sys.m";	sys: Sys; include "draw.m";	draw: Draw; include "arg.m"; BUF: con 65536;stderr: ref Sys->FD; Cmp: module{	init: fn(nil: ref Draw->Context, argv: list of string);}; init(nil: ref Draw->Context, args: list of string){	sys = load Sys Sys->PATH; 	lflag := Lflag := sflag := 0;	buf1 := array[BUF] of byte;	buf2 := array[BUF] of byte; 	stderr = sys->fildes(2); 	arg := load Arg Arg->PATH;		if(arg == nil){		sys->fprint(stderr, "cmp: cannot load %s: %r\n", Arg->PATH);		raise "fail:load";	}	arg->init(args);	while((op := arg->opt()) != 0)		case op {		'l' =>		lflag = 1;		'L' =>	Lflag = 1;		's' =>		sflag = 1;		* =>		usage();		}	args = arg->argv();	arg = nil;	if(args == nil)		usage(); 	if(len args < 2)		usage();	name1 := hd args;	args = tl args; 	if((f1 := sys->open(name1, Sys->OREAD)) == nil){		sys->fprint(stderr, "cmp: can't open %s: %r\n",name1);		raise "fail:open";	}	name2 := hd args;	args = tl args; 	if((f2 := sys->open(name2, Sys->OREAD)) == nil){		sys->fprint(stderr, "cmp: can't open %s: %r\n",name2);		raise "fail:open";	} 	if(args != nil){		o := big hd args;		if(sys->seek(f1, o, 0) < big 0){			sys->fprint(stderr, "cmp: seek by offset1 failed: %r\n");			raise "fail:seek 1";		}		args = tl args;	} 	if(args != nil){		o := big hd args;		if(sys->seek(f2, o, 0) < big 0){			sys->fprint(stderr, "cmp: seek by offset2 failed: %r");			raise "fail:seek 2";		}		args = tl args;	}	if(args != nil)		usage();	nc := big 1;	l := big 1;	diff := 0;	b1, b2: array of byte;	for(;;){		if(len b1 == 0){			nr := sys->read(f1, buf1, BUF);			if(nr < 0){				if(!sflag)					sys->print("error on %s after %bd bytes\n", name1, nc-big 1);				raise "fail:read error";			}			b1 = buf1[0: nr];		}		if(len b2 == 0){			nr := sys->read(f2, buf2, BUF);			if(nr < 0){				if(!sflag)					sys->print("error on %s after %bd bytes\n", name2, nc-big 1);				raise "fail:read error";			}			b2 = buf2[0: nr];		}		n := len b2;		if(n > len b1)			n = len b1;		if(n == 0)			break;		for(i:=0; i<n; i++){			if(Lflag && b1[i]== byte '\n')				l++;			if(b1[i] != b2[i]){				if(!lflag){					if(!sflag){						sys->print("%s %s differ: char %bd", name1, name2, nc+big i);						if(Lflag)							sys->print(" line %bd\n", l);						else							sys->print("\n");					}					raise "fail:differ";				}				sys->print("%6bd 0x%.2x 0x%.2x\n", nc+big i, int b1[i], int b2[i]);				diff = 1;			}		}		nc += big n;		b1 = b1[n:];		b2 = b2[n:];	}	if(len b1 != len b2) {		nc--;		if(len b1 > len b2)			sys->print("EOF on %s after %bd bytes\n", name2, nc);		else 			sys->print("EOF on %s after %bd bytes\n", name1, nc);		raise "fail:EOF";	}	if(diff)		raise "fail:differ";	exit;}  usage() {	sys->fprint(stderr, "Usage: cmp [-lsL] file1 file2 [offset1 [offset2] ]\n");	raise "fail:usage";}