ccc-analyzer revision 61cd988a7eaadd4b81c63a18a4733bf31399b66c
1b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#!/usr/bin/env python
2b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#
3b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#                     The LLVM Compiler Infrastructure
4b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#
5b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek# This file is distributed under the University of Illinois Open Source
6b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek# License. See LICENSE.TXT for details.
7b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#
8b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek##===----------------------------------------------------------------------===##
9b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#
10b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek# A reduced version of the 'ccc' script that is designed to handle off
11b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek# actual compilation to gcc, but run the code passed to gcc through the
12b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek# static analyzer.
13b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek#
14b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek##===----------------------------------------------------------------------===##
15b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
16b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekimport sys
17b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekimport subprocess
18b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekimport os
19b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
20b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef error(message):
2161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  print >> sys.stderr, 'ccc: ' + message
2261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  sys.exit(1)
23b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
24d389465f426069115a35e857ef11f1fcc5a2f69cSeo Sanghyeondef quote(arg):
2561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if '"' in arg:
2661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    return repr(arg)
2761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  return arg
28d389465f426069115a35e857ef11f1fcc5a2f69cSeo Sanghyeon
29b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef run(args):
3061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  code = subprocess.call(args)
3161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if code > 255:
3261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    code = 1
3361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if code:
3461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    sys.exit(code)
35b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
36fe87354769e18d2c7e42b7286d7f01048412964cTed Kremenekdef compile(args):
37b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  command = 'gcc'.split()
38b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  run(command + args)
39b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
40b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef remove_pch_extension(path):
4161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  i = path.rfind('.gch')
4261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if i < 0:
4361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    return path
4461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  return path[:i]
45b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
461262fc4d66584224234691d30d779f8ff004585cTed Kremenekdef analyze(clang, args,language,output,files,verbose,htmldir,file,analysis_type):
4761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if language.find("c++") > 0:
4861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    return
49a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek
5061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  print_args = []
5161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
5261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if verbose:
5361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # We MUST print to stderr.  Some clients use the stdout output of
5461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # gcc for various purposes.
5561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print >> sys.stderr, ' '.join(['\n[LOCATION]:', os.getcwd(), '\n' ])
5661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    i = 0
5761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    while i < len(args):
5861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      print_args.append(''.join([ '\'', args[i], '\'' ]))
5961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      i += 1
60a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek
6161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  RunAnalyzer = 0;
62a9525c929b280f12bd4f92a1732f981b82a62d25Ted Kremenek
6361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if language.find("header") > 0:
6461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    target = remove_pch_extension(output)
6561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    command = 'cp'.split()
6661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    args = command + files + target.split()      
6761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  else:
6861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    command = clang.split() + analysis_type.split()
6961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    args = command + args;
7061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    RunAnalyzer = 1
7161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
7261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if verbose == 2:
7361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print >> sys.stderr, '#SHELL (cd ' + os.getcwd() + ' && ' + ' '.join(command + print_args) + ')\n'
7461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
7561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if RunAnalyzer and htmldir is not None:
7661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    args.append('-o')
7761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print_args.append('-o')
7861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    args.append(htmldir)
7961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print_args.append(htmldir)
8061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
8161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if verbose == 1: 
8261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # We MUST print to stderr.  Some clients use the stdout output of
8361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # gcc for various purposes. 
8461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print >> sys.stderr, ' '.join(command+print_args)
8561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    print >> sys.stderr, '\n'
86b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
8761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  subprocess.call(args)
88b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
89b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef extension(path):
90b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    return path.split(".")[-1]
91b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
92b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef changeextension(path, newext):
93b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    i = path.rfind('.')
94b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    if i < 0:
95b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek        return path
96b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    j = path.rfind('/', 0, i)
97b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    print path
98b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    if j < 0:
99b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek        return path[:i] + "." + newext
100b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    return path[j+1:i] + "." + newext
101b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
102b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef inferlanguage(extension):
103b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  if extension == "c":
104b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "c"
105b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  elif extension in ["cpp", "cc"]:
106b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "c++"
107b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  elif extension == "i":
108b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "c-cpp-output"
109b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  elif extension == "m":
110b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "objective-c"
111b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  elif extension == "mi":
112b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "objective-c-cpp-output"
11348921c8a2e9136d4cacfcfc2757b17be49977a51Ted Kremenek  elif extension == "s":
114bfd6a3fbc16d39543d7d5a2041e749e8b1276393Ted Kremenek      return "skip"
115b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek  else:
116b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek      return "unknown"
117b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
118b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekdef main(args):
11961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  old_args = args
12061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  action = 'link'
12161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  output = ''
12261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  compile_opts = [ ]
12361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  link_opts = [ ]
12461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  files = []
12561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  save_temps = 0
12661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  language = ''
12761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
12861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  verbose = 0
12961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  clang = "clang"    
13061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
13161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Forward to GCC.
13261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  compile(args)    
13361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
13461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Set the analyzer flag.
13561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  analysis_type = os.environ.get('CCC_ANALYZER_ANALYSIS')
13661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
13761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if analysis_type is not None:
13861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    analysis_type = "-" + analysis_type
13961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  else:
14061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    analysis_type = "-checker-cfref"
14161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
14261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Determine the level of verbosity.
14361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if os.environ.get('CCC_ANALYZER_VERBOSE') is not None:
14461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    verbose = 1
145f22eacb11b50e647e7d08531ca5648d3c84c38c3Ted Kremenek    
14661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if os.environ.get('CCC_ANALYZER_LOG') is not None:
14761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    verbose = 2
14809c2ad63c3069c08efa1b4cdbc8beafcb7f1a221Ted Kremenek    
14961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Determine what clang executable to use.
15061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  clang_env = os.environ.get('CLANG') 
15161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
15261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if clang_env is not None:
15361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    clang = clang_env
15461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
15561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Get the HTML output directory.
15661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  htmldir = None
15761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  
15861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if analysis_type == "-checker-cfref":
15961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    htmldir = os.environ.get('CCC_ANALYZER_HTML')
16061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
16161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  # Process the arguments.
16261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  i = 0
16361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  while i < len(args):
16461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    arg = args[i]
16561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
16661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Modes ccc supports
16761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-E':
16861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        action = 'preprocess'
16961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-c':
17061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        action = 'compile'
17161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg.startswith('-print-prog-name'):
17261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        action = 'print-prog-name'
17361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-save-temps':
17461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        save_temps = 1
17561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
17661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with no arguments that should pass through
17761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg in ['-v']:
17861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(arg)
17961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(arg)
18026681e8e3a18acebd347061e20e167a81c47a408Ted Kremenek    
18161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with one argument that should be ignored
18261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg in ['--param', '-u']:
18361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
18426681e8e3a18acebd347061e20e167a81c47a408Ted Kremenek
18561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Prefix matches for the compile mode
18661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg[:2] in ['-D', '-I', '-U', '-F' ]:
18761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        if not arg[2:]:
18861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek            arg += args[i+1]
189b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek            i += 1
19061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(arg)
191b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
19261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg[:5] in ['-std=']:
19361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(arg)
194b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
19561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with one argument that should pass through to compiler
19661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg in [ '-include', '-idirafter', '-iprefix',
19761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek                '-iquote', '-isystem', '-iwithprefix',
19861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek                '-iwithprefixbefore']:
19961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(arg)
20061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(args[i+1])
20161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
20261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        
20361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with no argument that should pass through to compiler
20461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg in [ '-nostdinc', '-fobjc-gc-only', '-fobjc-gc' ]:
20561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      compile_opts.append(arg)          
20661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
20761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with one argument that should pass through to linker
20861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-framework':
20961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(arg)
21061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(args[i+1])
21161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
212b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
21361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Options with one argument that should pass through to both
21461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg in ['-isysroot', '-arch']:
21561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(arg)
21661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        compile_opts.append(args[i+1])
21761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(arg)
21861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(args[i+1])
21961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
220b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
22161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Prefix matches for the link mode
22261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg[:2] in ['-l', '-L', '-O', '-F']:
22361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        if arg == '-O': arg = '-O1'
22461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        if arg == '-Os': arg = '-O2'
22561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        link_opts.append(arg)
22661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
22761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Input files
22861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-filelist':
22961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        f = open(args[i+1])
23061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        for line in f:
23161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek            files.append(line.strip())
23261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        f.close()
23361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
23461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-x':
23561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        language = args[i+1]
23661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        i += 1
23761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg[0] != '-':
23861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        files.append(arg)
239b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
24061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    # Output file
24161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    if arg == '-o':
24261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        output = args[i+1]
243b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek        i += 1
244b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
24561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    i += 1
24661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
24761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if action == 'print-prog-name':
24861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      # assume we can handle everything
24961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      print sys.argv[0]
25061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      return
25161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
25261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if not files:
25361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      error('no input files')
25461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
25561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek  if action == 'compile' or save_temps or action == 'link':
25661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek    for i, file in enumerate(files):
25761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      if not language:
25861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        language = inferlanguage(extension(file))
25961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        if language == "skip":
26061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek          continue
26161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek
26261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      if save_temps and action != "compile":
26361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        # Need a temporary output file
26461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        coutput = changeextension(file, "o");
26561cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        files[i] = coutput
26661cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      elif not output:
26761cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        coutput = changeextension(file, "o")
26861cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      else:
26961cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        coutput = output
27061cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      analyze_args = [ file ]
27161cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      if language != 'unknown':
27261cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek        analyze_args = [ '-x', language ] + analyze_args
27361cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      analyze_args = analyze_args + compile_opts
27461cd988a7eaadd4b81c63a18a4733bf31399b66cTed Kremenek      analyze(clang, analyze_args, language, output, files, verbose, htmldir, file, analysis_type)
275b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek
276b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenekif __name__ == '__main__':
277b0982880c09a07147b5a9ad275393fedff13aad0Ted Kremenek    main(sys.argv[1:])
278