4151
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
1 import mx
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
2 import commands
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
3
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
4 class OutputParser:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
5
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
6 def __init__(self, nonZeroIsFatal=True):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
7 self.matchers = []
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
8 self.nonZeroIsFatal = nonZeroIsFatal
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
9
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
10 def addMatcher(self, matcher):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
11 self.matchers.append(matcher)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
12
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
13 def parse(self, cmd, cwd=None):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
14 ret = [{}]
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
15
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
16 def parseLine(line):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
17 line = line.strip()
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
18 anyMatch = False
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
19 for matcher in self.matchers:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
20 parsed = matcher.parse(line)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
21 if parsed:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
22 anyMatch = True
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
23 if matcher.startNewLine and len(ret[0]) > 0:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
24 ret.append({})
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
25 ret[len(ret)-1].update(parsed)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
26 if anyMatch :
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
27 mx.log(line)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
28 else :
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
29 mx.log('# ' + line)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
30
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
31 commands.vm(cmd, nonZeroIsFatal=self.nonZeroIsFatal, out=parseLine, err=parseLine, cwd=cwd)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
32 return ret
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
33
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
34 class Matcher:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
35
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
36 def __init__(self, regex, valuesToParse, startNewLine=False):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
37 assert isinstance(valuesToParse, dict)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
38 self.regex = regex
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
39 self.valuesToParse = valuesToParse
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
40 self.startNewLine = startNewLine
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
41
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
42 def parse(self, line):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
43 match = self.regex.search(line)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
44 if not match:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
45 return False
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
46 ret = {}
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
47 for key, value in self.valuesToParse.items():
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
48 ret[self.parsestr(match, key)] = self.parsestr(match, value)
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
49 return ret
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
50
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
51 def parsestr(self, match, key):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
52 if isinstance(key, tuple):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
53 if len(key) != 2:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
54 raise Exception('Tuple arguments must have a lenght of 2')
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
55 tup1, tup2 = key
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
56 # check if key is a function
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
57 if hasattr(tup1, '__call__'):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
58 return tup1(self.parsestr(match, tup2))
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
59 elif hasattr(tup2, '__call__'):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
60 return tup2(self.parsestr(match, tup1))
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
61 else:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
62 raise Exception('Tuple must contain a function pointer')
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
63 elif key.startswith('const:'):
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
64 return key.split(':')[1]
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
65 else:
|
Gilles Duboscq <gilles.m.duboscq@gmail.com>
parents:
diff
changeset
|
66 return match.group(key)
|