sbsv2/raptor/bin/depcrunch.py
changeset 18 de5b887c98f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/bin/depcrunch.py	Fri Jun 04 13:09:28 2010 +0100
@@ -0,0 +1,111 @@
+#
+# Copyright (c) 2010 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: 
+# Minimise the dependencies in a C preprocessor dependency file to
+# those that CPP could not find.  Then add in an assumption about 
+# where to find them.  Output is assumed to be relevant to only one target
+# even if multiple dep files are analysed.
+#
+
+import sys
+from  optparse import OptionParser
+import re
+
+class NoTargetException(Exception):
+	pass
+
+def depcrunch(file,extensions,assume):
+	target_pattern = r"^\s*(\S+):\s+"
+	target_re = re.compile(target_pattern)
+	# Not the use of (?i) in the following expression.  re.I seems to cause re.findall
+	# to not actually find all files matching the extension whereas (?i) provides
+	# case insensitivity at the right point and it works.  Really don't understand this.
+	extension_pattern = r"\s([^/ \t]+\.((?i)" + "|".join([t for t in extensions]) + r"))\b"
+	extension_re = re.compile(extension_pattern)
+
+	target = None
+
+	deps = []
+
+	# Read through the dependencies.
+	for l in file:
+		l = l.replace("\\","/").rstrip("\n\r")
+
+		# Look out for the target name if 
+		# we have not found it yet
+		if not target:
+			t = target_re.match(l)
+			if t:
+				target = t.groups()[0]
+
+		# Look for prerequisites matching the 
+		# extensions.  There may be one or more on 
+		# the same line as the target name.
+		# Don't use re.I - somehow prevents 
+		# all but one match in a line which may have several files
+		m = extension_re.findall(l)
+		if m:
+			deps.extend([d[0] for d in m])
+
+	if not target:
+		raise NoTargetException()
+
+	if len(deps) > 0:
+		print "%s: \\" % target
+		for d in deps[:-1]:
+			print " %s \\" % (assume + "/" + d)
+		print " %s " % (assume + "/" + deps[-1])
+
+
+
+
+## Command Line Interface ####################################################
+
+parser = OptionParser(prog = "depcrunch",
+	usage = "%prog [-h | options] [<depfile>]")
+
+parser.add_option("-e", "--extensions", 
+	 action="store", dest="extensions", type='string', help="comma separated list of file extensions of missing files to keep in the crunched dep file.") 
+
+parser.add_option("-a", "--assume", 
+	 action="store", dest="assume", type='string', help="when cpp reports missing dependencies, assume that they are in this directory") 
+
+(options, args) = parser.parse_args()
+
+
+if not options.extensions:
+	parser.error("you must specify a comma-separated list of file extensions with the -e option.")
+	sys.exit(1)
+
+if not options.assume:
+	parser.error("you must specify an 'assumed directory' for correcting missing dependencies with the -a option.")
+	sys.exit(1)
+
+depfilename="stdin"
+if len(args) > 0:
+	depfilename=args[0]
+	file = open(depfilename,"r")
+else:
+	file = sys.stdin
+try:
+	depcrunch(file,options.extensions.split(","), options.assume)
+except NoTargetException,e:
+	sys.stderr.write("Target name not found in dependency file\n");
+	sys.exit(2)
+	
+
+if file != sys.stdin:
+	file.close()
+
+sys.exit(0)