#ifndef VLIBC_STRING_H #define VLIBC_STRING_H /* * vlibc — . * * String and memory functions, gated by the active compatibility profile * (see include/vlibc/features.h). Levels are cumulative: * * Level 1 (onlyposix): ISO C core + POSIX.1-2008 base — memcpy, memmove, * memset, memchr, memcmp, strlen, strnlen, strcmp, * strncmp, strcpy, strncpy, strcat, strncat, strchr, * strrchr, strspn, strcspn, strpbrk, strstr, strtok, * strtok_r, strcoll, strxfrm, strdup, strndup, * strsignal. * Level 2 (muslmimic): BSD + XSI extensions — strlcpy, strlcat, stpcpy, * stpncpy, memccpy, strcoll_l, strxfrm_l. * Level 3 (muslext): GNU extensions — strcasestr. * * This header includes itself, so the gates below always * see the configured VLIBC_LEVEL even when the caller included no vlibc * header first, and for size_t. */ #include #include #ifdef __cplusplus extern "C" { #endif /* Level 1: ISO C core (always present). */ /* * Return the length of s, excluding the terminating NUL. * pure: reads memory, no side effects. */ __attribute__((pure)) size_t strlen(const char *s); /* * Return the length of s, excluding the terminating NUL, examining at most * maxlen bytes; the result is at most maxlen even when s is not a proper * NUL-terminated string. * pure: reads memory, no side effects. */ __attribute__((pure)) size_t strnlen(const char *s, size_t maxlen); /* * Compare the strings lhs and rhs; return negative, zero, or positive when * lhs is less than, equal to, or greater than rhs. * pure: reads memory, no side effects. */ __attribute__((pure)) int strcmp(const char *lhs, const char *rhs); /* * Compare at most n bytes of lhs and rhs, stopping early at the first * difference or the first NUL; return negative, zero, or positive when lhs * is less than, equal to, or greater than rhs. * pure: reads memory, no side effects. */ __attribute__((pure)) int strncmp(const char *lhs, const char *rhs, size_t n); /* * Compare s1 and s2 under the active locale's collating sequence; return * negative, zero, or positive. Only the "C" locale exists so far (locales * are owned by a later todo), where collation is identical to strcmp. * pure: reads memory, no side effects. */ __attribute__((pure)) int strcoll(const char *s1, const char *s2); /* * Copy n bytes from src to dst. The regions must not overlap (restrict). * No intent attribute: it writes memory. */ void * memcpy(void *restrict dst, const void *restrict src, size_t n); /* * Copy n bytes from src to dst. The regions may overlap, so the parameters * are deliberately not restrict. * No intent attribute: it writes memory. */ void * memmove(void *dst, const void *src, size_t n); /* * Fill n bytes at dst with c (converted to unsigned char). * No intent attribute: it writes memory. */ void * memset(void *dst, int c, size_t n); /* * Return a pointer to the first occurrence of c (converted to unsigned * char) among the first n bytes of s, or NULL when absent. * pure: reads memory, no side effects. */ __attribute__((pure)) void * memchr(const void *s, int c, size_t n); /* * Compare the first n bytes of lhs and rhs as unsigned char; return * negative, zero, or positive when lhs is less than, equal to, or greater * than rhs. Unlike strcmp, a NUL byte does not end the comparison. * pure: reads memory, no side effects. */ __attribute__((pure)) int memcmp(const void *lhs, const void *rhs, size_t n); /* * Copy src to dst, including the terminating NUL; return dst. The strings * must not overlap (restrict). * No intent attribute: it writes memory. */ char * strcpy(char *restrict dst, const char *restrict src); /* * Copy at most n bytes from src to dst. When src is shorter than n the * remainder of dst is NUL-padded; when src is n bytes or longer the result * is not NUL-terminated. Return dst. * No intent attribute: it writes memory. */ char * strncpy(char *restrict dst, const char *restrict src, size_t n); /* * Append src (including its NUL) to the end of dst; return dst. The strings * must not overlap (restrict). * No intent attribute: it writes memory. */ char * strcat(char *restrict dst, const char *restrict src); /* * Append at most n bytes of src to dst and always NUL-terminate; return * dst. * No intent attribute: it writes memory. */ char * strncat(char *restrict dst, const char *restrict src, size_t n); /* * Return a pointer to the first occurrence of c (converted to char) in s, * or NULL when absent. The terminating NUL is part of the string, so * strchr(s, '\0') returns a pointer to it. * pure: reads memory, no side effects. */ __attribute__((pure)) char * strchr(const char *s, int c); /* * Return a pointer to the last occurrence of c (converted to char) in s, or * NULL when absent. The terminating NUL is part of the string, so * strrchr(s, '\0') returns a pointer to it. * pure: reads memory, no side effects. */ __attribute__((pure)) char * strrchr(const char *s, int c); /* * Return the length of the initial span of s consisting entirely of bytes * that occur in accept. * pure: reads memory, no side effects. */ __attribute__((pure)) size_t strspn(const char *s, const char *accept); /* * Return the length of the initial span of s consisting entirely of bytes * that do NOT occur in reject. * pure: reads memory, no side effects. */ __attribute__((pure)) size_t strcspn(const char *s, const char *reject); /* * Return a pointer to the first byte in s that also occurs in accept, or * NULL when none occurs. * pure: reads memory, no side effects. */ __attribute__((pure)) char * strpbrk(const char *s, const char *accept); /* * Return a pointer to the first occurrence of needle in haystack, or NULL * when absent. An empty needle matches haystack itself. * pure: reads memory, no side effects. */ __attribute__((pure)) char * strstr(const char *haystack, const char *needle); /* * Split s into tokens delimited by any byte from sep. On the first call s * names the string; subsequent calls with NULL continue the same string. * Leading and consecutive delimiters produce no empty tokens, and the * delimiter bytes in s are overwritten with NUL. Returns NULL when no token * remains. strtok keeps its state in private static storage and is not * thread-safe; strtok_r keeps it in *state and is. * No intent attribute: strtok mutates private state, strtok_r writes * through its parameters. */ char * strtok(char *restrict s, const char *restrict sep); char * strtok_r(char *restrict s, const char *restrict sep, char **restrict state); /* * Transform src under the active locale's collating sequence so that strcmp * on transformed strings orders them as strcoll would, storing at most n * bytes of the result in dst (always NUL-terminated when n > 0; nothing is * written when n == 0). Return the length of the full transformed string, * excluding the NUL. In the "C" locale the transformation is the identity * and the return is strlen(src). * No intent attribute: it writes memory. */ size_t strxfrm(char *restrict dst, const char *restrict src, size_t n); /* * Return a heap copy of s (malloc-allocated; release with free), or NULL * with errno ENOMEM on allocation failure. strndup copies at most n bytes * and NUL-terminates, so strndup(s, 0) returns the empty string. * malloc: returns fresh unaliased storage the caller owns. */ __attribute__((malloc)) char * strdup(const char *s); __attribute__((malloc)) char * strndup(const char *s, size_t n); /* * Return a pointer to a static string describing the signal sig, or a * formatted "Unknown signal " string for unrecognized numbers. Never * returns NULL; distinct known signals yield distinct strings. The text for * signal 0 is unspecified by POSIX and deliberately not pinned. * * No intent attribute: the unknown-signal path writes shared storage. */ char * strsignal(int sig); #if VLIBC_LEVEL >= 2 /* Level 2 (muslmimic): BSD extensions. */ /* * Copy at most size - 1 bytes from src to dst and NUL-terminate the result; * return strlen(src). No NUL is written when size is 0. * No intent attribute: it writes memory. */ size_t strlcpy(char *dst, const char *src, size_t size); /* * Append src to dst, NUL-terminating within size bytes; return the length of * the string that would have been created without truncation. * No intent attribute: it writes memory. */ size_t strlcat(char *dst, const char *src, size_t size); #endif /* VLIBC_LEVEL >= 2 */ #if VLIBC_LEVEL_GE(2) /* Level 2 (muslmimic): XSI extensions. */ /* * strcpy/strncpy variants returning a pointer to the terminating NUL of * dst: stpcpy to the NUL of the copied string, stpncpy to the first NUL * written (or to dst + n when no NUL was written). * No intent attribute: they write memory. */ char * stpcpy(char *restrict dst, const char *restrict src); char * stpncpy(char *restrict dst, const char *restrict src, size_t n); /* * Copy at most n bytes from src to dst, stopping after the first byte equal * to c (converted to unsigned char); return a pointer to the byte after c * in dst when found, NULL otherwise. The regions must not overlap * (restrict). * No intent attribute: it writes memory. */ void * memccpy(void *restrict dst, const void *restrict src, int c, size_t n); /* * Locale-parameterized XSI variants of strcoll/strxfrm. No locale machinery * exists yet, so the locale argument is accepted and ignored and behavior * is the "C" locale behavior of the base functions. The locale parameter is * typed void * for now: locale_t will be an ABI-identical pointer typedef * defined by , whose todo updates these signatures to the real * type. */ __attribute__((pure)) int strcoll_l(const char *s1, const char *s2, void *locale); size_t strxfrm_l(char *restrict dst, const char *restrict src, size_t n, void *locale); #endif /* VLIBC_LEVEL_GE(2) */ #if VLIBC_LEVEL >= 3 /* Level 3 (muslext): GNU extensions. */ /* * Return a pointer to the first case-insensitive (ASCII fold) occurrence of * needle in haystack, or NULL if absent; an empty needle matches haystack. * pure: reads memory, no side effects. */ __attribute__((pure)) char * strcasestr(const char *haystack, const char *needle); #endif /* VLIBC_LEVEL >= 3 */ #ifdef __cplusplus } #endif #endif /* VLIBC_STRING_H */