From 7be15140f2e012bb950efaf88d23636ee2857caf Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Tue, 21 Nov 2023 16:58:25 +0000 Subject: [PATCH 1/6] Add tab completion for files and directories --- src/mos_editor.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ src_fatfs/ffconf.h | 2 +- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/mos_editor.c b/src/mos_editor.c index 9d06c95..5a6d294 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -326,6 +326,87 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { } } } break; + + case 0x09: { // Tab + char *search_term; + char *path; + + FRESULT fr; + DIR dj; + FILINFO fno; + const char *searchTermStart; + const char *lastSpace = strrchr(buffer, ' '); + const char *lastSlash = strrchr(buffer, '/'); + + + if (lastSlash != NULL) { + int pathLength = 1; + + if (lastSpace != NULL && lastSlash > lastSpace) { + lastSpace++; + pathLength = lastSlash - lastSpace; // Path starts after the last space and includes the slash + } + if (lastSpace == NULL) { + lastSpace = buffer; + pathLength = lastSlash - lastSpace; + + } + + path = (char*) malloc(pathLength + 1); // +1 for null terminator + if (path == NULL) { + break; + } + strncpy(path, lastSpace, pathLength); // Start after the last space + path[pathLength] = '\0'; // Null-terminate the string + + // Determine the start of the search term + searchTermStart = lastSlash + 1; + if (lastSpace != NULL && lastSpace > lastSlash) { + searchTermStart = lastSpace + 1; + } + search_term = (char*) malloc(strlen(searchTermStart) + 2); // +2 for '*' and null terminator + } else { + + path = (char*) malloc(1); + if (path == NULL) { + break; + } + path[0] = '\0'; // Path is empty (current dir, essentially). + + searchTermStart = lastSpace ? lastSpace + 1 : buffer; + search_term = (char*) malloc(strlen(searchTermStart) + 2); // +2 for '*' and null terminator + } + + if (search_term == NULL) { + free(path); + break; + } + + strcpy(search_term, lastSpace && lastSlash > lastSpace ? lastSlash + 1 : lastSpace ? lastSpace + 1 : buffer); + strcat(search_term, "*"); + + //printf("Path:\"%s\" Pattern:\"%s\"\r\n", path, search_term); + fr = f_findfirst(&dj, &fno, path, search_term); + + if (fr == FR_OK && fno.fname[0]) { + + if (fno.fattrib & AM_DIR) printf("%s/", fno.fname + strlen(search_term) - 1); + else printf("%s", fno.fname + strlen(search_term) - 1); + + strcat(buffer, fno.fname + strlen(search_term) - 1); + if (fno.fattrib & AM_DIR) strcat(buffer, "/"); + + len = strlen(buffer); + insertPos = strlen(buffer); + + } + + // Free the allocated memory + free(search_term); + free(path); + + } break; + case 0x7F: { // Backspace if (deleteCharacter(buffer, insertPos, len)) { insertPos--; diff --git a/src_fatfs/ffconf.h b/src_fatfs/ffconf.h index f9b060b..561a174 100644 --- a/src_fatfs/ffconf.h +++ b/src_fatfs/ffconf.h @@ -39,7 +39,7 @@ / 3: f_lseek() function is removed in addition to 2. */ -#define FF_USE_FIND 0 +#define FF_USE_FIND 1 /* This option switches filtered directory read functions, f_findfirst() and / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ From 321347b3deb8a77c13beeae738d23239bd06848b Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Thu, 23 Nov 2023 21:35:47 +0000 Subject: [PATCH 2/6] Add autocomplete for moslets in /mos/ --- src/mos_editor.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/mos_editor.c b/src/mos_editor.c index 5a6d294..2656e1c 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -338,7 +338,28 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { const char *lastSpace = strrchr(buffer, ' '); const char *lastSlash = strrchr(buffer, '/'); - + if (lastSlash == NULL && lastSpace == NULL) { //Try commands first before fatfs completion + + search_term = (char*) malloc(strlen(buffer) + 6); + strcpy(search_term, buffer); + strcat(search_term, "*.bin"); + + fr = f_findfirst(&dj, &fno, "/mos/", search_term); + + if (fr == FR_OK && fno.fname[0]) { + + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + + } + + } + if (lastSlash != NULL) { int pathLength = 1; From 43c3cfe6d334b7e240ed8d0b8f70223d0eeb4c50 Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Sat, 25 Nov 2023 10:37:07 +0000 Subject: [PATCH 3/6] Adjust getCommand to return a pointer to the matched command, and take advantage of this to return the matched command. Allows auto-completion of internal commands while only needing to maintain mosCommands[] in mos.c centrally. --- src/mos.c | 13 ++++++++----- src/mos.h | 2 +- src/mos_editor.c | 22 +++++++++++++++++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/mos.c b/src/mos.c index ddc74b9..a3c4c89 100644 --- a/src/mos.c +++ b/src/mos.c @@ -171,16 +171,17 @@ UINT24 mos_input(char * buffer, int bufferLength) { // Returns: // - Function pointer, or 0 if command not found // -void * mos_getCommand(char * ptr) { +t_mosCommand *mos_getCommand(char * ptr) { int i; t_mosCommand * cmd; for(i = 0; i < mosCommands_count; i++) { cmd = &mosCommands[i]; if(mos_cmp(cmd->name, ptr) == 0) { - return cmd->func; + //return cmd->func; + return cmd; } } - return 0; + return NULL; } // Case insensitive commpare with abbreviations @@ -335,12 +336,14 @@ int mos_exec(char * buffer) { int (*func)(char * ptr); char path[256]; UINT8 mode; + t_mosCommand *cmd; ptr = mos_trim(buffer); ptr = mos_strtok(ptr, " "); if(ptr != NULL) { - func = mos_getCommand(ptr); - if(func != 0) { + cmd = mos_getCommand(ptr); + func = cmd->func; + if(cmd != NULL && func != 0) { fr = func(ptr); } else { diff --git a/src/mos.h b/src/mos.h index 0a7f7dc..93edce3 100644 --- a/src/mos.h +++ b/src/mos.h @@ -53,7 +53,7 @@ void mos_error(int error); BYTE mos_getkey(void); UINT24 mos_input(char * buffer, int bufferLength); -void * mos_getCommand(char * ptr); +t_mosCommand *mos_getCommand(char * ptr); BOOL mos_cmp(char *p1, char *p2); char * mos_trim(char * s); char * mos_strtok(char *s1, char * s2); diff --git a/src/mos_editor.c b/src/mos_editor.c index 2656e1c..5b7d00a 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -334,6 +334,7 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { FRESULT fr; DIR dj; FILINFO fno; + t_mosCommand *cmd; const char *searchTermStart; const char *lastSpace = strrchr(buffer, ' '); const char *lastSlash = strrchr(buffer, '/'); @@ -341,12 +342,27 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { if (lastSlash == NULL && lastSpace == NULL) { //Try commands first before fatfs completion search_term = (char*) malloc(strlen(buffer) + 6); + strcpy(search_term, buffer); - strcat(search_term, "*.bin"); + strcat(search_term, "."); - fr = f_findfirst(&dj, &fno, "/mos/", search_term); + cmd = mos_getCommand(search_term); + if (cmd != NULL) { //First try internal MOS commands + + printf("%s ", cmd->name + strlen(buffer)); + strcat(buffer, cmd->name + strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + + } - if (fr == FR_OK && fno.fname[0]) { + strcpy(search_term, buffer); + strcat(search_term, "*.bin"); + fr = f_findfirst(&dj, &fno, "/mos/", search_term); + if (fr == FR_OK && fno.fname[0]) { //Now try MOSlets printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); From 49ce8d04cdf65ccfac8349766049f4fce28105e9 Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Sat, 25 Nov 2023 13:54:30 +0000 Subject: [PATCH 4/6] Minor tweak to account for absolute/root paths --- src/mos_editor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mos_editor.c b/src/mos_editor.c index 5b7d00a..2922f32 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -380,7 +380,6 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { int pathLength = 1; if (lastSpace != NULL && lastSlash > lastSpace) { - lastSpace++; pathLength = lastSlash - lastSpace; // Path starts after the last space and includes the slash } if (lastSpace == NULL) { @@ -393,7 +392,7 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { if (path == NULL) { break; } - strncpy(path, lastSpace, pathLength); // Start after the last space + strncpy(path, lastSpace + 1, pathLength); // Start after the last space path[pathLength] = '\0'; // Null-terminate the string // Determine the start of the search term From 9a711ea6147ffa131206b996096298b5fe8415e4 Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Sun, 3 Dec 2023 12:27:00 +0000 Subject: [PATCH 5/6] Tab completion for /bin/ --- src/mos.c | 19 +++++++++++++++++++ src/mos_editor.c | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/mos.c b/src/mos.c index a3c4c89..e58d752 100644 --- a/src/mos.c +++ b/src/mos.c @@ -366,7 +366,26 @@ int mos_exec(char * buffer) { fr = 21; break; } + return fr; } + + sprintf(path, "/bin/%s.bin", ptr); + fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); + if(fr == 0) { + mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); + switch(mode) { + case 0: // Z80 mode + fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + case 1: // ADL mode + fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + default: // Unrecognised header + fr = 21; + break; + } + return fr; + } else { if(fr == 4) { fr = 20; diff --git a/src/mos_editor.c b/src/mos_editor.c index 2922f32..7373549 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -372,6 +372,18 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { free(search_term); break; + } else { //Otherwise try /bin/ + + fr = f_findfirst(&dj, &fno, "/bin/", search_term); + if (!(fr == FR_OK && fno.fname[0])) break; + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + } } From a83753c571bd5485254ffef002f84401200c85a2 Mon Sep 17 00:00:00 2001 From: HeathenUK Date: Sun, 21 Jan 2024 10:03:38 +0000 Subject: [PATCH 6/6] Add local .bin completion and add OSCLI guard rails from parallel branch. --- main.c | 2 +- src/mos.c | 58 +++++++++++++++++++++++++++++++++--------------- src/mos.h | 2 +- src/mos_editor.c | 23 ++++++++++++++----- 4 files changed, 60 insertions(+), 25 deletions(-) diff --git a/main.c b/main.c index 284863d..d767689 100644 --- a/main.c +++ b/main.c @@ -154,7 +154,7 @@ int main(void) { // while(1) { if(mos_input(&cmd, sizeof(cmd)) == 13) { - int err = mos_exec(&cmd); + int err = mos_exec(&cmd, TRUE); if(err > 0) { mos_error(err); } diff --git a/src/mos.c b/src/mos.c index e58d752..d630aa1 100644 --- a/src/mos.c +++ b/src/mos.c @@ -330,7 +330,7 @@ BOOL mos_parseString(char * ptr, char ** p_Value) { // Returns: // - MOS error code // -int mos_exec(char * buffer) { +int mos_exec(char * buffer, BOOL in_mos) { char * ptr; int fr = 0; int (*func)(char * ptr); @@ -369,22 +369,44 @@ int mos_exec(char * buffer) { return fr; } - sprintf(path, "/bin/%s.bin", ptr); - fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); - if(fr == 0) { - mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); - switch(mode) { - case 0: // Z80 mode - fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); - break; - case 1: // ADL mode - fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); - break; - default: // Unrecognised header - fr = 21; - break; + if (in_mos) { + + sprintf(path, "%s.bin", ptr); + fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); + if(fr == 0) { + mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); + switch(mode) { + case 0: // Z80 mode + fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + case 1: // ADL mode + fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + default: // Unrecognised header + fr = 21; + break; + } + return fr; + } + + sprintf(path, "/bin/%s.bin", ptr); + fr = mos_LOAD(path, MOS_defaultLoadAddress, 0); + if(fr == 0) { + mode = mos_execMode((UINT8 *)MOS_defaultLoadAddress); + switch(mode) { + case 0: // Z80 mode + fr = exec16(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + case 1: // ADL mode + fr = exec24(MOS_defaultLoadAddress, mos_strtok_ptr); + break; + default: // Unrecognised header + fr = 21; + break; + } + return fr; } - return fr; + } else { if(fr == 4) { @@ -1046,7 +1068,7 @@ UINT24 mos_BOOT(char * filename, char * buffer, UINT24 size) { if(fr == FR_OK) { while(!f_eof(&fil)) { f_gets(buffer, size, &fil); - mos_exec(buffer); + mos_exec(buffer, TRUE); } } f_close(&fil); @@ -1232,7 +1254,7 @@ void mos_GETERROR(UINT8 errno, UINT24 address, UINT24 size) { // UINT24 mos_OSCLI(char * cmd) { UINT24 fr; - fr = mos_exec(cmd); + fr = mos_exec(cmd, FALSE); return fr; } diff --git a/src/mos.h b/src/mos.h index 93edce3..14697a1 100644 --- a/src/mos.h +++ b/src/mos.h @@ -58,7 +58,7 @@ BOOL mos_cmp(char *p1, char *p2); char * mos_trim(char * s); char * mos_strtok(char *s1, char * s2); char * mos_strtok_r(char *s1, const char *s2, char **ptr); -int mos_exec(char * buffer); +int mos_exec(char * buffer, BOOL in_mos); UINT8 mos_execMode(UINT8 * ptr); int mos_mount(void); diff --git a/src/mos_editor.c b/src/mos_editor.c index 7373549..d3c1d6f 100644 --- a/src/mos_editor.c +++ b/src/mos_editor.c @@ -372,10 +372,23 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { free(search_term); break; - } else { //Otherwise try /bin/ - - fr = f_findfirst(&dj, &fno, "/bin/", search_term); - if (!(fr == FR_OK && fno.fname[0])) break; + } + + //Try local .bin + fr = f_findfirst(&dj, &fno, "", search_term); + if ((fr == FR_OK && fno.fname[0])) { + printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); + strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); + strcat(buffer, " "); + len = strlen(buffer); + insertPos = strlen(buffer); + free(search_term); + break; + } + + //Otherwise try /bin/ + fr = f_findfirst(&dj, &fno, "/bin/", search_term); + if ((fr == FR_OK && fno.fname[0])) { printf("%.*s ", strlen(fno.fname) - 4 - strlen(buffer), fno.fname + strlen(buffer)); strncat(buffer, fno.fname + strlen(buffer), strlen(fno.fname) - 4 - strlen(buffer)); strcat(buffer, " "); @@ -383,9 +396,9 @@ UINT24 mos_EDITLINE(char * buffer, int bufferLength, UINT8 clear) { insertPos = strlen(buffer); free(search_term); break; - } + } if (lastSlash != NULL) {