|
1 # |
|
2 # Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # Raptor Binary Variation var file to xml spec generator |
|
16 # Given a set of .var files, this script will generate an xml specification file |
|
17 # |
|
18 |
|
19 |
|
20 import sys,os,re,fnmatch |
|
21 import xml.dom.minidom |
|
22 from optparse import OptionParser |
|
23 |
|
24 doc = xml.dom.minidom.Document() |
|
25 class VarFile: |
|
26 |
|
27 def __init__(self,aFile): |
|
28 self.virtual = False |
|
29 self.varname = "" |
|
30 self.varhrh = "" |
|
31 self.build_include = "" |
|
32 self.rom_include = "" |
|
33 self.extends = "" |
|
34 self.file = aFile |
|
35 |
|
36 # Parse the var file |
|
37 def ParseVarFile(self): |
|
38 file = open(self.file) |
|
39 vardata = file.readlines() |
|
40 for var in vardata: |
|
41 if re.match('VARIANT\s+(?P<VARIANTNAME>\w+)',var): |
|
42 self.varname = re.match('VARIANT\s+(?P<VARIANTNAME>\w+)',var) |
|
43 elif re.match('VARIANT_HRH\s+(?P<VARIANTHRH>.+)',var): |
|
44 self.varhrh = re.match('VARIANT_HRH\s+(?P<VARIANTHRH>.+)',var) |
|
45 elif re.match('VIRTUAL\s+$',var): |
|
46 self.virtual = True |
|
47 elif re.match('BUILD_INCLUDE\s+.+',var): |
|
48 self.build_include = re.match('BUILD_INCLUDE\s+(?P<PROPERTY>\w+)\s+(?P<LOCATION>.+)',var) |
|
49 elif re.match('ROM_INCLUDE\s+.+',var): |
|
50 self.rom_include = re.match('ROM_INCLUDE\s+(?P<PROPERTY>\w+)\s+(?P<LOCATION>.+)',var) |
|
51 elif re.match('EXTENDS\s+(?P<EXTENDS>\w+)',var): |
|
52 self.extends = re.match('EXTENDS\s+(?P<EXTENDSNODE>\w+)',var) |
|
53 if self.varname: |
|
54 self.varname = self.varname.group('VARIANTNAME') |
|
55 if self.varhrh: |
|
56 self.varhrh = self.varhrh.group('VARIANTHRH') |
|
57 if self.extends: |
|
58 self.extends = self.extends.group('EXTENDSNODE') |
|
59 file.close() |
|
60 |
|
61 # Write the specs for a variant object and attach it to a parent node |
|
62 def CreateSpec(self,parentNode): |
|
63 |
|
64 var = doc.createElement("var") |
|
65 parentNode.appendChild(var) |
|
66 |
|
67 # Set the FEATUREVARIANT name |
|
68 vname = doc.createElement("set") |
|
69 vname.setAttribute("name","FEATUREVARIANT") |
|
70 vname.setAttribute("value",self.varname) |
|
71 if self.virtual: |
|
72 vname.setAttribute("abstract","true") |
|
73 var.appendChild(vname) |
|
74 |
|
75 # Set the VARIANT_HRH name |
|
76 hrhname = doc.createElement("set") |
|
77 hrhname.setAttribute("name","VARIANT_HRH") |
|
78 hrhname.setAttribute("value",self.varhrh) |
|
79 var.appendChild(hrhname) |
|
80 |
|
81 # Set the build includes |
|
82 if self.build_include: |
|
83 buildincs = doc.createElement(self.build_include.group('PROPERTY')) |
|
84 buildincs.setAttribute("name","BUILD_INCLUDE") |
|
85 buildincs.setAttribute("value",self.build_include.group('LOCATION')) |
|
86 var.appendChild(buildincs) |
|
87 |
|
88 # Set the rom includes |
|
89 if self.rom_include: |
|
90 buildincs = doc.createElement(self.rom_include.group('PROPERTY')) |
|
91 buildincs.setAttribute("name","ROM_INCLUDE") |
|
92 buildincs.setAttribute("value",self.rom_include.group('LOCATION')) |
|
93 var.appendChild(buildincs) |
|
94 |
|
95 # Main function |
|
96 def main(): |
|
97 |
|
98 parser = OptionParser(prog = "vartoxml.py") |
|
99 parser.add_option("-s","--sourcefile",action="append",dest="varfile",help="List of var files") |
|
100 parser.add_option("-o","--output",action="store",dest="outputxml",help="Output xml file") |
|
101 parser.add_option("-d","--folder",action="store",dest="folder",help="Folder names to search for var files") |
|
102 |
|
103 (options, leftover_args) = parser.parse_args(sys.argv[1:]) |
|
104 |
|
105 childlist = [] |
|
106 addedlist = [] |
|
107 nodesList = [] |
|
108 childnames = [] |
|
109 i = 0 |
|
110 |
|
111 # Get the list of .var file from the specified folder(s) |
|
112 if options.folder: |
|
113 for folder in options.folder: |
|
114 for fileName in os.listdir (folder): |
|
115 if fnmatch.fnmatch (fileName,'*.var'): |
|
116 if options.varfile: |
|
117 options.varfile.append(fileName) |
|
118 else: |
|
119 options.varfile = [] |
|
120 options.varfile.append(fileName) |
|
121 |
|
122 # We need some source files for this script to work |
|
123 if not options.varfile: |
|
124 print "Error: No source files specified " |
|
125 sys.exit() |
|
126 |
|
127 # Set parent node to gibberish |
|
128 parentNode = doc.createElement("build") |
|
129 doc.appendChild(parentNode) |
|
130 newparentNode = "" |
|
131 |
|
132 # Removes duplicate elements in the arguments and iterate through them |
|
133 # to find the top-level abstract parent node |
|
134 for arg in list(set(options.varfile)): |
|
135 varobj = VarFile(arg) |
|
136 varobj.ParseVarFile() |
|
137 if varobj.extends: |
|
138 childlist.append(varobj) |
|
139 else: |
|
140 addedlist.append(varobj) |
|
141 conf = doc.createElement("config") |
|
142 conf.setAttribute("name",varobj.varname) |
|
143 parentNode.appendChild(conf) |
|
144 varobj.CreateSpec(conf) |
|
145 nodesList.append(conf) |
|
146 |
|
147 # Names of all the children need to be stored separately |
|
148 for c in childlist: |
|
149 childnames.append(c.varname) |
|
150 |
|
151 childlist2 = list(childlist) |
|
152 |
|
153 # Check the list is correct, and append orphan nodes to master BUILD node |
|
154 for ch in childlist2: |
|
155 if addedlist: |
|
156 if not ch.extends in addedlist[0].varname: |
|
157 if not ch.extends in childnames: |
|
158 conf = doc.createElement("config") |
|
159 conf.setAttribute("name",ch.varname) |
|
160 parentNode.appendChild(conf) |
|
161 varobj.CreateSpec(conf) |
|
162 nodesList.append(conf) |
|
163 addedlist.append(ch) |
|
164 childlist.remove(ch) |
|
165 else: |
|
166 if not ch.extends in childnames: |
|
167 conf = doc.createElement("config") |
|
168 conf.setAttribute("name",ch.varname) |
|
169 parentNode.appendChild(conf) |
|
170 varobj.CreateSpec(conf) |
|
171 nodesList.append(conf) |
|
172 addedlist.append(ch) |
|
173 childlist.remove(ch) |
|
174 |
|
175 # Make a copy of the new childlist |
|
176 childlist2 = list(childlist) |
|
177 |
|
178 # Go through all the children, and add them to the xml spec |
|
179 while (childlist2): |
|
180 # Refactor the childlist to remove elements which have been added |
|
181 for add in addedlist: |
|
182 if add in childlist: |
|
183 childlist.remove(add) |
|
184 for ch in childlist: |
|
185 if ch.extends == addedlist[i].varname: |
|
186 addedlist.append(ch) |
|
187 childlist2.remove(ch) |
|
188 conf = doc.createElement("config") |
|
189 conf.setAttribute("name",ch.varname) |
|
190 nodesList[i].appendChild(conf) |
|
191 nodesList.append(conf) |
|
192 ch.CreateSpec(conf) |
|
193 else: |
|
194 pass |
|
195 i = i + 1 |
|
196 |
|
197 # If output xml file is specified, write to it otherwise print the xml to screen |
|
198 if options.outputxml: |
|
199 file = open(options.outputxml,"w") |
|
200 file.writelines(doc.toprettyxml(indent=" ")) |
|
201 file.close() |
|
202 else: |
|
203 print doc.toprettyxml(indent=" ") |
|
204 |
|
205 |
|
206 if __name__ == "__main__": |
|
207 main() |