import subprocess import sys import shlex import os import re os.environ["LC_ALL"] = "C" os.environ["LANG"] = "C" for k in list(os.environ.keys()): if k.startswith("LC_"): os.environ.pop(k) if len(sys.argv) < 2: sys.stderr.write("start as format-test.py gcc-123.45 [-options ...]\n") sys.exit(1) c_re = re.compile(r"//\s+(NO)?WARN") expect = {} lines = {} with open("format-test.c", "r") as fd: for lno, line in enumerate(fd.readlines(), 1): lines[lno] = line.strip() m = c_re.search(line) if m is None: continue if m.group(1) is None: expect[lno] = "warn" else: expect[lno] = "nowarn" cmd = shlex.split( "-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c" ) gcc = subprocess.Popen( sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) sout, serr = gcc.communicate() gcc.wait() gcclines = serr.decode("UTF-8").splitlines() line_re = re.compile(r"^format-test\.c:(\d+):(.*)$") gcc_warns = {} for line in gcclines: if line.find("In function") >= 0: continue m = line_re.match(line) if m is None: sys.stderr.write("cannot process GCC output: %s\n" % line) continue lno = int(m.group(1)) gcc_warns.setdefault(lno, []).append(line) for lno, val in expect.items(): if val == "nowarn" and lno in gcc_warns: 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])) ) if val == "warn" and lno not in gcc_warns: sys.stderr.write( "expected warning on line %d but did not get one\n\t%s\n" % (lno, lines[lno]) ) leftover = set(gcc_warns.keys()) - set(expect.keys()) for lno in sorted(leftover): 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])) )