209 lines
7.1 KiB
C
209 lines
7.1 KiB
C
#ifndef VLIBC_STDLIB_H
|
|
#define VLIBC_STDLIB_H
|
|
|
|
/*
|
|
* vlibc — <stdlib.h>.
|
|
*
|
|
* This header is the shared home for the stdlib declarations; it currently
|
|
* holds only the memory-management family (todo 7). Later todos extend it
|
|
* in place: todo 11 adds the numeric conversions (atoi/strtol/strtod/...),
|
|
* todo 12 the pseudo-random and search/divide functions
|
|
* (rand/srand/qsort/bsearch/abs/div/...), and todo 13 the environment and
|
|
* multibyte helpers (getenv/setenv/mblen/mbtowc/...).
|
|
*
|
|
* Memory management functions, gated by the active compatibility profile
|
|
* (see include/vlibc/features.h). Levels are cumulative:
|
|
*
|
|
* Level 1 (onlyposix): ISO C core + POSIX base — malloc, free, calloc,
|
|
* realloc, aligned_alloc, posix_memalign.
|
|
* Level 2 (muslmimic): malloc_usable_size (BSD/musl).
|
|
*
|
|
* This header includes <vlibc/features.h> itself, so the gates below always
|
|
* see the configured VLIBC_LEVEL even when the caller included no vlibc
|
|
* header first, and <stddef.h> for size_t.
|
|
*/
|
|
|
|
#include <vlibc/features.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Level 1: memory management (always present). */
|
|
|
|
/*
|
|
* Allocate size bytes, 16-byte aligned. The memory is uninitialized.
|
|
* malloc(0) returns a unique minimum-size block (never NULL on success).
|
|
* NULL + errno ENOMEM on failure.
|
|
* malloc: the result does not alias any other pointer and has size bytes.
|
|
*/
|
|
__attribute__((malloc, alloc_size(1))) void *
|
|
malloc(size_t size);
|
|
|
|
/*
|
|
* Release the block at ptr, which must be NULL or a value returned by an
|
|
* earlier allocation in this family. free(NULL) is a no-op.
|
|
*/
|
|
void
|
|
free(void *ptr);
|
|
|
|
/*
|
|
* Allocate an array of nmemb elements of size bytes each, all bits zero.
|
|
* The product is overflow-checked: on overflow NULL + errno ENOMEM.
|
|
* calloc with a zero product returns a unique zeroed minimum-size block.
|
|
* malloc: the result does not alias any other pointer and has nmemb*size
|
|
* bytes.
|
|
*/
|
|
__attribute__((malloc, alloc_size(1, 2))) void *
|
|
calloc(size_t nmemb, size_t size);
|
|
|
|
/*
|
|
* Resize the block at ptr to size bytes, preserving the first min(old,
|
|
* size) bytes. realloc(NULL, size) behaves as malloc(size); realloc(ptr, 0)
|
|
* frees ptr and returns NULL. The old block is freed on success and left
|
|
* untouched on failure (NULL + errno ENOMEM).
|
|
* alloc_size(2): the result has size bytes.
|
|
*/
|
|
__attribute__((alloc_size(2))) void *
|
|
realloc(void *ptr, size_t size);
|
|
|
|
/*
|
|
* Allocate size bytes aligned to alignment. alignment must be a power of
|
|
* two that is a multiple of sizeof(void *), and size must be a multiple of
|
|
* alignment; a violation fails with NULL + errno EINVAL (a non-power-of-two
|
|
* alignment is undefined behavior in C23, so only well-formed arguments
|
|
* reach the allocator). size 0 returns NULL. The result is released with
|
|
* free.
|
|
* malloc + alloc_align(1): the result does not alias any other pointer and
|
|
* is aligned to alignment.
|
|
*/
|
|
__attribute__((malloc, alloc_size(2), alloc_align(1))) void *
|
|
aligned_alloc(size_t alignment, size_t size);
|
|
|
|
/*
|
|
* Allocate size bytes at address alignment and store the result in
|
|
* *memptr. alignment must be a power of two and a multiple of
|
|
* sizeof(void *). Returns 0 on success, EINVAL for a bad alignment, ENOMEM
|
|
* on allocation failure. Never sets errno itself, and never modifies
|
|
* *memptr on failure. size 0 returns a unique minimum-size block.
|
|
*/
|
|
__attribute__((access(write_only, 1))) int
|
|
posix_memalign(void **memptr, size_t alignment, size_t size);
|
|
|
|
#if VLIBC_LEVEL_GE(2)
|
|
/* Level 2 (muslmimic): BSD/musl extensions. */
|
|
|
|
/*
|
|
* Return the number of bytes actually available in the block at ptr,
|
|
* including any internal padding; at least as large as the requested size.
|
|
* ptr may be any block returned by the allocator family; NULL returns 0.
|
|
* pure: reads memory, no side effects.
|
|
*/
|
|
__attribute__((pure)) size_t
|
|
malloc_usable_size(void *ptr);
|
|
#endif /* VLIBC_LEVEL_GE(2) */
|
|
|
|
/* numeric conversions (todo 11) */
|
|
|
|
/*
|
|
* String-to-number conversions (C23 7.24.1). All are ISO C core / POSIX
|
|
* base and present in every profile.
|
|
*
|
|
* The ato* wrappers carry no error reporting: their behavior is undefined
|
|
* if the converted value cannot be represented (C23 7.24.1.1-2), so they
|
|
* read their input and nothing else — hence pure.
|
|
*
|
|
* The strto* functions report range errors through errno and store the
|
|
* scan position through endptr; both are real side effects, so they carry
|
|
* no intent attribute. errno behavior follows C23 7.24.1.4-5: ERANGE when
|
|
* the subject sequence is outside the representable range (the clamped
|
|
* maximum/minimum is returned); EINVAL when base is not 0 and not in
|
|
* [2, 36] (endptr left at nptr, 0 returned); endptr points at nptr when
|
|
* no subject sequence is present.
|
|
*/
|
|
|
|
/*
|
|
* Convert the initial decimal digits of nptr to int, discarding leading
|
|
* whitespace and an optional sign. Equivalent to (int)strtol(nptr, 0, 10).
|
|
* pure: reads memory, no side effects.
|
|
*/
|
|
__attribute__((pure)) int
|
|
atoi(const char *nptr);
|
|
|
|
/*
|
|
* As atoi, converted to long: strtol(nptr, 0, 10).
|
|
* pure: reads memory, no side effects.
|
|
*/
|
|
__attribute__((pure)) long
|
|
atol(const char *nptr);
|
|
|
|
/*
|
|
* As atoi, converted to long long: strtoll(nptr, 0, 10).
|
|
* pure: reads memory, no side effects.
|
|
*/
|
|
__attribute__((pure)) long long
|
|
atoll(const char *nptr);
|
|
|
|
/*
|
|
* As atoi, converted to double: strtod(nptr, 0).
|
|
* pure: reads memory, no side effects.
|
|
*/
|
|
__attribute__((pure)) double
|
|
atof(const char *nptr);
|
|
|
|
/*
|
|
* Convert the initial portion of nptr to long, stopping at the first
|
|
* character that is not part of the subject sequence and storing its
|
|
* position in *endptr (if endptr is not NULL). See the family comment for
|
|
* base, errno, and endptr semantics.
|
|
*/
|
|
long
|
|
strtol(const char *restrict nptr, char **restrict endptr, int base);
|
|
|
|
/*
|
|
* As strtol, converted to unsigned long. A subject sequence with a minus
|
|
* sign yields the negated value computed in the return type (modulo
|
|
* ULONG_MAX + 1) without a range error (C23 7.24.1.4p8).
|
|
*/
|
|
unsigned long
|
|
strtoul(const char *restrict nptr, char **restrict endptr, int base);
|
|
|
|
/*
|
|
* As strtol, converted to long long.
|
|
*/
|
|
long long
|
|
strtoll(const char *restrict nptr, char **restrict endptr, int base);
|
|
|
|
/*
|
|
* As strtol, converted to unsigned long long. Negative subject sequences
|
|
* wrap modulo ULLONG_MAX + 1 as for strtoul.
|
|
*/
|
|
unsigned long long
|
|
strtoull(const char *restrict nptr, char **restrict endptr, int base);
|
|
|
|
/*
|
|
* Convert the initial portion of nptr to float, double, or long double
|
|
* (C23 7.24.1.3): optional whitespace, optional sign, then either an
|
|
* "inf"/"infinity" or "nan"/"nan(n-char-sequence)" subject (case-
|
|
* insensitive), a hexadecimal floating subject ("0x1.8p1"), or a decimal
|
|
* floating subject with optional exponent. Overflow returns ±HUGE_VAL*
|
|
* with errno ERANGE; results too small to represent return a subnormal or
|
|
* zero value with errno ERANGE. no-conversion stores nptr in *endptr.
|
|
*/
|
|
double
|
|
strtod(const char *restrict nptr, char **restrict endptr);
|
|
|
|
float
|
|
strtof(const char *restrict nptr, char **restrict endptr);
|
|
|
|
long double
|
|
strtold(const char *restrict nptr, char **restrict endptr);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* VLIBC_STDLIB_H */
|