diff --git a/example/linux/linux_main.c b/example/linux/linux_main.c index 184ab2c..025514b 100755 --- a/example/linux/linux_main.c +++ b/example/linux/linux_main.c @@ -1,7 +1,7 @@ /* * @Author: your name * @Date: 2021-09-14 23:58:24 - * @LastEditTime: 2021-09-22 23:13:05 + * @LastEditTime: 2021-10-08 21:51:36 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: /xcmd/example/linux/linux_main.c @@ -16,6 +16,7 @@ #include "ex_cmds.h" #include "socket_cmds.h" + int getch(void) { struct termios tm, tm_old; @@ -59,7 +60,7 @@ static int key_ctr_c(void* pv) static xcmd_key_t keys[] = { - {CTR_C, key_ctr_c, "ctr+c", NULL}, + {KEY_CTR_C, key_ctr_c, "ctr+c", NULL}, }; void user_keys_init(void) diff --git a/extensions/ex_keys/ex_keys.c b/extensions/ex_keys/ex_keys.c index 1baac0a..e8c0bfe 100644 --- a/extensions/ex_keys/ex_keys.c +++ b/extensions/ex_keys/ex_keys.c @@ -49,11 +49,11 @@ static int xcmd_ctr_l(void *pv) static xcmd_key_t ex_keys[] = { - {CTR_A, xcmd_ctr_a, "ctr+a", NULL}, - {CTR_E, xcmd_ctr_e, "ctr+e", NULL}, - {CTR_U, xcmd_ctr_u, "ctr+u", NULL}, - {CTR_K, xcmd_ctr_k, "ctr+k", NULL}, - {CTR_L, xcmd_ctr_l, "ctr+l", NULL}, + {KEY_CTR_A, xcmd_ctr_a, "ctr+a", NULL}, + {KEY_CTR_E, xcmd_ctr_e, "ctr+e", NULL}, + {KEY_CTR_U, xcmd_ctr_u, "ctr+u", NULL}, + {KEY_CTR_K, xcmd_ctr_k, "ctr+k", NULL}, + {KEY_CTR_L, xcmd_ctr_l, "ctr+l", NULL}, }; diff --git a/extensions/test/test.c b/extensions/test/test.c index af2aee3..fc5d839 100644 --- a/extensions/test/test.c +++ b/extensions/test/test.c @@ -154,7 +154,7 @@ static int cmd_ctr_q(void* pv) static xcmd_t cmds[] = { - {"echo", cmd_echo, "echo anything", NULL}, + {"echo", cmd_echo, "echo [msg]", NULL}, {"history", cmd_history, "show history list", NULL}, {"example", cmd_example, "example [-f|-i|-s] [val]", NULL}, {"delcmd", cmd_delete_cmd, "delete cmd [val]", NULL}, @@ -163,7 +163,7 @@ static xcmd_t cmds[] = static xcmd_key_t keys[] = { - {CTR_Q, cmd_ctr_q, "ctr+q", NULL}, + {KEY_CTR_Q, cmd_ctr_q, "ctr+q", NULL}, }; void test_cmd_init(void) diff --git a/inc/xcmd.h b/inc/xcmd.h index 6af9d1d..7fac58b 100755 --- a/inc/xcmd.h +++ b/inc/xcmd.h @@ -27,7 +27,7 @@ typedef struct __cmd typedef struct __key { - XCMD_KEY_T key; + char* key; cmd_key_func_t func; char* help; struct __key *next; @@ -153,6 +153,13 @@ char* xcmd_display_get(void); void xcmd_display_print(const char *msg); void xcmd_display_write(const char* buf, uint16_t len); +/** + * @description: + * @param {*} + * @return {*} + */ +char* xcmd_display_line_end(void); + /** * @description: 光标操作函数 * @param {*} @@ -167,6 +174,14 @@ uint16_t xcmd_display_cursor_get(void); * @return {*} */ void xcmd_set_prompt(const char* prompt); +const char* xcmd_get_prompt(void); + +/** + * @description: 注册解释器接收函数的钩子函数 + * @param {func_p} 钩子函数,返回0则接收到的数据会返回给解释器,返回1则不会 + * @return {*} 无 + */ +void xcmd_register_rcv_hook_func(uint8_t(*func_p)(char*)); /** * @description: 获取历史记录的个数 diff --git a/inc/xcmd_confg.h b/inc/xcmd_confg.h index d72a2cb..b817728 100755 --- a/inc/xcmd_confg.h +++ b/inc/xcmd_confg.h @@ -1,7 +1,7 @@ /* * @Author: your name * @Date: 2021-09-17 23:03:06 - * @LastEditTime: 2021-09-22 21:59:50 + * @LastEditTime: 2021-10-08 21:52:29 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: /xcmd/inc/xcmd_confg.h diff --git a/inc/xcmd_define.h b/inc/xcmd_define.h index 0a471aa..4437b0a 100644 --- a/inc/xcmd_define.h +++ b/inc/xcmd_define.h @@ -14,80 +14,87 @@ extern "C" { #endif -typedef enum -{ - CTR_A = 1, - CTR_B = 2, - CTR_C = 3, - CTR_D = 4, - CTR_E = 5, - CTR_F = 6, - CTR_G = 7, - CTR_H = 8, - BACKSPACE = 8, - CTR_I = 9, - LF = 9, - TAB = 9, - CTR_J = 10, - CTR_K = 11, - CTR_L = 12, - CTR_M = 13, - CR = 13, - CTR_N = 14, - CTR_O = 15, - CTR_P = 16, - CTR_Q = 17, - CTR_R = 18, - CTR_S = 19, - CTR_T = 20, - CTR_U = 21, - CTR_V = 22, - CTR_W = 23, - CTR_X = 24, - CTR_Y = 25, - CTR_Z = 26, - ESC = 27, - FS = 28, - GS = 29, - RS = 30, - US = 31, - L_DELETE = 127, - UP = 0x00415B1B, - DW = 0x00425B1B, - RIGHT = 0x00435B1B, - LEFT = 0x00445B1B, - END = 0x00465B1B, - HOME = 0x00485B1B, - INSERT = 0x7E325B1B, - R_DELETE = 0x7E335B1B, - PGUP = 0x7E355B1B, - PGDW = 0x7E365B1B, -}XCMD_KEY_T; +#define KEY_CTR_A "\x01" +#define KEY_CTR_B "\x02" +#define KEY_CTR_C "\x03" +#define KEY_CTR_D "\x04" +#define KEY_CTR_E "\x05" +#define KEY_CTR_F "\x06" +#define KEY_CTR_G "\x07" +#define KEY_CTR_H "\x08" +#define KEY_CTR_I "\x09" +#define KEY_TAB "\x09" +#define KEY_CTR_J "\x0A" +#define KEY_CTR_K "\x0B" +#define KEY_CTR_L "\x0C" +#define KEY_CTR_M "\x0D" +#define KEY_CTR_N "\x0E" +#define KEY_CTR_O "\x0F" +#define KEY_CTR_P "\x10" +#define KEY_CTR_Q "\x11" +#define KEY_CTR_R "\x12" +#define KEY_CTR_S "\x13" +#define KEY_CTR_T "\x14" +#define KEY_CTR_U "\x15" +#define KEY_CTR_V "\x16" +#define KEY_CTR_W "\x17" +#define KEY_CTR_X "\x18" +#define KEY_CTR_Y "\x19" +#define KEY_CTR_Z "\x1A" +#define KEY_PAUSE "\x1A" +#define KEY_ESC "\x1B" +#define KEY_BACKSPACE "\x7F" +#define KEY_UP "\x1B[A" +#define KEY_DW "\x1B[B" +#define KEY_RIGHT "\x1B[C" +#define KEY_LEFT "\x1B[D" +#define KEY_HOME "\x1B[H" +#define KEY_EMD "\x1B[F" +#define KEY_CTR_UP "\x1B[1;5A" +#define KEY_CTR_DW "\x1B[1;5B" +#define KEY_CTR_RIGHT "\x1B[1;5C" +#define KEY_CTR_LEFT "\x1B[1;5D" +#define KEY_INSERT "\x1B[2~" +#define KEY_DELETE "\x1B[3~" +#define KEY_PAGE_UP "\x1B[5~" +#define KEY_PAGE_DOWN "\x1B[6~" +#define KEY_F1 "\x1BOP" +#define KEY_F2 "\x1BOQ" +#define KEY_F3 "\x1BOR" +#define KEY_F4 "\x1BOS" +#define KEY_F5 "\x1B[15~" +#define KEY_F6 "\x1B[17~" +#define KEY_F7 "\x1B[18~" +#define KEY_F8 "\x1B[19~" +#define KEY_F9 "\x1B[20~" +#define KEY_F10 "\x1B[21~" +#define KEY_F11 "\x1B[23~" +#define KEY_F12 "\x1B[24~" /*光标操作符,其中0x1B是ESC,只适用于xcmd_print函数*/ -#define CUU(n) "\x1B[%dA",n /* 光标向上 光标向上 行 */ -#define CUD(n) "\x1B[%dB",n /* 光标向下 光标向下 行 */ -#define CUF(n) "\x1B[%dC",n /* 光标向前 光标向前(右) 行 */ -#define CUB(n) "\x1B[%dD",n /* 光标向后 光标向后(左) 行 */ -#define CNL(n) "\x1B[%dE",n /* 光标下一行 光标从当前位置向下 行 */ -#define CPL(n) "\x1B[%dF",n /* 光标当前行 光标从当前位置向上 行 */ -#define CHA(n) "\x1B[%dG",n /* 绝对光标水平 光标在当前行中水平移动到第 个位置 */ -#define VPA(n) "\x1B[%dd",n /* 绝对垂直行位置 光标在当前列中垂直移动到第 个位置 */ -#define CUP(y,x) "\x1B[%d;%dH",y,x /* 光标位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ -#define HVP(y,x) "\x1B[%d;%df",y,x /* 水平垂直位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ +#define CUU(n) "\x1B[%dA",n /* 光标向上 光标向上 行 */ +#define CUD(n) "\x1B[%dB",n /* 光标向下 光标向下 行 */ +#define CUF(n) "\x1B[%dC",n /* 光标向前 光标向前(右) 行 */ +#define CUB(n) "\x1B[%dD",n /* 光标向后 光标向后(左) 行 */ +#define CNL(n) "\x1B[%dE",n /* 光标下一行 光标从当前位置向下 行 */ +#define CPL(n) "\x1B[%dF",n /* 光标当前行 光标从当前位置向上 行 */ +#define CHA(n) "\x1B[%dG",n /* 绝对光标水平 光标在当前行中水平移动到第 个位置 */ +#define VPA(n) "\x1B[%dd",n /* 绝对垂直行位置 光标在当前列中垂直移动到第 个位置 */ +#define CUP(y,x) "\x1B[%d;%dH",y,x /* 光标位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ +#define HVP(y,x) "\x1B[%d;%df",y,x /* 水平垂直位置 *光标移动到视区中的 ; 坐标,其中 行的列 */ /*光标可见性*/ -#define CU_START_BL "\x1B[?12h" /* ATT160 文本光标启用闪烁 开始光标闪烁 */ -#define CU_STOP_BL "\x1B[?12l" /* ATT160 文本光标禁用闪烁 停止闪烁光标 */ -#define CU_SHOW "\x1B[?25h" /* DECTCEM 文本光标启用模式显示 显示光标 */ -#define CU_HIDE "\x1B[?25l" /* DECTCEM 文本光标启用模式隐藏 隐藏光标 */ +#define CU_START_BL "\x1B[?12h" /* ATT160 文本光标启用闪烁 开始光标闪烁 */ +#define CU_STOP_BL "\x1B[?12l" /* ATT160 文本光标禁用闪烁 停止闪烁光标 */ +#define CU_SHOW "\x1B[?25h" /* DECTCEM 文本光标启用模式显示 显示光标 */ +#define CU_HIDE "\x1B[?25l" /* DECTCEM 文本光标启用模式隐藏 隐藏光标 */ /* 字符操作 */ -#define ICH(n) "\x1B[%d@",n /* 插入字符 在当前光标位置插入 个空格,这会将所有现有文本移到右侧。 向右溢出屏幕的文本会被删除。*/ -#define DCH(n) "\x1B[%dP",n /* 删除字符 删除当前光标位置的 个字符,这会从屏幕右边缘以空格字符移动。*/ -#define ECH(n) "\x1B[%dX",n /* 擦除字符 擦除当前光标位置的 个字符,方法是使用空格字符覆盖它们。*/ -#define IL(n) "\x1B[%dL",n /* 插入行 将 行插入光标位置的缓冲区。 光标所在的行及其下方的行将向下移动。*/ -#define DL(n) "\x1B[%dM",n /* 删除行 从缓冲区中删除 行,从光标所在的行开始。*/ +#define ICH(n) "\x1B[%d@",n /* 插入字符 在当前光标位置插入 个空格,这会将所有现有文本移到右侧。 向右溢出屏幕的文本会被删除。*/ +#define DCH(n) "\x1B[%dP",n /* 删除字符 删除当前光标位置的 个字符,这会从屏幕右边缘以空格字符移动。*/ +#define ECH(n) "\x1B[%dX",n /* 擦除字符 擦除当前光标位置的 个字符,方法是使用空格字符覆盖它们。*/ +#define IL(n) "\x1B[%dL",n /* 插入行 将 行插入光标位置的缓冲区。 光标所在的行及其下方的行将向下移动。*/ +#define DL(n) "\x1B[%dM",n /* 删除行 从缓冲区中删除 行,从光标所在的行开始。*/ #ifdef __cplusplus } diff --git a/src/xcmd.c b/src/xcmd.c index 80f8ae8..eca9d0d 100755 --- a/src/xcmd.c +++ b/src/xcmd.c @@ -7,6 +7,9 @@ #include #define CMD_IS_ENDLINE(c) ((c == '\n') || (c == '\r')) +#define CMD_IS_END_KEY(c) ( ((c >= 'A') && (c <= 'D')) || ((c >= 'P') && (c <= 'S')) || \ + (c == '~') || (c == 'H') || (c == 'F')) + #define CMD_IS_PRINT(c) ((c >= 32) && (c <= 126)) typedef struct __history @@ -59,11 +62,14 @@ struct uint16_t byte_num; /* 当前行的字符个数 */ uint16_t cursor; /* 光标所在位置 */ uint8_t encode_case_stu; + char encode_buf[7]; + uint8_t encode_count; uint32_t key_val; uint16_t param_len; + uint8_t (*recv_hook_func)(char*); /* 解释器接收钩子函数,返回0则接收到的数据会返回给解释器,返回1则不会 */ }parser; uint8_t _initOK; -} g_xcmder; +} g_xcmder = {0}; static char *xcmd_strpbrk(char*s, const char *delim) //返回s1中第一个满足条件的字符的指针, 并且保留""号内的源格式 { @@ -192,12 +198,12 @@ static void xcmd_cmd_match(int argc, char*argv[]) } } -static void xcmd_key_match(XCMD_KEY_T key) +static void xcmd_key_match(char* key) { xcmd_key_t *p = g_xcmder.key_list.head; while(p) { - if(p->key == key) + if(strcmp(key, p->key) == 0) { p->func(&g_xcmder); break; @@ -206,72 +212,56 @@ static void xcmd_key_match(XCMD_KEY_T key) } } -static void xcmd_key_exec(XCMD_KEY_T key) +static void xcmd_key_exec(char* key) { xcmd_key_match(key); } - -static uint32_t xcmd_bytes_encode(uint8_t byte) +static uint8_t xcmd_rcv_encode(uint8_t byte) { - uint32_t ret = byte; - - switch(g_xcmder.parser.encode_case_stu) - { - case 0: - if(byte==0x1B) //1~2 - { - g_xcmder.parser.encode_case_stu = 1; - g_xcmder.parser.key_val = byte; - ret = 0; - } - break; - case 1: - if(byte==0x5B) - { - g_xcmder.parser.encode_case_stu++; - g_xcmder.parser.key_val |= (uint32_t)byte<<8; - ret = 0; - } - else - { - g_xcmder.parser.encode_case_stu = 0; - } - break; - case 2: - if(byte >= 0x41) - { - g_xcmder.parser.encode_case_stu = 0; - g_xcmder.parser.key_val |= (uint32_t)byte<<16; - ret = g_xcmder.parser.key_val; - } - else - { - g_xcmder.parser.encode_case_stu++; - g_xcmder.parser.key_val |= (uint32_t)byte<<16; - ret = 0; - } - break; - case 3: - if(byte == 0x7E) - { - g_xcmder.parser.encode_case_stu = 0; - g_xcmder.parser.key_val |= (uint32_t)byte<<24; - ret = g_xcmder.parser.key_val; - } - else - { - g_xcmder.parser.encode_case_stu = 0; - } - break; - default: - break; - } + uint8_t ret = 0; - return ret; + switch (g_xcmder.parser.encode_case_stu) + { + case 0: + g_xcmder.parser.encode_count = 0; + if (byte == 0x1B) //ESC + { + g_xcmder.parser.encode_case_stu = 1; + g_xcmder.parser.key_val = byte; + } + else + { + g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; + g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count] = '\0'; + ret = 1; + } + break; + case 1: + if (CMD_IS_END_KEY(byte)) + { + g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; + g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count] = '\0'; + ret = g_xcmder.parser.encode_count; + g_xcmder.parser.encode_case_stu = 0; + } + else + { + g_xcmder.parser.encode_buf[g_xcmder.parser.encode_count++] = byte; + if (g_xcmder.parser.encode_count >= 6) + { + g_xcmder.parser.encode_case_stu = 0; + ret = 0; + } + } + break; + default: + break; + } + return ret; } -static char* xcmd_line_end(void) +char* xcmd_display_line_end(void) { char* ret = g_xcmder.parser.display_line; if(g_xcmder.parser.byte_num) @@ -299,30 +289,28 @@ static char* xcmd_line_end(void) static void xcmd_parser(uint8_t byte) { - uint32_t c = 0; + uint32_t num = 0; - c = xcmd_bytes_encode(byte); + num = xcmd_rcv_encode(byte); - if(CMD_IS_PRINT(c)) + if(num > 0) { - xcmd_display_insert_char(c); - } - else if(CMD_IS_ENDLINE(c)) - { - char *cmd = xcmd_line_end(); - xcmd_print("\n\r"); - if(cmd[0]) + if(num == 1) { - xcmd_exec(cmd); - cmd[0] = '\0'; + if( !(g_xcmder.parser.recv_hook_func && g_xcmder.parser.recv_hook_func(g_xcmder.parser.encode_buf)) ) + { + if(CMD_IS_PRINT(g_xcmder.parser.encode_buf[0])) + { + xcmd_display_insert_char(g_xcmder.parser.encode_buf[0]); + return; + } + else + { + xcmd_key_exec(g_xcmder.parser.encode_buf); + } + } } - xcmd_print("%s", g_xcmder.parser.prompt); } - else - { - xcmd_key_exec((XCMD_KEY_T)c); - } - fflush(stdout); } void xcmd_print(const char *fmt, ...) @@ -646,6 +634,16 @@ void xcmd_set_prompt(const char* prompt) } } +const char* xcmd_get_prompt(void) +{ + return g_xcmder.parser.prompt; +} + +void xcmd_register_rcv_hook_func(uint8_t(*func_p)(char*)) +{ + g_xcmder.parser.recv_hook_func = func_p; +} + void xcmd_init( int (*get_c)(uint8_t*), int (*put_c)(uint8_t)) { if(get_c && put_c) diff --git a/src/xcmd_default_keys.c b/src/xcmd_default_keys.c index e4a4f43..684265d 100755 --- a/src/xcmd_default_keys.c +++ b/src/xcmd_default_keys.c @@ -29,6 +29,19 @@ static int xcmd_del_char(void *pv) return 0; } +static int xcmd_enter(void *pv) +{ + char *cmd = xcmd_display_line_end(); + xcmd_print("\n\r"); + if(cmd[0]) + { + xcmd_exec(cmd); + cmd[0] = '\0'; + } + xcmd_print("%s", xcmd_get_prompt()); + return 0; +} + static int xcmd_cursor_left(void *pv) { uint16_t pos = xcmd_display_cursor_get(); @@ -125,14 +138,15 @@ static int xcmd_auto_completion(void *pv) static xcmd_key_t default_keys[] = { - {BACKSPACE, xcmd_del_char, "backspace", NULL}, - {L_DELETE, xcmd_del_char, "left delete", NULL}, - {LEFT, xcmd_cursor_left, "left", NULL}, - {RIGHT, xcmd_cursor_right, "right", NULL}, - {TAB, xcmd_auto_completion, "tab", NULL}, + {KEY_CTR_M, xcmd_enter, "enter", NULL}, + {KEY_CTR_H, xcmd_del_char, "backspace", NULL}, + {KEY_BACKSPACE, xcmd_del_char, "delete", NULL}, + {KEY_LEFT, xcmd_cursor_left, "left", NULL}, + {KEY_RIGHT, xcmd_cursor_right, "right", NULL}, + {KEY_TAB, xcmd_auto_completion, "tab", NULL}, #if XCMD_HISTORY_MAX_NUM - {DW, xcmd_history_dw, "down", NULL}, - {UP, xcmd_history_up, "up", NULL}, + {KEY_DW, xcmd_history_dw, "down", NULL}, + {KEY_UP, xcmd_history_up, "up", NULL}, #endif };