Permalink
Cannot retrieve contributors at this time
92 lines (80 sloc)
2.28 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| /* Copyright (c) 2003-2004, Roger Dingledine | |
| * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. | |
| * Copyright (c) 2007-2020, 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 <string.h> | |
| /** | |
| * Split a string <b>str</b> along all occurrences of <b>sep</b>, | |
| * appending the (newly allocated) split strings, in order, to | |
| * <b>sl</b>. Return the number of strings added to <b>sl</b>. | |
| * | |
| * If <b>flags</b>&SPLIT_SKIP_SPACE is true, remove initial and | |
| * trailing space from each entry. | |
| * If <b>flags</b>&SPLIT_IGNORE_BLANK is true, remove any entries | |
| * of length 0. | |
| * If <b>flags</b>&SPLIT_STRIP_SPACE is true, strip spaces from each | |
| * split string. | |
| * | |
| * If <b>max</b>\>0, divide the string into no more than <b>max</b> pieces. If | |
| * <b>sep</b> 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; | |
| } |