Changeset f4338d2 in mainline


Ignore:
Timestamp:
2005-11-26T22:48:17Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a8c48241
Parents:
ff3b3197
Message:

Improve kconsole's support for recognition of commands with arguments.
Implement ARG_TYPE_STRING.
Add 'describe' command.
Move kconsole.c to generic/src/console.
Move kconsole.h to generic/include/console.

Files:
6 edited
2 moved

Legend:

Unmodified
Added
Removed
  • Makefile

    rff3b3197 rf4338d2  
    9696        generic/src/console/chardev.c \
    9797        generic/src/console/console.c \
     98        generic/src/console/kconsole.c \
    9899        generic/src/cpu/cpu.c \
    99100        generic/src/main/main.c \
    100         generic/src/main/kconsole.c \
    101101        generic/src/main/kinit.c \
    102102        generic/src/main/uinit.c \
  • generic/include/console/kconsole.h

    rff3b3197 rf4338d2  
    4444        cmd_arg_type_t type;            /**< Type descriptor. */
    4545        void *buffer;                   /**< Buffer where to store data. */
    46         size_t buflen;                  /**< Size of the buffer. */
     46        size_t len;                     /**< Size of the buffer. */
    4747};
    4848
     
    5353        const char *name;               /**< Command name. */
    5454        const char *description;        /**< Textual description. */
    55         int (* func)(cmd_arg_t *cmd);   /**< Function implementing the command. */
     55        int (* func)(cmd_arg_t *);      /**< Function implementing the command. */
    5656        count_t argc;                   /**< Number of arguments. */
    5757        cmd_arg_t *argv;                /**< Argument vector. */
     58        void (* help)(void);            /**< Function for printing detailed help. */
    5859};
    5960
  • generic/include/func.h

    rff3b3197 rf4338d2  
    3838
    3939extern size_t strlen(const char *str);
    40 extern int strcmp(const char *src, const char *dst, size_t len);
     40extern int strncmp(const char *src, const char *dst, size_t len);
     41extern void strncpy(char *dest, const char *src, size_t len);
    4142
    4243#endif
  • generic/include/macros.h

    rff3b3197 rf4338d2  
    3737#define is_white(c)     (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
    3838
     39#define min(a,b)        ((a)<(b)?(a):(b))
     40#define max(a,b)        ((a)>(b)?(a):(b))
     41
    3942#endif
  • generic/src/console/kconsole.c

    rff3b3197 rf4338d2  
    2727 */
    2828
    29 #include <main/kconsole.h>
     29#include <console/kconsole.h>
    3030#include <console/console.h>
    3131#include <console/chardev.h>
     
    3838#include <func.h>
    3939#include <macros.h>
     40#include <debug.h>
    4041
    4142#define MAX_CMDLINE     256
     
    4445 *
    4546 * The console is realized by kernel thread kconsole.
    46  * It doesn't understand any commands on its own, but
    47  * makes it possible for other kernel subsystems to
     47 * It doesn't understand any useful command on its own,
     48 * but makes it possible for other kernel subsystems to
    4849 * register their own commands.
    4950 */
     
    6869
    6970static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
    70 static int cmd_help(cmd_arg_t *cmd);
    71 
     71static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end);
     72
     73/** Data and methods for 'help' command. */
     74static int cmd_help(cmd_arg_t *argv);
    7275static cmd_info_t help_info;
     76
     77/** Data and methods for 'description' command. */
     78static int cmd_desc(cmd_arg_t *argv);
     79static void desc_help(void);
     80static cmd_info_t desc_info;
     81static char desc_buf[MAX_CMDLINE+1];
     82static cmd_arg_t desc_argv = {
     83        .type = ARG_TYPE_STRING,
     84        .buffer = desc_buf,
     85        .len = sizeof(desc_buf)
     86};
    7387
    7488/** Initialize kconsole data structures. */
     
    8195        help_info.description = "List supported commands.";
    8296        help_info.func = cmd_help;
     97        help_info.help = NULL;
    8398        help_info.argc = 0;
    8499        help_info.argv = NULL;
    85        
     100
    86101        spinlock_initialize(&help_info.lock);
    87102        link_initialize(&help_info.link);
    88        
     103
    89104        if (!cmd_register(&help_info))
    90                 panic("could not register command\n");
     105                panic("could not register command %s\n", help_info.name);
     106
     107
     108        desc_info.name = "describe";
     109        desc_info.description = "Describe specified command.";
     110        desc_info.help = desc_help;
     111        desc_info.func = cmd_desc;
     112        desc_info.argc = 1;
     113        desc_info.argv = &desc_argv;
     114       
     115        spinlock_initialize(&desc_info.lock);
     116        link_initialize(&desc_info.link);
     117       
     118        if (!cmd_register(&desc_info))
     119                panic("could not register command %s\n", desc_info.name);
    91120}
    92121
     
    130159                }
    131160               
    132                 if ((strcmp(hlp->name, cmd->name, strlen(cmd->name)) == 0)) {
     161                if ((strncmp(hlp->name, cmd->name, strlen(cmd->name)) == 0)) {
    133162                        /* The command is already there. */
    134163                        spinlock_unlock(&hlp->lock);
     
    170199        while (true) {
    171200                printf("%s> ", __FUNCTION__);
    172                 len = gets(stdin, cmdline, sizeof(cmdline));
     201                if (!(len = gets(stdin, cmdline, sizeof(cmdline))))
     202                        continue;
    173203                cmdline[len] = '\0';
    174204                cmd_info = parse_cmdline(cmdline, len);
    175                 if (!cmd_info) {
    176                         printf("?\n");
     205                if (!cmd_info)
    177206                        continue;
    178                 }
    179207                (void) cmd_info->func(cmd_info->argv);
    180208        }
     
    191219{
    192220        index_t start = 0, end = 0;
    193         bool found_start = false;
    194221        cmd_info_t *cmd = NULL;
    195222        link_t *cur;
     
    197224        int i;
    198225       
    199         for (i = 0; i < len; i++) {
     226        if (!parse_argument(cmdline, len, &start, &end)) {
     227                /* Command line did not contain alphanumeric word. */
     228                return NULL;
     229        }
     230
     231        ipl = interrupts_disable();
     232        spinlock_lock(&cmd_lock);
     233       
     234        for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
     235                cmd_info_t *hlp;
     236               
     237                hlp = list_get_instance(cur, cmd_info_t, link);
     238                spinlock_lock(&hlp->lock);
     239               
     240                if (strncmp(hlp->name, &cmdline[start], (end - start) + 1) == 0) {
     241                        cmd = hlp;
     242                        break;
     243                }
     244               
     245                spinlock_unlock(&hlp->lock);
     246        }
     247       
     248        spinlock_unlock(&cmd_lock);     
     249       
     250        if (!cmd) {
     251                /* Unknown command. */
     252                printf("Unknown command.\n");
     253                interrupts_restore(ipl);
     254                return NULL;
     255        }
     256
     257        /* cmd == hlp is locked */
     258       
     259        /*
     260         * The command line must be further analyzed and
     261         * the parameters therefrom must be matched and
     262         * converted to those specified in the cmd info
     263         * structure.
     264         */
     265
     266        for (i = 0; i < cmd->argc; i++) {
     267                char *buf;
     268                start = end + 1;
     269                if (!parse_argument(cmdline, len, &start, &end)) {
     270                        printf("Too few arguments.\n");
     271                        spinlock_unlock(&cmd->lock);
     272                        interrupts_restore(ipl);
     273                        return NULL;
     274                }
     275               
     276                switch (cmd->argv[i].type) {
     277                    case ARG_TYPE_STRING:
     278                        buf = cmd->argv[i].buffer;
     279                        strncpy(buf, (const char *) &cmdline[start], min((end - start) + 1, cmd->argv[i].len - 1));
     280                        buf[min((end - start) + 1, cmd->argv[i].len - 1)] = '\0';
     281                        break;
     282                    case ARG_TYPE_INT:
     283                    case ARG_TYPE_INVALID:
     284                    default:
     285                        panic("invalid argument type\n");
     286                        break;
     287                }
     288        }
     289       
     290        start = end + 1;
     291        if (parse_argument(cmdline, len, &start, &end)) {
     292                printf("Too many arguments.\n");
     293                spinlock_unlock(&cmd->lock);
     294                interrupts_restore(ipl);
     295                return NULL;
     296        }
     297       
     298        spinlock_unlock(&cmd->lock);
     299        interrupts_restore(ipl);
     300        return cmd;
     301}
     302
     303/** Parse argument.
     304 *
     305 * Find start and end positions of command line argument.
     306 *
     307 * @param cmdline Command line as read from the input device.
     308 * @param len Number of characters in cmdline.
     309 * @param start On entry, 'start' contains pointer to the index
     310 *        of first unprocessed character of cmdline.
     311 *        On successful exit, it marks beginning of the next argument.
     312 * @param end Undefined on entry. On exit, 'end' points to the last character
     313 *        of the next argument.
     314 *
     315 * @return false on failure, true on success.
     316 */
     317bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end)
     318{
     319        int i;
     320        bool found_start = false;
     321       
     322        ASSERT(start != NULL);
     323        ASSERT(end != NULL);
     324       
     325        for (i = *start; i < len; i++) {
    200326                if (!found_start) {
    201327                        if (is_white(cmdline[i]))
    202                                 start++;
     328                                (*start)++;
    203329                        else
    204330                                found_start = true;
     
    208334                }
    209335        }
    210         end = i - 1;
    211        
    212         if (!found_start) {
    213                 /* Command line did not contain alphanumeric word. */
    214                 return NULL;
    215         }
     336        *end = i - 1;
     337
     338        return found_start;
     339}
     340
     341
     342/** List supported commands.
     343 *
     344 * @param argv Argument vector.
     345 *
     346 * @return 0 on failure, 1 on success.
     347 */
     348int cmd_help(cmd_arg_t *argv)
     349{
     350        link_t *cur;
     351        ipl_t ipl;
    216352
    217353        ipl = interrupts_disable();
     
    224360                spinlock_lock(&hlp->lock);
    225361               
    226                 if (strcmp(hlp->name, &cmdline[start], (end - start) + 1) == 0) {
    227                         cmd = hlp;
    228                         break;
    229                 }
    230                
     362                printf("%s - %s\n", hlp->name, hlp->description);
     363
    231364                spinlock_unlock(&hlp->lock);
    232365        }
    233366       
    234367        spinlock_unlock(&cmd_lock);     
    235        
    236         if (!cmd) {
    237                 /* Unknown command. */
    238                 interrupts_restore(ipl);
    239                 return NULL;
    240         }
    241 
    242         /* cmd == hlp is locked */
    243        
    244         /*
    245          * TODO:
    246          * The command line must be further analyzed and
    247          * the parameters therefrom must be matched and
    248          * converted to those specified in the cmd info
    249          * structure.
    250          */
    251        
    252         spinlock_unlock(&cmd->lock);
    253368        interrupts_restore(ipl);
    254         return cmd;
    255 }
    256 
    257 /** List supported commands.
    258  *
    259  * @param cmd Argument vector.
     369
     370        return 1;
     371}
     372
     373/** Describe specified command.
     374 *
     375 * @param argv Argument vector.
    260376 *
    261377 * @return 0 on failure, 1 on success.
    262378 */
    263 int cmd_help(cmd_arg_t *cmd)
     379int cmd_desc(cmd_arg_t *argv)
    264380{
    265381        link_t *cur;
     
    274390                hlp = list_get_instance(cur, cmd_info_t, link);
    275391                spinlock_lock(&hlp->lock);
    276                
    277                 printf("%s\t%s\n", hlp->name, hlp->description);
     392
     393                if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
     394                        printf("%s - %s\n", hlp->name, hlp->description);
     395                        if (hlp->help)
     396                                hlp->help();
     397                        spinlock_unlock(&hlp->lock);
     398                        break;
     399                }
    278400
    279401                spinlock_unlock(&hlp->lock);
     
    285407        return 1;
    286408}
     409
     410/** Print detailed description of 'describe' command. */
     411void desc_help(void)
     412{
     413        printf("Syntax: describe command_name\n");
     414}
  • generic/src/lib/func.c

    rff3b3197 rf4338d2  
    8383 *
    8484 */
    85 int strcmp(const char *src, const char *dst, size_t len)
     85int strncmp(const char *src, const char *dst, size_t len)
    8686{
    8787        int i;
     
    9696}
    9797
     98/** Copy NULL terminated string.
     99 *
     100 * Copy at most 'len' characters from string 'src' to 'dest'.
     101 * If 'src' is shorter than 'len', '\0' is inserted behind the
     102 * last copied character.
     103 *
     104 * @param src Source string.
     105 * @param dst Destination buffer.
     106 * @param len Size of destination buffer.
     107 */
     108void strncpy(char *dest, const char *src, size_t len)
     109{
     110        int i;
     111        for (i = 0; i < len; i++) {
     112                if (!(dest[i] = src[i]))
     113                        return;
     114        }
     115}
  • generic/src/main/kinit.c

    rff3b3197 rf4338d2  
    2828
    2929#include <main/kinit.h>
    30 #include <main/kconsole.h>
    3130#include <main/uinit.h>
    3231#include <config.h>
     
    4645#include <memstr.h>
    4746#include <console/console.h>
     47#include <console/kconsole.h>
    4848
    4949#ifdef CONFIG_SMP
  • generic/src/main/main.c

    rff3b3197 rf4338d2  
    3737#include <proc/task.h>
    3838#include <main/kinit.h>
    39 #include <main/kconsole.h>
     39#include <console/kconsole.h>
    4040#include <cpu.h>
    4141#include <align.h>
Note: See TracChangeset for help on using the changeset viewer.