diff options
Diffstat (limited to 'src/vppinfra/string.c')
-rw-r--r-- | src/vppinfra/string.c | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/src/vppinfra/string.c b/src/vppinfra/string.c index b90f432c0cc..feae5b9165c 100644 --- a/src/vppinfra/string.c +++ b/src/vppinfra/string.c @@ -38,6 +38,12 @@ #include <vppinfra/string.h> #include <vppinfra/error.h> +/** + * @file + * @brief String Handling routines, including a performant + * implementation of many c-11 "safe" string functions. + */ + /* Exchanges source and destination. */ void clib_memswap (void *_a, void *_b, uword bytes) @@ -91,6 +97,25 @@ clib_c11_violation (const char *s) _clib_error (CLIB_ERROR_WARNING, (char *) __FUNCTION__, 0, (char *) s); } +/** + * @brief copy src to dest, at most n bytes, up to dmax + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *dest pointer to memory to copy to + * @param dmax maximum length of resulting dest + * @param *src pointer to memory to copy from + * @param n maximum number of characters to copy from src + * + * @constraints No null pointers + * n shall not be greater than dmax + * no memory overlap between src and dest + * + * @return EOK success + * EINVAL runtime constraint error + * + */ errno_t memcpy_s (void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n) @@ -98,12 +123,356 @@ memcpy_s (void *__restrict__ dest, rsize_t dmax, return memcpy_s_inline (dest, dmax, src, n); } +/** + * @brief set n bytes starting at s to the specified c value + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s pointer to memory to set the c value + * @param smax maximum length of resulting s + * @param c byte value + * @param n maximum number of characters to set in s + * + * @constraints No null pointers + * n shall not be greater than smax + * + * @return EOK success + * EINVAL runtime constraint error + * + */ errno_t memset_s (void *s, rsize_t smax, int c, rsize_t n) { return memset_s_inline (s, smax, c, n); } +/** + * @brief compare memory until they differ, and their difference is returned in + * diff + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s1 pointer to memory to compare against + * @param s1max maximum length of s1 + * @param *s2 pointer to memory to compare with s1 + * @param s2max length of s2 + * @param *diff pointer to the diff which is an integer greater than, equal to, + * or less than zero according to s1 is greater than, equal to, + * or less than s2. + * + * @constraints No null pointers + * s1max and s2max shall not be zero + * s2max shall not be greater than s1max + * + * @return EOK success + * diff when the return code is EOK + * >0 s1 greater s2 + * 0 s1 == s2 + * <0 s1 < s2 + * EINVAL runtime constraint error + * + */ +errno_t +memcmp_s (const void *s1, rsize_t s1max, const void *s2, rsize_t s2max, + int *diff) +{ + return memcmp_s_inline (s1, s1max, s2, s2max, diff); +} + +/** + * @brief compare string s2 to string s1, and their difference is returned in + * indicator + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s1 pointer to string to compare against + * @param s1max maximum length of s1, excluding null + * @param *s2 pointer to string to compare with s1 + * @param *indicator pointer to the comparison result, which is an integer + * greater than, equal to, or less than zero according to + * s1 is greater than, equal to, or less than s2. + * + * @constraints No null pointers + * s1max shall not be zero + * s1 shall be null terminated + * n shall not be greater than the smaller of s1max and strlen + * of s1 + * + * @return EOK success + * indicator when the return code is EOK + * >0 s1 greater s2 + * 0 s1 == s2 + * <0 s1 < s2 + * EINVAL runtime constraint error + * + */ +errno_t +strcmp_s (const char *s1, rsize_t s1max, const char *s2, int *indicator) +{ + return strcmp_s_inline (s1, s1max, s2, indicator); +} + +/** + * @brief compare string s2 to string s1, no more than n characters, and their + * difference is returned in indicator + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s1 pointer to string to compare against + * @param s1max maximum length of s1, excluding null + * @param *s2 pointer to string to compare with s1 + * @param n maximum number of characters to compare + * @param *indicator pointer to the comparison result, which is an integer + * greater than, equal to, or less than zero according to + * s1 is greater than, equal to, or less than s2. + * + * @constraints No null pointers + * s1max shall not be zero + * s1 shall be null terminated + * + * @return EOK success + * indicator when the return code is EOK + * >0 s1 greater s2 + * 0 s1 == s2 + * <0 s1 < s2 + * EINVAL runtime constraint error + * + */ +errno_t +strncmp_s (const char *s1, rsize_t s1max, const char *s2, rsize_t n, + int *indicator) +{ + return strncmp_s_inline (s1, s1max, s2, n, indicator); +} + +/** + * @brief copy src string to dest string + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *dest pointer to string to copy to + * @param dmax maximum length of resulting dest string, including null + * @param *src pointer to string to copy from + * + * @constraints No null pointers + * dmax shall not be zero + * dmax shall be greater than string length of src + * no memory overlap between src and dest + * + * @return EOK success + * EINVAL runtime constraint error + * + */ +errno_t +strcpy_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src) +{ + return strcpy_s_inline (dest, dmax, src); +} + +/** + * @brief copy src string to dest string, no more than n characters + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *dest pointer to string to copy to + * @param dmax maximum length of resulting dest string, including null + * @param *src pointer to string to copy from + * @param n maximum number of characters to copy from src, excluding null + * + * @constraints No null pointers + * dmax shall not be zero + * no memory overlap between src and dest + * + * @return EOK success + * EINVAL runtime constraint error + * EOVERFLOW truncated operation. dmax - 1 characters were copied. + * dest is null terminated. + * + */ +errno_t +strncpy_s (char *__restrict__ dest, rsize_t dmax, + const char *__restrict__ src, rsize_t n) +{ + return strncpy_s_inline (dest, dmax, src, n); +} + +/** + * @brief append src string to dest string, including null + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *dest pointer to string to append to + * @param dmax maximum length of resulting dest string, including null + * @param *src pointer to string to append from + * + * @constraints No null pointers + * dmax shall not be zero + * dest shall be null terminated + * given m = dmax - strnlen (dest, dmax) + * n = strnlen (src, m) + * n shall not be >= m + * no memory overlap between src and dest + * + * @return EOK success + * EINVAL runtime constraint error + * + */ +errno_t +strcat_s (char *__restrict__ dest, rsize_t dmax, const char *__restrict__ src) +{ + return strcat_s_inline (dest, dmax, src); +} + +/** + * @brief append src string to dest string, including null, no more than n + * characters + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *dest pointer to string to append to + * @param dmax maximum length of resulting dest string, including null + * @param *src pointer to string to append from + * @param n maximum characters to append (excluding null) + * + * @constraints No null pointers + * dmax shall not be zero + * dest shall be null terminated + * dmax - strnlen (dest, dmax) shall not be zero + * no memory overlap between src and dest + * + * @return EOK success + * EINVAL runtime constraint error + * EOVERFLOW truncated operation. dmax - 1 characters were appended. + * dest is null terminated. + * + */ +errno_t +strncat_s (char *__restrict__ dest, rsize_t dmax, + const char *__restrict__ src, rsize_t n) +{ + return strncat_s_inline (dest, dmax, src, n); +} + +/** + * @brief tokenize string s1 with delimiter specified in s2. This is a stateful + * API when it is iterately called, it returns the next token from s1 + * which is delimited by s2. s1max and ptr maintain the stateful + * information for the same caller and must not be altered by the + * caller during the iteration for the correct result + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s1 pointer to string to be searched for substring + * @param *s1max restricted maximum length of s1 + * @param *s2 pointer to substring to search (16 characters max, + * including null) + * @param **ptr in/out pointer which maintains the stateful information + * + * @constraints s2, s1max, and ptr shall not be null + * if s1 is null, contents of ptr shall not be null + * s1 and s2 shall be null terminated + * + * @return non-null pointer to the first character of a token + * s1max and ptr are modified to contain the state + * null runtime constraint error or token is not found + * + * @example + * char *str2 = " "; + * char str1[100]; + * uword len; + * char *p2str = 0; + * char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7; + * + * strncpy (str1, "brevity is the soul of wit", sizeof (str1)); + * len = strlen (str1); + * tok1 = strtok_s (str1, &len, str2, &p2str); + * tok2 = strtok_s (0, &len, str2, &p2str); + * tok3 = strtok_s (0, &len, str2, &p2str); + * tok4 = strtok_s (0, &len, str2, &p2str); + * tok5 = strtok_s (0, &len, str2, &p2str); + * tok6 = strtok_s (0, &len, str2, &p2str); + * tok7 = strtok_s (0, &len, str2, &p2str); + * + * After the above series of calls, + * tok1 = "brevity", tok2 = "is", tok3 = "the", tok4 = "soul", tok5 = "of", + * tok6 = "wit", tok7 = null + */ +char * +strtok_s (char *__restrict__ s1, rsize_t * __restrict__ s1max, + const char *__restrict__ s2, char **__restrict__ ptr) +{ + return strtok_s_inline (s1, s1max, s2, ptr); +} + +/** + * @brief compute the length in s, no more than maxsize + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s pointer to string + * @param maxsize restricted maximum length + * + * @constraints No null pointers + * maxsize shall not be zero + * + * @return size_t the string length in s, excluding null character, and no + * more than maxsize or 0 if there is a constraint error + * + */ +size_t +strnlen_s (const char *s, size_t maxsize) +{ + return strnlen_s_inline (s, maxsize); +} + +/** + * @brief locate the first occurrence of the substring s2 in s1 + * + * ISO/IEC 9899:2017(C11), Porgramming languages -- C + * Annex K; Bounds-checking interfaces + * + * @param *s1 pointer to string to be searched for substring + * @param s1max restricted maximum length of s1 + * @param *s2 pointer to substring to search + * @param s2max restricted maximum length of s2 + * @param **substring pointer to pointer substring to be returned + * + * @constraints No null pointers + * s1max and s2max shall not be zero + * s1 and s2 shall be null terminated + * + * @return EOK success + * substring when the return code is EOK, it contains the pointer which + * points to s1 that matches s2 + * EINVAL runtime constraint error + * ESRCH no match + * + * @example + * char *sub = 0; + * char *s1 = "success is not final, failure is not fatal."; + * + * strstr_s (s1, strlen (s1), "failure", strlen ("failure"), &sub); + * + * After the above call, + * sub = "failure is not fatal." + */ +errno_t +strstr_s (char *s1, rsize_t s1max, const char *s2, rsize_t s2max, + char **substring) +{ + return strstr_s_inline (s1, s1max, s2, s2max, substring); +} + /* * fd.io coding-style-patch-verification: ON * |