From 99b7a7bd7612fd0af229e932c7233f4a96d5a76b Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 09:03:06 +1100 Subject: [PATCH 01/12] chore(misc): language discrimination; CI branch(es) --- .github/workflows/ci.yml | 2 +- include/cstring/cstring.h | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9967548..a83a9e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - rc1 - rc2 - rc3 - - directories + - hash-review pull_request: concurrency: diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index 9d974b3..cf1f8cd 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -4,7 +4,7 @@ * Purpose: Definition of the cstring.core API. * * Created: 16th June 1994 - * Updated: 4th October 2026 + * Updated: 5th October 2026 * * Home: http://synesis.com.au/software/ * @@ -56,7 +56,7 @@ # define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3 # define CSTRING_VER_CSTRING_H_CSTRING_MINOR 12 # define CSTRING_VER_CSTRING_H_CSTRING_REVISION 2 -# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 94 +# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 95 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ @@ -1234,11 +1234,16 @@ cstring_hash_fnv1a_len_ci( /* ///////////////////////////////////////////////////////////////////////// - * string access shims + * language */ #ifdef __cplusplus + +/* ///////////////////////////////////////////////////////////////////////// + * string access shims + */ + inline cstring_char_t const* c_str_data( @@ -1557,6 +1562,12 @@ namespace stlsoft } /* namespace stlsoft */ # endif /* !_STLSOFT_NO_NAMESPACE */ + + +/* ///////////////////////////////////////////////////////////////////////// + * language + */ + #endif /* __cplusplus */ From d1df3d7b0084cb482ee42d7b779860f2a3685d3c Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 09:07:31 +1100 Subject: [PATCH 02/12] chore(misc): ensuring `\file` designators are correct --- src/cstring.core.c | 2 +- src/cstring.hash.c | 13 ++++++------- src/cstring.vector.c | 4 ++-- src/win.c | 40 +++++++++++++++++++++------------------- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/cstring.core.c b/src/cstring.core.c index bbd6245..4b42ef7 100644 --- a/src/cstring.core.c +++ b/src/cstring.core.c @@ -4,7 +4,7 @@ * Purpose: The implementation of the cstring core API * * Created: 16th June 1994 - * Updated: 3rd October 2026 + * Updated: 5th October 2026 * * Home: http://synesis.com.au/software/ * diff --git a/src/cstring.hash.c b/src/cstring.hash.c index 3ec9259..daccb69 100644 --- a/src/cstring.hash.c +++ b/src/cstring.hash.c @@ -1,15 +1,14 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: cstring.core.c + * File: cstring.hash.c * - * Purpose: The implementation of the cstring core API + * Purpose: The implementation of the cstring hash API * - * Created: 16th June 1994 - * Updated: 29th September 2026 + * Created: 5th September 2026 + * Updated: 5th October 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems - * Copyright (c) 1994-2019, Matthew Wilson and Synesis Software + * Copyright (c) 2026, Matthew Wilson and Synesis Information Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +40,7 @@ * ////////////////////////////////////////////////////////////////////// */ -/** \file cstring.core.c The implementation of the cstring core API +/** \file cstring.hash.c The implementation of the cstring hash API */ /* ///////////////////////////////////////////////////////////////////////// diff --git a/src/cstring.vector.c b/src/cstring.vector.c index 81f43ed..4437159 100644 --- a/src/cstring.vector.c +++ b/src/cstring.vector.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// * File: cstring.vector.c * - * Purpose: The implementation of the cstring.vector API + * Purpose: The implementation of the cstring vector API * * Created: 16th June 1994 - * Updated: 29th September 2026 + * Updated: 5th October 2026 * * Home: http://synesis.com.au/software/ * diff --git a/src/win.c b/src/win.c index 1d07a52..a458e76 100644 --- a/src/win.c +++ b/src/win.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// * File: win.c * - * Purpose: Windows memory arenas for the cstring core API. + * Purpose: Windows memory arenas for cstring API. * * Created: 28th September 2026 - * Updated: 29th September 2026 + * Updated: 5th October 2026 * * Home: http://synesis.com.au/software/ * @@ -41,7 +41,7 @@ * ////////////////////////////////////////////////////////////////////// */ -/** \file win.c Windows memory arenas for the cstring core API +/** \file win.c Windows memory arenas for cstring API */ /* ///////////////////////////////////////////////////////////////////////// @@ -57,22 +57,24 @@ */ #ifndef CSTRING_DOCUMENTATION_SKIP_SECTION -# if defined(__MWERKS__) -# define GMEM_FIXED 0 -# define GMEM_MOVEABLE 2 -typedef int BOOL; -typedef void* HANDLE; -typedef void* HGLOBAL; -__declspec(dllimport) HANDLE __stdcall GetProcessHeap(void); -__declspec(dllimport) HGLOBAL __stdcall GlobalAlloc(unsigned int, unsigned long); -__declspec(dllimport) HGLOBAL __stdcall GlobalFree(HGLOBAL); -__declspec(dllimport) HGLOBAL __stdcall GlobalReAlloc(HGLOBAL, unsigned long, unsigned int); -__declspec(dllimport) void* __stdcall HeapAlloc(HANDLE, unsigned long, unsigned int); -__declspec(dllimport) BOOL __stdcall HeapFree(HANDLE, unsigned long, void* ); -__declspec(dllimport) void* __stdcall HeapReAlloc(HANDLE, unsigned long, void*, unsigned int); -__declspec(dllimport) void* __stdcall CoTaskMemAlloc(unsigned long); -__declspec(dllimport) void __stdcall CoTaskMemFree(void* ); -__declspec(dllimport) void* __stdcall CoTaskMemRealloc(void* , unsigned long); +# if 0 +# elif defined(__MWERKS__) + +# define GMEM_FIXED 0 +# define GMEM_MOVEABLE 2 +typedef int BOOL; +typedef void* HANDLE; +typedef void* HGLOBAL; +__declspec(dllimport) HANDLE __stdcall GetProcessHeap(void); +__declspec(dllimport) HGLOBAL __stdcall GlobalAlloc(unsigned int, unsigned long); +__declspec(dllimport) HGLOBAL __stdcall GlobalFree(HGLOBAL); +__declspec(dllimport) HGLOBAL __stdcall GlobalReAlloc(HGLOBAL, unsigned long, unsigned int); +__declspec(dllimport) void* __stdcall HeapAlloc(HANDLE, unsigned long, unsigned int); +__declspec(dllimport) BOOL __stdcall HeapFree(HANDLE, unsigned long, void* ); +__declspec(dllimport) void* __stdcall HeapReAlloc(HANDLE, unsigned long, void*, unsigned int); +__declspec(dllimport) void* __stdcall CoTaskMemAlloc(unsigned long); +__declspec(dllimport) void __stdcall CoTaskMemFree(void* ); +__declspec(dllimport) void* __stdcall CoTaskMemRealloc(void* , unsigned long); # else /* ? compiler */ # include From 42b58c6caeb999491eb6202fa1b4e3592d102b07 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 09:18:44 +1100 Subject: [PATCH 03/12] chore(mist): removed unused `CSTRING_VECTOR_ASSERT()` --- src/cstring.vector.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/cstring.vector.c b/src/cstring.vector.c index 4437159..cef19b6 100644 --- a/src/cstring.vector.c +++ b/src/cstring.vector.c @@ -71,13 +71,6 @@ #define CSTRING_VECTOR_DEF_CAPACITY_ (8) -/* ///////////////////////////////////////////////////////////////////////// - * debugging - */ - -#define CSTRING_VECTOR_ASSERT(expr) assert(expr) - - /* ///////////////////////////////////////////////////////////////////////// * compiler compatibility */ From cce1302c467f06243df06cc4baa27cd02c6aec52 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 09:21:29 +1100 Subject: [PATCH 04/12] chore(misc): tidying --- src/win.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/win.c b/src/win.c index a458e76..91e43b3 100644 --- a/src/win.c +++ b/src/win.c @@ -53,7 +53,7 @@ /* ///////////////////////////////////////////////////////////////////////// - * Win32 functions + * Windows functions */ #ifndef CSTRING_DOCUMENTATION_SKIP_SECTION @@ -82,7 +82,10 @@ __declspec(dllimport) void* __stdcall CoTaskMemRealloc(void* , unsigned lo # endif /* compiler */ #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ -/* ////////////////////////////////////////////////////////////////////// */ + +/* ///////////////////////////////////////////////////////////////////////// + * internal API functions + */ void* win32_global_realloc( From 32f74058a579e65fc3ae59399743af17350d1ad0 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 10:17:45 +1100 Subject: [PATCH 05/12] fix(cstring): discriminate cstring_hash_t and use it for hashing Gate on C99, on C++ with that header or C++11, and on MSVC 7.1 or later, and typedef cstring_hash_t to uint64_t when it is included; use cstring_hash_t for the djb2 and FNV-1a API and for the hash unit tests. --- include/cstring/cstring.h | 97 ++++++++++++++++++++++++++++----------- src/cstring.hash.c | 28 +++++------ test/unit/hash/entry.cpp | 12 ++--- 3 files changed, 90 insertions(+), 47 deletions(-) diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index cf1f8cd..9e08b10 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -54,9 +54,9 @@ #ifndef CSTRING_DOCUMENTATION_SKIP_SECTION # define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3 -# define CSTRING_VER_CSTRING_H_CSTRING_MINOR 12 -# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 2 -# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 95 +# define CSTRING_VER_CSTRING_H_CSTRING_MINOR 13 +# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 1 +# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 96 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ @@ -142,14 +142,46 @@ /* ///////////////////////////////////////////////////////////////////////// - * includes + * includes - 1 */ #include -#if defined(_MSC_VER) && \ - _MSC_VER < 1600 -typedef unsigned __int64 uint64_t; + + +/* ///////////////////////////////////////////////////////////////////////// + * compatibility + */ + +#if 0 +#elif defined(__STDC_VERSION__) &&\ + __STDC_VERSION__ >= 199901L + +# define CSTRING_HAS_h_stdint_ +#elif defined(__cplusplus) &&\ + defined(__has_include) &&\ + __has_include() + +# define CSTRING_HAS_h_stdint_ +#elif defined(__cplusplus) &&\ + __cplusplus >= 201103L + +# define CSTRING_HAS_h_stdint_ +#elif 0 ||\ + ( defined(_MSC_VER) &&\ + _MSC_VER >= 1310) ||\ + 0 + +# define CSTRING_HAS_h_stdint_ #else + +#endif + + +/* ///////////////////////////////////////////////////////////////////////// + * includes - 2 + */ + +#ifdef CSTRING_HAS_h_stdint_ # include #endif #include @@ -260,7 +292,18 @@ typedef int cstring_flags_t; /** \brief Hash value type * \ingroup group__cstring_api */ +#if 0 +#elif defined(CSTRING_HAS_h_stdint_) ||\ + defined(CSTRING_DOCUMENTATION_SKIP_SECTION) + typedef uint64_t cstring_hash_t; +#elif defined(_MSC_VER) + +typedef unsigned __int64_t cstring_hash_t; +#else + +# error 64-bit unsigned integer type not discriminated +#endif /** \brief The cstring structure * \ingroup group__cstring_api @@ -1108,7 +1151,7 @@ cstring_appendLenFn( * \return A 64-bit djb2 hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_djb2( struct cstring_t const* pcs ); @@ -1122,7 +1165,7 @@ cstring_hash_djb2( * \return A case-insensitive 64-bit djb2 hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_djb2_ci( struct cstring_t const* pcs ); @@ -1137,7 +1180,7 @@ cstring_hash_djb2_ci( * \return A 64-bit djb2 hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_djb2_len( cstring_char_t const* s , size_t cch @@ -1153,7 +1196,7 @@ cstring_hash_djb2_len( * \return A case-insensitive 64-bit djb2 hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_djb2_len_ci( cstring_char_t const* s , size_t cch @@ -1167,7 +1210,7 @@ cstring_hash_djb2_len_ci( * \return A 64-bit FNV-1a hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_fnv1a( struct cstring_t const* pcs ); @@ -1181,7 +1224,7 @@ cstring_hash_fnv1a( * \return A case-insensitive 64-bit FNV-1a hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_fnv1a_ci( struct cstring_t const* pcs ); @@ -1196,7 +1239,7 @@ cstring_hash_fnv1a_ci( * \return A 64-bit FNV-1a hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_fnv1a_len( cstring_char_t const* s , size_t cch @@ -1212,7 +1255,7 @@ cstring_hash_fnv1a_len( * \return A case-insensitive 64-bit FNV-1a hash value. */ CSTRING_EXTERN_C -uint64_t +cstring_hash_t cstring_hash_fnv1a_len_ci( cstring_char_t const* s , size_t cch @@ -1434,7 +1477,7 @@ c_str_ptr( */ inline -uint64_t +cstring_hash_t hash_djb2( struct cstring_t const* pcs ) @@ -1443,7 +1486,7 @@ hash_djb2( } inline -uint64_t +cstring_hash_t hash_djb2( struct cstring_t const& cs ) @@ -1452,7 +1495,7 @@ hash_djb2( } inline -uint64_t +cstring_hash_t hash_djb2( cstring_char_t const* s , size_t cch @@ -1462,7 +1505,7 @@ hash_djb2( } inline -uint64_t +cstring_hash_t hash_djb2_ci( struct cstring_t const* pcs ) @@ -1471,7 +1514,7 @@ hash_djb2_ci( } inline -uint64_t +cstring_hash_t hash_djb2_ci( struct cstring_t const& cs ) @@ -1480,7 +1523,7 @@ hash_djb2_ci( } inline -uint64_t +cstring_hash_t hash_djb2_ci( cstring_char_t const* s , size_t cch @@ -1490,7 +1533,7 @@ hash_djb2_ci( } inline -uint64_t +cstring_hash_t hash_fnv1a( struct cstring_t const* pcs ) @@ -1499,7 +1542,7 @@ hash_fnv1a( } inline -uint64_t +cstring_hash_t hash_fnv1a( struct cstring_t const& cs ) @@ -1508,7 +1551,7 @@ hash_fnv1a( } inline -uint64_t +cstring_hash_t hash_fnv1a( cstring_char_t const* s , size_t cch @@ -1518,7 +1561,7 @@ hash_fnv1a( } inline -uint64_t +cstring_hash_t hash_fnv1a_ci( struct cstring_t const* pcs ) @@ -1527,7 +1570,7 @@ hash_fnv1a_ci( } inline -uint64_t +cstring_hash_t hash_fnv1a_ci( struct cstring_t const& cs ) @@ -1536,7 +1579,7 @@ hash_fnv1a_ci( } inline -uint64_t +cstring_hash_t hash_fnv1a_ci( cstring_char_t const* s , size_t cch diff --git a/src/cstring.hash.c b/src/cstring.hash.c index daccb69..2f65bda 100644 --- a/src/cstring.hash.c +++ b/src/cstring.hash.c @@ -77,7 +77,7 @@ * hashing functions */ -uint64_t +cstring_hash_t cstring_hash_djb2( struct cstring_t const* pcs ) @@ -90,7 +90,7 @@ cstring_hash_djb2( return cstring_hash_djb2_len(pcs->ptr, pcs->len); } -uint64_t +cstring_hash_t cstring_hash_djb2_ci( struct cstring_t const* pcs ) @@ -103,13 +103,13 @@ cstring_hash_djb2_ci( return cstring_hash_djb2_len_ci(pcs->ptr, pcs->len); } -uint64_t +cstring_hash_t cstring_hash_djb2_len( cstring_char_t const* s , size_t cch ) { - uint64_t hash = 5381; + cstring_hash_t hash = 5381; if (NULL != s) { @@ -126,13 +126,13 @@ cstring_hash_djb2_len( return hash; } -uint64_t +cstring_hash_t cstring_hash_djb2_len_ci( cstring_char_t const* s , size_t cch ) { - uint64_t hash = 5381; + cstring_hash_t hash = 5381; if (NULL != s) { @@ -153,7 +153,7 @@ cstring_hash_djb2_len_ci( return hash; } -uint64_t +cstring_hash_t cstring_hash_fnv1a( struct cstring_t const* pcs ) @@ -166,7 +166,7 @@ cstring_hash_fnv1a( return cstring_hash_fnv1a_len(pcs->ptr, pcs->len); } -uint64_t +cstring_hash_t cstring_hash_fnv1a_ci( struct cstring_t const* pcs ) @@ -179,14 +179,14 @@ cstring_hash_fnv1a_ci( return cstring_hash_fnv1a_len_ci(pcs->ptr, pcs->len); } -uint64_t +cstring_hash_t cstring_hash_fnv1a_len( cstring_char_t const* s , size_t cch ) { - uint64_t const fnv_prime = 0x100000001b3ULL; - uint64_t hash = 0xcbf29ce484222325ULL; + cstring_hash_t const fnv_prime = 0x100000001b3ULL; + cstring_hash_t hash = 0xcbf29ce484222325ULL; if (NULL != s) { @@ -204,14 +204,14 @@ cstring_hash_fnv1a_len( return hash; } -uint64_t +cstring_hash_t cstring_hash_fnv1a_len_ci( cstring_char_t const* s , size_t cch ) { - uint64_t const fnv_prime = 0x100000001b3ULL; - uint64_t hash = 0xcbf29ce484222325ULL; + cstring_hash_t const fnv_prime = 0x100000001b3ULL; + cstring_hash_t hash = 0xcbf29ce484222325ULL; if (NULL != s) { diff --git a/test/unit/hash/entry.cpp b/test/unit/hash/entry.cpp index de224db..5590729 100644 --- a/test/unit/hash/entry.cpp +++ b/test/unit/hash/entry.cpp @@ -214,13 +214,13 @@ static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void) static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) { /* Buffer checks */ - uint64_t djb2_ci_base = cstring_hash_djb2_len_ci(CSTRING_T_("Test"), 4); + cstring_hash_t djb2_ci_base = cstring_hash_djb2_len_ci(CSTRING_T_("Test"), 4); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("tEst"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("TEST"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("test"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("teSt"), 4)); - uint64_t fnv1a_ci_base = cstring_hash_fnv1a_len_ci(CSTRING_T_("Test"), 4); + cstring_hash_t fnv1a_ci_base = cstring_hash_fnv1a_len_ci(CSTRING_T_("Test"), 4); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("tEst"), 4)); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("TEST"), 4)); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("test"), 4)); @@ -346,12 +346,12 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) /* Slices without constructing cstring_t */ /* "quick" starts at index 4, length 5 */ - uint64_t djb2_quick_slice = cstring_hash_djb2_len(text + 4, 5); - uint64_t djb2_quick_direct = cstring_hash_djb2_len(CSTRING_T_("quick"), 5); + cstring_hash_t djb2_quick_slice = cstring_hash_djb2_len(text + 4, 5); + cstring_hash_t djb2_quick_direct = cstring_hash_djb2_len(CSTRING_T_("quick"), 5); TEST_INT_EQ(djb2_quick_direct, djb2_quick_slice); - uint64_t fnv1a_quick_slice = cstring_hash_fnv1a_len(text + 4, 5); - uint64_t fnv1a_quick_direct = cstring_hash_fnv1a_len(CSTRING_T_("quick"), 5); + cstring_hash_t fnv1a_quick_slice = cstring_hash_fnv1a_len(text + 4, 5); + cstring_hash_t fnv1a_quick_direct = cstring_hash_fnv1a_len(CSTRING_T_("quick"), 5); TEST_INT_EQ(fnv1a_quick_direct, fnv1a_quick_slice); /* "Fox" starts at index 16, length 3 */ From a0c89fc916f13fba47cb791898710f0cb9200341 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 10:18:19 +1100 Subject: [PATCH 06/12] chore(performance tests): prefer `uint64_t` to `std::uint64_t` --- test/performance/cstring_readline/main.cpp | 30 ++++++------- test/performance/cstring_vector/main.cpp | 52 +++++++++++----------- test/performance/perf_harness.hpp | 6 +-- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/test/performance/cstring_readline/main.cpp b/test/performance/cstring_readline/main.cpp index e6eb9fa..164de2e 100644 --- a/test/performance/cstring_readline/main.cpp +++ b/test/performance/cstring_readline/main.cpp @@ -119,13 +119,13 @@ emit_row( ); } -std::uint64_t +uint64_t line_anchor( size_t len , unsigned char head ) { - return static_cast(len) + 1u + static_cast(head); + return static_cast(len) + 1u + static_cast(head); } unsigned char @@ -142,7 +142,7 @@ content_head( return static_cast(p[0]); } -std::uint64_t +uint64_t read_all_cstring( char const* path , size_t line_len @@ -156,8 +156,8 @@ read_all_cstring( return 0; } - cstring_t cs = cstring_t_DEFAULT; - std::uint64_t anchor = 0; + cstring_t cs = cstring_t_DEFAULT; + uint64_t anchor = 0; if (INSTANCE_PRERESERVED == mode && 0 != line_len) { @@ -203,7 +203,7 @@ read_all_cstring( return anchor; } -std::uint64_t +uint64_t read_all_getline( char const* path , size_t line_len @@ -218,7 +218,7 @@ read_all_getline( } std::string line; - std::uint64_t anchor = 0; + uint64_t anchor = 0; if (INSTANCE_PRERESERVED == mode && 0 != line_len) { @@ -252,7 +252,7 @@ read_all_getline( */ size_t const FGETS_REUSE_BUF = 4096u; -std::uint64_t +uint64_t read_all_fgets( char const* path , size_t line_len @@ -271,7 +271,7 @@ read_all_fgets( ; std::vector buf; - std::uint64_t anchor = 0; + uint64_t anchor = 0; size_t content_len = 0; unsigned char head = 0; bool pending_cr = false; @@ -380,7 +380,7 @@ read_all_fgets( return anchor; } -std::uint64_t +uint64_t read_all_raw_fgetc( char const* path , size_t line_len @@ -408,7 +408,7 @@ read_all_raw_fgetc( } } - std::uint64_t anchor = 0; + uint64_t anchor = 0; int previous = '\0'; for (;;) @@ -534,19 +534,19 @@ scenario_readline( size_t const line_len = spec.line_len; instance_mode_t const mode = spec.mode; - run_result const cs = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> std::uint64_t { + run_result const cs = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> uint64_t { return read_all_cstring(path, line_len, mode); }); - run_result const gl = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> std::uint64_t { + run_result const gl = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> uint64_t { return read_all_getline(path, line_len, mode); }); - run_result const fg = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> std::uint64_t { + run_result const fg = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> uint64_t { return read_all_fgets(path, line_len, mode); }); - run_result const raw = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> std::uint64_t { + run_result const raw = time_iterations(num_trials, num_warm_loops, [path, line_len, mode]() -> uint64_t { return read_all_raw_fgetc(path, line_len, mode); }); diff --git a/test/performance/cstring_vector/main.cpp b/test/performance/cstring_vector/main.cpp index 70b73c3..91234ef 100644 --- a/test/performance/cstring_vector/main.cpp +++ b/test/performance/cstring_vector/main.cpp @@ -121,20 +121,20 @@ scenario_create_destroy( , size_t num_warm_loops ) { - run_result const cs = time_iterations(num_iterations, num_warm_loops, [n]() -> std::uint64_t { + run_result const cs = time_iterations(num_iterations, num_warm_loops, [n]() -> uint64_t { cstring_vector_t v = cstring_vector_t_DEFAULT; cstring_vector_create(&v, n); - std::uint64_t const a = v.len + v.capacity; + uint64_t const a = v.len + v.capacity; cstring_vector_destroy(&v); return a; }); - run_result const st = time_iterations(num_iterations, num_warm_loops, [n]() -> std::uint64_t { + run_result const st = time_iterations(num_iterations, num_warm_loops, [n]() -> uint64_t { std::vector v(n); return v.size() + v.capacity(); }); - run_result const raw = time_iterations(num_iterations, num_warm_loops, [n]() -> std::uint64_t { + run_result const raw = time_iterations(num_iterations, num_warm_loops, [n]() -> uint64_t { raw_string_vector v; raw_vec_init(&v); raw_vec_reserve(&v, n); @@ -143,7 +143,7 @@ scenario_create_destroy( { v.ptr[i] = NULL; } - std::uint64_t const a = v.len + v.capacity; + uint64_t const a = v.len + v.capacity; raw_vec_destroy(&v); return a; }); @@ -164,7 +164,7 @@ scenario_append_one_by_one( cstring_t payload = make_cstring_payload(payload_len); std::string const payload_s = make_payload(payload_len); - run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payload, k]() -> std::uint64_t { + run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payload, k]() -> uint64_t { cstring_vector_t v = cstring_vector_t_DEFAULT; cstring_vector_init(&v, 0); for (size_t i = 0; k != i; ++i) @@ -181,7 +181,7 @@ scenario_append_one_by_one( ? v.ptr[v.len - 1u].ptr : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -190,7 +190,7 @@ scenario_append_one_by_one( return a; }); - run_result const st = time_iterations(num_iterations, num_warm_loops, [&payload_s, k]() -> std::uint64_t { + run_result const st = time_iterations(num_iterations, num_warm_loops, [&payload_s, k]() -> uint64_t { std::vector v; for (size_t i = 0; k != i; ++i) { @@ -204,7 +204,7 @@ scenario_append_one_by_one( ; }); - run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payload_s, payload_len, k]() -> std::uint64_t { + run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payload_s, payload_len, k]() -> uint64_t { raw_string_vector v; raw_vec_init(&v); for (size_t i = 0; k != i; ++i) @@ -217,7 +217,7 @@ scenario_append_one_by_one( char const* volatile tail = (0 != v.len && NULL != v.ptr) ? v.ptr[v.len - 1u] : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -252,7 +252,7 @@ scenario_append_batch( payloads_s[i] = proto; } - run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payloads, k]() -> std::uint64_t { + run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payloads, k]() -> uint64_t { cstring_vector_t v = cstring_vector_t_DEFAULT; cstring_vector_init(&v, 0); cstring_vector_append(&v, &payloads[0], k); @@ -266,7 +266,7 @@ scenario_append_batch( ? v.ptr[v.len - 1u].ptr : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -275,7 +275,7 @@ scenario_append_batch( return a; }); - run_result const st = time_iterations(num_iterations, num_warm_loops, [&payloads_s]() -> std::uint64_t { + run_result const st = time_iterations(num_iterations, num_warm_loops, [&payloads_s]() -> uint64_t { std::vector v; v.insert(v.end(), payloads_s.begin(), payloads_s.end()); char const* volatile head = v.empty() ? NULL : v.front().data(); @@ -286,7 +286,7 @@ scenario_append_batch( ; }); - run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payloads_s, payload_len, k]() -> std::uint64_t { + run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payloads_s, payload_len, k]() -> uint64_t { raw_string_vector v; raw_vec_init(&v); raw_vec_reserve(&v, k); @@ -300,7 +300,7 @@ scenario_append_batch( char const* volatile tail = (0 != v.len && NULL != v.ptr) ? v.ptr[v.len - 1u] : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -330,7 +330,7 @@ scenario_prepend_one_by_one( cstring_t payload = make_cstring_payload(payload_len); std::string const payload_s = make_payload(payload_len); - run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payload, k]() -> std::uint64_t { + run_result const cs = time_iterations(num_iterations, num_warm_loops, [&payload, k]() -> uint64_t { cstring_vector_t v = cstring_vector_t_DEFAULT; cstring_vector_init(&v, 0); for (size_t i = 0; k != i; ++i) @@ -347,7 +347,7 @@ scenario_prepend_one_by_one( ? v.ptr[v.len - 1u].ptr : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -356,7 +356,7 @@ scenario_prepend_one_by_one( return a; }); - run_result const st = time_iterations(num_iterations, num_warm_loops, [&payload_s, k]() -> std::uint64_t { + run_result const st = time_iterations(num_iterations, num_warm_loops, [&payload_s, k]() -> uint64_t { std::vector v; for (size_t i = 0; k != i; ++i) { @@ -370,7 +370,7 @@ scenario_prepend_one_by_one( ; }); - run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payload_s, payload_len, k]() -> std::uint64_t { + run_result const raw = time_iterations(num_iterations, num_warm_loops, [&payload_s, payload_len, k]() -> uint64_t { raw_string_vector v; raw_vec_init(&v); for (size_t i = 0; k != i; ++i) @@ -383,7 +383,7 @@ scenario_prepend_one_by_one( char const* volatile tail = (0 != v.len && NULL != v.ptr) ? v.ptr[v.len - 1u] : NULL ; - std::uint64_t const a = + uint64_t const a = v.len + (NULL != head ? static_cast(head[0]) : 0u) + (NULL != tail ? static_cast(tail[0]) : 0u) @@ -401,13 +401,13 @@ scenario_prepend_one_by_one( #ifdef HAS_P99 template -std::uint64_t +uint64_t sum_line_lengths( size_t count , F length_at ) { - std::uint64_t a = count; + uint64_t a = count; for (size_t i = 0; count != i; ++i) { @@ -474,7 +474,7 @@ scenario_file_lines_vs_readlines( << std::endl ; - run_result const cs = time_iterations(num_trials, num_warm_loops, []() -> std::uint64_t { + run_result const cs = time_iterations(num_trials, num_warm_loops, []() -> uint64_t { FILE* f = std::fopen(TEST_FILE_NAME, "rb"); if (NULL == f) { @@ -484,7 +484,7 @@ scenario_file_lines_vs_readlines( cstring_vector_t v = cstring_vector_t_DEFAULT; cstring_vector_init(&v, 0); cstring_vector_readLines(f, &v, NULL); - std::uint64_t const a = sum_line_lengths( + uint64_t const a = sum_line_lengths( v.len , [&v](size_t i) -> size_t { @@ -496,7 +496,7 @@ scenario_file_lines_vs_readlines( return a; }); - run_result const gl = time_iterations(num_trials, num_warm_loops, []() -> std::uint64_t { + run_result const gl = time_iterations(num_trials, num_warm_loops, []() -> uint64_t { std::ifstream in(TEST_FILE_NAME, std::ios::in | std::ios::binary); if (!in) @@ -522,7 +522,7 @@ scenario_file_lines_vs_readlines( ); }); - run_result const fl = time_iterations(num_trials, num_warm_loops, []() -> std::uint64_t { + run_result const fl = time_iterations(num_trials, num_warm_loops, []() -> uint64_t { platformstl::file_lines_a lines(TEST_FILE_NAME); return sum_line_lengths( lines.size() diff --git a/test/performance/perf_harness.hpp b/test/performance/perf_harness.hpp index 103d390..a3fef6e 100644 --- a/test/performance/perf_harness.hpp +++ b/test/performance/perf_harness.hpp @@ -203,7 +203,7 @@ write_lines_file( struct run_result { interval_t tm_ns; - std::uint64_t anchor; + uint64_t anchor; #ifdef HAS_P99 p99::histogram hist; @@ -248,7 +248,7 @@ time_iterations( if (1 == w) { - std::uint64_t volatile hist_anchor = 0; + uint64_t volatile hist_anchor = 0; for (size_t i = 0; num_iterations != i; ++i) { @@ -258,7 +258,7 @@ time_iterations( interval_t const sample = sw.get_nanoseconds(); - (void)result.hist.push_ns(static_cast(sample)); + (void)result.hist.push_ns(static_cast(sample)); } (void)hist_anchor; From 4e2e0c7aa1c1c62c4738e57ae0ef5a59d165e62e Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 10:29:34 +1100 Subject: [PATCH 07/12] test(cstring): exercise the hashing API from a C unit test Move the eight C hashing functions into **test.unit.hash** (`entry.c`) so the suite builds when `NO_CSTRING_CPP_API` is on. Keep the C++ shim checks in **test.unit.hash.cxx**, which stays behind that option. --- CHANGES.md | 2 +- test/unit/CMakeLists.txt | 8 +- test/unit/hash.cxx/CMakeLists.txt | 2 + test/unit/hash.cxx/entry.cpp | 162 ++++++++++++++++++++++++ test/unit/hash/CMakeLists.txt | 3 +- test/unit/hash/{entry.cpp => entry.c} | 172 ++++++++++---------------- 6 files changed, 238 insertions(+), 111 deletions(-) create mode 100644 test/unit/hash.cxx/CMakeLists.txt create mode 100644 test/unit/hash.cxx/entry.cpp rename test/unit/hash/{entry.cpp => entry.c} (73%) diff --git a/CHANGES.md b/CHANGES.md index 079a6dc..cb1e1ad 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ * Added 64-bit `FNV-1a` hash functions: `cstring_hash_fnv1a()`, `cstring_hash_fnv1a_ci()`, `cstring_hash_fnv1a_len()`, and `cstring_hash_fnv1a_len_ci()`; * Added `cstring_hash_t` typedef (`uint64_t`); * Added C++ hash access shims for `cstring_t` (reference and pointer) and buffer/slice forms; -* Added unit test suite **test.unit.hash**; +* Added unit test **test.unit.hash** (C hashing API, built with and without the C++ API) and **test.unit.hash.cxx** (C++ hash shims); ## 4.0.19 - 4th October 2026 diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index ccc1aab..6685e09 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,11 +1,15 @@ add_subdirectory(auto-buffer) -add_subdirectory(cstring) add_subdirectory(cstring_vector) if(NOT NO_CSTRING_CPP_API) add_subdirectory(cstring.cxx) - add_subdirectory(hash) +endif() +add_subdirectory(cstring) +add_subdirectory(hash) +if(NOT NO_CSTRING_CPP_API) + + add_subdirectory(hash.cxx) endif() add_subdirectory(insert-replace) add_subdirectory(status-codes) diff --git a/test/unit/hash.cxx/CMakeLists.txt b/test/unit/hash.cxx/CMakeLists.txt new file mode 100644 index 0000000..8fa9d69 --- /dev/null +++ b/test/unit/hash.cxx/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.hash.cxx entry.cpp) diff --git a/test/unit/hash.cxx/entry.cpp b/test/unit/hash.cxx/entry.cpp new file mode 100644 index 0000000..60a6a9f --- /dev/null +++ b/test/unit/hash.cxx/entry.cpp @@ -0,0 +1,162 @@ +/* ///////////////////////////////////////////////////////////////////////// + * File: test/unit/hash.cxx/entry.cpp + * + * Purpose: Unit-tests for the C++ cstring hash access shims. + * + * Created: 5th September 2026 + * Updated: 5th October 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + + +/* ///////////////////////////////////////////////////////////////////////// + * includes + */ + +/* ///////////////////////////////////// + * test component header file include(s) + */ + +#include + +/* ///////////////////////////////////// + * general includes + */ + +/* xTests header files */ +#include + +/* STLSoft header files */ +#include + +/* Standard C header files */ +#include + + +/* ///////////////////////////////////////////////////////////////////////// + * character encoding + */ + +#ifdef CSTRING_USE_WIDE_STRINGS +# define CSTRING_T_(x) L ## x +#else /* ? CSTRING_USE_WIDE_STRINGS */ +# define CSTRING_T_(x) x +#endif /* CSTRING_USE_WIDE_STRINGS */ + + +/* ///////////////////////////////////////////////////////////////////////// + * forward declarations + */ + +namespace +{ + + static void TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY(void); + static void TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS(void); + static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void); +} /* anonymous namespace */ + + +/* ///////////////////////////////////////////////////////////////////////// + * main + */ + +int main(int argc, char* argv[]) +{ + int retCode = EXIT_SUCCESS; + int verbosity = 2; + + XTESTS_COMMANDLINE_PARSEVERBOSITY(argc, argv, &verbosity); + + if (XTESTS_START_RUNNER("test.unit.hash.cxx", verbosity)) + { + XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY); + XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS); + XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci); + + XTESTS_PRINT_RESULTS(); + + XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode); + } + + return retCode; +} + + +/* ///////////////////////////////////////////////////////////////////////// + * test function implementations + */ + +namespace +{ + +static void TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY(void) +{ + cstring_t const default_cs = cstring_t_DEFAULT; + + TEST_INT_EQ(5381ULL, hash_djb2(static_cast(NULL))); + TEST_INT_EQ(5381ULL, hash_djb2_ci(static_cast(NULL))); + TEST_INT_EQ(5381ULL, hash_djb2(default_cs)); + TEST_INT_EQ(5381ULL, hash_djb2_ci(default_cs)); + TEST_INT_EQ(5381ULL, hash_djb2(NULL, 0)); + TEST_INT_EQ(5381ULL, hash_djb2_ci(NULL, 0)); + + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(static_cast(NULL))); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(static_cast(NULL))); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(default_cs)); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(default_cs)); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(NULL, 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(NULL, 0)); +} + +static void TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS(void) +{ + cstring_t cs_a; + cstring_t cs_foobar; + CSTRING_RC rc; + + rc = cstring_create(&cs_a, CSTRING_T_("a")); + TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); + TEST_INT_EQ(177670ULL, hash_djb2(cs_a)); + TEST_INT_EQ(0xaf63dc4c8601ec8cULL, hash_fnv1a(cs_a)); + cstring_destroy(&cs_a); + + rc = cstring_create(&cs_foobar, CSTRING_T_("foobar")); + TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); + TEST_INT_EQ(6953516687550ULL, hash_djb2(cs_foobar)); + TEST_INT_EQ(0x85944171f73967e8ULL, hash_fnv1a(cs_foobar)); + cstring_destroy(&cs_foobar); +} + +static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void) +{ + cstring_t cs; + CSTRING_RC rc = cstring_create(&cs, CSTRING_T_("Hello World")); + + TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); + + /* Overload by reference */ + TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(cs)); + TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(cs)); + TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(cs)); + TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(cs)); + + /* Overload by pointer */ + TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(&cs)); + TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(&cs)); + TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(&cs)); + TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(&cs)); + + /* Overload by slice/buffer */ + TEST_INT_EQ(cstring_hash_djb2_len(cs.ptr, cs.len), hash_djb2(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_djb2_len_ci(cs.ptr, cs.len), hash_djb2_ci(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_fnv1a_len(cs.ptr, cs.len), hash_fnv1a(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_fnv1a_len_ci(cs.ptr, cs.len), hash_fnv1a_ci(cs.ptr, cs.len)); + + cstring_destroy(&cs); +} +} /* anonymous namespace */ + + +/* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/unit/hash/CMakeLists.txt b/test/unit/hash/CMakeLists.txt index 0e47709..e88ce91 100644 --- a/test/unit/hash/CMakeLists.txt +++ b/test/unit/hash/CMakeLists.txt @@ -1 +1,2 @@ -define_automated_test_program(test.unit.hash entry.cpp) +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.hash entry.c) diff --git a/test/unit/hash/entry.cpp b/test/unit/hash/entry.c similarity index 73% rename from test/unit/hash/entry.cpp rename to test/unit/hash/entry.c index 5590729..b1b2622 100644 --- a/test/unit/hash/entry.cpp +++ b/test/unit/hash/entry.c @@ -1,22 +1,26 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test/unit/hash/entry.cpp + * File: test/unit/hash/entry.c * - * Purpose: Unit-tests for cstring hashing extensions. + * Purpose: Unit-tests for the cstring hashing API. * * Created: 5th September 2026 - * Updated: 5th September 2026 + * Updated: 5th October 2026 * * ////////////////////////////////////////////////////////////////////// */ /* ///////////////////////////////////////////////////////////////////////// + * includes + */ + +/* ///////////////////////////////////// * test component header file include(s) */ #include -/* ///////////////////////////////////////////////////////////////////////// - * includes +/* ///////////////////////////////////// + * general includes */ /* xTests header files */ @@ -26,9 +30,20 @@ #include /* Standard C header files */ -#include #include -#include + + +/* ///////////////////////////////////////////////////////////////////////// + * forward declarations + */ + +static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void); +static void TEST_cstring_hash_fnv1a_KNOWN_VECTORS(void); +static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void); +static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void); +static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void); +static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void); +static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void); /* ///////////////////////////////////////////////////////////////////////// @@ -42,24 +57,6 @@ #endif /* CSTRING_USE_WIDE_STRINGS */ -/* ///////////////////////////////////////////////////////////////////////// - * forward declarations - */ - -namespace -{ - - static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void); - static void TEST_cstring_hash_fnv1a_KNOWN_VECTORS(void); - static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void); - static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void); - static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void); - static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void); - static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void); - static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void); -} // anonymous namespace - - /* ///////////////////////////////////////////////////////////////////////// * main */ @@ -71,7 +68,7 @@ int main(int argc, char* argv[]) XTESTS_COMMANDLINE_PARSEVERBOSITY(argc, argv, &verbosity); - if (XTESTS_START_RUNNER("test.unit.cstring.hash", verbosity)) + if (XTESTS_START_RUNNER("test.unit.hash", verbosity)) { XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY); XTESTS_RUN_CASE(TEST_cstring_hash_fnv1a_KNOWN_VECTORS); @@ -80,7 +77,6 @@ int main(int argc, char* argv[]) XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES); - XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci); XTESTS_PRINT_RESULTS(); @@ -95,17 +91,15 @@ int main(int argc, char* argv[]) * test function implementations */ -namespace -{ - static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) { struct cstring_t const* pcs_null = NULL; cstring_t null_cs = { 0, NULL, 0, 0 }; cstring_t default_cs = cstring_t_DEFAULT; cstring_t created_empty; + CSTRING_RC rc; - CSTRING_RC rc = cstring_create(&created_empty, CSTRING_T_("")); + rc = cstring_create(&created_empty, CSTRING_T_("")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); /* djb2: initial seed is 5381 */ @@ -125,13 +119,6 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(CSTRING_T_(""), 0)); TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_ci(CSTRING_T_(""), 0)); - TEST_INT_EQ(5381ULL, hash_djb2(static_cast(NULL))); - TEST_INT_EQ(5381ULL, hash_djb2_ci(static_cast(NULL))); - TEST_INT_EQ(5381ULL, hash_djb2(default_cs)); - TEST_INT_EQ(5381ULL, hash_djb2_ci(default_cs)); - TEST_INT_EQ(5381ULL, hash_djb2(NULL, 0)); - TEST_INT_EQ(5381ULL, hash_djb2_ci(NULL, 0)); - /* FNV-1a: offset basis is 0xcbf29ce484222325ULL */ TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(pcs_null)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_ci(pcs_null)); @@ -149,13 +136,6 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(CSTRING_T_(""), 0)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(CSTRING_T_(""), 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(static_cast(NULL))); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(static_cast(NULL))); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(default_cs)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(default_cs)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(NULL, 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(NULL, 0)); - cstring_destroy(&created_empty); } @@ -166,22 +146,22 @@ static void TEST_cstring_hash_fnv1a_KNOWN_VECTORS(void) * "a" -> 0xaf63dc4c8601ec8cULL * "foobar" -> 0x85944171f73967e8ULL */ + cstring_t cs_a; + cstring_t cs_foobar; + CSTRING_RC rc; + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(CSTRING_T_(""), 0)); TEST_INT_EQ(0xaf63dc4c8601ec8cULL, cstring_hash_fnv1a_len(CSTRING_T_("a"), 1)); TEST_INT_EQ(0x85944171f73967e8ULL, cstring_hash_fnv1a_len(CSTRING_T_("foobar"), 6)); - cstring_t cs_a; - CSTRING_RC rc = cstring_create(&cs_a, CSTRING_T_("a")); + rc = cstring_create(&cs_a, CSTRING_T_("a")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); TEST_INT_EQ(0xaf63dc4c8601ec8cULL, cstring_hash_fnv1a(&cs_a)); - TEST_INT_EQ(0xaf63dc4c8601ec8cULL, hash_fnv1a(cs_a)); cstring_destroy(&cs_a); - cstring_t cs_foobar; rc = cstring_create(&cs_foobar, CSTRING_T_("foobar")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); TEST_INT_EQ(0x85944171f73967e8ULL, cstring_hash_fnv1a(&cs_foobar)); - TEST_INT_EQ(0x85944171f73967e8ULL, hash_fnv1a(cs_foobar)); cstring_destroy(&cs_foobar); } @@ -192,35 +172,43 @@ static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void) * "a" -> 5381 * 33 + 97 = 177670ULL (0x2b606ULL) * "foobar" -> 6953516687550ULL (0x652fde460beULL) */ + cstring_t cs_a; + cstring_t cs_foobar; + CSTRING_RC rc; + TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(CSTRING_T_(""), 0)); TEST_INT_EQ(177670ULL, cstring_hash_djb2_len(CSTRING_T_("a"), 1)); TEST_INT_EQ(6953516687550ULL, cstring_hash_djb2_len(CSTRING_T_("foobar"), 6)); - cstring_t cs_a; - CSTRING_RC rc = cstring_create(&cs_a, CSTRING_T_("a")); + rc = cstring_create(&cs_a, CSTRING_T_("a")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); TEST_INT_EQ(177670ULL, cstring_hash_djb2(&cs_a)); - TEST_INT_EQ(177670ULL, hash_djb2(cs_a)); cstring_destroy(&cs_a); - cstring_t cs_foobar; rc = cstring_create(&cs_foobar, CSTRING_T_("foobar")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); TEST_INT_EQ(6953516687550ULL, cstring_hash_djb2(&cs_foobar)); - TEST_INT_EQ(6953516687550ULL, hash_djb2(cs_foobar)); cstring_destroy(&cs_foobar); } static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) { + cstring_hash_t djb2_ci_base; + cstring_hash_t fnv1a_ci_base; + cstring_t cs1; + cstring_t cs2; + cstring_t cs3; + cstring_t cs4; + CSTRING_RC rc; + /* Buffer checks */ - cstring_hash_t djb2_ci_base = cstring_hash_djb2_len_ci(CSTRING_T_("Test"), 4); + djb2_ci_base = cstring_hash_djb2_len_ci(CSTRING_T_("Test"), 4); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("tEst"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("TEST"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("test"), 4)); TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("teSt"), 4)); - cstring_hash_t fnv1a_ci_base = cstring_hash_fnv1a_len_ci(CSTRING_T_("Test"), 4); + fnv1a_ci_base = cstring_hash_fnv1a_len_ci(CSTRING_T_("Test"), 4); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("tEst"), 4)); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("TEST"), 4)); TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("test"), 4)); @@ -231,12 +219,6 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("Test"), 4), cstring_hash_fnv1a_len(CSTRING_T_("tEst"), 4)); /* Instance checks */ - cstring_t cs1; - cstring_t cs2; - cstring_t cs3; - cstring_t cs4; - - CSTRING_RC rc; rc = cstring_create(&cs1, CSTRING_T_("Test")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); rc = cstring_create(&cs2, CSTRING_T_("tEst")); @@ -289,10 +271,13 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void) static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) { - cstring_char_t long_pattern_mixed[1025]; - cstring_char_t long_pattern_lower[1025]; - size_t const pattern_len = 1024; - size_t i; + cstring_char_t long_pattern_mixed[1025]; + cstring_char_t long_pattern_lower[1025]; + size_t const pattern_len = 1024; + size_t i; + cstring_t cs_mixed; + cstring_t cs_lower; + CSTRING_RC rc; for (i = 0; i < pattern_len; ++i) { @@ -312,10 +297,6 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) long_pattern_mixed[pattern_len] = 0; long_pattern_lower[pattern_len] = 0; - cstring_t cs_mixed; - cstring_t cs_lower; - - CSTRING_RC rc; rc = cstring_createLen(&cs_mixed, long_pattern_mixed, pattern_len); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); rc = cstring_createLen(&cs_lower, long_pattern_lower, pattern_len); @@ -341,17 +322,23 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) { - cstring_char_t const text[] = CSTRING_T_("The quick brown Fox jumps over the lazy Dog."); - size_t const total_len = sizeof(text) / sizeof(text[0]) - 1; + cstring_char_t const text[] = CSTRING_T_("The quick brown Fox jumps over the lazy Dog."); + size_t const total_len = sizeof(text) / sizeof(text[0]) - 1; + cstring_hash_t djb2_quick_slice; + cstring_hash_t djb2_quick_direct; + cstring_hash_t fnv1a_quick_slice; + cstring_hash_t fnv1a_quick_direct; + cstring_t cs; + CSTRING_RC rc; /* Slices without constructing cstring_t */ /* "quick" starts at index 4, length 5 */ - cstring_hash_t djb2_quick_slice = cstring_hash_djb2_len(text + 4, 5); - cstring_hash_t djb2_quick_direct = cstring_hash_djb2_len(CSTRING_T_("quick"), 5); + djb2_quick_slice = cstring_hash_djb2_len(text + 4, 5); + djb2_quick_direct = cstring_hash_djb2_len(CSTRING_T_("quick"), 5); TEST_INT_EQ(djb2_quick_direct, djb2_quick_slice); - cstring_hash_t fnv1a_quick_slice = cstring_hash_fnv1a_len(text + 4, 5); - cstring_hash_t fnv1a_quick_direct = cstring_hash_fnv1a_len(CSTRING_T_("quick"), 5); + fnv1a_quick_slice = cstring_hash_fnv1a_len(text + 4, 5); + fnv1a_quick_direct = cstring_hash_fnv1a_len(CSTRING_T_("quick"), 5); TEST_INT_EQ(fnv1a_quick_direct, fnv1a_quick_slice); /* "Fox" starts at index 16, length 3 */ @@ -361,42 +348,13 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) TEST_INT_NE(cstring_hash_fnv1a_len(text + 16, 3), cstring_hash_fnv1a_len(CSTRING_T_("fox"), 3)); /* Hashing full text via buffer API */ - cstring_t cs; - CSTRING_RC rc = cstring_createLen(&cs, text, total_len); + rc = cstring_createLen(&cs, text, total_len); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); TEST_INT_EQ(cstring_hash_djb2_len(text, total_len), cstring_hash_djb2(&cs)); TEST_INT_EQ(cstring_hash_fnv1a_len(text, total_len), cstring_hash_fnv1a(&cs)); cstring_destroy(&cs); } -static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void) -{ - cstring_t cs; - CSTRING_RC rc = cstring_create(&cs, CSTRING_T_("Hello World")); - TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); - - /* Overload by reference */ - TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(cs)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(cs)); - TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(cs)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(cs)); - - /* Overload by pointer */ - TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(&cs)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(&cs)); - TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(&cs)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(&cs)); - - /* Overload by slice/buffer */ - TEST_INT_EQ(cstring_hash_djb2_len(cs.ptr, cs.len), hash_djb2(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_djb2_len_ci(cs.ptr, cs.len), hash_djb2_ci(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_fnv1a_len(cs.ptr, cs.len), hash_fnv1a(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_fnv1a_len_ci(cs.ptr, cs.len), hash_fnv1a_ci(cs.ptr, cs.len)); - - cstring_destroy(&cs); -} -} // anonymous namespace - /* ///////////////////////////// end of file //////////////////////////// */ From 05793a0a56486ac642c9f52f5a2d0810b1c893b2 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 15:15:36 +1100 Subject: [PATCH 08/12] test(cstring): lock high-byte and embedded-NUL hash results Cover octet 0xFF and an interior NUL in test.unit.hash. Exact narrow vectors stay off the wide build so a later wchar_t fix is not frozen. --- test/unit/hash/entry.c | 67 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/unit/hash/entry.c b/test/unit/hash/entry.c index b1b2622..b3f69a1 100644 --- a/test/unit/hash/entry.c +++ b/test/unit/hash/entry.c @@ -44,6 +44,8 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void); static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void); static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void); static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void); +static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_OCTET_ABOVE_7F(void); +static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_EMBEDDED_NUL(void); /* ///////////////////////////////////////////////////////////////////////// @@ -77,6 +79,8 @@ int main(int argc, char* argv[]) XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES); + XTESTS_RUN_CASE(TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_OCTET_ABOVE_7F); + XTESTS_RUN_CASE(TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_EMBEDDED_NUL); XTESTS_PRINT_RESULTS(); @@ -355,6 +359,69 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) cstring_destroy(&cs); } +static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_OCTET_ABOVE_7F(void) +{ + cstring_char_t const hi[1] = { (cstring_char_t)0xFF }; + cstring_char_t const mid[1] = { (cstring_char_t)0x7F }; + +#ifndef CSTRING_USE_WIDE_STRINGS + /* djb2: 5381 * 33 + octet. FNV-1a: one-byte 64-bit vectors. */ + TEST_INT_EQ(177828ULL, cstring_hash_djb2_len(hi, 1)); + TEST_INT_EQ(0xaf64724c8602eb6eULL, cstring_hash_fnv1a_len(hi, 1)); + TEST_INT_EQ(177700ULL, cstring_hash_djb2_len(mid, 1)); + TEST_INT_EQ(0xaf63f24c860211eeULL, cstring_hash_fnv1a_len(mid, 1)); + + TEST_INT_NE(5381ULL, cstring_hash_djb2_len(hi, 1)); + TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(hi, 1)); + + /* tolower of octets above 0x7F follows the process locale. */ + TEST_INT_NE(cstring_hash_djb2_len_ci(mid, 1), cstring_hash_djb2_len_ci(hi, 1)); + TEST_INT_NE(5381ULL, cstring_hash_djb2_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_ci(mid, 1), cstring_hash_fnv1a_len_ci(hi, 1)); + TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(hi, 1)); +#else /* ? CSTRING_USE_WIDE_STRINGS */ + /* Distinct code units only; exact octets would freeze truncation. */ + TEST_INT_NE(cstring_hash_djb2_len(mid, 1), cstring_hash_djb2_len(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len(hi, 0), cstring_hash_djb2_len(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len_ci(mid, 1), cstring_hash_djb2_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len_ci(hi, 0), cstring_hash_djb2_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len(mid, 1), cstring_hash_fnv1a_len(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len(hi, 0), cstring_hash_fnv1a_len(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_ci(mid, 1), cstring_hash_fnv1a_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_ci(hi, 0), cstring_hash_fnv1a_len_ci(hi, 1)); +#endif /* CSTRING_USE_WIDE_STRINGS */ +} + +static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_EMBEDDED_NUL(void) +{ + cstring_char_t const a_nul_b[3] = { CSTRING_T_('a'), (cstring_char_t)0, CSTRING_T_('b') }; + cstring_char_t const a_only[1] = { CSTRING_T_('a') }; + cstring_char_t const ab[2] = { CSTRING_T_('a'), CSTRING_T_('b') }; + cstring_char_t const a_nul_c[3] = { CSTRING_T_('a'), (cstring_char_t)0, CSTRING_T_('c') }; + + /* Explicit length, so an interior NUL does not end the slice. */ + TEST_INT_NE(cstring_hash_djb2_len(a_only, 1), cstring_hash_djb2_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len(ab, 2), cstring_hash_djb2_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len(a_nul_c, 3), cstring_hash_djb2_len(a_nul_b, 3)); + + TEST_INT_NE(cstring_hash_djb2_len_ci(a_only, 1), cstring_hash_djb2_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len_ci(ab, 2), cstring_hash_djb2_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len_ci(a_nul_c, 3), cstring_hash_djb2_len_ci(a_nul_b, 3)); + + TEST_INT_NE(cstring_hash_fnv1a_len(a_only, 1), cstring_hash_fnv1a_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len(ab, 2), cstring_hash_fnv1a_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len(a_nul_c, 3), cstring_hash_fnv1a_len(a_nul_b, 3)); + + TEST_INT_NE(cstring_hash_fnv1a_len_ci(a_only, 1), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len_ci(ab, 2), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len_ci(a_nul_c, 3), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); + +#ifndef CSTRING_USE_WIDE_STRINGS + TEST_INT_EQ(193482728ULL, cstring_hash_djb2_len(a_nul_b, 3)); + TEST_INT_EQ(0xe5d29919042666b2ULL, cstring_hash_fnv1a_len(a_nul_b, 3)); +#endif /* CSTRING_USE_WIDE_STRINGS */ +} + /* ///////////////////////////// end of file //////////////////////////// */ From fe50c1e7a96d66d1312d2c7e01f8d111d944638c Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 15:35:44 +1100 Subject: [PATCH 09/12] feat(cstring): publish the djb2 and FNV-1a basis macros Add CSTRING_HASH_DJB2_SEED, CSTRING_HASH_FNV1A_OFFSET, and CSTRING_HASH_FNV1A_PRIME beside cstring_hash_t, and use them as the only copies of those constants in the hash implementation. Cite Yigit's djb2 page and the Fowler, Noll, and Vo notes and RFC 9923, and lock each macro to its historic literal in the C unit test. --- CHANGES.md | 2 ++ README.md | 5 ++++- include/cstring/cstring.h | 38 ++++++++++++++++++++++++++++++++++++-- src/cstring.hash.c | 22 ++++++++++------------ test/unit/hash/entry.c | 4 ++++ 5 files changed, 56 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cb1e1ad..a3003d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,8 @@ * Added `cstring_hash_t` typedef (`uint64_t`); * Added C++ hash access shims for `cstring_t` (reference and pointer) and buffer/slice forms; * Added unit test **test.unit.hash** (C hashing API, built with and without the C++ API) and **test.unit.hash.cxx** (C++ hash shims); +* Published `CSTRING_HASH_DJB2_SEED`, `CSTRING_HASH_FNV1A_OFFSET`, and `CSTRING_HASH_FNV1A_PRIME` as the djb2 and FNV-1a basis constants; +* Documented `CSTRING_HASH_DJB2_SEED`, `CSTRING_HASH_FNV1A_OFFSET`, and `CSTRING_HASH_FNV1A_PRIME` with references to the published djb2 and FNV-1a algorithms; ## 4.0.19 - 4th October 2026 diff --git a/README.md b/README.md index f002166..d45652f 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,9 @@ Supporting scalar typedefs: * `cstring_vector_t_DEFAULT` — the same shape for a `cstring_vector_t`; * `cstring_vector_DEFAULT_CAPACITY` — sentinel (`~(size_t)0`) passed to creators so the implementation chooses the capacity; * `CSTRING_FROM_END(x)` — reverse index for `cstring_insert()`, `cstring_insertLen()`, `cstring_replace()`, and `cstring_replaceLen()`; +* `CSTRING_HASH_DJB2_SEED` — djb2 initial seed (`5381`); also the hash of an empty input; +* `CSTRING_HASH_FNV1A_OFFSET` — FNV-1a 64-bit offset basis (`0xcbf29ce484222325ULL`); also the hash of an empty input; +* `CSTRING_HASH_FNV1A_PRIME` — FNV-1a 64-bit prime (`0x100000001b3ULL`); ### String API @@ -212,7 +215,7 @@ Defined in **cstring/cstring.h**: #### Hashing functions -Both 64-bit **djb2** (initial seed `5381`) and **FNV-1a** (offset basis `0xcbf29ce484222325ULL`, prime `0x100000001b3ULL`) hash functions are provided, returning `cstring_hash_t` (`uint64_t`). Buffer/slice variants (`_len`) allow hashing character sequences without constructing a `cstring_t` instance. Case-insensitive variants (`_ci`) fold characters to lower case, facilitating case-folded lookups and comparisons. All functions safely tolerate `NULL` pointers and zero lengths, returning the respective algorithm's initial basis / seed value: +Both 64-bit **djb2** (initial seed `5381`, `CSTRING_HASH_DJB2_SEED`) and **FNV-1a** (offset basis `0xcbf29ce484222325ULL`, `CSTRING_HASH_FNV1A_OFFSET`; prime `0x100000001b3ULL`, `CSTRING_HASH_FNV1A_PRIME`) hash functions are provided, returning `cstring_hash_t` (`uint64_t`). Buffer/slice variants (`_len`) allow hashing character sequences without constructing a `cstring_t` instance. Case-insensitive variants (`_ci`) fold characters to lower case, facilitating case-folded lookups and comparisons. All functions safely tolerate `NULL` pointers and zero lengths. An empty or `NULL` input hashes to `CSTRING_HASH_DJB2_SEED` or `CSTRING_HASH_FNV1A_OFFSET`: * `cstring_hash_djb2()` — calculates a 64-bit djb2 hash of a `cstring_t` instance; * `cstring_hash_djb2_ci()` — calculates a case-insensitive 64-bit djb2 hash of a `cstring_t` instance; diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index 9e08b10..819b76c 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -55,8 +55,8 @@ #ifndef CSTRING_DOCUMENTATION_SKIP_SECTION # define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3 # define CSTRING_VER_CSTRING_H_CSTRING_MINOR 13 -# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 1 -# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 96 +# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 2 +# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 98 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ @@ -305,6 +305,40 @@ typedef unsigned __int64_t cstring_hash_t; # error 64-bit unsigned integer type not discriminated #endif +/** \def CSTRING_HASH_DJB2_SEED + * \ingroup group__cstring_api + * \brief djb2 initial seed (also the hash of an empty input) + * + * Daniel J. Bernstein's djb2, as published by Ozan Yigit. + * \sa http://www.cse.yorku.ca/~oz/hash.html#djb2 + */ +#define CSTRING_HASH_DJB2_SEED 5381ULL + +/** \def CSTRING_HASH_FNV1A_OFFSET + * \ingroup group__cstring_api + * \brief FNV-1a 64-bit offset basis (also the hash of an empty input) + * + * FNV-1a offset basis published by Fowler, Noll, and Vo, and in RFC 9923. + * \sa https://www.isthe.com/chongo/tech/comp/fnv/#FNV-1a + * \sa https://www.isthe.com/chongo/tech/comp/fnv/#FNV-param + * \sa https://www.rfc-editor.org/rfc/rfc9923.html#section-2.2 + * \sa https://www.rfc-editor.org/rfc/rfc9923.html#section-5 + */ +#define CSTRING_HASH_FNV1A_OFFSET 0xcbf29ce484222325ULL + +/** \def CSTRING_HASH_FNV1A_PRIME + * \ingroup group__cstring_api + * \brief FNV-1a 64-bit prime + * + * FNV-1a prime published by Fowler, Noll, and Vo, and in RFC 9923. + * \sa https://www.isthe.com/chongo/tech/comp/fnv/#FNV-1a + * \sa https://www.isthe.com/chongo/tech/comp/fnv/#FNV-param + * \sa https://www.isthe.com/chongo/tech/comp/fnv/#fnv-prime + * \sa https://www.rfc-editor.org/rfc/rfc9923.html#section-2.1 + * \sa https://www.rfc-editor.org/rfc/rfc9923.html#section-5 + */ +#define CSTRING_HASH_FNV1A_PRIME 0x100000001b3ULL + /** \brief The cstring structure * \ingroup group__cstring_api * diff --git a/src/cstring.hash.c b/src/cstring.hash.c index 2f65bda..1601e1f 100644 --- a/src/cstring.hash.c +++ b/src/cstring.hash.c @@ -84,7 +84,7 @@ cstring_hash_djb2( { if (NULL == pcs) { - return 5381; + return CSTRING_HASH_DJB2_SEED; } return cstring_hash_djb2_len(pcs->ptr, pcs->len); @@ -97,7 +97,7 @@ cstring_hash_djb2_ci( { if (NULL == pcs) { - return 5381; + return CSTRING_HASH_DJB2_SEED; } return cstring_hash_djb2_len_ci(pcs->ptr, pcs->len); @@ -109,7 +109,7 @@ cstring_hash_djb2_len( , size_t cch ) { - cstring_hash_t hash = 5381; + cstring_hash_t hash = CSTRING_HASH_DJB2_SEED; if (NULL != s) { @@ -132,7 +132,7 @@ cstring_hash_djb2_len_ci( , size_t cch ) { - cstring_hash_t hash = 5381; + cstring_hash_t hash = CSTRING_HASH_DJB2_SEED; if (NULL != s) { @@ -160,7 +160,7 @@ cstring_hash_fnv1a( { if (NULL == pcs) { - return 0xcbf29ce484222325ULL; + return CSTRING_HASH_FNV1A_OFFSET; } return cstring_hash_fnv1a_len(pcs->ptr, pcs->len); @@ -173,7 +173,7 @@ cstring_hash_fnv1a_ci( { if (NULL == pcs) { - return 0xcbf29ce484222325ULL; + return CSTRING_HASH_FNV1A_OFFSET; } return cstring_hash_fnv1a_len_ci(pcs->ptr, pcs->len); @@ -185,8 +185,7 @@ cstring_hash_fnv1a_len( , size_t cch ) { - cstring_hash_t const fnv_prime = 0x100000001b3ULL; - cstring_hash_t hash = 0xcbf29ce484222325ULL; + cstring_hash_t hash = CSTRING_HASH_FNV1A_OFFSET; if (NULL != s) { @@ -197,7 +196,7 @@ cstring_hash_fnv1a_len( uint8_t const c = (uint8_t)s[i]; hash ^= c; - hash *= fnv_prime; + hash *= CSTRING_HASH_FNV1A_PRIME; } } @@ -210,8 +209,7 @@ cstring_hash_fnv1a_len_ci( , size_t cch ) { - cstring_hash_t const fnv_prime = 0x100000001b3ULL; - cstring_hash_t hash = 0xcbf29ce484222325ULL; + cstring_hash_t hash = CSTRING_HASH_FNV1A_OFFSET; if (NULL != s) { @@ -226,7 +224,7 @@ cstring_hash_fnv1a_len_ci( #endif hash ^= c; - hash *= fnv_prime; + hash *= CSTRING_HASH_FNV1A_PRIME; } } diff --git a/test/unit/hash/entry.c b/test/unit/hash/entry.c index b3f69a1..7c9626d 100644 --- a/test/unit/hash/entry.c +++ b/test/unit/hash/entry.c @@ -103,6 +103,10 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) cstring_t created_empty; CSTRING_RC rc; + TEST_INT_EQ(5381ULL, CSTRING_HASH_DJB2_SEED); + TEST_INT_EQ(0xcbf29ce484222325ULL, CSTRING_HASH_FNV1A_OFFSET); + TEST_INT_EQ(0x100000001b3ULL, CSTRING_HASH_FNV1A_PRIME); + rc = cstring_create(&created_empty, CSTRING_T_("")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); From e0b086d1567444563ac27fba8f286e46146b3b5c Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 15:46:00 +1100 Subject: [PATCH 10/12] fix --- test/unit/hash/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/unit/hash/CMakeLists.txt b/test/unit/hash/CMakeLists.txt index e88ce91..47c1f69 100644 --- a/test/unit/hash/CMakeLists.txt +++ b/test/unit/hash/CMakeLists.txt @@ -1,2 +1,7 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +# MSVC C4310: (cstring_char_t)0xFF truncates when char is signed. The test +# stores that octet on purpose, including the signed-char case. +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED + 4310 +) + define_automated_test_program(test.unit.hash entry.c) From ffc3877f087c44bce528e567d708e921a1896f9d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 16:06:45 +1100 Subject: [PATCH 11/12] refactor(cstring): rename the case-folded hash suffix to _case Rename the case-folded hash functions from the `_ci` suffix to `_case` (`cstring_hash_djb2_case`, `cstring_hash_djb2_len_case`, and the FNV-1a twins), including the C++ shims and the unit tests. --- include/cstring/cstring.h | 32 ++++----- src/cstring.hash.c | 12 ++-- test/unit/hash.cxx/entry.cpp | 30 ++++---- test/unit/hash/entry.c | 128 +++++++++++++++++------------------ 4 files changed, 101 insertions(+), 101 deletions(-) diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index 819b76c..7da5205 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -1200,7 +1200,7 @@ cstring_hash_djb2( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_djb2_ci( +cstring_hash_djb2_case( struct cstring_t const* pcs ); @@ -1231,7 +1231,7 @@ cstring_hash_djb2_len( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_djb2_len_ci( +cstring_hash_djb2_len_case( cstring_char_t const* s , size_t cch ); @@ -1259,7 +1259,7 @@ cstring_hash_fnv1a( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_fnv1a_ci( +cstring_hash_fnv1a_case( struct cstring_t const* pcs ); @@ -1290,7 +1290,7 @@ cstring_hash_fnv1a_len( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_fnv1a_len_ci( +cstring_hash_fnv1a_len_case( cstring_char_t const* s , size_t cch ); @@ -1540,30 +1540,30 @@ hash_djb2( inline cstring_hash_t -hash_djb2_ci( +hash_djb2_case( struct cstring_t const* pcs ) { - return cstring_hash_djb2_ci(pcs); + return cstring_hash_djb2_case(pcs); } inline cstring_hash_t -hash_djb2_ci( +hash_djb2_case( struct cstring_t const& cs ) { - return cstring_hash_djb2_ci(&cs); + return cstring_hash_djb2_case(&cs); } inline cstring_hash_t -hash_djb2_ci( +hash_djb2_case( cstring_char_t const* s , size_t cch ) { - return cstring_hash_djb2_len_ci(s, cch); + return cstring_hash_djb2_len_case(s, cch); } inline @@ -1596,30 +1596,30 @@ hash_fnv1a( inline cstring_hash_t -hash_fnv1a_ci( +hash_fnv1a_case( struct cstring_t const* pcs ) { - return cstring_hash_fnv1a_ci(pcs); + return cstring_hash_fnv1a_case(pcs); } inline cstring_hash_t -hash_fnv1a_ci( +hash_fnv1a_case( struct cstring_t const& cs ) { - return cstring_hash_fnv1a_ci(&cs); + return cstring_hash_fnv1a_case(&cs); } inline cstring_hash_t -hash_fnv1a_ci( +hash_fnv1a_case( cstring_char_t const* s , size_t cch ) { - return cstring_hash_fnv1a_len_ci(s, cch); + return cstring_hash_fnv1a_len_case(s, cch); } # ifndef _STLSOFT_NO_NAMESPACE diff --git a/src/cstring.hash.c b/src/cstring.hash.c index 1601e1f..584a930 100644 --- a/src/cstring.hash.c +++ b/src/cstring.hash.c @@ -91,7 +91,7 @@ cstring_hash_djb2( } cstring_hash_t -cstring_hash_djb2_ci( +cstring_hash_djb2_case( struct cstring_t const* pcs ) { @@ -100,7 +100,7 @@ cstring_hash_djb2_ci( return CSTRING_HASH_DJB2_SEED; } - return cstring_hash_djb2_len_ci(pcs->ptr, pcs->len); + return cstring_hash_djb2_len_case(pcs->ptr, pcs->len); } cstring_hash_t @@ -127,7 +127,7 @@ cstring_hash_djb2_len( } cstring_hash_t -cstring_hash_djb2_len_ci( +cstring_hash_djb2_len_case( cstring_char_t const* s , size_t cch ) @@ -167,7 +167,7 @@ cstring_hash_fnv1a( } cstring_hash_t -cstring_hash_fnv1a_ci( +cstring_hash_fnv1a_case( struct cstring_t const* pcs ) { @@ -176,7 +176,7 @@ cstring_hash_fnv1a_ci( return CSTRING_HASH_FNV1A_OFFSET; } - return cstring_hash_fnv1a_len_ci(pcs->ptr, pcs->len); + return cstring_hash_fnv1a_len_case(pcs->ptr, pcs->len); } cstring_hash_t @@ -204,7 +204,7 @@ cstring_hash_fnv1a_len( } cstring_hash_t -cstring_hash_fnv1a_len_ci( +cstring_hash_fnv1a_len_case( cstring_char_t const* s , size_t cch ) diff --git a/test/unit/hash.cxx/entry.cpp b/test/unit/hash.cxx/entry.cpp index 60a6a9f..133d4f0 100644 --- a/test/unit/hash.cxx/entry.cpp +++ b/test/unit/hash.cxx/entry.cpp @@ -53,7 +53,7 @@ namespace static void TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY(void); static void TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS(void); - static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void); + static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_case(void); } /* anonymous namespace */ @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) { XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY); XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS); - XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci); + XTESTS_RUN_CASE(TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_case); XTESTS_PRINT_RESULTS(); @@ -95,18 +95,18 @@ static void TEST_hash_djb2_AND_hash_fnv1a_NULL_AND_EMPTY(void) cstring_t const default_cs = cstring_t_DEFAULT; TEST_INT_EQ(5381ULL, hash_djb2(static_cast(NULL))); - TEST_INT_EQ(5381ULL, hash_djb2_ci(static_cast(NULL))); + TEST_INT_EQ(5381ULL, hash_djb2_case(static_cast(NULL))); TEST_INT_EQ(5381ULL, hash_djb2(default_cs)); - TEST_INT_EQ(5381ULL, hash_djb2_ci(default_cs)); + TEST_INT_EQ(5381ULL, hash_djb2_case(default_cs)); TEST_INT_EQ(5381ULL, hash_djb2(NULL, 0)); - TEST_INT_EQ(5381ULL, hash_djb2_ci(NULL, 0)); + TEST_INT_EQ(5381ULL, hash_djb2_case(NULL, 0)); TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(static_cast(NULL))); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(static_cast(NULL))); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_case(static_cast(NULL))); TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(default_cs)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(default_cs)); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_case(default_cs)); TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a(NULL, 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_ci(NULL, 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, hash_fnv1a_case(NULL, 0)); } static void TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS(void) @@ -128,7 +128,7 @@ static void TEST_hash_djb2_AND_hash_fnv1a_KNOWN_VECTORS(void) cstring_destroy(&cs_foobar); } -static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(void) +static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_case(void) { cstring_t cs; CSTRING_RC rc = cstring_create(&cs, CSTRING_T_("Hello World")); @@ -137,21 +137,21 @@ static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_ci(voi /* Overload by reference */ TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(cs)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(cs)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs), hash_djb2_case(cs)); TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(cs)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(cs)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs), hash_fnv1a_case(cs)); /* Overload by pointer */ TEST_INT_EQ(cstring_hash_djb2(&cs), hash_djb2(&cs)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs), hash_djb2_ci(&cs)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs), hash_djb2_case(&cs)); TEST_INT_EQ(cstring_hash_fnv1a(&cs), hash_fnv1a(&cs)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs), hash_fnv1a_ci(&cs)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs), hash_fnv1a_case(&cs)); /* Overload by slice/buffer */ TEST_INT_EQ(cstring_hash_djb2_len(cs.ptr, cs.len), hash_djb2(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_djb2_len_ci(cs.ptr, cs.len), hash_djb2_ci(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_djb2_len_case(cs.ptr, cs.len), hash_djb2_case(cs.ptr, cs.len)); TEST_INT_EQ(cstring_hash_fnv1a_len(cs.ptr, cs.len), hash_fnv1a(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_fnv1a_len_ci(cs.ptr, cs.len), hash_fnv1a_ci(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_fnv1a_len_case(cs.ptr, cs.len), hash_fnv1a_case(cs.ptr, cs.len)); cstring_destroy(&cs); } diff --git a/test/unit/hash/entry.c b/test/unit/hash/entry.c index 7c9626d..5368190 100644 --- a/test/unit/hash/entry.c +++ b/test/unit/hash/entry.c @@ -40,7 +40,7 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void); static void TEST_cstring_hash_fnv1a_KNOWN_VECTORS(void); static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void); -static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void); +static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_case(void); static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void); static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void); static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void); @@ -75,7 +75,7 @@ int main(int argc, char* argv[]) XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY); XTESTS_RUN_CASE(TEST_cstring_hash_fnv1a_KNOWN_VECTORS); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_KNOWN_VECTORS); - XTESTS_RUN_CASE(TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci); + XTESTS_RUN_CASE(TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_case); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING); XTESTS_RUN_CASE(TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES); @@ -112,37 +112,37 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) /* djb2: initial seed is 5381 */ TEST_INT_EQ(5381ULL, cstring_hash_djb2(pcs_null)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_ci(pcs_null)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_case(pcs_null)); TEST_INT_EQ(5381ULL, cstring_hash_djb2(&null_cs)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_ci(&null_cs)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_case(&null_cs)); TEST_INT_EQ(5381ULL, cstring_hash_djb2(&default_cs)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_ci(&default_cs)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_case(&default_cs)); TEST_INT_EQ(5381ULL, cstring_hash_djb2(&created_empty)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_ci(&created_empty)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_case(&created_empty)); TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(NULL, 0)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_ci(NULL, 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(NULL, 0)); TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(NULL, 10)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_ci(NULL, 10)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(NULL, 10)); TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_ci(CSTRING_T_(""), 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(CSTRING_T_(""), 0)); /* FNV-1a: offset basis is 0xcbf29ce484222325ULL */ TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(pcs_null)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_ci(pcs_null)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_case(pcs_null)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(&null_cs)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_ci(&null_cs)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_case(&null_cs)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(&default_cs)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_ci(&default_cs)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_case(&default_cs)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(&created_empty)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_ci(&created_empty)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_case(&created_empty)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(NULL, 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(NULL, 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(NULL, 0)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(NULL, 10)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(NULL, 10)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(NULL, 10)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(CSTRING_T_(""), 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(CSTRING_T_(""), 0)); cstring_destroy(&created_empty); } @@ -199,7 +199,7 @@ static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void) cstring_destroy(&cs_foobar); } -static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) +static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_case(void) { cstring_hash_t djb2_ci_base; cstring_hash_t fnv1a_ci_base; @@ -210,17 +210,17 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) CSTRING_RC rc; /* Buffer checks */ - djb2_ci_base = cstring_hash_djb2_len_ci(CSTRING_T_("Test"), 4); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("tEst"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("TEST"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("test"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_ci(CSTRING_T_("teSt"), 4)); - - fnv1a_ci_base = cstring_hash_fnv1a_len_ci(CSTRING_T_("Test"), 4); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("tEst"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("TEST"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("test"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_ci(CSTRING_T_("teSt"), 4)); + djb2_ci_base = cstring_hash_djb2_len_case(CSTRING_T_("Test"), 4); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("tEst"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("TEST"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("test"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("teSt"), 4)); + + fnv1a_ci_base = cstring_hash_fnv1a_len_case(CSTRING_T_("Test"), 4); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("tEst"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("TEST"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("test"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("teSt"), 4)); /* Case-sensitive inequality */ TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("Test"), 4), cstring_hash_djb2_len(CSTRING_T_("tEst"), 4)); @@ -236,13 +236,13 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) rc = cstring_create(&cs4, CSTRING_T_("test")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs1), cstring_hash_djb2_ci(&cs2)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs1), cstring_hash_djb2_ci(&cs3)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs1), cstring_hash_djb2_ci(&cs4)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs1), cstring_hash_djb2_case(&cs2)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs1), cstring_hash_djb2_case(&cs3)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs1), cstring_hash_djb2_case(&cs4)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs1), cstring_hash_fnv1a_ci(&cs2)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs1), cstring_hash_fnv1a_ci(&cs3)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs1), cstring_hash_fnv1a_ci(&cs4)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs1), cstring_hash_fnv1a_case(&cs2)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs1), cstring_hash_fnv1a_case(&cs3)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs1), cstring_hash_fnv1a_case(&cs4)); TEST_INT_NE(cstring_hash_djb2(&cs1), cstring_hash_djb2(&cs2)); TEST_INT_NE(cstring_hash_fnv1a(&cs1), cstring_hash_fnv1a(&cs2)); @@ -256,25 +256,25 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_ci(void) static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void) { /* Letters */ - TEST_INT_EQ(cstring_hash_djb2_len_ci(CSTRING_T_("a"), 1), cstring_hash_djb2_len_ci(CSTRING_T_("A"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len_ci(CSTRING_T_("a"), 1), cstring_hash_fnv1a_len_ci(CSTRING_T_("A"), 1)); + TEST_INT_EQ(cstring_hash_djb2_len_case(CSTRING_T_("a"), 1), cstring_hash_djb2_len_case(CSTRING_T_("A"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_len_case(CSTRING_T_("a"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("A"), 1)); TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("a"), 1), cstring_hash_djb2_len(CSTRING_T_("A"), 1)); TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("a"), 1), cstring_hash_fnv1a_len(CSTRING_T_("A"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len_ci(CSTRING_T_("z"), 1), cstring_hash_djb2_len_ci(CSTRING_T_("Z"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len_ci(CSTRING_T_("z"), 1), cstring_hash_fnv1a_len_ci(CSTRING_T_("Z"), 1)); + TEST_INT_EQ(cstring_hash_djb2_len_case(CSTRING_T_("z"), 1), cstring_hash_djb2_len_case(CSTRING_T_("Z"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_len_case(CSTRING_T_("z"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("Z"), 1)); TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("z"), 1), cstring_hash_djb2_len(CSTRING_T_("Z"), 1)); TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("z"), 1), cstring_hash_fnv1a_len(CSTRING_T_("Z"), 1)); /* Non-letters have identical case-sensitive and case-insensitive hashes */ - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("0"), 1), cstring_hash_djb2_len_ci(CSTRING_T_("0"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("0"), 1), cstring_hash_fnv1a_len_ci(CSTRING_T_("0"), 1)); + TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("0"), 1), cstring_hash_djb2_len_case(CSTRING_T_("0"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("0"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("0"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("!"), 1), cstring_hash_djb2_len_ci(CSTRING_T_("!"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("!"), 1), cstring_hash_fnv1a_len_ci(CSTRING_T_("!"), 1)); + TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("!"), 1), cstring_hash_djb2_len_case(CSTRING_T_("!"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("!"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("!"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_(" "), 1), cstring_hash_djb2_len_ci(CSTRING_T_(" "), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_(" "), 1), cstring_hash_fnv1a_len_ci(CSTRING_T_(" "), 1)); + TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_(" "), 1), cstring_hash_djb2_len_case(CSTRING_T_(" "), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_(" "), 1), cstring_hash_fnv1a_len_case(CSTRING_T_(" "), 1)); } static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) @@ -312,13 +312,13 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) /* Verify consistency between struct and buffer APIs */ TEST_INT_EQ(cstring_hash_djb2(&cs_mixed), cstring_hash_djb2_len(cs_mixed.ptr, cs_mixed.len)); - TEST_INT_EQ(cstring_hash_djb2_ci(&cs_mixed), cstring_hash_djb2_len_ci(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs_mixed), cstring_hash_djb2_len_case(cs_mixed.ptr, cs_mixed.len)); TEST_INT_EQ(cstring_hash_fnv1a(&cs_mixed), cstring_hash_fnv1a_len(cs_mixed.ptr, cs_mixed.len)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs_mixed), cstring_hash_fnv1a_len_ci(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs_mixed), cstring_hash_fnv1a_len_case(cs_mixed.ptr, cs_mixed.len)); /* Case-insensitive hashes must match */ - TEST_INT_EQ(cstring_hash_djb2_ci(&cs_mixed), cstring_hash_djb2_ci(&cs_lower)); - TEST_INT_EQ(cstring_hash_fnv1a_ci(&cs_mixed), cstring_hash_fnv1a_ci(&cs_lower)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs_mixed), cstring_hash_djb2_case(&cs_lower)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs_mixed), cstring_hash_fnv1a_case(&cs_lower)); /* Case-sensitive hashes must not match */ TEST_INT_NE(cstring_hash_djb2(&cs_mixed), cstring_hash_djb2(&cs_lower)); @@ -350,8 +350,8 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) TEST_INT_EQ(fnv1a_quick_direct, fnv1a_quick_slice); /* "Fox" starts at index 16, length 3 */ - TEST_INT_EQ(cstring_hash_djb2_len_ci(text + 16, 3), cstring_hash_djb2_len_ci(CSTRING_T_("fox"), 3)); - TEST_INT_EQ(cstring_hash_fnv1a_len_ci(text + 16, 3), cstring_hash_fnv1a_len_ci(CSTRING_T_("fox"), 3)); + TEST_INT_EQ(cstring_hash_djb2_len_case(text + 16, 3), cstring_hash_djb2_len_case(CSTRING_T_("fox"), 3)); + TEST_INT_EQ(cstring_hash_fnv1a_len_case(text + 16, 3), cstring_hash_fnv1a_len_case(CSTRING_T_("fox"), 3)); TEST_INT_NE(cstring_hash_djb2_len(text + 16, 3), cstring_hash_djb2_len(CSTRING_T_("fox"), 3)); TEST_INT_NE(cstring_hash_fnv1a_len(text + 16, 3), cstring_hash_fnv1a_len(CSTRING_T_("fox"), 3)); @@ -379,20 +379,20 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_OCTET_ABOVE_7F TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(hi, 1)); /* tolower of octets above 0x7F follows the process locale. */ - TEST_INT_NE(cstring_hash_djb2_len_ci(mid, 1), cstring_hash_djb2_len_ci(hi, 1)); - TEST_INT_NE(5381ULL, cstring_hash_djb2_len_ci(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(mid, 1), cstring_hash_fnv1a_len_ci(hi, 1)); - TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len_case(mid, 1), cstring_hash_djb2_len_case(hi, 1)); + TEST_INT_NE(5381ULL, cstring_hash_djb2_len_case(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(mid, 1), cstring_hash_fnv1a_len_case(hi, 1)); + TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(hi, 1)); #else /* ? CSTRING_USE_WIDE_STRINGS */ /* Distinct code units only; exact octets would freeze truncation. */ TEST_INT_NE(cstring_hash_djb2_len(mid, 1), cstring_hash_djb2_len(hi, 1)); TEST_INT_NE(cstring_hash_djb2_len(hi, 0), cstring_hash_djb2_len(hi, 1)); - TEST_INT_NE(cstring_hash_djb2_len_ci(mid, 1), cstring_hash_djb2_len_ci(hi, 1)); - TEST_INT_NE(cstring_hash_djb2_len_ci(hi, 0), cstring_hash_djb2_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len_case(mid, 1), cstring_hash_djb2_len_case(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_len_case(hi, 0), cstring_hash_djb2_len_case(hi, 1)); TEST_INT_NE(cstring_hash_fnv1a_len(mid, 1), cstring_hash_fnv1a_len(hi, 1)); TEST_INT_NE(cstring_hash_fnv1a_len(hi, 0), cstring_hash_fnv1a_len(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(mid, 1), cstring_hash_fnv1a_len_ci(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(hi, 0), cstring_hash_fnv1a_len_ci(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(mid, 1), cstring_hash_fnv1a_len_case(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(hi, 0), cstring_hash_fnv1a_len_case(hi, 1)); #endif /* CSTRING_USE_WIDE_STRINGS */ } @@ -408,17 +408,17 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_EMBEDDED_NUL(v TEST_INT_NE(cstring_hash_djb2_len(ab, 2), cstring_hash_djb2_len(a_nul_b, 3)); TEST_INT_NE(cstring_hash_djb2_len(a_nul_c, 3), cstring_hash_djb2_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_ci(a_only, 1), cstring_hash_djb2_len_ci(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_ci(ab, 2), cstring_hash_djb2_len_ci(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_ci(a_nul_c, 3), cstring_hash_djb2_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len_case(a_only, 1), cstring_hash_djb2_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len_case(ab, 2), cstring_hash_djb2_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_len_case(a_nul_c, 3), cstring_hash_djb2_len_case(a_nul_b, 3)); TEST_INT_NE(cstring_hash_fnv1a_len(a_only, 1), cstring_hash_fnv1a_len(a_nul_b, 3)); TEST_INT_NE(cstring_hash_fnv1a_len(ab, 2), cstring_hash_fnv1a_len(a_nul_b, 3)); TEST_INT_NE(cstring_hash_fnv1a_len(a_nul_c, 3), cstring_hash_fnv1a_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(a_only, 1), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(ab, 2), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_ci(a_nul_c, 3), cstring_hash_fnv1a_len_ci(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(a_only, 1), cstring_hash_fnv1a_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(ab, 2), cstring_hash_fnv1a_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_len_case(a_nul_c, 3), cstring_hash_fnv1a_len_case(a_nul_b, 3)); #ifndef CSTRING_USE_WIDE_STRINGS TEST_INT_EQ(193482728ULL, cstring_hash_djb2_len(a_nul_b, 3)); From 0c624dd2c9ef66d108eeb8b574720302576ec6f0 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 5 Oct 2026 16:11:47 +1100 Subject: [PATCH 12/12] refactor(cstring): rename the counted hash suffix from _len to _buf Rename the pointer-and-length hash functions from `_len` to `_buf` (`cstring_hash_djb2_buf`, `cstring_hash_djb2_buf_case`, and the FNV-1a twins), including the C++ shims and the unit tests. --- include/cstring/cstring.h | 16 +-- src/cstring.hash.c | 16 +-- test/unit/hash.cxx/entry.cpp | 8 +- test/unit/hash/entry.c | 182 +++++++++++++++++------------------ 4 files changed, 111 insertions(+), 111 deletions(-) diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index 7da5205..a72b8f0 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -1215,7 +1215,7 @@ cstring_hash_djb2_case( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_djb2_len( +cstring_hash_djb2_buf( cstring_char_t const* s , size_t cch ); @@ -1231,7 +1231,7 @@ cstring_hash_djb2_len( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_djb2_len_case( +cstring_hash_djb2_buf_case( cstring_char_t const* s , size_t cch ); @@ -1274,7 +1274,7 @@ cstring_hash_fnv1a_case( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_fnv1a_len( +cstring_hash_fnv1a_buf( cstring_char_t const* s , size_t cch ); @@ -1290,7 +1290,7 @@ cstring_hash_fnv1a_len( */ CSTRING_EXTERN_C cstring_hash_t -cstring_hash_fnv1a_len_case( +cstring_hash_fnv1a_buf_case( cstring_char_t const* s , size_t cch ); @@ -1535,7 +1535,7 @@ hash_djb2( , size_t cch ) { - return cstring_hash_djb2_len(s, cch); + return cstring_hash_djb2_buf(s, cch); } inline @@ -1563,7 +1563,7 @@ hash_djb2_case( , size_t cch ) { - return cstring_hash_djb2_len_case(s, cch); + return cstring_hash_djb2_buf_case(s, cch); } inline @@ -1591,7 +1591,7 @@ hash_fnv1a( , size_t cch ) { - return cstring_hash_fnv1a_len(s, cch); + return cstring_hash_fnv1a_buf(s, cch); } inline @@ -1619,7 +1619,7 @@ hash_fnv1a_case( , size_t cch ) { - return cstring_hash_fnv1a_len_case(s, cch); + return cstring_hash_fnv1a_buf_case(s, cch); } # ifndef _STLSOFT_NO_NAMESPACE diff --git a/src/cstring.hash.c b/src/cstring.hash.c index 584a930..7ecbe71 100644 --- a/src/cstring.hash.c +++ b/src/cstring.hash.c @@ -87,7 +87,7 @@ cstring_hash_djb2( return CSTRING_HASH_DJB2_SEED; } - return cstring_hash_djb2_len(pcs->ptr, pcs->len); + return cstring_hash_djb2_buf(pcs->ptr, pcs->len); } cstring_hash_t @@ -100,11 +100,11 @@ cstring_hash_djb2_case( return CSTRING_HASH_DJB2_SEED; } - return cstring_hash_djb2_len_case(pcs->ptr, pcs->len); + return cstring_hash_djb2_buf_case(pcs->ptr, pcs->len); } cstring_hash_t -cstring_hash_djb2_len( +cstring_hash_djb2_buf( cstring_char_t const* s , size_t cch ) @@ -127,7 +127,7 @@ cstring_hash_djb2_len( } cstring_hash_t -cstring_hash_djb2_len_case( +cstring_hash_djb2_buf_case( cstring_char_t const* s , size_t cch ) @@ -163,7 +163,7 @@ cstring_hash_fnv1a( return CSTRING_HASH_FNV1A_OFFSET; } - return cstring_hash_fnv1a_len(pcs->ptr, pcs->len); + return cstring_hash_fnv1a_buf(pcs->ptr, pcs->len); } cstring_hash_t @@ -176,11 +176,11 @@ cstring_hash_fnv1a_case( return CSTRING_HASH_FNV1A_OFFSET; } - return cstring_hash_fnv1a_len_case(pcs->ptr, pcs->len); + return cstring_hash_fnv1a_buf_case(pcs->ptr, pcs->len); } cstring_hash_t -cstring_hash_fnv1a_len( +cstring_hash_fnv1a_buf( cstring_char_t const* s , size_t cch ) @@ -204,7 +204,7 @@ cstring_hash_fnv1a_len( } cstring_hash_t -cstring_hash_fnv1a_len_case( +cstring_hash_fnv1a_buf_case( cstring_char_t const* s , size_t cch ) diff --git a/test/unit/hash.cxx/entry.cpp b/test/unit/hash.cxx/entry.cpp index 133d4f0..ac423fb 100644 --- a/test/unit/hash.cxx/entry.cpp +++ b/test/unit/hash.cxx/entry.cpp @@ -148,10 +148,10 @@ static void TEST_hash_djb2_AND_hash_djb2_ci_AND_hash_fnv1a_AND_hash_fnv1a_case(v TEST_INT_EQ(cstring_hash_fnv1a_case(&cs), hash_fnv1a_case(&cs)); /* Overload by slice/buffer */ - TEST_INT_EQ(cstring_hash_djb2_len(cs.ptr, cs.len), hash_djb2(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_djb2_len_case(cs.ptr, cs.len), hash_djb2_case(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_fnv1a_len(cs.ptr, cs.len), hash_fnv1a(cs.ptr, cs.len)); - TEST_INT_EQ(cstring_hash_fnv1a_len_case(cs.ptr, cs.len), hash_fnv1a_case(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_djb2_buf(cs.ptr, cs.len), hash_djb2(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_djb2_buf_case(cs.ptr, cs.len), hash_djb2_case(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_fnv1a_buf(cs.ptr, cs.len), hash_fnv1a(cs.ptr, cs.len)); + TEST_INT_EQ(cstring_hash_fnv1a_buf_case(cs.ptr, cs.len), hash_fnv1a_case(cs.ptr, cs.len)); cstring_destroy(&cs); } diff --git a/test/unit/hash/entry.c b/test/unit/hash/entry.c index 5368190..1308e2b 100644 --- a/test/unit/hash/entry.c +++ b/test/unit/hash/entry.c @@ -120,12 +120,12 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) TEST_INT_EQ(5381ULL, cstring_hash_djb2(&created_empty)); TEST_INT_EQ(5381ULL, cstring_hash_djb2_case(&created_empty)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(NULL, 0)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(NULL, 0)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(NULL, 10)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(NULL, 10)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len_case(CSTRING_T_(""), 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf(NULL, 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf_case(NULL, 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf(NULL, 10)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf_case(NULL, 10)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf(CSTRING_T_(""), 0)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf_case(CSTRING_T_(""), 0)); /* FNV-1a: offset basis is 0xcbf29ce484222325ULL */ TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(pcs_null)); @@ -137,12 +137,12 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_NULL_AND_EMPTY(void) TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a(&created_empty)); TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_case(&created_empty)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(NULL, 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(NULL, 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(NULL, 10)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(NULL, 10)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(CSTRING_T_(""), 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf(NULL, 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf_case(NULL, 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf(NULL, 10)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf_case(NULL, 10)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf(CSTRING_T_(""), 0)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf_case(CSTRING_T_(""), 0)); cstring_destroy(&created_empty); } @@ -158,9 +158,9 @@ static void TEST_cstring_hash_fnv1a_KNOWN_VECTORS(void) cstring_t cs_foobar; CSTRING_RC rc; - TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(0xaf63dc4c8601ec8cULL, cstring_hash_fnv1a_len(CSTRING_T_("a"), 1)); - TEST_INT_EQ(0x85944171f73967e8ULL, cstring_hash_fnv1a_len(CSTRING_T_("foobar"), 6)); + TEST_INT_EQ(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf(CSTRING_T_(""), 0)); + TEST_INT_EQ(0xaf63dc4c8601ec8cULL, cstring_hash_fnv1a_buf(CSTRING_T_("a"), 1)); + TEST_INT_EQ(0x85944171f73967e8ULL, cstring_hash_fnv1a_buf(CSTRING_T_("foobar"), 6)); rc = cstring_create(&cs_a, CSTRING_T_("a")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); @@ -184,9 +184,9 @@ static void TEST_cstring_hash_djb2_KNOWN_VECTORS(void) cstring_t cs_foobar; CSTRING_RC rc; - TEST_INT_EQ(5381ULL, cstring_hash_djb2_len(CSTRING_T_(""), 0)); - TEST_INT_EQ(177670ULL, cstring_hash_djb2_len(CSTRING_T_("a"), 1)); - TEST_INT_EQ(6953516687550ULL, cstring_hash_djb2_len(CSTRING_T_("foobar"), 6)); + TEST_INT_EQ(5381ULL, cstring_hash_djb2_buf(CSTRING_T_(""), 0)); + TEST_INT_EQ(177670ULL, cstring_hash_djb2_buf(CSTRING_T_("a"), 1)); + TEST_INT_EQ(6953516687550ULL, cstring_hash_djb2_buf(CSTRING_T_("foobar"), 6)); rc = cstring_create(&cs_a, CSTRING_T_("a")); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); @@ -210,21 +210,21 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_case(void) CSTRING_RC rc; /* Buffer checks */ - djb2_ci_base = cstring_hash_djb2_len_case(CSTRING_T_("Test"), 4); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("tEst"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("TEST"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("test"), 4)); - TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_len_case(CSTRING_T_("teSt"), 4)); - - fnv1a_ci_base = cstring_hash_fnv1a_len_case(CSTRING_T_("Test"), 4); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("tEst"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("TEST"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("test"), 4)); - TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_len_case(CSTRING_T_("teSt"), 4)); + djb2_ci_base = cstring_hash_djb2_buf_case(CSTRING_T_("Test"), 4); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_buf_case(CSTRING_T_("tEst"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_buf_case(CSTRING_T_("TEST"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_buf_case(CSTRING_T_("test"), 4)); + TEST_INT_EQ(djb2_ci_base, cstring_hash_djb2_buf_case(CSTRING_T_("teSt"), 4)); + + fnv1a_ci_base = cstring_hash_fnv1a_buf_case(CSTRING_T_("Test"), 4); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_buf_case(CSTRING_T_("tEst"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_buf_case(CSTRING_T_("TEST"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_buf_case(CSTRING_T_("test"), 4)); + TEST_INT_EQ(fnv1a_ci_base, cstring_hash_fnv1a_buf_case(CSTRING_T_("teSt"), 4)); /* Case-sensitive inequality */ - TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("Test"), 4), cstring_hash_djb2_len(CSTRING_T_("tEst"), 4)); - TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("Test"), 4), cstring_hash_fnv1a_len(CSTRING_T_("tEst"), 4)); + TEST_INT_NE(cstring_hash_djb2_buf(CSTRING_T_("Test"), 4), cstring_hash_djb2_buf(CSTRING_T_("tEst"), 4)); + TEST_INT_NE(cstring_hash_fnv1a_buf(CSTRING_T_("Test"), 4), cstring_hash_fnv1a_buf(CSTRING_T_("tEst"), 4)); /* Instance checks */ rc = cstring_create(&cs1, CSTRING_T_("Test")); @@ -256,25 +256,25 @@ static void TEST_cstring_hash_djb2_ci_AND_cstring_hash_fnv1a_case(void) static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_SINGLE_CHARACTER(void) { /* Letters */ - TEST_INT_EQ(cstring_hash_djb2_len_case(CSTRING_T_("a"), 1), cstring_hash_djb2_len_case(CSTRING_T_("A"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len_case(CSTRING_T_("a"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("A"), 1)); - TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("a"), 1), cstring_hash_djb2_len(CSTRING_T_("A"), 1)); - TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("a"), 1), cstring_hash_fnv1a_len(CSTRING_T_("A"), 1)); + TEST_INT_EQ(cstring_hash_djb2_buf_case(CSTRING_T_("a"), 1), cstring_hash_djb2_buf_case(CSTRING_T_("A"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_buf_case(CSTRING_T_("a"), 1), cstring_hash_fnv1a_buf_case(CSTRING_T_("A"), 1)); + TEST_INT_NE(cstring_hash_djb2_buf(CSTRING_T_("a"), 1), cstring_hash_djb2_buf(CSTRING_T_("A"), 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf(CSTRING_T_("a"), 1), cstring_hash_fnv1a_buf(CSTRING_T_("A"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len_case(CSTRING_T_("z"), 1), cstring_hash_djb2_len_case(CSTRING_T_("Z"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len_case(CSTRING_T_("z"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("Z"), 1)); - TEST_INT_NE(cstring_hash_djb2_len(CSTRING_T_("z"), 1), cstring_hash_djb2_len(CSTRING_T_("Z"), 1)); - TEST_INT_NE(cstring_hash_fnv1a_len(CSTRING_T_("z"), 1), cstring_hash_fnv1a_len(CSTRING_T_("Z"), 1)); + TEST_INT_EQ(cstring_hash_djb2_buf_case(CSTRING_T_("z"), 1), cstring_hash_djb2_buf_case(CSTRING_T_("Z"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_buf_case(CSTRING_T_("z"), 1), cstring_hash_fnv1a_buf_case(CSTRING_T_("Z"), 1)); + TEST_INT_NE(cstring_hash_djb2_buf(CSTRING_T_("z"), 1), cstring_hash_djb2_buf(CSTRING_T_("Z"), 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf(CSTRING_T_("z"), 1), cstring_hash_fnv1a_buf(CSTRING_T_("Z"), 1)); /* Non-letters have identical case-sensitive and case-insensitive hashes */ - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("0"), 1), cstring_hash_djb2_len_case(CSTRING_T_("0"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("0"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("0"), 1)); + TEST_INT_EQ(cstring_hash_djb2_buf(CSTRING_T_("0"), 1), cstring_hash_djb2_buf_case(CSTRING_T_("0"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_buf(CSTRING_T_("0"), 1), cstring_hash_fnv1a_buf_case(CSTRING_T_("0"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_("!"), 1), cstring_hash_djb2_len_case(CSTRING_T_("!"), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_("!"), 1), cstring_hash_fnv1a_len_case(CSTRING_T_("!"), 1)); + TEST_INT_EQ(cstring_hash_djb2_buf(CSTRING_T_("!"), 1), cstring_hash_djb2_buf_case(CSTRING_T_("!"), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_buf(CSTRING_T_("!"), 1), cstring_hash_fnv1a_buf_case(CSTRING_T_("!"), 1)); - TEST_INT_EQ(cstring_hash_djb2_len(CSTRING_T_(" "), 1), cstring_hash_djb2_len_case(CSTRING_T_(" "), 1)); - TEST_INT_EQ(cstring_hash_fnv1a_len(CSTRING_T_(" "), 1), cstring_hash_fnv1a_len_case(CSTRING_T_(" "), 1)); + TEST_INT_EQ(cstring_hash_djb2_buf(CSTRING_T_(" "), 1), cstring_hash_djb2_buf_case(CSTRING_T_(" "), 1)); + TEST_INT_EQ(cstring_hash_fnv1a_buf(CSTRING_T_(" "), 1), cstring_hash_fnv1a_buf_case(CSTRING_T_(" "), 1)); } static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) @@ -311,10 +311,10 @@ static void TEST_cstring_hash_djb2_AND_cstring_hash_fnv1a_LONG_STRING(void) TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); /* Verify consistency between struct and buffer APIs */ - TEST_INT_EQ(cstring_hash_djb2(&cs_mixed), cstring_hash_djb2_len(cs_mixed.ptr, cs_mixed.len)); - TEST_INT_EQ(cstring_hash_djb2_case(&cs_mixed), cstring_hash_djb2_len_case(cs_mixed.ptr, cs_mixed.len)); - TEST_INT_EQ(cstring_hash_fnv1a(&cs_mixed), cstring_hash_fnv1a_len(cs_mixed.ptr, cs_mixed.len)); - TEST_INT_EQ(cstring_hash_fnv1a_case(&cs_mixed), cstring_hash_fnv1a_len_case(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_djb2(&cs_mixed), cstring_hash_djb2_buf(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_djb2_case(&cs_mixed), cstring_hash_djb2_buf_case(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_fnv1a(&cs_mixed), cstring_hash_fnv1a_buf(cs_mixed.ptr, cs_mixed.len)); + TEST_INT_EQ(cstring_hash_fnv1a_case(&cs_mixed), cstring_hash_fnv1a_buf_case(cs_mixed.ptr, cs_mixed.len)); /* Case-insensitive hashes must match */ TEST_INT_EQ(cstring_hash_djb2_case(&cs_mixed), cstring_hash_djb2_case(&cs_lower)); @@ -341,25 +341,25 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_SLICES(void) /* Slices without constructing cstring_t */ /* "quick" starts at index 4, length 5 */ - djb2_quick_slice = cstring_hash_djb2_len(text + 4, 5); - djb2_quick_direct = cstring_hash_djb2_len(CSTRING_T_("quick"), 5); + djb2_quick_slice = cstring_hash_djb2_buf(text + 4, 5); + djb2_quick_direct = cstring_hash_djb2_buf(CSTRING_T_("quick"), 5); TEST_INT_EQ(djb2_quick_direct, djb2_quick_slice); - fnv1a_quick_slice = cstring_hash_fnv1a_len(text + 4, 5); - fnv1a_quick_direct = cstring_hash_fnv1a_len(CSTRING_T_("quick"), 5); + fnv1a_quick_slice = cstring_hash_fnv1a_buf(text + 4, 5); + fnv1a_quick_direct = cstring_hash_fnv1a_buf(CSTRING_T_("quick"), 5); TEST_INT_EQ(fnv1a_quick_direct, fnv1a_quick_slice); /* "Fox" starts at index 16, length 3 */ - TEST_INT_EQ(cstring_hash_djb2_len_case(text + 16, 3), cstring_hash_djb2_len_case(CSTRING_T_("fox"), 3)); - TEST_INT_EQ(cstring_hash_fnv1a_len_case(text + 16, 3), cstring_hash_fnv1a_len_case(CSTRING_T_("fox"), 3)); - TEST_INT_NE(cstring_hash_djb2_len(text + 16, 3), cstring_hash_djb2_len(CSTRING_T_("fox"), 3)); - TEST_INT_NE(cstring_hash_fnv1a_len(text + 16, 3), cstring_hash_fnv1a_len(CSTRING_T_("fox"), 3)); + TEST_INT_EQ(cstring_hash_djb2_buf_case(text + 16, 3), cstring_hash_djb2_buf_case(CSTRING_T_("fox"), 3)); + TEST_INT_EQ(cstring_hash_fnv1a_buf_case(text + 16, 3), cstring_hash_fnv1a_buf_case(CSTRING_T_("fox"), 3)); + TEST_INT_NE(cstring_hash_djb2_buf(text + 16, 3), cstring_hash_djb2_buf(CSTRING_T_("fox"), 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf(text + 16, 3), cstring_hash_fnv1a_buf(CSTRING_T_("fox"), 3)); /* Hashing full text via buffer API */ rc = cstring_createLen(&cs, text, total_len); TEST_ENUM_EQ(CSTRING_RC_SUCCESS, rc); - TEST_INT_EQ(cstring_hash_djb2_len(text, total_len), cstring_hash_djb2(&cs)); - TEST_INT_EQ(cstring_hash_fnv1a_len(text, total_len), cstring_hash_fnv1a(&cs)); + TEST_INT_EQ(cstring_hash_djb2_buf(text, total_len), cstring_hash_djb2(&cs)); + TEST_INT_EQ(cstring_hash_fnv1a_buf(text, total_len), cstring_hash_fnv1a(&cs)); cstring_destroy(&cs); } @@ -370,29 +370,29 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_OCTET_ABOVE_7F #ifndef CSTRING_USE_WIDE_STRINGS /* djb2: 5381 * 33 + octet. FNV-1a: one-byte 64-bit vectors. */ - TEST_INT_EQ(177828ULL, cstring_hash_djb2_len(hi, 1)); - TEST_INT_EQ(0xaf64724c8602eb6eULL, cstring_hash_fnv1a_len(hi, 1)); - TEST_INT_EQ(177700ULL, cstring_hash_djb2_len(mid, 1)); - TEST_INT_EQ(0xaf63f24c860211eeULL, cstring_hash_fnv1a_len(mid, 1)); + TEST_INT_EQ(177828ULL, cstring_hash_djb2_buf(hi, 1)); + TEST_INT_EQ(0xaf64724c8602eb6eULL, cstring_hash_fnv1a_buf(hi, 1)); + TEST_INT_EQ(177700ULL, cstring_hash_djb2_buf(mid, 1)); + TEST_INT_EQ(0xaf63f24c860211eeULL, cstring_hash_fnv1a_buf(mid, 1)); - TEST_INT_NE(5381ULL, cstring_hash_djb2_len(hi, 1)); - TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len(hi, 1)); + TEST_INT_NE(5381ULL, cstring_hash_djb2_buf(hi, 1)); + TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf(hi, 1)); /* tolower of octets above 0x7F follows the process locale. */ - TEST_INT_NE(cstring_hash_djb2_len_case(mid, 1), cstring_hash_djb2_len_case(hi, 1)); - TEST_INT_NE(5381ULL, cstring_hash_djb2_len_case(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(mid, 1), cstring_hash_fnv1a_len_case(hi, 1)); - TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_len_case(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_buf_case(mid, 1), cstring_hash_djb2_buf_case(hi, 1)); + TEST_INT_NE(5381ULL, cstring_hash_djb2_buf_case(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(mid, 1), cstring_hash_fnv1a_buf_case(hi, 1)); + TEST_INT_NE(0xcbf29ce484222325ULL, cstring_hash_fnv1a_buf_case(hi, 1)); #else /* ? CSTRING_USE_WIDE_STRINGS */ /* Distinct code units only; exact octets would freeze truncation. */ - TEST_INT_NE(cstring_hash_djb2_len(mid, 1), cstring_hash_djb2_len(hi, 1)); - TEST_INT_NE(cstring_hash_djb2_len(hi, 0), cstring_hash_djb2_len(hi, 1)); - TEST_INT_NE(cstring_hash_djb2_len_case(mid, 1), cstring_hash_djb2_len_case(hi, 1)); - TEST_INT_NE(cstring_hash_djb2_len_case(hi, 0), cstring_hash_djb2_len_case(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len(mid, 1), cstring_hash_fnv1a_len(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len(hi, 0), cstring_hash_fnv1a_len(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(mid, 1), cstring_hash_fnv1a_len_case(hi, 1)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(hi, 0), cstring_hash_fnv1a_len_case(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_buf(mid, 1), cstring_hash_djb2_buf(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_buf(hi, 0), cstring_hash_djb2_buf(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_buf_case(mid, 1), cstring_hash_djb2_buf_case(hi, 1)); + TEST_INT_NE(cstring_hash_djb2_buf_case(hi, 0), cstring_hash_djb2_buf_case(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf(mid, 1), cstring_hash_fnv1a_buf(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf(hi, 0), cstring_hash_fnv1a_buf(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(mid, 1), cstring_hash_fnv1a_buf_case(hi, 1)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(hi, 0), cstring_hash_fnv1a_buf_case(hi, 1)); #endif /* CSTRING_USE_WIDE_STRINGS */ } @@ -404,25 +404,25 @@ static void TEST_cstring_hash_djb2_len_AND_cstring_hash_fnv1a_len_EMBEDDED_NUL(v cstring_char_t const a_nul_c[3] = { CSTRING_T_('a'), (cstring_char_t)0, CSTRING_T_('c') }; /* Explicit length, so an interior NUL does not end the slice. */ - TEST_INT_NE(cstring_hash_djb2_len(a_only, 1), cstring_hash_djb2_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len(ab, 2), cstring_hash_djb2_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len(a_nul_c, 3), cstring_hash_djb2_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf(a_only, 1), cstring_hash_djb2_buf(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf(ab, 2), cstring_hash_djb2_buf(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf(a_nul_c, 3), cstring_hash_djb2_buf(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_case(a_only, 1), cstring_hash_djb2_len_case(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_case(ab, 2), cstring_hash_djb2_len_case(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_djb2_len_case(a_nul_c, 3), cstring_hash_djb2_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf_case(a_only, 1), cstring_hash_djb2_buf_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf_case(ab, 2), cstring_hash_djb2_buf_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_djb2_buf_case(a_nul_c, 3), cstring_hash_djb2_buf_case(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len(a_only, 1), cstring_hash_fnv1a_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len(ab, 2), cstring_hash_fnv1a_len(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len(a_nul_c, 3), cstring_hash_fnv1a_len(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf(a_only, 1), cstring_hash_fnv1a_buf(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf(ab, 2), cstring_hash_fnv1a_buf(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf(a_nul_c, 3), cstring_hash_fnv1a_buf(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(a_only, 1), cstring_hash_fnv1a_len_case(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(ab, 2), cstring_hash_fnv1a_len_case(a_nul_b, 3)); - TEST_INT_NE(cstring_hash_fnv1a_len_case(a_nul_c, 3), cstring_hash_fnv1a_len_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(a_only, 1), cstring_hash_fnv1a_buf_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(ab, 2), cstring_hash_fnv1a_buf_case(a_nul_b, 3)); + TEST_INT_NE(cstring_hash_fnv1a_buf_case(a_nul_c, 3), cstring_hash_fnv1a_buf_case(a_nul_b, 3)); #ifndef CSTRING_USE_WIDE_STRINGS - TEST_INT_EQ(193482728ULL, cstring_hash_djb2_len(a_nul_b, 3)); - TEST_INT_EQ(0xe5d29919042666b2ULL, cstring_hash_fnv1a_len(a_nul_b, 3)); + TEST_INT_EQ(193482728ULL, cstring_hash_djb2_buf(a_nul_b, 3)); + TEST_INT_EQ(0xe5d29919042666b2ULL, cstring_hash_fnv1a_buf(a_nul_b, 3)); #endif /* CSTRING_USE_WIDE_STRINGS */ }