tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }