Merge branch 'tor-gitlab/mr/583' into maint-0.4.7
[tor.git] / src / lib / string / compat_string.c
blobc7d809c997c73d6d88aaf6a48a142e89e570f3fd
1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file compat_string.c
8 * \brief Useful string-processing functions that some platforms don't
9 * provide.
10 **/
12 #include "lib/string/compat_string.h"
13 #include "lib/err/torerr.h"
15 /* Inline the strl functions if the platform doesn't have them. */
16 #ifndef HAVE_STRLCPY
17 #include "ext/strlcpy.c"
18 #endif
19 #ifndef HAVE_STRLCAT
20 #include "ext/strlcat.c"
21 #endif
23 #include <stdlib.h>
24 #include <string.h>
26 /** Helper for tor_strtok_r_impl: Advances cp past all characters in
27 * <b>sep</b>, and returns its new value. */
28 static char *
29 strtok_helper(char *cp, const char *sep)
31 if (sep[1]) {
32 while (*cp && strchr(sep, *cp))
33 ++cp;
34 } else {
35 while (*cp && *cp == *sep)
36 ++cp;
38 return cp;
41 /** Implementation of strtok_r for platforms whose coders haven't figured out
42 * how to write one. Hey, retrograde libc developers! You can use this code
43 * here for free! */
44 char *
45 tor_strtok_r_impl(char *str, const char *sep, char **lasts)
47 char *cp, *start;
48 raw_assert(*sep);
49 if (str) {
50 str = strtok_helper(str, sep);
51 if (!*str)
52 return NULL;
53 start = cp = *lasts = str;
54 } else if (!*lasts || !**lasts) {
55 return NULL;
56 } else {
57 start = cp = *lasts;
60 if (sep[1]) {
61 while (*cp && !strchr(sep, *cp))
62 ++cp;
63 } else {
64 cp = strchr(cp, *sep);
67 if (!cp || !*cp) {
68 *lasts = NULL;
69 } else {
70 *cp++ = '\0';
71 *lasts = strtok_helper(cp, sep);
73 return start;