support unittest for REPL, check overflow for REPL

This commit is contained in:
lyon 2022-10-25 11:52:42 +08:00
parent 08c6797c0c
commit d0df040067
10 changed files with 128 additions and 39 deletions

View File

@ -51,6 +51,7 @@ void PikaDebug_Debuger_set_trace(PikaObj* self) {
struct ShellConfig cfg = {
.prefix = "(pika-debug) ",
.handler = __obj_shellLineHandler_debug,
.getchar = __platform_getchar,
};
obj_shellLineProcess(self, &cfg);
_do_pikaScriptShell(self, &cfg);
}

View File

@ -635,11 +635,12 @@ char* PikaStdLib_SysObj_input(PikaObj* self, PikaTuple* info) {
.prefix = "",
.context = NULL,
.handler = __obj_shellLineHandler_input,
.getchar = __platform_getchar,
};
if (tuple_getSize(info) > 0) {
__platform_printf("%s", tuple_getStr(info, 0));
}
_temp_obj_shellLineProcess(self, &cfg);
_temp__do_pikaScriptShell(self, &cfg);
char* res = obj_cacheStr(self, arg_getStr(cfg.context));
arg_deinit(cfg.context);
return res;

View File

@ -51,6 +51,7 @@ void PikaDebug_Debuger_set_trace(PikaObj* self) {
struct ShellConfig cfg = {
.prefix = "(pika-debug) ",
.handler = __obj_shellLineHandler_debug,
.getchar = __platform_getchar,
};
obj_shellLineProcess(self, &cfg);
_do_pikaScriptShell(self, &cfg);
}

View File

@ -635,11 +635,12 @@ char* PikaStdLib_SysObj_input(PikaObj* self, PikaTuple* info) {
.prefix = "",
.context = NULL,
.handler = __obj_shellLineHandler_input,
.getchar = __platform_getchar,
};
if (tuple_getSize(info) > 0) {
__platform_printf("%s", tuple_getStr(info, 0));
}
_temp_obj_shellLineProcess(self, &cfg);
_temp__do_pikaScriptShell(self, &cfg);
char* res = obj_cacheStr(self, arg_getStr(cfg.context));
arg_deinit(cfg.context);
return res;

View File

@ -850,16 +850,15 @@ PIKA_RES obj_runNativeMethod(PikaObj* self, char* method_name, Args* args) {
return PIKA_RES_OK;
}
static void __clearBuff(char* buff, int size) {
for (int i = 0; i < size; i++) {
buff[i] = 0;
}
static void __clearBuff(ShellConfig* cfg) {
memset(cfg->lineBuff, 0, PIKA_LINE_BUFF_SIZE);
cfg->lineBuff_i = 0;
}
static void _obj_runChar_beforeRun(PikaObj* self, ShellConfig* cfg) {
/* create the line buff for the first time */
memset(cfg->lineBuff, 0, PIKA_LINE_BUFF_SIZE);
cfg->inBlock = PIKA_FALSE;
__clearBuff(cfg);
__platform_printf("%s", cfg->prefix);
}
@ -889,7 +888,15 @@ enum shell_state _do_obj_runChar(PikaObj* self,
goto exit;
}
if ((inputChar != '\r') && (inputChar != '\n')) {
strAppendWithSize(rxBuff, &inputChar, 1);
if (cfg->lineBuff_i >= PIKA_LINE_BUFF_SIZE) {
__platform_printf(
"\r\nError: line buff overflow, please use bigger "
"'PIKA_LINE_BUFF_SIZE'\r\n");
state = SHELL_STATE_EXIT;
__clearBuff(cfg);
goto exit;
}
rxBuff[cfg->lineBuff_i++] = inputChar;
state = SHELL_STATE_CONTINUE;
goto exit;
}
@ -912,13 +919,13 @@ enum shell_state _do_obj_runChar(PikaObj* self,
cfg->inBlock = PIKA_FALSE;
input_line = obj_getStr(self, cfg->blockBuffName);
state = cfg->handler(self, input_line, cfg);
__clearBuff(rxBuff, PIKA_LINE_BUFF_SIZE);
__clearBuff(cfg);
__platform_printf(">>> ");
goto exit;
} else {
__platform_printf("... ");
}
__clearBuff(rxBuff, PIKA_LINE_BUFF_SIZE);
__clearBuff(cfg);
state = SHELL_STATE_CONTINUE;
goto exit;
}
@ -929,7 +936,7 @@ enum shell_state _do_obj_runChar(PikaObj* self,
char _n = '\n';
strAppendWithSize(rxBuff, &_n, 1);
obj_setStr(self, cfg->blockBuffName, rxBuff);
__clearBuff(rxBuff, PIKA_LINE_BUFF_SIZE);
__clearBuff(cfg);
__platform_printf("... ");
state = SHELL_STATE_CONTINUE;
goto exit;
@ -938,7 +945,7 @@ enum shell_state _do_obj_runChar(PikaObj* self,
input_line = rxBuff;
state = cfg->handler(self, input_line, cfg);
__platform_printf("%s", cfg->prefix);
__clearBuff(rxBuff, PIKA_LINE_BUFF_SIZE);
__clearBuff(cfg);
goto exit;
}
exit:
@ -962,7 +969,7 @@ enum shell_state obj_runChar(PikaObj* self, char inputChar) {
return _do_obj_runChar(self, inputChar, cfg);
}
void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) {
/* init the shell */
_obj_runChar_beforeRun(self, cfg);
@ -971,7 +978,7 @@ void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
int bytecode_index = 1;
while (1) {
inputChar[1] = inputChar[0];
inputChar[0] = __platform_getchar();
inputChar[0] = cfg->getchar();
/* run python script */
if (inputChar[0] == '!' && inputChar[1] == '#') {
@ -984,12 +991,12 @@ void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
PIKA_BOOL is_first_line = PIKA_TRUE;
while (1) {
input[1] = input[0];
input[0] = __platform_getchar();
input[0] = cfg->getchar();
if (input[0] == '!' && input[1] == '#') {
buff[buff_i - 1] = 0;
for (int i = 0; i < 4; i++) {
/* eat 'pika' */
__platform_getchar();
cfg->getchar();
}
break;
}
@ -1057,16 +1064,16 @@ void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
if (inputChar[0] == 'p' && inputChar[1] == 0x7f) {
for (int i = 0; i < 2; i++) {
/* eat 'yo' */
__platform_getchar();
cfg->getchar();
}
uint32_t size = 0;
for (int i = 0; i < 4; i++) {
uint8_t* size_byte = (uint8_t*)&size;
size_byte[i] = __platform_getchar();
size_byte[i] = cfg->getchar();
}
uint8_t* buff = pikaMalloc(size);
for (uint32_t i = 0; i < size; i++) {
buff[i] = __platform_getchar();
buff[i] = cfg->getchar();
}
__platform_printf("\r\n=============== [Code] ===============\r\n");
__platform_printf("[ Info] Bytecode size: %d\r\n", size);
@ -1086,13 +1093,13 @@ void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
}
}
void _temp_obj_shellLineProcess(PikaObj* self, ShellConfig* cfg) {
void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) {
/* init the shell */
_obj_runChar_beforeRun(self, cfg);
/* getchar and run */
while (1) {
char inputChar = __platform_getchar();
char inputChar = cfg->getchar();
if (SHELL_STATE_EXIT == _do_obj_runChar(self, inputChar, cfg)) {
break;
}
@ -1112,13 +1119,19 @@ static enum shell_state __obj_shellLineHandler_REPL(PikaObj* self,
return SHELL_STATE_CONTINUE;
}
void pikaScriptShell(PikaObj* self) {
ShellConfig cfg = {
static volatile ShellConfig g_repl_cfg = {
.handler = __obj_shellLineHandler_REPL,
.prefix = ">>> ",
.blockBuffName = "@sh0",
};
obj_shellLineProcess(self, &cfg);
};
void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn) {
g_repl_cfg.getchar = getchar_fn;
_do_pikaScriptShell(self, (ShellConfig*)&g_repl_cfg);
}
void pikaScriptShell(PikaObj* self) {
pikaScriptShell_withGetchar(self, __platform_getchar);
}
void obj_setErrorCode(PikaObj* self, int32_t errCode) {

View File

@ -249,20 +249,23 @@ enum shell_state { SHELL_STATE_CONTINUE, SHELL_STATE_EXIT };
typedef struct ShellConfig ShellConfig;
typedef enum shell_state (*sh_handler)(PikaObj*, char*, ShellConfig*);
typedef char (*sh_getchar)(void);
struct ShellConfig {
char* prefix;
sh_handler handler;
void* context;
char lineBuff[PIKA_LINE_BUFF_SIZE];
size_t lineBuff_i;
char* blockBuffName;
PIKA_BOOL inBlock;
char lastChar;
sh_getchar getchar;
};
void obj_shellLineProcess(PikaObj* self, ShellConfig* cfg);
void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);
void _temp_obj_shellLineProcess(PikaObj* self, ShellConfig* cfg);
void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);
/*
need implament :

View File

@ -2,4 +2,4 @@
#define PIKA_VERSION_MINOR 11
#define PIKA_VERSION_MICRO 5
#define PIKA_EDIT_TIME "2022/10/24 12:20:33"
#define PIKA_EDIT_TIME "2022/10/25 11:52:41"

View File

@ -378,8 +378,7 @@ TEST(module, mod1_mod2_mod1) {
__platform_printf("BEGIN\r\n");
obj_run(pikaMain,
"import test_module1\n"
"test_module1.test_module2.test_module1.mytest()"
);
"test_module1.test_module2.test_module1.mytest()");
/* collect */
/* assert */
EXPECT_STREQ(log_buff[0], "test_module_1_hello\r\n");
@ -396,8 +395,7 @@ TEST(module, improt_as_cmodule) {
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
obj_run(pikaMain,
"from PikaStdData import String as string\n");
obj_run(pikaMain, "from PikaStdData import String as string\n");
/* collect */
/* assert */
/* deinit */
@ -405,4 +403,73 @@ TEST(module, improt_as_cmodule) {
EXPECT_EQ(pikaMemNow(), 0);
}
extern "C" {
volatile FILE* f_getchar_fp = NULL;
char f_getchar(void) {
char c = 0;
fread(&c, 1, 1, (FILE*)f_getchar_fp);
return c;
}
void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn);
}
TEST(module, REPL_runbytecode) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
f_getchar_fp = fopen("package/pikascript/cjson_test.py.o", "rb");
pikaScriptShell_withGetchar(pikaMain, f_getchar);
fclose((FILE*)f_getchar_fp);
obj_run(pikaMain, "test_start()");
/* collect */
/* assert */
EXPECT_STREQ(log_buff[0], "shopping\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(module, REPL_script) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
f_getchar_fp = fopen("test/python/UnitTest.py", "rb");
pikaScriptShell_withGetchar(pikaMain, f_getchar);
fclose((FILE*)f_getchar_fp);
/* collect */
/* assert */
EXPECT_STREQ(log_buff[4], "mem used max:\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(module, REPL_big_script) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
f_getchar_fp = fopen("package/pikascript/cjson_test.py", "rb");
pikaScriptShell_withGetchar(pikaMain, f_getchar);
fclose((FILE*)f_getchar_fp);
/* collect */
/* assert */
EXPECT_STREQ(log_buff[0],
"\r\nError: line buff overflow, please use bigger "
"'PIKA_LINE_BUFF_SIZE'\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif

View File

@ -93,3 +93,4 @@ print('[Unit Tests Succeed]')
print('====================')
print('mem used max:')
mem.max()
exit()

View File

@ -17,6 +17,7 @@ extern "C" {
#include "dataStrs.h"
#include "pikaScript.h"
#include "pika_config_gtest.h"
#include <stdio.h>
extern PikaMemInfo pikaMemInfo;
/* the log_buff of printf */
extern char log_buff[LOG_BUFF_MAX][LOG_SIZE];