tor

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

smartlist_split.c (2337B)


      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 smartlist_split.c
      8 * \brief Split a string into a smartlist_t of substrings.
      9 **/
     10 
     11 #include "lib/smartlist_core/smartlist_core.h"
     12 #include "lib/smartlist_core/smartlist_split.h"
     13 
     14 #include "lib/err/torerr.h"
     15 #include "lib/string/util_string.h"
     16 #include "lib/string/compat_ctype.h"
     17 #include "lib/malloc/malloc.h"
     18 
     19 #include <string.h>
     20 
     21 /**
     22 * Split a string <b>str</b> along all occurrences of <b>sep</b>,
     23 * appending the (newly allocated) split strings, in order, to
     24 * <b>sl</b>.  Return the number of strings added to <b>sl</b>.
     25 *
     26 * If <b>flags</b>&amp;SPLIT_SKIP_SPACE is true, remove initial and
     27 * trailing space from each entry.
     28 * If <b>flags</b>&amp;SPLIT_IGNORE_BLANK is true, remove any entries
     29 * of length 0.
     30 * If <b>flags</b>&amp;SPLIT_STRIP_SPACE is true, strip spaces from each
     31 * split string.
     32 *
     33 * If <b>max</b>\>0, divide the string into no more than <b>max</b> pieces. If
     34 * <b>sep</b> is NULL, split on any sequence of horizontal space.
     35 */
     36 int
     37 smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
     38                       int flags, int max)
     39 {
     40  const char *cp, *end, *next;
     41  int n = 0;
     42 
     43  raw_assert(sl);
     44  raw_assert(str);
     45 
     46  cp = str;
     47  while (1) {
     48    if (flags&SPLIT_SKIP_SPACE) {
     49      while (TOR_ISSPACE(*cp)) ++cp;
     50    }
     51 
     52    if (max>0 && n == max-1) {
     53      end = strchr(cp,'\0');
     54    } else if (sep) {
     55      end = strstr(cp,sep);
     56      if (!end)
     57        end = strchr(cp,'\0');
     58    } else {
     59      for (end = cp; *end && *end != '\t' && *end != ' '; ++end)
     60        ;
     61    }
     62 
     63    raw_assert(end);
     64 
     65    if (!*end) {
     66      next = NULL;
     67    } else if (sep) {
     68      next = end+strlen(sep);
     69    } else {
     70      next = end+1;
     71      while (*next == '\t' || *next == ' ')
     72        ++next;
     73    }
     74 
     75    if (flags&SPLIT_SKIP_SPACE) {
     76      while (end > cp && TOR_ISSPACE(*(end-1)))
     77        --end;
     78    }
     79    if (end != cp || !(flags&SPLIT_IGNORE_BLANK)) {
     80      char *string = tor_strndup(cp, end-cp);
     81      if (flags&SPLIT_STRIP_SPACE)
     82        tor_strstrip(string, " ");
     83      smartlist_add(sl, string);
     84      ++n;
     85    }
     86    if (!next)
     87      break;
     88    cp = next;
     89  }
     90 
     91  return n;
     92 }