Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 1e01a35 in mainline


Ignore:
Timestamp:
2012-07-10T12:01:07Z (10 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial
Children:
f0d7bd9
Parents:
b4ca0a9c
git-author:
Sandeep Kumar <> (2012-07-10 12:01:07)
git-committer:
Vojtech Horky <vojtechhorky@…> (2012-07-10 12:01:07)
Message:

Symbol table completion for kernel console (#50)

Kernel console command arguments are tab-completed with words from symbol
table. Thanks Sandeep Kumar.

Location:
kernel/generic
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/debug.h

    rb4ca0a9c r1e01a35  
    3737
    3838#include <panic.h>
    39 #include <symtab.h>
     39#include <symtab_lookup.h>
    4040
    4141#define CALLER  ((uintptr_t) __builtin_return_address(0))
  • kernel/generic/include/symtab.h

    rb4ca0a9c r1e01a35  
    3636#define KERN_SYMTAB_H_
    3737
    38 #include <typedefs.h>
     38#define MAX_TAB_HINTS 37
    3939
    40 #define MAX_SYMBOL_NAME  64
     40#include <symtab_lookup.h>
     41#include <console/chardev.h>
    4142
    42 struct symtab_entry {
    43         uint64_t address_le;
    44         char symbol_name[MAX_SYMBOL_NAME];
    45 };
    46 
    47 extern int symtab_name_lookup(uintptr_t, const char **, uintptr_t *);
    48 extern const char *symtab_fmt_name_lookup(uintptr_t);
    49 extern int symtab_addr_lookup(const char *, uintptr_t *);
    5043extern void symtab_print_search(const char *);
    51 extern int symtab_compl(char *, size_t);
    52 
    53 #ifdef CONFIG_SYMTAB
    54 
    55 /** Symtable linked together by build process
    56  *
    57  */
    58 extern struct symtab_entry symbol_table[];
    59 
    60 #endif /* CONFIG_SYMTAB */
     44extern int symtab_compl(char *, size_t, indev_t *);
    6145
    6246#endif
  • kernel/generic/src/console/kconsole.c

    rb4ca0a9c r1e01a35  
    201201 *
    202202 */
    203 NO_TRACE static int cmdtab_compl(char *input, size_t size)
     203NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t * indev)
    204204{
    205205        const char *name = input;
    206206       
    207207        size_t found = 0;
     208        /* Maximum Match Length : Length of longest matching common substring in
     209           case more than one match is found */
     210        size_t max_match_len = size;
     211        size_t max_match_len_tmp = size;
     212        size_t input_len = str_length(input);
    208213        link_t *pos = NULL;
    209214        const char *hint;
    210215        char *output = malloc(MAX_CMDLINE, 0);
     216        char display = 'y';
     217        size_t hints_to_show = MAX_TAB_HINTS - 1;
     218        size_t total_hints_shown = 0;
     219        char continue_showing_hints = 'y';
    211220       
    212221        output[0] = 0;
     
    218227                pos = pos->next;
    219228                found++;
     229        }
     230       
     231        /* If possible completions are more than MAX_TAB_HINTS, ask user whether to display them or not. */
     232        if (found > MAX_TAB_HINTS) {
     233                printf("\nDisplay all %zu possibilities? (y or n)", found);
     234                do {
     235                        display = indev_pop_character(indev);
     236                } while (display != 'y' && display != 'n' && display != 'Y' && display != 'N');
    220237        }
    221238       
     
    225242                while (cmdtab_search_one(name, &pos)) {
    226243                        cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
    227                         printf("%s (%s)\n", hlp->name, hlp->description);
     244
     245                        if (display == 'y' || display == 'Y') { /* We are still showing hints */
     246                                printf("%s (%s)\n", hlp->name, hlp->description);
     247                                --hints_to_show;
     248                                ++total_hints_shown;
     249
     250                                if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
     251                                        printf("--More--");
     252                                        do {
     253                                                continue_showing_hints = indev_pop_character(indev);
     254                                                if (continue_showing_hints == 'y' || continue_showing_hints == 'Y'
     255                                                                || continue_showing_hints == ' ') {
     256                                                        hints_to_show = MAX_TAB_HINTS - 1; /* Display a full page again */
     257                                                        break;
     258                                                }
     259
     260                                                if (continue_showing_hints == 'n' || continue_showing_hints == 'N'
     261                                                                || continue_showing_hints == 'q' || continue_showing_hints == 'Q') {
     262                                                        display = 'n'; /* Stop displaying hints */
     263                                                        break;
     264                                                }
     265
     266                                                if (continue_showing_hints == '\n') {
     267                                                        hints_to_show = 1; /* Show one more hint */
     268                                                        break;
     269                                                }
     270                                        } while (1);
     271
     272                                        printf("\r         \r"); /* Delete the --More-- option */
     273                                }
     274                        }
     275
    228276                        pos = pos->next;
    229                 }
     277                        for(max_match_len_tmp = 0; output[max_match_len_tmp] == hlp->name[input_len + max_match_len_tmp]
     278                                        && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     279                        max_match_len = max_match_len_tmp;
     280                }
     281                /* keep only the characters common in all completions */
     282                output[max_match_len] = 0;
    230283        }
    231284       
     
    294347                        if (beg == 0) {
    295348                                /* Command completion */
    296                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     349                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    297350                        } else {
    298351                                /* Symbol completion */
    299                                 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     352                                found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    300353                        }
    301354                       
    302355                        if (found == 0)
    303356                                continue;
    304                        
    305                         if (found > 1) {
    306                                 /* No unique hint, list was printed */
    307                                 printf("%s> ", prompt);
    308                                 printf("%ls", current);
    309                                 print_cc('\b', wstr_length(current) - position);
    310                                 continue;
    311                         }
    312                        
    313                         /* We have a hint */
    314                        
     357
     358                        /* We have hints, may be many. In case of more than one hint,
     359                           tmp will contain the common prefix. */
    315360                        size_t off = 0;
    316361                        size_t i = 0;
     
    320365                                i++;
    321366                        }
     367                       
     368                        if (found > 1) {
     369                                /* No unique hint, list was printed */
     370                                printf("%s> ", prompt);
     371                                printf("%ls", current);
     372                                position += str_length(tmp);
     373                                print_cc('\b', wstr_length(current) - position);
     374                                continue;
     375                        }
     376                       
     377                        /* We have a hint */
    322378                       
    323379                        printf("%ls", current + position);
     
    540596/** Parse command line.
    541597 *
    542  * @param cmdline Command line as read from input device. 
     598 * @param cmdline Command line as read from input device.
    543599 * @param size    Size (in bytes) of the string.
    544600 *
  • kernel/generic/src/debug/symtab.c

    rb4ca0a9c r1e01a35  
    209209 *
    210210 */
    211 int symtab_compl(char *input, size_t size)
     211int symtab_compl(char *input, size_t size, indev_t * indev)
    212212{
    213213#ifdef CONFIG_SYMTAB
     
    226226        const char *hint;
    227227        char output[MAX_SYMBOL_NAME];
     228        /* Maximum Match Length : Length of longest matching common substring in
     229           case more than one match is found */
     230        size_t max_match_len = size;
     231        size_t max_match_len_tmp = size;
     232        size_t input_len = str_length(input);
     233        char *sym_name;
     234        char display = 'y';
     235        size_t hints_to_show = MAX_TAB_HINTS - 1;
     236        size_t total_hints_shown = 0;
     237        char continue_showing_hints = 'y';
    228238       
    229239        output[0] = 0;
     240
     241        while ((hint = symtab_search_one(name, &pos))) {
     242                ++pos;
     243        }
     244
     245        pos = 0;
    230246       
    231247        while ((hint = symtab_search_one(name, &pos))) {
     
    237253        }
    238254       
     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("\nDisplay all %zu possibilities? (y or n)", found);
     258                do {
     259                        display = indev_pop_character(indev);
     260                } while (display != 'y' && display != 'n' && display != 'Y' && display != 'N');
     261        }
     262       
    239263        if ((found > 1) && (str_length(output) != 0)) {
    240264                printf("\n");
    241265                pos = 0;
    242266                while (symtab_search_one(name, &pos)) {
    243                         printf("%s\n", symbol_table[pos].symbol_name);
     267                        sym_name = symbol_table[pos].symbol_name;
    244268                        pos++;
     269
     270                        if (display == 'y' || display == 'Y') { /* We are still showing hints */
     271                                printf("%s\n", sym_name);
     272                                --hints_to_show;
     273                                ++total_hints_shown;
     274
     275                                if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
     276                                        printf("--More--");
     277                                        do {
     278                                                continue_showing_hints = indev_pop_character(indev);
     279                                                if (continue_showing_hints == 'y' || continue_showing_hints == 'Y'
     280                                                                || continue_showing_hints == ' ') {
     281                                                        hints_to_show = MAX_TAB_HINTS - 1; /* Display a full page again */
     282                                                        break;
     283                                                }
     284
     285                                                if (continue_showing_hints == 'n' || continue_showing_hints == 'N'
     286                                                                || continue_showing_hints == 'q' || continue_showing_hints == 'Q') {
     287                                                        display = 'n'; /* Stop displaying hints */
     288                                                        break;
     289                                                }
     290
     291                                                if (continue_showing_hints == '\n') {
     292                                                        hints_to_show = 1; /* Show one more hint */
     293                                                        break;
     294                                                }
     295                                        } while (1);
     296
     297                                        printf("\r         \r"); /* Delete the --More-- option */
     298                                }
     299                        }
     300
     301                        for(max_match_len_tmp = 0; output[max_match_len_tmp] == sym_name[input_len + max_match_len_tmp]
     302                                        && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     303                        max_match_len = max_match_len_tmp;
    245304                }
     305                /* keep only the characters common in all completions */
     306                output[max_match_len] = 0;
    246307        }
    247308       
Note: See TracChangeset for help on using the changeset viewer.