自己做的网站怎么用qq登入,wordpress 生成cookies,电视网站免费大全,自做网站nr_shell 是一套开源 shell 框架#xff0c;基于框架可创建终端交互功能。
为了记录终端输入指令#xff0c;以及进行解析处理#xff0c;nr_shell 提供了一套 cmd 结构体#xff0c;具体如下#xff1a;typedef struct static_cmd_function_struct
{char cmd[NR_SHELL_CM…nr_shell 是一套开源 shell 框架基于框架可创建终端交互功能。
为了记录终端输入指令以及进行解析处理nr_shell 提供了一套 cmd 结构体具体如下typedef struct static_cmd_function_struct
{char cmd[NR_SHELL_CMD_NAME_MAX_LENGTH]void (*fp)(char argc, char *argv);char *description;
} static_cmd_st;typedef struct shell_history_queue_struct
{unsigned short int fp;unsigned short int rp;unsigned short int len;unsigned short int index;unsigned short int store_front;unsigned short int store_rear;unsigned short int store_num;char queue[NR_SHELL_MAX_CMD_HISTORY_NUM 1];char buf[NR_SHELL_CMD_HISTORY_BUF_LENGTH 1];
} shell_his_queue_t;typedef struct nr_shell
{char user_name[NR_SHELL_USER_NAME_MAX_LENGTH];const static_cmd_st *static_cmd;shell_his_queue_st cmd_his;
} shell_st;nr_shell 启动后shell_st 结构体将作为 nr_shell 的实例对象维护 nr_shell 的运行环境。
根据结构体可知 shell_st 结构将记录当前用户的名称当前运行的指令以及运行过的历史指令。当输入指令格式后将通过 shell 函数进行解析处理。
对于指令的具体解析nr_shell 提供了 ansi_st 进行处理。关于 ansi_st 结构体的作用如下ansi_st nr_ansi;typedef struct nr_ansi_struct
{short p;unsigned int counter;char current_line[NR_ANSI_LINE_SIZE];char combine_buf[NR_ANSI_CTRL_MAX_LEN];char cmd_num;char combine_state;
} ansi_st;//初始阶段counter 代表指令格式字符串计数为0p 代表当前字符索引为 -1current_line 代表指令格式字符串
void ansi_init(ansi_st *ansi)
{ansi-counter 0; ansi-p -1;ansi-current_line[ansi-counter] \0;ansi-cmd_num 0;ansi-combine_state ANSI_NO_CTRL_CHAR;
}接下来是完整的字符串解析过程
对输入的字符串逐字解析首先判断其是否为特殊符号比如\b\n\033 等若不是则进行通用处理否则参考对应的处理办法处理。#define shell(c) \{ \if (ansi_get_char(c, nr_ansi) NR_SHELL_END_CHAR) \{ \shell_parser(nr_shell, nr_ansi.current_line); \ansi_clear_current_line(nr_ansi); \} \}char ansi_get_char(char x, ansi_st *ansi)
{int cmd_id -1;if (ansi-combine_state ANSI_NO_CTRL_CHAR) {cmd_id ansi_search_char(x, nr_ansi_in_special_symbol);if (cmd_id 0){if (nr_ansi_in_special_symbol_fun[cmd_id] ! NULL){nr_ansi_in_special_symbol_fun[cmd_id](ansi);}}else if (x \033){ansi-combine_state ANSI_WAIT_CTRL_CHAR_END;ansi-combine_buf[ansi-cmd_num] x;ansi-cmd_num;}else{nr_ansi_common_char_slover(ansi, x);}}else if (ansi-combine_state ANSI_WAIT_CTRL_CHAR_END){ansi-combine_buf[ansi-cmd_num] x;if ((a x z x) || (A x Z x) || x ~){cmd_id ansi_search_char(x, nr_ansi_in_cmd);nr_ansi_in_cmd_fun[cmd_id](ansi);ansi-cmd_num 0;anis-combine_state ANSI_NO_CTRL_CHAR;}else if (ansi-cmd_num 18){ansi-cmd_num 0;ansi-combine_state ANSI_NO_CTRL_CHAR;}else{ansi-cmd_num;}}else {ansi-combine_state ANSI_NO_CTRL_CHAR;}return x;
}int ansi_search_char(char x, const char *buf)
{int i 0;for (i 0; (buf[i] ! x) (buf[i] ! \0); i);if (buf[i] ! \0) {return i;}else {return -1;}
}void nr_ansi_common_char_slover(ansi_st *ansi, char x)
{unsigned int i;if (ansi-counter NR_ANSI_LINE_SIZE - 2){//该判断条件的目的是将 \0 字符向后复制空出中间字符添加新的字符if (ansi-p ansi-counter) {for (i ansi-counter; i ansi-p; i--){ansi-current_line[i] ansi-current_line[i - 1];}}//当前字符位置与字符串个数自增ansi-p;ansi-counter;//添加输入的字符ansi-current_line[ansi-p] x;//字符串添加结束标志符ansi-current_line[ansi-counter] \0if (ansi-p 1 ansi-counter) {shell_printf(\033[1);}#ifndef NR_MICRO_SHELL_SIMULATORansi_show_char(x);
#endif} else{ansi-counter NR_ANSI_LINE_SIZE - 3;if (ansi-p ansi-counter){ansi-p ansi-counter - 1;}ansi-current_line[ansi-counter] \0;}
}void shell_parser(shell_st *shell, char *str)
{char argc 0;char argv[NR_SHELL_CMD_LINE_MAX_LENGTH NR_SHELL_CMD_PARAS_MAX_NUM];char *token str;shell_fun_t fp;char index NR_SHELL_CMD_PARAS_MAX_NUM;if (shell_his_queue_search_cmd(shell-cmd_his, str) 0 str[0] ! \0){shell_his_queue_add_cmd(shell-cmd_his, str);}if (strlen(str) NR_SHELL_CMD_LINE_MAX_LENGTH){shell_printf(this command is too long.NR_SHELL_NEXT_LINE);shell_printf(%s, shell-user_name);return;}token nr_shell_strtok(token, );//从指令表中查看当前指令是否存在因此需根据实际情况在指令表中添加fp shell_search_cmd(shell, str);if (fp NULL){if (isalpha(str[0])){shell_printf(no command named: %sNR_SHELL_NEXT_LINE, token);}}else{argv[argc] index;strcpy(argv index, str);index strlen(str) 1;argc;token nr_shell_strtok(NULL, );//循环获取指令参数while (token ! NULL){argv[argc] index;strcpy(argv index, token);index strlen(token) 1;argc;token nr_shell_strtok(NULL, );}}if (fp ! NULL){fp(argc, argv); //执行指令对应的函数接口}
}关于 nr_shell 对指令的支持主要通过框架中的全局变量 nr_shell 完成。
新指令目前不支持接口添加只能直接在数组表中直接添加。shell_st nr_shell {
{.user_name NR_SHELL_USER_NAME,.static_cmd nr_cmd_start_add;
};#define nr_cmd_start_add (static_cmd[0])const static_cmd_st static_cmd[]
{{ls, shell_ls_cmd},{test, shell_test_cmd},{\0, NULL}
};以上就是对 nr_shell 框架的简单分析只针对 nr_shell 的运作流程以及新指令的添加。注特殊指令比如方向键等未做分析。