diff options
author | Junio C Hamano <gitster@pobox.com> | 2012-09-17 15:53:31 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-09-17 15:53:31 -0700 |
commit | 3b0b6b53d5fa8f7ea5d2d9ddb74b0f8186252d28 (patch) | |
tree | 7a08742c7be74c972b2ddbbf5848f0a805108290 /string-list.c | |
parent | Merge branch 'jc/maint-blame-no-such-path' (diff) | |
parent | api-string-list.txt: initialize the string_list the easy way (diff) | |
download | tgif-3b0b6b53d5fa8f7ea5d2d9ddb74b0f8186252d28.tar.xz |
Merge branch 'mh/string-list'
* mh/string-list:
api-string-list.txt: initialize the string_list the easy way
string_list: add a function string_list_longest_prefix()
string_list: add a new function, string_list_remove_duplicates()
string_list: add a new function, filter_string_list()
string_list: add two new functions for splitting strings
string_list: add function string_list_append_nodup()
Diffstat (limited to 'string-list.c')
-rw-r--r-- | string-list.c | 127 |
1 files changed, 122 insertions, 5 deletions
diff --git a/string-list.c b/string-list.c index d9810aba42..c54b816244 100644 --- a/string-list.c +++ b/string-list.c @@ -92,6 +92,23 @@ struct string_list_item *string_list_lookup(struct string_list *list, const char return list->items + i; } +void string_list_remove_duplicates(struct string_list *list, int free_util) +{ + if (list->nr > 1) { + int src, dst; + for (src = dst = 1; src < list->nr; src++) { + if (!strcmp(list->items[dst - 1].string, list->items[src].string)) { + if (list->strdup_strings) + free(list->items[src].string); + if (free_util) + free(list->items[src].util); + } else + list->items[dst++] = list->items[src]; + } + list->nr = dst; + } +} + int for_each_string_list(struct string_list *list, string_list_each_func_t fn, void *cb_data) { @@ -102,6 +119,43 @@ int for_each_string_list(struct string_list *list, return ret; } +void filter_string_list(struct string_list *list, int free_util, + string_list_each_func_t want, void *cb_data) +{ + int src, dst = 0; + for (src = 0; src < list->nr; src++) { + if (want(&list->items[src], cb_data)) { + list->items[dst++] = list->items[src]; + } else { + if (list->strdup_strings) + free(list->items[src].string); + if (free_util) + free(list->items[src].util); + } + } + list->nr = dst; +} + +char *string_list_longest_prefix(const struct string_list *prefixes, + const char *string) +{ + int i, max_len = -1; + char *retval = NULL; + + for (i = 0; i < prefixes->nr; i++) { + char *prefix = prefixes->items[i].string; + if (!prefixcmp(string, prefix)) { + int len = strlen(prefix); + if (len > max_len) { + retval = prefix; + max_len = len; + } + } + } + + return retval; +} + void string_list_clear(struct string_list *list, int free_util) { if (list->items) { @@ -148,13 +202,23 @@ void print_string_list(const struct string_list *p, const char *text) printf("%s:%p\n", p->items[i].string, p->items[i].util); } -struct string_list_item *string_list_append(struct string_list *list, const char *string) +struct string_list_item *string_list_append_nodup(struct string_list *list, + char *string) { + struct string_list_item *retval; ALLOC_GROW(list->items, list->nr + 1, list->alloc); - list->items[list->nr].string = - list->strdup_strings ? xstrdup(string) : (char *)string; - list->items[list->nr].util = NULL; - return list->items + list->nr++; + retval = &list->items[list->nr++]; + retval->string = string; + retval->util = NULL; + return retval; +} + +struct string_list_item *string_list_append(struct string_list *list, + const char *string) +{ + return string_list_append_nodup( + list, + list->strdup_strings ? xstrdup(string) : (char *)string); } static int cmp_items(const void *a, const void *b) @@ -194,3 +258,56 @@ void unsorted_string_list_delete_item(struct string_list *list, int i, int free_ list->items[i] = list->items[list->nr-1]; list->nr--; } + +int string_list_split(struct string_list *list, const char *string, + int delim, int maxsplit) +{ + int count = 0; + const char *p = string, *end; + + if (!list->strdup_strings) + die("internal error in string_list_split(): " + "list->strdup_strings must be set"); + for (;;) { + count++; + if (maxsplit >= 0 && count > maxsplit) { + string_list_append(list, p); + return count; + } + end = strchr(p, delim); + if (end) { + string_list_append_nodup(list, xmemdupz(p, end - p)); + p = end + 1; + } else { + string_list_append(list, p); + return count; + } + } +} + +int string_list_split_in_place(struct string_list *list, char *string, + int delim, int maxsplit) +{ + int count = 0; + char *p = string, *end; + + if (list->strdup_strings) + die("internal error in string_list_split_in_place(): " + "list->strdup_strings must not be set"); + for (;;) { + count++; + if (maxsplit >= 0 && count > maxsplit) { + string_list_append(list, p); + return count; + } + end = strchr(p, delim); + if (end) { + *end = '\0'; + string_list_append(list, p); + p = end + 1; + } else { + string_list_append(list, p); + return count; + } + } +} |