#include "Error.hpp"
#include "FormatNonstdStringView.hpp"
#include "ProgressBar.hpp"
+#include "ScopeGuard.hpp"
#include "Util.hpp"
#include "args.hpp"
#include "cleanup.hpp"
// but with arguments from @file and similar constructs expanded. It's only
// used as a temporary data structure to loop over.
struct args* expanded_args = args_copy(args);
+ ArgsScopeGuard expanded_args_guard(expanded_args);
// common_args contains all original arguments except:
// * those that never should be passed to the preprocessor,
// is false), and
// * dependency options (like -MD and friends).
struct args* common_args = args_init(0, NULL);
+ ArgsScopeGuard common_args_guard(common_args);
// cpp_args contains arguments that were not added to common_args, i.e. those
// that should only be passed to the preprocessor if run_second_cpp is false.
// If run_second_cpp is true, they will be passed to the compiler as well.
struct args* cpp_args = args_init(0, NULL);
+ ArgsScopeGuard cpp_args_guard(cpp_args);
// dep_args contains dependency options like -MD. They are only passed to the
// preprocessor, never to the compiler.
struct args* dep_args = args_init(0, NULL);
+ ArgsScopeGuard dep_args_guard(dep_args);
// compiler_only_args contains arguments that should only be passed to the
// compiler, not the preprocessor.
- struct args* compiler_only_args = args_init(0, NULL);
+ struct args* compiler_only_args = args_init(0, NULL); // will leak on failure
bool found_color_diagnostics = false;
bool found_directives_only = false;
char** argv = expanded_args->argv;
args_add(common_args, argv[0]);
- bool result = true;
for (int i = 1; i < argc; i++) {
// The user knows best: just swallow the next arg.
if (str_eq(argv[i], "--ccache-skip")) {
if (i == argc) {
cc_log("--ccache-skip lacks an argument");
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_add(common_args, argv[i]);
continue;
// Special case for -E.
if (str_eq(argv[i], "-E")) {
stats_update(STATS_PREPROCESSING);
- result = false;
- goto out;
+ return false;
}
// Handle "@file" argument.
if (!file_args) {
cc_log("Couldn't read arg file %s", argpath);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_insert(expanded_args, i, file_args, true);
if (i == argc - 1) {
cc_log("Expected argument after %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
++i;
if (!file_args) {
cc_log("Couldn't read cuda options file %s", str_start);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
int new_index = file_args->argc + index;
|| str_startswith(argv[i], "-MJ")) {
cc_log("Compiler option %s is unsupported", argv[i]);
stats_update(STATS_UNSUPPORTED_OPTION);
- result = false;
- goto out;
+ return false;
}
// These are too hard in direct mode.
if (str_startswith(argv[i], "-Xarch_")) {
cc_log("Unsupported compiler option :%s", argv[i]);
stats_update(STATS_UNSUPPORTED_OPTION);
- result = false;
- goto out;
+ return false;
}
// Handle -arch options.
cc_log("Too many -arch compiler options; ccache supports at most %d",
MAX_ARCH_ARGS);
stats_update(STATS_UNSUPPORTED_OPTION);
- result = false;
- goto out;
+ return false;
}
++i;
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_add(compiler_only_args, argv[i + 1]);
++i;
cc_log("Compiler option %s is unsupported without direct depend mode",
argv[i]);
stats_update(STATS_CANTUSEMODULES);
- result = false;
- goto out;
+ return false;
} else if (!(g_config.sloppiness() & SLOPPY_MODULES)) {
cc_log(
"You have to specify \"modules\" sloppiness when using"
" -fmodules to get hits");
stats_update(STATS_CANTUSEMODULES);
- result = false;
- goto out;
+ return false;
}
}
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
if (!input_file) {
explicit_language = argv[i + 1];
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
output_obj = make_relative_path(x_strdup(argv[i + 1]));
i++;
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
arg = argv[i + 1];
i++;
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_add(dep_args, argv[i]);
relpath = make_relative_path(x_strdup(argv[i + 1]));
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_add(common_args, argv[i]);
char* relpath = make_relative_path(x_strdup(argv[i + 1]));
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
args_add(common_args, argv[i]);
args_add(common_args, argv[i + 1]);
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
generating_diagnostics = true;
output_dia = make_relative_path(x_strdup(argv[i + 1]));
if (arg_profile_dir && profile_dir) {
cc_log("Profile directory already set; giving up");
stats_update(STATS_UNSUPPORTED_OPTION);
- result = false;
- goto out;
+ return false;
} else if (arg_profile_dir) {
cc_log("Setting profile directory to %s", arg_profile_dir);
profile_dir = x_strdup(arg_profile_dir);
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
if (!detect_pch(argv[i], argv[i + 1], &found_pch)) {
- result = false;
- goto out;
+ return false;
}
char* relpath = make_relative_path(x_strdup(argv[i + 1]));
if (i == argc - 1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
if (compopt_affects_cpp(argv[i])) {
cc_log("Unsupported source extension: %s", argv[i]);
stats_update(STATS_SOURCELANG);
}
- result = false;
- goto out;
+ return false;
}
// The source code file path gets put into the notes.
if (!input_file) {
cc_log("No input file found");
stats_update(STATS_NOINPUT);
- result = false;
- goto out;
+ return false;
}
if (found_pch || found_fpch_preprocess) {
" precompiled headers to get direct hits");
cc_log("Disabling direct mode");
stats_update(STATS_CANTUSEPCH);
- result = false;
- goto out;
+ return false;
}
}
if (!language_is_supported(explicit_language)) {
cc_log("Unsupported language: %s", explicit_language);
stats_update(STATS_SOURCELANG);
- result = false;
- goto out;
+ return false;
}
actual_language = x_strdup(explicit_language);
} else {
"You have to specify \"pch_defines,time_macros\" sloppiness when"
" creating precompiled headers");
stats_update(STATS_CANTUSEPCH);
- result = false;
- goto out;
+ return false;
}
if (!found_c_opt && !found_dc_opt && !found_S_opt) {
} else {
stats_update(STATS_LINK);
}
- result = false;
- goto out;
+ return false;
}
}
if (!actual_language) {
cc_log("Unsupported source extension: %s", input_file);
stats_update(STATS_SOURCELANG);
- result = false;
- goto out;
+ return false;
}
if (!g_config.run_second_cpp() && str_eq(actual_language, "cu")) {
if (output_obj && str_eq(output_obj, "-")) {
stats_update(STATS_OUTSTDOUT);
cc_log("Output file is -");
- result = false;
- goto out;
+ return false;
}
if (!output_obj) {
if (!p || !p[1]) {
cc_log("Badly formed object filename");
stats_update(STATS_ARGS);
- result = false;
- goto out;
+ return false;
}
output_dwo = x_strdup(Util::change_extension(output_obj, ".dwo").c_str());
if (st && !st.is_regular()) {
cc_log("Not a regular file: %s", output_obj);
stats_update(STATS_BADOUTPUTFILE);
- result = false;
- goto out;
+ return false;
}
}
if (!st || !st.is_directory()) {
cc_log("Directory does not exist: %s", output_dir);
stats_update(STATS_BADOUTPUTFILE);
- result = false;
free(output_dir);
- goto out;
+ return false;
}
free(output_dir);
}
args_extend(*extra_args_to_hash, dep_args);
}
-out:
- args_free(expanded_args);
- args_free(common_args);
- args_free(dep_args);
- args_free(cpp_args);
- return result;
+ return true;
}
static void