xref: /inferno-os/appl/cmd/uniq.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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