Пример #1
0
/** Command completion of the commands
 *
 * @param name String to match, changed to hint on exit
 * @param size Input buffer size
 *
 * @return Number of found matches
 *
 */
NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev,
    hints_enum_func_t hints_enum)
{
	const char *name = input;
	
	size_t found = 0;
	
	/*
	 * Maximum Match Length: Length of longest matching common
	 * substring in case more than one match is found.
	 */
	size_t max_match_len = size;
	size_t max_match_len_tmp = size;
	void *pos = NULL;
	const char *hint;
	const char *help;
	char *output = malloc(MAX_CMDLINE, 0);
	size_t hints_to_show = MAX_TAB_HINTS - 1;
	size_t total_hints_shown = 0;
	bool continue_showing_hints = true;
	
	output[0] = 0;
	
	while ((hint = hints_enum(name, NULL, &pos))) {
		if ((found == 0) || (str_length(hint) > str_length(output)))
			str_cpy(output, MAX_CMDLINE, hint);
		
		found++;
	}
	
	/*
	 * If the number of possible completions is more than MAX_TAB_HINTS,
	 * ask the user whether to display them or not.
	 */
	if (found > MAX_TAB_HINTS) {
		printf("\n");
		continue_showing_hints =
		    console_prompt_display_all_hints(indev, found);
	}
	
	if ((found > 1) && (str_length(output) != 0)) {
		printf("\n");
		pos = NULL;
		while ((hint = hints_enum(name, &help, &pos))) {
			
			if (continue_showing_hints) {
				if (help)
					printf("%s%s (%s)\n", name, hint, help);
				else
					printf("%s%s\n", name, hint);
				
				--hints_to_show;
				++total_hints_shown;
				
				if ((hints_to_show == 0) && (total_hints_shown != found)) {
					/* Ask user to continue */
					continue_showing_hints =
					    console_prompt_more_hints(indev, &hints_to_show);
				}
			}
			
			for (max_match_len_tmp = 0;
			    (output[max_match_len_tmp] ==
			    hint[max_match_len_tmp]) &&
			    (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
			
			max_match_len = max_match_len_tmp;
		}
		
		/* Keep only the characters common in all completions */
		output[max_match_len] = 0;
	}
	
	if (found > 0)
		str_cpy(input, size, output);
	
	free(output);
	return found;
}
Пример #2
0
/** Symtab completion
 *
 * @param input Search string, completes to symbol name
 * @param size  Input buffer size
 *
 * @return 0 - nothing found, 1 - success, >1 print duplicates
 *
 */
int symtab_compl(char *input, size_t size, indev_t *indev)
{
#ifdef CONFIG_SYMTAB
	const char *name = input;
	
	/* Allow completion of pointers */
	if ((name[0] == '*') || (name[0] == '&'))
		name++;
	
	/* Do not print all symbols */
	if (str_length(name) == 0)
		return 0;
	
	size_t found = 0;
	size_t pos = 0;
	const char *hint;
	char output[MAX_SYMBOL_NAME];
	
	/*
	 * Maximum Match Length: Length of longest matching common substring in
	 * case more than one match is found.
	 */
	size_t max_match_len = size;
	size_t max_match_len_tmp = size;
	size_t input_len = str_length(input);
	char *sym_name;
	size_t hints_to_show = MAX_TAB_HINTS - 1;
	size_t total_hints_shown = 0;
	bool continue_showing_hints = true;
	
	output[0] = 0;
	
	while ((hint = symtab_search_one(name, &pos)))
		pos++;
	
	pos = 0;
	
	while ((hint = symtab_search_one(name, &pos))) {
		if ((found == 0) || (str_length(output) > str_length(hint)))
			str_cpy(output, MAX_SYMBOL_NAME, hint);
		
		pos++;
		found++;
	}
	
	/*
	 * If the number of possible completions is more than MAX_TAB_HINTS,
	 * ask the user whether to display them or not.
	 */
	if (found > MAX_TAB_HINTS) {
		printf("\n");
		continue_showing_hints =
		    console_prompt_display_all_hints(indev, found);
	}
	
	if ((found > 1) && (str_length(output) != 0)) {
		printf("\n");
		pos = 0;
		while (symtab_search_one(name, &pos)) {
			sym_name = symbol_table[pos].symbol_name;
			pos++;
			
			if (continue_showing_hints) {
				/* We are still showing hints */
				printf("%s\n", sym_name);
				--hints_to_show;
				++total_hints_shown;
				
				if ((hints_to_show == 0) && (total_hints_shown != found)) {
					/* Ask the user to continue */
					continue_showing_hints =
					    console_prompt_more_hints(indev, &hints_to_show);
				}
			}
			
			for (max_match_len_tmp = 0;
			    (output[max_match_len_tmp] ==
			    sym_name[input_len + max_match_len_tmp]) &&
			    (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
			
			max_match_len = max_match_len_tmp;
		}
		
		/* Keep only the characters common in all completions */
		output[max_match_len] = 0;
	}
	
	if (found > 0)
		str_cpy(input, size, output);
	
	return found;
	
#else
	return 0;
#endif
}