From: Joel Rosdahl Date: Wed, 4 Feb 2026 20:14:53 +0000 (+0100) Subject: refactor: Remove now unnecessary util::{starts,ends}_with X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b79f9ec35b1de186e924e3f9f467ad1504b523e;p=thirdparty%2Fccache.git refactor: Remove now unnecessary util::{starts,ends}_with --- diff --git a/src/ccache/argprocessing.cpp b/src/ccache/argprocessing.cpp index 40461349..ab16295d 100644 --- a/src/ccache/argprocessing.cpp +++ b/src/ccache/argprocessing.cpp @@ -276,11 +276,11 @@ process_profiling_option(const Context& ctx, return true; } - if (util::starts_with(arg, "-fprofile-update")) { + if (arg.starts_with("-fprofile-update")) { return true; } - if (util::starts_with(arg, "-fprofile-prefix-path=")) { + if (arg.starts_with("-fprofile-prefix-path=")) { args_info.profile_prefix_path = arg.substr(arg.find('=') + 1); LOG("Set profile prefix path to {}", args_info.profile_prefix_path); return true; @@ -289,7 +289,7 @@ process_profiling_option(const Context& ctx, fs::path new_profile_path; bool new_profile_use = false; - if (util::starts_with(arg, "-fprofile-dir=")) { + if (arg.starts_with("-fprofile-dir=")) { new_profile_path = arg.substr(arg.find('=') + 1); } else if (arg == "-fprofile-generate" || arg == "-fprofile-instr-generate") { args_info.profile_generate = true; @@ -299,8 +299,8 @@ process_profiling_option(const Context& ctx, // GCC uses $PWD/$(basename $obj). new_profile_path = ctx.apparent_cwd; } - } else if (util::starts_with(arg, "-fprofile-generate=") - || util::starts_with(arg, "-fprofile-instr-generate=")) { + } else if (arg.starts_with("-fprofile-generate=") + || arg.starts_with("-fprofile-instr-generate=")) { args_info.profile_generate = true; new_profile_path = arg.substr(arg.find('=') + 1); } else if (arg == "-fprofile-use" || arg == "-fprofile-instr-use" @@ -310,10 +310,10 @@ process_profiling_option(const Context& ctx, if (args_info.profile_path.empty()) { new_profile_path = "."; } - } else if (util::starts_with(arg, "-fprofile-use=") - || util::starts_with(arg, "-fprofile-instr-use=") - || util::starts_with(arg, "-fprofile-sample-use=") - || util::starts_with(arg, "-fauto-profile=")) { + } else if (arg.starts_with("-fprofile-use=") + || arg.starts_with("-fprofile-instr-use=") + || arg.starts_with("-fprofile-sample-use=") + || arg.starts_with("-fauto-profile=")) { new_profile_use = true; new_profile_path = arg.substr(arg.find('=') + 1); } else { @@ -347,7 +347,7 @@ std::string make_dash_option(const Config& config, const std::string& arg) { std::string new_arg = arg; - if (config.is_compiler_group_msvc() && util::starts_with(arg, "/")) { + if (config.is_compiler_group_msvc() && arg.starts_with("/")) { // MSVC understands both /option and -option, so convert all /option to // -option to simplify our handling. new_arg[0] = '-'; @@ -419,7 +419,7 @@ process_option_arg(const Context& ctx, } // Handle "@file" argument. - if (util::starts_with(arg, "@") || util::starts_with(arg, "-@")) { + if (arg.starts_with("@") || arg.starts_with("-@")) { const char* argpath = arg.c_str() + 1; if (argpath[-1] == '-') { @@ -469,10 +469,9 @@ process_option_arg(const Context& ctx, } // These are always too hard. - if (compopt_too_hard(arg) || util::starts_with(arg, "-fdump-") - || util::starts_with(arg, "-MJ") - || util::starts_with(arg, "--config-system-dir=") - || util::starts_with(arg, "--config-user-dir=")) { + if (compopt_too_hard(arg) || arg.starts_with("-fdump-") + || arg.starts_with("-MJ") || arg.starts_with("--config-system-dir=") + || arg.starts_with("--config-user-dir=")) { LOG("Compiler option {} is unsupported", args[i]); return Statistic::unsupported_compiler_option; } @@ -484,7 +483,7 @@ process_option_arg(const Context& ctx, } // Handle -Xpreprocessor options. - if (util::starts_with(arg, "-Xpreprocessor")) { + if (arg.starts_with("-Xpreprocessor")) { if (i == args.size() - 1) { LOG("Missing argument to {}", args[i]); return Statistic::bad_compiler_arguments; @@ -498,7 +497,7 @@ process_option_arg(const Context& ctx, } // Handle -Xarch_* options. - if (util::starts_with(arg, "-Xarch_")) { + if (arg.starts_with("-Xarch_")) { if (i == args.size() - 1) { LOG("Missing argument to {}", args[i]); return Statistic::bad_compiler_arguments; @@ -542,9 +541,9 @@ process_option_arg(const Context& ctx, arg = make_dash_option(ctx.config, args[i]); } - if (util::starts_with(arg, "-Wa,")) { + if (arg.starts_with("-Wa,")) { for (const auto part : util::Tokenizer(&arg[4], ",")) { - if (util::starts_with(part, "-a")) { + if (part.starts_with("-a")) { if (state.found_Wa_a_opt) { LOG_RAW( "Multiple assembler listing options (-Wa,-a) are not supported"); @@ -622,13 +621,13 @@ process_option_arg(const Context& ctx, if (config.is_compiler_group_msvc()) { // MSVC /Fo with no space. - if (util::starts_with(arg, "-Fo")) { + if (arg.starts_with("-Fo")) { args_info.output_obj = arg.substr(3); return Statistic::none; } // MSVC /Tc and /Tp options in concatenated form for specifying input file. - if (arg.length() > 3 && util::starts_with(arg, "-T") + if (arg.length() > 3 && arg.starts_with("-T") && (arg[2] == 'c' || arg[2] == 'p')) { args_info.input_file_prefix = arg.substr(0, 3); state.input_files.emplace_back(arg.substr(3)); @@ -669,7 +668,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-x")) { + if (arg.starts_with("-x")) { if (arg.length() >= 3 && !util::is_lower(arg[2])) { // -xCODE (where CODE can be e.g. Host or CORE-AVX2, always starting with // an uppercase letter) is an ordinary Intel compiler option, not a @@ -715,30 +714,29 @@ process_option_arg(const Context& ctx, // Cl does support it as deprecated, but also has -openmp or -link -out // which can confuse this and cause incorrect output_obj (and thus // ccache debug file location), so better ignore it. - if (util::starts_with(arg, "-o") - && config.compiler_type() != CompilerType::nvcc + if (arg.starts_with("-o") && config.compiler_type() != CompilerType::nvcc && config.compiler_type() != CompilerType::msvc) { args_info.output_obj = arg.substr(2); return Statistic::none; } - if (util::starts_with(arg, "-fdebug-prefix-map=") - || util::starts_with(arg, "-ffile-prefix-map=")) { + if (arg.starts_with("-fdebug-prefix-map=") + || arg.starts_with("-ffile-prefix-map=")) { std::string map = arg.substr(arg.find('=') + 1); args_info.debug_prefix_maps.push_back(map); state.add_common_arg(args[i]); return Statistic::none; } - if (util::starts_with(arg, "-fcoverage-prefix-map=")) { + if (arg.starts_with("-fcoverage-prefix-map=")) { std::string map = arg.substr(arg.find('=') + 1); args_info.coverage_prefix_maps.push_back(map); state.add_common_arg(args[i]); return Statistic::none; } - if (util::starts_with(arg, "-fdebug-compilation-dir") - || util::starts_with(arg, "-ffile-compilation-dir")) { + if (arg.starts_with("-fdebug-compilation-dir") + || arg.starts_with("-ffile-compilation-dir")) { std::string compilation_dir; // -ffile-compilation-dir cannot be followed by a space. if (arg == "-fdebug-compilation-dir") { @@ -761,7 +759,7 @@ process_option_arg(const Context& ctx, } if (std::string_view prefix{"-fcoverage-compilation-dir="}; - util::starts_with(arg, prefix)) { + arg.starts_with(prefix)) { args_info.coverage_compilation_dir = arg.substr(prefix.length()); state.add_common_arg(args[i]); return Statistic::none; @@ -769,17 +767,17 @@ process_option_arg(const Context& ctx, // Debugging is handled specially, so that we know if we can strip line // number info. - if (util::starts_with(arg, "-g")) { + if (arg.starts_with("-g")) { state.add_common_arg(args[i]); - if (util::starts_with(arg, "-gdwarf")) { + if (arg.starts_with("-gdwarf")) { // Selection of DWARF format (-gdwarf or -gdwarf-) enables // debug info on level 2. args_info.generating_debuginfo = true; return Statistic::none; } - if (util::starts_with(arg, "-gz")) { + if (arg.starts_with("-gz")) { // -gz[=type] neither disables nor enables debug info. return Statistic::none; } @@ -804,13 +802,13 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (config.is_compiler_group_msvc() && util::starts_with(arg, "-Fd")) { + if (config.is_compiler_group_msvc() && arg.starts_with("-Fd")) { state.add_compiler_only_arg_no_hash(args[i]); return Statistic::none; } if (config.is_compiler_group_msvc() - && (util::starts_with(arg, "-MP") || arg == "-FS")) { + && (arg.starts_with("-MP") || arg == "-FS")) { state.add_compiler_only_arg_no_hash(args[i]); return Statistic::none; } @@ -830,7 +828,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-MF") + if (arg.starts_with("-MF") // nvcc -MF: || arg == "--dependency-output") { state.found_mf_opt = true; @@ -865,8 +863,8 @@ process_option_arg(const Context& ctx, } if (!config.is_compiler_group_msvc() - && (util::starts_with(arg, "-MQ") - || util::starts_with(arg, "-MT") + && (arg.starts_with("-MQ") + || arg.starts_with("-MT") // nvcc -MT: || arg == "--dependency-target-name")) { const bool is_mq = arg[2] == 'Q'; @@ -904,8 +902,8 @@ process_option_arg(const Context& ctx, // MSVC -MD[d], -MT[d] and -LT[d] options are something different than GCC's // -MD etc. if (config.is_compiler_group_msvc() - && (util::starts_with(arg, "-MD") || util::starts_with(arg, "-MT") - || util::starts_with(arg, "-LD"))) { + && (arg.starts_with("-MD") || arg.starts_with("-MT") + || arg.starts_with("-LD"))) { // These affect compiler but also #define some things. state.add_common_arg(args[i]); return Statistic::none; @@ -938,7 +936,7 @@ process_option_arg(const Context& ctx, } // This covers all the different marker cases - if (util::starts_with(arg, "-fcallgraph-info")) { + if (arg.starts_with("-fcallgraph-info")) { args_info.generating_callgraphinfo = true; state.add_common_arg(args[i]); return Statistic::none; @@ -970,8 +968,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-fprofile-") - || util::starts_with(arg, "-fauto-profile") + if (arg.starts_with("-fprofile-") || arg.starts_with("-fauto-profile") || arg == "-fbranch-probabilities") { if (!process_profiling_option(ctx, args_info, arg)) { // The failure is logged by process_profiling_option. @@ -981,7 +978,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-fsanitize-blacklist=")) { + if (arg.starts_with("-fsanitize-blacklist=")) { auto path = std::string_view(args[i]).substr(21); args_info.sanitize_blacklists.emplace_back(path); auto relpath = core::make_relative_path(ctx, path); @@ -989,7 +986,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "--sysroot=")) { + if (arg.starts_with("--sysroot=")) { auto path = std::string_view(arg).substr(10); auto relpath = core::make_relative_path(ctx, path); state.add_common_arg(FMT("--sysroot={}", relpath)); @@ -1028,12 +1025,12 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-Wp,")) { - if (arg.find(",-P,") != std::string::npos || util::ends_with(arg, ",-P")) { + if (arg.starts_with("-Wp,")) { + if (arg.find(",-P,") != std::string::npos || arg.ends_with(",-P")) { LOG("-P together with other preprocessor options is too hard: {}", args[i]); return Statistic::unsupported_compiler_option; - } else if (util::starts_with(arg, "-Wp,-MD,") + } else if (arg.starts_with("-Wp,-MD,") && arg.find(',', 8) == std::string::npos) { state.found_wp_md_or_mmd_opt = true; args_info.generating_dependencies = true; @@ -1043,7 +1040,7 @@ process_option_arg(const Context& ctx, } state.add_compiler_only_arg(args[i]); return Statistic::none; - } else if (util::starts_with(arg, "-Wp,-MMD,") + } else if (arg.starts_with("-Wp,-MMD,") && arg.find(',', 9) == std::string::npos) { state.found_wp_md_or_mmd_opt = true; args_info.generating_dependencies = true; @@ -1053,14 +1050,12 @@ process_option_arg(const Context& ctx, } state.add_compiler_only_arg(args[i]); return Statistic::none; - } else if ((util::starts_with(arg, "-Wp,-D") - || util::starts_with(arg, "-Wp,-U")) + } else if ((arg.starts_with("-Wp,-D") || arg.starts_with("-Wp,-U")) && arg.find(',', 6) == std::string::npos) { state.add_common_arg(args[i]); return Statistic::none; } else if (arg == "-Wp,-MP" - || (arg.size() > 8 && util::starts_with(arg, "-Wp,-M") - && arg[7] == ',' + || (arg.size() > 8 && arg.starts_with("-Wp,-M") && arg[7] == ',' && (arg[6] == 'F' || arg[6] == 'Q' || arg[6] == 'T') && arg.find(',', 8) == std::string::npos)) { state.add_compiler_only_arg(args[i]); @@ -1085,7 +1080,7 @@ process_option_arg(const Context& ctx, } // Input charset needs to be handled specially. - if (util::starts_with(arg, "-finput-charset=")) { + if (arg.starts_with("-finput-charset=")) { state.input_charset_option = args[i]; return Statistic::none; } @@ -1104,13 +1099,13 @@ process_option_arg(const Context& ctx, const std::string_view source_dep_directives_opt = "-sourceDependencies:directives"; - if (util::starts_with(arg, source_dep_directives_opt)) { + if (arg.starts_with(source_dep_directives_opt)) { LOG("Compiler option {} is unsupported", args[i]); return Statistic::unsupported_compiler_option; } const std::string_view source_dep_opt = "-sourceDependencies"; - if (util::starts_with(arg, source_dep_opt)) { + if (arg.starts_with(source_dep_opt)) { // The generated file embeds absolute include paths resolved relative to the // actual working directory even when -I uses relative paths. To avoid false // positive cache hits across different working directories, bind the result @@ -1198,7 +1193,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (util::starts_with(arg, "-fbuild-session-file") + if (arg.starts_with("-fbuild-session-file") && !(config.sloppiness().contains(core::Sloppy::time_macros))) { args_info.build_session_file = arg.substr(arg.find('=') + 1); } @@ -1274,9 +1269,9 @@ process_option_arg(const Context& ctx, } // Detect PCH for options with concatenated path (relative or absolute). - if (util::starts_with(arg, "-include") || util::starts_with(arg, "-Fp") - || util::starts_with(arg, "-Yu") || util::starts_with(arg, "-Yc")) { - const size_t path_pos = util::starts_with(arg, "-include") ? 8 : 3; + if (arg.starts_with("-include") || arg.starts_with("-Fp") + || arg.starts_with("-Yu") || arg.starts_with("-Yc")) { + const size_t path_pos = arg.starts_with("-include") ? 8 : 3; if (!detect_pch(arg.substr(0, path_pos), arg.substr(path_pos), args_info, @@ -1815,8 +1810,7 @@ option_should_be_ignored(const std::string& arg, patterns.cbegin(), patterns.cend(), [&arg](const auto& pattern) { const auto& prefix = std::string_view(pattern).substr(0, pattern.length() - 1); - return ( - pattern == arg - || (util::ends_with(pattern, "*") && util::starts_with(arg, prefix))); + return (pattern == arg + || (pattern.ends_with("*") && arg.starts_with(prefix))); }); } diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index a33ad7fe..1debc0ac 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -421,8 +421,7 @@ remember_include_file(Context& ctx, if (!ctx.ignore_header_paths.empty()) { // Canonicalize path for comparison; Clang uses ./header.h. const std::string& canonical_path_str = - util::starts_with(path_str.str(), "./") ? path_str.str().substr(2) - : path_str; + path_str.str().starts_with("./") ? path_str.str().substr(2) : path_str; for (const auto& ignore_header_path : ctx.ignore_header_paths) { if (file_path_matches_dir_prefix_or_file(ignore_header_path, canonical_path_str)) { @@ -566,14 +565,14 @@ process_preprocessed_file(Context& ctx, Hash& hash, const fs::path& path) // GCC: && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9') // GCC precompiled header: - || util::starts_with(&q[1], pragma_gcc_pch_preprocess) + || std::string_view(&q[1]).starts_with(pragma_gcc_pch_preprocess) // HP/AIX: || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e' && q[5] == ' ')) && (q == data.data() || q[-1] == '\n')) { // Workarounds for preprocessor linemarker bugs in GCC version 6. if (q[2] == '3') { - if (util::starts_with(q, hash_31_command_line_newline)) { + if (std::string_view(q).starts_with(hash_31_command_line_newline)) { // Bogus extra line with #31, after the regular #1: Ignore the whole // line, and continue parsing. hash.hash(p, q - p); @@ -583,7 +582,8 @@ process_preprocessed_file(Context& ctx, Hash& hash, const fs::path& path) q++; p = q; continue; - } else if (util::starts_with(q, hash_32_command_line_2_newline)) { + } else if (std::string_view(q).starts_with( + hash_32_command_line_2_newline)) { // Bogus wrong line with #32, instead of regular #1: Replace the line // number with the usual one. hash.hash(p, q - p); @@ -1086,7 +1086,7 @@ rewrite_stdout_from_compiler(const Context& ctx, util::Bytes&& stdout_data) "\n", Mode::include_empty, IncludeDelimiter::yes)) { - if (util::starts_with(line, "__________")) { + if (line.starts_with("__________")) { // distcc-pump outputs lines like this: // // __________Using # distcc servers in pump mode @@ -1095,7 +1095,7 @@ rewrite_stdout_from_compiler(const Context& ctx, util::Bytes&& stdout_data) core::send_to_console(ctx, line, STDOUT_FILENO); } else if (ctx.config.compiler_type() == CompilerType::msvc && !ctx.config.base_dirs().empty() - && util::starts_with(line, ctx.config.msvc_dep_prefix())) { + && line.starts_with(ctx.config.msvc_dep_prefix())) { // Ninja uses the lines with 'Note: including file: ' to determine the // used headers. Headers within basedir need to be changed into relative // paths because otherwise Ninja will use the abs path to original @@ -1504,7 +1504,7 @@ hash_compiler(const Context& ctx, hash.hash_delimiter("cc_mtime"); hash.hash(dir_entry.size()); hash.hash(util::nsec_tot(dir_entry.mtime())); - } else if (util::starts_with(ctx.config.compiler_check(), "string:")) { + } else if (ctx.config.compiler_check().starts_with("string:")) { hash.hash_delimiter("cc_hash"); hash.hash(&ctx.config.compiler_check()[7]); } else if (ctx.config.compiler_check() == "content" || !allow_command) { @@ -1586,7 +1586,7 @@ apply_prefix_remapping(const std::vector& maps, fs::path& path) const std::string old_prefix{map.substr(0, sep_pos)}; const std::string new_prefix{map.substr(sep_pos + 1)}; - if (!util::starts_with(util::pstr(path).str(), old_prefix)) { + if (!util::pstr(path).str().starts_with(old_prefix)) { continue; } @@ -1954,7 +1954,7 @@ get_option_and_value(std::string_view option, const util::Args& args, size_t& i) } else { return {std::nullopt, std::nullopt}; } - } else if (util::starts_with(args[i], option)) { + } else if (args[i].starts_with(option)) { return {option, std::string_view(args[i]).substr(option.length())}; } else { return {std::nullopt, std::nullopt}; @@ -1985,16 +1985,16 @@ hash_argument(const Context& ctx, i++; return {}; } - if (util::starts_with(args[i], "-L") && !is_clang) { + if (args[i].starts_with("-L") && !is_clang) { return {}; } // -Wl,... doesn't affect compilation (except for clang). - if (util::starts_with(args[i], "-Wl,") && !is_clang) { + if (args[i].starts_with("-Wl,") && !is_clang) { return {}; } - if (util::starts_with(args[i], "-Wa,")) { + if (args[i].starts_with("-Wa,")) { // We have to distinguish between three cases: // // Case 1: -Wa,-a (write to stdout) @@ -2013,7 +2013,7 @@ hash_argument(const Context& ctx, } else { hash.hash(","); } - if (util::starts_with(part, "-a")) { + if (part.starts_with("-a")) { const auto eq_pos = part.find('='); if (eq_pos < part.size() - 1) { // Case 3: @@ -2032,35 +2032,35 @@ hash_argument(const Context& ctx, // CCACHE_BASEDIR to reuse results across different directories. Skip using // the value of the option from hashing but still hash the existence of the // option. - if (util::starts_with(args[i], "-fdebug-prefix-map=")) { + if (args[i].starts_with("-fdebug-prefix-map=")) { hash.hash_delimiter("arg"); hash.hash("-fdebug-prefix-map="); return {}; } - if (util::starts_with(args[i], "-ffile-prefix-map=")) { + if (args[i].starts_with("-ffile-prefix-map=")) { hash.hash_delimiter("arg"); hash.hash("-ffile-prefix-map="); return {}; } - if (util::starts_with(args[i], "-fmacro-prefix-map=")) { + if (args[i].starts_with("-fmacro-prefix-map=")) { hash.hash_delimiter("arg"); hash.hash("-fmacro-prefix-map="); return {}; } // -fprofile-prefix-path can also be used to reuse ccache results // across different directories - if (util::starts_with(args[i], "-fprofile-prefix-path=")) { + if (args[i].starts_with("-fprofile-prefix-path=")) { hash.hash_delimiter("arg"); hash.hash("-fprofile-prefix-path="); return {}; } - if (util::starts_with(args[i], "-fcoverage-prefix-map=")) { + if (args[i].starts_with("-fcoverage-prefix-map=")) { hash.hash_delimiter("arg"); hash.hash("-fcoverage-prefix-map="); return {}; } - if (util::starts_with(args[i], "-frandom-seed=") + if (args[i].starts_with("-frandom-seed=") && ctx.config.sloppiness().contains(core::Sloppy::random_seed)) { LOG("Ignoring {} since random_seed sloppiness is requested", args[i]); return {}; @@ -2068,7 +2068,7 @@ hash_argument(const Context& ctx, static const std::string_view frandomize_layout_seed_file = "-frandomize-layout-seed-file="; - if (util::starts_with(args[i], frandomize_layout_seed_file)) { + if (args[i].starts_with(frandomize_layout_seed_file)) { hash.hash_delimiter(frandomize_layout_seed_file); auto file = args[i].substr(frandomize_layout_seed_file.length()); if (!hash_binary_file(ctx, hash, file)) { @@ -2120,13 +2120,13 @@ hash_argument(const Context& ctx, } if (ctx.args_info.generating_dependencies) { - if (util::starts_with(args[i], "-Wp,")) { + if (args[i].starts_with("-Wp,")) { // Skip the dependency filename since it doesn't impact the output. - if (util::starts_with(args[i], "-Wp,-MD,") + if (args[i].starts_with("-Wp,-MD,") && args[i].find(',', 8) == std::string::npos) { hash.hash(args[i].data(), 8); return {}; - } else if (util::starts_with(args[i], "-Wp,-MMD,") + } else if (args[i].starts_with("-Wp,-MMD,") && args[i].find(',', 9) == std::string::npos) { hash.hash(args[i].data(), 9); return {}; @@ -2149,8 +2149,8 @@ hash_argument(const Context& ctx, } } - if (util::starts_with(args[i], "-specs=") || args[i] == "-specs" - || util::starts_with(args[i], "--specs=") || args[i] == "--specs") { + if (args[i].starts_with("-specs=") || args[i] == "-specs" + || args[i].starts_with("--specs=") || args[i] == "--specs") { auto [_option, specs] = util::split_once_into_views(args[i], '='); if (!specs) { if (i + 1 >= args.size()) { @@ -2163,7 +2163,7 @@ hash_argument(const Context& ctx, if (ctx.config.is_compiler_group_clang()) { // Clang accepts -specs but ignores it. - if (!util::ends_with(args[i], "=")) { + if (!args[i].ends_with("=")) { hash.hash_delimiter("arg"); hash.hash(args[i - 1]); } @@ -2188,7 +2188,7 @@ hash_argument(const Context& ctx, return {}; } - if (args[i] == "--config" || util::starts_with(args[i], "--config=")) { + if (args[i] == "--config" || args[i].starts_with("--config=")) { // Clang's --config(=)name option behaves like this: // // --config foo -> read /usr/lib/llvm-$ver/bin/foo.cfg (ver < 16) @@ -2228,7 +2228,7 @@ hash_argument(const Context& ctx, return {}; } - if (util::starts_with(args[i], "-fplugin=")) { + if (args[i].starts_with("-fplugin=")) { DirEntry dir_entry(&args[i][9], DirEntry::LogOnError::yes); if (dir_entry.is_regular_file()) { hash.hash_delimiter("plugin"); @@ -3112,7 +3112,7 @@ is_ccache_executable(const fs::path& path) #ifdef _WIN32 name = util::to_lowercase(name); #endif - return util::starts_with(name, "ccache"); + return name.starts_with("ccache"); } bool diff --git a/src/ccache/compiler/msvc.cpp b/src/ccache/compiler/msvc.cpp index 05eec4c2..24cb3581 100644 --- a/src/ccache/compiler/msvc.cpp +++ b/src/ccache/compiler/msvc.cpp @@ -35,7 +35,7 @@ get_includes_from_msvc_show_includes(std::string_view file_content, // This will split at each \r or \n, but that simply means there will be empty // "lines". for (std::string_view line : util::split_into_views(file_content, "\r\n")) { - if (util::starts_with(line, prefix)) { + if (line.starts_with(prefix)) { size_t pos = prefix.size(); while (pos < line.size() && util::is_space(line[pos])) { ++pos; @@ -67,7 +67,7 @@ strip_includes_from_msvc_show_includes(const Context& ctx, "\n", Mode::include_empty, IncludeDelimiter::yes)) { - if (!util::starts_with(line, ctx.config.msvc_dep_prefix())) { + if (!line.starts_with(ctx.config.msvc_dep_prefix())) { new_stdout_data.insert(new_stdout_data.end(), line.data(), line.size()); } } diff --git a/src/ccache/config.cpp b/src/ccache/config.cpp index 7ccdf9f3..79c1522b 100644 --- a/src/ccache/config.cpp +++ b/src/ccache/config.cpp @@ -763,7 +763,7 @@ Config::update_from_environment() for (char** env = environ; *env; ++env) { std::string setting = *env; const std::string prefix = "CCACHE_"; - if (!util::starts_with(setting, prefix)) { + if (!setting.starts_with(prefix)) { continue; } size_t equal_pos = setting.find('='); @@ -773,7 +773,7 @@ Config::update_from_environment() std::string key = setting.substr(prefix.size(), equal_pos - prefix.size()); std::string value = setting.substr(equal_pos + 1); - bool negate = util::starts_with(key, "NO"); + bool negate = key.starts_with("NO"); if (negate) { key = key.substr(2); } @@ -884,7 +884,7 @@ Config::get_string_value(const std::string& key) const case ConfigItem::max_size: { auto result = util::format_human_readable_size(m_max_size, m_size_prefix_type); - if (util::ends_with(result, " bytes")) { + if (result.ends_with(" bytes")) { // Special case to make the output parsable by util::parse_size. result.resize(result.size() - 6); } diff --git a/src/ccache/core/common.cpp b/src/ccache/core/common.cpp index 9106b27f..92ee8616 100644 --- a/src/ccache/core/common.cpp +++ b/src/ccache/core/common.cpp @@ -98,7 +98,7 @@ parse_inlined_from_msg(std::string_view& line, std::string& result) static const std::string_view inlined_from_msg = " inlined from "; static const std::string_view inlined_from_msg_separator = " at "; - if (!util::starts_with(line, inlined_from_msg)) { + if (!line.starts_with(inlined_from_msg)) { return false; } @@ -131,7 +131,7 @@ parse_in_file_included_from_msg(std::string_view& line, std::string& result) }; for (const auto& in_file_included_from : in_file_included_from_msgs) { - if (util::starts_with(line, in_file_included_from)) { + if (line.starts_with(in_file_included_from)) { result += in_file_included_from; line = line.substr(in_file_included_from.length()); return true; diff --git a/src/ccache/storage/local/util.cpp b/src/ccache/storage/local/util.cpp index 984bcea5..495a844a 100644 --- a/src/ccache/storage/local/util.cpp +++ b/src/ccache/storage/local/util.cpp @@ -79,7 +79,7 @@ get_cache_dir_files(const fs::path& dir) util::traverse_directory(dir, [&](const auto& de) { std::string name = util::pstr(de.path().filename()); if (name == "CACHEDIR.TAG" || name == "stats" - || util::starts_with(name, ".nfs")) { + || name.starts_with(".nfs")) { return; } diff --git a/src/ccache/storage/remote/helper.cpp b/src/ccache/storage/remote/helper.cpp index e5e9a2d2..707c4e9a 100644 --- a/src/ccache/storage/remote/helper.cpp +++ b/src/ccache/storage/remote/helper.cpp @@ -184,8 +184,8 @@ is_ccache_crsh_var(std::string_view entry) return name == "CRSH_IPC_ENDPOINT" || name == "CRSH_URL" || name == "CRSH_IDLE_TIMEOUT" || name == "CRSH_NUM_ATTR" - || util::starts_with(name, "CRSH_ATTR_KEY_") - || util::starts_with(name, "CRSH_ATTR_VALUE_"); + || name.starts_with("CRSH_ATTR_KEY_") + || name.starts_with("CRSH_ATTR_VALUE_"); } #ifndef _WIN32 @@ -248,7 +248,7 @@ spawn_helper(const fs::path& helper_path, #ifdef _WIN32 // Don't pass \\.\pipe\ prefix on Windows. - DEBUG_ASSERT(util::starts_with(endpoint, k_named_pipe_prefix)); + DEBUG_ASSERT(endpoint.starts_with(k_named_pipe_prefix)); auto ipc_endpoint = endpoint.substr(k_named_pipe_prefix.length()); #else const auto& ipc_endpoint = endpoint; diff --git a/src/ccache/util/args.cpp b/src/ccache/util/args.cpp index a77ed611..a3d081e1 100644 --- a/src/ccache/util/args.cpp +++ b/src/ccache/util/args.cpp @@ -224,8 +224,8 @@ Args::erase_last(std::string_view arg) void Args::erase_with_prefix(std::string_view prefix) { - std::erase_if( - m_args, [&prefix](const auto& s) { return util::starts_with(s, prefix); }); + std::erase_if(m_args, + [&prefix](const auto& s) { return s.starts_with(prefix); }); } void diff --git a/src/ccache/util/string.cpp b/src/ccache/util/string.cpp index 423c0f4b..9eca073d 100644 --- a/src/ccache/util/string.cpp +++ b/src/ccache/util/string.cpp @@ -67,7 +67,8 @@ format_argv_as_win32_command_string(const char* const* argv, } std::string result; - if (getenv("_CCACHE_TEST") && argv[0] && util::ends_with(argv[0], ".sh")) { + if (getenv("_CCACHE_TEST") && argv[0] + && std::string_view(argv[0]).ends_with(".sh")) { result += "sh.exe "; } @@ -453,7 +454,7 @@ parse_unsigned(std::string_view value, size_t end = 0; unsigned long long result = 0; bool failed = false; - if (starts_with(stripped_value, "-")) { + if (stripped_value.starts_with("-")) { failed = true; } else { try { diff --git a/src/ccache/util/string.hpp b/src/ccache/util/string.hpp index bc27ded1..b9bc31bf 100644 --- a/src/ccache/util/string.hpp +++ b/src/ccache/util/string.hpp @@ -46,9 +46,6 @@ class Bytes; enum class SizeUnitPrefixType { binary, decimal }; enum class TimeZone { local, utc }; -// Return true if `suffix` is a suffix of `string`. -bool ends_with(std::string_view string, std::string_view suffix); - // Recreate a Windows command line string based on `argv`. If `prefix` is // non-empty, add it as the first argument. If `escape_backslashes` is true, // emit an additional backslash for each backslash that is not preceding '"' and @@ -226,12 +223,6 @@ split_option_with_concat_path(std::string_view string); // %PATH% on Windows platforms) into paths. std::vector split_path_list(std::string_view path_list); -// Return true if `prefix` is a prefix of `string`. -bool starts_with(const char* string, std::string_view prefix); - -// Return true if `prefix` is a prefix of `string`. -bool starts_with(std::string_view string, std::string_view prefix); - // Strip whitespace from left and right side of a string. [[nodiscard]] std::string strip_whitespace(std::string_view string); @@ -243,13 +234,6 @@ char to_lower(char ch); // --- Inline implementations --- -inline bool -ends_with(const std::string_view string, const std::string_view suffix) -{ - return string.length() >= suffix.length() - && string.substr(string.length() - suffix.length()) == suffix; -} - inline bool is_alnum(char ch) { @@ -301,20 +285,6 @@ join(const T& begin, const T& end, const std::string_view delimiter) return result; } -inline bool -starts_with(const char* const string, const std::string_view prefix) -{ - // Optimized version of starts_with(string_view, string_view): avoid computing - // the length of the string argument. - return std::strncmp(string, prefix.data(), prefix.length()) == 0; -} - -inline bool -starts_with(const std::string_view string, const std::string_view prefix) -{ - return string.substr(0, prefix.size()) == prefix; -} - inline char to_lower(char ch) { diff --git a/unittest/test_argprocessing.cpp b/unittest/test_argprocessing.cpp index b2db1ece..763035f5 100644 --- a/unittest/test_argprocessing.cpp +++ b/unittest/test_argprocessing.cpp @@ -690,8 +690,7 @@ TEST_CASE("-x") // MSVC's /U option, so disable the test case there. This will be possible to // improve when/if a compiler abstraction is introduced (issue #956). TEST_CASE("MSVC options" - * doctest::skip(util::starts_with(fs::current_path()->string(), - "/U"))) + * doctest::skip(fs::current_path()->string().starts_with("/U"))) { TestContext test_context; Context ctx; diff --git a/unittest/test_util_exec.cpp b/unittest/test_util_exec.cpp index 7c56732c..42b3da95 100644 --- a/unittest/test_util_exec.cpp +++ b/unittest/test_util_exec.cpp @@ -55,7 +55,7 @@ TEST_CASE("util::exec_to_string") auto result = exec_to_string({"doesnotexist"}); REQUIRE(!result); #ifdef _WIN32 - CHECK(util::starts_with(result.error(), "CreateProcess failure: ")); + CHECK(result.error().starts_with("CreateProcess failure: ")); #else CHECK(result.error() == "posix_spawnp failed: No such file or directory"); #endif diff --git a/unittest/test_util_file.cpp b/unittest/test_util_file.cpp index 16ffd705..ec5a24b1 100644 --- a/unittest/test_util_file.cpp +++ b/unittest/test_util_file.cpp @@ -181,8 +181,8 @@ TEST_CASE("util::read_file with UTF-16 little endian encoding") CHECK(util::write_file("test", data)); read_data = util::read_file("test"); REQUIRE(!read_data); - REQUIRE(util::starts_with(read_data.error(), - "Failed to convert test from UTF-16LE to UTF-8:")); + REQUIRE(read_data.error().starts_with( + "Failed to convert test from UTF-16LE to UTF-8:")); } #endif diff --git a/unittest/test_util_string.cpp b/unittest/test_util_string.cpp index 4b90db0d..9421dd5b 100644 --- a/unittest/test_util_string.cpp +++ b/unittest/test_util_string.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2025 Joel Rosdahl and other contributors +// Copyright (C) 2021-2026 Joel Rosdahl and other contributors // // See doc/authors.adoc for a complete list of contributors. // @@ -255,24 +255,6 @@ TEST_CASE("util::format_base32hex") CHECK(util::format_base32hex({input, 6}) == "cpnmuoj1e8"); } -TEST_CASE("util::ends_with") -{ - CHECK(util::ends_with("", "")); - CHECK(util::ends_with("x", "")); - CHECK(util::ends_with("x", "x")); - CHECK(util::ends_with("xy", "")); - CHECK(util::ends_with("xy", "y")); - CHECK(util::ends_with("xy", "xy")); - CHECK(util::ends_with("xyz", "")); - CHECK(util::ends_with("xyz", "z")); - CHECK(util::ends_with("xyz", "yz")); - CHECK(util::ends_with("xyz", "xyz")); - - CHECK_FALSE(util::ends_with("", "x")); - CHECK_FALSE(util::ends_with("x", "y")); - CHECK_FALSE(util::ends_with("x", "xy")); -} - TEST_CASE("util::format_human_readable_diff") { using SUPT = util::SizeUnitPrefixType; @@ -772,41 +754,6 @@ TEST_CASE("util::split_path_list") } } -TEST_CASE("util::starts_with") -{ - // starts_with(const char*, string_view) - CHECK(util::starts_with("", "")); - CHECK(util::starts_with("x", "")); - CHECK(util::starts_with("x", "x")); - CHECK(util::starts_with("xy", "")); - CHECK(util::starts_with("xy", "x")); - CHECK(util::starts_with("xy", "xy")); - CHECK(util::starts_with("xyz", "")); - CHECK(util::starts_with("xyz", "x")); - CHECK(util::starts_with("xyz", "xy")); - CHECK(util::starts_with("xyz", "xyz")); - - CHECK_FALSE(util::starts_with("", "x")); - CHECK_FALSE(util::starts_with("x", "y")); - CHECK_FALSE(util::starts_with("x", "xy")); - - // starts_with(string_view, string_view) - CHECK(util::starts_with(std::string(""), "")); - CHECK(util::starts_with(std::string("x"), "")); - CHECK(util::starts_with(std::string("x"), "x")); - CHECK(util::starts_with(std::string("xy"), "")); - CHECK(util::starts_with(std::string("xy"), "x")); - CHECK(util::starts_with(std::string("xy"), "xy")); - CHECK(util::starts_with(std::string("xyz"), "")); - CHECK(util::starts_with(std::string("xyz"), "x")); - CHECK(util::starts_with(std::string("xyz"), "xy")); - CHECK(util::starts_with(std::string("xyz"), "xyz")); - - CHECK_FALSE(util::starts_with(std::string(""), "x")); - CHECK_FALSE(util::starts_with(std::string("x"), "y")); - CHECK_FALSE(util::starts_with(std::string("x"), "xy")); -} - TEST_CASE("util::strip_whitespace") { CHECK(util::strip_whitespace("") == "");