Skip to content

Commit 26f4354

Browse files
committed
update
1 parent 35b4076 commit 26f4354

File tree

7 files changed

+196
-5
lines changed

7 files changed

+196
-5
lines changed

port/linux/.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
// "--gtest_filter=module.REPL_big_script"
1515
// "--gtest_filter=parser.input_issue1"
1616
// "--gtest_filter=except.raise_type"
17-
"--gtest_filter=module.REPL_big_script"
17+
// "--gtest_filter=module.REPL_big_script"
18+
"--gtest_filter=builtin.repl_mode"
1819
],
1920
"stopAtEntry": false,
2021
"cwd": "${workspaceFolder}",

port/linux/test/module-test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ TEST(module, REPL_big_script) {
603603
fclose((FILE*)f_getchar_fp);
604604
/* collect */
605605
/* assert */
606-
EXPECT_STREQ(log_buff[0],
606+
EXPECT_STREQ(log_buff[3],
607607
"\r\nError: line buff overflow, please use bigger "
608608
"'PIKA_LINE_BUFF_SIZE'\r\n");
609609
/* deinit */

src/PikaObj.c

Lines changed: 177 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,135 @@ typedef enum {
13951395
__FILTER_SUCCESS_DROP_ALL_PEEKED
13961396
} FilterReturn;
13971397

1398+
typedef struct {
1399+
int count;
1400+
char** completions;
1401+
} CompletionList;
1402+
1403+
typedef struct {
1404+
char lineBuff[PIKA_LINE_BUFF_SIZE];
1405+
size_t line_position;
1406+
size_t line_curpos;
1407+
char prefix[32];
1408+
} Shell;
1409+
1410+
const char* dictionary[] = {
1411+
"import", "PikaStdLib", "from", "high",
1412+
"low", "Pin", "value", "def",
1413+
"PikaStdDevice", "setPin", "enable", "print",
1414+
"sleep_ms", "read", "setMode", "setCallBack",
1415+
"setPull", "as", "MemChecker", "max",
1416+
"min", "float", "int", "str",
1417+
"list", "dict", "tuple", "if",
1418+
"else", "elif", "for", "while",
1419+
"break", "continue", "return", "try",
1420+
"except", "finally", "with", "open",
1421+
"write", "append", "close", "True",
1422+
"False", "None", "self", "class",
1423+
"init", "len", "range", "input",
1424+
"output", "config", "setup", "loop",
1425+
"GPIO", "UART", "I2C", "SPI",
1426+
"ADC", "PWM", "digitalRead", "digitalWrite",
1427+
"analogRead", "analogWrite", "time", "datetime",
1428+
"random", "OS", "sys", "math",
1429+
"json", "readFile", "writeFile", ""};
1430+
1431+
int dictSize = sizeof(dictionary) / sizeof(dictionary[0]);
1432+
1433+
static CompletionList filtered_complete = {0, NULL};
1434+
1435+
void shCompletePrint(CompletionList* completeList, const char* prefix) {
1436+
for (int i = 0; i < completeList->count; i++) {
1437+
printf("%s ", completeList->completions[i]);
1438+
}
1439+
}
1440+
1441+
void getFilteredCompletions(const char* prefix,
1442+
const char** dictionary,
1443+
int dictSize,
1444+
CompletionList* result) {
1445+
printf("\n");
1446+
if (result->completions != NULL) {
1447+
for (int i = 0; i < result->count; i++) {
1448+
free(result->completions[i]);
1449+
}
1450+
free(result->completions);
1451+
result->completions = NULL;
1452+
}
1453+
result->count = 0;
1454+
result->completions = (char**)malloc(dictSize * sizeof(char*));
1455+
if (result->completions == NULL) {
1456+
printf("Memory allocation failed\n");
1457+
return;
1458+
}
1459+
1460+
for (int i = 0; i < dictSize; i++) {
1461+
if (strncmp(dictionary[i], prefix, strlen(prefix)) == 0) {
1462+
result->completions[result->count] = strdup(dictionary[i]);
1463+
if (result->completions[result->count] == NULL) {
1464+
printf("Memory allocation failed for completion\n");
1465+
continue;
1466+
}
1467+
result->count++;
1468+
}
1469+
}
1470+
1471+
if (result->count == 0) {
1472+
printf("Warning: No matches found for '%s'\n", prefix);
1473+
}
1474+
}
1475+
1476+
/*free CompletionList*/
1477+
void freeCompletionList(CompletionList* list) {
1478+
for (int i = 0; i < list->count; ++i) {
1479+
free(list->completions[i]);
1480+
}
1481+
free(list->completions);
1482+
list->completions = NULL;
1483+
list->count = 0;
1484+
}
1485+
1486+
void handleTabCompletion(ShellConfig* shell, char* prefix) {
1487+
#if PIKA_TAB_ENABLE
1488+
if (shell->line_position > 0) {
1489+
if (prefix == NULL) {
1490+
printf("Memory allocation failed for prefix\n");
1491+
return;
1492+
}
1493+
1494+
// printf("\n================[fetch : %s ]=====================\n",
1495+
// prefix);
1496+
getFilteredCompletions(prefix, dictionary, dictSize,
1497+
&filtered_complete);
1498+
1499+
if (filtered_complete.count == 1) {
1500+
char* last_space = strrchr(shell->lineBuff, ' ');
1501+
size_t start_pos = 0;
1502+
1503+
if (last_space != NULL) {
1504+
start_pos = last_space - shell->lineBuff + 1;
1505+
}
1506+
1507+
memset(shell->lineBuff + start_pos, 0,
1508+
sizeof(shell->lineBuff) - start_pos);
1509+
strncpy(shell->lineBuff + start_pos,
1510+
filtered_complete.completions[0],
1511+
sizeof(shell->lineBuff) - start_pos - 1);
1512+
shell->lineBuff[sizeof(shell->lineBuff) - 1] = '\0';
1513+
shell->line_position = strlen(shell->lineBuff);
1514+
shell->line_curpos = shell->line_position;
1515+
1516+
printf(">>> %s", shell->lineBuff);
1517+
} else {
1518+
shCompletePrint(&filtered_complete, prefix);
1519+
printf("\n>>> %s", shell->lineBuff);
1520+
}
1521+
free(prefix);
1522+
}
1523+
#endif
1524+
freeCompletionList(&filtered_complete);
1525+
}
1526+
13981527
pika_bool _filter_msg_hi_pika_handler(FilterItem* msg,
13991528
PikaObj* self,
14001529
ShellConfig* shell) {
@@ -1668,6 +1797,14 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16681797
ShellConfig* shell) {
16691798
char* input_line = NULL;
16701799
enum shellCTRL ctrl = SHELL_CTRL_CONTINUE;
1800+
static uint64_t tick_start_block_input = 0;
1801+
if (tick_start_block_input != 0) {
1802+
if (pika_platform_get_tick() - tick_start_block_input < 5000) {
1803+
return SHELL_CTRL_CONTINUE;
1804+
} else {
1805+
tick_start_block_input = 0;
1806+
}
1807+
}
16711808
if (inputChar == 0x7F) {
16721809
inputChar = '\b';
16731810
}
@@ -1682,6 +1819,34 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16821819
ctrl = SHELL_CTRL_CONTINUE;
16831820
goto __exit;
16841821
}
1822+
if (inputChar == 0x09) {
1823+
#if PIKA_TAB_ENABLE
1824+
if (shell->line_position > 0) {
1825+
// printf("Current cursor position: %zu, Line position: %zu\n",
1826+
// shell->line_curpos, shell->line_position);
1827+
char* shell_content = NULL;
1828+
char* last_space = strrchr(shell->lineBuff, ' ');
1829+
1830+
if (last_space == NULL) {
1831+
shell_content = strndup(shell->lineBuff, shell->line_position);
1832+
} else {
1833+
shell_content = strdup(last_space + 1);
1834+
}
1835+
1836+
if (shell_content == NULL) {
1837+
printf("Memory allocation failed for shell_content\n");
1838+
// return;
1839+
}
1840+
1841+
handleTabCompletion(shell, shell_content);
1842+
ctrl = SHELL_CTRL_CONTINUE;
1843+
// __clearBuff(shell);
1844+
goto __exit;
1845+
}
1846+
#endif
1847+
ctrl = SHELL_CTRL_CONTINUE;
1848+
goto __exit;
1849+
}
16851850
if (inputChar == 0x1b) {
16861851
shell->stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY;
16871852
ctrl = SHELL_CTRL_CONTINUE;
@@ -1762,7 +1927,12 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
17621927
pika_platform_printf(
17631928
"\r\nError: line buff overflow, please use bigger "
17641929
"'PIKA_LINE_BUFF_SIZE'\r\n");
1765-
ctrl = SHELL_CTRL_EXIT;
1930+
ctrl = SHELL_CTRL_CONTINUE;
1931+
pika_platform_printf(
1932+
"Input is blocked for 5 seconds to protect the "
1933+
"kernel...\r\n");
1934+
tick_start_block_input = pika_platform_get_tick();
1935+
pika_platform_printf(">>> ");
17661936
__clearBuff(shell);
17671937
goto __exit;
17681938
}
@@ -1981,6 +2151,12 @@ void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) {
19812151
while (1) {
19822152
inputChar[1] = inputChar[0];
19832153
inputChar[0] = _await_getchar(cfg->fn_getchar);
2154+
#ifdef __linux
2155+
if (inputChar[0] == EOF) {
2156+
pika_platform_printf("\r\n");
2157+
return;
2158+
}
2159+
#endif
19842160
#if !PIKA_NANO_ENABLE
19852161
/* run python script */
19862162
if (inputChar[0] == '!' && inputChar[1] == '#') {

src/PikaObj.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ char* shHistory_getPrev(ShellHistory* self);
498498
char* shHistory_getNext(ShellHistory* self);
499499
#endif
500500

501+
#if PIKA_TAB_ENABLE
502+
void handleTabCompletion(ShellConfig* shell, char* prefix);
503+
#endif
504+
501505
void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);
502506

503507
void _temp__do_pikaScriptShell(PikaObj* self, ShellConfig* cfg);

src/PikaParser.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2720,7 +2720,9 @@ static char* Suger_semicolon(Args* outbuffs, char* sLine) {
27202720
sStmtItem = strsAppend(&buffs, sStmtItem, "\n");
27212721
sStmtAfter = strsAppend(&buffs, sStmtAfter, sStmtItem);
27222722
}
2723-
sStmtAfter[strGetSize(sStmtAfter) - 1] = '\0';
2723+
if (sStmtAfter[0] != '\0') {
2724+
sStmtAfter[strGetSize(sStmtAfter) - 1] = '\0';
2725+
}
27242726
sStmtAfter = strsCopy(outbuffs, sStmtAfter);
27252727
strsDeinit(&buffs);
27262728
return sStmtAfter;

src/PikaVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
#define PIKA_VERSION_MINOR 13
33
#define PIKA_VERSION_MICRO 4
44

5-
#define PIKA_EDIT_TIME "2025/05/21 20:12:08"
5+
#define PIKA_EDIT_TIME "2025/06/02 13:54:26"

src/pika_config_valid.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ extern "C" {
9393
#define PIKA_SHELL_HISTORY_ENABLE 0
9494
#endif
9595

96+
#ifndef PIKA_TAB_ENABLE
97+
#define PIKA_TAB_ENABLE 0
98+
#endif
99+
96100
#endif
97101

98102
/* default optimize */
@@ -495,6 +499,10 @@ extern "C" {
495499
#define PIKA_SHELL_HISTORY_ENABLE 1
496500
#endif
497501

502+
#ifndef PIKA_TAB_ENABLE
503+
#define PIKA_TAB_ENABLE 1
504+
#endif
505+
498506
#ifndef PIKA_SHELL_HISTORY_NUM
499507
#define PIKA_SHELL_HISTORY_NUM 5
500508
#endif

0 commit comments

Comments
 (0)