1import subprocess 2import sys 3import shlex 4import os 5import re 6 7os.environ['LC_ALL'] = 'C' 8os.environ['LANG'] = 'C' 9for k in list(os.environ.keys()): 10 if k.startswith('LC_'): 11 os.environ.pop(k) 12 13if len(sys.argv) < 2: 14 sys.stderr.write('start as format-test.py gcc-123.45 [-options ...]\n') 15 sys.exit(1) 16 17c_re = re.compile(r'//\s+(NO)?WARN') 18expect = {} 19lines = {} 20 21with open('format-test.c', 'r') as fd: 22 for lno, line in enumerate(fd.readlines(), 1): 23 lines[lno] = line.strip() 24 m = c_re.search(line) 25 if m is None: 26 continue 27 if m.group(1) is None: 28 expect[lno] = 'warn' 29 else: 30 expect[lno] = 'nowarn' 31 32cmd = shlex.split('-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c') 33 34gcc = subprocess.Popen(sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 35sout, serr = gcc.communicate() 36gcc.wait() 37 38gcclines = serr.decode('UTF-8').splitlines() 39line_re = re.compile(r'^format-test\.c:(\d+):(.*)$') 40gcc_warns = {} 41 42for line in gcclines: 43 if line.find('In function') >= 0: 44 continue 45 m = line_re.match(line) 46 if m is None: 47 sys.stderr.write('cannot process GCC output: %s\n' % line) 48 continue 49 50 lno = int(m.group(1)) 51 gcc_warns.setdefault(lno, []).append(line) 52 53for lno, val in expect.items(): 54 if val == 'nowarn' and lno in gcc_warns: 55 sys.stderr.write('unexpected gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno]))) 56 if val == 'warn' and lno not in gcc_warns: 57 sys.stderr.write('expected warning on line %d but did not get one\n\t%s\n' % (lno, lines[lno])) 58 59leftover = set(gcc_warns.keys()) - set(expect.keys()) 60for lno in sorted(leftover): 61 sys.stderr.write('unmarked gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno]))) 62