58: def parse_commands(data)
59: context = resource[:context]
60:
61: if (context.length > 0)
62: context << "/" if context[-1, 1] != "/"
63: end
64:
65: data = data.split($/) if data.is_a?(String)
66: data = data.flatten
67: args = []
68: data.each do |line|
69: line.strip!
70: next if line.nil? || line.empty?
71: argline = []
72: sc = StringScanner.new(line)
73: cmd = sc.scan(/\w+|==|!=/)
74: formals = COMMANDS[cmd]
75: fail("Unknown command #{cmd}") unless formals
76: argline << cmd
77: narg = 0
78: formals.each do |f|
79: sc.skip(/\s+/)
80: narg += 1
81: if f == :path
82: start = sc.pos
83: nbracket = 0
84: inSingleTick = false
85: inDoubleTick = false
86: begin
87: sc.skip(/([^\]\[\s\\'"]|\\.)+/)
88: ch = sc.getch
89: nbracket += 1 if ch == "["
90: nbracket -= 1 if ch == "]"
91: inSingleTick = !inSingleTick if ch == "'"
92: inDoubleTick = !inDoubleTick if ch == "\""
93: fail("unmatched [") if nbracket < 0
94: end until ((nbracket == 0 && !inSingleTick && !inDoubleTick && (ch =~ /\s/)) || sc.eos?)
95: len = sc.pos - start
96: len -= 1 unless sc.eos?
97: unless p = sc.string[start, len]
98: fail("missing path argument #{narg} for #{cmd}")
99: end
100:
101: p = p[1, (p.size - 2)] if p[0,1] == "'" || p[0,1] == "\""
102: p.chomp!("/")
103: if p[0,1] != '$' && p[0,1] != "/"
104: argline << context + p
105: else
106: argline << p
107: end
108: elsif f == :string
109: delim = sc.peek(1)
110: if delim == "'" || delim == "\""
111: sc.getch
112: argline << sc.scan(/([^\\#{delim}]|(\\.))*/)
113: sc.getch
114: else
115: argline << sc.scan(/[^\s]+/)
116: end
117: fail("missing string argument #{narg} for #{cmd}") unless argline[-1]
118: elsif f == :comparator
119: argline << sc.scan(/(==|!=|=~|<|<=|>|>=)/)
120: unless argline[-1]
121: puts sc.rest
122: fail("invalid comparator for command #{cmd}")
123: end
124: elsif f == :int
125: argline << sc.scan(/\d+/).to_i
126: elsif f== :glob
127: argline << sc.rest
128: end
129: end
130: args << argline
131: end
132: args
133: end