doc: add Doxygen support

This commit is contained in:
anna 2021-07-26 16:54:05 +02:00
parent 0a8ee6173e
commit c3776c0654
Signed by: fef
GPG key ID: EC22E476DC2D3D84
14 changed files with 3052 additions and 228 deletions

2622
doc/Doxyfile.in Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,8 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
/**
* @file Main libneo header file providing core functionalities.
*/
#pragma once

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
@ -6,46 +6,56 @@
#include "neo/_types.h"
/**
* Throw an error. If `err` is `nil`, the program halts.
* Functions accepting an `err` object must call either `yeet` or `neat`
* @defgroup error Error Handling
*
* @{
*/
/**
* @brief Throw an error. If `err` is `nil`, the program halts.
*
* Functions accepting an `error` object must call either `yeet()` or `neat()`
* on the object exactly once, or the behavior is undefined.
* If a function yeets an error, its return value is undefined.
*
* @param err: The error pointer passed to the callee
* @param number: An error number appropriate for the condition,
* @param err The error pointer passed to the callee
* @param number An error number appropriate for the condition,
* usually one from `errno.h`
* @param fmt: If non nil, a printf-style format string followed by
* @param fmt If non `nil`, a printf-style format string followed by
* the values to insert which will become the error message.
*/
__attribute__(( __format__(printf, 3, 4) ))
void yeet(error *err, u32 number, const char *restrict fmt, ...);
void yeet(error *err, u32 number, const char *restrict fmt, ...)
__attribute__(( __format__(printf, 3, 4) ));
/**
* Indicate an operation has completed successfully.
* Functions accepting an `error` pointer must call either `yeet` or `neat`,
* Functions accepting an `error` pointer must call either `yeet()` or `neat()`,
* or the begavior is undefined.
*
* @param err: Error object
* @param err Error object
*/
void neat(error *err);
/**
* Release any resources allocated for an error.
* @brief Release any resources allocated for an error.
*
* This must always be called within the catch block of the outermost calling
* function, i.e. the one that declared the error variable (not the ones just
* accepting an error * argument and passing it through to further calls).
* accepting an `error *` argument and passing it through to further calls).
*
* Put another way, you probably need to call this if you had to put an `&`
* before the error variable for passing it into `catch`.
* before the error variable for passing it into `catch()`.
*
* @param err: Error object to destroy
* @param err Error object to destroy
*/
void errput(error *err);
/**
* @brief Catch an error.
*
* Execute the expression after this macro call if the error pointed to
* by `err` is an actual error, i.e. it has been `yeet`ed to.
* Resources for the error must be released using `nput`.
* by `err` is an actual error, i.e. it has been `yeet()`ed to.
* Resources for the error must be released using `nput()`.
*/
#define ncatch(err) if ((err) != nil && (err)->_number != 0)
#ifndef __cplusplus
@ -53,17 +63,27 @@ void errput(error *err);
#endif
/**
* Get the error number.
* Must only be used within a catch block and before `errput` is called.
* @brief Get the error number.
*
* Must only be used within a catch block and before `errput()` is called.
*
* @param err `error *` to get the number of
* @returns The error number
*/
#define errnum(err) ((err) == nil ? 0 : (err)->_number)
/**
* Get an optional error message, this may be `nil`
* Must only be used within a catch block and before `errput` is called.
* @brief Get an optional error message, this may be `nil`.
*
* Must only be used within a catch block and before `errput()` is called.
*
* @param err `error *` to get the message of
* @returns The error message, may be `nil`
*/
#define errmsg(err) ((err) == nil ? (nstr_t *)nil : (err)->_message)
/** @} */
/*
* This file is part of libneo.
* Copyright (c) 2021 Fefie <owo@fef.moe>.

View file

@ -1,35 +1,44 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
#include "neo/_toolchain.h"
#include "neo/_types.h"
/**
* @defgroup nalloc Memory Management
*
* @{
*/
/**
* @brief Release memory.
*
* @param ptr Pointer returned by `nalloc()` or `nzalloc()`
*/
void nfree(void *ptr);
/**
* Allocate `size` bytes of memory and return a pointer to the memory region.
* The memory is *not* initialized; use `nzalloc` if you want it to be.
* The memory is *not* initialized; use `nzalloc()` if you want it to be.
* If `size` is 0, the allocation fails.
* If the allocation fails, the error is set and `nil` is returned.
*
* @param size: Desired memory size in bytes
* @param err: Error object
* @param size Desired memory size in bytes
* @param err Error object
*/
__neo_malloc(nfree, 1)
void *nalloc(usize size, error *err);
void *nalloc(usize size, error *err) __neo_malloc(nfree, 1);
/**
* Allocate `size` bytes of memory and return a pointer to the memory region.
* The memory is initialized to zeroes; use `nalloc` if you don't want that.
* The memory is initialized to zeroes; use `nalloc()` if you don't want that.
* If `size` is 0, the allocation fails.
* If the allocation fails, the error is set and `nil` is returned.
*
* @param size: Desired memory size in bytes
* @param err: Error object
* @param size Desired memory size in bytes
* @param err Error object
*/
__neo_malloc(nfree, 1)
void *nzalloc(usize size, error *err);
void *nzalloc(usize size, error *err) __neo_malloc(nfree, 1);
/**
* Resize an allocated memory region to fit at least `newsize` bytes and return
@ -38,13 +47,14 @@ void *nzalloc(usize size, error *err);
* If `ptr` is `nil`, the function behaves like `nalloc`.
* If allocation fails, an error is yeeted.
*
* @param ptr: The pointer to the memory region to be expanded,
* as returned by `nalloc` or `nzalloc`.
* @param newsize: The new size.
* @param err: Error object
* @param ptr The pointer to the memory region to be expanded,
* as returned by `nalloc()` or `nzalloc()`
* @param newsize The new size
* @param err Error object
*/
__neo_malloc(nfree, 1)
void *nrealloc(void *ptr, usize newsize, error *err);
void *nrealloc(void *ptr, usize newsize, error *err) __neo_malloc(nfree, 1);
/** @} */
/*
* This file is part of libneo.

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
@ -6,72 +6,78 @@
#include "neo/_types.h"
/**
* Create a new buffer of fixed size.
* @defgroup nbuf Buffers
*
* @{
*/
/**
* @brief Create a new buffer of fixed size.
*
* If allocation fails or `size` is 0, an error is yeeted.
*
* @param size: Size in bytes
* @param err: Error pointer
* @param size Size in bytes
* @param err Error pointer
* @returns The buffer, except if an error occurred
*/
nbuf_t *nbuf_create(usize size, error *err);
/**
* Create a new buffer of fixed size and copy `data` into it.
* @brief Create a new buffer of fixed size and copy `data` into it.
*
* The original pointer is neither modified nor deallocated.
* If allocation fails, `data` is `nil`, or `size` is 0, an error is yeeted.
*
* @param data: Raw data to fill the buffer with
* @param size: How many bytes are read from `data`, and the buffer size
* @param err: Error pointer
* @param data Raw data to fill the buffer with
* @param size How many bytes are read from `data`, and the buffer size
* @param err Error pointer
* @returns The buffer, except if an error occurred
*/
nbuf_t *nbuf_from(const void *restrict data, usize size, error *err);
/**
* Create a new buffer of fixed size and copy a string into it.
* @brief Create a new buffer of fixed size and copy a string into it.
*
* The original string is neither modified not deallocated.
* The original string is neither modified nor deallocated.
* If allocation fails or `s` is `nil`, an error is yeeted.
*
* @param s: String to fill the buffer with
* @param err: Error pointer
* @param s String to fill the buffer with
* @param err Error pointer
* @returns The buffer, except if an error occurred
*/
nbuf_t *nbuf_from_str(const char *restrict s, error *err);
/**
* Create a new buffer of fixed size and copy a neo string into it.
* @brief Create a new buffer of fixed size and copy a neo string into it.
*
* The original string is unmodified.
* If allocation fails or `s` is `nil`, an error is yeeted.
*
* @param s: Neo string to fill the buffer with
* @param err: Error pointer
* @param s Neo string to fill the buffer with
* @param err Error pointer
* @returns The buffer, except if an error occurred
*/
nbuf_t *nbuf_from_nstr(nstr_t *s, error *err);
/**
* Return a new copy of `buf`.
* @brief Return a new copy of `buf`.
*
* If `buf` is `nil` or allocation fails, an error is yeeted.
*
* @param buf: Buffer to create a copy of
* @param err: Error pointer
* @param buf Buffer to create a copy of
* @param err Error pointer
* @returns A copy of `buf`, unless an error occurred
*/
nbuf_t *nbuf_clone(nbuf_t *buf, error *err);
/**
* Get the byte at the specified index.
* @brief Get the byte at the specified index.
*
* If `buf` is `nil` or `index` is out of bounds, an error is yeeted.
*
* @param buf: `nbuf_t *` to get the byte from
* @param index: Byte index (counting from 0)
* @param err: Error pointer
* @param buf `nbuf_t *` to get the byte from
* @param index Byte index (counting from 0)
* @param err Error pointer
* @returns The byte at position `index` (as a `u8`), unless an error occurred
*/
#define nbuf_byte(buf, index, err) ({ \
@ -91,7 +97,7 @@ nbuf_t *nbuf_clone(nbuf_t *buf, error *err);
cursor++)
/**
* Compare two buffers.
* @brief Compare two buffers.
*
* If the first buffer is found to be greater than the second one, the return
* value is greater than 0.
@ -101,15 +107,17 @@ nbuf_t *nbuf_clone(nbuf_t *buf, error *err);
*
* If `buf1` or `buf2` is `nil`, an error is yeeted.
*
* @param buf1: First buffer to compare
* @param buf2: Second buffer to compare
* @param err: Error pointer
* @param buf1 First buffer to compare
* @param buf2 Second buffer to compare
* @param err Error pointer
* @returns The difference between the buffers, unless an error occurred
*/
int nbuf_cmp(const nbuf_t *buf1, const nbuf_t *buf2, error *err);
#define nbuf_eq(buf1, buf2, err) ( (bool)(nbuf_cmp(buf1, buf2, err) == 0) )
/** @} */
/*
* This file is part of libneo.
* Copyright (c) 2021 Fefie <owo@fef.moe>.

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
@ -6,51 +6,66 @@
void _neo_nref_init(struct _neo_nref *ref, void (*destroy)(void *ptr), usize offset);
int _neo_nget(struct _neo_nref *ref);
int _neo_nput(struct _neo_nref *ref);
/**
* Initialize the reference counter in a structure.
* @defgroup nref Reference Counting
*
* @{
*/
/**
* @brief Initialize the reference counter in a structure.
*
* The count is initialized to 1 and can be incremented and decremented using
* `nget` and `nput` respectively. If the count reaches 0, the `destroy`
* `nget()` and `nput()` respectively. If the count reaches 0, the `destroy`
* callback is invoked where the structure and all resources tied to it must
* be released. The reference counter must be embedded in the struct using
* the `NREF_FIELD` macro.
*
* @param ptr: The `struct *` containing the `NREF_FIELD`
* @param destroy: A callback accepting a pointer to the original struct as its
* @param ptr The `struct *` containing the `NREF_FIELD`
* @param destroy A callback accepting a pointer to the original struct as its
* only parameter and return type `void`, which will deallocate the struct
*/
#define nref_init(ptr, destroy) ({ \
void (*__destroy_typechecked)(typeof(ptr)) = destroy; \
void (*__destroy_typechecked)(typeof(ptr)) = (destroy); \
_neo_nref_init(&(ptr)->__neo_nref, \
(void (*)(void *))__destroy_typechecked, \
offsetof(typeof(*(ptr)), __neo_nref)); \
})
int _neo_nget(struct _neo_nref *ref);
int _neo_nput(struct _neo_nref *ref);
/**
* Increment the reference counter of a structure embedding `NREF_FIELD`.
* @brief Increment the reference counter of a structure embedding `NREF_FIELD`.
*
* @param ptr: The `struct *` to increment the reference counter of
* @returns The new reference count
* @param ptr The `struct *` to increment the reference counter of
*/
#define nget(ptr) (_neo_nget( &(ptr)->__neo_nref ))
#define nget(ptr) ((void)_neo_nget( &(ptr)->__neo_nref ))
/**
* Decrement the reference counter of a structure embedding `NREF_FIELD`.
* @brief Decrement the reference counter of a structure embedding `NREF_FIELD`.
*
* If the counter reaches zero, the destroy callback passed to `nref_init`
* is invoked and the pointer is set to `nil` to prevent any further usage.
*
* @param ptr: The `struct *` to decrement the reference counter of
* @returns The new reference count
* @param ptr The `struct *` to decrement the reference counter of
*/
#define nput(ptr) ({ \
if (_neo_nput(&(ptr)->__neo_nref) == 0) \
ptr = nil; \
})
/**
* @brief Return the current reference count of a structure embedding `NREF_FIELD`.
* You usually shouldn't need this though.
*
* @param ptr The `struct *` embedding `NREF_FIELD`
* @returns The structure's current refcount value as a `const int`
*/
#define nref_count(ptr) ((const int)(ptr)->__neo_nref._count)
/** @} */
/*
* This file is part of libneo.
* Copyright (c) 2021 Fefie <owo@fef.moe>.

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
@ -20,12 +20,31 @@ struct _neo_nstr_init_info {
};
/**
* Statically define a neo string.
* @defgroup nstr Strings
*
* @{
*/
/**
* @brief Return a pointer to the raw C string stored in this neo string.
*
* This macro should only be used when it is strictly necessary, for example
* when passing the string to `printf` and friends, because it will bypass the
* refcounting protection. If you absolutely need to store it in a structure
* with dynamic lifetime, it is advisable to combine it with `borrow`.
*
* @param nstr `nstr_t *` to get the raw string of
* @returns A `const char *` pointing to the raw C string
*/
#define nstr_raw(nstr) ((nstr)->_data)
/**
* @brief Statically define a neo string (file scope only).
*
* The string will be initialized before `main` is called.
*
* @param name: Name of the `nstr_t *` variable to be declared
* @param content: A `const char *` with the contents of the string
* @param name Name of the `nstr_t *` variable to be declared
* @param content A `const char *` with the contents of the string
*/
#define NSTR_DEFINE(name, content) \
nstr_t *name = nil; \
@ -36,20 +55,20 @@ struct _neo_nstr_init_info {
}
/**
* Copy a regular C string to a neo string.
* @brief Copy a regular C string to a neo string.
*
* `s` must be NUL terminated, and be deallocated manually if no longer needed.
* If `s` is `nil` or allocation fails, an error is yeeted. Strings in libneo
* are reference counted, see `nget` and `nput`.
*
* @param s: String to convert
* @param err: Error pointer
* @param s String to convert
* @param err Error pointer
* @returns The converted string, unless an error occurred
*/
nstr_t *nstr(const char *restrict s, error *err);
/**
* Copy a regular C string to a neo string, but at most `maxsize` bytes.
* @brief Copy a regular C string to a neo string, but at most `maxsize` bytes.
*
* The string is copied until a NUL terminator is encountered, or until
* `maxsize` bytes have been read. If `maxsize` is 0, an empty string is
@ -63,147 +82,153 @@ nstr_t *nstr(const char *restrict s, error *err);
nstr_t *nnstr(const char *restrict s, usize maxsize, error *err);
/**
* Get the Unicode code point in a string at the specified index.
* @brief Get the Unicode code point in a string at the specified index.
*
* If the string is `nil` or the index is out of range, an error is yeeted.
*
* @param s: String to get a character from
* @param index: Character index, starting from 0
* @param err: Error pointer
* @param s String to get a character from
* @param index Character index, starting from 0
* @param err Error pointer
* @returns The Unicode code point at the specified index,
* unless an error occurred
*/
nchar nchrat(const nstr_t *s, usize index, error *err);
/**
* Convert a signed integer to a string.
* @brief Convert a signed integer to a string.
*
* If allocation fails or the radix is out of range, an error is yeeted.
*
* @param i: The integer
* @param radix: Base of the numerical system to convert to, must be within 2~36
* @param err: Error pointer
* @param i The integer
* @param radix Base of the numerical system to convert to, must be within 2~36
* @param err Error pointer
* @returns The stringified integer, unless an error occurred
*/
nstr_t *i2nstr(i64 i, int radix, error *err);
/**
* Convert an unsigned integer to a string.
* @brief Convert an unsigned integer to a string.
*
* If allocation fails or the radix is out of range, an error is yeeted.
*
* @param u: The integer
* @param radix: Base of the numerical system to convert to, must be within 2~36
* @param err: Error pointer
* @param u The integer
* @param radix Base of the numerical system to convert to, must be within 2~36
* @param err Error pointer
* @returns The stringified integer, unless an error occurred
*/
nstr_t *u2nstr(u64 u, int radix, error *err);
/**
* Duplicate a string.
* @brief Duplicate a string.
*
* This should never be neccessary because strings in libneo are refcounted
* and immutable. If `s` is `nil` or allocation fails, an error is yeeted.
*
* @param s: String to duplicate
* @param err: Error pointer
* @param s String to duplicate
* @param err Error pointer
* @returns The duplicated string, unless an error occurred
*/
nstr_t *nstrdup(nstr_t *s, error *err);
/**
* Repeat a string `n` times and return the new string.
* @brief Repeat a string `n` times and return the new string.
*
* If `s` is `nil` or allocation fails, an error is yeeted.
* If `n` is 0, an empty string is returned.
* If `n` is 1, this function behaves exactly like `nstrdup`.
*
* @param s: String to repeat, remains unmodified
* @param n: Total amount of repetitions
* @param err: Error pointer
* @param s String to repeat, remains unmodified
* @param n Total amount of repetitions
* @param err Error pointer
* @returns A new string with the repeated content, unless an error occurred
*/
nstr_t *nstrmul(nstr_t *s, usize n, error *err);
/**
* Create a string considting of `n` repetitions of `c`.
* @brief Create a string considting of `n` repetitions of `c`.
*
* If `c` is not within unicode space or allocation fails, an error is yeeted.
* If `n` is 0, an empty string is returned.
*
* @param c: Character to fill the string with
* @param n: How many characters to put into the string
* @param err: Error pointer
* @param c Character to fill the string with
* @param n How many characters to put into the string
* @param err Error pointer
* @returns The string, unless an error occurred
*/
nstr_t *nchrmul(nchar c, usize n, error *err);
/**
* Concatenate two strings and return the result.
* @brief Concatenate two strings and return the result.
*
* The original two strings are unmodified.
* If any of the two strings are `nil` or allocation fails, an error is yeeted.
*
* @param s1: First string
* @param s2: Second string
* @param err: Error pointer
* @param s1 First string
* @param s2 Second string
* @param err Error pointer
* @returns A new string instance that consists of the two concatenated ones,
* unless an error occurred
*/
nstr_t *nstrcat(const nstr_t *s1, const nstr_t *s2, error *err);
/**
* Compare two strings character by character.
* @brief Compare two strings character by character.
*
* The return value is negative if the first different character in `s1` comes
* before the one in `s2`
*
* @param s1: First string
* @param s2: Second string
* @param err: Error pointer
* @param s1 First string
* @param s2 Second string
* @param err Error pointer
* @returns The difference between the two strings, unless an error occurred
*/
int nstrcmp(const nstr_t *s1, const nstr_t *s2, error *err);
/**
* Determine whether two strings are exactly equal.
* @brief Determine whether two strings are exactly equal.
*
* If either of the two string are `nil` or acquiring a lock on them fails,
* an error is yeeted.
*
* @param s1: First `nstr_t *`
* @param s2: Second `nstr_t *`
* @param err: Error pointer
* @param s1 First `nstr_t *`
* @param s2 Second `nstr_t *`
* @param err Error pointer
* @returns Whether the two strings are equal, unless an error occurred
*/
#define nstreq(s1, s2, err) ( (bool)(nstrcmp(s1, s2, err) == 0) )
/**
* @brief Extend a string to match a certain length.
*
* Prepend fill characters to a string to make it a specific length, and return
* a new string with the result. The original string is unmodified.
* If the string is already longer than the desired width or allocation fails,
* an error is yeeted.
*
* @param s: String to expand
* @param length: Desired length of the new string
* @param fill: Character to fill the space with
* @param err: Error pointer
* @param s String to expand
* @param length Desired length of the new string
* @param fill Character to fill the space with
* @param err Error pointer
* @returns The new padded string
*/
nstr_t *leftpad(nstr_t *s, usize length, nchar fill, error *err);
/**
* Iterate over each character in a string.
* @brief Iterate over each character in a string.
*
* @param cursor: `nchar *` to store the current character in
* @param nstr: `nstr_t *` to iterate over
* @param err: Error pointer; the loop will terminate early if an uncaught
* @param cursor `nchar *` to store the current character in
* @param nstr `nstr_t *` to iterate over
* @param err Error pointer; the loop will terminate early if an uncaught
* error occurred
*/
#define nstr_foreach(cursor, nstr, err) \
for (const char *__pos = \
for (const char *__next = \
(nstr)->_data + utf8_to_nchr(cursor, (nstr)->_data, err); \
/* errput sets the error number to 0xffffffff, thus number + 1 */ \
*__pos != '\0' && (err) != nil && (err)->_number + 1 < 2; \
__pos += utf8_to_nchr(cursor, __pos, err))
*__next != '\0' && (err) != nil && (err)->_number + 1 < 2; \
__next += utf8_to_nchr(cursor, __next, err))
/** @} */
/** Internal callback for nref */
void _neo_nstr_destroy(nstr_t *s);

View file

@ -1,9 +1,15 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
#include "neo/_types.h"
/**
* @defgroup stddef Core Macros
*
* @{
*/
#ifdef __cplusplus
# define nil nullptr
#else
@ -18,7 +24,7 @@
# define typeof(expr) __typeof(expr)
#endif
/** Get the absolute (non negative) value of an integer */
/** @brief Get the absolute (non negative) value of an integer */
#define nabs(n) ({ \
/* n is an expression, not a variable, evaluate it only once */ \
typeof(n) __neo_local_n = (n); \
@ -38,14 +44,18 @@
})
/**
* @brief Get the length of a data structure embedding `NLEN_FIELD`.
*
* Quickly get the length (as in amount of items, not bytes) of any libneo data
* structure that supports it. This includes strings, buffers, lists, and more.
*
* @param thing: Thing to get the length of
* @returns: The length as a `const usize`
* @param thing Thing to get the length of
* @returns The length as a `const usize`
*/
#define nlen(thing) ((thing)->__neo_nlen)
/* @} */
/*
* This file is part of libneo.
* Copyright (c) 2021 Fefie <owo@fef.moe>.

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once

View file

@ -1,9 +1,15 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
#pragma once
#include "neo/_stddef.h"
/**
* @defgroup types Primitive Types
*
* @{
*/
typedef __INT8_TYPE__ i8;
typedef __INT16_TYPE__ i16;
typedef __INT32_TYPE__ i32;
@ -18,13 +24,15 @@ typedef __UINT64_TYPE__ u64;
typedef __SIZE_TYPE__ usize;
typedef __PTRDIFF_TYPE__ isize;
/** A single Unicode character (32 bits) */
/** @brief A single Unicode character (32 bits) */
typedef u32 nchar;
typedef float f32;
typedef double f64;
typedef long double f128;
/** @} */
#ifdef __cplusplus
/* TODO: This is probably not a good idea */
# define __neo_atomic_type volatile int
@ -38,10 +46,12 @@ typedef long double f128;
#endif
/**
* Declare a length field in a structure.
* @brief Declare a length field in a structure.
* This makes it compatible with the `nlen` macro.
*
* @param name: field name, will be of type `usize`
* @param name field name, will be of type `usize`
*
* @ingroup stddef
*/
#define NLEN_FIELD(name) \
union { \
@ -56,12 +66,23 @@ struct _neo_nref {
__neo_atomic_type _count;
};
/**
* A basic reference counter for data structures.
* @brief A basic reference counter for data structures.
*
* Embed this into your data structure using the `NREF_FIELD` macro, initialize
* it using `nref_init`, and use `nget` and `nput` to increment/decrement the
* reference counter.
*
* @ingroup nref
*/
typedef struct _neo_nref nref_t;
/**
* @brief Embed this macro into your structure to enable refcounting.
*
* The reference counter must be initialized using `nref_init` and may be
* incremented and decremented using `nget` and `nput` respectively.
*
* @ingroup stddef
*/
#define NREF_FIELD nref_t __neo_nref
struct _neo_nbuf {
@ -75,7 +96,9 @@ struct _neo_nbuf {
const byte *_data;
};
/**
* A statically sized, refcounted buffer.
* @brief An immutable, refcounted buffer.
*
* @ingroup nbuf
*/
typedef struct _neo_nbuf nbuf_t;
@ -92,12 +115,22 @@ struct _neo_nstr {
nref_t *_borrow;
const char *_data;
};
/**
* @brief An immutable, refcounted UTF-8 string.
*
* @ingroup nstr
*/
typedef struct _neo_nstr nstr_t;
struct _neo_error {
nstr_t *_message;
u32 _number;
};
/**
* @brief The generic error type.
*
* @ingroup error
*/
typedef struct _neo_error error;
/*

View file

@ -1,4 +1,8 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
/**
* @file Hashtable API
*/
#pragma once
@ -24,31 +28,39 @@ struct _neo_hashtab {
u32 _buckets_len;
list_t _buckets[0]; /* -> _neo_hashtab_entry::link */
};
/**
* @defgroup hashtab Hashtable API
*
* @{
*/
/** @brief The hash table type. */
typedef struct _neo_hashtab hashtab_t;
/**
* Create a new hash table.
* @brief Create a new hash table.
*
* The hashing function used is implementation defined; use
* `hashtab_create_custom` to specify your own.
* If allocation fails or `buckets` is 0, an error is yeeted.
*
* @param buckets: Number of hash buckets
* @param err: Error pointer
* @param buckets Number of hash buckets
* @param err Error pointer
* @returns The initialized hash table, unless an error occurred
*/
hashtab_t *hashtab_create(u32 buckets, error *err);
/**
* Create a new hash table with custom hashing algorithm.
* @brief Create a new hash table with custom hashing algorithm.
*
* If allocation fails, `buckets` is 0, or `hashfn` is nil, an error is yeeted.
* The custom hash function must return a value less than the `limit` parameter
* passed to it. The `limit` parameter is the number of buckets minus one.
*
* @param buckets: Number of hash buckets
* @param hashfn: Custom hash function to use
* @param err: Error pointer
* @param buckets Number of hash buckets
* @param hashfn Custom hash function to use
* @param err Error pointer
* @returns The initialized hash table, unless an error occurred
*/
hashtab_t *hashtab_create_custom(u32 buckets,
@ -56,56 +68,56 @@ hashtab_t *hashtab_create_custom(u32 buckets,
error *err);
/**
* Get an entry in a hash table.
* @brief Get an entry in a hash table.
*
* If the key does not exist, *no* error is yeeted and the return value is `nil`.
* If the key is `nil` or the hash function returned a value greater than the
* maxval parameter passed to it, an error is yeeted.
*
* @param table: Hash table to get the entry from
* @param key: Key to get the value of
* @param err: Error pointer
* @param table Hash table to get the entry from
* @param key Key to get the value of
* @param err Error pointer
* @returns The entry or `nil` if it does not exist, unless an error occurred
*/
void *hashtab_get(hashtab_t *table, const nbuf_t *key, error *err);
/**
* Put an entry into a hash table.
* @brief Put an entry into a hash table.
*
* The reference counter in `key` is incremented.
* If `key` is `nil`, `key_size` is 0, the key already exists in the table,
* or the hash function returned a value greater than or equal to the `limit`
* parameter passed to it, an error is yeeted.
*
* @param table: Hash table to insert the value at
* @param key: Key to insert the value under
* @param val: Value to insert
* @param err: Error pointer
* @param table Hash table to insert the value at
* @param key Key to insert the value under
* @param val Value to insert
* @param err Error pointer
*/
void hashtab_put(hashtab_t *table, nbuf_t *key, void *val, error *err);
/**
* Delete an entry from a hash table.
* @brief Delete an entry from a hash table.
*
* If `table` or `key` is `nil`, or the key was not found within the table,
* an error is yeeted.
*
* @param table: Table to delete an entry from
* @param key: Key of the item to delete
* @param err: Error pointer
* @param table Table to delete an entry from
* @param key Key of the item to delete
* @param err Error pointer
* @returns The removed item, unless an error occurred
*/
void *hashtab_del(hashtab_t *table, nbuf_t *key, error *err);
/**
* Iterate over every entry in a hash table.
* @brief Iterate over every entry in a hash table.
*
* If `table` or `callback` is `nil`, an error is yeeted.
*
* @param table: Table to iterate over
* @param callback: Callback function that is invoked for every entry;
* @param table Table to iterate over
* @param callback Callback function that is invoked for every entry;
* the iteration stops if the return value is nonzero
* @param extra: Optional pointer that is passed as an extra argument to the
* @param extra Optional pointer that is passed as an extra argument to the
* callback function
* @returns The last return value of the callback, unless an error occurred
*/
@ -113,6 +125,8 @@ int hashtab_foreach(hashtab_t *table,
int (*callback)(hashtab_t *table, nbuf_t *key, void *val, void *extra),
void *extra, error *err);
/** @} */
#ifdef __cplusplus
}; /* extern "C" */
#endif

View file

@ -1,4 +1,8 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
/**
* @file List API
*/
#pragma once
@ -17,7 +21,9 @@ struct _neo_listnode {
struct _neo_list *_list;
};
/**
* List node anchor for embedding into your own structure.
* @brief List node anchor for embedding into your own structure.
*
* @ingroup list
*/
typedef struct _neo_listnode listnode_t;
@ -25,23 +31,21 @@ struct _neo_list {
struct _neo_listnode _root;
NLEN_FIELD(_len);
};
/**
* @brief List data type
*
* @ingroup list
*/
typedef struct _neo_list list_t;
/**
* Initialize a list.
* When casting out from a @a `listnode_t` to its supposed containing structure
* (in a loop), it is possible that it was in fact the @a `list_t` that contained
* the @a `listnode_t`. This macro checks whether that is the case.
*
* @param list: The list
*/
void list_init(list_t *list);
/**
* When casting out from a `listnode_t` to its supposed containing structure
* (in a loop), it is possible that it was in fact the `list_t` that contained
* the `listnode_t`. This macro checks whether that is the case.
*
* @param casted: `struct *` that the `listnode_t *` was casted out to
* @param list: `list_t *` storing the root `listnode_t`
* @param member: Name of the `listnode_t` member embedded within the `struct *`
* @param casted `struct *` that the @a `listnode_t *` was casted out to
* @param list @a `list_t *` storing the root @a `listnode_t`
* @param member Name of the @a `listnode_t` member embedded within the `struct *`
*/
#define _neo_list_is_root(casted, list, member) \
( &(casted)->member == &(list)->_root )
@ -64,52 +68,65 @@ void list_init(list_t *list);
((typeof(current))( (u8 *)((current)->member._prev) - offsetof(typeof(*(current)), member) ))
/**
* Append a new node to the end of a list.
* @defgroup list List API
*
* @param list: List to append to
* @param new_node: New node to append
* @{
*/
/**
* Initialize a list.
*
* @param list The list
*/
void list_init(list_t *list);
/**
* @brief Append a new node to the end of a list.
*
* @param list List to append to
* @param new_node New node to append
*/
void list_add(list_t *list, listnode_t *new_node);
/**
* Remove a node from a list.
* @brief Remove a node from a list.
*
* @param node: Node to remove
* @param node Node to remove
*/
void list_del(listnode_t *node);
/**
* Insert a new node to the beginning of a list.
* @brief Insert a new node to the beginning of a list.
*
* @param list: List to insert the node into
* @param new_node: New node to insert
* @param list List to insert the node into
* @param new_node New node to insert
*/
void list_add_first(list_t *list, listnode_t *new_node);
/**
* Insert a new node after the specified list node.
*
* @param pos: List node to insert the new node after
* @param new_node: Node to insert after the specified position
* @param pos List node to insert the new node after
* @param new_node Node to insert after the specified position
*/
void list_insert(listnode_t *pos, listnode_t *new_node);
/**
* Insert a new node before the specified list node.
*
* @param pos: List node to insert the new node before
* @param new_node: Node to insert before the specified position
* @param pos List node to insert the new node before
* @param new_node Node to insert before the specified position
*/
void list_insert_before(listnode_t *pos, listnode_t *new_node);
/**
* Iterate over each item in a list.
* @brief Iterate over each item in a list.
*
* The current entry can be safely removed from the list.
*
* @param cursor: `type *` to use as a cursor; may be a declaration
* @param list: `list_t *` to iterate over
* @param member: Name of the `listnode_t` member embedded within `cursor`
* @param cursor `type *` to use as a cursor
* @param list `list_t *` to iterate over
* @param member Name of the `listnode_t` member embedded within \a `cursor`
*/
#define list_foreach(cursor, list, member) \
for (typeof(cursor) __tmp = _neo_list_next( \
@ -120,13 +137,13 @@ void list_insert_before(listnode_t *pos, listnode_t *new_node);
cursor = __tmp, __tmp = _neo_list_next(__tmp, member))
/**
* Iterate over each item in a list in reverse order.
* @brief Iterate over each item in a list in reverse order.
*
* The current entry can be safely removed from the list.
*
* @param cursor: `type *` to use as a cursor; may be a declaration
* @param list: `list_t *` to iterate over
* @param member: Name of the `listnode_t` member embedded within `cursor`
* @param cursor `type *` to use as a cursor
* @param list `list_t *` to iterate over
* @param member Name of the `listnode_t` member embedded within \a `cursor`
*/
#define list_foreach_reverse(cursor, list, member) \
for (typeof(cursor) __tmp = _neo_list_prev( \
@ -136,6 +153,8 @@ void list_insert_before(listnode_t *pos, listnode_t *new_node);
!_neo_list_is_root(cursor, list, member); \
cursor = __tmp, __tmp = _neo_list_prev(__tmp, member))
/** @} */
#ifdef __cplusplus
}; /* extern "C" */
#endif

View file

@ -1,4 +1,4 @@
/** See the end of this file for copyright and license terms. */
/* See the end of this file for copyright and license terms. */
/**
* @file Conversion utilities for raw UTF.
@ -24,75 +24,75 @@ extern "C" {
#include "neo/_types.h"
/**
* Check whether a NUL terminated string is valid UTF-8.
* @brief Check whether a NUL terminated string is valid UTF-8.
*
* If the string contains any malformed code sequences, an error is yeeted.
*
* @param s: String to validate
* @param err: Error pointer
* @param s String to validate
* @param err Error pointer
* @returns The number of UTF-8 code points (i.e. number of Unicode characters)
* excluding the terminating NUL byte; undefined on error
*/
usize utf8_check(const char *restrict s, error *err);
/**
* Check whether a NUL terminated string is valid UTF-8, but read at most
* `maxsize + 3` bytes (this function uses `utf8_to_nchr` internally).
* @brief Check whether a NUL terminated string is valid UTF-8.
* At most `maxsize + 3` bytes are read (this function uses `utf8_to_nchr` internally).
*
* If a NUL terminator is encountered before `maxsize` bytes, reading stops
* before the specified size. If the string contains any malformed code
* sequences, an error is yeeted.
*
* @param s: String to validate
* @param maxsize: Maximum amount of byte to read from `s`
* @param err: Error pointer
* @param s String to validate
* @param maxsize Maximum amount of byte to read from `s`
* @param err Error pointer
* @returns The number of UTF-8 code points (i.e. number of Unicode characters)
* excluding the terminating NUL byte; undefined on error
*/
usize utf8_ncheck(const char *restrict s, usize maxsize, error *err);
/**
* Compute the length of a raw UTF-8 encoded, NUL terminated string.
* @brief Compute the length of a raw UTF-8 encoded, NUL terminated string.
*
* The string is *not* checked for malformed code sequences,
* use `utf8_check` for that.
*
* @param s: String to get the length of
* @returns: String length as in Unicode code points (not bytes),
* @param s String to get the length of
* @returns String length as in Unicode code points (not bytes),
* excluding the terminating NUL byte
*/
usize utf8_strlen(const char *restrict s);
/**
* Get the amount of bytes a Unicode character takes up in UTF-8.
* @brief Get the amount of bytes a Unicode character takes up in UTF-8.
*
* If the character is outside of the Unicode range (`0x00000000`~`0x0010ffff`),
* an error is yeeted.
*
* @param c: The character
* @param err: Error pointer
* @param c The character
* @param err Error pointer
* @returns The amount of bytes needed to store the character in UTF-8 encoding,
* which is always between 1 and 4 except on errors
*/
usize utf8_chrsize(nchar c, error *err);
/**
* UTF-8 encode a Unicode character and store it in `dest` with NUL terminator.
* @brief UTF-8 encode a Unicode character and store it in `dest` with NUL terminator.
*
* The buffer needs to hold at least 5 bytes. If the character is outside of
* the Unicode range (`0x00000000`~`0x0010ffff`), an error is yeeted and the
* buffer is not modified.
*
* @param dest: Where to store the encoded character (*not* NUL terminated)
* @param c: Character to encode
* @param err: Error pointer
* @param dest Where to store the encoded character (*not* NUL terminated)
* @param c Character to encode
* @param err Error pointer
* @returns The amount of bytes taken up by the character,
* which is always between 1 and 4 except on errors
*/
usize utf8_from_nchr(char *restrict dest, nchar c, error *err);
/**
* Decode a UTF-8 character and store it in `c`.
* @brief Decode a UTF-8 character and store it in `c`.
*
* If the character encoding is malformed, an error is yeeted and `c` is set to
* the ASCII NUL character. The encoded character does not need to be NUL
@ -101,9 +101,9 @@ usize utf8_from_nchr(char *restrict dest, nchar c, error *err);
* this may cause the method to read up to 3 bytes over the end of the buffer
* if the code sequence is malformed.
*
* @param c: Where to store the decoded character
* @param utf8chr: UTF-8 encoded character sequence
* @param err: Error pointer
* @param c Where to store the decoded character
* @param utf8chr UTF-8 encoded character sequence
* @param err Error pointer
* @returns The amount of bytes the character took up when encoded as UTF-8,
* which is always between 1 and 4 except on errors
*/

View file

@ -17,6 +17,50 @@ configure_file(
${CMAKE_BINARY_DIR}/include/neo/buildconfig.h
)
option(BUILD_DOCS "Build documentation" ON)
option(BUILD_DOCS_HTML "Build documentation in HTML format" ON)
option(BUILD_DOCS_LATEX "Build documentation in LaTEX format" OFF)
option(BUILD_DOCS_RTF "Build documentation in Rich Text Format" OFF)
option(BUILD_DOCS_XML "Build documentation in XML format" OFF)
if(BUILD_DOCS)
find_package(Doxygen REQUIRED)
set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/../doc/Doxyfile.in)
set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
if(BUILD_DOCS_HTML)
set(neo_BUILD_DOCS_HTML YES)
else()
set(neo_BUILD_DOCS_HTML NO)
endif()
if(BUILD_DOCS_LATEX)
set(neo_BUILD_DOCS_LATEX YES)
else()
set(neo_BUILD_DOCS_LATEX NO)
endif()
if(BUILD_DOCS_RTF)
set(neo_BUILD_DOCS_RTF YES)
else()
set(neo_BUILD_DOCS_RTF NO)
endif()
if(BUILD_DOCS_XML)
set(neo_BUILD_DOCS_XML YES)
else()
set(neo_BUILD_DOCS_XML NO)
endif()
add_custom_target(neo_docs ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Building documentation"
VERBATIM
)
endif()
target_include_directories(neo PUBLIC ../include)
target_include_directories(neo PRIVATE
./include