Skip to content

Commit f103f95

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 31d5451 commit f103f95

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

Documentation/technical/api-string-list.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ Functions
7575
to be deleted. Preserve the order of the items that are
7676
retained.
7777

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+
7886
`print_string_list`::
7987

8088
Dump a string_list to stdout, useful mainly for debugging purposes. It

string-list.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,26 @@ void filter_string_list(struct string_list *list, int free_util,
136136
list->nr = dst;
137137
}
138138

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+
139159
void string_list_clear(struct string_list *list, int free_util)
140160
{
141161
if (list->items) {

string-list.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ int for_each_string_list(struct string_list *list,
3838
void filter_string_list(struct string_list *list, int free_util,
3939
string_list_each_func_t want, void *cb_data);
4040

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+
4149

4250
/* Use these functions only on sorted lists: */
4351
int string_list_has_string(const struct string_list *list, const char *string);

t/t0063-string-list.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ test_split () {
1717
"
1818
}
1919

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+
2028
test_split "foo:bar:baz" ":" "-1" <<EOF
2129
3
2230
[0]: "foo"
@@ -88,4 +96,26 @@ test_expect_success "test remove_duplicates" '
8896
test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
8997
'
9098

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+
91121
test_done

test-string-list.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,26 @@ int main(int argc, char **argv)
9797
return 0;
9898
}
9999

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+
100120
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
101121
argv[1] ? argv[1] : "(there was none)");
102122
return 1;

0 commit comments

Comments
 (0)