qemu/scripts/check_sparse.py
<<
>>
Prefs
   1#! /usr/bin/env python3
   2
   3# Invoke sparse based on the contents of compile_commands.json,
   4# also working around several deficiencies in cgcc's command line
   5# parsing
   6
   7import json
   8import subprocess
   9import os
  10import sys
  11import shlex
  12
  13def cmdline_for_sparse(sparse, cmdline):
  14    # Do not include the C compiler executable
  15    skip = True
  16    arg = False
  17    out = sparse + ['-no-compile']
  18    for x in cmdline:
  19        if arg:
  20            out.append(x)
  21            arg = False
  22            continue
  23        if skip:
  24            skip = False
  25            continue
  26        # prevent sparse from treating output files as inputs
  27        if x == '-MF' or x == '-MQ' or x == '-o':
  28            skip = True
  29            continue
  30        # cgcc ignores -no-compile if it sees -M or -MM?
  31        if x.startswith('-M'):
  32            continue
  33        # sparse does not understand these!
  34        if x == '-iquote' or x == '-isystem':
  35            x = '-I'
  36        if x == '-I':
  37            arg = True
  38        out.append(x)
  39    return out
  40
  41root_path = os.getenv('MESON_BUILD_ROOT')
  42def build_path(s):
  43    return s if not root_path else os.path.join(root_path, s)
  44
  45ccjson_path = build_path(sys.argv[1])
  46with open(ccjson_path, 'r') as fd:
  47    compile_commands = json.load(fd)
  48
  49sparse = sys.argv[2:]
  50sparse_env = os.environ.copy()
  51for cmd in compile_commands:
  52    cmdline = shlex.split(cmd['command'])
  53    cmd = cmdline_for_sparse(sparse, cmdline)
  54    print('REAL_CC=%s' % shlex.quote(cmdline[0]),
  55          ' '.join((shlex.quote(x) for x in cmd)))
  56    sparse_env['REAL_CC'] = cmdline[0]
  57    r = subprocess.run(cmd, env=sparse_env, cwd=root_path)
  58    if r.returncode != 0:
  59        sys.exit(r.returncode)
  60