Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/debug/symtab.c

    r1558d85 raca4a04  
    4141#include <print.h>
    4242#include <typedefs.h>
     43#include <typedefs.h>
    4344#include <errno.h>
    4445#include <console/prompt.h>
     
    201202}
    202203
    203 /** Symtab completion enum, see kernel/generic/include/kconsole.h */
    204 const char* symtab_hints_enum(const char *input, const char **help,
    205     void **ctx)
    206 {
    207 #ifdef CONFIG_SYMTAB
    208         size_t len = str_length(input);
    209         struct symtab_entry **entry = (struct symtab_entry**)ctx;
    210        
    211         if (*entry == NULL)
    212                 *entry = symbol_table;
    213        
    214         for (; (*entry)->address_le; (*entry)++) {
    215                 const char *curname = (*entry)->symbol_name;
    216                
    217                 /* Find a ':' in curname */
    218                 const char *colon = str_chr(curname, ':');
    219                 if (colon == NULL)
    220                         continue;
    221                
    222                 if (str_length(curname) < len)
    223                         continue;
    224                
    225                 if (str_lcmp(input, curname, len) == 0) {
    226                         (*entry)++;
    227                         if (help)
    228                                 *help = NULL;
    229                         return (curname + str_lsize(curname, len));
     204/** Symtab completion
     205 *
     206 * @param input Search string, completes to symbol name
     207 * @param size  Input buffer size
     208 *
     209 * @return 0 - nothing found, 1 - success, >1 print duplicates
     210 *
     211 */
     212int symtab_compl(char *input, size_t size, indev_t * indev)
     213{
     214#ifdef CONFIG_SYMTAB
     215        const char *name = input;
     216       
     217        /* Allow completion of pointers */
     218        if ((name[0] == '*') || (name[0] == '&'))
     219                name++;
     220       
     221        /* Do not print all symbols */
     222        if (str_length(name) == 0)
     223                return 0;
     224       
     225        size_t found = 0;
     226        size_t pos = 0;
     227        const char *hint;
     228        char output[MAX_SYMBOL_NAME];
     229        /* Maximum Match Length : Length of longest matching common substring in
     230           case more than one match is found */
     231        size_t max_match_len = size;
     232        size_t max_match_len_tmp = size;
     233        size_t input_len = str_length(input);
     234        char *sym_name;
     235        size_t hints_to_show = MAX_TAB_HINTS - 1;
     236        size_t total_hints_shown = 0;
     237        bool continue_showing_hints = true;
     238       
     239        output[0] = 0;
     240
     241        while ((hint = symtab_search_one(name, &pos))) {
     242                ++pos;
     243        }
     244
     245        pos = 0;
     246       
     247        while ((hint = symtab_search_one(name, &pos))) {
     248                if ((found == 0) || (str_length(output) > str_length(hint)))
     249                        str_cpy(output, MAX_SYMBOL_NAME, hint);
     250               
     251                pos++;
     252                found++;
     253        }
     254       
     255        /* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
     256        if (found > MAX_TAB_HINTS) {
     257                printf("\n");
     258                continue_showing_hints = console_prompt_display_all_hints(indev, found);
     259        }
     260       
     261        if ((found > 1) && (str_length(output) != 0)) {
     262                printf("\n");
     263                pos = 0;
     264                while (symtab_search_one(name, &pos)) {
     265                        sym_name = symbol_table[pos].symbol_name;
     266                        pos++;
     267
     268                        if (continue_showing_hints) { /* We are still showing hints */
     269                                printf("%s\n", sym_name);
     270                                --hints_to_show;
     271                                ++total_hints_shown;
     272
     273                                if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
     274                                        continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
     275                                }
     276                        }
     277
     278                        for(max_match_len_tmp = 0; output[max_match_len_tmp] == sym_name[input_len + max_match_len_tmp]
     279                                        && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     280                        max_match_len = max_match_len_tmp;
    230281                }
    231         }
    232        
    233         return NULL;
    234        
    235 #else
    236         return NULL;
     282                /* keep only the characters common in all completions */
     283                output[max_match_len] = 0;
     284        }
     285       
     286        if (found > 0)
     287                str_cpy(input, size, output);
     288       
     289        return found;
     290       
     291#else
     292        return 0;
    237293#endif
    238294}
Note: See TracChangeset for help on using the changeset viewer.