From: Alexander Lanin Date: Fri, 4 Sep 2020 05:45:21 +0000 (+0200) Subject: refactoring: Convert stats to enum class (#651) X-Git-Tag: v4.0~136 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c0248cf7730c4ed95747e1aa7130f3c0e64b9e20;p=thirdparty%2Fccache.git refactoring: Convert stats to enum class (#651) --- diff --git a/src/Counters.cpp b/src/Counters.cpp index 772a17485..262b56270 100644 --- a/src/Counters.cpp +++ b/src/Counters.cpp @@ -22,27 +22,29 @@ #include -Counters::Counters() : m_counters(STATS_END) +Counters::Counters() : m_counters(static_cast(Statistic::END)) { } // clang-format off unsigned& -Counters::operator[](size_t index) +Counters::operator[](Statistic index) // clang-format on { - if (index >= m_counters.size()) { - m_counters.resize(index + 1); + const size_t i = static_cast(index); + if (i >= m_counters.size()) { + m_counters.resize(i + 1); } - return m_counters.at(index); + return m_counters.at(i); } // clang-format off unsigned -Counters::operator[](size_t index) const +Counters::operator[](Statistic index) const // clang-format on { - return index < m_counters.size() ? m_counters.at(index) : 0; + const size_t i = static_cast(index); + return i < m_counters.size() ? m_counters.at(i) : 0; } size_t diff --git a/src/Counters.hpp b/src/Counters.hpp index 1e05245e6..b72d83a50 100644 --- a/src/Counters.hpp +++ b/src/Counters.hpp @@ -22,6 +22,8 @@ #include +enum class Statistic; + // A simple wrapper around a vector of integers // used for the statistics counters. class Counters @@ -29,8 +31,8 @@ class Counters public: Counters(); - unsigned& operator[](size_t index); - unsigned operator[](size_t index) const; + unsigned& operator[](Statistic index); + unsigned operator[](Statistic index) const; size_t size() const; diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 746ba54f9..83a776732 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -212,7 +212,7 @@ add_depend_mode_extra_original_args(Context& ctx, const std::string& arg) } } -optional +optional process_arg(Context& ctx, Args& args, size_t& args_index, @@ -228,7 +228,7 @@ process_arg(Context& ctx, i++; if (i == args.size()) { log("--ccache-skip lacks an argument"); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } state.common_args.push_back(args[i]); return nullopt; @@ -236,7 +236,7 @@ process_arg(Context& ctx, // Special case for -E. if (args[i] == "-E") { - return STATS_PREPROCESSING; + return Statistic::called_for_preprocessing; } // Handle "@file" argument. @@ -249,7 +249,7 @@ process_arg(Context& ctx, auto file_args = Args::from_gcc_atfile(argpath); if (!file_args) { log("Couldn't read arg file {}", argpath); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } args.replace(i, *file_args); @@ -262,7 +262,7 @@ process_arg(Context& ctx, && (args[i] == "-optf" || args[i] == "--options-file")) { if (i == args.size() - 1) { log("Expected argument after {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } ++i; @@ -272,7 +272,7 @@ process_arg(Context& ctx, auto file_args = Args::from_gcc_atfile(*it); if (!file_args) { log("Couldn't read CUDA options file {}", *it); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } args.insert(i + 1, *file_args); @@ -285,7 +285,7 @@ process_arg(Context& ctx, if (compopt_too_hard(args[i]) || Util::starts_with(args[i], "-fdump-") || Util::starts_with(args[i], "-MJ")) { log("Compiler option {} is unsupported", args[i]); - return STATS_UNSUPPORTED_OPTION; + return Statistic::unsupported_compiler_option; } // These are too hard in direct mode. @@ -297,7 +297,7 @@ process_arg(Context& ctx, // -Xarch_* options are too hard. if (Util::starts_with(args[i], "-Xarch_")) { log("Unsupported compiler option: {}", args[i]); - return STATS_UNSUPPORTED_OPTION; + return Statistic::unsupported_compiler_option; } // Handle -arch options. @@ -335,7 +335,7 @@ process_arg(Context& ctx, && args[i] == "-Werror")) { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } state.compiler_only_args.push_back(args[i + 1]); ++i; @@ -359,12 +359,12 @@ process_arg(Context& ctx, if (!config.depend_mode() || !config.direct_mode()) { log("Compiler option {} is unsupported without direct depend mode", args[i]); - return STATS_CANTUSEMODULES; + return Statistic::could_not_use_modules; } else if (!(config.sloppiness() & SLOPPY_MODULES)) { log( "You have to specify \"modules\" sloppiness when using" " -fmodules to get hits"); - return STATS_CANTUSEMODULES; + return Statistic::could_not_use_modules; } } @@ -402,7 +402,7 @@ process_arg(Context& ctx, if (args[i] == "-x") { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } if (args_info.input_file.empty()) { state.explicit_language = args[i + 1]; @@ -421,7 +421,7 @@ process_arg(Context& ctx, if (args[i] == "-o") { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } args_info.output_obj = Util::make_relative_path(ctx, args[i + 1]); i++; @@ -496,7 +496,7 @@ process_arg(Context& ctx, // -MF arg if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } dep_file = args[i + 1]; i++; @@ -522,7 +522,7 @@ process_arg(Context& ctx, // -MQ arg or -MT arg if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } state.dep_args.push_back(args[i]); std::string relpath = Util::make_relative_path(ctx, args[i + 1]); @@ -568,7 +568,7 @@ process_arg(Context& ctx, || args[i] == "-fbranch-probabilities") { if (!process_profiling_option(ctx, args[i])) { // The failure is logged by process_profiling_option. - return STATS_UNSUPPORTED_OPTION; + return Statistic::unsupported_compiler_option; } state.common_args.push_back(args[i]); return nullopt; @@ -591,7 +591,7 @@ process_arg(Context& ctx, if (args[i] == "--sysroot") { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } state.common_args.push_back(args[i]); auto relpath = Util::make_relative_path(ctx, args[i + 1]); @@ -604,7 +604,7 @@ process_arg(Context& ctx, if (args[i] == "-target") { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } state.common_args.push_back(args[i]); state.common_args.push_back(args[i + 1]); @@ -619,7 +619,7 @@ process_arg(Context& ctx, // from compiling the preprocessed file will not be equal to the object // file produced when compiling without ccache. log("Too hard option -Wp,-P detected"); - return STATS_UNSUPPORTED_OPTION; + return Statistic::unsupported_compiler_option; } else if (Util::starts_with(args[i], "-Wp,-MD,") && args[i].find(',', 8) == std::string::npos) { args_info.generating_dependencies = true; @@ -676,7 +676,7 @@ process_arg(Context& ctx, if (args[i] == "--serialize-diagnostics") { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } args_info.generating_diagnostics = true; args_info.output_dia = Util::make_relative_path(ctx, args[i + 1]); @@ -741,7 +741,7 @@ process_arg(Context& ctx, if (compopt_takes_path(args[i])) { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } // In the -Xclang -include-(pch/pth) -Xclang case, the path is one @@ -753,7 +753,7 @@ process_arg(Context& ctx, if (!detect_pch( ctx, args[i], args[i + next], next == 2, &state.found_pch)) { - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } std::string relpath = Util::make_relative_path(ctx, args[i + next]); @@ -793,7 +793,7 @@ process_arg(Context& ctx, if (compopt_takes_arg(args[i])) { if (i == args.size() - 1) { log("Missing argument to {}", args[i]); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } if (compopt_affects_cpp(args[i])) { @@ -835,17 +835,17 @@ process_arg(Context& ctx, if (!args_info.input_file.empty()) { if (!language_for_file(args[i]).empty()) { log("Multiple input files: {} and {}", args_info.input_file, args[i]); - return STATS_MULTIPLE; + return Statistic::multiple_source_files; } else if (!state.found_c_opt && !state.found_dc_opt) { log("Called for link with {}", args[i]); if (args[i].find("conftest.") != std::string::npos) { - return STATS_CONFTEST; + return Statistic::autoconf_test; } else { - return STATS_LINK; + return Statistic::called_for_link; } } else { log("Unsupported source extension: {}", args[i]); - return STATS_SOURCELANG; + return Statistic::unsupported_source_language; } } @@ -920,7 +920,7 @@ handle_dependency_environment_variables(Context& ctx, } // namespace -optional +optional process_args(Context& ctx, Args& preprocessor_args, Args& extra_args_to_hash, @@ -955,7 +955,7 @@ process_args(Context& ctx, if (args_info.input_file.empty()) { log("No input file found"); - return STATS_NOINPUT; + return Statistic::no_input_file; } if (state.found_pch || state.found_fpch_preprocess) { @@ -965,7 +965,7 @@ process_args(Context& ctx, "You have to specify \"time_macros\" sloppiness when using" " precompiled headers to get direct hits"); log("Disabling direct mode"); - return STATS_CANTUSEPCH; + return Statistic::could_not_use_precompiled_header; } } @@ -980,7 +980,7 @@ process_args(Context& ctx, if (!state.explicit_language.empty()) { if (!language_is_supported(state.explicit_language)) { log("Unsupported language: {}", state.explicit_language); - return STATS_SOURCELANG; + return Statistic::unsupported_source_language; } args_info.actual_language = state.explicit_language; } else { @@ -996,7 +996,7 @@ process_args(Context& ctx, log( "You have to specify \"pch_defines,time_macros\" sloppiness when" " creating precompiled headers"); - return STATS_CANTUSEPCH; + return Statistic::could_not_use_precompiled_header; } if (!state.found_c_opt && !state.found_dc_opt && !state.found_S_opt) { @@ -1007,14 +1007,14 @@ process_args(Context& ctx, // Having a separate statistic for autoconf tests is useful, as they are // the dominant form of "called for link" in many cases. return args_info.input_file.find("conftest.") != std::string::npos - ? STATS_CONFTEST - : STATS_LINK; + ? Statistic::autoconf_test + : Statistic::called_for_link; } } if (args_info.actual_language.empty()) { log("Unsupported source extension: {}", args_info.input_file); - return STATS_SOURCELANG; + return Statistic::unsupported_source_language; } if (!config.run_second_cpp() && args_info.actual_language == "cu") { @@ -1038,7 +1038,7 @@ process_args(Context& ctx, // Don't try to second guess the compilers heuristics for stdout handling. if (args_info.output_obj == "-") { log("Output file is -"); - return STATS_OUTSTDOUT; + return Statistic::output_to_stdout; } if (args_info.output_obj.empty()) { @@ -1055,7 +1055,7 @@ process_args(Context& ctx, size_t pos = args_info.output_obj.rfind('.'); if (pos == std::string::npos || pos == args_info.output_obj.size() - 1) { log("Badly formed object filename"); - return STATS_ARGS; + return Statistic::bad_compiler_arguments; } args_info.output_dwo = Util::change_extension(args_info.output_obj, ".dwo"); @@ -1066,7 +1066,7 @@ process_args(Context& ctx, auto st = Stat::stat(args_info.output_obj); if (st && !st.is_regular()) { log("Not a regular file: {}", args_info.output_obj); - return STATS_BADOUTPUTFILE; + return Statistic::bad_output_file; } } @@ -1074,7 +1074,7 @@ process_args(Context& ctx, auto st = Stat::stat(output_dir); if (!st || !st.is_directory()) { log("Directory does not exist: {}", output_dir); - return STATS_BADOUTPUTFILE; + return Statistic::bad_output_file; } // Some options shouldn't be passed to the real compiler when it compiles diff --git a/src/argprocessing.hpp b/src/argprocessing.hpp index 19107f344..6df33229d 100644 --- a/src/argprocessing.hpp +++ b/src/argprocessing.hpp @@ -33,7 +33,7 @@ class Args; // // Returns nullopt on success, otherwise the statistics counter that should be // incremented. -nonstd::optional process_args(Context& ctx, - Args& preprocessor_args, - Args& extra_args_to_hash, - Args& compiler_args); +nonstd::optional process_args(Context& ctx, + Args& preprocessor_args, + Args& extra_args_to_hash, + Args& compiler_args); diff --git a/src/ccache.cpp b/src/ccache.cpp index 5526bc7b8..5d61f282c 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -549,7 +549,7 @@ process_preprocessed_file(Context& ctx, log( "Found unsupported .inc" "bin directive in source code"); - throw Failure(STATS_UNSUPPORTED_DIRECTIVE); + throw Failure(Statistic::unsupported_code_directive); } else if (pump && strncmp(q, "_________", 9) == 0) { // Unfortunately the distcc-pump wrapper outputs standard output lines: // __________Using distcc-pump from /usr/bin @@ -707,14 +707,14 @@ do_execute(Context& ctx, tmp_stdout.path.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600)); if (!tmp_stdout.fd) { log("Failed to truncate {}: {}", tmp_stdout.path, strerror(errno)); - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } tmp_stderr.fd = Fd(open( tmp_stderr.path.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600)); if (!tmp_stderr.fd) { log("Failed to truncate {}: {}", tmp_stderr.path, strerror(errno)); - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } ctx.diagnostics_color_failed = true; @@ -839,7 +839,7 @@ to_cache(Context& ctx, if (unlink(ctx.args_info.output_dwo.c_str()) != 0 && errno != ENOENT && errno != ESTALE) { log("Failed to unlink {}: {}", ctx.args_info.output_dwo, strerror(errno)); - throw Failure(STATS_BADOUTPUTFILE); + throw Failure(Statistic::bad_output_file); } } @@ -878,14 +878,14 @@ to_cache(Context& ctx, auto st = Stat::stat(tmp_stdout_path, Stat::OnError::log); if (!st) { // The stdout file was removed - cleanup in progress? Better bail out. - throw Failure(STATS_MISSING); + throw Failure(Statistic::missing_cache_file); } // distcc-pump outputs lines like this: // __________Using # distcc servers in pump mode if (st.size() != 0 && ctx.guessed_compiler != GuessedCompiler::pump) { log("Compiler produced stdout"); - throw Failure(STATS_STDOUT); + throw Failure(Statistic::compiler_produced_stdout); } // Merge stderr from the preprocessor (if any) and stderr from the real @@ -902,14 +902,14 @@ to_cache(Context& ctx, // We can output stderr immediately instead of rerunning the compiler. Util::send_to_stderr(ctx, Util::read_file(tmp_stderr_path)); - throw Failure(STATS_STATUS, status); + throw Failure(Statistic::compile_failed, status); } if (ctx.config.depend_mode()) { assert(depend_mode_hash); auto result_name = result_name_from_depfile(ctx, *depend_mode_hash); if (!result_name) { - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } ctx.set_result_name(*result_name); } @@ -924,16 +924,16 @@ to_cache(Context& ctx, st = Stat::stat(ctx.args_info.output_obj); if (!st) { log("Compiler didn't produce an object file"); - throw Failure(STATS_NOOUTPUT); + throw Failure(Statistic::compiler_produced_no_output); } if (st.size() == 0) { log("Compiler produced an empty object file"); - throw Failure(STATS_EMPTYOUTPUT); + throw Failure(Statistic::compiler_produced_empty_output); } st = Stat::stat(tmp_stderr_path, Stat::OnError::log); if (!st) { - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } auto orig_dest_stat = Stat::stat(ctx.result_path()); @@ -971,7 +971,7 @@ to_cache(Context& ctx, auto new_dest_stat = Stat::stat(ctx.result_path(), Stat::OnError::log); if (!new_dest_stat) { - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } stats_update_size(ctx.counter_updates, new_dest_stat.size_on_disk() @@ -1040,20 +1040,20 @@ get_result_name_from_cpp(Context& ctx, Args& args, Hash& hash) if (status != 0) { log("Preprocessor gave exit status {}", status); - throw Failure(STATS_PREPROCESSOR); + throw Failure(Statistic::preprocessor_error); } hash.hash_delimiter("cpp"); bool is_pump = ctx.guessed_compiler == GuessedCompiler::pump; if (!process_preprocessed_file(ctx, hash, stdout_path, is_pump)) { - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } hash.hash_delimiter("cppstderr"); if (!ctx.args_info.direct_i_file && !hash.hash_file(stderr_path)) { // Somebody removed the temporary file? log("Failed to open {}: {}", stderr_path, strerror(errno)); - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } if (ctx.args_info.direct_i_file) { @@ -1104,7 +1104,7 @@ hash_compiler(const Context& ctx, hash, ctx.config.compiler_check(), ctx.orig_args[0])) { log("Failure running compiler check command: {}", ctx.config.compiler_check()); - throw Failure(STATS_COMPCHECK); + throw Failure(Statistic::compiler_check_failed); } } } @@ -1188,7 +1188,7 @@ hash_common_info(const Context& ctx, auto st = Stat::stat(compiler_path, Stat::OnError::log); if (!st) { - throw Failure(STATS_COMPILER); + throw Failure(Statistic::could_not_find_compiler); } // Hash information about the compiler. @@ -1271,7 +1271,7 @@ hash_common_info(const Context& ctx, log("Hashing sanitize blacklist {}", sanitize_blacklist); hash.hash("sanitizeblacklist"); if (!hash_binary_file(ctx, hash, sanitize_blacklist)) { - throw Failure(STATS_BADEXTRAFILE); + throw Failure(Statistic::error_hashing_extra_file); } } @@ -1281,7 +1281,7 @@ hash_common_info(const Context& ctx, log("Hashing extra file {}", path); hash.hash_delimiter("extrafile"); if (!hash_binary_file(ctx, hash, path)) { - throw Failure(STATS_BADEXTRAFILE); + throw Failure(Statistic::error_hashing_extra_file); } } } @@ -1551,7 +1551,7 @@ calculate_result_name(Context& ctx, if (ctx.args_info.profile_use && !hash_profile_data_file(ctx, hash)) { log("No profile data file found"); - throw Failure(STATS_NOINPUT); + throw Failure(Statistic::no_input_file); } // Adding -arch to hash since cpp output is affected. @@ -1594,7 +1594,7 @@ calculate_result_name(Context& ctx, hash.hash_delimiter("sourcecode"); int result = hash_source_code_file(ctx, hash, ctx.args_info.input_file); if (result & HASH_SOURCE_CODE_ERROR) { - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } if (result & HASH_SOURCE_CODE_FOUND_TIME) { log("Disabling direct mode"); @@ -1637,7 +1637,7 @@ calculate_result_name(Context& ctx, } // Try to return the compile result from cache. -static optional +static optional from_cache(Context& ctx, enum fromcache_call_mode mode) { UmaskScope umask_scope(ctx.original_umask); @@ -1682,8 +1682,8 @@ from_cache(Context& ctx, enum fromcache_call_mode mode) MTR_END("cache", "from_cache"); - return mode == FROMCACHE_DIRECT_MODE ? STATS_CACHEHIT_DIR - : STATS_CACHEHIT_CPP; + return mode == FROMCACHE_DIRECT_MODE ? Statistic::direct_cache_hit + : Statistic::preprocessed_cache_hit; } // Find the real compiler. We just search the PATH to find an executable of the @@ -1730,7 +1730,7 @@ create_initial_config_file(Config& config) std::string stats_dir = fmt::format("{}/0", config.cache_dir()); if (Stat::stat(stats_dir)) { stats_get_obsolete_limits(stats_dir, &max_files, &max_size); - // STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory. + // Max files and max size were stored for each top directory. max_files *= 16; max_size *= 16; } else { @@ -1907,7 +1907,7 @@ set_up_uncached_err() dup(STDERR_FILENO); // The file descriptor is intentionally leaked. if (uncached_fd == -1) { log("dup(2) failed: {}", strerror(errno)); - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } Util::setenv("UNCACHED_ERR_FD", fmt::format("{}", uncached_fd)); @@ -1930,7 +1930,7 @@ configuration_printer(const std::string& key, } static int cache_compilation(int argc, const char* const* argv); -static enum stats do_cache_compilation(Context& ctx, const char* const* argv); +static Statistic do_cache_compilation(Context& ctx, const char* const* argv); // The entry point when invoked to cache a compilation. static int @@ -1948,11 +1948,11 @@ cache_compilation(int argc, const char* const* argv) MTR_END("main", "find_compiler"); try { - enum stats stat = do_cache_compilation(*ctx, argv); + Statistic stat = do_cache_compilation(*ctx, argv); stats_update(*ctx, stat); return EXIT_SUCCESS; } catch (const Failure& e) { - if (e.stat() != STATS_NONE) { + if (e.stat() != Statistic::none) { stats_update(*ctx, e.stat()); } @@ -1982,12 +1982,12 @@ cache_compilation(int argc, const char* const* argv) } } -static enum stats +static Statistic do_cache_compilation(Context& ctx, const char* const* argv) { if (ctx.actual_cwd.empty()) { log("Unable to determine current working directory: {}", strerror(errno)); - throw Failure(STATS_ERROR); + throw Failure(Statistic::internal_error); } MTR_BEGIN("main", "clean_up_internal_tempdir"); @@ -2002,8 +2002,8 @@ do_cache_compilation(Context& ctx, const char* const* argv) if (ctx.config.disable()) { log("ccache is disabled"); - // STATS_CACHEMISS is a dummy to trigger stats_flush. - throw Failure(STATS_CACHEMISS); + // Statistic::cache_miss is a dummy to trigger stats_flush. + throw Failure(Statistic::cache_miss); } MTR_BEGIN("main", "set_up_uncached_err"); @@ -2136,7 +2136,7 @@ do_cache_compilation(Context& ctx, const char* const* argv) if (ctx.config.read_only_direct()) { log("Read-only direct mode; running real compiler"); - throw Failure(STATS_CACHEMISS); + throw Failure(Statistic::cache_miss); } if (!ctx.config.depend_mode()) { @@ -2193,7 +2193,7 @@ do_cache_compilation(Context& ctx, const char* const* argv) if (ctx.config.read_only()) { log("Read-only mode; running real compiler"); - throw Failure(STATS_CACHEMISS); + throw Failure(Statistic::cache_miss); } add_prefix(ctx, compiler_args, ctx.config.prefix_command()); @@ -2208,7 +2208,7 @@ do_cache_compilation(Context& ctx, const char* const* argv) update_manifest_file(ctx); MTR_END("cache", "to_cache"); - return STATS_CACHEMISS; + return Statistic::cache_miss; } // The main program when not doing a compile. diff --git a/src/exceptions.hpp b/src/exceptions.hpp index defb1205c..b308bef32 100644 --- a/src/exceptions.hpp +++ b/src/exceptions.hpp @@ -84,21 +84,21 @@ inline Fatal::Fatal(T&&... args) // Throw a Failure if ccache did not succeed in getting or putting a result in // the cache. If `exit_code` is set, just exit with that code directly, // otherwise execute the real compiler and exit with its exit code. Also updates -// statistics counter `stat` if it's not STATS_NONE. +// statistics counter `stat` if it's not `Statistic::none`. class Failure : public std::exception { public: - Failure(enum stats stat, nonstd::optional exit_code = nonstd::nullopt); + Failure(Statistic stat, nonstd::optional exit_code = nonstd::nullopt); nonstd::optional exit_code() const; - enum stats stat() const; + Statistic stat() const; private: - enum stats m_stat; + Statistic m_stat; nonstd::optional m_exit_code; }; -inline Failure::Failure(enum stats stat, nonstd::optional exit_code) +inline Failure::Failure(Statistic stat, nonstd::optional exit_code) : m_stat(stat), m_exit_code(exit_code) { } @@ -109,7 +109,7 @@ Failure::exit_code() const return m_exit_code; } -inline enum stats +inline Statistic Failure::stat() const { return m_stat; diff --git a/src/stats.cpp b/src/stats.cpp index 7fb372ad5..b8eea4c6a 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -48,135 +48,163 @@ static std::string format_size_times_1024(uint64_t size); static std::string format_timestamp(uint64_t timestamp); // Statistics fields in display order. -static struct +static const struct { - enum stats stat; + Statistic stat; const char* id; // for --print-stats const char* message; // for --show-stats format_fn format; // nullptr -> use plain integer format unsigned flags; } stats_info[] = { - {STATS_ZEROTIMESTAMP, + {Statistic::stats_zeroed_timestamp, "stats_zeroed_timestamp", "stats zeroed", format_timestamp, FLAG_ALWAYS}, - {STATS_CACHEHIT_DIR, + {Statistic::direct_cache_hit, "direct_cache_hit", "cache hit (direct)", nullptr, FLAG_ALWAYS}, - {STATS_CACHEHIT_CPP, + {Statistic::preprocessed_cache_hit, "preprocessed_cache_hit", "cache hit (preprocessed)", nullptr, FLAG_ALWAYS}, - {STATS_CACHEMISS, "cache_miss", "cache miss", nullptr, FLAG_ALWAYS}, - {STATS_LINK, "called_for_link", "called for link", nullptr, 0}, - {STATS_PREPROCESSING, + {Statistic::cache_miss, "cache_miss", "cache miss", nullptr, FLAG_ALWAYS}, + {Statistic::called_for_link, + "called_for_link", + "called for link", + nullptr, + 0}, + {Statistic::called_for_preprocessing, "called_for_preprocessing", "called for preprocessing", nullptr, 0}, - {STATS_MULTIPLE, + {Statistic::multiple_source_files, "multiple_source_files", "multiple source files", nullptr, 0}, - {STATS_STDOUT, + {Statistic::compiler_produced_stdout, "compiler_produced_stdout", "compiler produced stdout", nullptr, 0}, - {STATS_NOOUTPUT, + {Statistic::compiler_produced_no_output, "compiler_produced_no_output", "compiler produced no output", nullptr, 0}, - {STATS_EMPTYOUTPUT, + {Statistic::compiler_produced_empty_output, "compiler_produced_empty_output", "compiler produced empty output", nullptr, 0}, - {STATS_STATUS, "compile_failed", "compile failed", nullptr, 0}, - {STATS_ERROR, "internal_error", "ccache internal error", nullptr, 0}, - {STATS_PREPROCESSOR, "preprocessor_error", "preprocessor error", nullptr, 0}, - {STATS_CANTUSEPCH, + {Statistic::compile_failed, "compile_failed", "compile failed", nullptr, 0}, + {Statistic::internal_error, + "internal_error", + "ccache internal error", + nullptr, + 0}, + {Statistic::preprocessor_error, + "preprocessor_error", + "preprocessor error", + nullptr, + 0}, + {Statistic::could_not_use_precompiled_header, "could_not_use_precompiled_header", "can't use precompiled header", nullptr, 0}, - {STATS_CANTUSEMODULES, + {Statistic::could_not_use_modules, "could_not_use_modules", "can't use modules", nullptr, 0}, - {STATS_COMPILER, + {Statistic::could_not_find_compiler, "could_not_find_compiler", "couldn't find the compiler", nullptr, 0}, - {STATS_MISSING, "missing_cache_file", "cache file missing", nullptr, 0}, - {STATS_ARGS, "bad_compiler_arguments", "bad compiler arguments", nullptr, 0}, - {STATS_SOURCELANG, + {Statistic::missing_cache_file, + "missing_cache_file", + "cache file missing", + nullptr, + 0}, + {Statistic::bad_compiler_arguments, + "bad_compiler_arguments", + "bad compiler arguments", + nullptr, + 0}, + {Statistic::unsupported_source_language, "unsupported_source_language", "unsupported source language", nullptr, 0}, - {STATS_COMPCHECK, + {Statistic::compiler_check_failed, "compiler_check_failed", "compiler check failed", nullptr, 0}, - {STATS_CONFTEST, "autoconf_test", "autoconf compile/link", nullptr, 0}, - {STATS_UNSUPPORTED_OPTION, + {Statistic::autoconf_test, + "autoconf_test", + "autoconf compile/link", + nullptr, + 0}, + {Statistic::unsupported_compiler_option, "unsupported_compiler_option", "unsupported compiler option", nullptr, 0}, - {STATS_UNSUPPORTED_DIRECTIVE, + {Statistic::unsupported_code_directive, "unsupported_code_directive", "unsupported code directive", nullptr, 0}, - {STATS_OUTSTDOUT, "output_to_stdout", "output to stdout", nullptr, 0}, - {STATS_BADOUTPUTFILE, + {Statistic::output_to_stdout, + "output_to_stdout", + "output to stdout", + nullptr, + 0}, + {Statistic::bad_output_file, "bad_output_file", "could not write to output file", nullptr, 0}, - {STATS_NOINPUT, "no_input_file", "no input file", nullptr, 0}, - {STATS_BADEXTRAFILE, + {Statistic::no_input_file, "no_input_file", "no input file", nullptr, 0}, + {Statistic::error_hashing_extra_file, "error_hashing_extra_file", "error hashing extra file", nullptr, 0}, - {STATS_NUMCLEANUPS, + {Statistic::cleanups_performed, "cleanups_performed", "cleanups performed", nullptr, FLAG_ALWAYS}, - {STATS_NUMFILES, + {Statistic::files_in_cache, "files_in_cache", "files in cache", nullptr, FLAG_NOZERO | FLAG_ALWAYS}, - {STATS_TOTALSIZE, + {Statistic::cache_size_kibibyte, "cache_size_kibibyte", "cache size", format_size_times_1024, FLAG_NOZERO | FLAG_ALWAYS}, - {STATS_OBSOLETE_MAXFILES, + {Statistic::obsolete_max_files, "OBSOLETE", "OBSOLETE", nullptr, FLAG_NOZERO | FLAG_NEVER}, - {STATS_OBSOLETE_MAXSIZE, + {Statistic::obsolete_max_size, "OBSOLETE", "OBSOLETE", nullptr, FLAG_NOZERO | FLAG_NEVER}, - {STATS_NONE, nullptr, nullptr, nullptr, 0}}; + {Statistic::none, nullptr, nullptr, nullptr, 0}}; static std::string format_size(uint64_t size) @@ -217,7 +245,7 @@ parse_stats(Counters& counters, const std::string& buf) if (p2 == p) { break; } - counters[i] += val; + counters[static_cast(i)] += val; i++; p = p2; } @@ -229,7 +257,7 @@ stats_write(const std::string& path, const Counters& counters) { AtomicFile file(path, AtomicFile::Mode::text); for (size_t i = 0; i < counters.size(); ++i) { - file.write(fmt::format("{}\n", counters[i])); + file.write(fmt::format("{}\n", counters[static_cast(i)])); } try { file.commit(); @@ -244,10 +272,10 @@ stats_write(const std::string& path, const Counters& counters) static double stats_hit_rate(const Counters& counters) { - unsigned direct = counters[STATS_CACHEHIT_DIR]; - unsigned preprocessed = counters[STATS_CACHEHIT_CPP]; + unsigned direct = counters[Statistic::direct_cache_hit]; + unsigned preprocessed = counters[Statistic::preprocessed_cache_hit]; unsigned hit = direct + preprocessed; - unsigned miss = counters[STATS_CACHEMISS]; + unsigned miss = counters[Statistic::cache_miss]; unsigned total = hit + miss; return total > 0 ? (100.0 * hit) / total : 0.0; } @@ -269,16 +297,17 @@ stats_collect(const Config& config, Counters& counters, time_t* last_updated) fname = fmt::format("{}/{:x}/stats", config.cache_dir(), dir); } - counters[STATS_ZEROTIMESTAMP] = 0; // Don't add + counters[Statistic::stats_zeroed_timestamp] = 0; // Don't add stats_read(fname, counters); - zero_timestamp = std::max(counters[STATS_ZEROTIMESTAMP], zero_timestamp); + zero_timestamp = + std::max(counters[Statistic::stats_zeroed_timestamp], zero_timestamp); auto st = Stat::stat(fname); if (st && st.mtime() > *last_updated) { *last_updated = st.mtime(); } } - counters[STATS_ZEROTIMESTAMP] = zero_timestamp; + counters[Statistic::stats_zeroed_timestamp] = zero_timestamp; } // Record that a number of bytes and files have been added to the cache. Size @@ -290,8 +319,8 @@ stats_update_size(Counters& counters, int64_t size, int files) return; } - counters[STATS_TOTALSIZE] += size / 1024; - counters[STATS_NUMFILES] += files; + counters[Statistic::cache_size_kibibyte] += size / 1024; + counters[Statistic::files_in_cache] += files; } // Read in the stats from one directory and add to the counters. @@ -343,8 +372,8 @@ stats_flush_to_file(const Config& config, } stats_read(sfile, counters); - for (int i = 0; i < STATS_END; ++i) { - counters[i] += updates[i]; + for (size_t i = 0; i < static_cast(Statistic::END); ++i) { + counters[static_cast(i)] += updates[static_cast(i)]; } stats_write(sfile, counters); } @@ -353,18 +382,19 @@ stats_flush_to_file(const Config& config, bool need_cleanup = false; if (config.max_files() != 0 - && counters[STATS_NUMFILES] > config.max_files() / 16) { + && counters[Statistic::files_in_cache] > config.max_files() / 16) { log("Need to clean up {} since it holds {} files (limit: {} files)", subdir, - counters[STATS_NUMFILES], + counters[Statistic::files_in_cache], config.max_files() / 16); need_cleanup = true; } if (config.max_size() != 0 - && counters[STATS_TOTALSIZE] > config.max_size() / 1024 / 16) { + && counters[Statistic::cache_size_kibibyte] + > config.max_size() / 1024 / 16) { log("Need to clean up {} since it holds {} KiB (limit: {} KiB)", subdir, - counters[STATS_TOTALSIZE], + counters[Statistic::cache_size_kibibyte], config.max_size() / 1024 / 16); need_cleanup = true; } @@ -388,9 +418,9 @@ stats_flush(Context& ctx) // Update a normal stat. void -stats_update(Context& ctx, enum stats stat) +stats_update(Context& ctx, Statistic stat) { - assert(stat > STATS_NONE && stat < STATS_END); + assert(stat > Statistic::none && stat < Statistic::END); ctx.counter_updates[stat] += 1; } @@ -419,7 +449,7 @@ stats_summary(const Context& ctx) // ...and display them. for (int i = 0; stats_info[i].message; i++) { - enum stats stat = stats_info[i].stat; + Statistic stat = stats_info[i].stat; if (stats_info[i].flags & FLAG_NEVER) { continue; @@ -438,7 +468,7 @@ stats_summary(const Context& ctx) fmt::print("{:31} {}\n", stats_info[i].message, value); } - if (stat == STATS_CACHEMISS) { + if (stat == Statistic::cache_miss) { double percent = stats_hit_rate(counters); fmt::print("cache hit rate {:6.2f} %\n", percent); } @@ -495,7 +525,7 @@ stats_zero(const Context& ctx) counters[stats_info[i].stat] = 0; } } - counters[STATS_ZEROTIMESTAMP] = timestamp; + counters[Statistic::stats_zeroed_timestamp] = timestamp; stats_write(fname, counters); } } @@ -513,8 +543,9 @@ stats_get_obsolete_limits(const std::string& dir, Counters counters; std::string sname = dir + "/stats"; stats_read(sname, counters); - *maxfiles = counters[STATS_OBSOLETE_MAXFILES]; - *maxsize = static_cast(counters[STATS_OBSOLETE_MAXSIZE]) * 1024; + *maxfiles = counters[Statistic::obsolete_max_files]; + *maxsize = + static_cast(counters[Statistic::obsolete_max_size]) * 1024; } // Set the per-directory sizes. @@ -526,8 +557,8 @@ stats_set_sizes(const std::string& dir, unsigned num_files, uint64_t total_size) Lockfile lock(statsfile); if (lock.acquired()) { stats_read(statsfile, counters); - counters[STATS_NUMFILES] = num_files; - counters[STATS_TOTALSIZE] = total_size / 1024; + counters[Statistic::files_in_cache] = num_files; + counters[Statistic::cache_size_kibibyte] = total_size / 1024; stats_write(statsfile, counters); } } @@ -541,7 +572,7 @@ stats_add_cleanup(const std::string& dir, unsigned count) Lockfile lock(statsfile); if (lock.acquired()) { stats_read(statsfile, counters); - counters[STATS_NUMCLEANUPS] += count; + counters[Statistic::cleanups_performed] += count; stats_write(statsfile, counters); } } diff --git a/src/stats.hpp b/src/stats.hpp index b0d5b37b3..0a36124d4 100644 --- a/src/stats.hpp +++ b/src/stats.hpp @@ -28,45 +28,45 @@ class Config; class Context; // Statistics fields in storage order. -enum stats { - STATS_NONE = 0, - STATS_STDOUT = 1, - STATS_STATUS = 2, - STATS_ERROR = 3, - STATS_CACHEMISS = 4, - STATS_PREPROCESSOR = 5, - STATS_COMPILER = 6, - STATS_MISSING = 7, - STATS_CACHEHIT_CPP = 8, - STATS_ARGS = 9, - STATS_LINK = 10, - STATS_NUMFILES = 11, - STATS_TOTALSIZE = 12, - STATS_OBSOLETE_MAXFILES = 13, - STATS_OBSOLETE_MAXSIZE = 14, - STATS_SOURCELANG = 15, - STATS_BADOUTPUTFILE = 16, - STATS_NOINPUT = 17, - STATS_MULTIPLE = 18, - STATS_CONFTEST = 19, - STATS_UNSUPPORTED_OPTION = 20, - STATS_OUTSTDOUT = 21, - STATS_CACHEHIT_DIR = 22, - STATS_NOOUTPUT = 23, - STATS_EMPTYOUTPUT = 24, - STATS_BADEXTRAFILE = 25, - STATS_COMPCHECK = 26, - STATS_CANTUSEPCH = 27, - STATS_PREPROCESSING = 28, - STATS_NUMCLEANUPS = 29, - STATS_UNSUPPORTED_DIRECTIVE = 30, - STATS_ZEROTIMESTAMP = 31, - STATS_CANTUSEMODULES = 32, +enum class Statistic { + none = 0, + compiler_produced_stdout = 1, + compile_failed = 2, + internal_error = 3, + cache_miss = 4, + preprocessor_error = 5, + could_not_find_compiler = 6, + missing_cache_file = 7, + preprocessed_cache_hit = 8, + bad_compiler_arguments = 9, + called_for_link = 10, + files_in_cache = 11, + cache_size_kibibyte = 12, + obsolete_max_files = 13, + obsolete_max_size = 14, + unsupported_source_language = 15, + bad_output_file = 16, + no_input_file = 17, + multiple_source_files = 18, + autoconf_test = 19, + unsupported_compiler_option = 20, + output_to_stdout = 21, + direct_cache_hit = 22, + compiler_produced_no_output = 23, + compiler_produced_empty_output = 24, + error_hashing_extra_file = 25, + compiler_check_failed = 26, + could_not_use_precompiled_header = 27, + called_for_preprocessing = 28, + cleanups_performed = 29, + unsupported_code_directive = 30, + stats_zeroed_timestamp = 31, + could_not_use_modules = 32, - STATS_END + END }; -void stats_update(Context& ctx, enum stats stat); +void stats_update(Context& ctx, Statistic stat); void stats_flush(Context& ctx); void stats_flush_to_file(const Config& config, const std::string& sfile, diff --git a/unittest/test_argprocessing.cpp b/unittest/test_argprocessing.cpp index 93f152b27..0d29e5076 100644 --- a/unittest/test_argprocessing.cpp +++ b/unittest/test_argprocessing.cpp @@ -82,7 +82,7 @@ TEST_CASE("dash_E_should_result_in_called_for_preprocessing") Util::write_file("foo.c", ""); CHECK(process_args(ctx, preprocessed, extra, compiler) - == STATS_PREPROCESSING); + == Statistic::called_for_preprocessing); } TEST_CASE("dash_M_should_be_unsupported") @@ -98,7 +98,7 @@ TEST_CASE("dash_M_should_be_unsupported") Util::write_file("foo.c", ""); CHECK(process_args(ctx, preprocessed, extra, compiler) - == STATS_UNSUPPORTED_OPTION); + == Statistic::unsupported_compiler_option); } TEST_CASE("dependency_args_to_preprocessor_if_run_second_cpp_is_false")