/
IO.winxed
130 lines (117 loc) · 3.61 KB
/
IO.winxed
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
125
126
127
128
129
130
/* Rosella IO Routines
These are convenience routines for doing some common IO-related tasks
in Rosella.
*/
namespace Rosella.IO
{
// swap the interpreter standard input, error and output handles with
// a named hash of replacements. Return a hash of the previous values
// by name
function swap_handles(var handles)
{
var save_handles = {};
var interp = getinterp();
if (exists handles["stderr"]) {
save_handles["stderr"] = interp.stderr_handle();
interp.stderr_handle(handles["stderr"]);
}
if (exists handles["stdin"]) {
save_handles["stdin"] = interp.stdin_handle();
interp.stdin_handle(handles["stdin"]);
}
if (exists handles["stdout"]) {
save_handles["stdout"] = interp.stdout_handle();
interp.stdout_handle(handles["stdout"]);
}
return save_handles;
}
function capture_output(int together, var func, var err_func = null)
{
var stdout = new "StringHandle";
stdout.open("blah", "rw");
var stderr;
if (together)
stderr = stdout;
else {
stderr = new "StringHandle";
stderr.open("blah", "rw");
}
var exception = null;
var save_handles = swap_handles({"stdout" : stdout, "stderr" : stderr});
string msg;
try {
func();
} catch(e) {
exception = e;
}
swap_handles(save_handles);
if (exception != null && err_func != null)
err_func(exception);
if (together)
return stdout;
else
return stdout, stderr;
}
function execute_pipe(string cmd, var on_err = null)
{
var pipe = open_pipe(cmd);
string output = pipe.readall();
int exit_status = close_pipe(pipe);
if (exit_status != 0 && on_err != null)
on_err(exit_status);
return output;
}
// Open a pipe to execute a child program. Return the pipe
function open_pipe(string cmd)
{
var pipe = new "FileHandle";
pipe.encoding('utf8');
pipe.open(cmd, "rp");
return pipe;
}
// Close the pipe. Don't worry about flushing the buffer or checking
// if we have unread data. The user should be aware of that before
// calling this.
function close_pipe(var pipe)
{
pipe.close();
int exit_status = pipe.exit_status();
return exit_status;
}
// Spawn and execute a child program, as an array of strings. Return the
// return value.
function spawn(var cmd)
{
int retval;
${ spawnw retval, cmd };
return (retval >> 8) & 0xFF;
}
// Spawn and execute a child program as a single string with all arguments.
// Return the return value.
function spawn(string cmd)
{
int retval;
${ spawnw retval, cmd };
return (retval >> 8) & 0xFF;
}
/* Convenience routines for performing formatted output
*/
// Say. Print with a trailing newline
function sayf(string fmt, var args[slurpy], var handle[named,optional], int has_h [opt_flag])
{
string msg = sprintf(fmt, args);
if (!has_h || handle == null)
say(msg);
else
handle.print(msg + "\n");
}
// Print with a trailing newline
function printf(string fmt, var args[slurpy], var handle[named,optional], int has_h [opt_flag])
{
string msg = sprintf(fmt, args);
if (!has_h || handle == null)
print(msg);
else
handle.print(msg);
}
}