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 <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Sep 12, 2012 at 16:04 UTC
f103f95b11d087f07c0c48bf784cd9197e18f203
5 files changed
+86
Documentation/technical/api-string-list.txt
+8
@@ -75,6 +75,14 @@ Functions
75
to be deleted. Preserve the order of the items that are
76
retained.
77
78
+`string_list_longest_prefix`::
79
+
80
+ Return the longest string within a string_list that is a
81
+ prefix (in the sense of prefixcmp()) of the specified string,
82
+ or NULL if no such prefix exists. This function does not
83
+ require the string_list to be sorted (it does a linear
84
+ search).
85
+
86
`print_string_list`::
87
88
Dump a string_list to stdout, useful mainly for debugging purposes. It
string-list.c
+20
@@ -136,6 +136,26 @@ void filter_string_list(struct string_list *list, int free_util,
136
list->nr = dst;
137
}
138
139
+char *string_list_longest_prefix(const struct string_list *prefixes,
140
+ const char *string)
141
+{
142
+ int i, max_len = -1;
143
+ char *retval = NULL;
144
+
145
+ for (i = 0; i < prefixes->nr; i++) {
146
+ char *prefix = prefixes->items[i].string;
147
+ if (!prefixcmp(string, prefix)) {
148
+ int len = strlen(prefix);
149
+ if (len > max_len) {
150
+ retval = prefix;
151
+ max_len = len;
152
+ }
153
+ }
154
+ }
155
+
156
+ return retval;
157
+}
158
+
159
void string_list_clear(struct string_list *list, int free_util)
160
{
161
if (list->items) {
string-list.h
+8
@@ -38,6 +38,14 @@ int for_each_string_list(struct string_list *list,
38
void filter_string_list(struct string_list *list, int free_util,
39
string_list_each_func_t want, void *cb_data);
40
41
+/*
42
+ * Return the longest string in prefixes that is a prefix (in the
43
+ * sense of prefixcmp()) of string, or NULL if no such prefix exists.
44
+ * This function does not require the string_list to be sorted (it
45
+ * does a linear search).
46
+ */
47
+char *string_list_longest_prefix(const struct string_list *prefixes, const char *string);
48
+
49
50
/* Use these functions only on sorted lists: */
51
int string_list_has_string(const struct string_list *list, const char *string);
t/t0063-string-list.sh
+30
@@ -17,6 +17,14 @@ test_split () {
17
"
18
}
19
20
+test_longest_prefix () {
21
+ test "$(test-string-list longest_prefix "$1" "$2")" = "$3"
22
+}
23
+
24
+test_no_longest_prefix () {
25
+ test_must_fail test-string-list longest_prefix "$1" "$2"
26
+}
27
+
28
test_split "foo:bar:baz" ":" "-1" <<EOF
29
3
30
[0]: "foo"
@@ -88,4 +96,26 @@ test_expect_success "test remove_duplicates" '
96
test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
97
'
98
99
+test_expect_success "test longest_prefix" '
100
+ test_no_longest_prefix - '' &&
101
+ test_no_longest_prefix - x &&
102
+ test_longest_prefix "" x "" &&
103
+ test_longest_prefix x x x &&
104
+ test_longest_prefix "" foo "" &&
105
+ test_longest_prefix : foo "" &&
106
+ test_longest_prefix f foo f &&
107
+ test_longest_prefix foo foobar foo &&
108
+ test_longest_prefix foo foo foo &&
109
+ test_no_longest_prefix bar foo &&
110
+ test_no_longest_prefix bar:bar foo &&
111
+ test_no_longest_prefix foobar foo &&
112
+ test_longest_prefix foo:bar foo foo &&
113
+ test_longest_prefix foo:bar bar bar &&
114
+ test_longest_prefix foo::bar foo foo &&
115
+ test_longest_prefix foo:foobar foo foo &&
116
+ test_longest_prefix foobar:foo foo foo &&
117
+ test_longest_prefix foo: bar "" &&
118
+ test_longest_prefix :foo bar ""
119
+'
120
+
121
test_done
test-string-list.c
+20
@@ -97,6 +97,26 @@ int main(int argc, char **argv)
97
return 0;
98
}
99
100
+ if (argc == 4 && !strcmp(argv[1], "longest_prefix")) {
101
+ /* arguments: <colon-separated-prefixes>|- <string> */
102
+ struct string_list prefixes = STRING_LIST_INIT_DUP;
103
+ int retval;
104
+ const char *prefix_string = argv[2];
105
+ const char *string = argv[3];
106
+ const char *match;
107
+
108
+ parse_string_list(&prefixes, prefix_string);
109
+ match = string_list_longest_prefix(&prefixes, string);
110
+ if (match) {
111
+ printf("%s\n", match);
112
+ retval = 0;
113
+ }
114
+ else
115
+ retval = 1;
116
+ string_list_clear(&prefixes, 0);
117
+ return retval;
118
+ }
119
+
120
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
121
argv[1] ? argv[1] : "(there was none)");
122
return 1;