Changeset 0c8e692 in mainline


Ignore:
Timestamp:
2005-12-11T19:55:56Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3550c393
Parents:
54aff98
Message:

Added some readline functionality to kconsole.
Arrows editing, history, tab completion.

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/i8042.h

    r54aff98 r0c8e692  
    3838#define SC_RSHIFT       0x36
    3939#define SC_CAPSLOCK     0x3a
     40#define SC_SPEC_ESCAPE  0xe0
     41#define SC_LEFTARR      0x4b
     42#define SC_RIGHTARR     0x4d
     43#define SC_UPARR        0x48
     44#define SC_DOWNARR      0x50
    4045
    4146extern void i8042_init(void);
  • arch/ia32/src/drivers/i8042.c

    r54aff98 r0c8e692  
    304304        spinlock_lock(&keylock);
    305305        switch (sc) {
    306             case SC_LSHIFT:
    307             case SC_RSHIFT:
     306        case SC_LSHIFT:
     307        case SC_RSHIFT:
    308308                keyflags |= PRESSED_SHIFT;
    309309                break;
    310             case SC_CAPSLOCK:
     310        case SC_CAPSLOCK:
    311311                keyflags |= PRESSED_CAPSLOCK;
    312312                break;
    313             default:
     313        case SC_SPEC_ESCAPE:
     314                break;
     315        case SC_LEFTARR:
     316                chardev_push_character(&kbrd, 0x1b);
     317                chardev_push_character(&kbrd, 0x5b);
     318                chardev_push_character(&kbrd, 0x44);
     319                break;
     320        case SC_RIGHTARR:
     321                chardev_push_character(&kbrd, 0x1b);
     322                chardev_push_character(&kbrd, 0x5b);
     323                chardev_push_character(&kbrd, 0x43);
     324                break;
     325        case SC_UPARR:
     326                chardev_push_character(&kbrd, 0x1b);
     327                chardev_push_character(&kbrd, 0x5b);
     328                chardev_push_character(&kbrd, 0x41);
     329                break;
     330        case SC_DOWNARR:
     331                chardev_push_character(&kbrd, 0x1b);
     332                chardev_push_character(&kbrd, 0x5b);
     333                chardev_push_character(&kbrd, 0x42);
     334                break;
     335        default:
    314336                letter = is_lower(ascii);
    315337                capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK);
  • generic/include/console/console.h

    r54aff98 r0c8e692  
    3737
    3838extern __u8 getc(chardev_t *chardev);
     39__u8 _getc(chardev_t *chardev);
    3940extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
    4041extern void putchar(char c);
  • generic/include/console/kconsole.h

    r54aff98 r0c8e692  
    3535
    3636#define MAX_CMDLINE     256
     37#define KCONSOLE_HISTORY 10
    3738
    3839enum cmd_arg_type {
  • generic/include/symtab.h

    r54aff98 r0c8e692  
    4242extern __address get_symbol_addr(const char *name);
    4343extern void symtab_print_search(const char *name);
     44extern int symtab_compl(char *name);
    4445
    4546/* Symtable linked together by build process */
  • generic/src/console/console.c

    r54aff98 r0c8e692  
    4040chardev_t *stdout = NULL;
    4141
    42 /** Get character from character device.
     42/** Get character from character device. Do not echo character.
    4343 *
    4444 * @param chardev Character device.
     
    4646 * @return Character read.
    4747 */
    48 static __u8 _getc(chardev_t *chardev)
     48__u8 _getc(chardev_t *chardev)
    4949{
    5050        __u8 ch;
  • generic/src/console/kconsole.c

    r54aff98 r0c8e692  
    7070static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
    7171static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
     72static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
    7273
    7374/** Initialize kconsole data structures. */
    7475void kconsole_init(void)
    7576{
     77        int i;
     78
    7679        spinlock_initialize(&cmd_lock, "kconsole_cmd");
    7780        list_initialize(&cmd_head);
    7881
    7982        cmd_init();
     83        for (i=0; i<KCONSOLE_HISTORY; i++)
     84                history[i][0] = '\0';
    8085}
    8186
     
    138143}
    139144
     145static void rdln_print_c(char ch, int count)
     146{
     147        int i;
     148        for (i=0;i<count;i++)
     149                putchar(ch);
     150}
     151
     152static void insert_char(char *str, char ch, int pos)
     153{
     154        int i;
     155       
     156        for (i=strlen(str);i > pos; i--)
     157                str[i] = str[i-1];
     158        str[pos] = ch;
     159}
     160
     161static const char * cmdtab_search_one(const char *name,link_t **startpos)
     162{
     163        int namelen = strlen(name);
     164        const char *curname;
     165        char *foundsym = NULL;
     166        int foundpos = 0;
     167
     168        spinlock_lock(&cmd_lock);
     169
     170        if (!*startpos)
     171                *startpos = cmd_head.next;
     172
     173        for (;*startpos != &cmd_head;*startpos = (*startpos)->next) {
     174                cmd_info_t *hlp;
     175                hlp = list_get_instance(*startpos, cmd_info_t, link);
     176
     177                curname = hlp->name;
     178                if (strlen(curname) < namelen)
     179                        continue;
     180                if (strncmp(curname, name, namelen) == 0) {
     181                        spinlock_unlock(&cmd_lock);     
     182                        return curname+namelen;
     183                }
     184        }
     185        spinlock_unlock(&cmd_lock);     
     186        return NULL;
     187}
     188
     189
     190/** Command completion of the commands
     191 *
     192 * @param name - string to match, changed to hint on exit
     193 * @return number of found matches
     194 */
     195static int cmdtab_compl(char *name)
     196{
     197        char output[MAX_SYMBOL_NAME+1];
     198        link_t *startpos = NULL;
     199        const char *foundtxt;
     200        int found = 0;
     201        int i;
     202
     203        output[0] = '\0';
     204        while ((foundtxt = cmdtab_search_one(name, &startpos))) {
     205                startpos = startpos->next;
     206                if (!found)
     207                        strncpy(output, foundtxt, strlen(foundtxt)+1);
     208                else {
     209                        for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
     210                                ;
     211                        output[i] = '\0';
     212                }
     213                found++;
     214        }
     215        if (!found)
     216                return 0;
     217
     218        if (found > 1) {
     219                printf("\n");
     220                startpos = NULL;
     221                while ((foundtxt = cmdtab_search_one(name, &startpos))) {
     222                        cmd_info_t *hlp;
     223                        hlp = list_get_instance(startpos, cmd_info_t, link);
     224                        printf("%s - %s\n", hlp->name, hlp->description);
     225                        startpos = startpos->next;
     226                }
     227        }
     228        strncpy(name, output, MAX_SYMBOL_NAME);
     229        return found;
     230       
     231}
     232
     233static char * clever_readline(const char *prompt, chardev_t *input)
     234{
     235        static int histposition = 0;
     236
     237        char tmp[MAX_CMDLINE+1];
     238        int curlen = 0, position = 0;
     239        char *current = history[histposition];
     240        int i;
     241        char c;
     242
     243        printf("%s> ", prompt);
     244        while (1) {
     245                c = _getc(input);
     246                if (c == '\n') {
     247                        putchar(c);
     248                        break;
     249                } if (c == '\b') {
     250                        if (position == 0)
     251                                continue;
     252                        for (i=position; i<curlen;i++)
     253                                current[i-1] = current[i];
     254                        curlen--;
     255                        position--;
     256                        putchar('\b');
     257                        for (i=position;i<curlen;i++)
     258                                putchar(current[i]);
     259                        putchar(' ');
     260                        rdln_print_c('\b',curlen-position+1);
     261                        continue;
     262                }
     263                if (c == '\t') {
     264                        int found;
     265
     266                        /* Move to the end of the word */
     267                        for (;position<curlen && current[position]!=' ';position++)
     268                                putchar(current[position]);
     269                        /* Copy to tmp last word */
     270                        for (i=position-1;i >= 0 && current[i]!=' ' ;i--)
     271                                ;
     272                        /* If word begins with * or &, skip it */
     273                        if (tmp[0] == '*' || tmp[0] == '&')
     274                                for (i=1;tmp[i];i++)
     275                                        tmp[i-1] = tmp[i];
     276                        i++; /* I is at the start of the word */
     277                        strncpy(tmp, current+i, position-i+1);
     278
     279                        if (i==0) { /* Command completion */
     280                                found = cmdtab_compl(tmp);
     281                        } else { /* Symtab completion */
     282                                found = symtab_compl(tmp);
     283                        }
     284
     285                        if (found == 0)
     286                                continue;
     287                        for (i=0;tmp[i] && curlen < MAX_CMDLINE;i++,curlen++)
     288                                insert_char(current, tmp[i], i+position);
     289                        if (found == 1) { /* One match */
     290                                for (i=position;i<curlen;i++)
     291                                        putchar(current[i]);
     292                                position += strlen(tmp);
     293                                /* Add space to end */
     294                                if (position == curlen && curlen < MAX_CMDLINE) {
     295                                        current[position] = ' ';
     296                                        curlen++;
     297                                        position++;
     298                                        putchar(' ');
     299                                }
     300                        } else {
     301                                printf("%s> ", prompt);
     302                                for (i=0; i<curlen;i++)
     303                                        putchar(current[i]);
     304                                position += strlen(tmp);
     305                        }
     306                        rdln_print_c('\b', curlen-position);
     307                        continue;
     308                }
     309                if (c == 0x1b) {
     310                        c = _getc(input);
     311                        if (c!= 0x5b)
     312                                continue;
     313                        c = _getc(input);
     314                        if (c == 0x44) { /* Left */
     315                                if (position > 0) {
     316                                        putchar('\b');
     317                                        position--;
     318                                }
     319                                continue;
     320                        }
     321                        if (c == 0x43) { /* Right */
     322                                if (position < curlen) {
     323                                        putchar(current[position]);
     324                                        position++;
     325                                }
     326                                continue;
     327                        }
     328                        if (c == 0x41 || c == 0x42) { /* Up,down */
     329                                rdln_print_c('\b',position);
     330                                rdln_print_c(' ',curlen);
     331                                rdln_print_c('\b',curlen);
     332                                if (c == 0x41)
     333                                        histposition--;
     334                                else
     335                                        histposition++;
     336                                if (histposition < 0)
     337                                        histposition = KCONSOLE_HISTORY -1 ;
     338                                else
     339                                        histposition =  histposition % KCONSOLE_HISTORY;
     340                                current = history[histposition];
     341                                printf("%s", current);
     342                                curlen = strlen(current);
     343                                position = curlen;
     344                                continue;
     345                        }
     346                        continue;
     347                }
     348                if (curlen >= MAX_CMDLINE)
     349                        continue;
     350
     351                insert_char(current, c, position);
     352
     353                curlen++;
     354                for (i=position;i<curlen;i++)
     355                        putchar(current[i]);
     356                position++;
     357                rdln_print_c('\b',curlen-position);
     358        }
     359        histposition++;
     360        histposition = histposition % KCONSOLE_HISTORY;
     361        current[curlen] = '\0';
     362        return current;
     363}
     364
    140365/** Kernel console managing thread.
    141366 *
     
    144369void kconsole(void *arg)
    145370{
    146         char cmdline[MAX_CMDLINE+1];
    147371        cmd_info_t *cmd_info;
    148372        count_t len;
     373        char *cmdline;
    149374
    150375        if (!stdin) {
     
    154379       
    155380        while (true) {
    156                 printf("%s> ", __FUNCTION__);
    157                 if (!(len = gets(stdin, cmdline, sizeof(cmdline))))
    158                         continue;
    159                 cmdline[len] = '\0';
     381                cmdline = clever_readline(__FUNCTION__, stdin);
     382                len = strlen(cmdline);
     383                if (!len)
     384                        continue;
    160385                cmd_info = parse_cmdline(cmdline, len);
    161386                if (!cmd_info)
  • generic/src/debug/symtab.c

    r54aff98 r0c8e692  
    5656}
    5757
     58/** Find symbols that match the parameter forward and print them
     59 *
     60 * @param name - search string
     61 * @param startpos - starting position, changes to found position
     62 * @return Pointer to the part of string that should be completed or NULL
     63 */
     64static char * symtab_search_one(const char *name, int *startpos)
     65{
     66        int namelen = strlen(name);
     67        char *curname;
     68        int i,j;
     69        char *foundsym = NULL;
     70        int foundpos = 0;
     71        int colonoffset = -1;
     72
     73        for (i=0;name[i];i++)
     74                if (name[i] == ':') {
     75                        colonoffset = i;
     76                        break;
     77                }
     78
     79        for (i=*startpos;symbol_table[i].address_le;++i) {
     80                /* Find a ':' in name */
     81                curname = symbol_table[i].symbol_name;
     82                for (j=0; curname[j] && curname[j] != ':'; j++)
     83                        ;
     84                if (!curname[j])
     85                        continue;
     86                j -= colonoffset;
     87                curname += j;
     88                if (strlen(curname) < namelen)
     89                        continue;
     90                if (strncmp(curname, name, namelen) == 0) {
     91                        *startpos = i;
     92                        return curname+namelen;
     93                }
     94        }
     95        return NULL;
     96}
     97
    5898/** Return address that corresponds to the entry
    5999 *
    60  * Search symbol table, and if the address ENDS with
    61  * the parameter, return value
     100 * Search symbol table, and if there is one match, return it
    62101 *
    63102 * @param name Name of the symbol
     
    66105__address get_symbol_addr(const char *name)
    67106{
    68         count_t i;
    69107        count_t found = 0;
    70         count_t found_pos;
     108        __address addr = NULL;
     109        char *hint;
     110        int i;
    71111
    72         count_t nmlen = strlen(name);
    73         count_t slen;
    74 
    75         for (i=0;symbol_table[i].address_le;++i) {
    76                 slen = strlen(symbol_table[i].symbol_name);
    77                 if (slen < nmlen)
    78                         continue;
    79                 if (strncmp(name, symbol_table[i].symbol_name + (slen-nmlen),
    80                             nmlen) == 0) {
     112        i = 0;
     113        while ((hint=symtab_search_one(name, &i))) {
     114                if (!strlen(hint)) {
     115                        addr =  __u64_le2host(symbol_table[i].address_le);
    81116                        found++;
    82                         found_pos = i;
    83117                }
     118                i++;
    84119        }
    85         if (found == 0)
    86                 return NULL;
    87         if (found == 1)
    88                 return __u64_le2host(symbol_table[found_pos].address_le);
    89         return ((__address) -1);
     120        if (found > 1)
     121                return ((__address) -1);
     122        return addr;
    90123}
    91124
     125/** Find symbols that match parameter and prints them */
    92126void symtab_print_search(const char *name)
    93127{
    94128        int i;
    95         count_t nmlen = strlen(name);
    96         count_t slen;
    97129        __address addr;
    98130        char *realname;
    99131
    100         for (i=0;symbol_table[i].address_le;++i) {
    101                 slen = strlen(symbol_table[i].symbol_name);
    102                 if (slen < nmlen)
    103                         continue;
    104                 if (strncmp(name, symbol_table[i].symbol_name + (slen-nmlen),
    105                             nmlen) == 0) {
    106                         addr =  __u64_le2host(symbol_table[i].address_le);
    107                         realname = symbol_table[i].symbol_name;
    108                         printf("0x%p: %s\n", addr, realname);
     132
     133        i = 0;
     134        while (symtab_search_one(name, &i)) {
     135                addr =  __u64_le2host(symbol_table[i].address_le);
     136                realname = symbol_table[i].symbol_name;
     137                printf("0x%p: %s\n", addr, realname);
     138                i++;
     139        }
     140}
     141
     142/** Symtab completion
     143 *
     144 * @param name - Search string, completes to symbol name
     145 * @returns - 0 - nothing found, 1 - success, >1 print duplicates
     146 */
     147int symtab_compl(char *name)
     148{
     149        char output[MAX_SYMBOL_NAME+1];
     150        int startpos = 0;
     151        char *foundtxt;
     152        int found = 0;
     153        int i;
     154
     155        /* Do not print everything */
     156        if (!strlen(name))
     157                return 0;
     158
     159        output[0] = '\0';
     160
     161        while ((foundtxt = symtab_search_one(name, &startpos))) {
     162                startpos++;
     163                if (!found)
     164                        strncpy(output, foundtxt, strlen(foundtxt)+1);
     165                else {
     166                        for (i=0; output[i] && foundtxt[i] && output[i]==foundtxt[i]; i++)
     167                                ;
     168                        output[i] = '\0';
     169                }
     170                found++;
     171        }
     172        if (!found)
     173                return 0;
     174
     175        if (found > 1) {
     176                printf("\n");
     177                startpos = 0;
     178                while ((foundtxt = symtab_search_one(name, &startpos))) {
     179                        printf("%s\n", symbol_table[startpos].symbol_name);
     180                        startpos++;
    109181                }
    110182        }
     183        strncpy(name, output, MAX_SYMBOL_NAME);
     184        return found;
     185       
    111186}
  • generic/src/lib/func.c

    r54aff98 r0c8e692  
    8080 * @param len Maximal length for comparison.
    8181 *
    82  * @return 0 if the strings are equal, 1 otherwise.
     82 * @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
    8383 *
    8484 */
     
    8888       
    8989        i = 0;
    90         while ((i < len) && (src[i] == dst[i])) {
    91                 if ((i == len - 1) || (src[i] == '\0'))
    92                         return 0;
    93                 i++;
     90        for (;*src && *dst && i < len;src++,dst++,i++) {
     91                if (*src < *dst)
     92                        return -1;
     93                if (*src > *dst)
     94                        return 1;
    9495        }
     96        if (i == len || *src == *dst)
     97                return 0;
     98        if (*src < *dst)
     99                return -1;
    95100        return 1;
    96101}
Note: See TracChangeset for help on using the changeset viewer.