summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--include/zix/attributes.h8
-rw-r--r--include/zix/string_view.h107
-rw-r--r--include/zix/zix.h1
-rw-r--r--meson.build4
-rw-r--r--src/string_view.c18
-rw-r--r--test/headers/test_headers.c1
7 files changed, 136 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index 1fba679..4f67966 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-zix (0.2.0) unstable; urgency=medium
+zix (0.3.0) unstable; urgency=medium
* Initial release
diff --git a/include/zix/attributes.h b/include/zix/attributes.h
index 1fe1183..b076fa7 100644
--- a/include/zix/attributes.h
+++ b/include/zix/attributes.h
@@ -34,13 +34,15 @@
// GCC function attributes
#ifdef __GNUC__
+# define ZIX_ALWAYS_INLINE_FUNC __attribute__((always_inline))
# define ZIX_PURE_FUNC __attribute__((pure))
# define ZIX_CONST_FUNC __attribute__((const))
# define ZIX_MALLOC_FUNC __attribute__((malloc))
#else
-# define ZIX_PURE_FUNC ///< Only reads memory
-# define ZIX_CONST_FUNC ///< Only reads its parameters
-# define ZIX_MALLOC_FUNC ///< Allocates memory
+# define ZIX_ALWAYS_INLINE_FUNC ///< Should absolutely always be inlined
+# define ZIX_PURE_FUNC ///< Only reads memory
+# define ZIX_CONST_FUNC ///< Only reads its parameters
+# define ZIX_MALLOC_FUNC ///< Allocates memory
#endif
/// A pure function in the public API that only reads memory
diff --git a/include/zix/string_view.h b/include/zix/string_view.h
new file mode 100644
index 0000000..f4cd6c2
--- /dev/null
+++ b/include/zix/string_view.h
@@ -0,0 +1,107 @@
+// Copyright 2011-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef ZIX_STRING_VIEW_H
+#define ZIX_STRING_VIEW_H
+
+#include "zix/allocator.h"
+#include "zix/attributes.h"
+
+#include <stddef.h>
+#include <string.h>
+
+ZIX_BEGIN_DECLS
+
+/**
+ @defgroup zix_string_view String View
+ @ingroup zix_utilities
+ @{
+*/
+
+/**
+ An immutable slice of a string.
+
+ This type is used for many string parameters, to allow referring to slices
+ of strings in-place and to avoid redundant string measurement.
+*/
+typedef struct {
+ const char* ZIX_NONNULL data; ///< Pointer to the first character
+ size_t length; ///< Length of string in bytes
+} ZixStringView;
+
+/// Return a view of an empty string
+ZIX_ALWAYS_INLINE_FUNC
+ZIX_CONST_FUNC
+static inline ZixStringView
+zix_empty_string(void)
+{
+ const ZixStringView view = {"", 0U};
+ return view;
+}
+
+/**
+ Return a view of a substring, or a premeasured string.
+
+ This makes either a view of a slice of a string (which may not be null
+ terminated), or a view of a string that has already been measured. This is
+ faster than zix_string() for dynamic strings since it does not call
+ `strlen`, so should be used when the length of the string is already known.
+
+ @param str Pointer to the start of the substring.
+
+ @param len Length of the substring in bytes, not including the trailing null
+ terminator if present.
+*/
+ZIX_ALWAYS_INLINE_FUNC
+ZIX_CONST_FUNC
+static inline ZixStringView
+zix_substring(const char* const ZIX_NONNULL str, const size_t len)
+{
+ const ZixStringView view = {str, len};
+ return view;
+}
+
+/**
+ Return a view of an entire string by measuring it.
+
+ This makes a view of the given string by measuring it with `strlen`.
+
+ @param str Pointer to the start of a null-terminated C string, or null.
+*/
+ZIX_ALWAYS_INLINE_FUNC
+ZIX_PURE_FUNC
+static inline ZixStringView
+zix_string(const char* const ZIX_NONNULL str)
+{
+ const ZixStringView view = {str, strlen(str)};
+ return view;
+}
+
+/**
+ Return a view of an entire string by measuring it.
+
+ This makes a view of the given string by measuring it with `strlen`.
+
+ @param str Pointer to the start of a null-terminated C string, or null.
+*/
+ZIX_PURE_FUNC
+static inline ZixStringView
+zix_optional_string(const char* const ZIX_NULLABLE str)
+{
+ return str ? zix_string(str) : zix_empty_string();
+}
+
+/**
+ Copy a string view into a newly allocated null-terminated string.
+*/
+ZIX_API
+char* ZIX_ALLOCATED
+zix_string_view_copy(ZixAllocator* ZIX_NULLABLE allocator, ZixStringView view);
+
+/**
+ @}
+*/
+
+ZIX_END_DECLS
+
+#endif // ZIX_STRING_VIEW_H
diff --git a/include/zix/zix.h b/include/zix/zix.h
index 02ab31f..223d1dc 100644
--- a/include/zix/zix.h
+++ b/include/zix/zix.h
@@ -20,6 +20,7 @@
#include "zix/digest.h"
#include "zix/function_types.h"
#include "zix/status.h"
+#include "zix/string_view.h"
/**
@}
diff --git a/meson.build b/meson.build
index c56a10e..9a64ba6 100644
--- a/meson.build
+++ b/meson.build
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: 0BSD OR ISC
project('zix', ['c'],
- version: '0.2.0',
+ version: '0.3.0',
license: 'ISC',
meson_version: '>= 0.56.0',
default_options: [
@@ -103,6 +103,7 @@ c_headers = files(
'include/zix/ring.h',
'include/zix/sem.h',
'include/zix/status.h',
+ 'include/zix/string_view.h',
'include/zix/thread.h',
'include/zix/tree.h',
'include/zix/zix.h',
@@ -118,6 +119,7 @@ sources = files(
'src/hash.c',
'src/ring.c',
'src/status.c',
+ 'src/string_view.c',
'src/tree.c',
)
diff --git a/src/string_view.c b/src/string_view.c
new file mode 100644
index 0000000..9d98258
--- /dev/null
+++ b/src/string_view.c
@@ -0,0 +1,18 @@
+// Copyright 2007-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "zix/string_view.h"
+#include "zix/allocator.h"
+
+#include <string.h>
+
+char*
+zix_string_view_copy(ZixAllocator* const allocator, const ZixStringView view)
+{
+ char* const copy = (char*)zix_malloc(allocator, view.length + 1U);
+ if (copy) {
+ memcpy(copy, view.data, view.length);
+ copy[view.length] = '\0';
+ }
+ return copy;
+}
diff --git a/test/headers/test_headers.c b/test/headers/test_headers.c
index c1a9fc3..dc580ea 100644
--- a/test/headers/test_headers.c
+++ b/test/headers/test_headers.c
@@ -12,6 +12,7 @@
#include "zix/ring.h" // IWYU pragma: keep
#include "zix/sem.h" // IWYU pragma: keep
#include "zix/status.h" // IWYU pragma: keep
+#include "zix/string_view.h" // IWYU pragma: keep
#include "zix/thread.h" // IWYU pragma: keep
#include "zix/tree.h" // IWYU pragma: keep
#include "zix/zix.h" // IWYU pragma: keep