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

Changeset f0348c8 in mainline


Ignore:
Timestamp:
2012-07-10T13:03:10Z (10 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial
Children:
97c7682, 9904eb90, ceafd1b, d9812b4, dfc07c1
Parents:
33fc3ae (diff), f4a8734 (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 kernel console completion and console interface clean-up

Kernel console completion (#50), thanks Sandeep Kumar

  • tab-completion uses symbol table
  • tab-completion display huge number of hints in user-friendly manner (display all?, more?)

Userspace console interface changes

  • console does not send special keys (arrows etc.) on its VFS interface
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r33fc3ae rf0348c8  
    196196        generic/src/console/chardev.c \
    197197        generic/src/console/console.c \
     198        generic/src/console/prompt.c \
    198199        generic/src/cpu/cpu.c \
    199200        generic/src/ddi/ddi.c \
  • kernel/generic/include/debug.h

    r33fc3ae rf0348c8  
    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

    r33fc3ae rf0348c8  
    3636#define KERN_SYMTAB_H_
    3737
    38 #include <typedefs.h>
     38#include <symtab_lookup.h>
     39#include <console/chardev.h>
    3940
    40 #define MAX_SYMBOL_NAME  64
    41 
    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 *);
    5041extern 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 */
     42extern int symtab_compl(char *, size_t, indev_t *);
    6143
    6244#endif
  • kernel/generic/src/console/kconsole.c

    r33fc3ae rf0348c8  
    4343#include <console/chardev.h>
    4444#include <console/cmd.h>
     45#include <console/prompt.h>
    4546#include <print.h>
    4647#include <panic.h>
     
    201202 *
    202203 */
    203 NO_TRACE static int cmdtab_compl(char *input, size_t size)
     204NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t * indev)
    204205{
    205206        const char *name = input;
    206207       
    207208        size_t found = 0;
     209        /* Maximum Match Length : Length of longest matching common substring in
     210           case more than one match is found */
     211        size_t max_match_len = size;
     212        size_t max_match_len_tmp = size;
     213        size_t input_len = str_length(input);
    208214        link_t *pos = NULL;
    209215        const char *hint;
    210216        char *output = malloc(MAX_CMDLINE, 0);
     217        size_t hints_to_show = MAX_TAB_HINTS - 1;
     218        size_t total_hints_shown = 0;
     219        bool continue_showing_hints = true;
    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("\n");
     234                continue_showing_hints = console_prompt_display_all_hints(indev, found);
    220235        }
    221236       
     
    225240                while (cmdtab_search_one(name, &pos)) {
    226241                        cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
    227                         printf("%s (%s)\n", hlp->name, hlp->description);
     242
     243                        if (continue_showing_hints) {
     244                                printf("%s (%s)\n", hlp->name, hlp->description);
     245                                --hints_to_show;
     246                                ++total_hints_shown;
     247
     248                                if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
     249                                        continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
     250                                }
     251                        }
     252
    228253                        pos = pos->next;
    229                 }
     254                        for(max_match_len_tmp = 0; output[max_match_len_tmp] == hlp->name[input_len + max_match_len_tmp]
     255                                        && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     256                        max_match_len = max_match_len_tmp;
     257                }
     258                /* keep only the characters common in all completions */
     259                output[max_match_len] = 0;
    230260        }
    231261       
     
    294324                        if (beg == 0) {
    295325                                /* Command completion */
    296                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     326                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    297327                        } else {
    298328                                /* Symbol completion */
    299                                 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     329                                found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    300330                        }
    301331                       
    302332                        if (found == 0)
    303333                                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                        
     334
     335                        /* We have hints, may be many. In case of more than one hint,
     336                           tmp will contain the common prefix. */
    315337                        size_t off = 0;
    316338                        size_t i = 0;
     
    320342                                i++;
    321343                        }
     344                       
     345                        if (found > 1) {
     346                                /* No unique hint, list was printed */
     347                                printf("%s> ", prompt);
     348                                printf("%ls", current);
     349                                position += str_length(tmp);
     350                                print_cc('\b', wstr_length(current) - position);
     351                                continue;
     352                        }
     353                       
     354                        /* We have a hint */
    322355                       
    323356                        printf("%ls", current + position);
     
    540573/** Parse command line.
    541574 *
    542  * @param cmdline Command line as read from input device. 
     575 * @param cmdline Command line as read from input device.
    543576 * @param size    Size (in bytes) of the string.
    544577 *
  • kernel/generic/src/debug/symtab.c

    r33fc3ae rf0348c8  
    4343#include <typedefs.h>
    4444#include <errno.h>
     45#include <console/prompt.h>
    4546
    4647/** Get name of a symbol that seems most likely to correspond to address.
     
    209210 *
    210211 */
    211 int symtab_compl(char *input, size_t size)
     212int symtab_compl(char *input, size_t size, indev_t * indev)
    212213{
    213214#ifdef CONFIG_SYMTAB
     
    226227        const char *hint;
    227228        char output[MAX_SYMBOL_NAME];
     229        /* Maximum Match Length : Length of longest matching common substring in
     230           case more than one match is found */
     231        size_t max_match_len = size;
     232        size_t max_match_len_tmp = size;
     233        size_t input_len = str_length(input);
     234        char *sym_name;
     235        size_t hints_to_show = MAX_TAB_HINTS - 1;
     236        size_t total_hints_shown = 0;
     237        bool continue_showing_hints = true;
    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))) {
     
    235251                pos++;
    236252                found++;
     253        }
     254       
     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("\n");
     258                continue_showing_hints = console_prompt_display_all_hints(indev, found);
    237259        }
    238260       
     
    241263                pos = 0;
    242264                while (symtab_search_one(name, &pos)) {
    243                         printf("%s\n", symbol_table[pos].symbol_name);
     265                        sym_name = symbol_table[pos].symbol_name;
    244266                        pos++;
     267
     268                        if (continue_showing_hints) { /* We are still showing hints */
     269                                printf("%s\n", sym_name);
     270                                --hints_to_show;
     271                                ++total_hints_shown;
     272
     273                                if (hints_to_show == 0 && total_hints_shown != found) { /* Time to ask user to continue */
     274                                        continue_showing_hints = console_prompt_more_hints(indev, &hints_to_show);
     275                                }
     276                        }
     277
     278                        for(max_match_len_tmp = 0; output[max_match_len_tmp] == sym_name[input_len + max_match_len_tmp]
     279                                        && max_match_len_tmp < max_match_len; ++max_match_len_tmp);
     280                        max_match_len = max_match_len_tmp;
    245281                }
     282                /* keep only the characters common in all completions */
     283                output[max_match_len] = 0;
    246284        }
    247285       
  • uspace/app/bdsh/cmds/modules/cat/cat.c

    r33fc3ae rf0348c8  
    6262static sysarg_t console_rows = 0;
    6363static bool should_quit = false;
     64static bool dash_represents_stdin = false;
    6465
    6566static console_ctrl_t *console = NULL;
     
    7374        { "more", no_argument, 0, 'm' },
    7475        { "hex", no_argument, 0, 'x' },
     76        { "stdin", no_argument, 0, 's' },
    7577        { 0, 0, 0, 0 }
    7678};
     
    9395                "  -m, --more       Pause after each screen full\n"
    9496                "  -x, --hex        Print bytes as hex values\n"
     97                "  -s  --stdin      Treat `-' in file list as standard input\n"
    9598                "Currently, %s is under development, some options don't work.\n",
    9699                cmdname, cmdname);
     
    172175        off64_t file_size = 0, length = 0;
    173176
    174         fd = open(fname, O_RDONLY);
     177        bool reading_stdin = dash_represents_stdin && (str_cmp(fname, "-") == 0);
     178
     179        if (reading_stdin) {
     180                fd = fileno(stdin);
     181                /* Allow storing the whole UTF-8 character. */
     182                blen = STR_BOUNDS(1);
     183        } else {
     184                fd = open(fname, O_RDONLY);
     185        }
    175186        if (fd < 0) {
    176187                printf("Unable to open %s\n", fname);
     
    207218
    208219        do {
    209                 bytes = read(fd, buff + copied_bytes, (
    210                         (length != CAT_FULL_FILE && length - (off64_t)count <= (off64_t)(blen - copied_bytes)) ?
    211                         (size_t)(length - count) :
    212                         (blen - copied_bytes) ) );
     220                size_t bytes_to_read;
     221                if (reading_stdin) {
     222                        bytes_to_read = 1;
     223                } else {
     224                        if ((length != CAT_FULL_FILE)
     225                            && (length - (off64_t)count <= (off64_t)(blen - copied_bytes))) {
     226                                bytes_to_read = (size_t) (length - count);
     227                        } else {
     228                                bytes_to_read = blen - copied_bytes;
     229                        }
     230                }
     231                bytes = read(fd, buff + copied_bytes, bytes_to_read);
    213232                bytes += copied_bytes;
    214233                copied_bytes = 0;
     
    242261                        reads++;
    243262                }
     263
     264                if (reading_stdin) {
     265                        fflush(stdout);
     266                }
    244267        } while (bytes > 0 && !should_quit && (count < length || length == CAT_FULL_FILE));
    245268
     
    284307
    285308        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    286                 c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
     309                c = getopt_long(argc, argv, "xhvmH:t:b:s", long_options, &opt_ind);
    287310                switch (c) {
    288311                case 'h':
     
    318341                        hex = true;
    319342                        break;
     343                case 's':
     344                        dash_represents_stdin = true;
     345                        break;
    320346                }
    321347        }
  • uspace/srv/hid/console/console.c

    r33fc3ae rf0348c8  
    7676} console_state_t;
    7777
     78#define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1)
     79
    7880typedef struct {
    7981        atomic_t refcnt;           /**< Connection reference count */
    8082        prodcons_t input_pc;       /**< Incoming keyboard events */
     83        char char_remains[UTF8_CHAR_BUFFER_SIZE]; /**< Not yet sent bytes of last char event. */
     84        size_t char_remains_len;   /**< Number of not yet sent bytes. */
    8185       
    8286        fibril_mutex_t mtx;        /**< Lock protecting mutable fields */
     
    613617       
    614618        size_t pos = 0;
     619
     620        /*
     621         * Read input from keyboard and copy it to the buffer.
     622         * We need to handle situation when wchar is split by 2 following
     623         * reads.
     624         */
    615625        while (pos < size) {
    616                 link_t *link = prodcons_consume(&cons->input_pc);
    617                 kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
    618                
    619                 if (event->type == KEY_PRESS) {
    620                         buf[pos] = event->c;
     626                /* Copy to the buffer remaining characters. */
     627                while ((pos < size) && (cons->char_remains_len > 0)) {
     628                        buf[pos] = cons->char_remains[0];
    621629                        pos++;
    622                 }
    623                
    624                 free(event);
     630                        /* Unshift the array. */
     631                        for (size_t i = 1; i < cons->char_remains_len; i++) {
     632                                cons->char_remains[i - 1] = cons->char_remains[i];
     633                        }
     634                        cons->char_remains_len--;
     635                }
     636                /* Still not enough? Then get another key from the queue. */
     637                if (pos < size) {
     638                        link_t *link = prodcons_consume(&cons->input_pc);
     639                        kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
     640
     641                        /* Accept key presses of printable chars only. */
     642                        if ((event->type == KEY_PRESS) && (event->c != 0)) {
     643                                wchar_t tmp[2] = { event->c, 0 };
     644                                wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
     645                                cons->char_remains_len = str_size(cons->char_remains);
     646                        }
     647
     648                        free(event);
     649                }
    625650        }
    626651       
     
    930955                fibril_mutex_initialize(&consoles[i].mtx);
    931956                prodcons_initialize(&consoles[i].input_pc);
     957                consoles[i].char_remains_len = 0;
    932958               
    933959                if (graphics_state == GRAPHICS_FULL) {
Note: See TracChangeset for help on using the changeset viewer.