summaryrefslogtreecommitdiffstats
path: root/tools/scan-build/set-xcode-analyzer
blob: cf0ba3a1af06716058244b71c83f3881292ed448 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python

import os
import sys
import re
import tempfile
import shutil
import stat

def FindClangSpecs(path):
  for root, dirs, files in os.walk(path):
    for f in files:
      if f.endswith(".xcspec") and f.startswith("Clang LLVM"):
        yield os.path.join(root, f)

def ModifySpec(path, pathToChecker):
  t = tempfile.NamedTemporaryFile(delete=False)
  foundAnalyzer = False
  with open(path) as f:
    for line in f:
      if not foundAnalyzer:
        if line.find("Static Analyzer") >= 0:
          foundAnalyzer = True
      else:
        m = re.search('^(\s*ExecPath\s*=\s*")', line)
        if m:
          line = "".join([m.group(0), pathToChecker, '";\n'])
      t.write(line)
  t.close()
  print "(+)", path
  try:
    shutil.copy(t.name, path)
    os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
  except IOError, why:
    print "\n    Cannot update file:", why, "\n"
  except OSError, why:
    print "\n    Cannot update file:", why, "\n"
  os.unlink(t.name)

def main():
  from optparse import OptionParser
  parser = OptionParser('usage: %prog [options]')
  parser.set_description(__doc__)
  parser.add_option("--use-checker-build", dest="path",
                    help="Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1")
  parser.add_option("--use-xcode-clang", action="store_const", 
                    const="$(CLANG)", dest="default",
                    help="Use the Clang bundled with Xcode")
  (options, args) = parser.parse_args()
  if options.path is None and options.default is None:
    parser.error("You must specify a version of Clang to use for static analysis.  Specify '-h' for details")

  if options.path:
    # Expand tildes.
    path = os.path.expanduser(options.path)
    if not path.endswith("clang"):
      print "Using Clang bundled with checker build:", path
      path = os.path.join(path, "bin", "clang");
    else:
      print "Using Clang located at:", path
  else:
    print "Using the Clang bundled with Xcode"
    path = options.default

  print ""
  for x in FindClangSpecs('/Developer'):
    ModifySpec(x, path)

if __name__ == '__main__':
  main()