/* Given a command trie, look up the action that matches the input * passed as an array of input strings (typically argv). The input * array and number of items in the array (num) are passed as * pointers, such that they are updated to the position of the * matched action. * The matching action (if any) is stored in the action pointer, and * the state of the matching is returned by the function: * NONE - command mismatch * ACTION - matched an action, arguments might remain in input * SUBTRIE - matched a "parent command", with available subcommands * * If auto_complete is TRUE, unambiguous prefixes of commands are * automatically matched. * * If completions is not NULL, a list of possible completions is * stored in it. */ command_trie_match_type_t command_trie_find (command_trie_t *trie, gchar ***input, gint *num, gboolean auto_complete, command_action_t **action, GList **completions) { command_trie_t *node; command_trie_match_type_t retval = COMMAND_TRIE_MATCH_NONE; if ((node = command_trie_find_node (trie, **input, auto_complete, completions))) { (*input) ++; (*num) --; if (node->match.type == COMMAND_TRIE_MATCH_ACTION) { *action = node->match.action; retval = COMMAND_TRIE_MATCH_ACTION; } else if (node->match.type == COMMAND_TRIE_MATCH_SUBTRIE) { if (*num == 0) { *action = node->match.action; retval = COMMAND_TRIE_MATCH_SUBTRIE; } else { retval = command_trie_find (node->match.subtrie, input, num, auto_complete, action, completions); } } } return retval; }
static command_trie_t * command_trie_find_node (command_trie_t *trie, gchar *input, gboolean auto_complete) { command_trie_t *node = NULL; GList *l; /* FIXME: If this happens when a parent command is given, make it nice! */ if (input == NULL) { return NULL; } if (*input == 0) { /* End of token, return current action, or unique completion */ if (command_trie_valid_match (trie)) { node = trie; } else if (auto_complete) { node = command_trie_find_leaf (trie); } } else { /* Recurse in next trie node */ l = g_list_find_custom (trie->next, input, command_trie_elem_cmp); if (l != NULL) { node = command_trie_find_node ((command_trie_t *) l->data, input + 1, auto_complete); } } return node; }