degesch: get rid of partial command name matching

This commit is contained in:
Přemysl Eric Janouch 2015-07-09 22:32:55 +02:00
parent 567ce62257
commit 445837007d
1 changed files with 8 additions and 30 deletions

View File

@ -7591,38 +7591,16 @@ handle_command_help (struct handler_args *a)
return true; return true;
} }
static int
command_handler_cmp_by_length (const void *a, const void *b)
{
const struct command_handler *first = a;
const struct command_handler *second = b;
return strlen (first->name) - strlen (second->name);
}
static void static void
init_partial_matching_user_command_map (struct str_map *partial) init_user_command_map (struct str_map *map)
{ {
// Trivially create a partial matching map str_map_init (map);
str_map_init (partial); map->key_xfrm = tolower_ascii_strxfrm;
partial->key_xfrm = tolower_ascii_strxfrm;
// We process them from the longest to the shortest one, for (size_t i = 0; i < N_ELEMENTS (g_command_handlers); i++)
// so that common prefixes favor shorter entries
struct command_handler *by_length[N_ELEMENTS (g_command_handlers)];
for (size_t i = 0; i < N_ELEMENTS (by_length); i++)
by_length[i] = &g_command_handlers[i];
qsort (by_length, N_ELEMENTS (by_length), sizeof *by_length,
command_handler_cmp_by_length);
for (size_t i = N_ELEMENTS (by_length); i--; )
{ {
char *copy = xstrdup (by_length[i]->name); struct command_handler *handler = &g_command_handlers[i];
for (size_t part = strlen (copy); part; part--) str_map_set (map, handler->name, handler);
{
copy[part] = '\0';
str_map_set (partial, copy, by_length[i]);
}
free (copy);
} }
} }
@ -7631,10 +7609,10 @@ process_user_command
(struct app_context *ctx, const char *command_name, char *input) (struct app_context *ctx, const char *command_name, char *input)
{ {
static bool initialized = false; static bool initialized = false;
static struct str_map partial; static struct str_map map;
if (!initialized) if (!initialized)
{ {
init_partial_matching_user_command_map (&partial); init_user_command_map (&map);
initialized = true; initialized = true;
} }