Ignore:
File:
1 edited

Legend:

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

    rfeeac0d re98f1c3e  
    5858#include <errno.h>
    5959#include <putchar.h>
    60 #include <str.h>
     60#include <mm/slab.h>
    6161
    6262/** Simple kernel console.
     
    164164
    165165/** Try to find a command beginning with prefix */
    166 NO_TRACE static const char *cmdtab_search_one(const char *name,
    167     link_t **startpos)
    168 {
     166const char *cmdtab_enum(const char *name, const char **h, void **ctx)
     167{
     168        link_t **startpos = (link_t**) ctx;
    169169        size_t namelen = str_length(name);
    170170       
     
    182182               
    183183                if (str_lcmp(curname, name, namelen) == 0) {
     184                        *startpos = (*startpos)->next;
     185                        if (h)
     186                                *h = hlp->description;
     187                       
    184188                        spinlock_unlock(&cmd_lock);
    185189                        return (curname + str_lsize(curname, namelen));
     
    199203 *
    200204 */
    201 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)
    202207{
    203208        const char *name = input;
     
    211216        size_t max_match_len = size;
    212217        size_t max_match_len_tmp = size;
    213         size_t input_len = str_length(input);
    214         link_t *pos = NULL;
     218        void *pos = NULL;
    215219        const char *hint;
     220        const char *help;
    216221        char *output = malloc(MAX_CMDLINE, 0);
    217222        size_t hints_to_show = MAX_TAB_HINTS - 1;
     
    221226        output[0] = 0;
    222227       
    223         while ((hint = cmdtab_search_one(name, &pos))) {
    224                 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)))
    225230                        str_cpy(output, MAX_CMDLINE, hint);
    226231               
    227                 pos = pos->next;
    228232                found++;
    229233        }
     
    242246                printf("\n");
    243247                pos = NULL;
    244                 while (cmdtab_search_one(name, &pos)) {
    245                         cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
     248                while ((hint = hints_enum(name, &help, &pos))) {
    246249                       
    247250                        if (continue_showing_hints) {
    248                                 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                               
    249256                                --hints_to_show;
    250257                                ++total_hints_shown;
     
    257264                        }
    258265                       
    259                         pos = pos->next;
    260                        
    261266                        for (max_match_len_tmp = 0;
    262267                            (output[max_match_len_tmp] ==
    263                             hlp->name[input_len + max_match_len_tmp]) &&
     268                            hint[max_match_len_tmp]) &&
    264269                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
    265270                       
     
    276281        free(output);
    277282        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;
    278322}
    279323
     
    318362                                putchar(current[position]);
    319363                       
    320                         if (position == 0)
    321                                 continue;
    322364                       
    323365                        /*
     
    326368                         */
    327369                        size_t beg;
    328                         for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
    329                             beg--);
    330                        
    331                         if (isspace(current[beg]))
    332                                 beg++;
    333                        
    334                         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--;
    335399                       
    336400                        int found;
    337                         if (beg == 0) {
     401                        if (narg == 0) {
    338402                                /* Command completion */
    339                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
     403                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev,
     404                                    cmdtab_enum);
    340405                        } else {
    341                                 /* Symbol completion */
    342                                 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);
    343412                        }
    344413                       
Note: See TracChangeset for help on using the changeset viewer.