mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-02-05 17:28:23 +08:00
support REPL_HISTORY
This commit is contained in:
parent
9a49ad985e
commit
31bcc66a75
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -20,7 +20,7 @@
|
|||||||
// "--gtest_filter=eventloop.test1"
|
// "--gtest_filter=eventloop.test1"
|
||||||
// "--gtest_filter=parser.tuple_single"
|
// "--gtest_filter=parser.tuple_single"
|
||||||
// "--gtest_filter=parser.*"
|
// "--gtest_filter=parser.*"
|
||||||
"--gtest_filter=pikaMain.REPL_key_up"
|
"--gtest_filter=pikaMain.REPL_key_down_over"
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (1 == argc) {
|
if (1 == argc) {
|
||||||
pikaScriptShell(pikaScriptInit());
|
PikaObj* pikaMain = pikaScriptInit();
|
||||||
|
pikaScriptShell(pikaMain);
|
||||||
|
obj_deinit(pikaMain);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (2 == argc) {
|
if (2 == argc) {
|
||||||
|
229
src/PikaObj.c
229
src/PikaObj.c
@ -37,6 +37,11 @@
|
|||||||
#include "dataQueue.h"
|
#include "dataQueue.h"
|
||||||
#include "dataString.h"
|
#include "dataString.h"
|
||||||
#include "dataStrs.h"
|
#include "dataStrs.h"
|
||||||
|
#if __linux
|
||||||
|
#include "signal.h"
|
||||||
|
#include "termios.h"
|
||||||
|
#include "unistd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern volatile VMSignal g_PikaVMSignal;
|
extern volatile VMSignal g_PikaVMSignal;
|
||||||
volatile PikaObjState g_PikaObjState = {
|
volatile PikaObjState g_PikaObjState = {
|
||||||
@ -66,6 +71,7 @@ void pikaGC_markObj(PikaGC* gc, PikaObj* self);
|
|||||||
void _pikaGC_mark(PikaGC* gc);
|
void _pikaGC_mark(PikaGC* gc);
|
||||||
void obj_dump(PikaObj* self);
|
void obj_dump(PikaObj* self);
|
||||||
void Locals_deinit(PikaObj* self);
|
void Locals_deinit(PikaObj* self);
|
||||||
|
static void disable_raw_mode(void);
|
||||||
|
|
||||||
static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self,
|
static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self,
|
||||||
char* input_line,
|
char* input_line,
|
||||||
@ -200,6 +206,9 @@ int32_t obj_deinit(PikaObj* self) {
|
|||||||
if (bisRoot) {
|
if (bisRoot) {
|
||||||
pikaGC_markSweep();
|
pikaGC_markSweep();
|
||||||
shConfig_deinit((ShellConfig*)&g_repl_shell);
|
shConfig_deinit((ShellConfig*)&g_repl_shell);
|
||||||
|
#if __linux
|
||||||
|
disable_raw_mode();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -639,6 +648,41 @@ static int set_disp_mode(int fd, int option) {
|
|||||||
|
|
||||||
static volatile uint8_t logo_printed = 0;
|
static volatile uint8_t logo_printed = 0;
|
||||||
|
|
||||||
|
#if __linux
|
||||||
|
struct termios original_termios;
|
||||||
|
|
||||||
|
static void enable_raw_mode(void) {
|
||||||
|
struct termios raw;
|
||||||
|
|
||||||
|
tcgetattr(STDIN_FILENO, &original_termios); // 获取当前终端属性
|
||||||
|
raw = original_termios;
|
||||||
|
raw.c_lflag &= ~(ECHO | ICANON); // 禁用回显和规范模式
|
||||||
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); // 设置终端属性
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disable_raw_mode(void) {
|
||||||
|
tcsetattr(STDIN_FILENO, TCSAFLUSH, &original_termios); // 恢复原始终端属性
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void signal_handler(int sig) {
|
||||||
|
if (sig == SIGSEGV) {
|
||||||
|
printf("Segmentation fault");
|
||||||
|
} else if (sig == SIGINT) {
|
||||||
|
printf("Ctrl+C");
|
||||||
|
} else if (sig == SIGTERM) {
|
||||||
|
printf("SIGTERM");
|
||||||
|
} else if (sig == SIGHUP) {
|
||||||
|
printf("SIGHUP");
|
||||||
|
} else if (sig == SIGABRT) {
|
||||||
|
printf("Aborted");
|
||||||
|
}
|
||||||
|
disable_raw_mode();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern volatile PikaObj* __pikaMain;
|
extern volatile PikaObj* __pikaMain;
|
||||||
PikaObj* newRootObj(char* name, NewFun newObjFun) {
|
PikaObj* newRootObj(char* name, NewFun newObjFun) {
|
||||||
g_PikaObjState.inRootObj = PIKA_TRUE;
|
g_PikaObjState.inRootObj = PIKA_TRUE;
|
||||||
@ -646,7 +690,12 @@ PikaObj* newRootObj(char* name, NewFun newObjFun) {
|
|||||||
mem_pool_init();
|
mem_pool_init();
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
// set_disp_mode(STDIN_FILENO, 0);
|
signal(SIGINT, signal_handler); // 捕获 SIGINT 信号(Ctrl+C)
|
||||||
|
signal(SIGTERM, signal_handler); // 捕获 SIGTERM 信号
|
||||||
|
signal(SIGHUP, signal_handler); // 捕获 SIGHUP 信号
|
||||||
|
signal(SIGSEGV, signal_handler); // 捕获 SIGHUP 信号
|
||||||
|
signal(SIGABRT, signal_handler);
|
||||||
|
enable_raw_mode();
|
||||||
#endif
|
#endif
|
||||||
PikaObj* newObj = newNormalObj(newObjFun);
|
PikaObj* newObj = newNormalObj(newObjFun);
|
||||||
if (!logo_printed) {
|
if (!logo_printed) {
|
||||||
@ -1289,87 +1338,76 @@ int16_t _do_stream_filter(PikaObj* self, ShellConfig* shell) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PIKA_SHELL_HISTORY_ENABLE
|
#if PIKA_SHELL_HISTORY_ENABLE
|
||||||
void shHistory_add(ShellHistory* self, char* command) {
|
|
||||||
pika_assert(NULL != self);
|
|
||||||
pika_assert(NULL != command);
|
|
||||||
if (self->current_size == self->max_size) {
|
|
||||||
pikaFree(self->history_list[self->head],
|
|
||||||
strGetSize(self->history_list[self->head]) + 1);
|
|
||||||
self->head = (self->head + 1) % self->max_size;
|
|
||||||
} else {
|
|
||||||
self->current_size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用pikaMalloc分配内存并复制字符串
|
|
||||||
size_t command_length = strGetSize(command);
|
|
||||||
self->history_list[self->tail] = (char*)pikaMalloc(command_length + 1);
|
|
||||||
pika_platform_memcpy(self->history_list[self->tail], command,
|
|
||||||
command_length);
|
|
||||||
self->history_list[self->tail][command_length] = '\0';
|
|
||||||
|
|
||||||
self->tail = (self->tail + 1) % self->max_size;
|
|
||||||
self->current_index = (self->tail - 1 + self->max_size) % self->max_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShellHistory* shHistory_create(int max_size) {
|
ShellHistory* shHistory_create(int max_size) {
|
||||||
ShellHistory* self = (ShellHistory*)pikaMalloc(sizeof(ShellHistory));
|
ShellHistory* self = (ShellHistory*)pikaMalloc(sizeof(ShellHistory));
|
||||||
self->max_size = max_size;
|
self->max_size = max_size;
|
||||||
self->current_size = 0;
|
self->current = -1;
|
||||||
self->head = 0;
|
self->count = 0;
|
||||||
self->tail = 0;
|
self->last_offset = 0;
|
||||||
self->current_index = -1;
|
self->history = (char**)pikaMalloc(max_size * sizeof(char*));
|
||||||
self->history_list = (char**)pikaMalloc(max_size * sizeof(char*));
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shHistory_destroy(ShellHistory* self) {
|
void shHistory_destroy(ShellHistory* self) {
|
||||||
for (int i = 0; i < self->current_size; i++) {
|
for (int i = 0; i < self->count; i++) {
|
||||||
pikaFree(self->history_list[i], strGetSize(self->history_list[i]) + 1);
|
pikaFree(self->history[i], strGetSize(self->history[i]) + 1);
|
||||||
}
|
}
|
||||||
pikaFree(self->history_list, self->max_size * sizeof(char*));
|
pikaFree(self->history, sizeof(char*) * self->max_size);
|
||||||
pikaFree(self, sizeof(ShellHistory));
|
pikaFree(self, sizeof(ShellHistory));
|
||||||
}
|
}
|
||||||
|
|
||||||
char* shHistory_get(ShellHistory* self, int index) {
|
void shHistory_add(ShellHistory* self, char* command) {
|
||||||
if (index < 0 || index >= self->current_size) {
|
if (self->count == self->max_size) {
|
||||||
return NULL;
|
pikaFree(self->history[0], strGetSize(self->history[0]) + 1);
|
||||||
|
pika_platform_memmove(self->history, self->history + 1,
|
||||||
|
(self->max_size - 1) * sizeof(char*));
|
||||||
|
self->count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
int actual_index = (self->head + index) % self->max_size;
|
/* filter for empty command */
|
||||||
return self->history_list[actual_index];
|
if (self->count > 0 && self->history[self->count - 1][0] == '\0') {
|
||||||
|
pikaFree(self->history[self->count - 1],
|
||||||
|
strGetSize(self->history[self->count - 1]) + 1);
|
||||||
|
self->count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* filter for same command */
|
||||||
|
if (self->count > 0 && strEqu(self->history[self->count - 1], command)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->history[self->count] = pikaMalloc(strGetSize(command) + 1);
|
||||||
|
pika_platform_memcpy(self->history[self->count], command,
|
||||||
|
strGetSize(command) + 1);
|
||||||
|
self->count++;
|
||||||
|
self->current = self->count - 1;
|
||||||
|
self->last_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* shHistory_get(ShellHistory* self, int offset) {
|
||||||
|
int actual_offset = offset + self->last_offset;
|
||||||
|
int index = self->current + actual_offset;
|
||||||
|
if (index < 0 || index >= self->count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->last_offset = actual_offset;
|
||||||
|
return self->history[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
char* shHistory_getPrev(ShellHistory* self) {
|
char* shHistory_getPrev(ShellHistory* self) {
|
||||||
if (self->current_size == 0) {
|
return shHistory_get(self, -1);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->current_index =
|
|
||||||
(self->current_index - 1 + self->max_size) % self->max_size;
|
|
||||||
|
|
||||||
if (self->current_index == self->tail) {
|
|
||||||
self->current_index =
|
|
||||||
(self->current_index - 1 + self->max_size) % self->max_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self->history_list[self->current_index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* shHistory_getNext(ShellHistory* self) {
|
char* shHistory_getNext(ShellHistory* self) {
|
||||||
if (self->current_size == 0) {
|
return shHistory_get(self, 1);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int next_index = (self->current_index + 1) % self->max_size;
|
#endif
|
||||||
|
|
||||||
if (next_index == self->tail) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->current_index = next_index;
|
|
||||||
return self->history_list[self->current_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if __linux
|
||||||
|
#define PIKA_BACKSPACE() printf("\b \b")
|
||||||
|
#else
|
||||||
|
#define PIKA_BACKSPACE() pika_platform_printf(" \b")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
||||||
@ -1377,23 +1415,25 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
ShellConfig* shell) {
|
ShellConfig* shell) {
|
||||||
char* input_line = NULL;
|
char* input_line = NULL;
|
||||||
enum shellCTRL ctrl = SHELL_CTRL_CONTINUE;
|
enum shellCTRL ctrl = SHELL_CTRL_CONTINUE;
|
||||||
#if !(defined(__linux) || defined(_WIN32))
|
#if __linux
|
||||||
|
printf("%c", inputChar);
|
||||||
|
#elif !(defined(_WIN32))
|
||||||
pika_platform_printf("%c", inputChar);
|
pika_platform_printf("%c", inputChar);
|
||||||
#endif
|
#endif
|
||||||
if (inputChar == '\n' && shell->lastChar == '\r') {
|
if (inputChar == '\n' && shell->lastChar == '\r') {
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if (inputChar == 0x1b) {
|
if (inputChar == 0x1b) {
|
||||||
shell->stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY;
|
shell->stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY;
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if (shell->stat == PIKA_SHELL_STATE_WAIT_SPEC_KEY) {
|
if (shell->stat == PIKA_SHELL_STATE_WAIT_SPEC_KEY) {
|
||||||
if (inputChar == 0x5b) {
|
if (inputChar == 0x5b) {
|
||||||
shell->stat = PIKA_SHELL_STATE_WAIT_FUNC_KEY;
|
shell->stat = PIKA_SHELL_STATE_WAIT_FUNC_KEY;
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
shell->stat = PIKA_SHELL_STATE_NORMAL;
|
shell->stat = PIKA_SHELL_STATE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -1405,7 +1445,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
pika_platform_printf(" ");
|
pika_platform_printf(" ");
|
||||||
}
|
}
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if (inputChar == PIKA_KEY_RIGHT) {
|
if (inputChar == PIKA_KEY_RIGHT) {
|
||||||
if (shell->line_curpos < shell->line_position) {
|
if (shell->line_curpos < shell->line_position) {
|
||||||
@ -1416,7 +1456,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
pika_platform_printf("\b");
|
pika_platform_printf("\b");
|
||||||
}
|
}
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if (inputChar == PIKA_KEY_UP) {
|
if (inputChar == PIKA_KEY_UP) {
|
||||||
_putc_cmd(PIKA_KEY_DOWN, 1);
|
_putc_cmd(PIKA_KEY_DOWN, 1);
|
||||||
@ -1425,14 +1465,18 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
if (NULL == shell->history) {
|
if (NULL == shell->history) {
|
||||||
shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM);
|
shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM);
|
||||||
}
|
}
|
||||||
if (NULL == shHistory_getNext(shell->history)) {
|
if (0 == shell->history->cached_current) {
|
||||||
/* save the current line */
|
/* save the current line */
|
||||||
shHistory_add(shell->history, shell->lineBuff);
|
shHistory_add(shell->history, shell->lineBuff);
|
||||||
|
shell->history->cached_current = 1;
|
||||||
}
|
}
|
||||||
char* prev = shHistory_getPrev(shell->history);
|
char* prev = shHistory_getPrev(shell->history);
|
||||||
|
if (NULL == prev) {
|
||||||
|
goto __exit;
|
||||||
|
}
|
||||||
/* clear the current line */
|
/* clear the current line */
|
||||||
for (int i = 0; i < shell->line_position; i++) {
|
for (int i = 0; i < shell->line_position; i++) {
|
||||||
pika_platform_printf("\b \b");
|
PIKA_BACKSPACE();
|
||||||
}
|
}
|
||||||
pika_platform_memcpy(shell->lineBuff, prev, strGetSize(prev) + 1);
|
pika_platform_memcpy(shell->lineBuff, prev, strGetSize(prev) + 1);
|
||||||
/* show the previous line */
|
/* show the previous line */
|
||||||
@ -1440,20 +1484,39 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
shell->line_position = strGetSize(prev);
|
shell->line_position = strGetSize(prev);
|
||||||
shell->line_curpos = shell->line_position;
|
shell->line_curpos = shell->line_position;
|
||||||
#endif
|
#endif
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if (inputChar == PIKA_KEY_DOWN) {
|
if (inputChar == PIKA_KEY_DOWN) {
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
#if PIKA_SHELL_HISTORY_ENABLE
|
||||||
|
char* next = shHistory_getNext(shell->history);
|
||||||
|
if (NULL == next) {
|
||||||
|
goto __exit;
|
||||||
|
}
|
||||||
|
/* clear the current line */
|
||||||
|
for (int i = 0; i < shell->line_position; i++) {
|
||||||
|
PIKA_BACKSPACE();
|
||||||
|
}
|
||||||
|
pika_platform_memcpy(shell->lineBuff, next, strGetSize(next) + 1);
|
||||||
|
/* show the previous line */
|
||||||
|
pika_platform_printf("%s", shell->lineBuff);
|
||||||
|
shell->line_position = strGetSize(next);
|
||||||
|
shell->line_curpos = shell->line_position;
|
||||||
|
#endif
|
||||||
|
goto __exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((inputChar == '\b') || (inputChar == 127)) {
|
if ((inputChar == '\b') || (inputChar == 127)) {
|
||||||
if (shell->line_position == 0) {
|
if (shell->line_curpos == 0) {
|
||||||
|
#if __linux
|
||||||
|
printf("\b ");
|
||||||
|
#else
|
||||||
pika_platform_printf(" ");
|
pika_platform_printf(" ");
|
||||||
|
#endif
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
pika_platform_printf(" \b");
|
PIKA_BACKSPACE();
|
||||||
shell->line_position--;
|
shell->line_position--;
|
||||||
shell->line_curpos--;
|
shell->line_curpos--;
|
||||||
pika_platform_memmove(shell->lineBuff + shell->line_curpos,
|
pika_platform_memmove(shell->lineBuff + shell->line_curpos,
|
||||||
@ -1468,7 +1531,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
shell->line_position - shell->line_curpos + 1);
|
shell->line_position - shell->line_curpos + 1);
|
||||||
}
|
}
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if ((inputChar != '\r') && (inputChar != '\n')) {
|
if ((inputChar != '\r') && (inputChar != '\n')) {
|
||||||
if (shell->line_position + 1 >= PIKA_LINE_BUFF_SIZE) {
|
if (shell->line_position + 1 >= PIKA_LINE_BUFF_SIZE) {
|
||||||
@ -1477,7 +1540,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
"'PIKA_LINE_BUFF_SIZE'\r\n");
|
"'PIKA_LINE_BUFF_SIZE'\r\n");
|
||||||
ctrl = SHELL_CTRL_EXIT;
|
ctrl = SHELL_CTRL_EXIT;
|
||||||
__clearBuff(shell);
|
__clearBuff(shell);
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if ('\0' != inputChar) {
|
if ('\0' != inputChar) {
|
||||||
pika_platform_memmove(shell->lineBuff + shell->line_curpos + 1,
|
pika_platform_memmove(shell->lineBuff + shell->line_curpos + 1,
|
||||||
@ -1494,7 +1557,7 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
shell->line_curpos++;
|
shell->line_curpos++;
|
||||||
}
|
}
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
if ((inputChar == '\r') || (inputChar == '\n')) {
|
if ((inputChar == '\r') || (inputChar == '\n')) {
|
||||||
#if !(defined(__linux) || defined(_WIN32) || PIKA_SHELL_NO_NEWLINE)
|
#if !(defined(__linux) || defined(_WIN32) || PIKA_SHELL_NO_NEWLINE)
|
||||||
@ -1504,7 +1567,11 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
if (NULL == shell->history) {
|
if (NULL == shell->history) {
|
||||||
shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM);
|
shell->history = shHistory_create(PIKA_SHELL_HISTORY_NUM);
|
||||||
}
|
}
|
||||||
|
if (shell->lineBuff[0] != '\0') {
|
||||||
shHistory_add(shell->history, shell->lineBuff);
|
shHistory_add(shell->history, shell->lineBuff);
|
||||||
|
}
|
||||||
|
shell->history->last_offset = 0;
|
||||||
|
shell->history->cached_current = 0;
|
||||||
#endif
|
#endif
|
||||||
/* still in block */
|
/* still in block */
|
||||||
if (shell->blockBuffName != NULL && shell->inBlock) {
|
if (shell->blockBuffName != NULL && shell->inBlock) {
|
||||||
@ -1524,13 +1591,13 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
ctrl = shell->handler(self, input_line, shell);
|
ctrl = shell->handler(self, input_line, shell);
|
||||||
__clearBuff(shell);
|
__clearBuff(shell);
|
||||||
pika_platform_printf(">>> ");
|
pika_platform_printf(">>> ");
|
||||||
goto exit;
|
goto __exit;
|
||||||
} else {
|
} else {
|
||||||
pika_platform_printf("... ");
|
pika_platform_printf("... ");
|
||||||
}
|
}
|
||||||
__clearBuff(shell);
|
__clearBuff(shell);
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
/* go in block */
|
/* go in block */
|
||||||
if (shell->blockBuffName != NULL && 0 != strGetSize(shell->lineBuff)) {
|
if (shell->blockBuffName != NULL && 0 != strGetSize(shell->lineBuff)) {
|
||||||
@ -1542,16 +1609,16 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
|
|||||||
__clearBuff(shell);
|
__clearBuff(shell);
|
||||||
pika_platform_printf("... ");
|
pika_platform_printf("... ");
|
||||||
ctrl = SHELL_CTRL_CONTINUE;
|
ctrl = SHELL_CTRL_CONTINUE;
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shell->lineBuff[shell->line_position] = '\0';
|
shell->lineBuff[shell->line_position] = '\0';
|
||||||
ctrl = shell->handler(self, shell->lineBuff, shell);
|
ctrl = shell->handler(self, shell->lineBuff, shell);
|
||||||
pika_platform_printf("%s", shell->prefix);
|
pika_platform_printf("%s", shell->prefix);
|
||||||
__clearBuff(shell);
|
__clearBuff(shell);
|
||||||
goto exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
exit:
|
__exit:
|
||||||
shell->lastChar = inputChar;
|
shell->lastChar = inputChar;
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
@ -365,11 +365,11 @@ struct FilterItem {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int max_size;
|
int max_size;
|
||||||
int current_size;
|
int current;
|
||||||
int head;
|
int count;
|
||||||
int tail;
|
int last_offset;
|
||||||
int current_index;
|
char** history;
|
||||||
char** history_list;
|
int cached_current;
|
||||||
} ShellHistory;
|
} ShellHistory;
|
||||||
|
|
||||||
struct ShellConfig {
|
struct ShellConfig {
|
||||||
|
@ -2827,6 +2827,7 @@ TEST(pikaMain, REPL_key_left_del) {
|
|||||||
EXPECT_EQ(pikaMemNow(), 0);
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PIKA_SHELL_HISTORY_ENABLE
|
||||||
TEST(pikaMain, REPL_key_up) {
|
TEST(pikaMain, REPL_key_up) {
|
||||||
char lines[] = {'1', '2', '+', '3', '4', '5', '\n',
|
char lines[] = {'1', '2', '+', '3', '4', '5', '\n',
|
||||||
0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00};
|
0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00};
|
||||||
@ -2846,6 +2847,89 @@ TEST(pikaMain, REPL_key_up) {
|
|||||||
EXPECT_EQ(pikaMemNow(), 0);
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(pikaMain, REPL_key_up_void) {
|
||||||
|
char lines[] = {0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00};
|
||||||
|
/* init */
|
||||||
|
g_PikaMemInfo.heapUsedMax = 0;
|
||||||
|
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||||
|
/* run */
|
||||||
|
__platform_printf("BEGIN\r\n");
|
||||||
|
for (size_t i = 0; i < strGetSize(lines); i++) {
|
||||||
|
obj_runChar(pikaMain, lines[i]);
|
||||||
|
}
|
||||||
|
/* collect */
|
||||||
|
/* assert */
|
||||||
|
EXPECT_STREQ(log_buff[1], "2\r\n");
|
||||||
|
/* deinit */
|
||||||
|
obj_deinit(pikaMain);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(pikaMain, REPL_key_up_2) {
|
||||||
|
char lines[] = {'1', '2', '+', '3', '4', '5', '\n',
|
||||||
|
'1', '3', '*', '2', '\n', 0x1b, 0x5b,
|
||||||
|
PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP, '2', '\n', 0x00};
|
||||||
|
/* init */
|
||||||
|
g_PikaMemInfo.heapUsedMax = 0;
|
||||||
|
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||||
|
/* run */
|
||||||
|
__platform_printf("BEGIN\r\n");
|
||||||
|
for (size_t i = 0; i < strGetSize(lines); i++) {
|
||||||
|
obj_runChar(pikaMain, lines[i]);
|
||||||
|
}
|
||||||
|
/* collect */
|
||||||
|
/* assert */
|
||||||
|
EXPECT_STREQ(log_buff[1], "3464\r\n");
|
||||||
|
/* deinit */
|
||||||
|
obj_deinit(pikaMain);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(pikaMain, REPL_key_down) {
|
||||||
|
char lines[] = {'1', '2', '+', '3', '4', '5',
|
||||||
|
'\n', '1', '3', '*', '2', '\n',
|
||||||
|
0x1b, 0x5b, PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP,
|
||||||
|
0x1b, 0x5b, PIKA_KEY_DOWN, '2', '\n', 0x00};
|
||||||
|
/* init */
|
||||||
|
g_PikaMemInfo.heapUsedMax = 0;
|
||||||
|
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||||
|
/* run */
|
||||||
|
__platform_printf("BEGIN\r\n");
|
||||||
|
for (size_t i = 0; i < strGetSize(lines); i++) {
|
||||||
|
obj_runChar(pikaMain, lines[i]);
|
||||||
|
}
|
||||||
|
/* collect */
|
||||||
|
/* assert */
|
||||||
|
EXPECT_STREQ(log_buff[1], "286\r\n");
|
||||||
|
/* deinit */
|
||||||
|
obj_deinit(pikaMain);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(pikaMain, REPL_key_down_over) {
|
||||||
|
char lines[] = {'1', '2', '+', '3', '4', '5',
|
||||||
|
'\n', '1', '3', '*', '2', '\n',
|
||||||
|
0x1b, 0x5b, PIKA_KEY_UP, 0x1b, 0x5b, PIKA_KEY_UP,
|
||||||
|
0x1b, 0x5b, PIKA_KEY_DOWN, 0x1b, 0x5b, PIKA_KEY_DOWN,
|
||||||
|
0x1b, 0x5b, PIKA_KEY_DOWN, '2', '\n', 0x00};
|
||||||
|
/* init */
|
||||||
|
g_PikaMemInfo.heapUsedMax = 0;
|
||||||
|
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||||
|
/* run */
|
||||||
|
__platform_printf("BEGIN\r\n");
|
||||||
|
for (size_t i = 0; i < strGetSize(lines); i++) {
|
||||||
|
obj_runChar(pikaMain, lines[i]);
|
||||||
|
}
|
||||||
|
/* collect */
|
||||||
|
/* assert */
|
||||||
|
EXPECT_STREQ(log_buff[1], "2\r\n");
|
||||||
|
/* deinit */
|
||||||
|
obj_deinit(pikaMain);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PIKA_SHELL_FILTER_ENABLE
|
#if PIKA_SHELL_FILTER_ENABLE
|
||||||
|
|
||||||
TEST(pikaMain, SHELL_filter_hi_pika) {
|
TEST(pikaMain, SHELL_filter_hi_pika) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user