1implement Uniq; 2 3include "sys.m"; 4 sys: Sys; 5include "bufio.m"; 6include "draw.m"; 7include "arg.m"; 8 9Uniq: module 10{ 11 init: fn(nil: ref Draw->Context, args: list of string); 12}; 13 14usage() 15{ 16 fail("usage", sys->sprint("usage: uniq [-ud] [file]")); 17} 18 19init(nil : ref Draw->Context, args : list of string) 20{ 21 bio : ref Bufio->Iobuf; 22 23 sys = load Sys Sys->PATH; 24 bufio := load Bufio Bufio->PATH; 25 if (bufio == nil) 26 fail("bad module", sys->sprint("uniq: cannot load %s: %r", Bufio->PATH)); 27 Iobuf: import bufio; 28 arg := load Arg Arg->PATH; 29 if (arg == nil) 30 fail("bad module", sys->sprint("uniq: cannot load %s: %r", Arg->PATH)); 31 32 uflag := 0; 33 dflag := 0; 34 arg->init(args); 35 while ((opt := arg->opt()) != 0) { 36 case opt { 37 'u' => 38 uflag = 1; 39 'd' => 40 dflag = 1; 41 * => 42 usage(); 43 } 44 } 45 args = arg->argv(); 46 if (len args > 1) 47 usage(); 48 if (args != nil) { 49 bio = bufio->open(hd args, Bufio->OREAD); 50 if (bio == nil) 51 fail("open file", sys->sprint("uniq: cannot open %s: %r\n", hd args)); 52 } else 53 bio = bufio->fopen(sys->fildes(0), Bufio->OREAD); 54 55 stdout := bufio->fopen(sys->fildes(1), Bufio->OWRITE); 56 if (!(uflag || dflag)) 57 uflag = dflag = 1; 58 prev := ""; 59 n := 0; 60 while ((s := bio.gets('\n')) != nil) { 61 if (s == prev) 62 n++; 63 else { 64 if ((uflag && n == 1) || (dflag && n > 1)) 65 stdout.puts(prev); 66 n = 1; 67 prev = s; 68 } 69 } 70 if ((uflag && n == 1) || (dflag && n > 1)) 71 stdout.puts(prev); 72 stdout.close(); 73} 74 75fail(ex, msg: string) 76{ 77 sys->fprint(sys->fildes(2), "%s\n", msg); 78 raise "fail:"+ex; 79} 80