You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
12 KiB
C
367 lines
12 KiB
C
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
#pragma once
|
|
|
|
#include <arch/string.h>
|
|
|
|
#include <gay/cdefs.h>
|
|
#include <gay/types.h>
|
|
|
|
/**
|
|
* @brief Copy up to `n` bytes from `src` to `dest`, but stop when the byte `c` is found.
|
|
* The regions `src` and `dest` must not overlap.
|
|
*
|
|
* @param dest Destination address
|
|
* @param src Source address
|
|
* @param c Stop character
|
|
* @param n Maximum number of bytes
|
|
* @return A pointer to the next character after `c`, or `NULL` if `c` was not
|
|
* encountered within the first `n` bytes
|
|
*/
|
|
void *memccpy(void *__restrict dest, const void *__restrict src, int c, usize n);
|
|
|
|
/**
|
|
* @brief Return the first occurrence of byte `c` within the first `n` bytes of `src`.
|
|
*
|
|
* @param src Start of buffer to search through
|
|
* @param c Character to search for
|
|
* @param n Maximum amount of bytes to search, starting from `src`
|
|
* @return The address of the found byte, or `NULL` if it was not found
|
|
* @note Because the run time of this function is not constant with respect
|
|
* to `n`, it should not be used in cryptographic operations.
|
|
*/
|
|
__pure void *memchr(const void *src, int c, usize n);
|
|
|
|
#if _GAY_SOURCE >= 202109L || __BSD_VISIBLE
|
|
/**
|
|
* @brief Return the last occurrence of byte `c` within the first `n` bytes of `src`.
|
|
* This function does the same thing as `memchr()` but in reverse direction.
|
|
*
|
|
* @param src Start of buffer to search through
|
|
* @param c Character to search for
|
|
* @param n Maximum amount of bytes to search, starting from `src`
|
|
* @return The address of the found byte, or `NULL` if it was not found
|
|
* @note Because the run time of this function is not constant with respect
|
|
* to `n`, it should not be used in cryptographic operations.
|
|
*/
|
|
__pure void *memrchr(const void *src, int c, usize n);
|
|
#endif /* _GAY_SOURCE >= 202109L || __BSD_VISIBLE */
|
|
|
|
/**
|
|
* @brief Copy `n` bytes from `src` to `dest`.
|
|
* The regions `src` and `dest` must not overlap.
|
|
*
|
|
* @param dest The destination
|
|
* @param src The source
|
|
* @param n The amount of bytes to copy
|
|
* @returns A pointer to `dest`
|
|
*/
|
|
void *memcpy(void *__restrict dest, const void *__restrict src, usize n);
|
|
|
|
/**
|
|
* @brief Compare two memory regions of size `n` for equality.
|
|
*
|
|
* @param s1 The first memory region
|
|
* @param s2 The second memory region
|
|
* @param n Amount of bytes to compare
|
|
* @return 0 if the first `n` bytes in `s1` and `s2` are found to be equal,
|
|
* or the difference between the first non equal bytes (interpreted as an
|
|
* `unsigned char`) such that the value is positive if the byte in `s1`
|
|
* is greater than the one in `s2`
|
|
* @note Because the run time of this function is not constant with respect
|
|
* to `n`, it should not be used in cryptographic operations.
|
|
*/
|
|
__pure int memcmp(const void *s1, const void *s2, usize n);
|
|
|
|
#ifndef __HAVE_ARCH_MEMSET
|
|
/**
|
|
* @brief Starting from `ptr`, fill `n` bytes with the constant byte `c`.
|
|
*
|
|
* @param ptr The start of the memory region
|
|
* @param c The byte to fill with
|
|
* @param n The amount of bytes to write
|
|
* @returns A pointer to `ptr`
|
|
*/
|
|
void *memset(void *ptr, int c, usize n);
|
|
#endif
|
|
|
|
#if _GAY_SOURCE >= 202109L
|
|
#ifndef __HAVE_ARCH_MEMSET16
|
|
void *memset16(u16 *dest, u16 c, usize nbyte);
|
|
#endif
|
|
#ifndef __HAVE_ARCH_MEMSET32
|
|
void *memset32(u32 *dest, u32 c, usize nbyte);
|
|
#endif
|
|
#ifndef __HAVE_ARCH_MEMSET64
|
|
void *memset64(u64 *dest, u64 c, usize nbyte);
|
|
#endif
|
|
|
|
#include <limits.h>
|
|
#if LONG_BIT == 32
|
|
#define memsetl memset32
|
|
#elif LONG_BIT == 64
|
|
#define memsetl memset64
|
|
#else
|
|
#error "Unsupported sizeof(long)"
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* @brief Copy a memory area.
|
|
* The two areas may overlap since the individual bytes are copied to a
|
|
* temporary array first.
|
|
*
|
|
* @param dest The destination address
|
|
* @param src The source address
|
|
* @param n The amount of bytes to copy
|
|
* @return a pointer to dest
|
|
*/
|
|
void *memmove(void *dest, const void *src, usize n);
|
|
|
|
/**
|
|
* @brief Compare the two strings `s1` and `s2`.
|
|
*
|
|
* @param s1 The first string
|
|
* @param s2 The second string
|
|
* @returns `0` if both strings are equal, a positive value f `s1` is greater
|
|
* than `s2`, and a negative value if `s1` is less than `s2`
|
|
*/
|
|
__pure int strcmp(const char *s1, const char *s2);
|
|
|
|
/**
|
|
* @brief Copy a `NUL` terminated string from `src` to `dest`.
|
|
* The `dest` and `src` regions must not overlap.
|
|
*
|
|
* @param dest The destination to copy to. The memory region must be able to
|
|
* hold the entire string plus one byte for the terminator.
|
|
* @param src The original string to copy from
|
|
* @returns A pointer to the destination string
|
|
*/
|
|
char *strcpy(char *dest, const char *src);
|
|
|
|
/**
|
|
* @brief Copy a `NUL` terminated string from `src` to `dest`, but at most `n` characters.
|
|
* Note that this may cause `dest` to miss a `NUL` terminator.
|
|
* The `dest` and `src` regions must not overlap.
|
|
*
|
|
* @param dest The destination to copy to. The memory region must be able to
|
|
* hold the entire string plus one byte for the terminator.
|
|
* @param src The original string to copy from
|
|
* @param n The amount of characters to copy at most
|
|
* @returns A pointer to the destination string
|
|
*/
|
|
char *strncpy(char *dest, const char *src, usize n);
|
|
|
|
#if _GAY_SOURCE >= 202109L || _POSIX_C_SOURCE >= 200809L
|
|
/** @brief The same as `strcpy()`, but the returned pointer is the NUL terminator of `dest`. */
|
|
char *stpcpy(char *__restrict dest, const char *__restrict src);
|
|
|
|
/** @brief The same as `strncpy()`, but the returned pointer is the NUL terminator of `dest`. */
|
|
char *stpncpy(char *__restrict dest, const char *__restrict src, usize n);
|
|
#endif /* _GAY_SOURCE >= 202109L || _POSIX_C_SOURCE >= 200809L */
|
|
|
|
/**
|
|
* @brief Append a NUL terminated string to another string.
|
|
* `s` must be sufficiently large to hold both strings.
|
|
*
|
|
* @param s String to append the other string to
|
|
* @param append String to append to `s`
|
|
* @return A pointer to `s`
|
|
*/
|
|
char *strcat(char *__restrict s, const char *__restrict append);
|
|
|
|
/**
|
|
* @brief Append a NUL terminated string to another string, but at most `count` bytes.
|
|
*
|
|
* @param s String to be appended to
|
|
* @param append String to append to `s`
|
|
* @param count Maximum amount of bytes to append, excluding the NUL terminator
|
|
* which is always appended at the end
|
|
* @return A pointer to `s`
|
|
*/
|
|
char *strncat(char *__restrict s, const char *__restrict append, usize count);
|
|
|
|
/**
|
|
* @brief Compare two strings for equality.
|
|
*
|
|
* @param s1 First string to compare
|
|
* @param s2 Second string to compare
|
|
* @param n Maximum amount of bytes (characters) to check. If a NUL terminator
|
|
* is encountered before this limit is reached, the comparison ends early.
|
|
* @return 0 if the strings are equal up to byte `n`, or the difference between
|
|
* the first non equal characters cast to an `unsigned char` (such that the
|
|
* return value becomes positive if the character in `s1` has a greater
|
|
* numerical value as the one in `s2`)
|
|
*/
|
|
int strncmp(const char *s1, const char *s2, usize n);
|
|
|
|
#if _GAY_SOURCE >= 202109L || __BSD_VISIBLE
|
|
/**
|
|
* @brief Append a NUL terminated string to another string, such that the
|
|
* resulting string is at most `dstsize` bytes long (including the NUL terminator) .
|
|
*
|
|
* @param s String to be appended to
|
|
* @param append String to append to `s`
|
|
* @param n Maximum total length of `s` in bytes
|
|
* @return A pointer to `s`
|
|
*/
|
|
usize strlcat(char *__restrict s, const char *__restrict append, usize dstsize);
|
|
|
|
/**
|
|
* @brief Copy the NUL terminated string `src` into dest, but at most `dstsize`
|
|
* bytes (including the NUL terminator, which is always appended).
|
|
*
|
|
* @param dest Destination address
|
|
* @param src Source string to copy from
|
|
* @param dstsize Maximum bytes (including NUL) to write to `dest`
|
|
* @return The amount of characters copied, including the NUL terminator
|
|
*/
|
|
usize strlcpy(char *__restrict dest, const char *__restrict src, usize dstsize);
|
|
#endif /* _GAY_SOURCE >= 202109L || __BSD_VISIBLE */
|
|
|
|
/**
|
|
* @brief Compute the length of the `NUL` terminated string `s`.
|
|
*
|
|
* @param s The string
|
|
* @returns The length of `s` without the `NUL` terminator
|
|
*/
|
|
__pure usize strlen(const char *s);
|
|
|
|
#if _POSIX_C_SOURCE >= 200809L || _GAY_SOURCE >= 202109L || __BSD_VISIBLE
|
|
/**
|
|
* @brief Compute the length of the `NUL` terminated string `s`, but at most `maxlen` bytes.
|
|
*
|
|
* @param s The string
|
|
* @param maxlen Maximum bytes after which to return
|
|
* @returns The length of `s` without the `NUL` terminator, but at most `maxlen`
|
|
*/
|
|
__pure size_t strnlen(const char *s, usize maxlen);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Search a string for any in a set of characters (excluding NUL).
|
|
*
|
|
* @param s String to search through
|
|
* @param find A set of characters to search for in `s`
|
|
* @return The first occurrence of one of the characters of `find` in `s`,
|
|
* or `NULL` if none were found
|
|
*/
|
|
__pure char *strpbrk(const char *s, const char *find);
|
|
|
|
/**
|
|
* @brief Span a string.
|
|
*
|
|
* @param s String to span
|
|
* @param charset Set of characters that should appear in `s`
|
|
* @return A pointer to the first character in `s` that *is not* within `charset`.
|
|
* @see `strcspn()`
|
|
*/
|
|
__pure usize strspn(const char *s, const char *charset);
|
|
|
|
/**
|
|
* @brief Span a string.
|
|
*
|
|
* @param s String to span
|
|
* @param charset Set of characters that may *not* appear in `s`
|
|
* @return A pointer to the first character in `s` that *is* within `charset`.
|
|
* @see `strspn()`
|
|
*/
|
|
__pure usize strcspn(const char *s, const char *charset);
|
|
|
|
/**
|
|
* @brief Find the first occurrence of `find` within `s`.
|
|
*
|
|
* @param s Haystack to search through
|
|
* @param find Needle to find
|
|
* @return A pointer to the beginning of the first occurrence of `find` in `s`,
|
|
* or `NULL` if it was not found
|
|
*/
|
|
__pure char *strstr(const char *s, const char *find);
|
|
|
|
#if _GAY_SOURCE >= 202109L || __BSD_VISIBLE
|
|
/**
|
|
* @brief Find the first occurrence of `find` within the first `slen` characters of `s`.
|
|
* If A NUL terminator is encountered in `s`, the search is aborted early.
|
|
*
|
|
* @param s Haystack to search through
|
|
* @param find Needle to find
|
|
* @param slen Maximum characters to search in `s`
|
|
* @return A pointer to the beginning of the first occurrence of `find` in `s`,
|
|
* or `NULL` if it was not found
|
|
*/
|
|
__pure char *strnstr(const char *s, const char *find, usize slen);
|
|
#endif /* _GAY_SOURCE >= 202109L || __BSD_VISIBLE */
|
|
|
|
/**
|
|
* @brief Duplicate a string.
|
|
*
|
|
* @param s String to duplicate
|
|
* @return A newly allocated copy of the string, or `NULL` if OOM
|
|
*/
|
|
__attribute__(( malloc ))
|
|
char *strdup(const char *s);
|
|
|
|
#if _POSIX_C_SOURCE >= 200809L
|
|
/**
|
|
* @brief Duplicate a string, but copy at most `maxlen` bytes (including NUL).
|
|
* New memory will be allocated.
|
|
*
|
|
* @param s String to duplicate
|
|
* @param maxlen Maximum length of the copied string in bytes
|
|
*/
|
|
__attribute__(( malloc ))
|
|
char *strndup(const char *s, usize maxlen);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Locate a character in a string.
|
|
*
|
|
* @param s String to search through
|
|
* @param c Character to search for
|
|
* @return The position of the *first* occurrence of `c` within `s`,
|
|
* or `NULL` if the character was not found
|
|
*/
|
|
__pure char *strchr(const char *s, int c);
|
|
|
|
#if _GAY_SOURCE >= 202109L || __BSD_VISIBLE
|
|
/**
|
|
* @brief Locate a character in a string in reverse order.
|
|
*
|
|
* @param s String to search through
|
|
* @param c Character to search for
|
|
* @return The position of the *last* occurrence of `c` within `s`,
|
|
* or `NULL` if the character was not found
|
|
*/
|
|
__pure char *strrchr(const char *s, int c);
|
|
|
|
/**
|
|
* @brief Locate a character in a string.
|
|
*
|
|
* @param s String to search through
|
|
* @param c Character to search for
|
|
* @return The position of the first occurrence of `c` within `s`,
|
|
* or the NUL terminator of `s` if the character was not not found
|
|
*/
|
|
__pure char *strchrnul(const char *s, int c);
|
|
|
|
/**
|
|
* @brief Separate a string into individual tokens.
|
|
* This is a slightly more sane replacement for `strtok()`.
|
|
*
|
|
* @param stringp Pointer to a `char *`, which will be advanced to one character
|
|
* after the first occurrence of one of the characters in `delim` (or NUL).
|
|
* The found delimiter is replaced with a NUL byte.
|
|
* @param delim A set of delimiter tokens
|
|
* @return The original value of `*stringp`, or `NULL` if it was `NULL`.
|
|
* If this points to a NUL terminator, the end of the string was reached.
|
|
*/
|
|
char *strsep(char **stringp, const char *delim);
|
|
#endif /* _GAY_SOURCE >= 202109L || __BSD_VISIBLE */
|
|
|
|
#ifndef _KERNEL /* we *really* don't want this anywhere in kernel code */
|
|
char *strtok(char *__restrict s, const char *__restrict tok);
|
|
# if _POSIX_C_SOURCE >= 199506L
|
|
char *strtok_r(char *s, const char *delim, char **last);
|
|
# endif /* _POSIX_C_SOURCE >= 199506L */
|
|
#endif /* not _KERNEL */
|