/* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * \file smartlist_split.c * \brief Split a string into a smartlist_t of substrings. **/ #include "lib/smartlist_core/smartlist_core.h" #include "lib/smartlist_core/smartlist_split.h" #include "lib/err/torerr.h" #include "lib/string/util_string.h" #include "lib/string/compat_ctype.h" #include "lib/malloc/malloc.h" #include /** * Split a string str along all occurrences of sep, * appending the (newly allocated) split strings, in order, to * sl. Return the number of strings added to sl. * * If flags&SPLIT_SKIP_SPACE is true, remove initial and * trailing space from each entry. * If flags&SPLIT_IGNORE_BLANK is true, remove any entries * of length 0. * If flags&SPLIT_STRIP_SPACE is true, strip spaces from each * split string. * * If max\>0, divide the string into no more than max pieces. If * sep is NULL, split on any sequence of horizontal space. */ int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max) { const char *cp, *end, *next; int n = 0; raw_assert(sl); raw_assert(str); cp = str; while (1) { if (flags&SPLIT_SKIP_SPACE) { while (TOR_ISSPACE(*cp)) ++cp; } if (max>0 && n == max-1) { end = strchr(cp,'\0'); } else if (sep) { end = strstr(cp,sep); if (!end) end = strchr(cp,'\0'); } else { for (end = cp; *end && *end != '\t' && *end != ' '; ++end) ; } raw_assert(end); if (!*end) { next = NULL; } else if (sep) { next = end+strlen(sep); } else { next = end+1; while (*next == '\t' || *next == ' ') ++next; } if (flags&SPLIT_SKIP_SPACE) { while (end > cp && TOR_ISSPACE(*(end-1))) --end; } if (end != cp || !(flags&SPLIT_IGNORE_BLANK)) { char *string = tor_strndup(cp, end-cp); if (flags&SPLIT_STRIP_SPACE) tor_strstrip(string, " "); smartlist_add(sl, string); ++n; } if (!next) break; cp = next; } return n; }