aboutsummaryrefslogtreecommitdiff
path: root/src/lib/string/compat_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/string/compat_string.c')
-rw-r--r--src/lib/string/compat_string.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/lib/string/compat_string.c b/src/lib/string/compat_string.c
index 6df1bc4a1d..3f8a4d515d 100644
--- a/src/lib/string/compat_string.c
+++ b/src/lib/string/compat_string.c
@@ -4,6 +4,7 @@
/* See LICENSE for licensing information */
#include "lib/string/compat_string.h"
+#include "lib/err/torerr.h"
/* Inline the strl functions if the platform doesn't have them. */
#ifndef HAVE_STRLCPY
@@ -12,3 +13,55 @@
#ifndef HAVE_STRLCAT
#include "strlcat.c"
#endif
+
+#include <stdlib.h>
+
+/** Helper for tor_strtok_r_impl: Advances cp past all characters in
+ * <b>sep</b>, and returns its new value. */
+static char *
+strtok_helper(char *cp, const char *sep)
+{
+ if (sep[1]) {
+ while (*cp && strchr(sep, *cp))
+ ++cp;
+ } else {
+ while (*cp && *cp == *sep)
+ ++cp;
+ }
+ return cp;
+}
+
+/** Implementation of strtok_r for platforms whose coders haven't figured out
+ * how to write one. Hey, retrograde libc developers! You can use this code
+ * here for free! */
+char *
+tor_strtok_r_impl(char *str, const char *sep, char **lasts)
+{
+ char *cp, *start;
+ raw_assert(*sep);
+ if (str) {
+ str = strtok_helper(str, sep);
+ if (!*str)
+ return NULL;
+ start = cp = *lasts = str;
+ } else if (!*lasts || !**lasts) {
+ return NULL;
+ } else {
+ start = cp = *lasts;
+ }
+
+ if (sep[1]) {
+ while (*cp && !strchr(sep, *cp))
+ ++cp;
+ } else {
+ cp = strchr(cp, *sep);
+ }
+
+ if (!cp || !*cp) {
+ *lasts = NULL;
+ } else {
+ *cp++ = '\0';
+ *lasts = strtok_helper(cp, sep);
+ }
+ return start;
+}