Move string-splitting into a separate function

svn:r2263
This commit is contained in:
Nick Mathewson 2004-08-17 21:06:36 +00:00
parent 2c002b1533
commit 7cb93e5bb6
4 changed files with 78 additions and 34 deletions

View File

@ -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
*/
struct strmap_entry_t {

View File

@ -158,6 +158,9 @@ void *smartlist_del(smartlist_t *sl, int idx);
void *smartlist_del_keeporder(smartlist_t *sl, int idx);
void smartlist_insert(smartlist_t *sl, int idx, void *val);
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) \
do { \
int sl_idx, sl_len=smartlist_len(sl); \

View File

@ -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>.
* 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
@ -202,7 +169,7 @@ static int config_compare(struct config_line_t *c, const char *key, config_type_
case CONFIG_TYPE_CSV:
if(*(smartlist_t**)arg == NULL)
*(smartlist_t**)arg = smartlist_create();
parse_csv_into_smartlist(*(smartlist_t**)arg, c->value);
smartlist_split_string(*(smartlist_t**)arg, c->value, ",", 1);
break;
case CONFIG_TYPE_LINELIST:
/* Note: this reverses the order that the lines appear in. That's

View File

@ -550,6 +550,40 @@ test_util() {
test_eq((void*)3, smartlist_get(sl,3));
test_eq((void*)4, smartlist_get(sl,4));
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. */
smartlist_free(sl);
}