Loading src/common/util.c +40 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading src/common/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); \ Loading src/or/config.c +1 −34 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading src/or/test.c +34 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading
src/common/util.c +40 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
src/common/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); \ Loading
src/or/config.c +1 −34 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading
src/or/test.c +34 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading