[PATCH] Add ST_MaxMatch function

Introduce a new string tree function, ST_MaxMatch. This will be our main
helper function for tab completion.

Given a partial string, this function will search a string tree for strings
who's prefix matches the partial string. It will then return a string which is
the maximum common prefix of the matching strings (i.e. can be longer than the
given partial string.

For now, if the match is unique, the returned string has a space appended. I'm
not sure if I want to keep it like that as it feels like a bit of a hack. It
will do for now.

Signed-off-by: Tyrann <tyrann@disenchant.net>
This commit is contained in:
Tyrann 2006-09-10 19:08:51 +09:30
parent 7447181075
commit 55f533b565
2 changed files with 63 additions and 0 deletions

View File

@ -157,6 +157,68 @@ ST_InsertAlloc(struct rb_string_root *root, const char *s,
return ret;
}
/* ST_MaxMatch helper */
static int
ST_node_match(struct rb_node *n, const char *str, int min_match, int max_match)
{
struct rb_string_node *sn;
if (n) {
max_match = ST_node_match(n->rb_left, str, min_match, max_match);
/* How much does this node match */
sn = rb_entry(n, struct rb_string_node, node);
while (max_match > min_match) {
if (!strncasecmp(str, sn->string, max_match))
break;
max_match--;
}
max_match = ST_node_match(n->rb_right, str, min_match, max_match);
}
return max_match;
}
/*
* Given a prefix, return the maximum common prefix of all other strings in
* the tree which match the given prefix.
*/
char *
ST_MaxMatch(struct rb_string_root *root, const char *pfx)
{
int max_match, min_match, match;
struct rb_node *n;
struct rb_string_node *sn;
char *result = NULL;
/* Can't be more than the shortest string */
max_match = root->minlen;
min_match = strlen(pfx);
n = root->root.rb_node;
sn = rb_entry(n, struct rb_string_node, node);
if (root->entries == 1) {
match = strlen(sn->string);
result = Z_Malloc(match + 2);
if (result) {
strncpy(result, sn->string, match);
result[match] = ' ';
result[match + 1] = 0;
}
} else if (root->entries > 1) {
match = ST_node_match(n, sn->string, min_match, max_match);
result = Z_Malloc(match + 1);
if (result) {
strncpy(result, sn->string, match);
result[match] = 0;
}
}
return result;
}
const char **completions_list = NULL;
static int num_completions = 0;

View File

@ -50,6 +50,7 @@ void ST_AllocInit(void);
qboolean ST_Insert(struct rb_string_root *root, struct rb_string_node *node);
qboolean ST_InsertAlloc(struct rb_string_root *root, const char *s,
struct rb_string_node *n);
char *ST_MaxMatch(struct rb_string_root *root, const char *pfx);
/*
* Set up some basic completion helpers