-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathedp.nt
64 lines (60 loc) · 1.66 KB
/
edp.nt
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
module edp;
import std.string, std.file, std.process;
import c.unistd;
import c.poll, c.stdlib;
template process(T) {
class ProcessorError : Error { void init() super.init "ProcessorError"; }
class processor {
T source;
char[auto~] buffer;
string[auto~] yieldbuf;
bool done;
int readTo(string marker) {
int pos;
do pos = buffer[].find marker;
while pos == -1 {
if (auto sup <- source) { buffer ~= char[]:sup; }
else { done = true; return 0; }
}
return pos;
}
string value;
bool advance() {
if (yieldbuf.length) {
(value, yieldbuf) = (yieldbuf[0], string[auto~]:yieldbuf[1 .. $]);
return true;
}
if (done) return false;
int startpos = readTo "<?exec ";
if !startpos {
(value, buffer) = (buffer[], char[auto~]:new char[] 0);
return eval value.length;
}
int endpos = readTo "</exec?>";
if !endpos {
writeln "No closing exec tag! ";
raise new ProcessorError;
}
(string pre, string main, string post)
= buffer[(0..startpos, startpos + 7 .. endpos, endpos + 8 .. $)];
if (main.find ">" == -1) {
writeln "No > in \"$main\". ";
raise (new ProcessorError);
}
auto cmd = slice (&main, ">");
auto text = join readback ("sh", ["-c", cmd], main);
yieldbuf ~= pre;
yieldbuf ~= text;
buffer = char[auto~]:post;
return advance();
}
}
processor process(T src) using new processor {
source = src;
return that;
}
}
void main() {
auto stdin = readfile 0, stdout = writefile 1;
while (auto entry <- process stdin) stdout byte[]:entry;
}