Skip to content

Instantly share code, notes, and snippets.

@rpuntaie
Created January 9, 2023 19:38
Show Gist options
  • Save rpuntaie/267a871795c774391444c07b9f14a274 to your computer and use it in GitHub Desktop.
Save rpuntaie/267a871795c774391444c07b9f14a274 to your computer and use it in GitHub Desktop.
Call include-what-you-use on C/C++ files with flags from compile_commands.json
#!/usr/bin/env python3
"""
! CHECK IN BEFORE EXPERIMENTING !
cd cmake_project/build
python iwyu.py
git status
git diff
Uses compile_commands.json for the C flags.
Replaces contiguous lines of includes as proposed by include-what-you-use.
"""
import sys
import json
import numpy as np
from subprocess import run, STDOUT
import re
ccjson = "compile_commands.json"
with open(ccjson) as ccf:
ccj = json.load(ccf)
excludes = sys.argv[1:]
iwyu = 'iwyu.txt'
with open(iwyu,'wb') as f:
f.write(b'\n')
for cc in ccj:
# cc = ccj[0]
cmd = cc['command']
file = cc['file']
skip = any([e in file for e in excludes])
if skip:
continue
cmdiwyn = ['include-what-you-use'] + cmd.split(' ')[1:]
r = run(cmdiwyn,capture_output=True)
with open(iwyu,'ab') as f:
f.write(b'\nsource_file\n')
f.write(cmdiwyn[-1].encode())
f.write(r.stderr or r.stdout)
with open(iwyu,'ab') as f:
f.write(b'\nsource_file\n')
with open(iwyu) as uf:
lns = uf.readlines()
def rindices(regex, lns):
regex = re.compile(regex)
for i, ln in enumerate(lns):
if regex.search(ln):
yield i
def in2s(nms):
return list(zip(nms[::2], nms[1::2]))
marker = "The full include-list for "
fixfiles = list(rindices(marker,lns))
for ff in fixfiles:
#ff = fixfiles[0]
ftf = lns[ff].split(marker)[1].split(':')[0]
skip = any([e in ftf for e in excludes])
if skip:
continue
ffend = ff
patch = []
while True:
ffend = ffend+1
pln = lns[ffend]
if pln.startswith('---'):
break
patch.append(pln)
with open(ftf) as ftff:
ftflns = ftff.readlines()
#len(ftflns)
incs = list(rindices('^#include',ftflns))
ica = list(rindices('/\*',ftflns))
icb = list(rindices('\*/',ftflns))
if len(ica) == len(icb):
for a,b in zip(ica,icb):
ai = 0
while ai < len(incs):
if incs[ai] >= a and incs[ai] <= b:
del incs[ai]
else:
ai = ai+1
if len(incs) > 1:
if max(np.diff(incs)) > 2:
print("not contiguous:",ftf)
continue
ftflns[min(incs):max(incs)+1] = patch
with open(ftf,'w') as ftff:
ftff.writelines(ftflns)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment