Line data Source code
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 */ 5 : 6 : /** 7 : * \file compat_string.c 8 : * \brief Useful string-processing functions that some platforms don't 9 : * provide. 10 : **/ 11 : 12 : #include "lib/string/compat_string.h" 13 : #include "lib/err/torerr.h" 14 : 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 22 : 23 : #include <stdlib.h> 24 : #include <string.h> 25 : 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 63 : strtok_helper(char *cp, const char *sep) 30 : { 31 63 : if (sep[1]) { 32 39 : while (*cp && strchr(sep, *cp)) 33 13 : ++cp; 34 : } else { 35 51 : while (*cp && *cp == *sep) 36 14 : ++cp; 37 : } 38 63 : return cp; 39 : } 40 : 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 65 : tor_strtok_r_impl(char *str, const char *sep, char **lasts) 46 : { 47 65 : char *cp, *start; 48 65 : raw_assert(*sep); 49 65 : if (str) { 50 18 : str = strtok_helper(str, sep); 51 18 : if (!*str) 52 : return NULL; 53 8 : start = cp = *lasts = str; 54 47 : } else if (!*lasts || !**lasts) { 55 : return NULL; 56 : } else { 57 : start = cp = *lasts; 58 : } 59 : 60 47 : if (sep[1]) { 61 132 : while (*cp && !strchr(sep, *cp)) 62 111 : ++cp; 63 : } else { 64 26 : cp = strchr(cp, *sep); 65 : } 66 : 67 47 : if (!cp || !*cp) { 68 2 : *lasts = NULL; 69 : } else { 70 45 : *cp++ = '\0'; 71 45 : *lasts = strtok_helper(cp, sep); 72 : } 73 : return start; 74 : }