diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/cmp.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/cmp.b')
| -rw-r--r-- | appl/cmd/cmp.b | 151 |
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"; +} |
