}
}
- 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");
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;
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);
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);
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);
}
}
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);
}
}
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;
}
}
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);
}
# 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))
# include <immintrin.h>
#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;
}
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;
// 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
}
#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
// <http://0x80.pl/articles/simd-strfind.html>.
-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;
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<const __m256i*>(str + pos));
+ _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&str[pos]));
const __m256i block_last =
- _mm256_loadu_si256(reinterpret_cast<const __m256i*>(str + pos + 5));
+ _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&str[pos + 5]));
// For i in 0..31:
// eq_X[i] = 0xFF if X[i] == block_X[i] else 0
// 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.
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.
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
#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);
}
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%") {
std::string win32args;
if (using_cmd_exe) {
- win32args = command; // quoted
+ win32args = adjusted_command; // quoted
} else {
win32args = Win32Util::argv_to_string(argv.data(), sh);
}
}
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;
}
#include "system.hpp"
-#include <inttypes.h>
+#include "third_party/nonstd/string_view.hpp"
+
+#include <string>
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);
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;
#include "third_party/doctest.h"
+using nonstd::string_view;
using TestUtil::TestContext;
TEST_SUITE_BEGIN("hashutil");
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"
"#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)));
}
}