summaryrefslogtreecommitdiff
path: root/lib/gitano/util.lua
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
}