diff --git a/share/analysis-scripts/list_files.py b/share/analysis-scripts/list_files.py index 063936ee84d76228a45f3a1a432c76146adb4555..e573679929cfb1adedd5859ac42b2007389f835f 100755 --- a/share/analysis-scripts/list_files.py +++ b/share/analysis-scripts/list_files.py @@ -40,9 +40,8 @@ else: arg = sys.argv[1] if not os.path.exists(arg): - print("error: file '%s' not found" % arg) - print("usage: %s [compile_commands.json]" % sys.argv[0]) - sys.exit(1) + print(f"error: file '{arg}' not found") + sys.exit(f"usage: {sys.argv[0]} [compile_commands.json]") # check if arg has a known extension def has_known_c_extension(arg): @@ -50,6 +49,7 @@ def has_known_c_extension(arg): pwd = os.getcwd() json = json.loads(open(arg).read()) +jcdb_dir = os.path.dirname(arg) includes = set() defines = set() files = set() @@ -60,10 +60,12 @@ for entry in json: # json compile spec says either command or arguments are mandatory if os.path.isabs(file): filepath = file - else: + elif os.path.isabs(dir): filepath = os.path.join(dir, file) + else: + filepath = os.path.join(jcdb_dir, dir, file) if not has_known_c_extension(filepath): - print("warning: ignoring file of unknown type: %s" % filepath) + print(f"warning: ignoring file of unknown type: {filepath}") else: files.add(os.path.relpath(filepath, pwd)) diff --git a/src/kernel_services/ast_queries/json_compilation_database.ml b/src/kernel_services/ast_queries/json_compilation_database.ml index 4f8eaa440efe9c2c426797e6df47e2ae1be306c0..6aeaf28c650a708ec5a3ecf0bdc20da04e82e789 100644 --- a/src/kernel_services/ast_queries/json_compilation_database.ml +++ b/src/kernel_services/ast_queries/json_compilation_database.ml @@ -131,10 +131,15 @@ let split_command_args s = never need quotes. *) let quote_define_argument arg = Format.sprintf "%S" arg -let parse_entry ?(cwd=Sys.getcwd()) r = +let parse_entry jcdb_dir r = let open Yojson.Basic.Util in let filename = r |> member "file" |> to_string in - let dirname = r |> member "directory" |> to_string_option |> Extlib.opt_conv "" in + let dirname = r |> member "directory" |> to_string_option |> Extlib.opt_conv jcdb_dir in + let dirname = + if Filepath.is_relative dirname then Filename.concat jcdb_dir dirname + else dirname + in + let dirname = Filepath.normalize dirname in let path = Datatype.Filepath.of_string ~base_name:dirname filename in (* get the list of arguments, and a flag indicating if the arguments @@ -157,13 +162,10 @@ let parse_entry ?(cwd=Sys.getcwd()) r = with _ -> Kernel.abort "compilation database: expected 'arguments' or 'command'" in - (* Normalize path names in include directives: first we normalize w.r.t. - the file's directory (following the compilation database logic), - then we relativize w.r.t. to Frama-C's PWD if possible - (to avoid overly long absolute paths). *) + (* conversion for '-I' flags *) let convert_path arg = - let abs = Filepath.normalize ~base_name:dirname arg in - Filepath.relativize ~base_name:cwd abs + if Filepath.is_relative arg then Filename.concat dirname arg + else arg in let convert_define arg = if requote then quote_define_argument arg else arg @@ -241,19 +243,19 @@ let get_flags f = if Kernel.JsonCompilationDatabase.get () <> "" then begin if not (Flags.is_computed ()) then begin let database = Kernel.JsonCompilationDatabase.get () in - let path = + let jcdb_dir, jcdb_path = if Sys.is_directory database then - Filename.concat database "compile_commands.json" - else database + database, Filename.concat database "compile_commands.json" + else Filename.dirname database, database in Kernel.feedback ~dkey:Kernel.dkey_compilation_db - "using compilation database: %s" path; + "using compilation database: %s" jcdb_path; begin try let r_list = - Yojson.Basic.from_file path |> Yojson.Basic.Util.to_list + Yojson.Basic.from_file jcdb_path |> Yojson.Basic.Util.to_list in - List.iter parse_entry r_list; + List.iter (parse_entry jcdb_dir) r_list; with | Sys_error msg | Yojson.Json_error msg diff --git a/tests/fc_script/list_files.json b/tests/fc_script/list_files.json index 7bece469142f9caad8021284ec3378d7c764d039..d3ab75506354c08d7b4a39de880f5d05588a8ea2 100644 --- a/tests/fc_script/list_files.json +++ b/tests/fc_script/list_files.json @@ -4,14 +4,14 @@ "cc", "main.c" ], - "directory": "tests/fc_script", + "directory": ".", "file": "main.c" }, - { "directory": "tests/fc_script", + { "directory": ".", "command": "gcc -DUH", "file": "main2.c" }, - { "directory": "tests/fc_script", + { "directory": ".", "command": "gcc", "file": "main3.c" } diff --git a/tests/jcdb/compile_commands.json b/tests/jcdb/compile_commands.json index dc47faa00ea9db4540ab33453afbd21de9f5e388..52a0f039c5ba20d81bf77a3dd803b8579d285c75 100644 --- a/tests/jcdb/compile_commands.json +++ b/tests/jcdb/compile_commands.json @@ -1,13 +1,13 @@ [ - { "directory": "tests/jcdb", + { "directory": ".", "command": "g++ -DDUPLICATE_FLAGS_THAT_WILL_BE_OVERWRITTEN", "file": "jcdb.c" }, - { "directory": "tests/jcdb", + { "directory": ".", "command": "g++ -DDUPLICATE_FLAGS_THAT_WILL_BE_OVERWRITTEN", "file": "jcdb.c" }, - { "directory": "tests/jcdb", + { "directory": ".", "command": "/usr/bin/clang++ -D'MSG=\"a \\\" \\\"b\"' -D'SINGLE_DOUBLE(a)=\"a \\\"with spaces and tab \"' -DSOMEDEF=\"With spaces, quotes and \\-es.\" -D\"DOUBLE_SINGLE(a)=a \\\"macro with spaces and non-escaped \\\\'\\\"\" -DEMPTY='' -DEMPTY2= -DTEST=42 -D'MACRO_FOR_INCR(s)=s+1' -DTOUNDEF -UTOUNDEF", "file": "jcdb.c" }, diff --git a/tests/jcdb/compile_commands_working.json b/tests/jcdb/compile_commands_working.json index 73899401e58039cc0f6333ee4c094b860168c122..c8c82c36f5d9d74233b44ea99cb0718a043536b0 100644 --- a/tests/jcdb/compile_commands_working.json +++ b/tests/jcdb/compile_commands_working.json @@ -1,9 +1,9 @@ [ - { "directory": "tests/jcdb", + { "directory": ".", "command": "gcc", "file": "jcdb.c" }, - { "directory": "tests/jcdb", + { "directory": ".", "command": "gcc", "file": "file_without_main.c" } diff --git a/tests/jcdb/with_arguments.json b/tests/jcdb/with_arguments.json index 4217869b5eafd76539298bf3156a9d8d7a1df764..06834b15f346a460ccacc4d57a2018c6f1a73692 100644 --- a/tests/jcdb/with_arguments.json +++ b/tests/jcdb/with_arguments.json @@ -1,5 +1,5 @@ [ - { "directory": "tests/jcdb", + { "directory": ".", "arguments": [ "cc", "-c", @@ -17,7 +17,7 @@ ], "file": "jcdb.c" }, - { "directory": "tests/jcdb", + { "directory": ".", "command": "/usr/bin/cc -DONION_VERSION=\\\"0.1.tr\\\" -Ibla -o jcdb2.o -c jcdb2.c jcdb.c", "file": "jcdb2.c" }