sbsv2/raptor/python/raptor_data.py
branchfix
changeset 374 96629a6f26e4
parent 371 2db10eac415a
child 400 554cc189839f
--- a/sbsv2/raptor/python/raptor_data.py	Fri Mar 05 10:22:42 2010 +0000
+++ b/sbsv2/raptor/python/raptor_data.py	Mon Mar 15 16:54:05 2010 +0000
@@ -65,7 +65,7 @@
 
 # Make sure not to start up on an unsupported platform
 if not HostPlatform.IsKnown(HostPlatform.hostplatform):
-	raise Exception("raptor_data module loaded on an unrecognised platform '%s'. Expected one of %s" % (hostplatform, str(hostplatforms)))
+	raise Exception("raptor_data module loaded on an unrecognised platform '%s'. Expected one of %s" % (HostPlatform.hostplatform, str(HostPlatform.hostplatforms)))
 
 
 # raptor_data module classes
@@ -139,7 +139,13 @@
 		raise BadReferenceError()
 
 	def GetModifiers(self, cache):
-		return [ cache.FindNamedVariant(m) for m in self.modifiers ]
+		mods = []
+		for m in self.modifiers:
+			try:
+				mods.append(cache.FindNamedVariant(m))
+			except KeyError:
+				raise BadReferenceError(m)
+		return mods
 
 	def Valid(self):
 		return self.ref
@@ -710,7 +716,7 @@
 
 	def __str__(self):
 		attributes = "name='" + self.name + "' type='" + self.type + "'"
-		if default != None:
+		if self.default != None:
 			attributes += " default='" + self.default + "'"
 
 		if type == "tool":
@@ -906,7 +912,6 @@
 		s += "</var>"
 		return s
 
-import traceback
 class VariantRef(Reference):
 
 	def __init__(self, ref=None):
@@ -918,7 +923,7 @@
 	def Resolve(self, cache):
 		try:
 			return cache.FindNamedVariant(self.ref)
-		except KeyError, e:
+		except KeyError:
 			raise BadReferenceError(self.ref)
 
 class MissingVariantException(Exception):
@@ -961,7 +966,7 @@
 					missing_variants.append(r.ref)
 				
 			if len(missing_variants) > 0:
-				raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants))
+				raise MissingVariantException("Missing variants '%s'" % " ".join(missing_variants))
 
 	def GenerateBuildUnits(self, cache):
 		self.Resolve(cache)
@@ -1029,22 +1034,24 @@
 		
 		missing_variants = []
 		for r in self.childRefs:
-			refMods = r.GetModifiers(cache)
-
 			try:
 				obj = r.Resolve(cache=cache)
 			except BadReferenceError:
 				missing_variants.append(r.ref)
 			else:
 				obj.ClearModifiers()
+				try:
+					refMods = r.GetModifiers(cache)
+				except BadReferenceError,e:
+					missing_variants.append(str(e))
+				else:
+					for m in refMods + self.modifiers:
+						obj.AddModifier(m)
 
-				for m in refMods + self.modifiers:
-					obj.AddModifier(m)
-
-				units.extend( obj.GenerateBuildUnits(cache) )
+					units.extend( obj.GenerateBuildUnits(cache) )
 
 		if len(missing_variants) > 0:
-			raise MissingVariantException("Missing variants '%s'", " ".join(missing_variants))
+			raise MissingVariantException("Missing variants '%s'" % " ".join(missing_variants))
 
 		return units
 
@@ -1063,6 +1070,81 @@
 		except KeyError:
 			raise BadReferenceError(self.ref)
 
+def GetBuildUnits(configNames, cache, logger):
+	"""expand a list of config strings like "arm.v5.urel" into a list
+	of BuildUnit objects that can be queried for settings.
+	
+	The expansion tries to be tolerant of errors in the XML so that a
+	typo in one part of a group does not invalidate the whole group.
+	"""
+	
+	# turn dot-separated name strings into Model objects (Group, Alias, Variant)
+	models = []
+		
+	for c in set(configNames):
+		ok = True
+		names = c.split(".")
+
+		base = names[0]
+		mods = names[1:]
+
+		if base in cache.groups:
+			x = cache.FindNamedGroup(base)
+		elif base in cache.aliases:
+			x = cache.FindNamedAlias(base)
+		elif base in cache.variants:
+			x = cache.FindNamedVariant(base)
+		else:
+			logger.Error("Unknown build configuration '%s'" % base)
+			continue
+
+		x.ClearModifiers()
+
+		for m in mods:
+			if m in cache.variants:
+				x.AddModifier( cache.FindNamedVariant(m) )
+			else:
+				logger.Error("Unknown build variant '%s'" % m)
+				ok = False
+				
+		if ok:
+			models.append(copy.copy(x))
+
+	# turn Model objects into BuildUnit objects
+	#
+	# all objects have a GenerateBuildUnits method but don't use
+	# that for Groups because it is not tolerant of errors (the
+	# first error raises an exception and the rest of the group is
+	# abandoned)
+	units = []
+		
+	while len(models) > 0:
+		x = models.pop()
+		try:
+			if isinstance(x, (Alias, Variant)):
+				# these we just turn straight into BuildUnits
+				units.extend(x.GenerateBuildUnits(cache))
+			elif isinstance(x, Group):
+				# deal with each part of the group separately (later)
+				for child in x.childRefs:
+					modChild = copy.copy(child)
+					modChild.modifiers = child.modifiers + [m.name for m in x.modifiers]
+					models.append(modChild)
+			elif isinstance(x, Reference):
+				# resolve references and their modifiers
+				try:
+					obj = x.Resolve(cache)
+					modObj = copy.copy(obj)
+					modObj.modifiers = x.GetModifiers(cache)
+				except BadReferenceError,e:
+					logger.Error("Unknown reference '%s'" % str(e))
+				else:
+					models.append(modObj)
+		except Exception, e:
+			logger.Error(str(e))
+
+	return units
+	
 class ToolErrorException(Exception):
 	def __init__(self, s):
 		Exception.__init__(self,s)
@@ -1364,6 +1446,9 @@
 class UninitialisedVariableException(Exception):
 	pass
 
+class RecursionException(Exception):
+	pass
+
 class Evaluator(object):
 	"""Determine the values of variables under different Configurations.
 	Either of specification and buildUnit may be None."""
@@ -1436,7 +1521,6 @@
 			for k, v in self.dict.items():
 				if v.find('$(' + k + ')') != -1:
 						raise RecursionException("Recursion Detected in variable '%s' in configuration '%s' " % (k,configName))
-						expanded = "RECURSIVE_INVALID_STRING"
 				else:
 					expanded = self.ExpandAll(v, specName, configName)