diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/zix/allocator.h | 13 | ||||
-rw-r--r-- | include/zix/attributes.h | 16 | ||||
-rw-r--r-- | include/zix/btree.h | 58 | ||||
-rw-r--r-- | include/zix/bump_allocator.h | 7 | ||||
-rw-r--r-- | include/zix/digest.h | 20 | ||||
-rw-r--r-- | include/zix/environment.h | 39 | ||||
-rw-r--r-- | include/zix/filesystem.h | 82 | ||||
-rw-r--r-- | include/zix/hash.h | 72 | ||||
-rw-r--r-- | include/zix/path.h | 74 | ||||
-rw-r--r-- | include/zix/ring.h | 124 | ||||
-rw-r--r-- | include/zix/sem.h | 32 | ||||
-rw-r--r-- | include/zix/status.h | 5 | ||||
-rw-r--r-- | include/zix/string_view.h | 32 | ||||
-rw-r--r-- | include/zix/thread.h | 10 | ||||
-rw-r--r-- | include/zix/tree.h | 59 | ||||
-rw-r--r-- | include/zix/zix.h | 38 |
16 files changed, 344 insertions, 337 deletions
diff --git a/include/zix/allocator.h b/include/zix/allocator.h index 619697e..5e796ff 100644 --- a/include/zix/allocator.h +++ b/include/zix/allocator.h @@ -4,7 +4,7 @@ #ifndef ZIX_ALLOCATOR_H #define ZIX_ALLOCATOR_H -#include "zix/attributes.h" +#include <zix/attributes.h> #include <stddef.h> @@ -103,12 +103,11 @@ struct ZixAllocatorImpl { }; /// Return the default allocator which simply uses the system allocator -ZIX_CONST_API -ZixAllocator* ZIX_NONNULL +ZIX_CONST_API ZixAllocator* ZIX_NONNULL zix_default_allocator(void); /// Convenience wrapper that defers to malloc() if allocator is null -static inline void* ZIX_ALLOCATED +ZIX_MALLOC_FUNC static inline void* ZIX_ALLOCATED zix_malloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t size) { ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); @@ -117,7 +116,7 @@ zix_malloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t size) } /// Convenience wrapper that defers to calloc() if allocator is null -static inline void* ZIX_ALLOCATED +ZIX_MALLOC_FUNC static inline void* ZIX_ALLOCATED zix_calloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t nmemb, const size_t size) @@ -128,7 +127,7 @@ zix_calloc(ZixAllocator* const ZIX_NULLABLE allocator, } /// Convenience wrapper that defers to realloc() if allocator is null -static inline void* ZIX_ALLOCATED +ZIX_NODISCARD static inline void* ZIX_ALLOCATED zix_realloc(ZixAllocator* const ZIX_NULLABLE allocator, void* const ZIX_NULLABLE ptr, const size_t size) @@ -149,7 +148,7 @@ zix_free(ZixAllocator* const ZIX_NULLABLE allocator, } /// Convenience wrapper that defers to the system allocator if allocator is null -static inline void* ZIX_ALLOCATED +ZIX_MALLOC_FUNC static inline void* ZIX_ALLOCATED zix_aligned_alloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t alignment, const size_t size) diff --git a/include/zix/attributes.h b/include/zix/attributes.h index 518e5fb..f92f2b0 100644 --- a/include/zix/attributes.h +++ b/include/zix/attributes.h @@ -38,27 +38,23 @@ # define ZIX_PURE_FUNC __attribute__((pure)) # define ZIX_CONST_FUNC __attribute__((const)) # define ZIX_MALLOC_FUNC __attribute__((malloc)) +# define ZIX_NODISCARD __attribute__((warn_unused_result)) #else # 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 +# define ZIX_MALLOC_FUNC ///< Allocates memory with no pointers in it +# define ZIX_NODISCARD ///< Returns a value that must be used #endif /// A pure function in the public API that only reads memory -#define ZIX_PURE_API \ - ZIX_API \ - ZIX_PURE_FUNC +#define ZIX_PURE_API ZIX_API ZIX_PURE_FUNC ZIX_NODISCARD /// A const function in the public API that is pure and only reads parameters -#define ZIX_CONST_API \ - ZIX_API \ - ZIX_CONST_FUNC +#define ZIX_CONST_API ZIX_API ZIX_CONST_FUNC ZIX_NODISCARD /// A malloc function in the public API that returns allocated memory -#define ZIX_MALLOC_API \ - ZIX_API \ - ZIX_MALLOC_FUNC +#define ZIX_MALLOC_API ZIX_API ZIX_MALLOC_FUNC ZIX_NODISCARD // Printf-like format functions #ifdef __GNUC__ diff --git a/include/zix/btree.h b/include/zix/btree.h index 3161817..859e092 100644 --- a/include/zix/btree.h +++ b/include/zix/btree.h @@ -4,9 +4,9 @@ #ifndef ZIX_BTREE_H #define ZIX_BTREE_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/status.h> #include <stdbool.h> #include <stddef.h> @@ -21,7 +21,7 @@ ZIX_BEGIN_DECLS */ /** - @defgroup zix_btree_setup Setup + @defgroup zix_btree_types Types @{ */ @@ -51,6 +51,12 @@ typedef void (*ZixBTreeDestroyFunc)(void* ZIX_UNSPECIFIED ptr, const void* ZIX_UNSPECIFIED user_data); /** + @} + @defgroup zix_btree_setup Setup + @{ +*/ + +/** Create a new (empty) B-Tree. The given comparator must be a total ordering and is used to internally @@ -59,8 +65,7 @@ typedef void (*ZixBTreeDestroyFunc)(void* ZIX_UNSPECIFIED ptr, Searching can be done with a custom comparator that supports wildcards, see zix_btree_lower_bound() for details. */ -ZIX_API -ZixBTree* ZIX_ALLOCATED +ZIX_API ZIX_NODISCARD ZixBTree* ZIX_ALLOCATED zix_btree_new(ZixAllocator* ZIX_NULLABLE allocator, ZixBTreeCompareFunc ZIX_NONNULL cmp, const void* ZIX_UNSPECIFIED cmp_data); @@ -75,8 +80,7 @@ zix_btree_new(ZixAllocator* ZIX_NULLABLE allocator, @param destroy_data Opaque user data pointer to pass to `destroy`. */ -ZIX_API -void +ZIX_API void zix_btree_free(ZixBTree* ZIX_NULLABLE t, ZixBTreeDestroyFunc ZIX_NULLABLE destroy, const void* ZIX_NULLABLE destroy_data); @@ -91,15 +95,13 @@ zix_btree_free(ZixBTree* ZIX_NULLABLE t, @param destroy_data Opaque user data pointer to pass to `destroy`. */ -ZIX_API -void +ZIX_API void zix_btree_clear(ZixBTree* ZIX_NONNULL t, ZixBTreeDestroyFunc ZIX_NULLABLE destroy, const void* ZIX_NULLABLE destroy_data); /// Return the number of elements in `t` -ZIX_PURE_API -size_t +ZIX_PURE_API size_t zix_btree_size(const ZixBTree* ZIX_NONNULL t); /** @@ -134,40 +136,34 @@ static const ZixBTreeIter zix_btree_end_iter = { }; /// Return the data at the given position in the tree -ZIX_PURE_API -void* ZIX_UNSPECIFIED +ZIX_PURE_API void* ZIX_UNSPECIFIED zix_btree_get(ZixBTreeIter ti); /// Return an iterator to the first (smallest) element in `t` -ZIX_PURE_API -ZixBTreeIter +ZIX_PURE_API ZixBTreeIter zix_btree_begin(const ZixBTree* ZIX_NONNULL t); /// Return an iterator to the end of `t` (one past the last element) -ZIX_CONST_API -ZixBTreeIter +ZIX_CONST_API ZixBTreeIter zix_btree_end(const ZixBTree* ZIX_NULLABLE t); /// Return true iff `lhs` is equal to `rhs` -ZIX_CONST_API -bool +ZIX_CONST_API bool zix_btree_iter_equals(ZixBTreeIter lhs, ZixBTreeIter rhs); /// Return true iff `i` is an iterator at the end of a tree -static inline bool +ZIX_NODISCARD static inline bool zix_btree_iter_is_end(const ZixBTreeIter i) { return i.level == 0 && !i.nodes[0]; } /// Increment `i` to point to the next element in the tree -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_btree_iter_increment(ZixBTreeIter* ZIX_NONNULL i); /// Return an iterator one past `iter` -ZIX_API -ZixBTreeIter +ZIX_API ZIX_NODISCARD ZixBTreeIter zix_btree_iter_next(ZixBTreeIter iter); /** @@ -182,8 +178,7 @@ zix_btree_iter_next(ZixBTreeIter iter); @return #ZIX_STATUS_SUCCESS on success, #ZIX_STATUS_EXISTS, or #ZIX_STATUS_NO_MEM. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_btree_insert(ZixBTree* ZIX_NONNULL t, void* ZIX_UNSPECIFIED e); /** @@ -200,8 +195,7 @@ zix_btree_insert(ZixBTree* ZIX_NONNULL t, void* ZIX_UNSPECIFIED e); @return #ZIX_STATUS_SUCCESS on success, or #ZIX_STATUS_NOT_FOUND. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_btree_remove(ZixBTree* ZIX_NONNULL t, const void* ZIX_UNSPECIFIED e, void* ZIX_UNSPECIFIED* ZIX_NONNULL out, @@ -220,8 +214,7 @@ zix_btree_remove(ZixBTree* ZIX_NONNULL t, @return #ZIX_STATUS_SUCCESS on success, or #ZIX_STATUS_NOT_FOUND. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_btree_find(const ZixBTree* ZIX_NONNULL t, const void* ZIX_UNSPECIFIED e, ZixBTreeIter* ZIX_NONNULL ti); @@ -242,8 +235,7 @@ zix_btree_find(const ZixBTree* ZIX_NONNULL t, @return #ZIX_STATUS_SUCCESS. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_btree_lower_bound(const ZixBTree* ZIX_NONNULL t, ZixBTreeCompareFunc ZIX_NULLABLE compare_key, const void* ZIX_NULLABLE compare_key_data, diff --git a/include/zix/bump_allocator.h b/include/zix/bump_allocator.h index c69de92..b5fdd7e 100644 --- a/include/zix/bump_allocator.h +++ b/include/zix/bump_allocator.h @@ -4,8 +4,8 @@ #ifndef ZIX_BUMP_ALLOCATOR_H #define ZIX_BUMP_ALLOCATOR_H -#include "zix/allocator.h" -#include "zix/attributes.h" +#include <zix/allocator.h> +#include <zix/attributes.h> #include <stddef.h> @@ -52,8 +52,7 @@ typedef struct { } ZixBumpAllocator; /// Return a bump allocator that works within a provided buffer -ZIX_API -ZixBumpAllocator +ZIX_API ZixBumpAllocator zix_bump_allocator(size_t capacity, void* ZIX_NONNULL buffer); /** diff --git a/include/zix/digest.h b/include/zix/digest.h index deffaf0..82f5b28 100644 --- a/include/zix/digest.h +++ b/include/zix/digest.h @@ -4,7 +4,7 @@ #ifndef ZIX_DIGEST_H #define ZIX_DIGEST_H -#include "zix/attributes.h" +#include <zix/attributes.h> #include <stddef.h> #include <stdint.h> @@ -29,8 +29,7 @@ ZIX_BEGIN_DECLS This can be used for any size or alignment. */ -ZIX_PURE_API -uint32_t +ZIX_PURE_API uint32_t zix_digest32(uint32_t seed, const void* ZIX_NONNULL buf, size_t len); /** @@ -39,8 +38,7 @@ zix_digest32(uint32_t seed, const void* ZIX_NONNULL buf, size_t len); Both the buffer and size must be aligned to 32 bits. For data that fits these requirements, this is equivalent to, but faster than, zix_digest32(). */ -ZIX_PURE_API -uint32_t +ZIX_PURE_API uint32_t zix_digest32_aligned(uint32_t seed, const void* ZIX_NONNULL buf, size_t len); /** @@ -48,8 +46,7 @@ zix_digest32_aligned(uint32_t seed, const void* ZIX_NONNULL buf, size_t len); This can be used for any size or alignment. */ -ZIX_PURE_API -uint64_t +ZIX_PURE_API uint64_t zix_digest64(uint64_t seed, const void* ZIX_NONNULL buf, size_t len); /** @@ -58,8 +55,7 @@ zix_digest64(uint64_t seed, const void* ZIX_NONNULL buf, size_t len); Both the buffer and size must be aligned to 64 bits. For data that fits these requirements, this is equivalent to, but faster than, zix_digest64(). */ -ZIX_PURE_API -uint64_t +ZIX_PURE_API uint64_t zix_digest64_aligned(uint64_t seed, const void* ZIX_NONNULL buf, size_t len); /** @@ -70,8 +66,7 @@ zix_digest64_aligned(uint64_t seed, const void* ZIX_NONNULL buf, size_t len); Internally, this simply dispatches to zix_digest32() or zix_digest64() as appropriate. */ -ZIX_PURE_API -size_t +ZIX_PURE_API size_t zix_digest(size_t seed, const void* ZIX_NONNULL buf, size_t len); /** @@ -84,8 +79,7 @@ zix_digest(size_t seed, const void* ZIX_NONNULL buf, size_t len); Internally, this simply dispatches to zix_digest32_aligned() or zix_digest64_aligned() as appropriate. */ -ZIX_PURE_API -size_t +ZIX_PURE_API size_t zix_digest_aligned(size_t seed, const void* ZIX_NONNULL buf, size_t len); /** diff --git a/include/zix/environment.h b/include/zix/environment.h new file mode 100644 index 0000000..095d421 --- /dev/null +++ b/include/zix/environment.h @@ -0,0 +1,39 @@ +// Copyright 2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef ZIX_ENVIRONMENT_H +#define ZIX_ENVIRONMENT_H + +#include <zix/allocator.h> +#include <zix/attributes.h> + +ZIX_BEGIN_DECLS + +/** + @defgroup zix_expand Variable Expansion + @ingroup zix_environment + @{ +*/ + +/** + Expand shell-style variables in a string. + + On Windows, this expands environment variable references like + "%USERPROFILE%". On POSIX systems, it expands environment variable + references like "$HOME", and the special path component "~". + + @param allocator Allocator used for returned string. + @param string Input string to expand. + @return A newly allocated copy of `string` with variables expanded, or null. +*/ +ZIX_MALLOC_API char* ZIX_ALLOCATED +zix_expand_environment_strings(ZixAllocator* ZIX_NULLABLE allocator, + const char* ZIX_NONNULL string); + +/** + @} +*/ + +ZIX_END_DECLS + +#endif /* ZIX_ENVIRONMENT_H */ diff --git a/include/zix/filesystem.h b/include/zix/filesystem.h index 9abafe1..dff4145 100644 --- a/include/zix/filesystem.h +++ b/include/zix/filesystem.h @@ -4,9 +4,9 @@ #ifndef ZIX_FILESYSTEM_H #define ZIX_FILESYSTEM_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/status.h> #if !(defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) # include <stddef.h> @@ -51,8 +51,7 @@ typedef uint32_t ZixCopyOptions; @param options Options to control the kind of copy and error conditions. @return #ZIX_STATUS_SUCCESS if `dst` was successfully created, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_copy_file(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL src, const char* ZIX_NONNULL dst, @@ -64,8 +63,7 @@ zix_copy_file(ZixAllocator* ZIX_NULLABLE allocator, @return #ZIX_STATUS_SUCCESS if `dir_path` was successfully created, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_directory(const char* ZIX_NONNULL dir_path); /** @@ -77,8 +75,7 @@ zix_create_directory(const char* ZIX_NONNULL dir_path); @return #ZIX_STATUS_SUCCESS if `dir_path` was successfully created, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_directory_like(const char* ZIX_NONNULL dir_path, const char* ZIX_NONNULL existing_path); @@ -92,8 +89,7 @@ zix_create_directory_like(const char* ZIX_NONNULL dir_path, @return #ZIX_STATUS_SUCCESS if all directories in `dir_path` were successfully created (or already existed), or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_directories(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL dir_path); @@ -102,8 +98,7 @@ zix_create_directories(ZixAllocator* ZIX_NULLABLE allocator, @return #ZIX_STATUS_SUCCESS, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_hard_link(const char* ZIX_NONNULL target_path, const char* ZIX_NONNULL link_path); @@ -116,8 +111,7 @@ zix_create_hard_link(const char* ZIX_NONNULL target_path, @return #ZIX_STATUS_SUCCESS, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_symlink(const char* ZIX_NONNULL target_path, const char* ZIX_NONNULL link_path); @@ -129,8 +123,7 @@ zix_create_symlink(const char* ZIX_NONNULL target_path, @return #ZIX_STATUS_SUCCESS, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_create_directory_symlink(const char* ZIX_NONNULL target_path, const char* ZIX_NONNULL link_path); @@ -146,14 +139,12 @@ zix_create_directory_symlink(const char* ZIX_NONNULL target_path, @return The path of the created directory, or null. */ -ZIX_API -char* ZIX_NULLABLE +ZIX_MALLOC_API char* ZIX_NULLABLE zix_create_temporary_directory(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL path_pattern); /// Remove the file or empty directory at `path` -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_remove(const char* ZIX_NONNULL path); /** @@ -163,6 +154,17 @@ zix_remove(const char* ZIX_NONNULL path); */ /** + Function for reading input bytes from a stream. + + @param path Path to the directory being visited. + @param name Name of the directory entry. + @param data Opaque user data. +*/ +typedef void (*ZixDirEntryVisitFunc)(const char* ZIX_NONNULL path, + const char* ZIX_NONNULL name, + void* ZIX_NONNULL data); + +/** Visit every file in the directory at `path`. @param path A path to a directory. @@ -173,13 +175,10 @@ zix_remove(const char* ZIX_NONNULL path); parameter is always the directory path passed to this function, the `name` parameter is the name of the directory entry (not its full path). */ -ZIX_API -void -zix_dir_for_each(const char* ZIX_NONNULL path, - void* ZIX_NULLABLE data, - void (*ZIX_NONNULL f)(const char* ZIX_NONNULL path, - const char* ZIX_NONNULL name, - void* ZIX_NONNULL data)); +ZIX_API void +zix_dir_for_each(const char* ZIX_NONNULL path, + void* ZIX_NULLABLE data, + ZixDirEntryVisitFunc ZIX_NONNULL f); /** Return whether the given paths point to files with identical contents. @@ -193,8 +192,7 @@ zix_dir_for_each(const char* ZIX_NONNULL path, @return True if the two files have byte-for-byte identical contents. */ -ZIX_API -bool +ZIX_API ZIX_NODISCARD bool zix_file_equals(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL a_path, const char* ZIX_NONNULL b_path); @@ -227,8 +225,7 @@ zix_file_equals(ZixAllocator* ZIX_NULLABLE allocator, @return A new canonical version of `path`, or null if it doesn't exist. */ -ZIX_API -char* ZIX_NULLABLE +ZIX_MALLOC_API char* ZIX_NULLABLE zix_canonical_path(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NULLABLE path); @@ -255,8 +252,7 @@ typedef enum { @param mode Lock mode. @return #ZIX_STATUS_SUCCESS if the file was locked, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_file_lock(FILE* ZIX_NONNULL file, ZixFileLockMode mode); /** @@ -266,8 +262,7 @@ zix_file_lock(FILE* ZIX_NONNULL file, ZixFileLockMode mode); @param mode Lock mode. @return #ZIX_STATUS_SUCCESS if the file was unlocked, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_file_unlock(FILE* ZIX_NONNULL file, ZixFileLockMode mode); /** @@ -308,8 +303,7 @@ typedef enum { /** Return the type of a file or directory, resolving symlinks. */ -ZIX_API -ZixFileType +ZIX_API ZixFileType zix_file_type(const char* ZIX_NONNULL path); /** @@ -318,8 +312,7 @@ zix_file_type(const char* ZIX_NONNULL path); On Windows, a directory symlink (actually a "reparse point") always appears as a directory. */ -ZIX_API -ZixFileType +ZIX_API ZixFileType zix_symlink_type(const char* ZIX_NONNULL path); /** @@ -331,8 +324,7 @@ zix_symlink_type(const char* ZIX_NONNULL path); @return A non-negative size in bytes, or -1 on error. */ -ZIX_API -ZixFileOffset +ZIX_API ZixFileOffset zix_file_size(const char* ZIX_NONNULL path); /** @@ -346,8 +338,7 @@ zix_file_size(const char* ZIX_NONNULL path); @param allocator Allocator used for the returned path. */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API char* ZIX_ALLOCATED zix_current_path(ZixAllocator* ZIX_NULLABLE allocator); /** @@ -357,8 +348,7 @@ zix_current_path(ZixAllocator* ZIX_NULLABLE allocator); @return A new path to a temporary directory, or null on error. */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API char* ZIX_ALLOCATED zix_temp_directory_path(ZixAllocator* ZIX_NULLABLE allocator); /** diff --git a/include/zix/hash.h b/include/zix/hash.h index e425b9f..3222e58 100644 --- a/include/zix/hash.h +++ b/include/zix/hash.h @@ -4,9 +4,9 @@ #ifndef ZIX_HASH_H #define ZIX_HASH_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/status.h> #include <stdbool.h> #include <stddef.h> @@ -20,7 +20,7 @@ ZIX_BEGIN_DECLS */ /** - @defgroup zix_hash_datatypes Datatypes + @defgroup zix_hash_types Types @{ */ @@ -28,14 +28,14 @@ ZIX_BEGIN_DECLS #if defined(ZIX_HASH_KEY_TYPE) typedef ZIX_HASH_KEY_TYPE ZixHashKey; #else -typedef void ZixHashKey; ///< The type of a key within a record +typedef void ZixHashKey; ///< The type of a key within a record #endif // ZIX_HASH_RECORD_TYPE can be defined to make the API more type-safe #if defined(ZIX_HASH_RECORD_TYPE) typedef ZIX_HASH_RECORD_TYPE ZixHashRecord; #else -typedef void ZixHashRecord; ///< The type of a hash table record +typedef void ZixHashRecord; ///< The type of a hash table record #endif // ZIX_HASH_SEARCH_DATA_TYPE can be defined to make the API more type-safe @@ -77,12 +77,6 @@ typedef struct ZixHashImpl ZixHash; /// A full hash code for a key which is not folded down to the table size typedef size_t ZixHashCode; -/** - @} - @defgroup zix_hash_setup Setup - @{ -*/ - /// User function for getting the key of a record typedef const ZixHashKey* ZIX_NONNULL (*ZixKeyFunc)( const ZixHashRecord* ZIX_NONNULL record); @@ -95,6 +89,12 @@ typedef bool (*ZixKeyEqualFunc)(const ZixHashKey* ZIX_NONNULL a, const ZixHashKey* ZIX_NONNULL b); /** + @} + @defgroup zix_hash_setup Setup + @{ +*/ + +/** Create a new hash table. @param allocator Allocator used for the internal array. @@ -102,21 +102,18 @@ typedef bool (*ZixKeyEqualFunc)(const ZixHashKey* ZIX_NONNULL a, @param hash_func The key hashing function. @param equal_func A function to test keys for equality. */ -ZIX_API -ZixHash* ZIX_ALLOCATED +ZIX_API ZIX_NODISCARD ZixHash* ZIX_ALLOCATED zix_hash_new(ZixAllocator* ZIX_NULLABLE allocator, ZixKeyFunc ZIX_NONNULL key_func, ZixHashFunc ZIX_NONNULL hash_func, ZixKeyEqualFunc ZIX_NONNULL equal_func); /// Free `hash` -ZIX_API -void +ZIX_API void zix_hash_free(ZixHash* ZIX_NULLABLE hash); /// Return the number of elements in the hash -ZIX_PURE_API -size_t +ZIX_PURE_API size_t zix_hash_size(const ZixHash* ZIX_NONNULL hash); /** @@ -134,23 +131,19 @@ zix_hash_size(const ZixHash* ZIX_NONNULL hash); typedef size_t ZixHashIter; /// Return an iterator to the first record in a hash, or the end if it is empty -ZIX_PURE_API -ZixHashIter +ZIX_PURE_API ZixHashIter zix_hash_begin(const ZixHash* ZIX_NONNULL hash); /// Return an iterator one past the last possible record in a hash -ZIX_PURE_API -ZixHashIter +ZIX_PURE_API ZixHashIter zix_hash_end(const ZixHash* ZIX_NONNULL hash); /// Return the record pointed to by an iterator -ZIX_PURE_API -ZixHashRecord* ZIX_NULLABLE +ZIX_PURE_API ZixHashRecord* ZIX_NULLABLE zix_hash_get(const ZixHash* ZIX_NONNULL hash, ZixHashIter i); /// Return an iterator that has been advanced to the next record in a hash -ZIX_PURE_API -ZixHashIter +ZIX_PURE_API ZixHashIter zix_hash_next(const ZixHash* ZIX_NONNULL hash, ZixHashIter i); /** @@ -188,8 +181,7 @@ typedef struct { record with this key using zix_hash_insert_at() until the hash table is modified (which invalidates the position). */ -ZIX_API -ZixHashInsertPlan +ZIX_API ZixHashInsertPlan zix_hash_plan_insert(const ZixHash* ZIX_NONNULL hash, const ZixHashKey* ZIX_NONNULL key); @@ -213,8 +205,7 @@ zix_hash_plan_insert(const ZixHash* ZIX_NONNULL hash, be inserted, and the predicate must return true only if the key it is called with (the first argument) matches the key to be inserted. */ -ZIX_API -ZixHashInsertPlan +ZIX_API ZixHashInsertPlan zix_hash_plan_insert_prehashed(const ZixHash* ZIX_NONNULL hash, ZixHashCode code, ZixKeyMatchFunc ZIX_NONNULL predicate, @@ -227,8 +218,7 @@ zix_hash_plan_insert_prehashed(const ZixHash* ZIX_NONNULL hash, can be used to insert a new record, or to access the existing matching record. */ -ZIX_PURE_API -ZixHashRecord* ZIX_NULLABLE +ZIX_PURE_API ZixHashRecord* ZIX_NULLABLE zix_hash_record_at(const ZixHash* ZIX_NONNULL hash, ZixHashInsertPlan position); /** @@ -248,8 +238,7 @@ zix_hash_record_at(const ZixHash* ZIX_NONNULL hash, ZixHashInsertPlan position); @return ZIX_STATUS_SUCCESS, ZIX_STATUS_EXISTS if a record already exists at this position, or ZIX_STATUS_NO_MEM if growing the hash table failed. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_hash_insert_at(ZixHash* ZIX_NONNULL hash, ZixHashInsertPlan position, ZixHashRecord* ZIX_NONNULL record); @@ -268,8 +257,7 @@ zix_hash_insert_at(ZixHash* ZIX_NONNULL hash, @return ZIX_STATUS_SUCCESS, ZIX_STATUS_EXISTS, or ZIX_STATUS_NO_MEM. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_hash_insert(ZixHash* ZIX_NONNULL hash, ZixHashRecord* ZIX_NONNULL record); /** @@ -286,8 +274,7 @@ zix_hash_insert(ZixHash* ZIX_NONNULL hash, ZixHashRecord* ZIX_NONNULL record); @return ZIX_STATUS_SUCCES or ZIX_STATUS_BAD_ARG if `i` does not point at a removable record. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_hash_erase(ZixHash* ZIX_NONNULL hash, ZixHashIter i, ZixHashRecord* ZIX_NULLABLE* ZIX_NONNULL removed); @@ -300,8 +287,7 @@ zix_hash_erase(ZixHash* ZIX_NONNULL hash, @param removed Set to the removed record, or null. @return ZIX_STATUS_SUCCES or ZIX_STATUS_NOT_FOUND. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_hash_remove(ZixHash* ZIX_NONNULL hash, const ZixHashKey* ZIX_NONNULL key, ZixHashRecord* ZIX_NULLABLE* ZIX_NONNULL removed); @@ -322,8 +308,7 @@ zix_hash_remove(ZixHash* ZIX_NONNULL hash, @return An iterator to the matching record, or the end iterator if no such record exists. */ -ZIX_API -ZixHashIter +ZIX_API ZixHashIter zix_hash_find(const ZixHash* ZIX_NONNULL hash, const ZixHashKey* ZIX_NONNULL key); @@ -339,8 +324,7 @@ zix_hash_find(const ZixHash* ZIX_NONNULL hash, @return A pointer to the matching record, of null if no such record exists. */ -ZIX_API -ZixHashRecord* ZIX_NULLABLE +ZIX_API ZixHashRecord* ZIX_NULLABLE zix_hash_find_record(const ZixHash* ZIX_NONNULL hash, const ZixHashKey* ZIX_NONNULL key); diff --git a/include/zix/path.h b/include/zix/path.h index 13225e6..ba23b10 100644 --- a/include/zix/path.h +++ b/include/zix/path.h @@ -4,9 +4,9 @@ #ifndef ZIX_PATH_H #define ZIX_PATH_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/string_view.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/string_view.h> #include <stdbool.h> @@ -35,8 +35,7 @@ ZIX_BEGIN_DECLS */ /// Join path `a` and path `b` with a single directory separator between them -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API ZIX_NODISCARD char* ZIX_ALLOCATED zix_path_join(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NULLABLE a, const char* ZIX_NULLABLE b); @@ -54,8 +53,7 @@ zix_path_join(ZixAllocator* ZIX_NULLABLE allocator, converted to the preferred separator (backslash on Windows, slash everywhere else). */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API ZIX_NODISCARD char* ZIX_ALLOCATED zix_path_preferred(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL path); @@ -64,14 +62,13 @@ zix_path_preferred(ZixAllocator* ZIX_NULLABLE allocator, Paths in normal form have all dot segments removed and use only a single preferred separator for all separators (that is, any number of separators is - replaced with a single "\" on Windows, and a single "/" everwhere else). + replaced with a single "\" on Windows, and a single "/" everywhere else). Note that this function doesn't access the filesystem, so won't do anything like case normalization or symbolic link dereferencing. For that, use zix_canonical_path(). */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API ZIX_NODISCARD char* ZIX_ALLOCATED zix_path_lexically_normal(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL path); @@ -82,8 +79,7 @@ zix_path_lexically_normal(ZixAllocator* ZIX_NULLABLE allocator, equivalent path relative to `base` is returned (which may contain up-references). */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API ZIX_NODISCARD char* ZIX_ALLOCATED zix_path_lexically_relative(ZixAllocator* ZIX_NULLABLE allocator, const char* ZIX_NONNULL path, const char* ZIX_NONNULL base); @@ -95,13 +91,11 @@ zix_path_lexically_relative(ZixAllocator* ZIX_NULLABLE allocator, */ /// Return the root name of `path` like "C:", or null -ZIX_PURE_WIN_API -ZixStringView +ZIX_PURE_WIN_API ZixStringView zix_path_root_name(const char* ZIX_NONNULL path); /// Return the root directory of `path` like "/" or "\", or null -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_root_directory(const char* ZIX_NONNULL path); /** @@ -117,8 +111,7 @@ zix_path_root_directory(const char* ZIX_NONNULL path); @return The newly allocated root path of `path`, or null if it has no root or allocation failed. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_root_path(const char* ZIX_NONNULL path); /** @@ -127,8 +120,7 @@ zix_path_root_path(const char* ZIX_NONNULL path); If the path has no relative path (because it is empty or a root path), this returns null. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_relative_path(const char* ZIX_NONNULL path); /** @@ -147,8 +139,7 @@ zix_path_relative_path(const char* ZIX_NONNULL path); @return The newly allocated path to the parent of `path`, or null if it has no parent or allocation failed. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_parent_path(const char* ZIX_NONNULL path); /** @@ -157,8 +148,7 @@ zix_path_parent_path(const char* ZIX_NONNULL path); The filename is the name after the last directory separator. If the path has no filename, this returns null. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_filename(const char* ZIX_NONNULL path); /** @@ -167,8 +157,7 @@ zix_path_filename(const char* ZIX_NONNULL path); The "stem" is the filename without the extension, that is, everything up to the last "." if "." is not the first character. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_stem(const char* ZIX_NONNULL path); /** @@ -177,8 +166,7 @@ zix_path_stem(const char* ZIX_NONNULL path); The "extension" is everything past the last "." in the filename, if "." is not the first character. */ -ZIX_PURE_API -ZixStringView +ZIX_PURE_API ZixStringView zix_path_extension(const char* ZIX_NONNULL path); /** @@ -188,53 +176,43 @@ zix_path_extension(const char* ZIX_NONNULL path); */ /// Return true if `path` has a root path like "/" or "C:\" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_root_path(const char* ZIX_NULLABLE path); /// Return true if `path` has a root name like "C:" -ZIX_PURE_WIN_API -bool +ZIX_PURE_WIN_API bool zix_path_has_root_name(const char* ZIX_NULLABLE path); /// Return true if `path` has a root directory like "/" or "\" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_root_directory(const char* ZIX_NULLABLE path); /// Return true if `path` has a relative path "dir/file.txt" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_relative_path(const char* ZIX_NULLABLE path); /// Return true if `path` has a parent path like "dir/" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_parent_path(const char* ZIX_NULLABLE path); /// Return true if `path` has a filename like "file.txt" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_filename(const char* ZIX_NULLABLE path); /// Return true if `path` has a stem like "file" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_stem(const char* ZIX_NULLABLE path); /// Return true if `path` has an extension like ".txt" -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_has_extension(const char* ZIX_NULLABLE path); /// Return true if `path` is an absolute path -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_is_absolute(const char* ZIX_NULLABLE path); /// Return true if `path` is a relative path -ZIX_PURE_API -bool +ZIX_PURE_API bool zix_path_is_relative(const char* ZIX_NULLABLE path); /** diff --git a/include/zix/ring.h b/include/zix/ring.h index 61c99be..4431658 100644 --- a/include/zix/ring.h +++ b/include/zix/ring.h @@ -4,9 +4,9 @@ #ifndef ZIX_RING_H #define ZIX_RING_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/status.h> #include <stdint.h> @@ -19,7 +19,7 @@ ZIX_BEGIN_DECLS */ /** - @defgroup zix_ring_setup Setup + @defgroup zix_ring_types Types @{ */ @@ -32,21 +32,30 @@ ZIX_BEGIN_DECLS typedef struct ZixRingImpl ZixRing; /** + @} + @defgroup zix_ring_setup Setup + @{ +*/ + +/** Create a new ring. @param allocator Allocator for the ring object and its array. - @param size Size of the ring in bytes (note this may be rounded up). + @param size Minimum size of the ring in bytes (rounded up to a power of 2). - At most `size` - 1 bytes may be stored in the ring at once. + Note that one byte of the ring is reserved, so in order to be able to write + `n` bytes to the ring at once, `size` must be `n + 1`. */ -ZIX_MALLOC_API -ZixRing* ZIX_ALLOCATED +ZIX_API ZIX_NODISCARD ZixRing* ZIX_ALLOCATED zix_ring_new(ZixAllocator* ZIX_NULLABLE allocator, uint32_t size); -/// Destroy a ring -ZIX_API -void +/** + Destroy a ring. + + This frees the ring structure and its buffer, discarding its contents. +*/ +ZIX_API void zix_ring_free(ZixRing* ZIX_NULLABLE ring); /** @@ -56,8 +65,7 @@ zix_ring_free(ZixRing* ZIX_NULLABLE ring); after zix_ring_new() to lock all ring memory to avoid page faults while using the ring. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_ring_mlock(ZixRing* ZIX_NONNULL ring); /** @@ -66,8 +74,7 @@ zix_ring_mlock(ZixRing* ZIX_NONNULL ring); This function is NOT thread-safe, it may only be called when there is no reader or writer. */ -ZIX_API -void +ZIX_API void zix_ring_reset(ZixRing* ZIX_NONNULL ring); /** @@ -76,8 +83,7 @@ zix_ring_reset(ZixRing* ZIX_NONNULL ring); This function returns a constant for any given ring, and may (but usually shouldn't) be called anywhere. */ -ZIX_PURE_API -uint32_t +ZIX_PURE_API uint32_t zix_ring_capacity(const ZixRing* ZIX_NONNULL ring); /** @@ -87,24 +93,47 @@ zix_ring_capacity(const ZixRing* ZIX_NONNULL ring); @{ */ -/// Return the number of bytes available for reading -ZIX_PURE_API -uint32_t +/** + Return the number of bytes available for reading. + + This function returns at most one less than the ring's buffer size. +*/ +ZIX_PURE_API uint32_t zix_ring_read_space(const ZixRing* ZIX_NONNULL ring); -/// Read from the ring without advancing the read head -ZIX_API -uint32_t +/** + Read from the ring without advancing the read head. + + @param ring The ring to read data from. + @param dst The buffer to write data to. + @param size The number of bytes to read from `ring` and write to `dst`. + + @return The number of bytes read, which is either `size` on success, or zero + on failure. +*/ +ZIX_API uint32_t zix_ring_peek(ZixRing* ZIX_NONNULL ring, void* ZIX_NONNULL dst, uint32_t size); -/// Read from the ring and advance the read head -ZIX_API -uint32_t +/** + Read from the ring and advance the read head. + + @param ring The ring to read data from. + @param dst The buffer to write data to. + @param size The number of bytes to read from `ring` and write to `dst`. + + @return The number of bytes read, which is either `size` on success, or zero + on failure. +*/ +ZIX_API uint32_t zix_ring_read(ZixRing* ZIX_NONNULL ring, void* ZIX_NONNULL dst, uint32_t size); -/// Advance the read head, ignoring any data -ZIX_API -uint32_t +/** + Advance the read head, ignoring any data. + + @return Either `size` on success, or zero if there aren't enough bytes to + skip. +*/ +ZIX_API uint32_t zix_ring_skip(ZixRing* ZIX_NONNULL ring, uint32_t size); /** @@ -122,20 +151,36 @@ zix_ring_skip(ZixRing* ZIX_NONNULL ring, uint32_t size); written in several chunks before being "committed" and becoming readable. This can be useful for things like prefixing messages with a header without needing an allocated buffer to construct the "packet". + + The contents of this structure are an implementation detail and must not be + manipulated by the user. */ typedef struct { uint32_t read_head; ///< Read head at the start of the transaction uint32_t write_head; ///< Write head if the transaction were committed } ZixRingTransaction; -/// Return the number of bytes available for writing -ZIX_PURE_API -uint32_t +/** + Return the number of bytes available for writing. + + This function returns at most one less than the ring's buffer size. +*/ +ZIX_PURE_API uint32_t zix_ring_write_space(const ZixRing* ZIX_NONNULL ring); -/// Write data to the ring -ZIX_API -uint32_t +/** + Write data to the ring. + + This writes a contiguous input buffer of bytes to the ring. + + @param ring The ring to write data to. + @param src The buffer to read data from. + @param size The number of bytes to read from `src` and write to `ring`. + + @return The number of bytes written, which is either `size` on success, or + zero on failure. +*/ +ZIX_API uint32_t zix_ring_write(ZixRing* ZIX_NONNULL ring, const void* ZIX_NONNULL src, uint32_t size); @@ -154,8 +199,7 @@ zix_ring_write(ZixRing* ZIX_NONNULL ring, @param ring The ring to write data to. @return A new empty transaction. */ -ZIX_API -ZixRingTransaction +ZIX_API ZIX_NODISCARD ZixRingTransaction zix_ring_begin_write(ZixRing* ZIX_NONNULL ring); /** @@ -176,8 +220,7 @@ zix_ring_begin_write(ZixRing* ZIX_NONNULL ring); @param size Length of data to write in bytes. @return #ZIX_STATUS_NO_MEM or #ZIX_STATUS_SUCCESS. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_ring_amend_write(ZixRing* ZIX_NONNULL ring, ZixRingTransaction* ZIX_NONNULL tx, const void* ZIX_NONNULL src, @@ -196,8 +239,7 @@ zix_ring_amend_write(ZixRing* ZIX_NONNULL ring, @param tx The active transaction, from zix_ring_begin_write(). @return #ZIX_STATUS_SUCCESS. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_ring_commit_write(ZixRing* ZIX_NONNULL ring, const ZixRingTransaction* ZIX_NONNULL tx); diff --git a/include/zix/sem.h b/include/zix/sem.h index 8aa205e..49ab5f8 100644 --- a/include/zix/sem.h +++ b/include/zix/sem.h @@ -4,8 +4,8 @@ #ifndef ZIX_SEM_H #define ZIX_SEM_H -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/attributes.h> +#include <zix/status.h> #ifdef __APPLE__ # include <mach/mach.h> @@ -15,10 +15,10 @@ # include <semaphore.h> #endif -ZIX_BEGIN_DECLS - #include <stdint.h> +ZIX_BEGIN_DECLS + /** @defgroup zix_sem Semaphore @ingroup zix_threading @@ -30,14 +30,14 @@ ZIX_BEGIN_DECLS This is an integer that is never negative, and has two main operations: increment (post) and decrement (wait). If a decrement can't be performed - (because the value is 0) the caller will be blocked until another thread posts - and the operation can succeed. + (because the value is 0) the caller will be blocked until another thread + posts and the operation can succeed. Semaphores can be created with any starting value, but typically this will be 0 so the semaphore can be used as a simple signal where each post corresponds to one wait. - Semaphores are very efficient (much moreso than a mutex/cond pair). In + Semaphores are very efficient (compared to a mutex/cond pair). In particular, at least on Linux, post is async-signal-safe, which means it does not block and will not be interrupted. If you need to signal from a realtime thread, this is the most appropriate primitive to use. @@ -49,8 +49,7 @@ typedef struct ZixSemImpl ZixSem; @return #ZIX_STATUS_SUCCESS, or an unlikely error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned initial); /** @@ -58,8 +57,7 @@ zix_sem_init(ZixSem* ZIX_NONNULL sem, unsigned initial); @return #ZIX_STATUS_SUCCESS, or an error. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_destroy(ZixSem* ZIX_NONNULL sem); /** @@ -71,8 +69,7 @@ zix_sem_destroy(ZixSem* ZIX_NONNULL sem); if the maximum possible value would have been exceeded, or #ZIX_STATUS_BAD_ARG if `sem` is invalid. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_post(ZixSem* ZIX_NONNULL sem); /** @@ -83,8 +80,7 @@ zix_sem_post(ZixSem* ZIX_NONNULL sem); @return #ZIX_STATUS_SUCCESS if `sem` was decremented, or #ZIX_STATUS_BAD_ARG if `sem` is invalid. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_wait(ZixSem* ZIX_NONNULL sem); /** @@ -94,8 +90,7 @@ zix_sem_wait(ZixSem* ZIX_NONNULL sem); #ZIX_STATUS_UNAVAILABLE if it was already zero, or #ZIX_STATUS_BAD_ARG if `sem` is invalid. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_try_wait(ZixSem* ZIX_NONNULL sem); /** @@ -108,8 +103,7 @@ zix_sem_try_wait(ZixSem* ZIX_NONNULL sem); the system does not support timed waits, or #ZIX_STATUS_BAD_ARG if `sem` is invalid. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_sem_timed_wait(ZixSem* ZIX_NONNULL sem, uint32_t seconds, uint32_t nanoseconds); diff --git a/include/zix/status.h b/include/zix/status.h index 47aede8..d03160e 100644 --- a/include/zix/status.h +++ b/include/zix/status.h @@ -4,7 +4,7 @@ #ifndef ZIX_STATUS_H #define ZIX_STATUS_H -#include "zix/attributes.h" +#include <zix/attributes.h> ZIX_BEGIN_DECLS @@ -38,8 +38,7 @@ typedef enum { The returned string is always one sentence, with an uppercase first character, and no trailing period. */ -ZIX_CONST_API -const char* +ZIX_CONST_API const char* zix_strerror(ZixStatus status); /** diff --git a/include/zix/string_view.h b/include/zix/string_view.h index f13f8d1..be15018 100644 --- a/include/zix/string_view.h +++ b/include/zix/string_view.h @@ -1,12 +1,13 @@ -// Copyright 2011-2023 David Robillard <d@drobilla.net> +// Copyright 2011-2024 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 <zix/allocator.h> +#include <zix/attributes.h> +#include <stdbool.h> #include <stddef.h> #include <string.h> @@ -39,9 +40,7 @@ typedef struct { // clang-format on /// Return a view of an empty string -ZIX_ALWAYS_INLINE_FUNC -ZIX_CONST_FUNC -static inline ZixStringView +ZIX_ALWAYS_INLINE_FUNC ZIX_CONST_FUNC static inline ZixStringView zix_empty_string(void) { const ZixStringView view = {"", 0U}; @@ -61,9 +60,7 @@ zix_empty_string(void) @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_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}; @@ -77,9 +74,7 @@ zix_substring(const char* const ZIX_NONNULL str, const size_t len) @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_ALWAYS_INLINE_FUNC ZIX_PURE_FUNC static inline ZixStringView // NOLINTNEXTLINE(clang-diagnostic-unused-function) zix_string(const char* const ZIX_NULLABLE str) { @@ -89,11 +84,20 @@ zix_string(const char* const ZIX_NULLABLE str) /** Copy a string view into a newly allocated null-terminated string. */ -ZIX_API -char* ZIX_ALLOCATED +ZIX_MALLOC_API char* ZIX_ALLOCATED zix_string_view_copy(ZixAllocator* ZIX_NULLABLE allocator, ZixStringView view); /** + Return true if both string views refer to equal strings. + + This may be significantly faster than a full string comparison, because it + has fast paths for when the operands have different lengths, or point to the + same string data. +*/ +ZIX_PURE_API bool +zix_string_view_equals(ZixStringView lhs, ZixStringView rhs); + +/** @} */ diff --git a/include/zix/thread.h b/include/zix/thread.h index 2493ed3..77a6bf5 100644 --- a/include/zix/thread.h +++ b/include/zix/thread.h @@ -4,8 +4,8 @@ #ifndef ZIX_THREAD_H #define ZIX_THREAD_H -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/attributes.h> +#include <zix/status.h> #ifdef _WIN32 # include <windows.h> @@ -62,8 +62,7 @@ typedef ZixThreadResult(ZIX_THREAD_FUNC* ZixThreadFunc)(void*); @return #ZIX_STATUS_SUCCESS on success, or #ZIX_STATUS_ERROR. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_thread_create(ZixThread* thread, size_t stack_size, ZixThreadFunc function, @@ -74,8 +73,7 @@ zix_thread_create(ZixThread* thread, @return #ZIX_STATUS_SUCCESS on success, or #ZIX_STATUS_ERROR. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_thread_join(ZixThread thread); /** diff --git a/include/zix/tree.h b/include/zix/tree.h index 0ad37f2..7a223a5 100644 --- a/include/zix/tree.h +++ b/include/zix/tree.h @@ -4,9 +4,9 @@ #ifndef ZIX_TREE_H #define ZIX_TREE_H -#include "zix/allocator.h" -#include "zix/attributes.h" -#include "zix/status.h" +#include <zix/allocator.h> +#include <zix/attributes.h> +#include <zix/status.h> #include <stdbool.h> #include <stddef.h> @@ -20,7 +20,7 @@ ZIX_BEGIN_DECLS */ /** - @defgroup zix_tree_setup Setup + @defgroup zix_tree_types Types @{ */ @@ -36,9 +36,14 @@ typedef int (*ZixTreeCompareFunc)(const void* ZIX_UNSPECIFIED a, typedef void (*ZixTreeDestroyFunc)(void* ZIX_UNSPECIFIED ptr, const void* ZIX_UNSPECIFIED user_data); +/** + @} + @defgroup zix_tree_setup Setup + @{ +*/ + /// Create a new (empty) tree -ZIX_API -ZixTree* ZIX_ALLOCATED +ZIX_API ZIX_NODISCARD ZixTree* ZIX_ALLOCATED zix_tree_new(ZixAllocator* ZIX_NULLABLE allocator, bool allow_duplicates, ZixTreeCompareFunc ZIX_NONNULL cmp, @@ -47,13 +52,11 @@ zix_tree_new(ZixAllocator* ZIX_NULLABLE allocator, const void* ZIX_NULLABLE destroy_user_data); /// Free `t` -ZIX_API -void +ZIX_API void zix_tree_free(ZixTree* ZIX_NULLABLE t); /// Return the number of elements in `t` -ZIX_PURE_API -size_t +ZIX_PURE_API size_t zix_tree_size(const ZixTree* ZIX_NONNULL t); /** @@ -66,48 +69,39 @@ zix_tree_size(const ZixTree* ZIX_NONNULL t); typedef struct ZixTreeNodeImpl ZixTreeIter; /// Return the data associated with the given tree item -ZIX_PURE_API -void* ZIX_UNSPECIFIED +ZIX_PURE_API void* ZIX_UNSPECIFIED zix_tree_get(const ZixTreeIter* ZIX_NULLABLE ti); /// Return an iterator to the first (smallest) element in `t` -ZIX_PURE_API -ZixTreeIter* ZIX_NULLABLE +ZIX_PURE_API ZixTreeIter* ZIX_NULLABLE zix_tree_begin(ZixTree* ZIX_NONNULL t); /// Return an iterator the the element one past the last element in `t` -ZIX_CONST_API -ZixTreeIter* ZIX_NULLABLE +ZIX_CONST_API ZixTreeIter* ZIX_NULLABLE zix_tree_end(ZixTree* ZIX_NONNULL t); /// Return true iff `i` is an iterator to the end of its tree -ZIX_CONST_API -bool +ZIX_CONST_API bool zix_tree_iter_is_end(const ZixTreeIter* ZIX_NULLABLE i); /// Return an iterator to the last (largest) element in `t` -ZIX_PURE_API -ZixTreeIter* ZIX_NULLABLE +ZIX_PURE_API ZixTreeIter* ZIX_NULLABLE zix_tree_rbegin(ZixTree* ZIX_NONNULL t); /// Return an iterator the the element one before the first element in `t` -ZIX_CONST_API -ZixTreeIter* ZIX_NULLABLE +ZIX_CONST_API ZixTreeIter* ZIX_NULLABLE zix_tree_rend(ZixTree* ZIX_NONNULL t); /// Return true iff `i` is an iterator to the reverse end of its tree -ZIX_CONST_API -bool +ZIX_CONST_API bool zix_tree_iter_is_rend(const ZixTreeIter* ZIX_NULLABLE i); /// Return an iterator that points to the element one past `i` -ZIX_PURE_API -ZixTreeIter* ZIX_NULLABLE +ZIX_PURE_API ZixTreeIter* ZIX_NULLABLE zix_tree_iter_next(ZixTreeIter* ZIX_NULLABLE i); /// Return an iterator that points to the element one before `i` -ZIX_PURE_API -ZixTreeIter* ZIX_NULLABLE +ZIX_PURE_API ZixTreeIter* ZIX_NULLABLE zix_tree_iter_prev(ZixTreeIter* ZIX_NULLABLE i); /** @@ -117,15 +111,13 @@ zix_tree_iter_prev(ZixTreeIter* ZIX_NULLABLE i); */ /// Insert the element `e` into `t` and point `ti` at the new element -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_tree_insert(ZixTree* ZIX_NONNULL t, void* ZIX_UNSPECIFIED e, ZixTreeIter* ZIX_NULLABLE* ZIX_NULLABLE ti); /// Remove the item pointed at by `ti` from `t` -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_tree_remove(ZixTree* ZIX_NONNULL t, ZixTreeIter* ZIX_NONNULL ti); /** @@ -139,8 +131,7 @@ zix_tree_remove(ZixTree* ZIX_NONNULL t, ZixTreeIter* ZIX_NONNULL ti); If no such item exists, `ti` is set to NULL. */ -ZIX_API -ZixStatus +ZIX_API ZixStatus zix_tree_find(const ZixTree* ZIX_NONNULL t, const void* ZIX_UNSPECIFIED e, ZixTreeIter* ZIX_NULLABLE* ZIX_NONNULL ti); diff --git a/include/zix/zix.h b/include/zix/zix.h index ca72d35..ceaadc0 100644 --- a/include/zix/zix.h +++ b/include/zix/zix.h @@ -1,4 +1,4 @@ -// Copyright 2016-2022 David Robillard <d@drobilla.net> +// Copyright 2016-2024 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #ifndef ZIX_ZIX_H @@ -16,9 +16,9 @@ @{ */ -#include "zix/attributes.h" -#include "zix/status.h" -#include "zix/string_view.h" +#include <zix/attributes.h> +#include <zix/status.h> +#include <zix/string_view.h> /** @} @@ -26,8 +26,8 @@ @{ */ -#include "zix/allocator.h" -#include "zix/bump_allocator.h" +#include <zix/allocator.h> +#include <zix/bump_allocator.h> /** @} @@ -35,7 +35,7 @@ @{ */ -#include "zix/digest.h" +#include <zix/digest.h> /** @} @@ -43,10 +43,10 @@ @{ */ -#include "zix/btree.h" -#include "zix/hash.h" -#include "zix/ring.h" -#include "zix/tree.h" +#include <zix/btree.h> +#include <zix/hash.h> +#include <zix/ring.h> +#include <zix/tree.h> /** @} @@ -54,8 +54,8 @@ @{ */ -#include "zix/sem.h" -#include "zix/thread.h" +#include <zix/sem.h> +#include <zix/thread.h> /** @} @@ -63,8 +63,16 @@ @{ */ -#include "zix/filesystem.h" -#include "zix/path.h" +#include <zix/filesystem.h> +#include <zix/path.h> + +/** + @} + @defgroup zix_environment Environment + @{ +*/ + +#include <zix/environment.h> /** @} |