Rewrite findleaves.sh in python

This cuts the make startup time by about 30 seconds.  Python is faster
than bash in this case, and also we can now supply multiple directories
to prune, and skip the .repo directory, which is, uh, big.

This is from my mac laptop:

$ time build/tools/findleaves.sh --prune="./out" . Android.mk > /dev/null

real    0m29.186s
user    0m0.550s
sys 0m5.897s

$ time build/tools/findleaves.py --prune="./out" . Android.mk > /dev/null

real    0m4.701s
user    0m0.645s
sys 0m1.294s

$ time build/tools/findleaves.py --prune="./out" --prune="./.repo" . Android.mk > /dev/null
real    0m0.176s
user    0m0.094s
sys 0m0.080s
diff --git a/tools/findleaves.py b/tools/findleaves.py
new file mode 100755
index 0000000..0cda23c
--- /dev/null
+++ b/tools/findleaves.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Finds files with the specified name under a particular directory, stopping
+# the search in a given subdirectory when the file is found.
+#
+
+import os
+import sys
+
+def perform_find(mindepth, prune, dirlist, filename):
+  result = []
+  pruneleaves = set(map(lambda x: os.path.split(x)[1], prune))
+  for rootdir in dirlist:
+    rootdepth = rootdir.count("/")
+    for root, dirs, files in os.walk(rootdir):
+      # prune
+      check_prune = False
+      for d in dirs:
+        if d in pruneleaves:
+          check_prune = True
+          break
+      if check_prune:
+        i = 0
+        while i < len(dirs):
+          if os.path.join(root, dirs[i]) in prune:
+            del dirs[i]
+          else:
+            i += 1
+      # mindepth
+      if mindepth > 0:
+        depth = 1 + root.count("/") - rootdepth
+        if depth < mindepth:
+          continue
+      # match
+      if filename in files:
+        result.append(os.path.join(root, filename))
+        del dirs[:]
+  return result
+
+def usage():
+  sys.stderr.write("""Usage: %(progName)s [<options>] <dirlist> <filename>
+Options:
+   --mindepth=<mindepth>
+       Both behave in the same way as their find(1) equivalents.
+   --prune=<dirname>
+       Avoids returning results from inside any directory called <dirname>
+       (e.g., "*/out/*"). May be used multiple times.
+""" % {
+      "progName": os.path.split(sys.argv[0])[1],
+    })
+  sys.exit(1)
+
+def main(argv):
+  mindepth = -1
+  prune = []
+  i=1
+  while i<len(argv) and len(argv[i])>2 and argv[i][0:2] == "--":
+    arg = argv[i]
+    if arg.startswith("--mindepth="):
+      try:
+        mindepth = int(arg[len("--mindepth="):])
+      except ValueError:
+        usage()
+    elif arg.startswith("--prune="):
+      p = arg[len("--prune="):]
+      if len(p) == 0:
+        usage()
+      prune.append(p)
+    else:
+      usage()
+    i += 1
+  if len(argv)-i < 2: # need both <dirlist> and <filename>
+    usage()
+  dirlist = argv[i:-1]
+  filename = argv[-1]
+  results = perform_find(mindepth, prune, dirlist, filename)
+  for r in results:
+    print r
+
+if __name__ == "__main__":
+  main(sys.argv)