libc: add strtok_r implementation
This is a standard function and useful for applications.
Signed-off-by: Siddharth Chandrasekaran <siddharth@embedjournal.com>
diff --git a/lib/libc/minimal/include/string.h b/lib/libc/minimal/include/string.h
index 73a60e7..d2a7d6e 100644
--- a/lib/libc/minimal/include/string.h
+++ b/lib/libc/minimal/include/string.h
@@ -25,6 +25,7 @@
extern size_t strnlen(const char *s, size_t maxlen);
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
+extern char *strtok_r(char *str, const char *sep, char **state);
extern char *strcat(char *_MLIBC_RESTRICT dest,
const char *_MLIBC_RESTRICT src);
extern char *strncat(char *_MLIBC_RESTRICT d, const char *_MLIBC_RESTRICT s,
diff --git a/lib/libc/minimal/source/string/string.c b/lib/libc/minimal/source/string/string.c
index 4dbc32d..9344f82 100644
--- a/lib/libc/minimal/source/string/string.c
+++ b/lib/libc/minimal/source/string/string.c
@@ -170,6 +170,45 @@
return (n == 0) ? 0 : (*s1 - *s2);
}
+/**
+ * @brief Separate `str` by any char in `sep` and return NULL terminated
+ * sections. Consecutive `sep` chars in `str` are treated as a single
+ * separator.
+ *
+ * @return pointer to NULL terminated string or NULL on errors.
+ */
+char *strtok_r(char *str, const char *sep, char **state)
+{
+ char *start, *end;
+
+ start = str ? str : *state;
+
+ /* skip leading delimiters */
+ while (*start && strchr(sep, *start)) {
+ start++;
+ }
+
+ if (*start == '\0') {
+ *state = start;
+ return NULL;
+ }
+
+ /* look for token chars */
+ end = start;
+ while (*end && !strchr(sep, *end)) {
+ end++;
+ }
+
+ if (*end != '\0') {
+ *end = '\0';
+ *state = end + 1;
+ } else {
+ *state = end;
+ }
+
+ return start;
+}
+
char *strcat(char *_MLIBC_RESTRICT dest, const char *_MLIBC_RESTRICT src)
{
strcpy(dest + strlen(dest), src);