]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Improve processing of input file arguments
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 2 Dec 2023 11:24:07 +0000 (12:24 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 10 Dec 2023 19:59:24 +0000 (20:59 +0100)
Instead of checking if a non-option argument has a known file extension,
switch to the better heuristic of checking if the file exists or not: if
it doesn't exist it isn't an input argument.

src/argprocessing.cpp
src/language.cpp
src/language.hpp

index 845ba8ecdb685cbac53eacfce69b93fbe7531eca..9c546e21e2434085f5949d513bbd454662513d0f 100644 (file)
@@ -25,6 +25,7 @@
 #include <Depfile.hpp>
 #include <Util.hpp>
 #include <util/assertions.hpp>
+#include <util/filesystem.hpp>
 #include <util/fmtmacros.hpp>
 #include <util/logging.hpp>
 #include <util/path.hpp>
@@ -36,7 +37,9 @@
 #endif
 
 #include <cassert>
+#include <vector>
 
+namespace fs = util::filesystem;
 using core::Statistic;
 using util::DirEntry;
 
@@ -85,6 +88,9 @@ struct ArgumentProcessingState
   // Is the compiler being asked to output debug info on level 3?
   bool generating_debuginfo_level_3 = false;
 
+  // Arguments classified as input files.
+  std::vector<fs::path> input_files;
+
   // common_args contains all original arguments except:
   // * those that never should be passed to the preprocessor,
   // * those that only should be passed to the preprocessor (if run_second_cpp
@@ -555,7 +561,7 @@ process_option_arg(const Context& ctx,
         LOG("Missing argument to {}", args[i]);
         return Statistic::bad_compiler_arguments;
       }
-      if (args_info.input_file.empty()) {
+      if (state.input_files.empty()) {
         state.explicit_language = args[i + 1];
       }
       i++;
@@ -563,7 +569,7 @@ process_option_arg(const Context& ctx,
     }
 
     DEBUG_ASSERT(arg.length() >= 3);
-    if (args_info.input_file.empty()) {
+    if (state.input_files.empty()) {
       state.explicit_language = arg.substr(2);
     }
     return Statistic::none;
@@ -1135,30 +1141,13 @@ process_arg(const Context& ctx,
     }
   }
 
-  if (!args_info.input_file.empty()) {
-    if (supported_source_extension(args[i])) {
-      LOG("Multiple input files: {} and {}", args_info.input_file, args[i]);
-      return Statistic::multiple_source_files;
-    } else if (!state.found_c_opt && !state.found_dc_opt
-               && !state.found_analyze_opt) {
-      LOG("Called for link with {}", args[i]);
-      if (args[i].find("conftest.") != std::string::npos) {
-        return Statistic::autoconf_test;
-      } else {
-        return Statistic::called_for_link;
-      }
-    } else {
-      LOG("Unsupported source extension: {}", args[i]);
-      return Statistic::unsupported_source_language;
-    }
+  if (fs::exists(args[i])) {
+    LOG("Detected input file: {}", args[i]);
+    state.input_files.emplace_back(args[i]);
+  } else {
+    LOG("Not considering {} an input file since it doesn't exist", args[i]);
+    state.common_args.push_back(args[i]);
   }
-
-  // Rewrite to relative to increase hit rate.
-  args_info.orig_input_file = args[i];
-  args_info.input_file = Util::make_relative_path(ctx, args[i]);
-  args_info.normalized_input_file =
-    Util::normalize_concrete_absolute_path(args_info.input_file);
-
   return Statistic::none;
 }
 
@@ -1194,6 +1183,34 @@ process_args(Context& ctx)
     }
   }
 
+  const bool is_link =
+    !(state.found_c_opt || state.found_dc_opt || state.found_S_opt
+      || state.found_syntax_only || state.found_analyze_opt);
+
+  if (state.input_files.empty()) {
+    LOG_RAW("No input file found");
+    return Statistic::no_input_file;
+  }
+  if (state.input_files.size() > 1) {
+    if (is_link) {
+      LOG_RAW("Called for link");
+      return state.input_files.front().string().find("conftest.")
+                 != std::string::npos
+               ? Statistic::autoconf_test
+               : Statistic::called_for_link;
+    } else {
+      LOG_RAW("Multiple input files");
+      return Statistic::multiple_source_files;
+    }
+  }
+
+  args_info.orig_input_file = state.input_files.front().string();
+  // Rewrite to relative to increase hit rate.
+  args_info.input_file =
+    Util::make_relative_path(ctx, args_info.orig_input_file);
+  args_info.normalized_input_file =
+    Util::normalize_concrete_absolute_path(args_info.input_file);
+
   // Bail out on too hard combinations of options.
   if (state.found_mf_opt && state.found_wp_md_or_mmd_opt) {
     // GCC and Clang behave differently when "-Wp,-M[M]D,wp.d" and "-MF mf.d"
@@ -1270,11 +1287,6 @@ process_args(Context& ctx)
   }
 #endif
 
-  if (args_info.input_file.empty()) {
-    LOG_RAW("No input file found");
-    return Statistic::no_input_file;
-  }
-
   if (state.found_pch || state.found_fpch_preprocess) {
     args_info.using_precompiled_header = true;
     if (!(config.sloppiness().contains(core::Sloppy::time_macros))) {
@@ -1322,9 +1334,7 @@ process_args(Context& ctx)
     return Statistic::could_not_use_precompiled_header;
   }
 
-  // -fsyntax-only/-Zs does not need -c
-  if (!state.found_c_opt && !state.found_dc_opt && !state.found_S_opt
-      && !state.found_syntax_only && !state.found_analyze_opt) {
+  if (is_link) {
     if (args_info.output_is_precompiled_header) {
       state.common_args.push_back("-c");
     } else {
index aa1a2cac7a6d900f965e97349582ff802f57dbee..4a4635ae06f20adccfb4502af396678a53de4087 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2010-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -102,18 +102,6 @@ const struct
 
 } // namespace
 
-bool
-supported_source_extension(const std::string& fname)
-{
-  const auto ext = Util::get_extension(fname);
-  for (size_t i = 0; k_ext_lang_table[i].extension; ++i) {
-    if (k_ext_lang_table[i].extension == ext) {
-      return true;
-    }
-  }
-  return false;
-}
-
 std::string
 language_for_file(const std::string& fname, CompilerType compiler_type)
 {
index 74be7aaf622c8d810fa5f85f0325092f5ecf04e4..3e79bdf51193d1e99c525db5913aba4c9e3bab73 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2010-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -22,9 +22,6 @@
 
 #include <string>
 
-// Return whether a filename has a supported source code extension.
-bool supported_source_extension(const std::string& fname);
-
 // Guess the language of `fname` based on its extension and a compiler type.
 // Returns the empty string if the extension is unknown.
 std::string language_for_file(const std::string& fname,