From: Joel Rosdahl Date: Wed, 29 Jul 2020 18:31:53 +0000 (+0200) Subject: C++-ify hashutil functions X-Git-Tag: v4.0~259 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d536ae7e1b8b9c532d3a56133ee671584e3926ca;p=thirdparty%2Fccache.git C++-ify hashutil functions --- diff --git a/src/ccache.cpp b/src/ccache.cpp index eb2f3f1c3..626a6e96b 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -344,7 +344,7 @@ do_remember_include_file(Context& ctx, } } - if (!hash_binary_file(ctx, fhash, path.c_str())) { + if (!hash_binary_file(ctx, fhash, path)) { return false; } cpp_hash.hash_delimiter(using_pch_sum ? "pch_sum_hash" : "pch_hash"); @@ -353,7 +353,7 @@ do_remember_include_file(Context& ctx, if (ctx.config.direct_mode()) { if (!is_pch) { // else: the file has already been hashed. - int result = hash_source_code_file(ctx, fhash, path.c_str()); + int result = hash_source_code_file(ctx, fhash, path); if (result & HASH_SOURCE_CODE_ERROR || result & HASH_SOURCE_CODE_FOUND_TIME) { return false; @@ -1073,7 +1073,7 @@ get_result_name_from_cpp(Context& ctx, Args& args, Hash& hash) hash.hash_delimiter("cppstderr"); if (!ctx.args_info.direct_i_file - && !hash_binary_file(ctx, hash, stderr_path.c_str())) { + && !hash_binary_file(ctx, hash, stderr_path)) { // Somebody removed the temporary file? cc_log("Failed to open %s: %s", stderr_path.c_str(), strerror(errno)); failed(STATS_ERROR); @@ -1123,9 +1123,8 @@ hash_compiler(const Context& ctx, hash.hash_delimiter("cc_content"); hash_binary_file(ctx, hash, path); } else { // command string - if (!hash_multicommand_output(hash, - ctx.config.compiler_check().c_str(), - ctx.orig_args[0].c_str())) { + if (!hash_multicommand_output( + hash, ctx.config.compiler_check(), ctx.orig_args[0])) { cc_log("Failure running compiler check command: %s", ctx.config.compiler_check().c_str()); failed(STATS_COMPCHECK); @@ -1294,7 +1293,7 @@ hash_common_info(const Context& ctx, for (const auto& sanitize_blacklist : args_info.sanitize_blacklists) { cc_log("Hashing sanitize blacklist %s", sanitize_blacklist.c_str()); hash.hash("sanitizeblacklist"); - if (!hash_binary_file(ctx, hash, sanitize_blacklist.c_str())) { + if (!hash_binary_file(ctx, hash, sanitize_blacklist)) { failed(STATS_BADEXTRAFILE); } } @@ -1304,7 +1303,7 @@ hash_common_info(const Context& ctx, ctx.config.extra_files_to_hash(), PATH_DELIM)) { cc_log("Hashing extra file %s", path.c_str()); hash.hash_delimiter("extrafile"); - if (!hash_binary_file(ctx, hash, path.c_str())) { + if (!hash_binary_file(ctx, hash, path)) { failed(STATS_BADEXTRAFILE); } } @@ -1348,7 +1347,7 @@ hash_profile_data_file(const Context& ctx, Hash& hash) if (st && !st.is_directory()) { cc_log("Adding profile data %s to the hash", p.c_str()); hash.hash_delimiter("-fprofile-use"); - if (hash_binary_file(ctx, hash, p.c_str())) { + if (hash_binary_file(ctx, hash, p)) { found = true; } } @@ -1622,8 +1621,7 @@ calculate_result_name(Context& ctx, hash.hash(ctx.args_info.input_file); hash.hash_delimiter("sourcecode"); - int result = - hash_source_code_file(ctx, hash, ctx.args_info.input_file.c_str()); + int result = hash_source_code_file(ctx, hash, ctx.args_info.input_file); if (result & HASH_SOURCE_CODE_ERROR) { failed(STATS_ERROR); } diff --git a/src/hashutil.cpp b/src/hashutil.cpp index e09a349cb..12f5761c8 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -37,17 +37,15 @@ # include "Win32Util.hpp" #endif -#include "third_party/xxhash.h" - // With older GCC (libgcc), __builtin_cpu_supports("avx2) returns true if AVX2 // is supported by the CPU but disabled by the OS. This was fixed in GCC 8, 7.4 // and 6.5 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100). // // For Clang it seems to be correct if compiler-rt is used as -rtlib, at least -// as of 3.9 (see https://bugs.llvm.org/show_bug.cgi?id=25510). But if libgcc -// is used we have the same problem as mentioned above. Unfortunately there -// doesn't seem to be a way to detect which one is used, or the version of -// libgcc when used by Clang, so assume that it works with Clang >= 3.9. +// as of 3.9 (see https://bugs.llvm.org/show_bug.cgi?id=25510). But if libgcc is +// used we have the same problem as mentioned above. Unfortunately there doesn't +// seem to be a way to detect which one is used, or the version of libgcc when +// used by Clang, so assume that it works with Clang >= 3.9. #if !(__GNUC__ >= 8 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 4) \ || (__GNUC__ == 6 && __GNUC_MINOR__ >= 5) || __clang_major__ > 3 \ || (__clang_major__ == 3 && __clang_minor__ >= 9)) @@ -58,35 +56,40 @@ # include #endif +using nonstd::string_view; + +namespace { + // Returns one of HASH_SOURCE_CODE_FOUND_DATE, HASH_SOURCE_CODE_FOUND_TIME or // HASH_SOURCE_CODE_FOUND_TIMESTAMP if "_DATE__", "_TIME__" or "_TIMESTAMP__" // starts at str[pos]. // // Pre-condition: str[pos - 1] == '_' -static int -check_for_temporal_macros_helper(const char* str, size_t len, size_t pos) +int +check_for_temporal_macros_helper(string_view str, size_t pos) { - if (pos + 7 > len) { + if (pos + 7 > str.length()) { return 0; } int found = 0; int macro_len = 7; - if (memcmp(str + pos, "_DATE__", 7) == 0) { + if (memcmp(&str[pos], "_DATE__", 7) == 0) { found = HASH_SOURCE_CODE_FOUND_DATE; - } else if (memcmp(str + pos, "_TIME__", 7) == 0) { + } else if (memcmp(&str[pos], "_TIME__", 7) == 0) { found = HASH_SOURCE_CODE_FOUND_TIME; - } else if (pos + 12 <= len && memcmp(str + pos, "_TIMESTAMP__", 12) == 0) { + } else if (pos + 12 <= str.length() + && memcmp(&str[pos], "_TIMESTAMP__", 12) == 0) { found = HASH_SOURCE_CODE_FOUND_TIMESTAMP; macro_len = 12; } else { return 0; } - // Check char before and after macro to verify that the found macro isn't - // part of another identifier. + // Check char before and after macro to verify that the found macro isn't part + // of another identifier. if ((pos == 1 || (str[pos - 2] != '_' && !isalnum(str[pos - 2]))) - && (pos + macro_len == len + && (pos + macro_len == str.length() || (str[pos + macro_len] != '_' && !isalnum(str[pos + macro_len])))) { return found; } @@ -94,8 +97,8 @@ check_for_temporal_macros_helper(const char* str, size_t len, size_t pos) return 0; } -static int -check_for_temporal_macros_bmh(const char* str, size_t len) +int +check_for_temporal_macros_bmh(string_view str) { int result = 0; @@ -104,12 +107,12 @@ check_for_temporal_macros_bmh(const char* str, size_t len) // starts at 7. size_t i = 7; - while (i < len) { + while (i < str.length()) { // Check whether the substring ending at str[i] has the form "_....E..". On // the assumption that 'E' is less common in source than '_', we check // str[i-2] first. if (str[i - 2] == 'E' && str[i - 7] == '_') { - result |= check_for_temporal_macros_helper(str, len, i - 6); + result |= check_for_temporal_macros_helper(str, i - 6); } // macro_skip tells us how far we can skip forward upon seeing str[i] at @@ -121,14 +124,14 @@ check_for_temporal_macros_bmh(const char* str, size_t len) } #ifdef HAVE_AVX2 -static int check_for_temporal_macros_avx2(const char* str, size_t len) +int check_for_temporal_macros_avx2(string_view str) __attribute__((target("avx2"))); // The following algorithm, which uses AVX2 instructions to find __DATE__, // __TIME__ and __TIMESTAMP__, is heavily inspired by // . -static int -check_for_temporal_macros_avx2(const char* str, size_t len) +int +check_for_temporal_macros_avx2(string_view str) { int result = 0; @@ -137,14 +140,14 @@ check_for_temporal_macros_avx2(const char* str, size_t len) const __m256i last = _mm256_set1_epi8('E'); size_t pos = 0; - for (; pos + 5 + 32 <= len; pos += 32) { + for (; pos + 5 + 32 <= str.length(); pos += 32) { // Load 32 bytes from the current position in the input string, with // block_last being offset 5 bytes (i.e. the offset of 'E' in all three // macros). const __m256i block_first = - _mm256_loadu_si256(reinterpret_cast(str + pos)); + _mm256_loadu_si256(reinterpret_cast(&str[pos])); const __m256i block_last = - _mm256_loadu_si256(reinterpret_cast(str + pos + 5)); + _mm256_loadu_si256(reinterpret_cast(&str[pos + 5])); // For i in 0..31: // eq_X[i] = 0xFF if X[i] == block_X[i] else 0 @@ -163,50 +166,87 @@ check_for_temporal_macros_avx2(const char* str, size_t len) // Clear the least significant bit set. mask = mask & (mask - 1); - result |= check_for_temporal_macros_helper(str, len, start); + result |= check_for_temporal_macros_helper(str, start); } } - result |= check_for_temporal_macros_bmh(str + pos, len - pos); + result |= check_for_temporal_macros_bmh(str.substr(pos)); return result; } #endif -// Search for the strings "__DATE__", "__TIME__" and "__TIMESTAMP__" in str. -// -// Returns a bitmask with HASH_SOURCE_CODE_FOUND_DATE, -// HASH_SOURCE_CODE_FOUND_TIME and HASH_SOURCE_CODE_FOUND_TIMESTAMP set -// appropriately. int -check_for_temporal_macros(const char* str, size_t len) +hash_source_code_file_nocache(const Context& ctx, + Hash& hash, + const std::string& path, + size_t size_hint, + bool is_precompiled) +{ + if (is_precompiled) { + if (hash.hash_file(path)) { + return HASH_SOURCE_CODE_OK; + } else { + return HASH_SOURCE_CODE_ERROR; + } + } else { + std::string data; + try { + data = Util::read_file(path, size_hint); + } catch (Error&) { + return HASH_SOURCE_CODE_ERROR; + } + int result = hash_source_code_string(ctx, hash, data, path); + return result; + } +} + +#ifdef INODE_CACHE_SUPPORTED +InodeCache::ContentType +get_content_type(const Config& config, const std::string& path) +{ + if (Util::is_precompiled_header(path)) { + return InodeCache::ContentType::precompiled_header; + } + if (config.sloppiness() & SLOPPY_TIME_MACROS) { + return InodeCache::ContentType::code_with_sloppy_time_macros; + } + return InodeCache::ContentType::code; +} +#endif + +} // namespace + +int +check_for_temporal_macros(string_view str) { #ifdef HAVE_AVX2 if (__builtin_cpu_supports("avx2")) { - return check_for_temporal_macros_avx2(str, len); + return check_for_temporal_macros_avx2(str); } #endif - return check_for_temporal_macros_bmh(str, len); + return check_for_temporal_macros_bmh(str); } -// Hash a string. Returns a bitmask of HASH_SOURCE_CODE_* results. int -hash_source_code_string( - const Context& ctx, Hash& hash, const char* str, size_t len, const char* path) +hash_source_code_string(const Context& ctx, + Hash& hash, + string_view str, + const std::string& path) { int result = HASH_SOURCE_CODE_OK; // Check for __DATE__, __TIME__ and __TIMESTAMP__if the sloppiness // configuration tells us we should. if (!(ctx.config.sloppiness() & SLOPPY_TIME_MACROS)) { - result |= check_for_temporal_macros(str, len); + result |= check_for_temporal_macros(str); } // Hash the source string. - hash.hash(str, len); + hash.hash(str); if (result & HASH_SOURCE_CODE_FOUND_DATE) { - cc_log("Found __DATE__ in %s", path); + cc_log("Found __DATE__ in %s", path.c_str()); // Make sure that the hash sum changes if the (potential) expansion of // __DATE__ changes. @@ -221,16 +261,15 @@ hash_source_code_string( hash.hash(now.tm_mday); } if (result & HASH_SOURCE_CODE_FOUND_TIME) { - // We don't know for sure that the program actually uses the __TIME__ - // macro, but we have to assume it anyway and hash the time stamp. However, - // that's not very useful since the chance that we get a cache hit later - // the same second should be quite slim... So, just signal back to the - // caller that __TIME__ has been found so that the direct mode can be - // disabled. - cc_log("Found __TIME__ in %s", path); + // We don't know for sure that the program actually uses the __TIME__ macro, + // but we have to assume it anyway and hash the time stamp. However, that's + // not very useful since the chance that we get a cache hit later the same + // second should be quite slim... So, just signal back to the caller that + // __TIME__ has been found so that the direct mode can be disabled. + cc_log("Found __TIME__ in %s", path.c_str()); } if (result & HASH_SOURCE_CODE_FOUND_TIMESTAMP) { - cc_log("Found __TIMESTAMP__ in %s", path); + cc_log("Found __TIMESTAMP__ in %s", path.c_str()); // Make sure that the hash sum changes if the (potential) expansion of // __TIMESTAMP__ changes. @@ -261,52 +300,10 @@ hash_source_code_string( return result; } -static int -hash_source_code_file_nocache(const Context& ctx, - Hash& hash, - const char* path, - size_t size_hint, - bool is_precompiled) -{ - if (is_precompiled) { - if (hash.hash_file(path)) { - return HASH_SOURCE_CODE_OK; - } else { - return HASH_SOURCE_CODE_ERROR; - } - } else { - std::string data; - try { - data = Util::read_file(path, size_hint); - } catch (Error&) { - return HASH_SOURCE_CODE_ERROR; - } - int result = - hash_source_code_string(ctx, hash, data.data(), data.size(), path); - return result; - } -} - -#ifdef INODE_CACHE_SUPPORTED -static InodeCache::ContentType -get_content_type(const Config& config, const char* path) -{ - if (Util::is_precompiled_header(path)) { - return InodeCache::ContentType::precompiled_header; - } - if (config.sloppiness() & SLOPPY_TIME_MACROS) { - return InodeCache::ContentType::code_with_sloppy_time_macros; - } - return InodeCache::ContentType::code; -} -#endif - -// Hash a file ignoring comments. Returns a bitmask of HASH_SOURCE_CODE_* -// results. int hash_source_code_file(const Context& ctx, Hash& hash, - const char* path, + const std::string& path, size_t size_hint) { #ifdef INODE_CACHE_SUPPORTED @@ -343,11 +340,8 @@ hash_source_code_file(const Context& ctx, #endif } -// Hash a binary file using the inode cache if enabled. -// -// Returns true on success, otherwise false. bool -hash_binary_file(const Context& ctx, Hash& hash, const char* path) +hash_binary_file(const Context& ctx, Hash& hash, const std::string& path) { if (!ctx.config.inode_cache()) { return hash.hash_file(path); @@ -374,33 +368,30 @@ hash_binary_file(const Context& ctx, Hash& hash, const char* path) } bool -hash_command_output(Hash& hash, const char* command, const char* compiler) +hash_command_output(Hash& hash, + const std::string& command, + const std::string& compiler) { #ifdef _WIN32 - // Trim leading space. - while (isspace(*command)) { - command++; - } + std::string adjusted_command = Util::strip_whitespace(command); // Add "echo" command. bool using_cmd_exe; - std::string adjusted_command; - if (str_startswith(command, "echo")) { - adjusted_command = fmt::format("cmd.exe /c \"{}\"", command); + if (Util::starts_with(adjusted_command, "echo")) { + adjusted_command = fmt::format("cmd.exe /c \"{}\"", adjusted_command); using_cmd_exe = true; - } else if (str_startswith(command, "%compiler%") - && str_eq(compiler, "echo")) { + } else if (Util::starts_with(adjusted_command, "%compiler%") + && compiler == "echo") { adjusted_command = - fmt::format("cmd.exe /c \"{}{}\"", compiler, command + 10); + fmt::format("cmd.exe /c \"{}{}\"", compiler, adjusted_command.substr(10)); using_cmd_exe = true; } else { - adjusted_command = command; using_cmd_exe = false; } - command = adjusted_command.c_str(); -#endif - + Args args = Args::from_string(adjusted_command); +#else Args args = Args::from_string(command); +#endif for (size_t i = 0; i < args.size(); i++) { if (args[i] == "%compiler%") { @@ -439,7 +430,7 @@ hash_command_output(Hash& hash, const char* command, const char* compiler) std::string win32args; if (using_cmd_exe) { - win32args = command; // quoted + win32args = adjusted_command; // quoted } else { win32args = Win32Util::argv_to_string(argv.data(), sh); } @@ -517,13 +508,14 @@ hash_command_output(Hash& hash, const char* command, const char* compiler) } bool -hash_multicommand_output(Hash& hash, const char* commands, const char* compiler) +hash_multicommand_output(Hash& hash, + const std::string& commands, + const std::string& compiler) { - bool ok = true; for (const std::string& cmd : Util::split_into_strings(commands, ";")) { - if (!hash_command_output(hash, cmd.c_str(), compiler)) { - ok = false; + if (!hash_command_output(hash, cmd, compiler)) { + return false; } } - return ok; + return true; } diff --git a/src/hashutil.hpp b/src/hashutil.hpp index bb10d8796..aa85cd554 100644 --- a/src/hashutil.hpp +++ b/src/hashutil.hpp @@ -20,29 +20,53 @@ #include "system.hpp" -#include +#include "third_party/nonstd/string_view.hpp" + +#include class Config; class Context; class Hash; -#define HASH_SOURCE_CODE_OK 0 -#define HASH_SOURCE_CODE_ERROR 1 -#define HASH_SOURCE_CODE_FOUND_DATE 2 -#define HASH_SOURCE_CODE_FOUND_TIME 4 -#define HASH_SOURCE_CODE_FOUND_TIMESTAMP 8 +const int HASH_SOURCE_CODE_OK = 0; +const int HASH_SOURCE_CODE_ERROR = (1 << 0); +const int HASH_SOURCE_CODE_FOUND_DATE = (1 << 1); +const int HASH_SOURCE_CODE_FOUND_TIME = (1 << 2); +const int HASH_SOURCE_CODE_FOUND_TIMESTAMP = (1 << 3); + +// Search for the strings "__DATE__", "__TIME__" and "__TIMESTAMP__" in `str`. +// +// Returns a bitmask with HASH_SOURCE_CODE_FOUND_DATE, +// HASH_SOURCE_CODE_FOUND_TIME and HASH_SOURCE_CODE_FOUND_TIMESTAMP set +// appropriately. +int check_for_temporal_macros(nonstd::string_view str); -int check_for_temporal_macros(const char* str, size_t len); +// Hash a string. Returns a bitmask of HASH_SOURCE_CODE_* results. int hash_source_code_string(const Context& ctx, Hash& hash, - const char* str, - size_t len, - const char* path); + nonstd::string_view str, + const std::string& path); + +// Hash a file ignoring comments. Returns a bitmask of HASH_SOURCE_CODE_* +// results. int hash_source_code_file(const Context& ctx, Hash& hash, - const char* path, + const std::string& path, size_t size_hint = 0); -bool hash_binary_file(const Context& ctx, Hash& hash, const char* path); -bool hash_command_output(Hash& hash, const char* command, const char* compiler); -bool -hash_multicommand_output(Hash& hash, const char* command, const char* compiler); + +// Hash a binary file using the inode cache if enabled. +// +// Returns true on success, otherwise false. +bool hash_binary_file(const Context& ctx, Hash& hash, const std::string& path); + +// Hash the output of `command` (not executed via a shell). A "%compiler%" +// string in `command` will be replaced with `compiler`. +bool hash_command_output(Hash& hash, + const std::string& command, + const std::string& compiler); + +// Like `hash_command_output` but for each semicolon-separated command in +// `command`. +bool hash_multicommand_output(Hash& hash, + const std::string& command, + const std::string& compiler); diff --git a/src/manifest.cpp b/src/manifest.cpp index 04decc6ed..6238f0882 100644 --- a/src/manifest.cpp +++ b/src/manifest.cpp @@ -452,7 +452,7 @@ verify_result(const Context& ctx, auto hashed_files_iter = hashed_files.find(path); if (hashed_files_iter == hashed_files.end()) { Hash hash; - int ret = hash_source_code_file(ctx, hash, path.c_str(), fs.size); + int ret = hash_source_code_file(ctx, hash, path, fs.size); if (ret & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path.c_str()); return false; diff --git a/unittest/test_hashutil.cpp b/unittest/test_hashutil.cpp index 9ca6678bb..8f7651657 100644 --- a/unittest/test_hashutil.cpp +++ b/unittest/test_hashutil.cpp @@ -23,6 +23,7 @@ #include "third_party/doctest.h" +using nonstd::string_view; using TestUtil::TestContext; TEST_SUITE_BEGIN("hashutil"); @@ -117,31 +118,31 @@ TEST_CASE("hash_multicommand_output_error_handling") TEST_CASE("check_for_temporal_macros") { - const char time_start[] = + const string_view time_start = "__TIME__\n" "int a;\n"; - const char time_middle[] = + const string_view time_middle = "#define a __TIME__\n" "int a;\n"; - const char time_end[] = "#define a __TIME__"; + const string_view time_end = "#define a __TIME__"; - const char date_start[] = + const string_view date_start = "__DATE__\n" "int ab;\n"; - const char date_middle[] = + const string_view date_middle = "#define ab __DATE__\n" "int ab;\n"; - const char date_end[] = "#define ab __DATE__"; + const string_view date_end = "#define ab __DATE__"; - const char timestamp_start[] = + const string_view timestamp_start = "__TIMESTAMP__\n" "int c;\n"; - const char timestamp_middle[] = + const string_view timestamp_middle = "#define c __TIMESTAMP__\n" "int c;\n"; - const char timestamp_end[] = "#define c __TIMESTAMP__"; + const string_view timestamp_end = "#define c __TIMESTAMP__"; - const char no_temporal[] = + const string_view no_temporal = "#define ab a__DATE__\n" "#define ab __DATE__a\n" "#define ab A__DATE__\n" @@ -164,83 +165,71 @@ TEST_CASE("check_for_temporal_macros") "#define ab __TIME __\n" "#define ab __TIME_ _\n"; - const char temporal_at_avx_boundary[] = + const string_view temporal_at_avx_boundary = "#define alphabet abcdefghijklmnopqrstuvwxyz\n" "__DATE__"; - CHECK(check_for_temporal_macros(time_start + 0, sizeof(time_start) - 0)); - CHECK(!check_for_temporal_macros(time_start + 1, sizeof(time_start) - 1)); - - CHECK(check_for_temporal_macros(time_middle + 0, sizeof(time_middle) - 0)); - CHECK(check_for_temporal_macros(time_middle + 1, sizeof(time_middle) - 1)); - CHECK(check_for_temporal_macros(time_middle + 2, sizeof(time_middle) - 2)); - CHECK(check_for_temporal_macros(time_middle + 3, sizeof(time_middle) - 3)); - CHECK(check_for_temporal_macros(time_middle + 4, sizeof(time_middle) - 4)); - CHECK(check_for_temporal_macros(time_middle + 5, sizeof(time_middle) - 5)); - CHECK(check_for_temporal_macros(time_middle + 6, sizeof(time_middle) - 6)); - CHECK(check_for_temporal_macros(time_middle + 7, sizeof(time_middle) - 7)); - - CHECK(check_for_temporal_macros(time_end + 0, sizeof(time_end) - 0)); - CHECK(check_for_temporal_macros(time_end + sizeof(time_end) - 9, 9)); - CHECK(!check_for_temporal_macros(time_end + sizeof(time_end) - 8, 8)); - - CHECK(check_for_temporal_macros(date_start + 0, sizeof(date_start) - 0)); - CHECK(!check_for_temporal_macros(date_start + 1, sizeof(date_start) - 1)); - - CHECK(check_for_temporal_macros(date_middle + 0, sizeof(date_middle) - 0)); - CHECK(check_for_temporal_macros(date_middle + 1, sizeof(date_middle) - 1)); - CHECK(check_for_temporal_macros(date_middle + 2, sizeof(date_middle) - 2)); - CHECK(check_for_temporal_macros(date_middle + 3, sizeof(date_middle) - 3)); - CHECK(check_for_temporal_macros(date_middle + 4, sizeof(date_middle) - 4)); - CHECK(check_for_temporal_macros(date_middle + 5, sizeof(date_middle) - 5)); - CHECK(check_for_temporal_macros(date_middle + 6, sizeof(date_middle) - 6)); - CHECK(check_for_temporal_macros(date_middle + 7, sizeof(date_middle) - 7)); - - CHECK(check_for_temporal_macros(date_end + 0, sizeof(date_end) - 0)); - CHECK(check_for_temporal_macros(date_end + sizeof(date_end) - 9, 9)); - CHECK(!check_for_temporal_macros(date_end + sizeof(date_end) - 8, 8)); - - CHECK(check_for_temporal_macros(timestamp_start + 0, - sizeof(timestamp_start) - 0)); - CHECK(!check_for_temporal_macros(timestamp_start + 1, - sizeof(timestamp_start) - 1)); - - CHECK(check_for_temporal_macros(timestamp_middle + 0, - sizeof(timestamp_middle) - 0)); - CHECK(check_for_temporal_macros(timestamp_middle + 1, - sizeof(timestamp_middle) - 1)); - CHECK(check_for_temporal_macros(timestamp_middle + 2, - sizeof(timestamp_middle) - 2)); - CHECK(check_for_temporal_macros(timestamp_middle + 3, - sizeof(timestamp_middle) - 3)); - CHECK(check_for_temporal_macros(timestamp_middle + 4, - sizeof(timestamp_middle) - 4)); - CHECK(check_for_temporal_macros(timestamp_middle + 5, - sizeof(timestamp_middle) - 5)); - CHECK(check_for_temporal_macros(timestamp_middle + 6, - sizeof(timestamp_middle) - 6)); - CHECK(check_for_temporal_macros(timestamp_middle + 7, - sizeof(timestamp_middle) - 7)); - - CHECK( - check_for_temporal_macros(timestamp_end + 0, sizeof(timestamp_end) - 0)); - CHECK( - check_for_temporal_macros(timestamp_end + sizeof(timestamp_end) - 14, 14)); - CHECK( - !check_for_temporal_macros(timestamp_end + sizeof(timestamp_end) - 13, 13)); - - CHECK(!check_for_temporal_macros(no_temporal + 0, sizeof(no_temporal) - 0)); - CHECK(!check_for_temporal_macros(no_temporal + 1, sizeof(no_temporal) - 1)); - CHECK(!check_for_temporal_macros(no_temporal + 2, sizeof(no_temporal) - 2)); - CHECK(!check_for_temporal_macros(no_temporal + 3, sizeof(no_temporal) - 3)); - CHECK(!check_for_temporal_macros(no_temporal + 4, sizeof(no_temporal) - 4)); - CHECK(!check_for_temporal_macros(no_temporal + 5, sizeof(no_temporal) - 5)); - CHECK(!check_for_temporal_macros(no_temporal + 6, sizeof(no_temporal) - 6)); - CHECK(!check_for_temporal_macros(no_temporal + 7, sizeof(no_temporal) - 7)); + CHECK(check_for_temporal_macros(time_start)); + CHECK(!check_for_temporal_macros(time_start.substr(1))); + + CHECK(check_for_temporal_macros(time_middle.substr(0))); + CHECK(check_for_temporal_macros(time_middle.substr(1))); + CHECK(check_for_temporal_macros(time_middle.substr(2))); + CHECK(check_for_temporal_macros(time_middle.substr(3))); + CHECK(check_for_temporal_macros(time_middle.substr(4))); + CHECK(check_for_temporal_macros(time_middle.substr(5))); + CHECK(check_for_temporal_macros(time_middle.substr(6))); + CHECK(check_for_temporal_macros(time_middle.substr(7))); + + CHECK(check_for_temporal_macros(time_end)); + CHECK(check_for_temporal_macros(time_end.substr(time_end.length() - 8))); + CHECK(!check_for_temporal_macros(time_end.substr(time_end.length() - 7))); + + CHECK(check_for_temporal_macros(date_start)); + CHECK(!check_for_temporal_macros(date_start.substr(1))); + + CHECK(check_for_temporal_macros(date_middle.substr(0))); + CHECK(check_for_temporal_macros(date_middle.substr(1))); + CHECK(check_for_temporal_macros(date_middle.substr(2))); + CHECK(check_for_temporal_macros(date_middle.substr(3))); + CHECK(check_for_temporal_macros(date_middle.substr(4))); + CHECK(check_for_temporal_macros(date_middle.substr(5))); + CHECK(check_for_temporal_macros(date_middle.substr(6))); + CHECK(check_for_temporal_macros(date_middle.substr(7))); + + CHECK(check_for_temporal_macros(date_end)); + CHECK(check_for_temporal_macros(date_end.substr(date_end.length() - 8))); + CHECK(!check_for_temporal_macros(date_end.substr(date_end.length() - 7))); + + CHECK(check_for_temporal_macros(timestamp_start)); + CHECK(!check_for_temporal_macros(timestamp_start.substr(1))); + + CHECK(check_for_temporal_macros(timestamp_middle)); + CHECK(check_for_temporal_macros(timestamp_middle.substr(1))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(2))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(3))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(4))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(5))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(6))); + CHECK(check_for_temporal_macros(timestamp_middle.substr(7))); + + CHECK(check_for_temporal_macros(timestamp_end)); + CHECK(check_for_temporal_macros( + timestamp_end.substr(timestamp_end.length() - 13))); + CHECK(!check_for_temporal_macros( + timestamp_end.substr(timestamp_end.length() - 12))); + + CHECK(!check_for_temporal_macros(no_temporal.substr(0))); + CHECK(!check_for_temporal_macros(no_temporal.substr(1))); + CHECK(!check_for_temporal_macros(no_temporal.substr(2))); + CHECK(!check_for_temporal_macros(no_temporal.substr(3))); + CHECK(!check_for_temporal_macros(no_temporal.substr(4))); + CHECK(!check_for_temporal_macros(no_temporal.substr(5))); + CHECK(!check_for_temporal_macros(no_temporal.substr(6))); + CHECK(!check_for_temporal_macros(no_temporal.substr(7))); for (size_t i = 0; i < sizeof(temporal_at_avx_boundary) - 8; ++i) { - CHECK(check_for_temporal_macros(temporal_at_avx_boundary + i, - sizeof(temporal_at_avx_boundary) - i)); + CHECK(check_for_temporal_macros(temporal_at_avx_boundary.substr(i))); } }