commit 0460147a6eb6d881eee3041393e2f1c120c56f4d
parent 31529df9243e91a1de7b32633d38dd8825b3a7db
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 1 Jun 2026 12:02:48 -0700
core: unify slice helpers onto the public inline impls
slice_from_cstr/slice_eq/slice_eq_cstr were a second, out-of-line copy of
logic already living inline in <cfree/core.h> (cfree_slice_cstr/eq/eq_cstr),
and had even diverged (memcmp vs byte loop for eq). Alias the internal names
to the public inline implementations, mirroring how core/hashmap.h aliases
CFREE_HASHMAP_DEFINE / cfree_hash_*. Call sites keep their short spellings.
slice.c now holds only slice_dup, which needs an Arena.
Diffstat:
2 files changed, 15 insertions(+), 38 deletions(-)
diff --git a/src/core/slice.c b/src/core/slice.c
@@ -1,26 +1,8 @@
#include "core/slice.h"
-#include <string.h>
-
-Slice slice_from_cstr(const char* z) {
- if (!z) return SLICE_NULL;
- return (Slice){.s = z, .len = strlen(z)};
-}
-
-bool slice_eq(Slice a, Slice b) {
- if (a.len != b.len) return false;
- if (a.len == 0) return true;
- return memcmp(a.s, b.s, a.len) == 0;
-}
-
-bool slice_eq_cstr(Slice a, const char* z) {
- size_t i;
- if (!z) return a.len == 0;
- for (i = 0; i < a.len; ++i) {
- if (z[i] == '\0' || z[i] != a.s[i]) return false;
- }
- return z[a.len] == '\0';
-}
+/* slice_from_cstr / slice_eq / slice_eq_cstr are aliases of the public inline
+ * implementations in <cfree/core.h> (see core/slice.h). Only slice_dup lives
+ * here, since it needs an Arena. */
Slice slice_dup(Arena* arena, Slice in) {
char* dst = arena_strdup(arena, in.s, in.len);
diff --git a/src/core/slice.h b/src/core/slice.h
@@ -3,8 +3,10 @@
/*
* Internal fat-pointer string/byte view. `Slice` is the internal alias of the
- * public CfreeSlice: a borrowed (ptr, len) pair, readable as text (`s`) or
- * bytes (`data`). `len` never counts a trailing NUL.
+ * public CfreeSlice, and the internal slice_* names are thin aliases of the
+ * public cfree_slice_* inline implementations in <cfree/core.h>: there is a
+ * single source of truth for the logic. Only slice_dup (which needs an Arena,
+ * so it cannot live in the freestanding public header) is internal-only.
*
* cfree carries lengths everywhere; NUL termination is only a boundary
* convenience. slice_from_cstr() is the single sanctioned place that scans a
@@ -16,23 +18,16 @@
typedef CfreeSlice Slice;
-/* Build a slice from a string literal (length is compile-time, no strlen). */
-#define SLICE_LIT(lit) ((Slice){.s = (lit), .len = sizeof(lit) - 1})
-/* The empty slice. */
-#define SLICE_NULL ((Slice){.s = NULL, .len = 0})
-/* Spread a slice into printf "%.*s" arguments. */
+/* Short internal spellings of the public slice surface. The logic lives once,
+ * in <cfree/core.h>; these are aliases (cf. core/hashmap.h aliasing the public
+ * CFREE_HASHMAP_DEFINE / cfree_hash_*). */
+#define SLICE_LIT(lit) CFREE_SLICE_LIT(lit)
+#define SLICE_NULL CFREE_SLICE_NULL
#define SLICE_ARG(x) CFREE_SLICE_ARG(x)
-/* Boundary helper: lift a NUL-terminated C string into a slice. The only
- * sanctioned NUL scan; use exclusively where a string arrives from the OS
- * (argv, getenv) or another NUL-terminated foreign API. NULL yields SLICE_NULL.
- */
-Slice slice_from_cstr(const char* z);
-
-/* Byte-exact equality. */
-bool slice_eq(Slice a, Slice b);
-/* Equality against a NUL-terminated literal/string (compares bytes, no NUL). */
-bool slice_eq_cstr(Slice a, const char* z);
+#define slice_from_cstr cfree_slice_cstr
+#define slice_eq cfree_slice_eq
+#define slice_eq_cstr cfree_slice_eq_cstr
/* Copy into the arena with a trailing NUL (so the result is also usable at a
* boundary). The trailing NUL is not counted in the returned length. */