sbsv2/raptor/bin/vartoxml.py
author timothy.murphy@nokia.com
Thu, 25 Mar 2010 13:43:28 +0000
branchfix
changeset 408 a819f9223567
parent 3 e1eecf4d390d
permissions -rw-r--r--
fix: stop using "magic" numbers in string operations for the copyannofile2log feature fix: When using the copylogfromannofile workaround, extract the build ID and build duration and add to the log as these are useful for analysis. The log should now be identical to the stdout file. fix: Remove extra blank lines from output in copylogfromannofile mode.

#
# Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "Eclipse Public License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
# Initial Contributors:
# Nokia Corporation - initial contribution.
#
# Contributors:
#
# Description: 
# Raptor Binary Variation var file to xml spec generator
# Given a set of .var files, this script will generate an xml specification file
#


import sys,os,re,fnmatch
import xml.dom.minidom 
from optparse import OptionParser

doc = xml.dom.minidom.Document()
class VarFile:

	def __init__(self,aFile):
		self.virtual = False
		self.varname = ""
		self.varhrh = ""
		self.build_include = ""
		self.rom_include = ""
		self.extends = ""
		self.file = aFile

	# Parse the var file
	def ParseVarFile(self):
		file = open(self.file)
		vardata = file.readlines()
		for var in vardata:
			if re.match('VARIANT\s+(?P<VARIANTNAME>\w+)',var):
				self.varname = re.match('VARIANT\s+(?P<VARIANTNAME>\w+)',var)
			elif re.match('VARIANT_HRH\s+(?P<VARIANTHRH>.+)',var):
				self.varhrh  = re.match('VARIANT_HRH\s+(?P<VARIANTHRH>.+)',var)
			elif re.match('VIRTUAL\s+$',var):
				self.virtual = True
			elif re.match('BUILD_INCLUDE\s+.+',var):
				self.build_include = re.match('BUILD_INCLUDE\s+(?P<PROPERTY>\w+)\s+(?P<LOCATION>.+)',var)
			elif re.match('ROM_INCLUDE\s+.+',var):
				self.rom_include = re.match('ROM_INCLUDE\s+(?P<PROPERTY>\w+)\s+(?P<LOCATION>.+)',var)
			elif re.match('EXTENDS\s+(?P<EXTENDS>\w+)',var):
				self.extends = re.match('EXTENDS\s+(?P<EXTENDSNODE>\w+)',var)
		if self.varname:
			self.varname = self.varname.group('VARIANTNAME')
		if self.varhrh:
			self.varhrh  = self.varhrh.group('VARIANTHRH')
		if self.extends:
			self.extends = self.extends.group('EXTENDSNODE')
		file.close()
	
	# Write the specs for a variant object and attach it to a parent node
	def CreateSpec(self,parentNode):
	
		var = doc.createElement("var")
		parentNode.appendChild(var)

		# Set the FEATUREVARIANT name
		vname = doc.createElement("set")
		vname.setAttribute("name","FEATUREVARIANT")
		vname.setAttribute("value",self.varname)
		if self.virtual:
			vname.setAttribute("abstract","true")
		var.appendChild(vname)

		# Set the VARIANT_HRH name
		hrhname = doc.createElement("set")
		hrhname.setAttribute("name","VARIANT_HRH")
		hrhname.setAttribute("value",self.varhrh)
		var.appendChild(hrhname)

		# Set the build includes
		if self.build_include:
			buildincs = doc.createElement(self.build_include.group('PROPERTY'))
			buildincs.setAttribute("name","BUILD_INCLUDE")
			buildincs.setAttribute("value",self.build_include.group('LOCATION'))
			var.appendChild(buildincs)

		# Set the rom includes
		if self.rom_include:
			buildincs = doc.createElement(self.rom_include.group('PROPERTY'))
			buildincs.setAttribute("name","ROM_INCLUDE")
			buildincs.setAttribute("value",self.rom_include.group('LOCATION'))
			var.appendChild(buildincs)

# Main function
def main():

	parser = OptionParser(prog = "vartoxml.py")
	parser.add_option("-s","--sourcefile",action="append",dest="varfile",help="List of var files")
	parser.add_option("-o","--output",action="store",dest="outputxml",help="Output xml file")
	parser.add_option("-d","--folder",action="store",dest="folder",help="Folder names to search for var files")

	(options, leftover_args) = parser.parse_args(sys.argv[1:])
	
	childlist = [] 
	addedlist = []
	nodesList = []
	childnames = []
	i = 0
	
	# Get the list of .var file from the specified folder(s)
	if options.folder:
		for folder in options.folder:
			for fileName in os.listdir (folder):
				if fnmatch.fnmatch (fileName,'*.var'):
					if options.varfile:
						options.varfile.append(fileName)
					else:
						options.varfile = []
						options.varfile.append(fileName)
	
	# We need some source files for this script to work
	if not options.varfile:
		print "Error: No source files specified "
		sys.exit()
		
	# Set parent node to gibberish
	parentNode = doc.createElement("build")
	doc.appendChild(parentNode)
	newparentNode = ""
	
	# Removes duplicate elements in the arguments and iterate through them
	# to find the top-level abstract parent node
	for arg in list(set(options.varfile)):
		varobj = VarFile(arg)
		varobj.ParseVarFile()
		if varobj.extends:
			childlist.append(varobj)
		else:
			addedlist.append(varobj)
			conf = doc.createElement("config")
			conf.setAttribute("name",varobj.varname)
			parentNode.appendChild(conf)
			varobj.CreateSpec(conf)
			nodesList.append(conf)
	
	# Names of all the children need to be stored separately
	for c in childlist:
		childnames.append(c.varname)

	childlist2 = list(childlist)

	# Check the list is correct, and append orphan nodes to master BUILD node
	for ch in childlist2:
		if addedlist:
			if not ch.extends in addedlist[0].varname:
				if not ch.extends in childnames:
					conf = doc.createElement("config")
					conf.setAttribute("name",ch.varname)
					parentNode.appendChild(conf)
					varobj.CreateSpec(conf)
					nodesList.append(conf)
					addedlist.append(ch)
					childlist.remove(ch)
		else:
			if not ch.extends in childnames:
				conf = doc.createElement("config")
				conf.setAttribute("name",ch.varname)
				parentNode.appendChild(conf)
				varobj.CreateSpec(conf)
				nodesList.append(conf)
				addedlist.append(ch)
				childlist.remove(ch)
				
	# Make a copy of the new childlist
	childlist2 = list(childlist)

	# Go through all the children, and add them to the xml spec
	while (childlist2):
		# Refactor the childlist to remove elements which have been added
		for add in addedlist:
			if add in childlist:
				childlist.remove(add)
		for ch in childlist:
			if ch.extends == addedlist[i].varname:
				addedlist.append(ch)
				childlist2.remove(ch)
				conf = doc.createElement("config")
				conf.setAttribute("name",ch.varname)
				nodesList[i].appendChild(conf)
				nodesList.append(conf)
				ch.CreateSpec(conf)
			else:
				pass
		i = i + 1
	
	# If output xml file is specified, write to it otherwise print the xml to screen
	if options.outputxml:
		file = open(options.outputxml,"w")
		file.writelines(doc.toprettyxml(indent="  "))
		file.close()
	else:
		print doc.toprettyxml(indent="  ")


if __name__ == "__main__":
    main()