diff --git a/include/klibc/kstring.h b/include/klibc/kstring.h index fc6c3bfa7dd..9ccd7363724 100644 --- a/include/klibc/kstring.h +++ b/include/klibc/kstring.h @@ -25,6 +25,7 @@ rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count); char *rt_strdup(const char *s); rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen); char *rt_strstr(const char *str1, const char *str2); +char *rt_strnstr(const char *s1, const char *s2, rt_size_t maxlen); rt_int32_t rt_strcasecmp(const char *a, const char *b); char *rt_strcpy(char *dst, const char *src); char *rt_strncpy(char *dest, const char *src, rt_size_t n); diff --git a/src/klibc/Kconfig b/src/klibc/Kconfig index bc90e90e8fa..bca097b38c0 100644 --- a/src/klibc/Kconfig +++ b/src/klibc/Kconfig @@ -178,6 +178,12 @@ menu "klibc options" endif endmenu # rt_strstr options + menu "rt_strnstr options" + config RT_KLIBC_USING_USER_STRNSTR + bool "Enable rt_strnstr to use user-defined version" + default n + endmenu # rt_strnstr options + menu "rt_strcasecmp options" config RT_KLIBC_USING_USER_STRCASECMP bool "Enable rt_strcasecmp to use user-defined version" diff --git a/src/klibc/kstring.c b/src/klibc/kstring.c index d2988d629cb..e93783ff2f1 100644 --- a/src/klibc/kstring.c +++ b/src/klibc/kstring.c @@ -313,6 +313,62 @@ char *rt_strstr(const char *s1, const char *s2) #endif /* RT_KLIBC_USING_USER_STRSTR */ RTM_EXPORT(rt_strstr); +/** + * @brief This function will return the first occurrence of a string, without the + * terminator '\0'. + * + * @param s1 is the source string. + * + * @param s2 is the find string. + * + * @param maxlen is the max size. + * + * @return The first occurrence of a s2 in s1, or RT_NULL if no found. + */ +#ifndef RT_KLIBC_USING_USER_STRNSTR +char *rt_strnstr(const char *s1, const char *s2, rt_size_t maxlen) +{ + rt_size_t l1 = 0, l2 = 0; + int max_pos = 0; + + l2 = rt_strlen(s2); + if (!l2) + { + return (char *)s1; + } + + l1 = rt_strlen(s1); + if (!l1) + { + return RT_NULL; + } + + max_pos = maxlen < l1 ? maxlen : l1; + if (max_pos < l2) + { + return RT_NULL; + } + + max_pos = max_pos - l2; + while (max_pos >= 0) + { + if (*s1 == *s2) + { + if (!rt_strncmp(s1, s2, l2)) + { + return (char *)s1; + } + } + + s1++; + max_pos--; + } + + return RT_NULL; +} +#endif /* RT_KLIBC_USING_USER_STRNSTR */ +RTM_EXPORT(rt_strnstr); + /** * @brief This function will compare two strings while ignoring differences in case *