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>&SPLIT_SKIP_SPACE is true, remove initial and 27 * trailing space from each entry. 28 * If <b>flags</b>&SPLIT_IGNORE_BLANK is true, remove any entries 29 * of length 0. 30 * If <b>flags</b>&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 }