fixing stuff
[dyninst.git] / testsuite / src / specification / tuples.py
1 # PLList -> []
2 # PLList -> [ List ]
3 # List -> Element
4 # List -> Element , List
5 # Element -> QString
6 # Element -> PLList
7 # QString -> ' string '
8 # QString -> string
9
10 def parse_pllist(pllist):
11         if (pllist == '[]'):
12                 return []
13         else:
14                 return parse_list(pllist[1:-1])
15
16 def find_matching_close(search_string):
17         # Precondition: search_string starts with '['
18         # Keep reading characters from search_string, incrementing a counter for
19         # each '[' seen, and decrementing for each ']' seen.  Stop when the counter
20         # reaches 0 and return the index of the ']' that decremented the counter
21         count = 0
22         index = 0
23         while True:
24                 if (search_string[index:index + 1] == '['):
25                         count = count + 1
26                 elif (search_string[index:index + 1] == ']'):
27                         count = count - 1
28                 index = index + 1
29                 if (count == 0):
30                         return index
31
32 # FIXME This function assumes that string elements do not contain single quotes
33 def parse_list(list):
34         elements = []
35         start = 0
36         while (list[start:] != ''):
37                 # does the first element start with a '['?
38                 if (list[start:start + 1] == '['):
39                         # We've got a list for the first element; find the matching close
40                         # bracket and parse it as a list
41                         matching_close = find_matching_close(list[start:])
42                         elements.append(parse_element(list[start:start+matching_close]))
43                         start = start + matching_close + 1
44                 elif list[start:start + 1] == "'":
45                         # First element in the list is within quotes
46                         matching_quote = list[start+1:].find("'") + 1
47                         elements.append(parse_qstring(list[start:start+matching_quote+1]))
48                         start = start + matching_quote + 2
49                 else:
50                         # Find the comma that signifies the end of this element
51                         next_element = list[start:].find(',')
52                         if (next_element == -1):
53                                 # This was the last element in the list
54                                 elements.append(parse_element(list[start:]))
55                                 start = start + len(list[start:])
56                         else:
57                                 elements.append(parse_element(list[start:start+next_element]))
58                                 start = start + next_element + 1
59         return elements
60
61 def parse_element(element):
62         if ((element[:1] == '[') and (element[-1:] == ']')):
63                 return parse_pllist(element)
64         else:
65                 return parse_qstring(element)
66
67 def parse_qstring(qstring):
68         if (qstring[:1] == qstring[-1:] == "'"):
69                 return qstring[1:-1]
70         else:
71                 return qstring
72
73 # The following three functions take a list of lists ("tuples") as their
74 # arguments, and return a list of dictionaries.  I figure that the dictionaries
75 # will make it easier to access the values of the tuples.
76
77 def parse_platforms(tuplestring):
78         plat_list = parse_pllist(tuplestring)
79         plat_labels = ('name', 'filename_conventions', 'linker', 'auxilliary_compilers',
80                                    'abis')
81         def convert_tuple(ptup):
82                 [pl, os, es, lp, ls, l, ac, as1] = ptup
83                 conv_labels = ('object_suffix', 'executable_suffix',
84                                            'library_prefix', 'library_suffix')
85                 fnconv = dict(zip(conv_labels, [os, es, lp, ls]))
86                 return [pl, fnconv, l, dict(ac), as1]
87         plat_map = map(lambda x: dict(zip(plat_labels, convert_tuple(x))),
88                                    plat_list)
89         return plat_map
90
91 def parse_languages(tuplestring):
92         lang_list = parse_pllist(tuplestring)
93         return map(lambda x: dict(zip(('name', 'extensions'), x)), lang_list)
94
95 def parse_mutators(tuplestring):
96         mutator_list = parse_pllist(tuplestring)
97         return map(lambda x: dict(zip(('name','sources','libraries','platform','compiler'), x)), mutator_list)
98
99 def parse_mutatees(tuplestring):
100         mutatee_labels = ('name', 'preprocessed_sources', 'raw_sources',
101                                           'libraries', 'platform', 'abi', 'compiler',
102                                           'optimization', 'groupable', 'module', 'format')
103         mutatee_list = parse_pllist(tuplestring)
104         return map(lambda x: dict(zip(mutatee_labels, x)), mutatee_list)
105
106 def parse_tests(tuplestring):
107         test_list = parse_pllist(tuplestring)
108         return map(lambda x: dict(zip(('name','mutator','mutatee','groupable', 'module'), x)), test_list)
109
110 def parse_compilers(tuplestring):
111         compiler_tuple_labels = ('executable', 'defstring', 'platforms',
112                                                          'presencevar', 'optimization', 'parameters',
113                                                          'languages', 'flags', 'abiflags', 'staticlink',
114                                                          'dynamiclink', 'platform')
115         compiler_list = parse_pllist(tuplestring)
116         compiler_dict = dict(map(lambda x: (x[0], dict(zip(compiler_tuple_labels,x[1:]))), compiler_list))
117         for c in compiler_dict:
118                 compiler_dict[c]['optimization'] = dict(compiler_dict[c]['optimization'])
119                 compiler_dict[c]['parameters'] = dict(compiler_dict[c]['parameters'])
120                 compiler_dict[c]['flags'] = dict(zip(('std', 'mutatee', 'link'), compiler_dict[c]['flags']))
121                 abiflags = {}
122                 for p in compiler_dict[c]['platforms']:
123                         abis = filter(lambda af: af[0] == p, compiler_dict[c]['abiflags'])
124                         abidict = {}
125                         for a in abis:
126                                 abidict[a[1]] = a[2]
127                         abiflags[p] = abidict
128                 compiler_dict[c]['abiflags'] = abiflags
129         return compiler_dict
130
131 def parse_rungroups(tuplestring):
132         rungroups_tuple_labels = ('mutatee', 'compiler', 'optimization',
133                                                           'run_mode', 'start_state', 'groupable', 'tests',
134                                                           'abi', 'thread_mode', 'process_mode', 'format')
135         rungroups_list = parse_pllist(tuplestring)
136         return map(lambda x: dict(zip(rungroups_tuple_labels, x)), rungroups_list)
137
138 # I want this one to return a dictionary mapping the name of an exception type
139 # to a list containing the names of its parameters
140 # NOTE: This function is not used
141 def parse_exception_types(tuplestring):
142         exception_type_list = parse_pllist(tuplestring)
143         exceptions = map(lambda et: [et[0], et[2]], exception_type_list)
144         return dict(exceptions)
145
146 # I want this to return a dictionary mapping the name of a file to a dictionary
147 # mapping each exception type applied to the file to that exception's
148 # parameters
149 # NOTE: This function is not used
150 def parse_exceptions(tuplestring):
151         exception_list = parse_pllist(tuplestring)
152         # Collect the names of the files with exceptions
153         excepted_files = []
154         for e in exception_list:
155                 if e[0] not in excepted_files:
156                         excepted_files += [e[0]]
157         # TODO Build an exception map for each file in excepted_files
158         exceptions = {}
159         for f in excepted_files:
160                 es = filter(lambda e: e[0] == f, exception_list)
161                 em = {}
162                 for e in es:
163                         if e[1] in em:
164                                 em[e[1]] += [dict(zip(e[2], e[3]))]
165                         else:
166                                 em[e[1]] = [dict(zip(e[2], e[3]))]
167                 exceptions[f] = em
168         return exceptions
169
170 def parse_object_files(tuplestring):
171         object_list = parse_pllist(tuplestring)
172         object_labels = ('object', 'compiler', 'sources', 'intermediate_sources',
173                                          'dependencies',
174                                          'flags')
175         return map(lambda o: dict(zip(object_labels, o)), object_list)