summaryrefslogtreecommitdiff
path: root/appl/cmd/cmp.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/cmp.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/cmd/cmp.b')
-rw-r--r--appl/cmd/cmp.b151
1 files changed, 151 insertions, 0 deletions
diff --git a/appl/cmd/cmp.b b/appl/cmd/cmp.b
new file mode 100644
index 00000000..ce631b93
--- /dev/null
+++ b/appl/cmd/cmp.b
@@ -0,0 +1,151 @@
+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";
+}