Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/kconsole.c

    r9b11a971 re98f1c3e  
    5353#include <func.h>
    5454#include <str.h>
    55 #include <macros.h>
    5655#include <sysinfo/sysinfo.h>
    5756#include <ddi/device.h>
     
    5958#include <errno.h>
    6059#include <putchar.h>
    61 #include <str.h>
     60#include <mm/slab.h>
    6261
    6362/** Simple kernel console.
     
    119118         * Make sure the command is not already listed.
    120119         */
    121         list_foreach(cmd_list, cur) {
    122                 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
    123                
     120        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    124121                if (hlp == cmd) {
    125122                        /* The command is already there. */
     
    167164
    168165/** Try to find a command beginning with prefix */
    169 NO_TRACE static const char *cmdtab_search_one(const char *name,
    170     link_t **startpos)
    171 {
     166const char *cmdtab_enum(const char *name, const char **h, void **ctx)
     167{
     168        link_t **startpos = (link_t**) ctx;
    172169        size_t namelen = str_length(name);
    173170       
     
    185182               
    186183                if (str_lcmp(curname, name, namelen) == 0) {
     184                        *startpos = (*startpos)->next;
     185                        if (h)
     186                                *h = hlp->description;
     187                       
    187188                        spinlock_unlock(&cmd_lock);
    188189                        return (curname + str_lsize(curname, namelen));
     
    202203 *
    203204 */
    204 NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev)
     205NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev,
     206    hints_enum_func_t hints_enum)
    205207{
    206208        const char *name = input;
     
    214216        size_t max_match_len = size;
    215217        size_t max_match_len_tmp = size;
    216         size_t input_len = str_length(input);
    217         link_t *pos = NULL;
     218        void *pos = NULL;
    218219        const char *hint;
     220        const char *help;
    219221        char *output = malloc(MAX_CMDLINE, 0);
    220222        size_t hints_to_show = MAX_TAB_HINTS - 1;
     
    224226        output[0] = 0;
    225227       
    226         while ((hint = cmdtab_search_one(name, &pos))) {
    227                 if ((found == 0) || (str_length(output) > str_length(hint)))
     228        while ((hint = hints_enum(name, NULL, &pos))) {
     229                if ((found == 0) || (str_length(hint) > str_length(output)))
    228230                        str_cpy(output, MAX_CMDLINE, hint);
    229231               
    230                 pos = pos->next;
    231232                found++;
    232233        }
     
    245246                printf("\n");
    246247                pos = NULL;
    247                 while (cmdtab_search_one(name, &pos)) {
    248                         cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
     248                while ((hint = hints_enum(name, &help, &pos))) {
    249249                       
    250250                        if (continue_showing_hints) {
    251                                 printf("%s (%s)\n", hlp->name, hlp->description);
     251                                if (help)
     252                                        printf("%s%s (%s)\n", name, hint, help);
     253                                else
     254                                        printf("%s%s\n", name, hint);
     255                               
    252256                                --hints_to_show;
    253257                                ++total_hints_shown;
     
    260264                        }
    261265                       
    262                         pos = pos->next;
    263                        
    264266                        for (max_match_len_tmp = 0;
    265267                            (output[max_match_len_tmp] ==
    266                             hlp->name[input_len + max_match_len_tmp]) &&
     268                            hint[max_match_len_tmp]) &&
    267269                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
    268270                       
     
    279281        free(output);
    280282        return found;
     283}
     284
     285NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline)
     286{
     287        size_t start = 0;
     288        size_t end;
     289        char *tmp;
     290       
     291        while (isspace(cmdline[start]))
     292                start++;
     293       
     294        end = start + 1;
     295       
     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;
    281322}
    282323
     
    321362                                putchar(current[position]);
    322363                       
    323                         if (position == 0)
    324                                 continue;
    325364                       
    326365                        /*
     
    329368                         */
    330369                        size_t beg;
    331                         for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
    332                             beg--);
    333                        
    334                         if (isspace(current[beg]))
    335                                 beg++;
    336                        
    337                         wstr_to_str(tmp, position - beg + 1, current + beg);
     370                        unsigned narg = 0;
     371                        if (position == 0) {
     372                                tmp[0] = '\0';
     373                                beg = 0;
     374                        } else {
     375                                for (beg = position - 1;
     376                                    (beg > 0) && (!isspace(current[beg]));
     377                                    beg--);
     378                               
     379                                if (isspace(current[beg]))
     380                                        beg++;
     381                               
     382                                wstr_to_str(tmp, position - beg + 1, current + beg);
     383                        }
     384                       
     385                        /* Count which argument number are we tabbing (narg=0 is cmd) */
     386                        bool sp = false;
     387                        for (; beg > 0; beg--) {
     388                                if (isspace(current[beg])) {
     389                                        if (!sp) {
     390                                                narg++;
     391                                                sp = true;
     392                                        }
     393                                } else
     394                                        sp = false;
     395                        }
     396                       
     397                        if (narg && isspace(current[0]))
     398                                narg--;
    338399                       
    339400                        int found;
    340                         if (beg == 0) {
     401                        if (narg == 0) {
    341402                                /* Command completion */
    342                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
     403                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev,
     404                                    cmdtab_enum);
    343405                        } else {
    344                                 /* Symbol completion */
    345                                 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
     406                                /* Arguments completion */
     407                                cmd_info_t *cmd = parse_cmd(current);
     408                                if (!cmd || !cmd->hints_enum || cmd->argc < narg)
     409                                        continue;
     410                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev,
     411                                    cmd->hints_enum);
    346412                        }
    347413                       
     
    613679        cmd_info_t *cmd = NULL;
    614680       
    615         list_foreach(cmd_list, cur) {
    616                 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
     681        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    617682                spinlock_lock(&hlp->lock);
    618683               
Note: See TracChangeset for help on using the changeset viewer.