mirror of
https://github.com/libretro/libretro-tyrquake.git
synced 2024-11-29 03:00:27 +00:00
[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:
parent
7447181075
commit
55f533b565
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user