blob: 8d594d7fa0ba8cfd973046d5111a68f05d680d03 (
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
92
93
94
95
|
-- legit.util
--
-- Low level utility routines for Legit
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--
local function _deep_copy(t, memo)
if not memo then memo = {} end
if memo[t] then return memo[t] end
local ret = {}
local kk, vv
for k, v in pairs(t) do
kk, vv = k, v
if type(k) == "table" then
kk = _deep_copy(k)
end
if type(v) == "table" then
vv = _deep_copy(v)
end
ret[kk] = vv
end
return ret
end
local function _parse_cmdline(cmdline)
local r = {}
local acc = ""
local c
local escaping = false
local quoting = false
while #cmdline > 0 do
c, cmdline = cmdline:match("^(.)(.*)$")
if escaping then
if c == "n" then
acc = acc .. "\n"
elseif c == "t" then
acc = acc .. "\t"
else
acc = acc .. c
end
escaping = false
else
if c == "'" and quoting == false then
-- Start single quotes
quoting = c
elseif c == '"' and quoting == false then
-- Start double quotes
quoting = c
elseif c == "'" and quoting == c then
-- End single quotes
quoting = false
elseif c == '"' and quoting == c then
-- End double quotes
quoting = false
elseif c == "\\" then
-- A backslash, entering escaping mode
escaping = true
elseif quoting then
-- Within quotes, so accumulate
acc = acc .. c
elseif c == " " then
-- A space and not quoting, so clear the accumulator
if acc ~= "" then
r[#r+1] = acc
end
acc = ""
else
acc = acc .. c
end
end
end
if acc ~= "" then
r[#r+1] = acc
end
local warnings = {}
if quoting then
warnings[#warnings+1] = "Un-terminated quoted string"
end
if escaping then
warnings[#warnings+1] = "Un-used escape at end"
end
if #r == 0 then
warnings[#warnings+1] = "No command found?"
end
return r, warnings
end
return {
parse_cmdline = _parse_cmdline,
deep_copy = _deep_copy
}
|