compat_string.c (1643B)
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 strtok_helper(char *cp, const char *sep) 30 { 31 if (sep[1]) { 32 while (*cp && strchr(sep, *cp)) 33 ++cp; 34 } else { 35 while (*cp && *cp == *sep) 36 ++cp; 37 } 38 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 tor_strtok_r_impl(char *str, const char *sep, char **lasts) 46 { 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; 58 } 59 60 if (sep[1]) { 61 while (*cp && !strchr(sep, *cp)) 62 ++cp; 63 } else { 64 cp = strchr(cp, *sep); 65 } 66 67 if (!cp || !*cp) { 68 *lasts = NULL; 69 } else { 70 *cp++ = '\0'; 71 *lasts = strtok_helper(cp, sep); 72 } 73 return start; 74 }