fixes tons of typos and grammar issues across the documentation - fixes #667 default tip

Sun, 12 Oct 2025 20:21:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 12 Oct 2025 20:21:56 +0200
changeset 1424
563033aa998c
parent 1423
9a72258446cd

fixes tons of typos and grammar issues across the documentation - fixes #667

docs/Writerside/topics/about.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/allocator.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/array_list.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/buffer.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/collection.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/compare.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/hash_key.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/hash_map.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/install.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/iterator.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/json.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/linked_list.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/map.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/parsers.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/printf.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/properties.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/streams.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/string.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/strings.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/test.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/tree.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/utils.md file | annotate | diff | comparison | revisions
src/cx/allocator.h file | annotate | diff | comparison | revisions
src/cx/array_list.h file | annotate | diff | comparison | revisions
src/cx/buffer.h file | annotate | diff | comparison | revisions
src/cx/collection.h file | annotate | diff | comparison | revisions
src/cx/common.h file | annotate | diff | comparison | revisions
src/cx/compare.h file | annotate | diff | comparison | revisions
src/cx/hash_key.h file | annotate | diff | comparison | revisions
src/cx/hash_map.h file | annotate | diff | comparison | revisions
src/cx/iterator.h file | annotate | diff | comparison | revisions
src/cx/json.h file | annotate | diff | comparison | revisions
src/cx/kv_list.h file | annotate | diff | comparison | revisions
src/cx/linked_list.h file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/cx/map.h file | annotate | diff | comparison | revisions
src/cx/printf.h file | annotate | diff | comparison | revisions
src/cx/properties.h file | annotate | diff | comparison | revisions
src/cx/streams.h file | annotate | diff | comparison | revisions
src/cx/string.h file | annotate | diff | comparison | revisions
src/cx/test.h file | annotate | diff | comparison | revisions
src/cx/tree.h file | annotate | diff | comparison | revisions
--- a/docs/Writerside/topics/about.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/about.md	Sun Oct 12 20:21:56 2025 +0200
@@ -3,7 +3,7 @@
 Welcome to the UAP Common Extensions.
 
 With this library we provide useful data structures and algorithms for common
-programmatic tasks in the C language. Using the build files you can create
+programmatic tasks in the C language. Using the build files, you can create
 a static and a shared lib containing all units, but you may also use the UCX
 sources in your project and compile specific units by yourself.
 
--- a/docs/Writerside/topics/allocator.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/allocator.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -1,7 +1,7 @@
 # Allocator
 
 The allocator interface provides a mechanism to implement own custom allocators 
-that can also be used in many other function in UCX.
+that can also be used in many other functions in UCX.
 
 A default allocator implementation using the stdlib functions is
 available via the global symbol `cxStdlibAllocator`,
@@ -11,8 +11,8 @@
 
 ## Default Allocator
 
-The global default allocator which is used by UCX,
-when no specific allocator is specified,
+The global default allocator which is used by UCX
+when no specific allocator is specified
 can be configured via the `cxDefaultAllocator`.
 It is by default set to the `cxStdlibAllocator`.
 
@@ -156,7 +156,7 @@
 The only difference is that you can pass additional custom `data` to an advanced destructor function.
 
 Destructor functions play a vital role in deep deallocations.
-Another scenarios, besides destroying elements in a collection, are the deallocation of objects
+Another scenario, besides destroying elements in a collection, is the deallocation of objects
 stored in a [memory pool](mempool.h.md) or deallocations of deeply nested [JSON](json.h.md) objects.
 
 > Destructor functions are not to be confused with `free()`-like functions.
--- a/docs/Writerside/topics/array_list.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/array_list.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -79,10 +79,10 @@
 cx_array_initialize_a(mpool->allocator, data.my_array, 16);
 ```
 
-> The aforementioned macros make your life simpler, but keep in mind that using them is not mandatory.
-> All other macros continue to work perfectly, if you declare and initialize your array manually, as long as you use
+> The aforementioned macros simplify your life, but keep in mind that using them is not mandatory.
+> All other macros continue to work perfectly if you declare and initialize your array manually, as long as you use
 > the naming convention to suffix the size variable with `_size` and the capacity variable with `_capacity`.
-> Also you can freely decide in which order you want to declare the variables.
+> Also, you can freely decide in which order you want to declare the variables.
 > 
 > For example, when you have multiple arrays in your struct with 8-bit `size_type` (because in your use case you don't expect more than 255 elements),
 > it is favorable to group all pointers and then declare the size and capacity variables to avoid padding between the array declarations. 
@@ -110,10 +110,10 @@
 extern CxArrayReallocator* cx_array_default_reallocator;
 ```
 
-The main purpose of the functions defined in the array list header,
-is to make it easier to write to an array without caring too much about a possibly needed reallocation.
+The main purpose of the functions defined in the array list header 
+is to make it easier to write to an array without caring too much about a possibly necessary reallocation.
 
-This is realized by passing a reallocator to the various functions which specifies how an array shall be reallocated when needed.
+This is realized by passing a reallocator to the various functions that specify how an array shall be reallocated when needed.
 
 The default `cx_array_default_reallocator` simply defers to the [default allocator](allocator.h.md#default-allocator).
 
@@ -125,7 +125,7 @@
 
 This allows you to allocate an array on the stack and instruct UCX to automatically move it to heap memory when the capacity is exceeded.
 Combined with a UCX [memory pool](mempool.h.md) this can be a powerful tool for local arrays
-which are expected to stay within the bounds of the stack memory most of the time, but are also allowed to sometimes grow their capacity when needed.
+which are expected to stay within the bounds of the stack memory most of the time, but are also allowed to sometimes grow their capacity.
 
 ## Reserve
 
@@ -146,9 +146,9 @@
 
 The `array` argument is a pointer to the location of the target array pointer.
 The reason for this additional indirection is that this function writes
-a new pointer back to that variable, if the array needed to be reallocated.
+a new pointer back to that variable if the array needed to be reallocated.
 
-If reallocation fails, this function returns non-zero leaving the array as it was.
+If reallocation fails, this function returns non-zero, leaving the array as it was.
 Otherwise, the function returns zero.
 
 If `*size + elem_count` does not exceed the current `*capacity`, this function does nothing and simply returns zero.
@@ -156,7 +156,7 @@
 If reallocation was necessary but failed, this function returns non-zero.
 
 The actual data type of `size` and `capacity` can be a pointer to an arbitrary integer whose byte-width is determined by the `width` argument.
-On 32-bit platforms the widths 1, 2, and 4 are supported and on 64-bit platforms, additionally a width of 8 is supported.
+On 32-bit platforms the widths 1, 2, and 4 are supported, and on 64-bit platforms a width of 8 is also supported.
 Passing zero as argument makes the function assume the native width for size arguments `sizeof(size_t)`.
 
 The convenience macros take the _name_ of an array variable and invoke the function by deducing the other arguments
@@ -164,7 +164,7 @@
 The reallocator used by the `cx_array_simple_reserve()` macro is the `cx_array_default_reallocator`.
 
 > While the actual integer type for `size` and `capacity` can be chosen freely, it must be _the same_ for both variables.
-> For example it is not allowed, and it does not make any sense either, to use a 16-bit integer for the size, but a 32-bit integer for the capacity.
+> For example, it is not allowed, and it does not make any sense either, to use a 16-bit integer for the size, but a 32-bit integer for the capacity.
 
 ## Copy
 
@@ -194,7 +194,7 @@
 * the data in the target array is overwritten - if you want to insert data, you first need to copy the existing data to the end of the array and then copy the new data in a separate call 
 
 > If you are using `cx_array_reserve()` already in your program, there is no need to call `cx_array_copy()` or any of the convenience macros anymore.
-> In other words: if you already guarantee, by any means, that no reallocation is necessary when writing to your array,
+> In other words: if you already guarantee, by any means that no reallocation is necessary when writing to your array,
 > it is strongly recommended to use standard library functions or direct index-based access instead of the UCX functions,
 > which only purpose is to make it easier for you to guarantee that your array's capacity is large enough to hold new elements.  
 
@@ -307,12 +307,12 @@
 Otherwise, the function returns `size`.
 
 The functions `cx_array_binary_search_inf()` and `cx_array_binary_search_sup()` are equivalent,
-except that they return the index of the closest element, if the searched element is not found.
-The former function returns the closest element that is less or equal (greatest lower bound / infimum),
-and the latter function returns the closest element that is larger or equal (least upper bound / supremum)
+except that they return the index of the closest element if the searched element is not found.
+The former function returns the closest element that is less or equal (the greatest lower bound / infimum),
+and the latter function returns the closest element that is larger or equal (the least upper bound / supremum)
 than the searched element.
 
-> Note, that all of the above functions are only well-defined on arrays which are sorted with respect to the given compare function.
+> Note that all of the above functions are only well-defined on arrays which are sorted with respect to the given compare function.
 > 
 > This can, for example, easily be achieved by calling the standard library's `qsort()` function.
 >{style="note"}
--- a/docs/Writerside/topics/buffer.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/buffer.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -3,14 +3,14 @@
 This buffer implementation can be used to read from or write to memory like you would do with a stream.
 
 This allows the use of `cx_stream_copy()` (see [](streams.h.md)) to copy contents from one buffer to another,
-or from a file or network streams to the buffer and vice versa.
+or from a file or network stream to the buffer and vice versa.
 
 More features for convenient use of the buffer can be enabled, like automatic memory management,
 automatic resizing of the buffer space, or automatic flushing of contents.
 
 The functions `cxBufferRead()` and `cxBufferWrite()` are `cx_read_func` and `cx_write_func` compatible,
 which in turn have a compatible signature to `fread()` and `fwrite()`.
-However, due to the different pointer type, the function pointers do not type check out of the box.
+However, due to the different pointer type the function pointers do not type check out of the box.
 For convenience, the macros `cxBufferReadFunc` and `cxBufferWriteFunc` are defined, which perform the necessary cast.
 
 ## Example
@@ -80,7 +80,7 @@
 #define CX_BUFFER_COPY_ON_EXTEND
 ```
 
-For creating a UCX buffer you have two options: initialize a pre-allocated structure, or allocate and initialize a new structure in one call.
+For creating a UCX buffer, you have two options: initialize a pre-allocated structure, or allocate and initialize a new structure in one call.
 
 For the first option, you can call `cxBufferInit()` with the `buffer` argument pointing to an uninitialized `CxBuffer` structure.
 You can pass a pre-allocated `space`, the desired `capacity`, and an `allocator`.
@@ -175,12 +175,12 @@
 The function `cxBufferPutString()` is a convenience function,
 that uses stdlib `strlen()` to compute the length of `str` and then invokes `cxBufferWrite()`.
 
-All of the above functions advance the buffers position by the number of bytes written,
+All the above functions advance the buffer position by the number of bytes written 
 and cause the _size_ of the buffer to grow, if necessary, to contain all written bytes.
 On the other hand, `cxBufferTerminate()` writes a zero-byte at the current position,
 effectively creating a zero-terminated string whose size equals the buffer size.
 
-The function `cxBufferAppend()` writes the data to end of the buffer (given by its size) regardless of the current position,
+The function `cxBufferAppend()` writes the data to the end of the buffer (given by its size) regardless of the current position,
 and it also does _not_ advance the position.
 If the write operation triggered a [flush](#flushing), however, the position will be shifted left alongside the shifted buffer contents.
 In case the data at which the current position points gets flushed, the new position will be zero.
@@ -199,8 +199,8 @@
 ```
 
 The function `cxBufferRead()` reads `nitems` number of items of `size` bytes each from the `buffer`
-and stores them into the memory pointed to by `ptr`, which must be sufficiently large to hold the contents.
-The function returns the actual bytes read, which might be lower, if the desired number of items is not available.
+and stores them into the memory pointed to by `ptr`, which must be large enough to hold the contents.
+The function returns the actual bytes read, which might be lower if the desired number of items is not available.
 
 The function `cxBufferGet()` is a `fgetc()`-like function which returns the next byte in the buffer converted to an `int`.
 Similar to `fgetc()` it returns `EOF` when there are no more bytes in the buffer.
@@ -225,8 +225,8 @@
 The function `cxBufferReset()` sets both size and position of the buffer to zero,
 and `cxBufferClear()` additionally uses `memset()` to set every byte in the buffer to zero.
 
-> When clearing the buffer, only the "live" data, i.e. bytes with indices `[0..size)`, are cleared.
-> If you which to clear the entire buffer's memory, you would need to set the size to the capacity, first.
+> When clearing the buffer, only the "live" data, i.e., bytes with indices `[0..size)`, are cleared.
+> If you want to clear the entire buffer's memory, you would need to set the size to the capacity, first.
 
 > If the `CX_BUFFER_COPY_ON_WRITE` flag is set, `cxBufferClear()` behaves exactly like `cxBufferReset()`,
 > because writing to the contents is disallowed.
@@ -263,9 +263,9 @@
 
 The function `cxBufferShift()` moves the contents within the buffer by the specified `shift` offset,
 where a negative offset means a shift to the left, and a positive offset means a shift to the right.
-It also adjusts the current position within the buffer, and in case of a right shift also the size, by the same offset.
+It also adjusts the current position within the buffer, and in the case of a right shift also the size, by the same offset.
 
-Data that is shift to the left, is always discarded when the new position of a byte would be smaller than zero.
+Data shifted to the left is always discarded when the new position of a byte would be smaller than zero.
 If the new position would be smaller than zero, it is set exactly to zero.
 
 When data is shift to the right, the behavior depends on the `CX_BUFFER_AUTO_EXTEND` flag.
@@ -274,8 +274,8 @@
 (which means, `cxBufferEof()` returns `true` after the operation). 
 
 The functions `cxBufferShiftRight()` and `cxBufferShiftLeft()` accept a larger (but in both cases positive) shift offset,
-which usually does not make much sense on a 64-bit platform where `off_t` is already large enough to represent any reasonable offset.
-You may, however, still use those function to express more explicitly in your code in which direction you want the contents to be shifted.
+which usually makes little sense on a 64-bit platform where `off_t` is already large enough to represent any reasonable offset.
+You may, however, still use those functions to express more explicitly in your code in which direction you want the contents to be shifted.
 
 ## Flushing
 
@@ -310,13 +310,13 @@
 Flushing happens by invoking the `wfunc` up to `blkmax` times, writing up to `blksize` bytes from the buffer to the `target` with each call.
 The target might not accept all bytes (i.e. the `wfunc` return value indicates that fewer items have been written than requested),
 in which case the remaining data remains in the buffer.
-That means, the buffer is effectively [shifted](#shift-contents) left by the number of successfully flushed bytes.
+That means the buffer is effectively [shifted](#shift-contents) left by the number of successfully flushed bytes.
 
 > When you write large amounts of data to a buffer, multiple flush cycles might happen.
-> After the first flush operations completed, the reclaimed space in the buffer is filled first, but if that
-> is not sufficient, another flush may be triggered within the same invocation of the write operation.
+> After the first flush operations are completed, the reclaimed space in the buffer is filled first, but if that
+> is not enough, another flush may be triggered within the same invocation of the write operation.
 > 
-> That means, as much data is written to the buffer and/or flushed as possible, until neither the flush target, nor the buffer accept more data.
+> That means as much data is written to the buffer and/or flushed as possible, until neither the flush target nor the buffer accept more data.
 >{style="note"}
 
 > The function `cxBufferFlush()` simply returns zero when flushing was not enabled via `cxBufferEnableFlushing()`.
--- a/docs/Writerside/topics/collection.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/collection.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -71,7 +71,7 @@
 > Destructor functions are always invoked with a pointer to the element in your collection.
 > If your collection is storing pointers (i.e. `cxCollectionStoresPointers()` returns `true`)
 > the `cx_invoke_destructor()` will make sure that the pointer to the element is dereferenced first,
-> so that the destructor functions are _always_ invoked with pointer to the actual element.
+> so that the destructor functions are _always_ invoked with a pointer to the actual element.
 {style="note"}
 
 <seealso>
--- a/docs/Writerside/topics/compare.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/compare.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -35,43 +35,44 @@
 #include <cx/compare.h>
 
 // Value Flavour
-cx_vcmp_double
-cx_vcmp_float
-cx_vcmp_int
-cx_vcmp_int16
-cx_vcmp_int32
-cx_vcmp_int64
-cx_vcmp_intptr
-cx_vcmp_longint
-cx_vcmp_longlong
-cx_vcmp_uint
-cx_vcmp_uint16
-cx_vcmp_uint32
-cx_vcmp_uint64
-cx_vcmp_size
-cx_vcmp_uintptr
-cx_vcmp_ulongint
-cx_vcmp_ulonglong
+int cx_vcmp_double(double a, double b);
+int cx_vcmp_float(float a, float b);
+int cx_vcmp_int(int a, int b);
+int cx_vcmp_int16(int16_t a, int16_t b);
+int cx_vcmp_int32(int32_t a, int32_t b));
+int cx_vcmp_int64(int64_t a, int64_t b);
+int cx_vcmp_intptr(intptr_t a, intptr_t b);
+int cx_vcmp_longint(long int a, long int b);
+int cx_vcmp_longlong(long long a, long long b);
+int cx_vcmp_uint(unsigned int a, unsigned int b);
+int cx_vcmp_uint16(uint16_t a, uint16_t b);
+int cx_vcmp_uint32(uint32_t a, uint32_t b);
+int cx_vcmp_uint64(uint64_t a, uint64_t b);
+int cx_vcmp_size(size_t a, size_t b);
+int cx_vcmp_uintptr(uintptr_t a, uintptr_t b);
+int cx_vcmp_ulongint(unsigned long int a, unsigned long int b);
+int cx_vcmp_ulonglong(unsigned long long a, unsigned long long b);
 
 // Pointer Flavour
-cx_cmp_double
-cx_cmp_float
-cx_cmp_int
-cx_cmp_int16
-cx_cmp_int32
-cx_cmp_int64
-cx_cmp_intptr
-cx_cmp_longint
-cx_cmp_longlong
-cx_cmp_ptr
-cx_cmp_uint
-cx_cmp_uint16
-cx_cmp_uint32
-cx_cmp_uint64
-cx_cmp_size
-cx_cmp_uintptr
-cx_cmp_ulongint
-cx_cmp_ulonglong
+// (unspecified types make them compatible with cx_compare_func)
+int cx_cmp_ptr(const void *a, const void *b);
+int cx_cmp_double(const void *a, const void *b);
+int cx_cmp_float(const void *a, const void *b);
+int cx_cmp_int(const void *a, const void *b);
+int cx_cmp_int16(const void *a, const void *b);
+int cx_cmp_int32(const void *a, const void *b);
+int cx_cmp_int64(const void *a, const void *b);
+int cx_cmp_intptr(const void *a, const void *b);
+int cx_cmp_longint(const void *a, const void *b);
+int cx_cmp_longlong(const void *a, const void *b);
+int cx_cmp_uint(const void *a, const void *b);
+int cx_cmp_uint16(const void *a, const void *b);
+int cx_cmp_uint32(const void *a, const void *b);
+int cx_cmp_uint64(const void *a, const void *b);
+int cx_cmp_size(const void *a, const void *b);
+int cx_cmp_uintptr(const void *a, const void *b);
+int cx_cmp_ulongint(const void *a, const void *b);
+int cx_cmp_ulonglong(const void *a, const void *b);
 ```
 
 <seealso>
--- a/docs/Writerside/topics/hash_key.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/hash_key.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -41,7 +41,7 @@
 > {style="note"}
 
 > UCX assigns the hash value `1574210520` to the `NULL` pointer.
-> This is a careful choice which is not standard MurmurHash2 and an extension to support `NULL` pointers.
+> This is a careful choice that is not standard MurmurHash2 and an extension to support `NULL` pointers.
 
 Hashes from integers are created more efficiently by mixing up the bits to produce a good statistical distribution.
 The function `cx_hash_u32()` and `cx_hash_u64()` are provided for this purpose and provide collision-free hashes.
--- a/docs/Writerside/topics/hash_map.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/hash_map.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -1,6 +1,6 @@
 # Hash Map
 
-UCX provides a basic hash map implementation with a configurable amount of buckets.
+UCX provides a basic hash map implementation with a configurable number of buckets.
 If you do not specify the number of buckets, a default of 16 buckets will be used.
 
 You can always rehash the map with `cxMapRehash()` to change the number of buckets to something more efficient,
@@ -28,11 +28,11 @@
 pointers instead of actual items.
 
 If you pass zero for the number of `buckets`, or use `cxHashMapSimple()`,
-the map is initialized with a default of 16 buckets, otherwise the specified number of buckets is allocated.
+the map is initialized with a default of 16 buckets; otherwise the specified number of buckets is allocated.
 
 The function `cxMapRehash()` allocates a new array of buckets and re-distributes all elements,
 if the number of elements exceeds ¾ of the number of buckets.
-Otherwise, no action is performed and this function simply returns 0.
+Otherwise, no action is performed, and this function simply returns 0.
 After rehashing, the number of buckets is at least 2½ times the number of elements.
 
 > Advice if you want to create your own hash map structures:
--- a/docs/Writerside/topics/install.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/install.md	Sun Oct 12 20:21:56 2025 +0200
@@ -62,7 +62,7 @@
 ### Features Defines
 
 The following macros are not defined by default.
-The effect when they are defined in described in the table.
+The effect when they are defined is described in the table.
 
 <table>
 <tr>
--- a/docs/Writerside/topics/iterator.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/iterator.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -6,7 +6,7 @@
 Creating an iterator is as simple as creating a `CxIterator` struct and setting the fields in a meaningful way.
 The UCX collections provide various functions to create such iterators.
 
-If the predefined fields are insufficient (or introduce too much bloat) for your use case,
+If the predefined fields are not enough (or introduce too much bloat) for your use case,
 you can alternatively create your own iterator structure
 and place the `CX_ITERATOR_BASE` macro as first member of that structure.
 
@@ -79,7 +79,7 @@
 2. the name of the variable you want to use for accessing the element,
 3. and the iterator.
 
-> An iterator does not necessarily need to iterate over the elements of a collections.
+> An iterator does not necessarily need to iterate over the concrete elements of a collection.
 > Map iterators, for example, can iterator over the key/value pairs,
 > but they can also iterate over just the values or just the keys.
 > 
@@ -100,7 +100,7 @@
 ## Passing Iterators to Functions
 
 To eliminate the need of memory management for iterators, the structures are usually used by value.
-This does not come with additional costs, because iteration is implemented entirely by macros.
+This does not come with additional costs because iteration is implemented entirely by using macros.
 
 However, sometimes it is necessary to pass an iterator to another function.
 To make that possible in a generalized way, such functions should accept a `CxIteratorBase*` pointer
@@ -145,8 +145,8 @@
 called by a wrapper implementation pointed to by `current`.
 This can be useful when you want to support the `store_pointer` field of the [](collection.h.md) API.
 
-A specialized, simple, and fast iterator over an array of a certain type,
-that does not support mutation, can be implemented as follows:
+A specialized, simple, and fast iterator over an array of a certain type
+that does not support mutation can be implemented as follows:
 ```C
 #include <cx/iterator.h>
 
@@ -196,11 +196,11 @@
 
 > Note, that the behavior of `current` is undefined when `valid` returns `false`.
 > That means, on the one hand, `current` does not need to check for validity of the iterator,
-> but on the other hand it is forbidden to invoke `current` when `valid` would return `false`.
+> but on the other hand, it is forbidden to invoke `current` when `valid` would return `false`.
 {style="note"}
 
 > If performance matters in your application, it is recommended that you indeed create specialized iterators
-> for your collections. The default UCX implementations trade some of the performance for generality.
+> for your collections. The default UCX implementations trade some performance for generality.
 
 <seealso>
 <category ref="apidoc">
--- a/docs/Writerside/topics/json.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/json.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -29,7 +29,7 @@
 Specifying `NULL` as `allocator` is allowed, in which case the `cxDefaultAllocator` will be used.
 
 The actual parsing is an interleaving invocation of the `cxJsonFill()` (or `cxJsonFilln()`) and `cxJsonNext()` functions.
-The `cxJsonFill()` function is a convenience function, that accepts UCX strings and normal zero-terminated C strings.
+The `cxJsonFill()` function is a convenience function that accepts UCX strings and normal zero-terminated C strings.
 
 Calling `cxJsonNext()` will return with `CX_JSON_NO_ERROR` (= zero) for each JSON value that is successfully parsed,
 and stores the pointer to the allocated value in the variable pointed to by `value`.
@@ -117,7 +117,7 @@
 
 The `cxJsonIsXYZ()` family functions check the type of the specified JSON value.
 
-The JSON specification only defines numbers, therefore `cxJsonIsNumber()` returns true for both floating point and integer numbers.
+The JSON specification only defines numbers, therefore `cxJsonIsNumber()` returns true for both floating-point and integer numbers.
 On the other hand, `cxJsonIsInteger()` only returns true for integral numbers.
 
 The function `cxJsonIsBool()` returns true if `cxJsonIsLiteral()` returns true, but `cxJsonIsNull()` does not.
@@ -125,7 +125,7 @@
 > Since a literal can be `true`, `false`, or `null`, note carefully that `!cxJsonIsTrue(v)`
 > is in general _not_ equivalent to `cxJsonIsFalse(v)`.
 > 
-> Additionally, UCX does implement the Javascript concept of a "falsy" value, meaning that
+> Additionally, UCX does implement the JavaScript concept of a "falsy" value, meaning that
 > `cxJsonIsFalse()` _only_ returns true, if the value is a literal `false`.
 >{style="note"}
 
@@ -148,7 +148,7 @@
 > 
 > This is **not** the case for `cxJsonArrRemove()` and `cxJsonObjRemove()`, which return `NULL` in that case.
 
-> If you don't have full control over the JSON data, you should always check the datatype of a value first, before accessing it.
+> If you don't have full control over the JSON data, you should always check the datatype of a value first before accessing it.
 >{style="note"}
 
 ## Deallocate Memory
--- a/docs/Writerside/topics/linked_list.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/linked_list.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -59,7 +59,7 @@
 If true, the function terminates and returns the current node.
 Otherwise, it moves on with the search.
 If `begin` is already the searched `node`, this function immediately returns `NULL` as there is no predecessor.
-Note carefully, that the behavior of this function is not defined when `node` is not contained in the list that starts with `begin`.
+Note carefully that the behavior of this function is not defined when `node` is not contained in the list that starts with `begin`.
 
 > It is advisable to use the low-level functions inside own custom functions that you define particularly for your lists.
 > Otherwise you will get a lot of boilerplate code when specifying the offsets to the pointers in your node structure in every call
@@ -208,7 +208,7 @@
         void *node, size_t num);
 ```
 
-You can either remove a single element or a specified number of subsequent elements from list.
+You can either remove a single element or a specified number of subsequent elements from the list.
 
 The function `cx_linked_list_remove()` is equivalent to `cx_linked_list_remove_chain()` where `num` is set to one.
 
@@ -272,7 +272,7 @@
 But it is also possible to start with the _last_ node of both lists and use the `prev` pointer to compare them backwards.
 
 The `loc_data` offset is used to calculate the pointer that is passed to the `cmp_fnc`.
-This can either be the offset of a specific field in the struct, or simply zero in which case the pointers to the nodes themselves are passed to the compare function.
+This can either be the offset of a specific field in the struct or simply zero, in which case the pointers to the nodes themselves are passed to the compare function.
 
 <seealso>
 <category ref="apidoc">
--- a/docs/Writerside/topics/map.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/map.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -22,7 +22,7 @@
 pointers instead of actual items.
 
 If you pass zero for the number of `buckets`, or use `cxHashMapSimple()`,
-the map is initialized with a default of 16 buckets, otherwise the specified number of buckets is allocated.
+the map is initialized with a default of 16 buckets; otherwise the specified number of buckets is allocated.
 
 > If you want to lazy-initialize maps, you can use the global `cxEmptyMap` symbol as a placeholder instead of using a `NULL`-pointer.
 > While you *must not* insert elements into that map, you can safely access this map or create iterators.
@@ -80,7 +80,7 @@
 
 In the first part we add several entries to the map.
 Then the example shows retrieval, updating, and removal of information.
-The last part shows how to iterate over the pairs of the map and how to recover the string from the key.
+The last part shows how to iterate over the pairs inside the map and how to recover the string from the key.
 
 In real-world situations, however, it is quite unlikely that you will use a map to store string literals.
 The next example shows a more realistic program, where it is necessary to store strings based on user input.
--- a/docs/Writerside/topics/parsers.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/parsers.md	Sun Oct 12 20:21:56 2025 +0200
@@ -2,7 +2,7 @@
 
 UCX offers parsers for two common formats: key/value [properties](properties.h.md) and [JSON](json.h.md).
 
-Both parser APIs are implemented in a memory efficient way.
-Depending on the use case, the properties parser can avoid memory allocations completely
+Both parser APIs are implemented in a memory-efficient way.
+Depending on the use case, the properties parser can avoid memory allocations completely, 
 and the JSON parser minimizes allocations as good as possible.
-Due to the nature of JSON, avoiding allocations altogether is of course not possible, though.
+Due to the nature of JSON, avoiding allocations altogether is, of course, not possible when operating on read-only memory.
--- a/docs/Writerside/topics/printf.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/printf.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -96,7 +96,7 @@
 
 The `cx_sprintf()` and `cx_sprintf_a()` functions take a pointer `str` to a pointer to a pre-allocated buffer,
 as well as a pointer `len` to `*str`'s length.
-If the formatted output would not fit into this buffer, it is reallocated
+If the formatted output does not fit into this buffer, it is reallocated
 and the new pointer to the buffer and the new length are written back to the variables pointed to by `str` and `len`.
 
 The `cx_sprintf_s()` and `cx_sprintf_sa()` functions differ from the previous function in that they take
--- a/docs/Writerside/topics/properties.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/properties.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -1,6 +1,6 @@
 # Properties
 
-The UCX properties parser can be used to parse line based key/value strings. 
+The UCX properties parser can be used to parse line-based key/value strings. 
 
 ## Supported Syntax
 
@@ -61,7 +61,7 @@
 ```
 
 The first step is to initialize a `CxProperties` structure with a call to `cxPropertiesInit()` using the desired config.
-The shorthand `cxPropertiesInitDefault()` creates a default configuration  with the equals sign `'='` as delimiter
+The shorthand `cxPropertiesInitDefault()` creates a default configuration with the equals sign `'='` as delimiter
 and the hash-symbol `'#'` as comment symbol (the other two comment symbols remain unused in the default config).
 
 > In a future UCX version, the default `continuation` character will be a backslash `'\'`.
@@ -87,7 +87,7 @@
 but the last line did not contain a full key/value pair.
 In that case, you can call `cxPropertiesFill()` again to add more data and continue with `cxPropertiesNext()`.
 
-Note, that adding more data to a non-empty input buffer will lead to an allocation,
+Note that adding more data to a non-empty input buffer will lead to an allocation,
 unless you specified some stack memory with `cxPropertiesUseStack()`.
 The stack capacity must be large enough to contain the longest line in your data.
 If the internal buffer is not large enough to contain a single line, it is extended.
@@ -178,7 +178,7 @@
 > If it does, it could mean that the source was unable to provide all the data, or the properties data ended unexpectedly.
 > The most expected status code is `CX_PROPERTIES_NO_ERROR` which means that at least one key/value-pair was found.
 > If `cxPropertiesLoad()` returns `CX_PROPERTIES_NO_DATA` it means that the source did not provide any key/value-pair.
-> There are several special status codes which are documented [below](#additional-status-codes). 
+> There are several special status codes that are documented [below](#additional-status-codes). 
 
 ### Creating own Sources and Sinks
 
--- a/docs/Writerside/topics/streams.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/streams.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -1,6 +1,6 @@
 # Data Streams
 
-Stream copy functions provide a way to copy all - or a  limited amount of - data from one stream to another.
+Stream copy functions provide a way to copy all - or a limited amount of - data from one stream to another.
 
 Since the read/write functions of a [UCX buffer](buffer.h.md) are fully compatible with stream read/write functions,
 you can, for example, easily transfer data from a file or network stream to a UCX buffer or vice versa.
--- a/docs/Writerside/topics/string.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/string.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -141,7 +141,7 @@
 The function `cx_strlen()` sums the length of the specified strings.
 
 > There is no reason to use `cx_strlen()` for a single UCX string.
-> Just access the `length` field of the structure directly. 
+> You can access the `length` field of the structure directly. 
 
 > You can mix `cxstring` and `cxmutstr` in the variadic arguments without the need of `cx_strcast()`.
 
@@ -181,7 +181,7 @@
 and `cx_strsubsl()` returns a substring with at most `length` bytes.
 
 The function `cx_strtrim()` returns the substring that results when removing all leading and trailing
-whitespace characters (a space character is one of the following string: `" \t\r\n\v\f"`).
+whitespace characters.
 
 All functions with the `_m` suffix behave exactly the same as their counterparts without `_m` suffix,
 except that they operate on a `cxmustr`.
@@ -306,9 +306,9 @@
 
 ## Conversion to Numbers
 
-For each integer type, as well as `float` and `double`, there are functions to convert a UCX string to a number of that type.
+For each integer type, as well as `float` and `double`, there are functions to convert a UCX string to a value of those types.
 
-Integer conversion comes in two flavours:
+Integer conversion comes in two flavors:
 ```C
 int cx_strtoi(AnyStr str, int *output, int base);
 
@@ -324,7 +324,7 @@
 array of group separator chars, each of which is simply ignored during conversion.
 The default group separator for the basic version is a comma `,`.
 
-The signature for the floating point conversions is quite similar:
+The signature for the floating-point conversions is quite similar:
 ```C
 int cx_strtof(AnyStr str, float *output);
 
@@ -332,13 +332,13 @@
         char decsep, const char *groupsep);
 ```
 
-The two differences are that the floating point versions do not support different bases,
+The two differences are that the floating-point versions do not support different bases,
 and the `_lc` variant allows specifying not only an array of group separators,
 but also the character used for the decimal separator.
 
 In the basic variant, the group separator is again a comma `,`, and the decimal separator is a dot `.`.
 
-> The floating point conversions of UCX 3.1 do not achieve the same precision as standard library implementations
+> The floating-point conversions of UCX 3.1 do not achieve the same precision as standard library implementations
 > which usually use more sophisticated algorithms.
 > The precision might increase in future UCX releases,
 > but until then be aware of slight inaccuracies, in particular when working with `double`.
--- a/docs/Writerside/topics/strings.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/strings.md	Sun Oct 12 20:21:56 2025 +0200
@@ -4,15 +4,15 @@
 UCX provides an API to work with structures that store a [string](string.h.md) together with its length,
 as well as a more sophisticated [buffer](buffer.h.md) API for working with text of dynamic or unknown length.
 
-Additionally, UCX offers several advanced [printf-like functions](printf.h.md) that also allow the convenient work
+Additionally, UCX offers several advanced [printf-like functions](printf.h.md) that also allow convenient work
 with strings of unknown length.
 For example, one the more advanced functions is `cx_sprintf_sa()` which lets you format a string into an existing
 pre-allocated buffer (e.g. on the stack) and automatically switches to a fresh buffer allocated by a custom allocator
 when the existing buffer is not large enough.
 
 The string API is designed to work with _both_ mutable and constant strings.
-The possibility to work with constant strings is especially important, when you want to work with string literals
-without copying them into a separate memory region - e.g. when you want to obtain a substring.
+The possibility to work with constant strings is especially important when you want to work with string literals
+without copying them into a separate memory region - e.g., when you want to get a substring.
 
 By default, UCX assumes strings are constant and stores them in a structure of type `cxstring`.
 Mutable strings are stored in a separate structure called `cxmutstr`.
--- a/docs/Writerside/topics/test.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/test.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -18,7 +18,7 @@
 A test case needs to be defined with the `CX_TEST` macro.
 The general structure of a test case is 1) setup code, 2) the actual test, 3) tear down code.
 In UCX this is realized by the `CX_TEST_DO` macro with which you can define a scope for the actual test.
-Whenever a test assertion fails, the scope is exited and the tear down code is executed.
+Whenever a test assertion fails, the scope is exited and the tear-down code is executed.
 
 <tabs>
 <tab title="Test">
@@ -110,9 +110,9 @@
 }
 ```
 
-> Any test function, test case or test subroutine, is a normal C function.
+> Any test function, test case or test subroutine is a normal C function.
 > As such you can decide to make them `static` when you do not want external linkage.
-> For example, just define the test as `static CX_TEST(test_foo)` instead of `CX_TEST(test_foo)`.
+> For example, you can define the test as `static CX_TEST(test_foo)` instead of `CX_TEST(test_foo)`.
 
 <seealso>
 <category ref="apidoc">
--- a/docs/Writerside/topics/tree.h.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/tree.h.md	Sun Oct 12 20:21:56 2025 +0200
@@ -1,6 +1,6 @@
 # Tree
 
-UCX provides several low-level function for working with arbitrary tree structures,
+UCX provides several low-level functions for working with arbitrary tree structures,
 as well as some high-level functions for trees that induce a certain order on the data they store. 
 
 The following convenience macros allow you to declare and use simple tree structures.
@@ -15,7 +15,7 @@
 `parent`, `children`, `last_child`, `prev`, and `next`,
 which must be placed as first member into your struct.
 
-You can use it for example like this:
+You can use it, for example, like this:
 ```C
 typedef struct my_tree_node_s {
     CX_TREE_NODE_BASE(struct my_tree_node_s);
@@ -106,7 +106,7 @@
 you may specify a negative location to indicate the missing pointer.
 All other pointers are mandatory and a non-negative location is expected.
 
-Note, that a wrapped tree by default has no create or search functions assigned.
+Note that a wrapped tree by default has no create or search functions assigned.
 Therefore, if you wish to use one of the functions below that needs those function pointers set,
 you will have to set them manually by assigning to the respective fields in the `CxTree` structure.
 
@@ -304,11 +304,11 @@
 1. The current node is compared with `data` / `node` using the `sfunc`.
 2. If `sfunc` returns zero, a matching node has been found and the pointer to that node is stored at the location given by `result`.
 3. If `sfunc` returns a negative number, the entire subtree is skipped.
-4. If `sfunc` returns a positive number, the subtree is searched, unless the number is larger than the number of an already searched subtree. The best match will be stored  at the location given by `result`. 
+4. If `sfunc` returns a positive number, the subtree is searched, unless the number is larger than the number of an already searched subtree. The best match will be stored at the location given by `result`. 
 5. The return value will be the return value of the `sfunc` for node that was stored in the `result`, or a negative number when no match was found
 
 > If the `sfunc` implements some kind of metric, the search functions will return the best match in the tree with respect to that metric.
-> When a positive number is returned, it means, that a new node with the searched data could be added as a child of the found node.
+> When a positive number is returned, it means that a new node with the searched data could be added as a child of the found node.
 > This is exactly how `cx_tree_add()` finds the best position to add a node to the tree.
 
 The function `cxTreeFind()` uses the `search_data_func` of the `CxTree`
@@ -348,7 +348,7 @@
 void cxTreeVisitorDispose(CxTreeVisitor *visitor);
 ```
 
-There are two different kind of iterators for trees.
+There are two different kinds of iterators for trees.
 The `CxTreeIterator` is performing a depth-first iteration with the capability of visiting a node twice:
 first when the iterator enters the node coming from its parent, and secondly when the iterator tracks back from its last child.
 This behavior is controlled via the `visit_on_exit` argument.
@@ -357,12 +357,12 @@
 
 On the other hand, the `CxTreeVisitor` performs a breadth-first iteration and visits every node only once.
 
-Since tree iteration needs to keep track of a stack (depth-first) or queue (breadth-frist), internal memory is allocated.
-This memory is _automatically_ disposed when the iteration _completes_.
+Since tree iteration needs to keep track of a stack (depth-first) or queue (breadth-first), internal memory is allocated.
+This memory is _automatically_ disposed of when the iteration _completes_.
 If you break from the iteration early, you must call `cxTreeIteratorDispose()` or `cxTreeVisitorDispose()`, respectively, to deallocate the memory.
 
 > It is recommended to always invoke the dispose functions, even when it seems not necessary.
-> In the best case it just does nothing, but calling them guarantees that no memory can be leaking, even when your code changes in the future.
+> In the best case it just does nothing, but calling them guarantees that no memory can be leaking, even when your code will change in the future.
 >{style="note"}
 
 The macros `cxTreeIteratorContinue()` and `cxTreeVisitorContinue()` equivalently instruct the iterator/visitor to skip the subtree below the currently inspected node.
@@ -412,12 +412,12 @@
 
 The function `cxTreeDestroyNode()` first [removes](#remove) the `node` from the tree, like `cxTreeRemoveNode()`,
 and then invokes the [destructor functions](collection.h.md#destructor-functions).
-It is guaranteed, that the simple destructor is called before the advanced destructor.
+It is guaranteed that the simple destructor is called before the advanced destructor.
 If no destructor function is registered at all, the behavior is identical to `cxTreeRemoveNode()`.
-That means, this function does not deallocate the memory for the node on its own and leaves that entirely to the destructor functions.
+That means this function does not deallocate the memory for the node on its own and leaves that entirely to the destructor functions.
 
 The function `cxTreeDestroySubtree()` performs the above actions for the entire subtree starting with `node`.
-The order in which the destructor functions for the nodes of the subtree are called are determined by a [tree iterator](#iterator-and-visitor).
+The order in which the destructor functions for the nodes of the subtree are called is determined by a [tree iterator](#iterator-and-visitor).
 
 The function `cxTreeClear()` is a shorthand for invoking `cxTreeDestroySubtree()` on the root node of the tree.
 
--- a/docs/Writerside/topics/utils.md	Sat Oct 11 15:42:48 2025 +0200
+++ b/docs/Writerside/topics/utils.md	Sun Oct 12 20:21:56 2025 +0200
@@ -10,5 +10,5 @@
 or any other stream (or buffer) API that uses an `fwrite`-compatible interface,
 you will find the stream copy function quite useful.
 
-And last, but not least, if you are interested in unit testing, but don't know which testing framework to use:
+And last, but not least, if you are interested in unit testing but don't know which testing framework to use:
 search no more, because we have got your back with [UCX Test](test.h.md).
--- a/src/cx/allocator.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/allocator.h	Sun Oct 12 20:21:56 2025 +0200
@@ -271,7 +271,7 @@
 /**
  * Reallocate the previously allocated block in @p mem, making the new block
  * @p n bytes long.
- * This function may return the same pointer that was passed to it, if moving
+ * This function may return the same pointer passed to it if moving
  * the memory was not necessary.
  *
  * @note Re-allocating a block allocated by a different allocator is undefined.
@@ -295,11 +295,11 @@
 /**
  * Reallocate the previously allocated block in @p mem, making the new block
  * @p n bytes long.
- * This function may return the same pointer that was passed to it, if moving
+ * This function may return the same pointer passed to it if moving
  * the memory was not necessary.
  *
  * The size is calculated by multiplying @p nemb and @p size.
- * If that multiplication overflows, this function returns @c NULL and @c errno
+ * If that multiplication overflows, this function returns @c NULL, and @c errno
  * will be set.
  *
  * @note Re-allocating a block allocated by a different allocator is undefined.
@@ -330,7 +330,7 @@
  * @note Re-allocating a block allocated by a different allocator is undefined.
  *
  * @par Error handling
- * @c errno will be set, if the underlying realloc function does so.
+ * @c errno will be set if the underlying realloc function does so.
  *
  * @param allocator the allocator
  * @param mem pointer to the pointer to allocated block
@@ -355,7 +355,7 @@
  * @note Re-allocating a block allocated by a different allocator is undefined.
  *
  * @par Error handling
- * @c errno will be set, if the underlying realloc function does so.
+ * @c errno will be set if the underlying realloc function does so.
  *
  * @param allocator (@c CxAllocator*) the allocator
  * @param mem (@c void**) pointer to the pointer to allocated block
--- a/src/cx/array_list.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/array_list.h	Sun Oct 12 20:21:56 2025 +0200
@@ -44,8 +44,8 @@
 #endif
 
 /**
- * The maximum item size in an array list that fits into stack buffer
- * when swapped.
+ * The maximum item size in an array list that fits into
+ * a stack buffer when swapped.
  */
 cx_attr_export
 extern const unsigned cx_array_swap_sbo_size;
@@ -84,7 +84,7 @@
 /**
  * Declares variables for an array that can be used with the convenience macros.
  *
- * The size and capacity variables will have @c size_t type.
+ * The size and capacity variables will have type @c size_t.
  * Use #CX_ARRAY_DECLARE_SIZED() to specify a different type.
  *
  * @par Examples
@@ -147,7 +147,7 @@
  * const CxAllocator *al = // ...
  * cx_array_initialize_a(al, myarray, 128);
  * // ...
- * cxFree(al, myarray); // don't forget to free with same allocator
+ * cxFree(al, myarray); // remember to free with the same allocator
  * @endcode
  *
  * @param allocator (@c CxAllocator*) the allocator
@@ -230,16 +230,16 @@
  * When @p allocator is @c NULL, the cxDefaultAllocator will be used.
  *
  * When @p stackmem is not @c NULL, the reallocator is supposed to be used
- * @em only for the specific array that is initially located at @p stackmem.
- * When reallocation is needed, the reallocator checks, if the array is
+ * @em only for the specific array initially located at @p stackmem.
+ * When reallocation is needed, the reallocator checks if the array is
  * still located at @p stackmem and copies the contents to the heap.
  *
- * @note Invoking this function with both arguments @c NULL will return a
+ * @note Invoking this function with both arguments being @c NULL will return a
  * reallocator that behaves like #cx_array_default_reallocator.
  *
  * @param allocator the allocator this reallocator shall be based on
  * @param stackmem the address of the array when the array is initially located
- * on the stack or shall not reallocated in place
+ * on the stack or shall not reallocate in place
  * @return an array reallocator
  */
 cx_attr_export
@@ -263,7 +263,7 @@
  *
  * The @p width in bytes refers to the size and capacity.
  * Both must have the same width.
- * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64 bit
+ * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit
  * architecture. If set to zero, the native word width is used.
  *
  * @param array a pointer to the target array
@@ -296,7 +296,7 @@
  * The elements are copied to the @p target array at the specified @p index,
  * overwriting possible elements. The @p index does not need to be in range of
  * the current array @p size. If the new index plus the number of elements added
- * would extend the array's size, the remaining @p capacity is used.
+ * extends the array's size, the remaining @p capacity is used.
  *
  * If the @p capacity is also insufficient to hold the new data, a reallocation
  * attempt is made with the specified @p reallocator.
@@ -305,7 +305,7 @@
  *
  * The @p width in bytes refers to the size and capacity.
  * Both must have the same width.
- * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64 bit
+ * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit
  * architecture. If set to zero, the native word width is used.
  *
  * @param target a pointer to the target array
@@ -810,8 +810,8 @@
  *
  * @param arr the array
  * @param elem_size the element size
- * @param idx1 index of first element
- * @param idx2 index of second element
+ * @param idx1 index of the first element
+ * @param idx2 index of the second element
  */
 cx_attr_nonnull
 cx_attr_export
@@ -826,7 +826,7 @@
  * Allocates an array list for storing elements with @p elem_size bytes each.
  *
  * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
- * copies of the added elements and the compare function will be automatically set
+ * copies of the added elements, and the compare function will be automatically set
  * to cx_cmp_ptr(), if none is given.
  *
  * @param allocator the allocator for allocating the list memory
--- a/src/cx/buffer.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/buffer.h	Sun Oct 12 20:21:56 2025 +0200
@@ -62,7 +62,7 @@
  * If this flag is enabled, the buffer will automatically free its contents when destroyed.
  *
  * Do NOT set this flag together with #CX_BUFFER_COPY_ON_WRITE. It will be automatically
- * set when the copy-on-write operations is performed.
+ * set when the copy-on-write operation is performed.
  */
 #define CX_BUFFER_FREE_CONTENTS 0x01
 
@@ -74,7 +74,7 @@
 /**
  * If this flag is enabled, the buffer will allocate new memory when written to.
  *
- * The current contents of the buffer will be copied to the new memory and the flag
+ * The current contents of the buffer will be copied to the new memory, and the flag
  * will be cleared while the #CX_BUFFER_FREE_CONTENTS flag will be set automatically.
  */
 #define CX_BUFFER_COPY_ON_WRITE 0x04
@@ -127,7 +127,7 @@
     size_t blkmax;
 
     /**
-     * The target for write function.
+     * The target for the write function.
      */
     void *target;
 
@@ -202,7 +202,7 @@
  * you will need to cast the pointer, and you should set the
  * #CX_BUFFER_COPY_ON_WRITE flag.
  *
- * You need to set the size manually after initialization, if
+ * You need to set the size manually after initialization if
  * you provide @p space which already contains data.
  *
  * When you specify stack memory as @p space and decide to use
@@ -210,7 +210,7 @@
  * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the
  * #CX_BUFFER_AUTO_EXTEND flag.
  *
- * @note You may provide @c NULL as argument for @p space.
+ * @note You may provide @c NULL as the argument for @p space.
  * Then this function will allocate the space and enforce
  * the #CX_BUFFER_FREE_CONTENTS flag. In that case, specifying
  * copy-on-write should be avoided, because the allocated
@@ -276,9 +276,6 @@
  * If the #CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys
  * the contents. If you @em only want to destroy the contents, use cxBufferDestroy().
  *
- * @remark As with all free() functions, this accepts @c NULL arguments in which
- * case it does nothing.
- *
  * @param buffer the buffer to deallocate
  * @see cxBufferCreate()
  */
@@ -296,7 +293,7 @@
  * #CX_BUFFER_COPY_ON_EXTEND flag, instead of the
  * #CX_BUFFER_AUTO_EXTEND flag.
  *
- * @note You may provide @c NULL as argument for @p space.
+ * @note You may provide @c NULL as the argument for @p space.
  * Then this function will allocate the space and enforce
  * the #CX_BUFFER_FREE_CONTENTS flag.
  *
@@ -327,8 +324,8 @@
  * If auto extension is enabled, the buffer grows, if necessary.
  * In case the auto extension fails, this function returns a non-zero value and
  * no contents are changed.
- * If auto extension is disabled, the contents that do not fit into the buffer
- * are discarded.
+ * When the auto extension is disabled, the contents that do not fit into the
+ * buffer are discarded.
  *
  * If the offset is negative, the contents are shifted to the left where the
  * first @p shift bytes are discarded.
@@ -336,15 +333,15 @@
  * If this value is larger than the buffer size, the buffer is emptied (but
  * not cleared, see the security note below).
  *
- * The buffer position gets shifted alongside with the content but is kept
+ * The buffer position gets shifted alongside the content but is kept
  * within the boundaries of the buffer.
  *
  * @note For situations where @c off_t is not large enough, there are specialized cxBufferShiftLeft() and
- * cxBufferShiftRight() functions using a @c size_t as parameter type.
+ * cxBufferShiftRight() functions using a @c size_t as the parameter type.
  *
  * @attention
  * Security Note: The shifting operation does @em not erase the previously occupied memory cells.
- * But you can easily do that manually, e.g. by calling
+ * But you can do that manually by calling
  * <code>memset(buffer->bytes, 0, shift)</code> for a right shift or
  * <code>memset(buffer->bytes + buffer->size, 0, buffer->capacity - buffer->size)</code>
  * for a left shift.
@@ -517,7 +514,7 @@
  * Writes data to a CxBuffer.
  *
  * If automatic flushing is not enabled, the data is simply written into the
- * buffer at the current position and the position of the buffer is increased
+ * buffer at the current position, and the position of the buffer is increased
  * by the number of bytes written.
  *
  * If flushing is enabled and the buffer needs to flush, the data is flushed to
@@ -526,7 +523,7 @@
  * data in this buffer is shifted to the beginning of this buffer so that the
  * newly available space can be used to append as much data as possible.
  *
- * This function only stops writing more elements, when the flush target and this
+ * This function only stops writing more elements when the flush target and this
  * buffer are both incapable of taking more data or all data has been written.
  *
  * If, after flushing, the number of items that shall be written still exceeds
@@ -534,14 +531,14 @@
  * to the flush target, if possible.
  *
  * The number returned by this function is the number of elements from
- * @c ptr that could be written to either the flush target or the buffer
- * (so it does not include the number of items that had been already in the buffer
- * in were flushed during the process).
+ * @c ptr that could be written to either the flush target or the buffer.
+ * That means it does @em not include the number of items that were already in
+ * the buffer and were also flushed during the process.
  *
  * @attention
  * When @p size is larger than one and the contents of the buffer are not aligned
  * with @p size, flushing stops after all complete items have been flushed, leaving
- * the mis-aligned part in the buffer.
+ * the misaligned part in the buffer.
  * Afterward, this function only writes as many items as possible to the buffer.
  *
  * @note The signature is compatible with the fwrite() family of functions.
@@ -614,19 +611,19 @@
  * at position 200. The flush configuration is
  * @c blkmax=4 and @c blksize=64 .
  * Assume that the entire flush operation is successful.
- * All 200 bytes on the left hand-side from the current
+ * All 200 bytes on the left-hand-side from the current
  * position are written.
- * That means, the size of the buffer is now 140 and the
+ * That means the size of the buffer is now 140 and the
  * position is zero.
  *
  * @par Example 2
  * Same as Example 1, but now the @c blkmax is 1.
- * The size of the buffer is now 276 and the position is 136.
+ * The size of the buffer is now 276, and the position is 136.
  *
  * @par Example 3
  * Same as Example 1, but now assume the flush target
  * only accepts 100 bytes before returning zero.
- * That means, the flush operations manages to flush
+ * That means the flush operation manages to flush
  * one complete block and one partial block, ending
  * up with a buffer with size 240 and position 100.
  *
@@ -636,8 +633,8 @@
  * @remark When the buffer uses copy-on-write, the memory
  * is copied first, before attempting any flush.
  * This is, however, considered an erroneous use of the
- * buffer, because it does not make much sense to put
- * readonly data into an UCX buffer for flushing, instead
+ * buffer because it makes little sense to put
+ * readonly data into an UCX buffer for flushing instead
  * of writing it directly to the target.
  *
  * @param buffer the buffer
@@ -678,9 +675,9 @@
  * The least significant byte of the argument is written to the buffer. If the
  * end of the buffer is reached and #CX_BUFFER_AUTO_EXTEND feature is enabled,
  * the buffer capacity is extended by cxBufferMinimumCapacity(). If the feature
- * is disabled or buffer extension fails, @c EOF is returned.
+ * is disabled or the buffer extension fails, @c EOF is returned.
  *
- * On successful write, the position of the buffer is increased.
+ * On successful writing, the position of the buffer is increased.
  *
  * If you just want to write a null-terminator at the current position, you
  * should use cxBufferTerminate() instead.
@@ -688,7 +685,7 @@
  * @param buffer the buffer to write to
  * @param c the character to write
  * @return the byte that has been written or @c EOF when the end of the stream is
- * reached and automatic extension is not enabled or not possible
+ * reached, and automatic extension is not enabled or not possible
  * @see cxBufferTerminate()
  */
 cx_attr_nonnull
--- a/src/cx/collection.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/collection.h	Sun Oct 12 20:21:56 2025 +0200
@@ -142,8 +142,10 @@
 /**
  * Indicates whether the collection can guarantee that the stored elements are currently sorted.
  *
- * This may return false even when the elements are sorted.
- * It is totally up to the implementation of the collection whether it keeps track of the order of its elements.
+ * This may return @c false even when the elements are sorted.
+ * It is totally up to the implementation of the collection when to check if the elements are sorted.
+ * It is usually a good practice to establish this property as an invariant that does not need
+ * to be re-checked on certain operations.
  *
  * @param c a pointer to a struct that contains #CX_COLLECTION_BASE
  * @retval true if the elements are currently sorted wrt. the collection's compare function
--- a/src/cx/common.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/common.h	Sun Oct 12 20:21:56 2025 +0200
@@ -49,7 +49,7 @@
  * <a href="https://uap-core.de/hg/ucx">https://uap-core.de/hg/ucx</a>
  * </p>
  *
- * <h2>LICENCE</h2>
+ * <h2>LICENSE</h2>
  *
  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
  *
@@ -189,7 +189,7 @@
  */
 #define cx_attr_cstr_arg(idx)
 /**
- * No support for access attribute in clang.
+ * No support for the access attribute in clang.
  */
 #define cx_attr_access(mode, ...)
 #else
--- a/src/cx/compare.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/compare.h	Sun Oct 12 20:21:56 2025 +0200
@@ -47,7 +47,7 @@
  *
  * All functions from compare.h with the cx_cmp prefix are
  * compatible with this signature and can be used as
- * compare function for collections, or other implementations
+ * compare function for collections or other implementations
  * that need to be type-agnostic.
  *
  * For simple comparisons the cx_vcmp family of functions
--- a/src/cx/hash_key.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/hash_key.h	Sun Oct 12 20:21:56 2025 +0200
@@ -178,7 +178,7 @@
  * used for data exchange with different machines.
  *
  * @param obj a pointer to an arbitrary object
- * @param len the length of object in memory
+ * @param len the length of the object in memory
  * @return the hash key
  */
 cx_attr_nodiscard
--- a/src/cx/hash_map.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/hash_map.h	Sun Oct 12 20:21:56 2025 +0200
@@ -73,7 +73,8 @@
  * copies of the added elements.
  *
  * @note Iterators provided by this hash map implementation provide the remove operation.
- * The index value of an iterator is incremented when the iterator advanced without removal.
+ * The index value of an iterator is incremented when the iterator advanced without
+ * removing an entry.
  * In other words, when the iterator is finished, @c index==size .
  *
  * @param allocator the allocator to use
@@ -99,7 +100,8 @@
  * copies of the added elements.
  *
  * @note Iterators provided by this hash map implementation provide the remove operation.
- * The index value of an iterator is incremented when the iterator advanced without removal.
+ * The index value of an iterator is incremented when the iterator advanced without
+ * removing an entry.
  * In other words, when the iterator is finished, @c index==size .
  *
  * @param itemsize (@c size_t) the size of one element
@@ -111,10 +113,10 @@
  * Increases the number of buckets, if necessary.
  *
  * The load threshold is @c 0.75*buckets. If the element count exceeds the load
- * threshold, the map will be rehashed. Otherwise, no action is performed and
+ * threshold, the map will be rehashed. Otherwise, no action is performed, and
  * this function simply returns 0.
  *
- * The rehashing process ensures, that the number of buckets is at least
+ * The rehashing process ensures that the number of buckets is at least
  * 2.5 times the element count. So there is enough room for additional
  * elements without the need of another soon rehashing.
  *
--- a/src/cx/iterator.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/iterator.h	Sun Oct 12 20:21:56 2025 +0200
@@ -145,7 +145,7 @@
  * Iterator type.
  *
  * An iterator points to a certain element in a (possibly unbounded) chain of elements.
- * Iterators that are based on collections (which have a defined "first" element), are supposed
+ * Iterators that are based on collections (which have a defined "first" element) are supposed
  * to be "position-aware", which means that they keep track of the current index within the collection.
  *
  * @note Objects that are pointed to by an iterator are always mutable through that iterator. However,
@@ -182,7 +182,7 @@
 #define cxIteratorNext(iter) (iter).base.next(&iter)
 
 /**
- * Flags the current element for removal, if this iterator is mutating.
+ * Flags the current element for removal if this iterator is mutating.
  *
  * Does nothing for non-mutating iterators.
  *
@@ -214,7 +214,7 @@
 /**
  * Creates an iterator for the specified plain array.
  *
- * The @p array can be @c NULL in which case the iterator will be immediately
+ * The @p array can be @c NULL, in which case the iterator will be immediately
  * initialized such that #cxIteratorValid() returns @c false.
  *
  * This iterator yields the addresses of the array elements.
@@ -248,7 +248,7 @@
  * moving all subsequent elements by one. Usually, when the order of elements is
  * not important, this parameter should be set to @c false.
  *
- * The @p array can be @c NULL in which case the iterator will be immediately
+ * The @p array can be @c NULL, in which case the iterator will be immediately
  * initialized such that #cxIteratorValid() returns @c false.
  *
  *
@@ -272,9 +272,9 @@
  * Creates an iterator for the specified plain pointer array.
  *
  * This iterator assumes that every element in the array is a pointer
- * and yields exactly those pointers during iteration (while in contrast
- * an iterator created with cxIterator() would return the addresses
- * of those pointers within the array).
+ * and yields exactly those pointers during iteration (on the other
+ * hand, an iterator created with cxIterator() would return the
+ * addresses of those pointers within the array).
  *
  * @param array a pointer to the array (can be @c NULL)
  * @param elem_count the number of elements in the array
--- a/src/cx/json.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/json.h	Sun Oct 12 20:21:56 2025 +0200
@@ -90,11 +90,11 @@
      */
     CX_JSON_TOKEN_STRING,
     /**
-     * A number token that can be represented as integer.
+     * A number token that can be represented as an integer.
      */
     CX_JSON_TOKEN_INTEGER,
     /**
-     * A number token that cannot be represented as integer.
+     * A number token that cannot be represented as an integer.
      */
     CX_JSON_TOKEN_NUMBER,
     /**
@@ -196,11 +196,11 @@
  */
 typedef struct cx_mutstr_s CxJsonString;
 /**
- * Type alias for a number that can be represented as 64-bit signed integer.
+ * Type alias for a number that can be represented as a 64-bit signed integer.
  */
 typedef int64_t CxJsonInteger;
 /**
- * Type alias for number that is not an integer.
+ * Type alias for a number that is not an integer.
  */
 typedef double CxJsonNumber;
 /**
@@ -272,27 +272,27 @@
      */
     union {
         /**
-         * The array data if type is #CX_JSON_ARRAY.
+         * The array data if the type is #CX_JSON_ARRAY.
          */
         CxJsonArray array;
         /**
-         * The object data if type is #CX_JSON_OBJECT.
+         * The object data if the type is #CX_JSON_OBJECT.
          */
         CxJsonObject object;
         /**
-         * The string data if type is #CX_JSON_STRING.
+         * The string data if the type is #CX_JSON_STRING.
          */
         CxJsonString string;
         /**
-         * The integer if type is #CX_JSON_INTEGER.
+         * The integer if the type is #CX_JSON_INTEGER.
          */
         CxJsonInteger integer;
         /**
-         * The number if type is #CX_JSON_NUMBER.
+         * The number if the type is #CX_JSON_NUMBER.
          */
         CxJsonNumber number;
         /**
-         * The literal type if type is #CX_JSON_LITERAL.
+         * The literal type if the type is #CX_JSON_LITERAL.
          */
         CxJsonLiteral literal;
     } value;
@@ -377,7 +377,7 @@
 };
 
 /**
- * Status codes for the json interface.
+ * Status codes for the JSON interface.
  */
 enum cx_json_status {
     /**
@@ -391,7 +391,7 @@
     /**
      * The input ends unexpectedly.
      *
-     * Refill the buffer with cxJsonFill() to complete the json data.
+     * Refill the buffer with cxJsonFill() to complete the JSON data.
      */
     CX_JSON_INCOMPLETE_DATA,
     /**
@@ -400,7 +400,7 @@
      * You can use this enumerator to check for all "good" status results
      * by checking if the status is less than @c CX_JSON_OK.
      *
-     * A "good" status means, that you can refill data and continue parsing.
+     * A "good" status means that you can refill data and continue parsing.
      */
     CX_JSON_OK,
     /**
@@ -412,7 +412,7 @@
      */
     CX_JSON_BUFFER_ALLOC_FAILED,
     /**
-     * Allocating memory for a json value failed.
+     * Allocating memory for a JSON value failed.
      */
     CX_JSON_VALUE_ALLOC_FAILED,
     /**
@@ -426,7 +426,7 @@
 };
 
 /**
- * Typedef for the json status enum.
+ * Typedef for the JSON status enum.
  */
 typedef enum cx_json_status CxJsonStatus;
 
@@ -445,7 +445,7 @@
     /**
      * The maximum number of fractional digits in a number value.
      * The default value is 6 and values larger than 15 are reduced to 15.
-     * Note, that the actual number of digits may be lower, depending on the concrete number.
+     * Note that the actual number of digits may be lower, depending on the concrete number.
      */
     uint8_t frac_max_digits;
     /**
@@ -465,7 +465,7 @@
 };
 
 /**
- * Typedef for the json writer.
+ * Typedef for the JSON writer.
  */
 typedef struct cx_json_writer_s CxJsonWriter;
 
@@ -496,9 +496,8 @@
  * that the data is only partially written when an error occurs with no
  * way to indicate how much data was written.
  * To avoid this problem, you can use a CxBuffer as @p target which is
- * unlikely to fail a write operation and either use the buffer's flush
- * feature to relay the data or use the data in the buffer manually to
- * write it to the actual target.
+ * unlikely to fail a write operation. You can, for example, use the buffer's flush
+ * feature to relay the data.
  *
  * @param target the buffer or stream where to write to
  * @param value the value that shall be written
@@ -517,9 +516,9 @@
 );
 
 /**
- * Initializes the json interface.
+ * Initializes the JSON interface.
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @param allocator the allocator that shall be used for the produced values
  * @see cxJsonDestroy()
  */
@@ -528,9 +527,9 @@
 void cxJsonInit(CxJson *json, const CxAllocator *allocator);
 
 /**
- * Destroys the json interface.
+ * Destroys the JSON interface.
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @see cxJsonInit()
  */
 cx_attr_nonnull
@@ -538,12 +537,12 @@
 void cxJsonDestroy(CxJson *json);
 
 /**
- * Destroys and re-initializes the json interface.
+ * Destroys and re-initializes the JSON interface.
  *
- * You might want to use this, to reset the parser after
+ * You might want to use this to reset the parser after
  * encountering a syntax error.
  *
- * @param json the json interface
+ * @param json the JSON interface
  */
 cx_attr_nonnull
 static inline void cxJsonReset(CxJson *json) {
@@ -563,7 +562,7 @@
  * the additional data is appended - inevitably leading to
  * an allocation of a new buffer and copying the previous contents.
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @param buf the source buffer
  * @param len the length of the source buffer
  * @retval zero success
@@ -579,7 +578,7 @@
 /**
  * Internal function, do not use.
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @param str the string
  * @retval zero success
  * @retval non-zero internal allocation error
@@ -600,7 +599,7 @@
  * the additional data is appended - inevitably leading to
  * an allocation of a new buffer and copying the previous contents.
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @param str the source string
  * @retval zero success
  * @retval non-zero internal allocation error
@@ -917,8 +916,8 @@
  * Recursively deallocates the memory of a JSON value.
  *
  * @remark The type of each deallocated value will be changed
- * to #CX_JSON_NOTHING and values of such type will be skipped
- * by the de-allocation. That means, this function protects
+ * to #CX_JSON_NOTHING, and values of such a type will be skipped
+ * by the deallocation. That means this function protects
  * you from double-frees when you are accidentally freeing
  * a nested value and then the parent value (or vice versa).
  *
@@ -937,7 +936,7 @@
  * add the missing data with another invocation of cxJsonFill()
  * and then repeat the call to cxJsonNext().
  *
- * @param json the json interface
+ * @param json the JSON interface
  * @param value a pointer where the next value shall be stored
  * @retval CX_JSON_NO_ERROR successfully retrieve the @p value
  * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from
@@ -993,7 +992,7 @@
 /**
  * Checks if the specified value is a JSON number.
  *
- * This function will return true for both floating point and
+ * This function will return true for both floating-point and
  * integer numbers.
  *
  * @param value a pointer to the value
@@ -1053,7 +1052,7 @@
 /**
  * Checks if the specified value is @c true.
  *
- * @remark Be advised, that this is not the same as
+ * @remark Be advised that this is different from
  * testing @c !cxJsonIsFalse(v).
  *
  * @param value a pointer to the value
@@ -1070,7 +1069,7 @@
 /**
  * Checks if the specified value is @c false.
  *
- * @remark Be advised, that this is not the same as
+ * @remark Be advised that this is different from
  * testing @c !cxJsonIsTrue(v).
  *
  * @param value a pointer to the value
@@ -1141,7 +1140,7 @@
 }
 
 /**
- * Obtains a double-precision floating point value from the given JSON value.
+ * Obtains a double-precision floating-point value from the given JSON value.
  *
  * If the @p value is not a JSON number, the behavior is undefined.
  *
--- a/src/cx/kv_list.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/kv_list.h	Sun Oct 12 20:21:56 2025 +0200
@@ -49,7 +49,7 @@
  *
  * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
  * copies of the added elements, and the compare function will be automatically set
- * to cx_cmp_ptr(), if none is given.
+ * to cx_cmp_ptr() if none is given.
  *
  * After creating the list, it can also be used as a map after converting the pointer
  * to a CxMap pointer with cxKvListAsMap().
@@ -81,7 +81,7 @@
  *
  * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
  * copies of the added elements, and the compare function will be automatically set
- * to cx_cmp_ptr(), if none is given.
+ * to cx_cmp_ptr() if none is given.
  *
  * This function creates the list with cxKvListCreate() and immediately applies
  * cxKvListAsMap(). If you want to use the returned object as a list, you can call
--- a/src/cx/linked_list.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/linked_list.h	Sun Oct 12 20:21:56 2025 +0200
@@ -44,7 +44,7 @@
 #endif
 
 /**
- * Meta data for a linked list.
+ * Metadata for a linked list.
  */
 typedef struct cx_linked_list_s {
     /** Base members. */
@@ -79,8 +79,8 @@
  * Allocates a linked list for storing elements with @p elem_size bytes each.
  *
  * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
- * copies of the added elements and the compare function will be automatically set
- * to cx_cmp_ptr(), if none is given.
+ * copies of the added elements, and the compare function will be automatically set
+ * to cx_cmp_ptr() if none is given.
  *
  * @param allocator the allocator for allocating the list nodes
  * (if @c NULL, the cxDefaultAllocator will be used)
@@ -108,7 +108,7 @@
  * after list creation or use cxLinkedListCreate().
  *
  * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
- * copies of the added elements and the compare function will be automatically set
+ * copies of the added elements, and the compare function will be automatically set
  * to cx_cmp_ptr().
  *
  * @param elem_size (@c size_t) the size of each element in bytes
@@ -121,12 +121,12 @@
  * Finds the node at a certain index.
  *
  * This function can be used to start at an arbitrary position within the list.
- * If the search index is large than the start index, @p loc_advance must denote
- * the location of some sort of @c next pointer (i.e. a pointer to the next node).
+ * If the search index is larger than the start index, @p loc_advance must denote
+ * the location of a @c next pointer (i.e., a pointer to the next node).
  * But it is also possible that the search index is smaller than the start index
- * (e.g. in cases where traversing a list backwards is faster) in which case
- * @p loc_advance must denote the location of some sort of @c prev pointer
- * (i.e. a pointer to the previous node).
+ * (e.g., in cases where traversing a list backwards is faster).
+ * In that case @p loc_advance must denote the location of a @c prev pointer
+ * (i.e., a pointer to the previous node).
  *
  * @param start a pointer to the start node
  * @param start_index the start index
@@ -225,7 +225,7 @@
 
 /**
  * Adds a new node to a linked list.
- * The node must not be part of any list already.
+ * The node must not be part of any list yet.
  *
  * @remark One of the pointers @p begin or @p end may be @c NULL, but not both.
  *
@@ -247,7 +247,7 @@
 
 /**
  * Prepends a new node to a linked list.
- * The node must not be part of any list already.
+ * The node must not be part of any list yet.
  *
  * @remark One of the pointers @p begin or @p end may be @c NULL, but not both.
  *
@@ -305,7 +305,7 @@
 
 /**
  * Inserts a new node after a given node of a linked list.
- * The new node must not be part of any list already.
+ * The new node must not be part of any list yet.
  *
  * @note If you specify @c NULL as the @p node to insert after, this function needs either the @p begin or
  * the @p end pointer to determine the start of the list. Then the new node will be prepended to the list.
@@ -330,7 +330,7 @@
 
 /**
  * Inserts a chain of nodes after a given node of a linked list.
- * The chain must not be part of any list already.
+ * The chain must not be part of any list yet.
  *
  * If you do not explicitly specify the end of the chain, it will be determined by traversing
  * the @c next pointer.
@@ -362,7 +362,7 @@
 
 /**
  * Inserts a node into a sorted linked list.
- * The new node must not be part of any list already.
+ * The new node must not be part of any list yet.
  *
  * If the list starting with the node pointed to by @p begin is not sorted
  * already, the behavior is undefined.
@@ -394,7 +394,7 @@
  *
  * @attention In contrast to cx_linked_list_insert_chain(), the source chain
  * will be broken and inserted into the target list so that the resulting list
- * will be sorted according to @p cmp_func. That means, each node in the source
+ * will be sorted according to @p cmp_func. That means each node in the source
  * chain may be re-linked with nodes from the target list.
  *
  * @param begin a pointer to the beginning node pointer (required)
@@ -475,7 +475,7 @@
 /**
  * Removes a chain of nodes from the linked list.
  *
- * If one of the nodes to remove is the beginning (resp. end) node of the list and if @p begin (resp. @p end)
+ * If one of the nodes to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end)
  * addresses are provided, the pointers are adjusted accordingly.
  *
  * The following combinations of arguments are valid (more arguments are optional):
@@ -507,7 +507,7 @@
 /**
  * Removes a node from the linked list.
  *
- * If the node to remove is the beginning (resp. end) node of the list and if @p begin (resp. @p end)
+ * If the node to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end)
  * addresses are provided, the pointers are adjusted accordingly.
  *
  * The following combinations of arguments are valid (more arguments are optional):
@@ -585,7 +585,7 @@
 /**
  * Compares two lists element wise.
  *
- * @attention Both list must have the same structure.
+ * @attention Both lists must have the same structure.
  *
  * @param begin_left the beginning of the left list (@c NULL denotes an empty list)
  * @param begin_right the beginning of the right list  (@c NULL denotes an empty list)
--- a/src/cx/list.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/list.h	Sun Oct 12 20:21:56 2025 +0200
@@ -82,7 +82,7 @@
 
     /**
      * Member function for inserting a single element.
-     * The data pointer may be @c NULL in which case the function shall only allocate memory.
+     * The data pointer may be @c NULL, in which case the function shall only allocate memory.
      * Returns a pointer to the allocated memory or @c NULL if allocation fails.
      */
     void *(*insert_element)(
@@ -194,7 +194,7 @@
     /**
      * Optional member function for comparing this list
      * to another list of the same type.
-     * If set to @c NULL, comparison won't be optimized.
+     * If set to @c NULL, the comparison won't be optimized.
      */
     int (*compare)(
             const struct cx_list_s *list,
@@ -226,7 +226,7 @@
  *
  * Writing to that list is not allowed.
  *
- * You can use this is a placeholder for initializing CxList pointers
+ * You can use this as a placeholder for initializing CxList pointers
  * for which you do not want to reserve memory right from the beginning.
  */
 cx_attr_export
@@ -340,12 +340,12 @@
  *
  * Only use this function if you are creating your own list implementation.
  * The purpose of this function is to be called in the initialization code
- * of your list, to set certain members correctly.
+ * of your list to set certain members correctly.
  *
  * This is particularly important when you want your list to support
  * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list
  * class accordingly and make sure that you can implement your list as if
- * it was only storing objects and the wrapper will automatically enable
+ * it was only storing objects, and the wrapper will automatically enable
  * the feature of storing pointers.
  *
  * @par Example
@@ -427,7 +427,7 @@
  * If there is not enough memory to add all elements, the returned value is
  * less than @p n.
  *
- * If this list is storing pointers instead of objects @p array is expected to
+ * If this list is storing pointers instead of objects, @p array is expected to
  * be an array of pointers.
  *
  * @param list the list
@@ -448,7 +448,7 @@
 /**
  * Inserts an item at the specified index.
  *
- * If @p index equals the list @c size, this is effectively cxListAdd().
+ * If the @p index equals the list @c size, this is effectively cxListAdd().
  *
  * @param list the list
  * @param index the index the element shall have
@@ -547,7 +547,7 @@
 
 /**
  * Inserts multiple items to the list at the specified index.
- * If @p index equals the list size, this is effectively cxListAddArray().
+ * If the @p index equals the list size, this is effectively cxListAddArray().
  *
  * This method is usually more efficient than invoking cxListInsert()
  * multiple times.
@@ -555,7 +555,7 @@
  * If there is not enough memory to add all elements, the returned value is
  * less than @p n.
  *
- * If this list is storing pointers instead of objects @p array is expected to
+ * If this list is storing pointers instead of objects, @p array is expected to
  * be an array of pointers.
  *
  * @param list the list
@@ -584,7 +584,7 @@
  * If there is not enough memory to add all elements, the returned value is
  * less than @p n.
  *
- * If this list is storing pointers instead of objects @p array is expected to
+ * If this list is storing pointers instead of objects, @p array is expected to
  * be an array of pointers.
  *
  * If the list is not sorted already, the behavior is undefined.
@@ -748,7 +748,7 @@
  * @param list the list
  * @param targetbuf a buffer where to copy the element
  * @retval zero success
- * @retval non-zero list is empty
+ * @retval non-zero the list is empty
  * @see cxListPopFront()
  * @see cxListRemoveAndGetLast()
  */
@@ -773,7 +773,7 @@
  * @param list (@c CxList*) the list
  * @param targetbuf (@c void*) a buffer where to copy the element
  * @retval zero success
- * @retval non-zero list is empty
+ * @retval non-zero the list is empty
  * @see cxListRemoveAndGetFirst()
  * @see cxListPop()
  */
@@ -790,7 +790,7 @@
  * @param list the list
  * @param targetbuf a buffer where to copy the element
  * @retval zero success
- * @retval non-zero list is empty
+ * @retval non-zero the list is empty
  */
 cx_attr_nonnull
 cx_attr_access_w(2)
@@ -814,7 +814,7 @@
  * @param list (@c CxList*) the list
  * @param targetbuf (@c void*) a buffer where to copy the element
  * @retval zero success
- * @retval non-zero list is empty
+ * @retval non-zero the list is empty
  * @see cxListRemoveAndGetLast()
  * @see cxListPopFront()
  */
@@ -1128,7 +1128,7 @@
 }
 
 /**
- * Checks, if the list contains the specified element.
+ * Checks if the list contains the specified element.
  *
  * The elements are compared with the list's comparator function.
  *
@@ -1233,7 +1233,7 @@
  *
  * Also calls the content destructor functions for each element, if specified.
  *
- * @param list the list which shall be freed
+ * @param list the list that shall be freed
  */
 cx_attr_export
 void cxListFree(CxList *list);
--- a/src/cx/map.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/map.h	Sun Oct 12 20:21:56 2025 +0200
@@ -230,7 +230,7 @@
  *
  * Writing to that map is not allowed.
  *
- * You can use this is a placeholder for initializing CxMap pointers
+ * You can use this as a placeholder for initializing CxMap pointers
  * for which you do not want to reserve memory right from the beginning.
  */
 cx_attr_export
@@ -292,7 +292,7 @@
 /**
  * Creates a key iterator for a map.
  *
- * The elements of the iterator are keys of type CxHashKey and the pointer returned
+ * The elements of the iterator are keys of type CxHashKey, and the pointer returned
  * during iterator shall be treated as @c const @c CxHashKey* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
@@ -310,7 +310,7 @@
 /**
  * Creates an iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
+ * The elements of the iterator are key/value pairs of type CxMapEntry, and the pointer returned
  * during iterator shall be treated as @c const @c CxMapEntry* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
@@ -348,7 +348,7 @@
 /**
  * Creates a mutating iterator over the keys of a map.
  *
- * The elements of the iterator are keys of type CxHashKey and the pointer returned
+ * The elements of the iterator are keys of type CxHashKey, and the pointer returned
  * during iterator shall be treated as @c const @c CxHashKey* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
@@ -364,7 +364,7 @@
 /**
  * Creates a mutating iterator for a map.
  *
- * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
+ * The elements of the iterator are key/value pairs of type CxMapEntry, and the pointer returned
  * during iterator shall be treated as @c const @c CxMapEntry* .
  *
  * @note An iterator iterates over all elements successively. Therefore, the order
@@ -516,7 +516,7 @@
 /**
  * Removes a key/value-pair from the map by using the key.
  *
- * Invokes the destructor functions, if any, on the removed element, if and only if the
+ * Invokes the destructor functions, if any, on the removed element if and only if the
  * @p targetbuf is @c NULL.
  *
  * @param map the map
--- a/src/cx/printf.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/printf.h	Sun Oct 12 20:21:56 2025 +0200
@@ -27,7 +27,7 @@
  */
 /**
  * @file printf.h
- * @brief Wrapper for write functions with a printf-like interface.
+ * @brief Wrapper for write-functions with a printf-like interface.
  * @author Mike Becker
  * @author Olaf Wintermann
  * @copyright 2-Clause BSD License
@@ -102,7 +102,7 @@
 );
 
 /**
- * A @c asprintf like function which allocates space for a string
+ * An @c asprintf like function which allocates space for a string
  * the result is written to.
  *
  * @note The resulting string is guaranteed to be zero-terminated,
@@ -126,7 +126,7 @@
 );
 
 /**
- * A @c asprintf like function which allocates space for a string
+ * An @c asprintf like function which allocates space for a string
  * the result is written to.
  *
  * @note The resulting string is guaranteed to be zero-terminated,
@@ -169,7 +169,7 @@
  * the result is written to.
  *
  * @note The resulting string is guaranteed to be zero-terminated,
- * unless there was in error, in which case the string's pointer
+ * unless there was an error, in which case the string's pointer
  * will be @c NULL.
  *
  * @param fmt (@c char*) format string
@@ -204,7 +204,7 @@
  * @param len (@c size_t*) a pointer to the length of the buffer
  * @param fmt (@c char*) the format string
  * @param ... additional arguments
- * @return (@c int) the length of produced string or an error code from stdlib printf implementation
+ * @return (@c int) the length of the produced string or an error code from stdlib printf implementation
  */
 #define cx_sprintf(str, len, fmt, ...) cx_sprintf_a(cxDefaultAllocator, str, len, fmt, __VA_ARGS__)
 
@@ -222,7 +222,7 @@
  * @param len a pointer to the length of the buffer
  * @param fmt the format string
  * @param ... additional arguments
- * @return the length of produced string or an error code from stdlib printf implementation
+ * @return the length of the produced string or an error code from stdlib printf implementation
  */
 cx_attr_nonnull_arg(1, 2, 3, 4)
 cx_attr_printf(4, 5)
@@ -248,7 +248,7 @@
  * @param len (@c size_t*) a pointer to the length of the buffer
  * @param fmt (@c char*) the format string
  * @param ap (@c va_list) argument list
- * @return (@c int) the length of produced string or an error code from stdlib printf implementation
+ * @return (@c int) the length of the produced string or an error code from stdlib printf implementation
  */
 #define cx_vsprintf(str, len, fmt, ap) cx_vsprintf_a(cxDefaultAllocator, str, len, fmt, ap)
 
@@ -266,7 +266,7 @@
  * @param len a pointer to the length of the buffer
  * @param fmt the format string
  * @param ap argument list
- * @return the length of produced string or an error code from stdlib printf implementation
+ * @return the length of the produced string or an error code from stdlib printf implementation
  */
 cx_attr_nonnull
 cx_attr_cstr_arg(4)
@@ -300,7 +300,7 @@
  * @param str (@c char**) a pointer where the location of the result shall be stored
  * @param fmt (@c char*) the format string
  * @param ... additional arguments
- * @return (@c int) the length of produced string or an error code from stdlib printf implementation
+ * @return (@c int) the length of the produced string or an error code from stdlib printf implementation
  */
 #define cx_sprintf_s(buf, len, str, fmt, ...) cx_sprintf_sa(cxDefaultAllocator, buf, len, str, fmt, __VA_ARGS__)
 
@@ -323,7 +323,7 @@
  * @param str a pointer where the location of the result shall be stored
  * @param fmt the format string
  * @param ... additional arguments
- * @return the length of produced string or an error code from stdlib printf implementation
+ * @return the length of the produced string or an error code from stdlib printf implementation
  */
 cx_attr_nonnull_arg(1, 2, 4, 5)
 cx_attr_printf(5, 6)
@@ -359,7 +359,7 @@
  * @param str (@c char**) a pointer where the location of the result shall be stored
  * @param fmt (@c char*) the format string
  * @param ap (@c va_list) argument list
- * @return (@c int) the length of produced string or an error code from stdlib printf implementation
+ * @return (@c int) the length of the produced string or an error code from stdlib printf implementation
  */
 #define cx_vsprintf_s(buf, len, str, fmt, ap) cx_vsprintf_sa(cxDefaultAllocator, buf, len, str, fmt, ap)
 
@@ -382,7 +382,7 @@
  * @param str a pointer where the location of the result shall be stored
  * @param fmt the format string
  * @param ap argument list
- * @return the length of produced string or an error code from stdlib printf implementation
+ * @return the length of the produced string or an error code from stdlib printf implementation
  */
 cx_attr_nonnull
 cx_attr_cstr_arg(5)
--- a/src/cx/properties.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/properties.h	Sun Oct 12 20:21:56 2025 +0200
@@ -122,7 +122,7 @@
      * You can use this enumerator to check for all "good" status results
      * by checking if the status is less than @c CX_PROPERTIES_OK.
      *
-     * A "good" status means, that you can refill data and continue parsing.
+     * A "good" status means that you can refill data and continue parsing.
      */
     CX_PROPERTIES_OK,
     /**
@@ -130,11 +130,11 @@
      */
     CX_PROPERTIES_NULL_INPUT,
     /**
-     * The line contains a delimiter, but no key.
+     * The line contains a delimiter but no key.
      */
     CX_PROPERTIES_INVALID_EMPTY_KEY,
     /**
-     * The line contains data, but no delimiter.
+     * The line contains data but no delimiter.
      */
     CX_PROPERTIES_INVALID_MISSING_DELIMITER,
     /**
@@ -200,7 +200,7 @@
 /**
  * A function that consumes a k/v-pair in a sink.
  *
- * The sink could be e.g. a map and the sink function would be calling
+ * The sink could be a map, and the sink function would be calling
  * a map function to store the k/v-pair.
  *
  * @param prop the properties interface that wants to sink a k/v-pair
@@ -297,7 +297,7 @@
     /**
      * The source object.
      *
-     * For example a file stream or a string.
+     * For example, a file stream or a string.
      */
     void *src;
     /**
@@ -339,9 +339,9 @@
  *
  * @note Even when you are certain that you did not use the interface in a
  * way that caused a memory allocation, you should call this function anyway.
- * Future versions of the library might add features that need additional memory
- * and you really don't want to search the entire code where you might need
- * add call to this function.
+ * Future versions of the library might add features that need additional memory,
+ * and you really don't want to search the entire code where you might need to
+ * add a call to this function.
  *
  * @param prop the properties interface
  */
@@ -352,7 +352,7 @@
 /**
  * Destroys and re-initializes the properties interface.
  *
- * You might want to use this, to reset the parser after
+ * You might want to use this to reset the parser after
  * encountering a syntax error.
  *
  * @param prop the properties interface
@@ -442,7 +442,7 @@
 #define cxPropertiesFill(prop, str) cx_properties_fill(prop, cx_strcast(str))
 
 /**
- * Specifies stack memory that shall be used as internal buffer.
+ * Specifies stack memory that shall be used as an internal buffer.
  *
  * @param prop the properties interface
  * @param buf a pointer to stack memory
--- a/src/cx/streams.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/streams.h	Sun Oct 12 20:21:56 2025 +0200
@@ -54,7 +54,7 @@
  * @param wfnc the write function
  * @param buf a pointer to the copy buffer or @c NULL if a buffer
  * shall be implicitly created on the heap
- * @param bufsize the size of the copy buffer - if @p buf is @c NULL you can
+ * @param bufsize the size of the copy buffer - if @p buf is @c NULL, you can
  * set this to zero to let the implementation decide
  * @param n the maximum number of bytes that shall be copied.
  * If this is larger than @p bufsize, the content is copied over multiple
@@ -86,7 +86,7 @@
  * @param buf (@c char*) a pointer to the copy buffer or @c NULL if a buffer
  * shall be implicitly created on the heap
  * @param bufsize (@c size_t) the size of the copy buffer - if @p buf is
- * @c NULL you can set this to zero to let the implementation decide
+ * @c NULL, you can set this to zero to let the implementation decide
  * @return total number of bytes copied
  */
 #define cx_stream_bcopy(src, dest, rfnc, wfnc, buf, bufsize) \
@@ -95,7 +95,7 @@
 /**
  * Reads data from a stream and writes it to another stream.
  *
- * The data is temporarily stored in a stack allocated buffer.
+ * The data is temporarily stored in a stack-allocated buffer.
  *
  * @param src the source stream
  * @param dest the destination stream
@@ -119,7 +119,7 @@
 /**
  * Reads data from a stream and writes it to another stream.
  *
- * The data is temporarily stored in a stack allocated buffer.
+ * The data is temporarily stored in a stack-allocated buffer.
  *
  * @param src (@c void*) the source stream
  * @param dest (@c void*) the destination stream
--- a/src/cx/string.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/string.h	Sun Oct 12 20:21:56 2025 +0200
@@ -112,10 +112,10 @@
      */
     size_t pos;
     /**
-     * Position of next delimiter in the source string.
+     * Position of the next delimiter in the source string.
      *
      * If the tokenizer has not yet returned a token, the content of this field
-     * is undefined. If the tokenizer reached the end of the string, this field
+     * is undefined. If the tokenizer reaches the end of the string, this field
      * contains the length of the source string.
      */
     size_t delim_pos;
@@ -174,7 +174,7 @@
  *
  * If you need to wrap a constant string, use cx_str().
  *
- * @param cstring the string to wrap, must be zero-terminated
+ * @param cstring the string to wrap (must be zero-terminated)
  * @return the wrapped string
  *
  * @see cx_mutstrn()
@@ -220,7 +220,7 @@
  *
  * If you need to wrap a non-constant string, use cx_mutstr().
  *
- * @param cstring the string to wrap, must be zero-terminated
+ * @param cstring the string to wrap (must be zero-terminated)
  * @return the wrapped string
  *
  * @see cx_strn()
@@ -321,12 +321,12 @@
 /**
  * Passes the pointer in this string to the cxDefaultAllocator's @c free() function.
  *
- * The pointer in the struct is set to @c NULL and the length is set to zero
+ * The pointer in the struct is set to @c NULL, and the length is set to zero,
  * which means that this function protects you against double-free.
  *
  * @note There is no implementation for cxstring, because it is unlikely that
  * you ever have a <code>const char*</code> you are really supposed to free.
- * If you encounter such situation, you should double-check your code.
+ * If you encounter such a situation, you should double-check your code.
  *
  * @param str the string to free
  */
@@ -334,14 +334,14 @@
 void cx_strfree(cxmutstr *str);
 
 /**
- * Passes the pointer in this string to the allocators free function.
+ * Passes the pointer in this string to the allocator's free function.
  *
- * The pointer in the struct is set to @c NULL and the length is set to zero
+ * The pointer in the struct is set to @c NULL, and the length is set to zero,
  * which means that this function protects you against double-free.
  *
  * @note There is no implementation for cxstring, because it is unlikely that
  * you ever have a <code>const char*</code> you are really supposed to free.
- * If you encounter such situation, you should double-check your code.
+ * If you encounter such a situation, you should double-check your code.
  *
  * @param alloc the allocator
  * @param str the string to free
@@ -983,7 +983,7 @@
 cxmutstr cx_strtrim_m(cxmutstr string);
 
 /**
- * Checks, if a string has a specific prefix.
+ * Checks if a string has a specific prefix.
  *
  * @param string the string to check
  * @param prefix the prefix the string should have
@@ -998,7 +998,7 @@
 );
 
 /**
- * Checks, if a string has a specific suffix.
+ * Checks if a string has a specific suffix.
  *
  * @param string the string to check
  * @param suffix the suffix the string should have
@@ -1013,7 +1013,7 @@
 );
 
 /**
- * Checks, if a string has a specific prefix, ignoring the case.
+ * Checks if a string has a specific prefix, ignoring the case.
  *
  * @param string the string to check
  * @param prefix the prefix the string should have
@@ -1045,7 +1045,7 @@
 /**
  * Replaces a string with another string.
  *
- * Replaces at most @p replmax occurrences.
+ * The function replaces at most @p replmax occurrences.
  *
  * The returned string will be allocated by @p allocator and is guaranteed
  * to be zero-terminated.
@@ -1074,7 +1074,7 @@
 /**
  * Replaces a string with another string.
  *
- * Replaces at most @p replmax occurrences.
+ * The function replaces at most @p replmax occurrences.
  *
  * The returned string will be allocated by the cxDefaultAllocator and is guaranteed
  * to be zero-terminated.
@@ -1225,7 +1225,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1242,7 +1242,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1259,7 +1259,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1276,7 +1276,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1293,7 +1293,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1310,7 +1310,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1327,7 +1327,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1344,7 +1344,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1361,7 +1361,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1378,7 +1378,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1395,7 +1395,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1412,7 +1412,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1429,7 +1429,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1446,7 +1446,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1463,7 +1463,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1480,7 +1480,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1497,7 +1497,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1505,7 +1505,7 @@
 int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep);
 
 /**
- * Converts a string to a single precision floating point number.
+ * Converts a string to a single precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
@@ -1514,7 +1514,7 @@
  * @param str the string to convert
  * @param output a pointer to the float variable where the result shall be stored
  * @param decsep the decimal separator
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1522,7 +1522,7 @@
 int cx_strtof_lc_(cxstring str, float *output, char decsep, const char *groupsep);
 
 /**
- * Converts a string to a double precision floating point number.
+ * Converts a string to a double precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
@@ -1531,7 +1531,7 @@
  * @param str the string to convert
  * @param output a pointer to the float variable where the result shall be stored
  * @param decsep the decimal separator
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1548,7 +1548,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1564,7 +1564,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1580,7 +1580,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1596,7 +1596,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1612,7 +1612,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1628,7 +1628,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1644,7 +1644,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1660,7 +1660,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1676,7 +1676,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1692,7 +1692,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1708,7 +1708,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1724,7 +1724,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1740,7 +1740,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1756,7 +1756,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1772,7 +1772,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1788,7 +1788,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1804,7 +1804,7 @@
  * @param str the string to convert
  * @param output a pointer to the integer variable where the result shall be stored
  * @param base 2, 8, 10, or 16
- * @param groupsep (@c const @c char*) each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
@@ -1817,7 +1817,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1835,7 +1835,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1853,7 +1853,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1871,7 +1871,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1889,7 +1889,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1907,7 +1907,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1925,7 +1925,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1943,7 +1943,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1961,7 +1961,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1979,7 +1979,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -1997,7 +1997,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2015,7 +2015,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2033,7 +2033,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2051,7 +2051,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2069,7 +2069,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2087,7 +2087,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2105,7 +2105,7 @@
  * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base.
  * It sets errno to ERANGE when the target datatype is too small.
  *
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()).
  *
  * @param str the string to convert
@@ -2117,7 +2117,7 @@
 #define cx_strtou64(str, output, base) cx_strtou64_lc_(cx_strcast(str), output, base, ",")
 
 /**
- * Converts a string to a single precision floating point number.
+ * Converts a string to a single precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
@@ -2126,14 +2126,14 @@
  * @param str the string to convert
  * @param output a pointer to the float variable where the result shall be stored
  * @param decsep the decimal separator
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
 #define cx_strtof_lc(str, output, decsep, groupsep) cx_strtof_lc_(cx_strcast(str), output, decsep, groupsep)
 
 /**
- * Converts a string to a double precision floating point number.
+ * Converts a string to a double precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
@@ -2141,21 +2141,21 @@
  * @param str the string to convert
  * @param output a pointer to the double variable where the result shall be stored
  * @param decsep the decimal separator
- * @param groupsep each character in this string is treated as group separator and ignored during conversion
+ * @param groupsep each character in this string is treated as a group separator and ignored during conversion
  * @retval zero success
  * @retval non-zero conversion was not possible
  */
 #define cx_strtod_lc(str, output, decsep, groupsep) cx_strtod_lc_(cx_strcast(str), output, decsep, groupsep)
 
 /**
- * Converts a string to a single precision floating point number.
+ * Converts a string to a single precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
  * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h.
  *
  * The decimal separator is assumed to be a dot character.
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose a different format, use cx_strtof_lc().
  *
  * @param str the string to convert
@@ -2166,13 +2166,13 @@
 #define cx_strtof(str, output) cx_strtof_lc_(cx_strcast(str), output, '.', ",")
 
 /**
- * Converts a string to a double precision floating point number.
+ * Converts a string to a double precision floating-point number.
  *
  * The function returns non-zero when conversion is not possible.
  * In that case the function sets errno to EINVAL when the reason is an invalid character.
  *
  * The decimal separator is assumed to be a dot character.
- * The comma character is treated as group separator and ignored during parsing.
+ * The comma character is treated as a group separator and ignored during parsing.
  * If you want to choose a different format, use cx_strtof_lc().
  *
  * @param str the string to convert
--- a/src/cx/test.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/test.h	Sun Oct 12 20:21:56 2025 +0200
@@ -56,7 +56,7 @@
  * }
  * </code>
  * 
- * @attention Do not call own functions within a test, that use
+ * @attention Do not call own functions within a test that use
  * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE().
  *
  * @author Mike Becker
@@ -171,7 +171,7 @@
 /**
  * Registers a test function with the specified test suite.
  * 
- * @param suite the suite, the test function shall be added to
+ * @param suite the suite the test function shall be added to
  * @param test the test function to register
  * @retval zero success
  * @retval non-zero failure
@@ -263,7 +263,7 @@
  * }
  * @endcode
  *
- * @attention Any CX_TEST_ASSERT() calls must be performed in scope of
+ * @attention Any CX_TEST_ASSERT() calls must be performed in the scope of
  * #CX_TEST_DO.
  */
 #define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\
--- a/src/cx/tree.h	Sat Oct 11 15:42:48 2025 +0200
+++ b/src/cx/tree.h	Sun Oct 12 20:21:56 2025 +0200
@@ -49,12 +49,12 @@
  *
  * This iterator is not position-aware in a strict sense, as it does not assume
  * a particular order of elements in the tree. However, the iterator keeps track
- * of the number of nodes it has passed in a counter variable.
+ * of the number of nodes it has passed in a counter-variable.
  * Each node, regardless of the number of passes, is counted only once.
  *
  * @note Objects that are pointed to by an iterator are mutable through that
  * iterator. However, if the
- * underlying data structure is mutated by other means than this iterator (e.g.
+ * underlying data structure is mutated by other means than this iterator (e.g.,
  * elements added or removed), the iterator becomes invalid (regardless of what
  * cxIteratorValid() returns).
  *
@@ -71,7 +71,7 @@
     bool skip;
     /**
      * Set to true, when the iterator shall visit a node again
-     * when all it's children have been processed.
+     * when all its children have been processed.
      */
     bool visit_on_exit;
     /**
@@ -97,7 +97,7 @@
      */
     void *node;
     /**
-     * Stores a copy of the next pointer of the visited node.
+     * Stores a copy of the pointer to the successor of the visited node.
      * Allows freeing a node on exit without corrupting the iteration.
      */
     void *node_next;
@@ -155,12 +155,12 @@
  *
  * This iterator is not position-aware in a strict sense, as it does not assume
  * a particular order of elements in the tree. However, the iterator keeps track
- * of the number of nodes it has passed in a counter variable.
+ * of the number of nodes it has passed in a counter-variable.
  * Each node, regardless of the number of passes, is counted only once.
  *
  * @note Objects that are pointed to by an iterator are mutable through that
  * iterator. However, if the
- * underlying data structure is mutated by other means than this iterator (e.g.
+ * underlying data structure is mutated by other means than this iterator (e.g.,
  * elements added or removed), the iterator becomes invalid (regardless of what
  * cxIteratorValid() returns).
  *
@@ -250,7 +250,7 @@
 /**
  * Links a node to a (new) parent.
  *
- * If the node has already a parent, it is unlinked, first.
+ * If the node already has a parent, it is unlinked, first.
  * If the parent has children already, the node is @em appended to the list
  * of all currently existing children.
  *
@@ -318,8 +318,8 @@
  * Zero means exact match and a positive number is an implementation defined
  * measure for the distance to an exact match.
  *
- * For example if a tree stores file path information, a node that is
- * describing a parent directory of a filename that is searched, shall
+ * For example, consider a tree that stores file path information.
+ * A node which is describing a parent directory of a searched file shall
  * return a positive number to indicate that a child node might contain the
  * searched item. On the other hand, if the node denotes a path that is not a
  * prefix of the searched filename, the function would return -1 to indicate
@@ -330,7 +330,7 @@
  *
  * @return 0 if the node contains the data,
  * positive if one of the children might contain the data,
- * negative if neither the node, nor the children contains the data
+ * negative if neither the node nor the children contains the data
  */
 cx_attr_nonnull
 typedef int (*cx_tree_search_data_func)(const void *node, const void *data);
@@ -348,8 +348,8 @@
  * Zero means exact match and a positive number is an implementation defined
  * measure for the distance to an exact match.
  *
- * For example if a tree stores file path information, a node that is
- * describing a parent directory of a filename that is searched, shall
+ * For example, consider a tree that stores file path information.
+ * A node which is describing a parent directory of a searched file shall
  * return a positive number to indicate that a child node might contain the
  * searched item. On the other hand, if the node denotes a path that is not a
  * prefix of the searched filename, the function would return -1 to indicate
@@ -360,7 +360,7 @@
  *
  * @return 0 if @p node contains the same data as @p new_node,
  * positive if one of the children might contain the data,
- * negative if neither the node, nor the children contains the data
+ * negative if neither the node nor the children contains the data
  */
 cx_attr_nonnull
 typedef int (*cx_tree_search_func)(const void *node, const void *new_node);
@@ -368,11 +368,11 @@
 /**
  * Searches for data in a tree.
  *
- * When the data cannot be found exactly, the search function might return a
- * closest result which might be a good starting point for adding a new node
+ * When the data cannot be found exactly, the search function might return the
+ * closest result, which might be a good starting point for adding a new node
  * to the tree (see also #cx_tree_add()).
  *
- * Depending on the tree structure it is not necessarily guaranteed that the
+ * Depending on the tree structure, it is not necessarily guaranteed that the
  * "closest" match is uniquely defined. This function will search for a node
  * with the best match according to the @p sfunc (meaning: the return value of
  * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
@@ -406,10 +406,10 @@
  * Searches for a node in a tree.
  *
  * When no node with the same data can be found, the search function might
- * return a closest result which might be a good starting point for adding the
+ * return the closest result, which might be a good starting point for adding the
  * new node to the tree (see also #cx_tree_add()).
  *
- * Depending on the tree structure it is not necessarily guaranteed that the
+ * Depending on the tree structure, it is not necessarily guaranteed that the
  * "closest" match is uniquely defined. This function will search for a node
  * with the best match according to the @p sfunc (meaning: the return value of
  * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
@@ -496,8 +496,8 @@
 
 /**
  * Describes a function that creates a tree node from the specified data.
- * The first argument points to the data the node shall contain and
- * the second argument may be used for additional data (e.g. an allocator).
+ * The first argument points to the data the node shall contain, and
+ * the second argument may be used for additional data (e.g., an allocator).
  * Functions of this type shall either return a new pointer to a newly
  * created node or @c NULL when allocation fails.
  *
@@ -637,17 +637,17 @@
  * When a location is found, the @p cfunc will be invoked with @p cdata.
  *
  * The node returned by @p cfunc will be linked into the tree.
- * When @p sfunc returned a positive integer, the new node will be linked as a
+ * When @p sfunc returns a positive integer, the new node will be linked as a
  * child. The other children (now siblings of the new node) are then checked
  * with @p sfunc, whether they could be children of the new node and re-linked
  * accordingly.
  *
- * When @p sfunc returned zero and the found node has a parent, the new
- * node will be added as sibling - otherwise, the new node will be added
+ * When @p sfunc returns zero and the found node has a parent, the new
+ * node will be added as a sibling - otherwise, the new node will be added
  * as a child.
  *
- * When @p sfunc returned a negative value, the new node will not be added to
- * the tree and this function returns a non-zero value.
+ * When @p sfunc returns a negative value, the new node will not be added to
+ * the tree, and this function returns a non-zero value.
  * The caller should check if @p cnode contains a node pointer and deal with the
  * node that could not be added.
  *
@@ -747,9 +747,9 @@
      * A function to create new nodes.
      *
      * Invocations to this function will receive a pointer to this tree
-     * structure as second argument.
+     * structure as the second argument.
      *
-     * Nodes MAY use #cx_tree_node_base_s as base layout, but do not need to.
+     * Nodes MAY use #cx_tree_node_base_s as the base layout, but do not need to.
      */
     cx_tree_node_create_func node_create;
 
@@ -814,7 +814,7 @@
  * Macro to roll out the #cx_tree_node_base_s structure with a custom
  * node type.
  *
- * Must be used as first member in your custom tree struct.
+ * Must be used as the first member in your custom tree struct.
  *
  * @param type the data type for the nodes
  */
@@ -858,7 +858,7 @@
     /**
      * Member function for inserting multiple elements.
      *
-     * Implementations SHALL avoid to perform a full search in the tree for
+     * Implementations SHALL avoid performing a full search in the tree for
      * every element even though the source data MAY be unsorted.
      */
     size_t (*insert_many)(
@@ -885,7 +885,7 @@
 
 
 /**
- * Destroys a node and it's subtree.
+ * Destroys a node and its subtree.
  *
  * It is guaranteed that the simple destructor is invoked before
  * the advanced destructor, starting with the leaf nodes of the subtree.
@@ -921,7 +921,7 @@
  *
  * @attention Be careful when calling this function when no destructor function
  * is registered that actually frees the memory of nodes. In that case you will
- * need a reference to the (former) root node of the tree somewhere or
+ * need a reference to the (former) root node of the tree somewhere, or
  * otherwise you will be leaking memory.
  *
  * @param tree the tree
@@ -992,9 +992,9 @@
 /**
  * Creates a new tree structure based on a default layout.
  *
- * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first
+ * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as the first
  * member (or at least respect the default offsets specified in the tree
- * struct) and they MUST be allocated with the specified allocator.
+ * struct), and they MUST be allocated with the specified allocator.
  *
  * @note This function will also register an advanced destructor which
  * will free the nodes with the allocator's free() method.
@@ -1019,7 +1019,7 @@
  * @attention This function will create an incompletely defined tree structure
  * where neither the create function, the search function, nor a destructor
  * will be set. If you wish to use any of this functionality for the wrapped
- * tree, you need to specify those functions afterwards.
+ * tree, you need to specify those functions afterward.
  *
  * @param allocator the allocator that was used for nodes of the wrapped tree
  * (if @c NULL, the cxDefaultAllocator is assumed)
@@ -1289,7 +1289,7 @@
 /**
  * Sets the (new) parent of the specified child.
  *
- * If the @p child is not already member of the tree, this function behaves
+ * If the @p child is not already a member of the tree, this function behaves
  * as #cxTreeAddChildNode().
  *
  * @param tree the tree
@@ -1308,11 +1308,11 @@
 /**
  * Adds a new node to the tree.
  *
- * If the @p child is already member of the tree, the behavior is undefined.
+ * If the @p child is already a member of the tree, the behavior is undefined.
  * Use #cxTreeSetParent() if you want to move a subtree to another location.
  *
  * @attention The node may be externally created, but MUST obey the same rules
- * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use
+ * as if it was created by the tree itself with #cxTreeAddChild() (e.g., use
  * the same allocator).
  *
  * @param tree the tree
@@ -1336,7 +1336,7 @@
  * leaving this task to the tree by using #cxTreeInsert().
  *
  * Be aware that adding nodes at arbitrary locations in the tree might cause
- * wrong or undesired results when subsequently invoking #cxTreeInsert() and
+ * wrong or undesired results when subsequently invoking #cxTreeInsert(), and
  * the invariant imposed by the search function does not hold any longer.
  *
  * @param tree the tree
@@ -1395,7 +1395,7 @@
 );
 
 /**
- * Removes a node and it's subtree from the tree.
+ * Removes a node and its subtree from the tree.
  *
  * If the node is not part of the tree, the behavior is undefined.
  *

mercurial