From 38ab9d38b52c873da1338f4d5eb58edb2ad5c2bc Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Mon, 6 Mar 2023 20:26:06 +0100 Subject: refactor: Use util::BitSet for hash_source_code_file --- src/InodeCache.cpp | 9 +-- src/InodeCache.hpp | 5 +- src/ccache.cpp | 12 ++-- src/core/Manifest.cpp | 6 +- src/hashutil.cpp | 75 ++++++++++++------------ src/hashutil.hpp | 38 ++++++------- unittest/test_InodeCache.cpp | 44 ++++++++++----- unittest/test_hashutil.cpp | 132 +++++++++++++++++++++++-------------------- 8 files changed, 173 insertions(+), 148 deletions(-) diff --git a/src/InodeCache.cpp b/src/InodeCache.cpp index 17e92417..7610417e 100644 --- a/src/InodeCache.cpp +++ b/src/InodeCache.cpp @@ -469,7 +469,7 @@ bool InodeCache::get(const std::string& path, ContentType type, Digest& file_digest, - int* return_value) + HashSourceCodeResult* return_value) { if (!initialize()) { return false; @@ -492,7 +492,8 @@ InodeCache::get(const std::string& path, file_digest = bucket->entries[0].file_digest; if (return_value) { - *return_value = bucket->entries[0].return_value; + *return_value = + HashSourceCodeResult::from_bitmask(bucket->entries[0].return_value); } found = true; break; @@ -518,7 +519,7 @@ bool InodeCache::put(const std::string& path, ContentType type, const Digest& file_digest, - int return_value) + HashSourceCodeResult return_value) { if (!initialize()) { return false; @@ -536,7 +537,7 @@ InodeCache::put(const std::string& path, bucket->entries[0].key_digest = key_digest; bucket->entries[0].file_digest = file_digest; - bucket->entries[0].return_value = return_value; + bucket->entries[0].return_value = return_value.to_bitmask(); }); if (!success) { diff --git a/src/InodeCache.hpp b/src/InodeCache.hpp index 5819ed07..eea3b49d 100644 --- a/src/InodeCache.hpp +++ b/src/InodeCache.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -79,7 +80,7 @@ public: bool get(const std::string& path, ContentType type, Digest& file_digest, - int* return_value = nullptr); + HashSourceCodeResult* return_value = nullptr); // Put hash digest and return value from a successful call to do_hash_file() // in hashutil.cpp. @@ -88,7 +89,7 @@ public: bool put(const std::string& path, ContentType type, const Digest& file_digest, - int return_value = 0); + HashSourceCodeResult return_value); // Unmaps the current cache and removes the mapped file from disk. // diff --git a/src/ccache.cpp b/src/ccache.cpp index 7d3eabdf..9efbd563 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -394,9 +394,9 @@ 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, file_digest, path); - if (result & HASH_SOURCE_CODE_ERROR - || result & HASH_SOURCE_CODE_FOUND_TIME) { + auto ret = hash_source_code_file(ctx, file_digest, path); + if (ret.contains(HashSourceCode::error) + || ret.contains(HashSourceCode::found_time)) { return false; } } @@ -1822,12 +1822,12 @@ get_manifest_key(Context& ctx, Hash& hash) hash.hash_delimiter("sourcecode hash"); Digest input_file_digest; - int result = + auto ret = hash_source_code_file(ctx, input_file_digest, ctx.args_info.input_file); - if (result & HASH_SOURCE_CODE_ERROR) { + if (ret.contains(HashSourceCode::error)) { return nonstd::make_unexpected(Statistic::internal_error); } - if (result & HASH_SOURCE_CODE_FOUND_TIME) { + if (ret.contains(HashSourceCode::found_time)) { LOG_RAW("Disabling direct mode"); ctx.config.set_direct_mode(false); return {}; diff --git a/src/core/Manifest.cpp b/src/core/Manifest.cpp index 2137103e..c1c3e0cd 100644 --- a/src/core/Manifest.cpp +++ b/src/core/Manifest.cpp @@ -400,12 +400,12 @@ Manifest::result_matches( auto hashed_files_iter = hashed_files.find(path); if (hashed_files_iter == hashed_files.end()) { Digest actual_digest; - int ret = hash_source_code_file(ctx, actual_digest, path, fs.size); - if (ret & HASH_SOURCE_CODE_ERROR) { + auto ret = hash_source_code_file(ctx, actual_digest, path, fs.size); + if (ret.contains(HashSourceCode::error)) { LOG("Failed hashing {}", path); return false; } - if (ret & HASH_SOURCE_CODE_FOUND_TIME) { + if (ret.contains(HashSourceCode::found_time)) { return false; } diff --git a/src/hashutil.cpp b/src/hashutil.cpp index 96838456..f241903d 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -55,30 +55,26 @@ 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] == '_' -int +HashSourceCode check_for_temporal_macros_helper(std::string_view str, size_t pos) { if (pos + 7 > str.length()) { - return 0; + return HashSourceCode::ok; } - int found = 0; + HashSourceCode found = HashSourceCode::ok; int macro_len = 7; if (memcmp(&str[pos], "_DATE__", 7) == 0) { - found = HASH_SOURCE_CODE_FOUND_DATE; + found = HashSourceCode::found_date; } else if (memcmp(&str[pos], "_TIME__", 7) == 0) { - found = HASH_SOURCE_CODE_FOUND_TIME; + found = HashSourceCode::found_time; } else if (pos + 12 <= str.length() && memcmp(&str[pos], "_TIMESTAMP__", 12) == 0) { - found = HASH_SOURCE_CODE_FOUND_TIMESTAMP; + found = HashSourceCode::found_timestamp; macro_len = 12; } else { - return 0; + return HashSourceCode::ok; } // Check char before and after macro to verify that the found macro isn't part @@ -89,13 +85,13 @@ check_for_temporal_macros_helper(std::string_view str, size_t pos) return found; } - return 0; + return HashSourceCode::ok; } -int +HashSourceCodeResult check_for_temporal_macros_bmh(std::string_view str, size_t start = 0) { - int result = 0; + HashSourceCodeResult result; // We're using the Boyer-Moore-Horspool algorithm, which searches starting // from the *end* of the needle. Our needles are 8 characters long, so i @@ -107,7 +103,7 @@ check_for_temporal_macros_bmh(std::string_view str, size_t start = 0) // 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, i - 6); + result.insert(check_for_temporal_macros_helper(str, i - 6)); } // macro_skip tells us how far we can skip forward upon seeing str[i] at @@ -120,17 +116,17 @@ check_for_temporal_macros_bmh(std::string_view str, size_t start = 0) #ifdef HAVE_AVX2 # ifndef _MSC_VER // MSVC does not need explicit enabling of AVX2. -int check_for_temporal_macros_avx2(std::string_view str) +HashSourceCodeResult check_for_temporal_macros_avx2(std::string_view str) __attribute__((target("avx2"))); # endif // The following algorithm, which uses AVX2 instructions to find __DATE__, // __TIME__ and __TIMESTAMP__, is heavily inspired by // . -int +HashSourceCodeResult check_for_temporal_macros_avx2(std::string_view str) { - int result = 0; + HashSourceCodeResult result; // Set all 32 bytes in first and last to '_' and 'E' respectively. const __m256i first = _mm256_set1_epi8('_'); @@ -169,17 +165,17 @@ check_for_temporal_macros_avx2(std::string_view str) // Clear the least significant bit set. mask = mask & (mask - 1); - result |= check_for_temporal_macros_helper(str, start); + result.insert(check_for_temporal_macros_helper(str, start)); } } - result |= check_for_temporal_macros_bmh(str, pos); + result.insert(check_for_temporal_macros_bmh(str, pos)); return result; } #endif -int +HashSourceCodeResult do_hash_file(const Context& ctx, Digest& digest, const std::string& path, @@ -191,7 +187,7 @@ do_hash_file(const Context& ctx, check_temporal_macros ? InodeCache::ContentType::checked_for_temporal_macros : InodeCache::ContentType::raw; if (ctx.config.inode_cache()) { - int result; + HashSourceCodeResult result; if (ctx.inode_cache.get(path, content_type, digest, &result)) { return result; } @@ -203,12 +199,12 @@ do_hash_file(const Context& ctx, const auto data = util::read_file(path, size_hint); if (!data) { LOG("Failed to read {}: {}", path, data.error()); - return HASH_SOURCE_CODE_ERROR; + return HashSourceCodeResult(HashSourceCode::error); } - int result = HASH_SOURCE_CODE_OK; + HashSourceCodeResult result; if (check_temporal_macros) { - result |= check_for_temporal_macros(*data); + result.insert(check_for_temporal_macros(*data)); } Hash hash; @@ -224,7 +220,7 @@ do_hash_file(const Context& ctx, } // namespace -int +HashSourceCodeResult check_for_temporal_macros(std::string_view str) { #ifdef HAVE_AVX2 @@ -235,7 +231,7 @@ check_for_temporal_macros(std::string_view str) return check_for_temporal_macros_bmh(str); } -int +HashSourceCodeResult hash_source_code_file(const Context& ctx, Digest& digest, const std::string& path, @@ -246,12 +242,12 @@ hash_source_code_file(const Context& ctx, auto result = do_hash_file(ctx, digest, path, size_hint, check_temporal_macros); - if (!check_temporal_macros || result == HASH_SOURCE_CODE_OK - || (result & HASH_SOURCE_CODE_ERROR)) { + if (!check_temporal_macros || result.empty() + || result.contains(HashSourceCode::error)) { return result; } - if (result & HASH_SOURCE_CODE_FOUND_TIME) { + if (result.contains(HashSourceCode::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 @@ -269,13 +265,14 @@ hash_source_code_file(const Context& ctx, Hash hash; hash.hash(digest.to_string()); - if (result & HASH_SOURCE_CODE_FOUND_DATE) { + if (result.contains(HashSourceCode::found_date)) { LOG("Found __DATE__ in {}", path); hash.hash_delimiter("date"); auto now = Util::localtime(); if (!now) { - return HASH_SOURCE_CODE_ERROR; + result.insert(HashSourceCode::error); + return result; } hash.hash(now->tm_year); hash.hash(now->tm_mon); @@ -291,17 +288,19 @@ hash_source_code_file(const Context& ctx, } } - if (result & HASH_SOURCE_CODE_FOUND_TIMESTAMP) { + if (result.contains(HashSourceCode::found_timestamp)) { LOG("Found __TIMESTAMP__ in {}", path); const auto stat = Stat::stat(path); if (!stat) { - return HASH_SOURCE_CODE_ERROR; + result.insert(HashSourceCode::error); + return result; } auto modified_time = Util::localtime(stat.mtime()); if (!modified_time) { - return HASH_SOURCE_CODE_ERROR; + result.insert(HashSourceCode::error); + return result; } hash.hash_delimiter("timestamp"); #ifdef HAVE_ASCTIME_R @@ -311,7 +310,8 @@ hash_source_code_file(const Context& ctx, auto timestamp = asctime(&*modified_time); #endif if (!timestamp) { - return HASH_SOURCE_CODE_ERROR; + result.insert(HashSourceCode::error); + return result; } hash.hash(timestamp); } @@ -326,8 +326,7 @@ hash_binary_file(const Context& ctx, const std::string& path, size_t size_hint) { - return do_hash_file(ctx, digest, path, size_hint, false) - == HASH_SOURCE_CODE_OK; + return do_hash_file(ctx, digest, path, size_hint, false).empty(); } bool diff --git a/src/hashutil.hpp b/src/hashutil.hpp index d0fd1420..c270b38e 100644 --- a/src/hashutil.hpp +++ b/src/hashutil.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2009-2022 Joel Rosdahl and other contributors +// Copyright (C) 2009-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,6 +18,8 @@ #pragma once +#include + #include #include #include @@ -27,26 +29,24 @@ class Context; class Digest; class Hash; -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); +enum class HashSourceCode { + ok = 0, + error = 1U << 0, + found_date = 1U << 1, + found_time = 1U << 2, + found_timestamp = 1U << 3, +}; -// Search for the strings "DATE", "TIME" and "TIMESTAMP" with two surrounding -// underscores 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(std::string_view str); +using HashSourceCodeResult = util::BitSet; + +// Search for tokens (described in HashSourceCode) in `str`. +HashSourceCodeResult check_for_temporal_macros(std::string_view str); -// Hash a source code file using the inode cache if enabled. Returns a bitmask -// of HASH_SOURCE_CODE_* results. -int hash_source_code_file(const Context& ctx, - Digest& digest, - const std::string& path, - size_t size_hint = 0); +// Hash a source code file using the inode cache if enabled. +HashSourceCodeResult hash_source_code_file(const Context& ctx, + Digest& digest, + const std::string& path, + size_t size_hint = 0); // Hash a binary file (using the inode cache if enabled) and put its digest in // `digest` diff --git a/unittest/test_InodeCache.cpp b/unittest/test_InodeCache.cpp index 5f08f36f..e60a0733 100644 --- a/unittest/test_InodeCache.cpp +++ b/unittest/test_InodeCache.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2022 Joel Rosdahl and other contributors +// Copyright (C) 2020-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -55,7 +55,7 @@ bool put(InodeCache& inode_cache, const std::string& filename, const std::string& str, - int return_value) + HashSourceCodeResult return_value) { return inode_cache.put(filename, InodeCache::ContentType::checked_for_temporal_macros, @@ -77,7 +77,7 @@ TEST_CASE("Test disabled") InodeCache inode_cache(config, util::Duration(0)); Digest digest; - int return_value; + HashSourceCodeResult return_value; CHECK(!inode_cache.get("a", InodeCache::ContentType::checked_for_temporal_macros, @@ -103,7 +103,7 @@ TEST_CASE("Test lookup nonexistent") util::write_file("a", ""); Digest digest; - int return_value; + HashSourceCodeResult return_value; CHECK(!inode_cache.get("a", InodeCache::ContentType::checked_for_temporal_macros, @@ -124,17 +124,20 @@ TEST_CASE("Test put and lookup") InodeCache inode_cache(config, util::Duration(0)); util::write_file("a", "a text"); - CHECK(put(inode_cache, "a", "a text", 1)); + HashSourceCodeResult result; + result.insert(HashSourceCode::found_date); + CHECK(put(inode_cache, "a", "a text", result)); Digest digest; - int return_value; + HashSourceCodeResult return_value; CHECK(inode_cache.get("a", InodeCache::ContentType::checked_for_temporal_macros, digest, &return_value)); CHECK(digest == Hash().hash("a text").digest()); - CHECK(return_value == 1); + CHECK(return_value.to_bitmask() + == static_cast(HashSourceCode::found_date)); CHECK(inode_cache.get_hits() == 1); CHECK(inode_cache.get_misses() == 0); CHECK(inode_cache.get_errors() == 0); @@ -149,14 +152,18 @@ TEST_CASE("Test put and lookup") CHECK(inode_cache.get_misses() == 1); CHECK(inode_cache.get_errors() == 0); - CHECK(put(inode_cache, "a", "something else", 2)); + CHECK(put(inode_cache, + "a", + "something else", + HashSourceCodeResult(HashSourceCode::found_time))); CHECK(inode_cache.get("a", InodeCache::ContentType::checked_for_temporal_macros, digest, &return_value)); CHECK(digest == Hash().hash("something else").digest()); - CHECK(return_value == 2); + CHECK(return_value.to_bitmask() + == static_cast(HashSourceCode::found_time)); CHECK(inode_cache.get_hits() == 2); CHECK(inode_cache.get_misses() == 1); CHECK(inode_cache.get_errors() == 0); @@ -192,24 +199,31 @@ TEST_CASE("Test content type") Digest binary_digest = Hash().hash("binary").digest(); Digest code_digest = Hash().hash("code").digest(); - CHECK(inode_cache.put("a", InodeCache::ContentType::raw, binary_digest, 1)); - CHECK(inode_cache.put( - "a", InodeCache::ContentType::checked_for_temporal_macros, code_digest, 2)); + CHECK(inode_cache.put("a", + InodeCache::ContentType::raw, + binary_digest, + HashSourceCodeResult(HashSourceCode::found_date))); + CHECK(inode_cache.put("a", + InodeCache::ContentType::checked_for_temporal_macros, + code_digest, + HashSourceCodeResult(HashSourceCode::found_time))); Digest digest; - int return_value; + HashSourceCodeResult return_value; CHECK( inode_cache.get("a", InodeCache::ContentType::raw, digest, &return_value)); CHECK(digest == binary_digest); - CHECK(return_value == 1); + CHECK(return_value.to_bitmask() + == static_cast(HashSourceCode::found_date)); CHECK(inode_cache.get("a", InodeCache::ContentType::checked_for_temporal_macros, digest, &return_value)); CHECK(digest == code_digest); - CHECK(return_value == 2); + CHECK(return_value.to_bitmask() + == static_cast(HashSourceCode::found_time)); } TEST_SUITE_END(); diff --git a/unittest/test_hashutil.cpp b/unittest/test_hashutil.cpp index 84199d16..bb4522c5 100644 --- a/unittest/test_hashutil.cpp +++ b/unittest/test_hashutil.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2022 Joel Rosdahl and other contributors +// Copyright (C) 2010-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -171,70 +171,80 @@ TEST_CASE("check_for_temporal_macros") "#define alphabet abcdefghijklmnopqrstuvwxyz\n" "a__DATE__"; - 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))); + auto check = check_for_temporal_macros; + + CHECK(check(time_start).contains(HashSourceCode::found_time)); + CHECK(check(time_start.substr(1)).empty()); + + CHECK(check(time_middle.substr(0)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(1)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(2)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(3)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(4)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(5)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(6)).contains(HashSourceCode::found_time)); + CHECK(check(time_middle.substr(7)).contains(HashSourceCode::found_time)); + + CHECK(check(time_end).contains(HashSourceCode::found_time)); + CHECK(check(time_end.substr(time_end.length() - 8)) + .contains(HashSourceCode::found_time)); + CHECK(check(time_end.substr(time_end.length() - 7)).empty()); + + CHECK(check(date_start).contains(HashSourceCode::found_date)); + CHECK(check(date_start.substr(1)).empty()); + + CHECK(check(date_middle.substr(0)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(1)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(2)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(3)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(4)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(5)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(6)).contains(HashSourceCode::found_date)); + CHECK(check(date_middle.substr(7)).contains(HashSourceCode::found_date)); + + CHECK(check(date_end).contains(HashSourceCode::found_date)); + CHECK(check(date_end.substr(date_end.length() - 8)) + .contains(HashSourceCode::found_date)); + CHECK(check(date_end.substr(date_end.length() - 7)).empty()); + + CHECK(check(timestamp_start).contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_start.substr(1)).empty()); + + CHECK(check(timestamp_middle).contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(1)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(2)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(3)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(4)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(5)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(6)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_middle.substr(7)) + .contains(HashSourceCode::found_timestamp)); + + CHECK(check(timestamp_end).contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_end.substr(timestamp_end.length() - 13)) + .contains(HashSourceCode::found_timestamp)); + CHECK(check(timestamp_end.substr(timestamp_end.length() - 12)).empty()); + + CHECK(check(no_temporal.substr(0)).empty()); + CHECK(check(no_temporal.substr(1)).empty()); + CHECK(check(no_temporal.substr(2)).empty()); + CHECK(check(no_temporal.substr(3)).empty()); + CHECK(check(no_temporal.substr(4)).empty()); + CHECK(check(no_temporal.substr(5)).empty()); + CHECK(check(no_temporal.substr(6)).empty()); + CHECK(check(no_temporal.substr(7)).empty()); for (size_t i = 0; i < temporal_at_avx_boundary.size() - 8; ++i) { - CHECK(check_for_temporal_macros(temporal_at_avx_boundary.substr(i))); + CHECK(!check(temporal_at_avx_boundary.substr(i)).empty()); } for (size_t i = 0; i < no_temporal_at_avx_boundary.size() - 8; ++i) { - CHECK(!check_for_temporal_macros(no_temporal_at_avx_boundary.substr(i))); + CHECK(check(no_temporal_at_avx_boundary.substr(i)).empty()); } } -- cgit v1.2.1