Skip to content

Commit 0bc3c19

Browse files
committed
process: added here-strings, more redir operators
1 parent 7fac72b commit 0bc3c19

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

base/export.jl

+5
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ export
302302
.>>,
303303
.<<,
304304
>>>,
305+
<<<,
306+
&>,
307+
&>>,
308+
&<,
309+
&<<,
305310
\,
306311
^,
307312
|,

base/process.jl

+46-13
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,10 @@ fd(sink::FileSink) = fd(sink.s)
193193

194194
type Cmd
195195
exec::Executable
196+
name::String
196197
pipes::Dict{FileDes,PipeEnd}
197198
sinks::Dict{FileDes,FileSink}
199+
closed_fds::Vector{FileDes}
198200
pipeline::Set{Cmd}
199201
pid::Int32
200202
status::ProcessStatus
@@ -205,8 +207,10 @@ type Cmd
205207
error("Cmd: too few words to exec")
206208
end
207209
this = new(exec,
210+
"",
208211
Dict{FileDes,PipeEnd}(),
209212
Dict{FileDes,FileSink}(),
213+
FileDes[],
210214
Set{Cmd}(),
211215
0,
212216
ProcessNotRun(),
@@ -226,7 +230,9 @@ setsuccess(cmd::Cmd, f::Function) = (cmd.successful=f; cmd)
226230
ignorestatus(cmd::Cmd) = setsuccess(cmd, ignore_success)
227231

228232
function show(io, cmd::Cmd)
229-
if isa(cmd.exec,Vector{ByteString})
233+
if cmd.name != ""
234+
show(io, cmd.name)
235+
elseif isa(cmd.exec,Vector{ByteString})
230236
esc = shell_escape(cmd.exec...)
231237
print(io, '`')
232238
for c in esc
@@ -237,7 +243,7 @@ function show(io, cmd::Cmd)
237243
end
238244
print(io, '`')
239245
else
240-
invoke(show, (Any,), cmd.exec)
246+
invoke(show, (Any, Any,), io, cmd.exec)
241247
end
242248
end
243249

@@ -257,7 +263,7 @@ type Port
257263
end
258264

259265
function fd(cmd::Cmd, f::FileDes)
260-
if !has(cmd.pipes, f) && !has(cmd.sinks, f)
266+
if !has(cmd.pipes, f) && !has(cmd.sinks, f) && !contains(cmd.closed_fds, f)
261267
return Port(cmd,f)
262268
end
263269
error("no ", f, " available in ", cmd)
@@ -266,12 +272,12 @@ end
266272
function fd(cmds::Set{Cmd}, f::FileDes)
267273
set = Set{Port}()
268274
for cmd in cmds
269-
if !has(cmd.pipes, f) && !has(cmd.sinks, f)
275+
if !has(cmd.pipes, f) && !has(cmd.sinks, f) && !contains(cmd.closed_fds, f)
270276
add(set, fd(cmd,f))
271277
end
272278
end
273279
if isempty(set)
274-
error("no ", f, " available: ", cmds)
280+
error("no ", f, " available in ", cmds)
275281
end
276282
set
277283
end
@@ -320,6 +326,9 @@ end
320326
output(cmds::Cmds) = stdout(cmds) & stderr(cmds)
321327

322328
function connect(port::Port, pend::PipeEnd)
329+
if contains(port.cmd.closed_fds, port.fd)
330+
error(port.cmd, " port ", port.fd, " is closed")
331+
end
323332
if !has(port.cmd.pipes, port.fd) && !has(port.cmd.sinks, port.fd)
324333
port.cmd.pipes[port.fd] = pend
325334
elseif has(port.cmd.pipes, port.fd) && port.cmd.pipes[port.fd] != pend
@@ -392,6 +401,7 @@ function redir(ports::Ports, sink::FileSink)
392401
end
393402
end
394403

404+
# redirect stdout
395405
function (>)(src::String, dst::Cmds)
396406
redir(stdin(dst), FileSink(src, "r"))
397407
return dst
@@ -426,6 +436,7 @@ end
426436

427437
(<)(dst::IOStream, src::Cmds) = (>)(src, dst)
428438

439+
# redirect stderr
429440
function (.>)(src::Cmds, dst::String)
430441
redir(stderr(src), FileSink(dst, "w"))
431442
return src
@@ -446,15 +457,37 @@ end
446457

447458
(.<)(dst::IOStream, src::Cmds) = (.>)(src, dst)
448459

449-
#TODO: here-strings
450-
#function (>>>)(src::String, dst::Cmds)
451-
#redir(stdin(dst), FileSink(src, "r"))
452-
#return dst
453-
#end
454-
#
455-
#(<<<)(dst::Cmds, src::String) = (>>>)(src, dst)
460+
# redirect both stdout and stderr
461+
function (&>)(src::Cmds, dst::String)
462+
redir(output(src), FileSink(dst, "w"))
463+
return src
464+
end
465+
466+
function (&>>)(src::Cmds, dst::String)
467+
redir(output(src), FileSink(dst, "a"))
468+
return src
469+
end
456470

471+
(&<)(dst::String, src::Cmds) = (&>)(src, dst)
472+
(&<<)(dst::String, src::Cmds) = (&>>)(src, dst)
473+
474+
function (&>)(src::Cmds, dst::IOStream)
475+
redir(output(src), FileSink(dst))
476+
return src
477+
end
478+
479+
(&<)(dst::IOStream, src::Cmds) = (&>)(src, dst)
480+
481+
# here-strings:
482+
function (>>>)(src::String, dst::Cmds)
483+
hscmd = Cmd(()->print(src))
484+
push(hscmd.closed_fds, STDIN)
485+
push(hscmd.closed_fds, STDERR)
486+
hscmd.name = "here-string<" * src * ">"
487+
return hscmd | dst
488+
end
457489

490+
(<<<)(dst::Cmds, src::String) = (>>>)(src, dst)
458491

459492

460493
# spawn(cmd) starts all processes connected to cmd
@@ -508,7 +541,7 @@ function spawn(cmd::Cmd)
508541
println(stderr_stream, "dup: ", strerror())
509542
exit(0x7f)
510543
end
511-
bk_stderr_stream = fdio(bk_stderr_fd, true)
544+
bk_stderr_stream = fdio(bk_stderr_fd)
512545

513546
# now actually do the fork and exec without writes
514547
pid = fork()

src/julia-parser.scm

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
; the way the lexer works, every prefix of an operator must also
88
; be an operator.
99
(<- -- -->)
10-
(> < >= <= == === != |.>| |.<| |.>=| |.<=| |.==| |.!=| |.=| |.!| |<:| |>:|)
10+
(> < >= <= == === != |.>| |.<| |.>=| |.<=| |.==| |.!=| |.=| |.!| |<:| |>:| |&>| |&<|)
1111
(: |..|)
1212
(+ - |.+| |.-| |\|| $)
13-
(<< >> >>> |.<<| |.>>|)
13+
(<< >> <<< >>> |.<<| |.>>| |&>>| |&<<|)
1414
(* / |./| % & |.*| |\\| |.\\|)
1515
(// .//)
1616
(^ |.^|)

0 commit comments

Comments
 (0)