From f103f95b11d087f07c0c48bf784cd9197e18f203 Mon Sep 17 00:00:00 2001 From: Michael Haggerty Date: Wed, 12 Sep 2012 16:04:46 +0200 Subject: [PATCH] string_list: add a function string_list_longest_prefix() Add a function that finds the longest string from a string_list that is a prefix of a given string. Signed-off-by: Michael Haggerty Signed-off-by: Junio C Hamano --- Documentation/technical/api-string-list.txt | 8 ++++++++ string-list.c | 20 +++++++++++++++++++ string-list.h | 8 ++++++++ t/t0063-string-list.sh | 30 +++++++++++++++++++++++++++++ test-string-list.c | 20 +++++++++++++++++++ 5 files changed, 86 insertions(+) diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt index 0f8b7cee3..32b35d918 100644 --- a/Documentation/technical/api-string-list.txt +++ b/Documentation/technical/api-string-list.txt @@ -75,6 +75,14 @@ Functions to be deleted. Preserve the order of the items that are retained. +`string_list_longest_prefix`:: + + Return the longest string within a string_list that is a + prefix (in the sense of prefixcmp()) of the specified string, + or NULL if no such prefix exists. This function does not + require the string_list to be sorted (it does a linear + search). + `print_string_list`:: Dump a string_list to stdout, useful mainly for debugging purposes. It diff --git a/string-list.c b/string-list.c index decfa747f..c54b81624 100644 --- a/string-list.c +++ b/string-list.c @@ -136,6 +136,26 @@ void filter_string_list(struct string_list *list, int free_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) { diff --git a/string-list.h b/string-list.h index 3a6a6dc39..5efd07b44 100644 --- a/string-list.h +++ b/string-list.h @@ -38,6 +38,14 @@ int for_each_string_list(struct string_list *list, void filter_string_list(struct string_list *list, int free_util, string_list_each_func_t want, void *cb_data); +/* + * Return the longest string in prefixes that is a prefix (in the + * sense of prefixcmp()) of string, or NULL if no such prefix exists. + * This function does not require the string_list to be sorted (it + * does a linear search). + */ +char *string_list_longest_prefix(const struct string_list *prefixes, const char *string); + /* Use these functions only on sorted lists: */ int string_list_has_string(const struct string_list *list, const char *string); diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh index dbfc05ebd..41c8826a7 100755 --- a/t/t0063-string-list.sh +++ b/t/t0063-string-list.sh @@ -17,6 +17,14 @@ test_split () { " } +test_longest_prefix () { + test "$(test-string-list longest_prefix "$1" "$2")" = "$3" +} + +test_no_longest_prefix () { + test_must_fail test-string-list longest_prefix "$1" "$2" +} + test_split "foo:bar:baz" ":" "-1" <|- */ + struct string_list prefixes = STRING_LIST_INIT_DUP; + int retval; + const char *prefix_string = argv[2]; + const char *string = argv[3]; + const char *match; + + parse_string_list(&prefixes, prefix_string); + match = string_list_longest_prefix(&prefixes, string); + if (match) { + printf("%s\n", match); + retval = 0; + } + else + retval = 1; + string_list_clear(&prefixes, 0); + return retval; + } + fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; -- 2.11.0