feat(string): complete string.h + strdup/memccpy
This commit is contained in:
+226
-2
@@ -7,8 +7,14 @@
|
||||
* String and memory functions, gated by the active compatibility profile
|
||||
* (see include/vlibc/features.h). Levels are cumulative:
|
||||
*
|
||||
* Level 1 (onlyposix): ISO C core — memcpy, memmove, memset, strlen, strcmp.
|
||||
* Level 2 (muslmimic): BSD extensions — strlcpy, strlcat.
|
||||
* 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 <vlibc/features.h> itself, so the gates below always
|
||||
@@ -33,6 +39,15 @@ extern "C" {
|
||||
__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.
|
||||
@@ -41,6 +56,24 @@ strlen(const char *s);
|
||||
__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.
|
||||
@@ -63,6 +96,157 @@ memmove(void *dst, const void *src, size_t n);
|
||||
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 <sig>" 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. */
|
||||
|
||||
@@ -83,6 +267,46 @@ 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 <locale.h>, 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. */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user