parser = argparse.ArgumentParser()
parser.add_argument("--clang", help="The clang binary (could be a relative or absolute path)",
action="store", default=default_clang_path())
- parser.add_argument("--source", help="the source file. Command used to generate the json will be of the format <clang> -cc1 -ast-dump=json <opts> <source>",
- action="store", required=True)
+ parser.add_argument("--source", help="the source file(s). Without --update, the command used to generate the JSON "
+ "will be of the format <clang> -cc1 -ast-dump=json <opts> <source>",
+ action="store", nargs=argparse.ONE_OR_MORE, required=True)
parser.add_argument("--filters", help="comma separated list of AST filters. Ex: --filters=TypedefDecl,BuiltinType",
action="store", default='')
update_or_generate_group = parser.add_mutually_exclusive_group()
args = parser.parse_args()
if not args.source:
- print("Specify the source file to give to clang.")
- return -1
+ sys.exit("Specify the source file to give to clang.")
clang_binary = os.path.abspath(args.clang)
if not os.path.isfile(clang_binary):
- print("clang binary specified not present.")
- return -1
+ sys.exit("clang binary specified not present.")
+
+ for src in args.source:
+ process_file(src, clang_binary, cmdline_filters=args.filters,
+ cmdline_opts=args.opts, do_update=args.update,
+ force_update=args.update_manual)
+
+def process_file(source_file, clang_binary, cmdline_filters, cmdline_opts,
+ do_update, force_update):
note_firstline = "// NOTE: CHECK lines have been autogenerated by " \
"gen_ast_dump_json_test.py"
filters_line_prefix = "// using --filters="
note = note_firstline
cmd = [clang_binary, "-cc1"]
- if args.update:
+ if do_update:
# When updating the first line of the test must be a RUN: line
- with open(args.source, "r") as srcf:
+ with open(source_file, "r") as srcf:
first_line = srcf.readline()
found_autogenerated_line = False
filters_line = None
if line.startswith(note_firstline):
found_autogenerated_line = True
# print("Found autogenerated disclaimer at line", i + 1)
- if not found_autogenerated_line and not args.update_manual:
- print("Not updating", args.source, "since it is not autogenerated.")
- sys.exit(0)
- if not args.filters and filters_line:
- args.filters = filters_line
- print("Inferred filters as '" + args.filters + "'")
+ if not found_autogenerated_line and not force_update:
+ print("Not updating", source_file, "since it is not autogenerated.",
+ file=sys.stderr)
+ return
+ if not cmdline_filters and filters_line:
+ cmdline_filters = filters_line
+ print("Inferred filters as '" + cmdline_filters + "'")
if "RUN: %clang_cc1 " not in first_line:
sys.exit("When using --update the first line of the input file must contain RUN: %clang_cc1")
sys.exit("ERROR: RUN: line does not contain %s")
options.remove("%s")
else:
- options = args.opts.split()
+ options = cmdline_opts.split()
options.append("-ast-dump=json")
cmd.extend(options)
using_ast_dump_filter = any('ast-dump-filter' in arg for arg in cmd)
- cmd.append(args.source)
+ cmd.append(source_file)
print("Will run", cmd)
filters = set()
- if args.filters:
- note += "\n" + filters_line_prefix + args.filters
- filters = set(args.filters.split(','))
+ if cmdline_filters:
+ note += "\n" + filters_line_prefix + cmdline_filters
+ filters = set(cmdline_filters.split(','))
print("Will use the following filters:", filters)
-
try:
json_str = subprocess.check_output(cmd)
except Exception as ex:
filter_json(j, filters, out_asts)
with tempfile.NamedTemporaryFile("w") as f:
- with open(args.source, "r") as srcf:
+ with open(source_file, "r") as srcf:
for line in srcf.readlines():
# copy up to the note:
if line.rstrip() == note_firstline:
f.write(out_str)
f.flush()
- if args.update:
- print("Updating json appended source file to %s." % args.source)
- copyfile(f.name, args.source)
+ if do_update:
+ print("Updating json appended source file to %s." % source_file)
+ copyfile(f.name, source_file)
else:
- partition = args.source.rpartition('.')
+ partition = source_file.rpartition('.')
dest_path = '%s-json%s%s' % (partition[0], partition[1], partition[2])
print("Writing json appended source file to %s." % dest_path)
copyfile(f.name, dest_path)
return 0
-
+
+
if __name__ == '__main__':
main()