summaryrefslogtreecommitdiff
path: root/appl/alphabet/grid/line2rec.b
blob: 2429a67dfb21764c588e38dcf456d2a4da88f573 (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
implement Line2rec, Gridmodule;
include "sys.m";
	sys: Sys;
include "draw.m";
include "sh.m";
include "bufio.m";
	bufio: Bufio;
	Iobuf: import bufio;
include "alphabet/reports.m";
	reports: Reports;
		Report, report: import reports;
include "alphabet/endpoints.m";
include "alphabet/grid.m";
	grid: Grid;
	Value: import grid;

Line2rec: module {};

types(): string
{
	return "bf";
}

init()
{
	sys = load Sys Sys->PATH;
	grid = load Grid Grid->PATH;
	reports = load Reports Reports->PATH;
	bufio = load Bufio Bufio->PATH;
}

quit()
{
}

run(nil: chan of string, r: ref Report,
		nil: list of (int, list of ref Value), args: list of ref Value): ref Value
{
	f := chan of ref Sys->FD;
	spawn line2recproc((hd args).f().i, f, r.start("line2rec"));
	return ref Value.Vb(f);
}

line2recproc(
	f0,
	f1: chan of ref Sys->FD,
	errorc: chan of string)
{
	(fd0, fd1) := startfilter(f0, f1, errorc);
	iob0 := bufio->fopen(fd0, Sys->OREAD);
	iob1 := bufio->fopen(fd1, Sys->OWRITE);
	{
		while((s := iob0.gets('\n')) != nil){
			d := array of byte s;
			if(iob1.puts("data "+string len d) < 0)
				break;
			if(iob1.write(d, len d) != len d)
				break;
		}
		iob1.flush();
		sys->fprint(fd1, "");
	}exception{
	"write on closed pipe" =>
		;
	}
	reports->quit(errorc);
}

# read side (when it's an argument):
# 	read proposed new fd
# 	write actual fd for them to write to (creating pipe in necessary)
# 
# write side (when you're returning it):
# 	write a proposed new fd (or nil if no suggestion)
# 	read actual fd for writing
startfilter(f0, f1: chan of ref Sys->FD, errorc: chan of string): (ref Sys->FD, ref Sys->FD)
{
	f1 <-= nil;
	if((fd1 := <-f1) == nil){
		<-f0;
		f0 <-= nil;
		reports->quit(errorc);
	}
	if((fd0 := <-f0) == nil){
		sys->pipe(p := array[2] of ref Sys->FD);
		f0 <-= p[1];
		fd0 = p[0];
	}else
		f0 <-= nil;
	return (fd0, fd1);
}