Lettershell之命令解析

时间:2024-10-16 11:05:25

lettershell项目链接 https://github.com/NevermindZZT/letter-shell

更多精彩内容欢迎关注微信公众号:码农练功房
在这里插入图片描述
往期精彩内容:
Lettershell之移植篇
Lettershell之命令注册
Lettershell之按键识别
Lettershell之输入缓冲区

当我们按下回车键时,shellEnter函数被回调:

void shellEnter(Shell *shell) {
   
    shellExec(shell);
    shellWritePrompt(shell, 1);
}

void shellExec(Shell *shell){
   
    if (shell->parser.length == 0){
   
        return;
    }
    shell->parser.buffer[shell->parser.length] = 0;
    if (shell->status.isChecked){
   
    #if SHELL_HISTORY_MAX_NUMBER > 0
        shellHistoryAdd(shell);
    #endif /** SHELL_HISTORY_MAX_NUMBER > 0 */
        shellParserParam(shell);
        shell->parser.length = shell->parser.cursor = 0;
        if (shell->parser.paramCount == 0) {
   
            return;
        }
        shellWriteString(shell, "\r\n");

        ShellCommand *command = shellSeekCommand(shell,
                                                 shell->parser.param[0],
                                                 shell->commandList.base,
                                                 0);
        if (command != NULL){
   
            shellRunCommand(shell, command);
        } else {
   
            shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]);
        }
    }
    else{
   
        shellCheckPassword(shell);
    }
}

此时以输入缓冲区为中心的业务逻辑便开始了,shellExec函数做了以下几件事:

  1. 历史命令记录(后续作为历史命令查询功能的数据来源)。
  2. 以空格为分隔符,对输入缓冲区中的保存的字符串进行分割,从而得到命令名称、命令参数列表。
  3. 将上一步得到的命令名称和命令注册表中的命令匹配,如果找到则执行命令,否则提示没有找到命令。

字符串分割

以空格为分隔符,通过对输入缓冲区中的保存的字符串进行分割:

static void shellParserParam(Shell *shell)
{
   
    shell->parser.paramCount = 
        shellSplit(shell->parser.buffer, shell->parser.length, 
                   shell->parser.param, ' ', SHELL_PARAMETER_MAX_NUMBER);
}

可以得到命令名称、命令参数列表。分割的结果保存在以下变量中:

#define     SHELL_PARAMETER_MAX_NUMBER  8