mirror of
https://github.com/natnat-mc/moonbuild
synced 2026-07-06 15:37:13 +02:00
v2
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import gsub, sub, match from string
|
||||
import concat from table
|
||||
|
||||
specialchars =
|
||||
'\"': '\\\"'
|
||||
'\\': '\\\\'
|
||||
'\'': '\\\''
|
||||
'\n': '\\n'
|
||||
'\r': '\\r'
|
||||
'\t': '\\t'
|
||||
|
||||
replacespecialchar = (c) -> specialchars[c] or c
|
||||
|
||||
escape = (arg) ->
|
||||
return arg if match arg, "^[a-zA-Z0-9_.-]+$"
|
||||
'"'..(gsub arg, "([\"\\\n\r\t])", replacespecialchar)..'"'
|
||||
|
||||
parseargs = (argstr) ->
|
||||
state = 'normal'
|
||||
current, ci = {}, 1
|
||||
args, ai = {}, 1
|
||||
c = nil
|
||||
i = 0
|
||||
running = true
|
||||
|
||||
add = ->
|
||||
current[ci], ci = c, ci+1
|
||||
push = ->
|
||||
args[ai], ai, current, ci = (concat current), ai+1, {}, 1 if ci!=1
|
||||
addv = (v) ->
|
||||
current[ci], ci = v, ci+1
|
||||
fail = (msg) ->
|
||||
error "failed to parse: #{msg} in state #{state} at pos #{i}", 2
|
||||
finish = ->
|
||||
running = false
|
||||
EOF = ''
|
||||
|
||||
while running
|
||||
i += 1
|
||||
c = sub argstr, i, i
|
||||
|
||||
switch state
|
||||
when 'normal'
|
||||
switch c
|
||||
when '\"'
|
||||
state = 'doublequote'
|
||||
when '\''
|
||||
state = 'singlequote'
|
||||
when ' '
|
||||
push!
|
||||
when '\n'
|
||||
push!
|
||||
when '\t'
|
||||
push!
|
||||
when '\\'
|
||||
state = 'backslashnormal'
|
||||
when EOF
|
||||
push!
|
||||
finish!
|
||||
else
|
||||
add!
|
||||
|
||||
when 'doublequote'
|
||||
switch c
|
||||
when '\"'
|
||||
state = 'normal'
|
||||
when '\\'
|
||||
state = 'backslashdoublequote'
|
||||
when EOF
|
||||
fail "unexpected EOF"
|
||||
else
|
||||
add!
|
||||
|
||||
when 'singlequote'
|
||||
switch c
|
||||
when '\''
|
||||
state = 'normal'
|
||||
when EOF
|
||||
fail "unexpected EOF"
|
||||
else
|
||||
add!
|
||||
|
||||
when 'backslashnormal'
|
||||
switch c
|
||||
when '\n'
|
||||
state = 'normal'
|
||||
when EOF
|
||||
fail "unexpected EOF"
|
||||
else
|
||||
add!
|
||||
state = 'normal'
|
||||
|
||||
when 'backslashdoublequote'
|
||||
switch c
|
||||
when '$'
|
||||
add!
|
||||
state = 'doublequote'
|
||||
when '`'
|
||||
add!
|
||||
state = 'doublequote'
|
||||
when '\"'
|
||||
add!
|
||||
state = 'doublequote'
|
||||
when '\\'
|
||||
add!
|
||||
state = 'doublequote'
|
||||
when '\n'
|
||||
state = 'doublequote'
|
||||
when EOF
|
||||
fail "unexpected EOF"
|
||||
else
|
||||
addv '\\'
|
||||
add!
|
||||
state = 'doublequote'
|
||||
|
||||
args
|
||||
|
||||
{
|
||||
:escape
|
||||
:parseargs
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import escape from require 'moonbuild._cmd.common'
|
||||
import flatten from require 'moonbuild._common'
|
||||
import execute from require 'moonbuild.compat.execute'
|
||||
import popen from io
|
||||
import concat from table
|
||||
|
||||
cmdline = (...) ->
|
||||
concat [escape arg for arg in *flatten ...], ' '
|
||||
|
||||
cmd = (...) ->
|
||||
ok, ret, code = execute cmdline ...
|
||||
error "command #{first ...} exited with #{code} (#{ret})" unless ok
|
||||
|
||||
cmdrst = (...) ->
|
||||
fd, err = popen cmdline ...
|
||||
error err unless fd
|
||||
data = fd\read '*a'
|
||||
fd\close!
|
||||
data
|
||||
|
||||
sh = (cli) ->
|
||||
ok, ret, code = execute cli
|
||||
error "command '#{cli}' exited with #{code} (#{ret})" unless ok
|
||||
|
||||
{
|
||||
:cmd
|
||||
:cmdrst
|
||||
:sh
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import spawn from require 'posix'
|
||||
import fork, execp, pipe, dup2, _exit, close from require 'posix.unistd'
|
||||
import fdopen from require 'posix.stdio'
|
||||
import wait from require 'posix.sys.wait'
|
||||
import flatten, first from require 'moonbuild._common'
|
||||
import remove from table
|
||||
|
||||
cmd = (...) ->
|
||||
code, ty = spawn flatten ...
|
||||
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
|
||||
|
||||
cmdrst = (...) ->
|
||||
rd, wr = pipe!
|
||||
pid, err = fork!
|
||||
|
||||
if pid == 0
|
||||
dup2 wr, 1
|
||||
close rd
|
||||
args = flatten ...
|
||||
c = remove args, 1
|
||||
execp c, args
|
||||
return _exit 1
|
||||
|
||||
if pid == nil
|
||||
close rd
|
||||
close wr
|
||||
error "command #{first ...} failed to start: couldn't fork(): #{err}"
|
||||
|
||||
close wr
|
||||
fd = fdopen rd, 'r'
|
||||
data = fd\read '*a'
|
||||
fd\close!
|
||||
close rd
|
||||
|
||||
_, ty, code = wait pid
|
||||
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
|
||||
data
|
||||
|
||||
sh = (cli) ->
|
||||
cmd 'sh', '-c', cli
|
||||
|
||||
{
|
||||
:cmd
|
||||
:cmdrst
|
||||
:sh
|
||||
}
|
||||
Reference in New Issue
Block a user