⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readline.c

📁 一个实时操作系统的源代码。包括任务的调度机制、文件系统等
💻 C
📖 第 1 页 / 共 2 页
字号:
        line += 2;
        incmd = RL_INCMD_TOP;
    }
    else if (line[0] == '.')
    {
        line += 1;
        incmd = RL_INCMD_BACK;
    }
    else if (line[0] == 'h' &&
        line[1] == 'e' &&
        line[2] == 'l' &&
        line[3] == 'p')
    {
        line += 4;
        incmd = RL_INCMD_HELP;
    }
    else if (line[0] == 'q' &&
        line[1] == 'u' &&
        line[2] == 'i' &&
        line[3] == 't')
    {
        line += 4;
        incmd = RL_INCMD_QUIT;
    }
    
    trim_left(line);
    
    if (line[0] == 0)
        return incmd;

    return RL_INCMD_NULL;
}

static void readline_linein(readline_t __p_* rl, char __p_* line)
{
    int status;
    readline_cmd_t __p_* _cmd;
    

    trim_left(line);

    status = readline_incmd(line);

    switch (status) {
    
    case RL_INCMD_HELP:
    
        /* Display root command help. */
        readline_inhelp(rl);
        break;
        
    case RL_INCMD_BACK:
    
        /* return to back level. */
        if (rl->root_cmd->parent != NULL)
            rl->root_cmd = rl->root_cmd->parent;

        break;
        
    case RL_INCMD_TOP:

        _cmd = rl->root_cmd;

        while (_cmd->parent != NULL)
            _cmd = _cmd->parent;

        rl->root_cmd = _cmd;

        break;
        
    case RL_INCMD_QUIT:

        readline_quit(rl);
        break;
        
    default:
        _cmd = rl->root_cmd;
        
        /* See if empty line. */
        if (*line != '\0') {
        
            /* Not empty line. */
            status = readline_search(&_cmd, &line);
            
            if (status == RL_OK) {
            
                if (_cmd->child == NULL)
                    readline_exec(rl, _cmd, line);
                else if (*line == '\0')
                    rl->root_cmd = _cmd->child;
                else if (*line == '?' &&
                    wordend(*(line+1)))
                {
                    readline_dohelp(rl, _cmd->child);
                }

            } else if (status == RL_AMBIGUITY) {
            
                puts("Ambiguity: ");
                puts(line);
                putc('\n');
                
            } else if (status == RL_MATCH_NULL) {
            
                puts("No such command: ");
                puts(line);
                putc('\n');
            }

            /* Add line to history. */
            if (++rl->hist == RSI_HISTORY_DEPTH)
                rl->hist = 0;
        }
    }
}

/* try to complete current command line
 */
static void readline_complete(readline_t __p_* rl)
{
    readline_cmd_t __p_* _cmd;
    char __p_* _line;
    char __p_* _p;
    int match, i;
    
    _cmd = rl->root_cmd;
    _line = rl->line[rl->hist];

    trim_left(_line);

    if (*_line == 0) {
        putc('\n');
        readline_dohelp(rl, rl->root_cmd);
        readline_newline(rl);
        return;
    }
    
    for (;;) {

        _p = _line;
        match = readline_lookup(&_cmd, &_p);

        /* See if command found. */
        if (match == RL_MATCH_NULL) {
            /* Not match. */
            break;
        }
        
        i = 0;
        while (_line[i] && !whitespace(_line[i]))
            i++;

        /* append line. */
        if (_line[i] == '\0') {

            for ( ; ; i++) {

                if (_cmd->name[i] == '\0')
                    break;

                _line[i] = _cmd->name[i];
                _line[i+1] = '\0';
                rl->index++;

                _p = _line;
                if (match != readline_lookup(&_cmd, &_p)) {
                
                    _line[i] = '\0';
                    rl->index--;
                    break;
                }
                
                putc(_line[i]);
            }
            
            break;
        }

        /* See if command neither match and nor the end-word. */
        if (match == RL_AMBIGUITY)
            break;
        
        /* command match and not the end-word. */
        _cmd = _cmd->child;
        _line = _p;
    }
}


/* character parse. */
static void readline_cparse(readline_t __p_* rl, char c)
{
    RSI_REG char __p_* line;

    line = rl->line[rl->hist];
    line[rl->index] = 0;

    switch (c) {

    /* validate command */
    case '\r':
        c = '\n';
    case '\n':
        /* first, echo the newline */
        if (echo)
            putc(c);

        readline_linein(rl, line);
        readline_newline(rl);

        break;

    /* backspace */
    case 8:
    case 127:
        if (rl->index > 0) {
        
            puts("\b \b");
            rl->index--;
            line[rl->index] = 0;
        }
        break;

    /* CTRL-N: next in history */
    case 14:
    {
        int nextline = (rl->hist + 1) % RSI_HISTORY_DEPTH;

        line = rl->line[nextline];
        
        if (line[0]) {
        
            /* Fill the rest of the line with spaces */
            while (rl->index-- > strlen(line))
                puts("\b \b");
            putc('\r');
            readline_newline(rl);
            puts(line);
            rl->index = strlen(line);
            rl->hist = nextline;
        }

        break;
    }
    
    /* CTRL-P: back in history */
    case 16:
    {
        int prevline = (rl->hist + RSI_HISTORY_DEPTH - 1) % RSI_HISTORY_DEPTH;

        line = rl->line[prevline];

        if (line[0]) {
        
            /* Fill the rest of the line with spaces */
            while (rl->index-- > strlen(line))
                puts("\b \b");
                
            putc('\r');
            readline_newline(rl);
            puts(line);
            rl->index = strlen(line);
            rl->hist = prevline;
        }

        break;
    }

    /* TAB: autocompletion */
    case 9:
    case '!':
        readline_complete(rl);

        break;
    
    /* Any input character */
    default:
        if (rl->index < RSI_INBUFF_SZ - 1) {
            if (echo)
                putc(c);
            line[rl->index++] = c;
        }
    }
}

/* New character input. */
void readline_charin(readline_t __p_* rl, char c)
{
    RSI_ASSERT(rl != NULL);
    RSI_ASSERT(rl->init == RSI_INITED);

    /*
     * Filter characters here. */
     
    readline_cparse(rl, c);
}


/* Set shell prompt. */
void readline_set_prompt(readline_t __p_* rl, char __p_* s)
{
    RSI_REG int i;

    RSI_ASSERT(rl != NULL);
    RSI_ASSERT(rl->init == RSI_INITED);
    RSI_ASSERT(s != NULL);
    
    for (i = 0; i < RSI_PROMPT_SZ; i++) {
    
        rl->prompt[i] = s[i];

        if (s[i] == '\0')
            break;
    }

    /* prevent string crash. */
    rl->prompt[RSI_PROMPT_SZ - 1] = '\0';
}


/* Add a new command */
status_t readline_add_cmd(
    readline_t      __p_* rl,
    char            __p_* parent,
    readline_cmd_t  __p_* cmd
    )
{
    int match;
    readline_cmd_t __p_* _cmd;
    char __p_* _line;

    if (parent && !rl->root_cmd)
        return RS_ENULL;

    for (_cmd = cmd; _cmd->name != NULL; _cmd++) {
    
        if (parent != NULL) {

            readline_cmd_t __p_* _root_cmd;

            _root_cmd = rl->root_cmd;
            _line = parent;
            
            match = readline_search(&_root_cmd, &_line);

            if (match == RL_OK) {

                _cmd->parent = _root_cmd;
                if (_root_cmd->child == NULL) {
                    _cmd->next = _cmd;
                    _root_cmd->child = _cmd;
                } else {
                    _cmd->next = _root_cmd->child->next;
                    _root_cmd->child->next = _cmd;
                }
            }
            
        } else {
        
            if (rl->root_cmd == NULL) {
                _cmd->next = _cmd;
                rl->root_cmd = _cmd;
            } else {
                _cmd->next = rl->root_cmd->next;                
                rl->root_cmd->next = _cmd;
            }
        }
    }

    return RS_EOK;
}


status_t readline_quit(readline_t __p_* rl)
{
    RSI_ASSERT(rl != NULL);
    RSI_ASSERT(rl->init == RSI_INITED);

    rl->quit = 1;

    return RS_EOK;
}


status_t readline_loop(readline_t __p_* rl)
{
    RSI_REG char c;

    RSI_ASSERT(rl != NULL);
    RSI_ASSERT(rl->init == RSI_INITED);

    readline_newline(rl);
    
    /* main loop */
    while (rl->quit == 0) {
    
        c = getc();

        readline_charin(rl, c);
    }

    return RS_EOK;
}


status_t readline_init(
        readline_t      __p_* rl,
        char            __p_* prompt,
        readline_io_t   __p_* iofnt,
        int8u  options
        )
{
    int i;
    
    RSI_ASSERT(rl != NULL);
    RSI_ASSERT(iofnt != NULL);

    rl->root_cmd = NULL;
    rl->hist = 0;
    rl->index = 0;
    rl->quit = 0;

    for (i = 0; i < RSI_HISTORY_DEPTH; i++)
        rl->line[i][0] = 0;
    
    if (iofnt != NULL)
        rl->io = *iofnt;

    rl->prompt[0] = '#';
    rl->prompt[1] = '\0';

    rl->options = options;
    
#if CFG_DEBUG > 0
    /* Initialized flag. */
    rl->init = RSI_INITED;
#endif

    if (prompt != NULL)
        readline_set_prompt(rl, prompt);

    /* Return succeed. */
    return RS_EOK;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -