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

Changeset d4d8255 in mainline


Ignore:
Timestamp:
2016-03-09T20:01:43Z (5 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
c1b8ad4
Parents:
df425da (diff), dc0e41c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~aurelio-x/helenos/kcon-devel

Location:
kernel
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/console/kconsole.h

    rdf425da rd4d8255  
    4343#define KCONSOLE_HISTORY  10
    4444
     45/** Callback to be used to enum hints for cmd tab completion. */
     46typedef const char *(*hints_enum_func_t)(const char *, const char **, void **);
     47
    4548typedef enum {
    4649        ARG_TYPE_INVALID = 0,
     
    8588        /** Function for printing detailed help. */
    8689        void (* help)(void);
     90        /** Function for enumerating hints for arguments. */
     91        hints_enum_func_t hints_enum;
    8792} cmd_info_t;
    8893
     
    100105
    101106extern bool cmd_register(cmd_info_t *cmd);
     107extern const char *cmdtab_enum(const char *name, const char **h, void **ctx);
    102108
    103109#endif
  • kernel/generic/include/str.h

    rdf425da rd4d8255  
    6262
    6363/**< Maximum size of a string containing cnt characters */
    64 #define STR_BOUNDS(cnt)  (cnt << 2)
     64#define STR_BOUNDS(cnt)  ((cnt) << 2)
    6565
    6666extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
  • kernel/generic/include/symtab.h

    rdf425da rd4d8255  
    4040
    4141extern void symtab_print_search(const char *);
    42 extern int symtab_compl(char *, size_t, indev_t *);
     42extern const char* symtab_hints_enum(const char *, const char **, void **);
    4343
    4444#endif
  • kernel/generic/src/console/cmd.c

    rdf425da rd4d8255  
    206206        .func = cmd_test,
    207207        .argc = 1,
    208         .argv = test_argv
     208        .argv = test_argv,
     209        .hints_enum = tests_hints_enum
    209210};
    210211
     
    246247        .func = cmd_desc,
    247248        .argc = 1,
    248         .argv = &desc_argv
     249        .argv = &desc_argv,
     250        .hints_enum = cmdtab_enum
    249251};
    250252
     
    262264        .func = cmd_symaddr,
    263265        .argc = 1,
    264         .argv = &symaddr_argv
     266        .argv = &symaddr_argv,
     267        .hints_enum = symtab_hints_enum,
    265268};
    266269
     
    303306        .func = cmd_call0,
    304307        .argc = 1,
    305         .argv = &call0_argv
     308        .argv = &call0_argv,
     309        .hints_enum = symtab_hints_enum
    306310};
    307311
     
    318322        .func = cmd_mcall0,
    319323        .argc = 1,
    320         .argv = &mcall0_argv
     324        .argv = &mcall0_argv,
     325        .hints_enum = symtab_hints_enum
    321326};
    322327
     
    340345        .func = cmd_call1,
    341346        .argc = 2,
    342         .argv = call1_argv
     347        .argv = call1_argv,
     348        .hints_enum = symtab_hints_enum
    343349};
    344350
     
    367373        .func = cmd_call2,
    368374        .argc = 3,
    369         .argv = call2_argv
     375        .argv = call2_argv,
     376        .hints_enum = symtab_hints_enum
    370377};
    371378
     
    400407        .func = cmd_call3,
    401408        .argc = 4,
    402         .argv = call3_argv
     409        .argv = call3_argv,
     410        .hints_enum = symtab_hints_enum
    403411};
    404412
  • kernel/generic/src/console/kconsole.c

    rdf425da rd4d8255  
    165165
    166166/** Try to find a command beginning with prefix */
    167 NO_TRACE static const char *cmdtab_search_one(const char *name,
    168     link_t **startpos)
    169 {
     167const char *cmdtab_enum(const char *name, const char **h, void **ctx)
     168{
     169        link_t **startpos = (link_t**)ctx;
    170170        size_t namelen = str_length(name);
    171171       
     
    183183               
    184184                if (str_lcmp(curname, name, namelen) == 0) {
     185                        *startpos = (*startpos)->next;
     186                        if (h) {
     187                                *h = hlp->description;
     188                        }
    185189                        spinlock_unlock(&cmd_lock);
    186190                        return (curname + str_lsize(curname, namelen));
     
    200204 *
    201205 */
    202 NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev)
     206NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev,
     207    hints_enum_func_t hints_enum)
    203208{
    204209        const char *name = input;
     
    212217        size_t max_match_len = size;
    213218        size_t max_match_len_tmp = size;
    214         size_t input_len = str_length(input);
    215         link_t *pos = NULL;
     219        void *pos = NULL;
    216220        const char *hint;
     221        const char *help;
    217222        char *output = malloc(MAX_CMDLINE, 0);
    218223        size_t hints_to_show = MAX_TAB_HINTS - 1;
     
    222227        output[0] = 0;
    223228       
    224         while ((hint = cmdtab_search_one(name, &pos))) {
    225                 if ((found == 0) || (str_length(output) > str_length(hint)))
     229        while ((hint = hints_enum(name, NULL, &pos))) {
     230                if ((found == 0) || (str_length(hint) > str_length(output)))
    226231                        str_cpy(output, MAX_CMDLINE, hint);
    227232               
    228                 pos = pos->next;
    229233                found++;
    230234        }
     
    243247                printf("\n");
    244248                pos = NULL;
    245                 while (cmdtab_search_one(name, &pos)) {
    246                         cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
     249                while ((hint = hints_enum(name, &help, &pos))) {
    247250                       
    248251                        if (continue_showing_hints) {
    249                                 printf("%s (%s)\n", hlp->name, hlp->description);
     252                               
     253                                if (help)
     254                                        printf("%s%s (%s)\n", name, hint, help);
     255                                else
     256                                        printf("%s%s\n", name, hint);
     257                               
    250258                                --hints_to_show;
    251259                                ++total_hints_shown;
     
    258266                        }
    259267                       
    260                         pos = pos->next;
    261                        
    262268                        for (max_match_len_tmp = 0;
    263269                            (output[max_match_len_tmp] ==
    264                             hlp->name[input_len + max_match_len_tmp]) &&
     270                            hint[max_match_len_tmp]) &&
    265271                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
    266272                       
     
    277283        free(output);
    278284        return found;
     285}
     286
     287NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline)
     288{
     289        size_t start = 0;
     290        size_t end;
     291        char *tmp;
     292       
     293        while (isspace(cmdline[start]))
     294                start++;
     295        end = start + 1;
     296        while (!isspace(cmdline[end]))
     297                end++;
     298       
     299        tmp = malloc(STR_BOUNDS(end - start + 1), 0);
     300       
     301        wstr_to_str(tmp, end - start + 1, &cmdline[start]);
     302       
     303        spinlock_lock(&cmd_lock);
     304       
     305        list_foreach(cmd_list, link, cmd_info_t, hlp) {
     306                spinlock_lock(&hlp->lock);
     307               
     308                if (str_cmp(hlp->name, tmp) == 0) {
     309                        spinlock_unlock(&hlp->lock);
     310                        spinlock_unlock(&cmd_lock);
     311                        free(tmp);
     312                        return hlp;
     313                }
     314               
     315                spinlock_unlock(&hlp->lock);
     316        }
     317       
     318        free(tmp);
     319        spinlock_unlock(&cmd_lock);
     320       
     321        return NULL;
    279322}
    280323
     
    338381                        if (beg == 0) {
    339382                                /* Command completion */
    340                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
     383                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev,
     384                                    cmdtab_enum);
    341385                        } else {
    342                                 /* Symbol completion */
    343                                 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
     386                                /* Arguments completion */
     387                                cmd_info_t *cmd = parse_cmd(current);
     388                                if (!cmd || !cmd->hints_enum)
     389                                        continue;
     390                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev,
     391                                    cmd->hints_enum);
    344392                        }
    345393                       
  • kernel/generic/src/debug/symtab.c

    rdf425da rd4d8255  
    202202}
    203203
    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  */
    212 int 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        
    230         /*
    231          * Maximum Match Length: Length of longest matching common substring in
    232          * case more than one match is found.
    233          */
    234         size_t max_match_len = size;
    235         size_t max_match_len_tmp = size;
    236         size_t input_len = str_length(input);
    237         char *sym_name;
    238         size_t hints_to_show = MAX_TAB_HINTS - 1;
    239         size_t total_hints_shown = 0;
    240         bool continue_showing_hints = true;
    241        
    242         output[0] = 0;
    243        
    244         while ((hint = symtab_search_one(name, &pos)))
    245                 pos++;
    246        
    247         pos = 0;
    248        
    249         while ((hint = symtab_search_one(name, &pos))) {
    250                 if ((found == 0) || (str_length(output) > str_length(hint)))
    251                         str_cpy(output, MAX_SYMBOL_NAME, hint);
    252                
    253                 pos++;
    254                 found++;
    255         }
    256        
    257         /*
    258          * If the number of possible completions is more than MAX_TAB_HINTS,
    259          * ask the user whether to display them or not.
    260          */
    261         if (found > MAX_TAB_HINTS) {
    262                 printf("\n");
    263                 continue_showing_hints =
    264                     console_prompt_display_all_hints(indev, found);
    265         }
    266        
    267         if ((found > 1) && (str_length(output) != 0)) {
    268                 printf("\n");
    269                 pos = 0;
    270                 while (symtab_search_one(name, &pos)) {
    271                         sym_name = symbol_table[pos].symbol_name;
    272                         pos++;
    273                        
    274                         if (continue_showing_hints) {
    275                                 /* We are still showing hints */
    276                                 printf("%s\n", sym_name);
    277                                 --hints_to_show;
    278                                 ++total_hints_shown;
    279                                
    280                                 if ((hints_to_show == 0) && (total_hints_shown != found)) {
    281                                         /* Ask the user to continue */
    282                                         continue_showing_hints =
    283                                             console_prompt_more_hints(indev, &hints_to_show);
    284                                 }
    285                         }
    286                        
    287                         for (max_match_len_tmp = 0;
    288                             (output[max_match_len_tmp] ==
    289                             sym_name[input_len + max_match_len_tmp]) &&
    290                             (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
    291                        
    292                         max_match_len = max_match_len_tmp;
     204/** Symtab completion enum, see kernel/generic/include/kconsole.h */
     205const char* symtab_hints_enum(const char *input, const char **help,
     206    void **ctx)
     207{
     208#ifdef CONFIG_SYMTAB
     209        size_t len = str_length(input);
     210        struct symtab_entry **entry = (struct symtab_entry**)ctx;
     211       
     212        if (*entry == NULL)
     213                *entry = symbol_table;
     214       
     215        for (; (*entry)->address_le; (*entry)++) {
     216                const char *curname = (*entry)->symbol_name;
     217               
     218                /* Find a ':' in curname */
     219                const char *colon = str_chr(curname, ':');
     220                if (colon == NULL)
     221                        continue;
     222               
     223                if (str_length(curname) < len)
     224                        continue;
     225               
     226                if (str_lcmp(input, curname, len) == 0) {
     227                        (*entry)++;
     228                        if (help)
     229                                *help = NULL;
     230                        return (curname + str_lsize(curname, len));
    293231                }
    294                
    295                 /* Keep only the characters common in all completions */
    296                 output[max_match_len] = 0;
    297         }
    298        
    299         if (found > 0)
    300                 str_cpy(input, size, output);
    301        
    302         return found;
    303        
    304 #else
    305         return 0;
     232        }
     233       
     234        return NULL;
     235       
     236#else
     237        return NULL;
    306238#endif
    307239}
  • kernel/test/test.c

    rdf425da rd4d8255  
    3434
    3535#include <test.h>
     36#include <str.h>
    3637
    3738bool test_quiet;
     
    6869};
    6970
     71const char* tests_hints_enum(const char *input, const char **help,
     72    void **ctx)
     73{
     74        size_t len = str_length(input);
     75        test_t **test = (test_t**)ctx;
     76       
     77        if (*test == NULL)
     78                *test = tests;
     79       
     80        for (; (*test)->name; (*test)++) {
     81                const char *curname = (*test)->name;
     82               
     83                if (str_length(curname) < len)
     84                        continue;
     85               
     86                if (str_lcmp(input, curname, len) == 0) {
     87                        (*test)++;
     88                        if (help)
     89                                *help = (*test)->desc;
     90                        return (curname + str_lsize(curname, len));
     91                }
     92        }
     93       
     94        return NULL;
     95}
     96
    7097/** @}
    7198 */
  • kernel/test/test.h

    rdf425da rd4d8255  
    8585extern test_t tests[];
    8686
     87extern const char* tests_hints_enum(const char *, const char **, void **);
     88
    8789#endif
    8890
Note: See TracChangeset for help on using the changeset viewer.