OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 """ | 2 """ |
3 KVM test configuration file parser | 3 Cartesian configuration format file parser. |
| 4 |
| 5 Filter syntax: |
| 6 , means OR |
| 7 .. means AND |
| 8 . means IMMEDIATELY-FOLLOWED-BY |
| 9 |
| 10 Example: |
| 11 qcow2..Fedora.14, RHEL.6..raw..boot, smp2..qcow2..migrate..ide |
| 12 means match all dicts whose names have: |
| 13 (qcow2 AND (Fedora IMMEDIATELY-FOLLOWED-BY 14)) OR |
| 14 ((RHEL IMMEDIATELY-FOLLOWED-BY 6) AND raw AND boot) OR |
| 15 (smp2 AND qcow2 AND migrate AND ide) |
| 16 |
| 17 Note: |
| 18 'qcow2..Fedora.14' is equivalent to 'Fedora.14..qcow2'. |
| 19 'qcow2..Fedora.14' is not equivalent to 'qcow2..14.Fedora'. |
| 20 'ide, scsi' is equivalent to 'scsi, ide'. |
| 21 |
| 22 Filters can be used in 3 ways: |
| 23 only <filter> |
| 24 no <filter> |
| 25 <filter>: |
| 26 The last one starts a conditional block. |
4 | 27 |
5 @copyright: Red Hat 2008-2011 | 28 @copyright: Red Hat 2008-2011 |
6 """ | 29 """ |
7 | 30 |
8 import re, os, sys, optparse, collections | 31 import re, os, sys, optparse, collections |
9 | 32 |
10 | |
11 # Filter syntax: | |
12 # , means OR | |
13 # .. means AND | |
14 # . means IMMEDIATELY-FOLLOWED-BY | |
15 | |
16 # Example: | |
17 # qcow2..Fedora.14, RHEL.6..raw..boot, smp2..qcow2..migrate..ide | |
18 # means match all dicts whose names have: | |
19 # (qcow2 AND (Fedora IMMEDIATELY-FOLLOWED-BY 14)) OR | |
20 # ((RHEL IMMEDIATELY-FOLLOWED-BY 6) AND raw AND boot) OR | |
21 # (smp2 AND qcow2 AND migrate AND ide) | |
22 | |
23 # Note: | |
24 # 'qcow2..Fedora.14' is equivalent to 'Fedora.14..qcow2'. | |
25 # 'qcow2..Fedora.14' is not equivalent to 'qcow2..14.Fedora'. | |
26 # 'ide, scsi' is equivalent to 'scsi, ide'. | |
27 | |
28 # Filters can be used in 3 ways: | |
29 # only <filter> | |
30 # no <filter> | |
31 # <filter>: | |
32 # The last one starts a conditional block. | |
33 | |
34 | |
35 class ParserError: | 33 class ParserError: |
36 def __init__(self, msg, line=None, filename=None, linenum=None): | 34 def __init__(self, msg, line=None, filename=None, linenum=None): |
37 self.msg = msg | 35 self.msg = msg |
38 self.line = line | 36 self.line = line |
39 self.filename = filename | 37 self.filename = filename |
40 self.linenum = linenum | 38 self.linenum = linenum |
41 | 39 |
42 def __str__(self): | 40 def __str__(self): |
43 if self.line: | 41 if self.line: |
44 return "%s: %r (%s:%s)" % (self.msg, self.line, | 42 return "%s: %r (%s:%s)" % (self.msg, self.line, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 181 |
184 class NegativeCondition(OnlyFilter): | 182 class NegativeCondition(OnlyFilter): |
185 def __init__(self, line): | 183 def __init__(self, line): |
186 Filter.__init__(self, line.lstrip("!").rstrip(":")) | 184 Filter.__init__(self, line.lstrip("!").rstrip(":")) |
187 self.line = line | 185 self.line = line |
188 self.content = [] | 186 self.content = [] |
189 | 187 |
190 | 188 |
191 class Parser(object): | 189 class Parser(object): |
192 """ | 190 """ |
193 Parse an input file or string that follows the KVM Test Config File format | 191 Parse an input file or string that follows the Cartesian Config File format |
194 and generate a list of dicts that will be later used as configuration | 192 and generate a list of dicts that will be later used as configuration |
195 parameters by the KVM tests. | 193 parameters by autotest tests that use that format. |
196 | 194 |
197 @see: http://www.linux-kvm.org/page/KVM-Autotest/Test_Config_File | 195 @see: http://autotest.kernel.org/wiki/CartesianConfig |
198 """ | 196 """ |
199 | 197 |
200 def __init__(self, filename=None, debug=False): | 198 def __init__(self, filename=None, debug=False): |
201 """ | 199 """ |
202 Initialize the parser and optionally parse a file. | 200 Initialize the parser and optionally parse a file. |
203 | 201 |
204 @param filename: Path of the file to parse. | 202 @param filename: Path of the file to parse. |
205 @param debug: Whether to turn on debugging output. | 203 @param debug: Whether to turn on debugging output. |
206 """ | 204 """ |
207 self.node = Node() | 205 self.node = Node() |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 for i, d in enumerate(c.get_dicts()): | 687 for i, d in enumerate(c.get_dicts()): |
690 if options.fullname: | 688 if options.fullname: |
691 print "dict %4d: %s" % (i + 1, d["name"]) | 689 print "dict %4d: %s" % (i + 1, d["name"]) |
692 else: | 690 else: |
693 print "dict %4d: %s" % (i + 1, d["shortname"]) | 691 print "dict %4d: %s" % (i + 1, d["shortname"]) |
694 if options.contents: | 692 if options.contents: |
695 keys = d.keys() | 693 keys = d.keys() |
696 keys.sort() | 694 keys.sort() |
697 for key in keys: | 695 for key in keys: |
698 print " %s = %s" % (key, d[key]) | 696 print " %s = %s" % (key, d[key]) |
OLD | NEW |