aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-08-17 21:06:36 +0000
committerNick Mathewson <nickm@torproject.org>2004-08-17 21:06:36 +0000
commit7cb93e5bb652bf365e66077bc6ad4e18f134ad0b (patch)
tree2c4b55ebe372fea17eebee880e648b3fbe42523c
parent2c002b1533b82299694598ab565923a05b3de574 (diff)
downloadtor-7cb93e5bb652bf365e66077bc6ad4e18f134ad0b.tar
tor-7cb93e5bb652bf365e66077bc6ad4e18f134ad0b.tar.gz
Move string-splitting into a separate function
svn:r2263
-rw-r--r--src/common/util.c40
-rw-r--r--src/common/util.h3
-rw-r--r--src/or/config.c35
-rw-r--r--src/or/test.c34
4 files changed, 78 insertions, 34 deletions
diff --git a/src/common/util.c b/src/common/util.c
index ff2b02371..43d6d41ab 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -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 {
diff --git a/src/common/util.h b/src/common/util.h
index 4c629a221..05a41db18 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -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); \
diff --git a/src/or/config.c b/src/or/config.c
index 716fb4d5c..fb099cad4 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -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
diff --git a/src/or/test.c b/src/or/test.c
index fa84b7ca8..80167bc57 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -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);
}