mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-09-20 21:16:22 +02:00
Move string-splitting into a separate function
svn:r2263
This commit is contained in:
parent
2c002b1533
commit
7cb93e5bb6
@ -481,6 +481,46 @@ void smartlist_insert(smartlist_t *sl, int idx, void *val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a string <b>str</b> along all occurences of <b>sep</b>, adding the
|
||||||
|
* split strings, in order, to <b>sl</b>. If <b>skipSpace</b> is true,
|
||||||
|
* remove initial and trailing space from each entry.
|
||||||
|
*/
|
||||||
|
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
|
||||||
|
int skipSpace)
|
||||||
|
{
|
||||||
|
const char *cp, *end, *next;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
tor_assert(sl && str && sep);
|
||||||
|
|
||||||
|
cp = str;
|
||||||
|
while (1) {
|
||||||
|
if (skipSpace) {
|
||||||
|
while (isspace(*cp)) ++cp;
|
||||||
|
}
|
||||||
|
end = strstr(cp,sep);
|
||||||
|
if (!end) {
|
||||||
|
end = strchr(cp,'\0');
|
||||||
|
next = NULL;
|
||||||
|
} else {
|
||||||
|
next = end+strlen(sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipSpace) {
|
||||||
|
while (end > cp && isspace(*(end-1)))
|
||||||
|
--end;
|
||||||
|
}
|
||||||
|
smartlist_add(sl, tor_strndup(cp, end-cp));
|
||||||
|
++n;
|
||||||
|
if (!next)
|
||||||
|
break;
|
||||||
|
cp = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/* Splay-tree implementation of string-to-void* map
|
/* Splay-tree implementation of string-to-void* map
|
||||||
*/
|
*/
|
||||||
struct strmap_entry_t {
|
struct strmap_entry_t {
|
||||||
|
@ -158,6 +158,9 @@ void *smartlist_del(smartlist_t *sl, int idx);
|
|||||||
void *smartlist_del_keeporder(smartlist_t *sl, int idx);
|
void *smartlist_del_keeporder(smartlist_t *sl, int idx);
|
||||||
void smartlist_insert(smartlist_t *sl, int idx, void *val);
|
void smartlist_insert(smartlist_t *sl, int idx, void *val);
|
||||||
int smartlist_len(const smartlist_t *sl);
|
int smartlist_len(const smartlist_t *sl);
|
||||||
|
int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep,
|
||||||
|
int skipSpace);
|
||||||
|
|
||||||
#define SMARTLIST_FOREACH(sl, type, var, cmd) \
|
#define SMARTLIST_FOREACH(sl, type, var, cmd) \
|
||||||
do { \
|
do { \
|
||||||
int sl_idx, sl_len=smartlist_len(sl); \
|
int sl_idx, sl_len=smartlist_len(sl); \
|
||||||
|
@ -128,39 +128,6 @@ static void config_free_lines(struct config_line_t *front) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a list of comma-separated entries, each surrounded by optional
|
|
||||||
* whitespace, insert copies of the entries (in order) into lst, without
|
|
||||||
* their surrounding whitespace.
|
|
||||||
*/
|
|
||||||
static void parse_csv_into_smartlist(smartlist_t *lst, const char *val)
|
|
||||||
{
|
|
||||||
const char *cp, *start, *end;
|
|
||||||
|
|
||||||
cp = val;
|
|
||||||
while (1) {
|
|
||||||
while (isspace(*cp))
|
|
||||||
++cp;
|
|
||||||
start = cp;
|
|
||||||
end = strchr(cp, ',');
|
|
||||||
if (!end)
|
|
||||||
end = strchr(cp, '\0');
|
|
||||||
for (cp=end-1; cp>=start && isspace(*cp); --cp)
|
|
||||||
;
|
|
||||||
/* Now start points to the first nonspace character of an entry,
|
|
||||||
* end points to the terminator of that entry,
|
|
||||||
* and cp points to the last nonspace character of an entry. */
|
|
||||||
tor_assert(start <= cp);
|
|
||||||
tor_assert(cp <= end);
|
|
||||||
tor_assert(*end == '\0' || *end == ',');
|
|
||||||
tor_assert((!isspace(*start) && !isspace(*cp)) || start==cp);
|
|
||||||
smartlist_add(lst, tor_strndup(start, cp-start+1));
|
|
||||||
if (!*end)
|
|
||||||
break;
|
|
||||||
cp = end+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Search the linked list <b>c</b> for any option whose key is <b>key</b>.
|
/** Search the linked list <b>c</b> for any option whose key is <b>key</b>.
|
||||||
* If such an option is found, interpret it as of type <b>type</b>, and store
|
* If such an option is found, interpret it as of type <b>type</b>, and store
|
||||||
* the result in <b>arg</b>. If the option is misformatted, log a warning and
|
* the result in <b>arg</b>. If the option is misformatted, log a warning and
|
||||||
@ -202,7 +169,7 @@ static int config_compare(struct config_line_t *c, const char *key, config_type_
|
|||||||
case CONFIG_TYPE_CSV:
|
case CONFIG_TYPE_CSV:
|
||||||
if(*(smartlist_t**)arg == NULL)
|
if(*(smartlist_t**)arg == NULL)
|
||||||
*(smartlist_t**)arg = smartlist_create();
|
*(smartlist_t**)arg = smartlist_create();
|
||||||
parse_csv_into_smartlist(*(smartlist_t**)arg, c->value);
|
smartlist_split_string(*(smartlist_t**)arg, c->value, ",", 1);
|
||||||
break;
|
break;
|
||||||
case CONFIG_TYPE_LINELIST:
|
case CONFIG_TYPE_LINELIST:
|
||||||
/* Note: this reverses the order that the lines appear in. That's
|
/* Note: this reverses the order that the lines appear in. That's
|
||||||
|
@ -550,6 +550,40 @@ test_util() {
|
|||||||
test_eq((void*)3, smartlist_get(sl,3));
|
test_eq((void*)3, smartlist_get(sl,3));
|
||||||
test_eq((void*)4, smartlist_get(sl,4));
|
test_eq((void*)4, smartlist_get(sl,4));
|
||||||
test_eq((void*)555, smartlist_get(sl,5));
|
test_eq((void*)555, smartlist_get(sl,5));
|
||||||
|
|
||||||
|
smartlist_clear(sl);
|
||||||
|
smartlist_split_string(sl, "abc", ":", 0);
|
||||||
|
test_eq(1, smartlist_len(sl));
|
||||||
|
test_streq("abc", smartlist_get(sl, 0));
|
||||||
|
smartlist_split_string(sl, "a::bc::", "::", 0);
|
||||||
|
test_eq(4, smartlist_len(sl));
|
||||||
|
test_streq("a", smartlist_get(sl, 1));
|
||||||
|
test_streq("bc", smartlist_get(sl, 2));
|
||||||
|
test_streq("", smartlist_get(sl, 3));
|
||||||
|
smartlist_split_string(sl, "/def/ /ghijk", "/", 0);
|
||||||
|
test_eq(8, smartlist_len(sl));
|
||||||
|
test_streq("", smartlist_get(sl, 4));
|
||||||
|
test_streq("def", smartlist_get(sl, 5));
|
||||||
|
test_streq(" ", smartlist_get(sl, 6));
|
||||||
|
test_streq("ghijk", smartlist_get(sl, 7));
|
||||||
|
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||||
|
smartlist_clear(sl);
|
||||||
|
|
||||||
|
smartlist_split_string(sl, "a,bbd,cdef", ",", 1);
|
||||||
|
test_eq(3, smartlist_len(sl));
|
||||||
|
test_streq("a", smartlist_get(sl,0));
|
||||||
|
test_streq("bbd", smartlist_get(sl,1));
|
||||||
|
test_streq("cdef", smartlist_get(sl,2));
|
||||||
|
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>", 1);
|
||||||
|
test_eq(8, smartlist_len(sl));
|
||||||
|
test_streq("z", smartlist_get(sl,3));
|
||||||
|
test_streq("zhasd", smartlist_get(sl,4));
|
||||||
|
test_streq("", smartlist_get(sl,5));
|
||||||
|
test_streq("bnud", smartlist_get(sl,6));
|
||||||
|
test_streq("", smartlist_get(sl,7));
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||||
|
|
||||||
/* XXXX test older functions. */
|
/* XXXX test older functions. */
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user