summaryrefslogtreecommitdiff
path: root/appl/cmd/comm.b
blob: 1e56310e087e30a7ba14660b0f0a75cb0bfa4a5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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";
}