1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2019, 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;
}
|