diff options
Diffstat (limited to 'appl/cmd/comm.b')
| -rwxr-xr-x | appl/cmd/comm.b | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/appl/cmd/comm.b b/appl/cmd/comm.b new file mode 100755 index 00000000..1e56310e --- /dev/null +++ b/appl/cmd/comm.b @@ -0,0 +1,124 @@ +implement Comm; + +# Copyright © 2002 Lucent Technologies Inc. +# Subject to the Lucent Public Licence 1.02 +# Limbo translation by Vita Nuova 2004; bug fixed. + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; + +include "arg.m"; + +Comm: module +{ + init: fn(nil: ref Draw->Context, args: list of string); +}; + +One, Two, Three: con 1<<iota; +cols := One|Two|Three; +ldr := array[3] of {"", "\t", "\t\t"}; + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + bufio = load Bufio Bufio->PATH; + + arg := load Arg Arg->PATH; + arg->init(args); + arg->setusage("comm [-123] file1 file2"); + while((c := arg->opt()) != 0){ + case c { + '1' to '3' => + cols &= ~(1 << (c-'1')); + * => + arg->usage(); + } + } + args = arg->argv(); + if(len args != 2) + arg->usage(); + arg = nil; + + if((cols & One) == 0){ + ldr[1] = ""; + ldr[2] = ldr[2][1:]; + } + if((cols & Two) == 0) + ldr[2] = ldr[2][1:]; + + ib1 := openfil(hd args); + ib2 := openfil(hd tl args); + if((lb1 := ib1.gets('\n')) == nil){ + if((lb2 := ib2.gets('\n')) == nil) + exit; + copy(ib2, lb2, 2); + } + if((lb2 := ib2.gets('\n')) == nil) + copy(ib1, lb1, 1); + for(;;) + case compare(lb1, lb2) { + 0 => + wr(lb1, 3); + if((lb1 = ib1.gets('\n')) == nil){ + if((lb2 = ib2.gets('\n')) == nil) + exit; + copy(ib2, lb2, 2); + } + if((lb2 = ib2.gets('\n')) == nil) + copy(ib1, lb1, 1); + 1 => + wr(lb1, 1); + if((lb1 = ib1.gets('\n')) == nil) + copy(ib2, lb2, 2); + 2 => + wr(lb2, 2); + if((lb2 = ib2.gets('\n')) == nil) + copy(ib1, lb1, 1); + } +} + +wr(str: string, n: int) +{ + if(cols & (1<<(n-1))) + sys->print("%s%s", ldr[n-1], str); +} + +copy(ibuf: ref Iobuf, lbuf: string, n: int) +{ + do + wr(lbuf, n); + while((lbuf = ibuf.gets('\n')) != nil); + exit; +} + +compare(a: string, b: string): int +{ + for(i := 0; i < len a; i++){ + if(i >= len b || a[i] < b[i]) + return 1; + if(a[i] != b[i]) + return 2; + } + if(i == len b) + return 0; + return 2; +} + +openfil(s: string): ref Iobuf +{ + if(s == "-") + b := bufio->fopen(sys->fildes(0), Bufio->OREAD); + else + b = bufio->open(s, Bufio->OREAD); + if(b != nil) + return b; + sys->fprint(sys->fildes(2), "comm: cannot open %s: %r\n", s); + raise "fail:open"; +} + |
