From 3cd78d6efd5b288702d69b2f55be9288c947666f Mon Sep 17 00:00:00 2001 From: suchmememanyskill Date: Sun, 18 Jul 2021 23:51:27 +0200 Subject: [PATCH] add scripts to the main menu, fix script parser reading beyond EOF --- source/fs/menus/explorer.h | 5 ++- source/fs/menus/filemenu.c | 2 +- source/script/ABadIdeaVersion3.c | 2 +- source/script/parser.c | 9 +++-- source/script/parser.h | 4 +- source/script/standardLibrary.c | 37 ++++++++--------- source/tegraexplorer/mainmenu.c | 68 ++++++++++++++++++++++++++++++-- 7 files changed, 94 insertions(+), 33 deletions(-) diff --git a/source/fs/menus/explorer.h b/source/fs/menus/explorer.h index 840f4d8..cda9e09 100644 --- a/source/fs/menus/explorer.h +++ b/source/fs/menus/explorer.h @@ -1,4 +1,7 @@ #pragma once #include "../../utils/vector.h" +#include "../../gfx/menu.h" +#include "../fstypes.h" -void FileExplorer(char *path); \ No newline at end of file +void FileExplorer(char *path); +MenuEntry_t MakeMenuOutFSEntry(FSEntry_t entry); \ No newline at end of file diff --git a/source/fs/menus/filemenu.c b/source/fs/menus/filemenu.c index dc9caca..0beff1a 100644 --- a/source/fs/menus/filemenu.c +++ b/source/fs/menus/filemenu.c @@ -101,7 +101,7 @@ void RunScript(char *path, FSEntry_t entry){ gfx_printf("Init gc\n"); initGarbageCollector(); gfx_printf("Parsing\n"); - ParserRet_t ret = parseScript(script); + ParserRet_t ret = parseScript(script, size); free(script); gfx_printf("Init vars\n"); setStaticVars(&ret.staticVarHolder); diff --git a/source/script/ABadIdeaVersion3.c b/source/script/ABadIdeaVersion3.c index 5a52ce9..5e0a4e0 100644 --- a/source/script/ABadIdeaVersion3.c +++ b/source/script/ABadIdeaVersion3.c @@ -71,7 +71,7 @@ int main() //parseScript("#REQUIRE VER 3.0.5\nmain = { two = 1 + 1 }"); //ParserRet_t ret = parseScript("a.b.c(1){ a.b.c() }"); - ParserRet_t ret = parseScript(script); + ParserRet_t ret = parseScript(script, strlen(script)); free(script); setStaticVars(&ret.staticVarHolder); diff --git a/source/script/parser.c b/source/script/parser.c index 359c996..0833042 100644 --- a/source/script/parser.c +++ b/source/script/parser.c @@ -71,6 +71,8 @@ typedef enum { History_Array, } StackHistory_t; +char* end; + u8 nextToken(char** inPtr, void** val) { char* in = *inPtr; u8 ret = Token_Err; @@ -191,7 +193,7 @@ u8 nextToken(char** inPtr, void** val) { ret = Token_String; *val = storage; } - else if (*in == '\0') { + else if (*in == '\0' || in > end) { *inPtr = in; return ret; } @@ -258,7 +260,7 @@ int isLastVarCall(Operator_t* opHolder) { return (opHolder->token == CallArgs && getLastRef(&opHolder->callArgs)->action == ActionCall); } -ParserRet_t parseScript(char* in) { +ParserRet_t parseScript(char* in, u32 len) { Vector_t functionStack; // Function_t Vector_t stackHistoryHolder; // StaticHistory_t Vector_t staticVariableHolder; // Variable_t @@ -275,8 +277,9 @@ ParserRet_t parseScript(char* in) { u8 notNext = 0; lineNumber = 1; scriptCurrentLine = 1; + end = in + len; - while (*in) { + while (*in && in <= end) { Function_t* lastFunc = getStackEntry(&functionStack); StackHistory_t* lastHistory = getStackEntry(&stackHistoryHolder); diff --git a/source/script/parser.h b/source/script/parser.h index b09bd7a..c81e3a2 100644 --- a/source/script/parser.h +++ b/source/script/parser.h @@ -10,6 +10,6 @@ typedef struct { #define SCRIPT_PARSER_ERR(message, ...) printScriptError(SCRIPT_PARSER_FATAL, message, ##__VA_ARGS__); return (ParserRet_t){0} -ParserRet_t parseScript(char* in); void exitStaticVars(Vector_t* v); -void exitFunction(Operator_t* start, u32 len); \ No newline at end of file +void exitFunction(Operator_t* start, u32 len); +ParserRet_t parseScript(char* in, u32 len); \ No newline at end of file diff --git a/source/script/standardLibrary.c b/source/script/standardLibrary.c index f8d7672..cf7719e 100644 --- a/source/script/standardLibrary.c +++ b/source/script/standardLibrary.c @@ -70,6 +70,12 @@ ClassFunction(stdPrint) { return &emptyClass; } +ClassFunction(stdPrintLn) { + stdPrint(caller, args, argsLen); + gfx_printf("\n"); + return &emptyClass; +} + ClassFunction(stdExit) { return NULL; } @@ -128,33 +134,22 @@ ClassFunction(stdSetPixel) { } #endif -enum standardFunctionIndexes { - STD_IF = 0, - STD_WHILE, - STD_PRINT, - STD_MOUNTSYSMMC, - STD_MOUNTSAVE, - STD_EXIT, - STD_BREAK, - STD_DICT, - STD_SETPIXEL, -}; - u8 oneIntoneFunction[] = { IntClass, FunctionClass }; u8 doubleFunctionClass[] = { FunctionClass, FunctionClass }; u8 oneStringArgStd[] = {StringClass}; u8 threeIntsStd[] = { IntClass, IntClass, IntClass }; ClassFunctionTableEntry_t standardFunctionDefenitions[] = { - [STD_IF] = {"if", stdIf, 2, oneIntoneFunction}, - [STD_WHILE] = {"while", stdWhile, 2, doubleFunctionClass}, - [STD_PRINT] = {"print", stdPrint, VARARGCOUNT, 0}, - [STD_MOUNTSYSMMC] = {"mountsys", stdMountSysmmc, 1, oneStringArgStd}, - [STD_MOUNTSAVE] = {"readsave", stdMountSave, 1, oneStringArgStd}, - [STD_EXIT] = {"exit", stdExit, 0, 0}, - [STD_BREAK] = {"break", stdBreak, 0, 0}, - [STD_DICT] = {"dict", stdDict, 0, 0}, - [STD_SETPIXEL] = {"setpixel", stdSetPixel, 3, threeIntsStd}, + {"if", stdIf, 2, oneIntoneFunction}, + {"while", stdWhile, 2, doubleFunctionClass}, + {"print", stdPrint, VARARGCOUNT, 0}, + {"println", stdPrintLn, VARARGCOUNT, 0}, + {"mountsys", stdMountSysmmc, 1, oneStringArgStd}, + {"readsave", stdMountSave, 1, oneStringArgStd}, + {"exit", stdExit, 0, 0}, + {"break", stdBreak, 0, 0}, + {"dict", stdDict, 0, 0}, + {"setpixel", stdSetPixel, 3, threeIntsStd}, }; ClassFunctionTableEntry_t* searchStdLib(char* funcName) { diff --git a/source/tegraexplorer/mainmenu.c b/source/tegraexplorer/mainmenu.c index feffed2..48c2112 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -17,6 +17,10 @@ #include #include "../utils/utils.h" #include "../config.h" +#include "../fs/readers/folderReader.h" +#include +#include +#include "../fs/menus/filemenu.h" extern hekate_config h_cfg; @@ -36,7 +40,8 @@ enum { MainRebootRCM, MainRebootNormal, MainRebootHekate, - MainRebootAMS + MainRebootAMS, + MainScripts, }; MenuEntry_t mainMenuEntries[] = { @@ -55,7 +60,8 @@ MenuEntry_t mainMenuEntries[] = { [MainRebootRCM] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to RCM"}, [MainRebootNormal] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot normally"}, [MainRebootHekate] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to bootloader/update.bin"}, - [MainRebootAMS] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to atmosphere/reboot_payload.bin"} + [MainRebootAMS] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to atmosphere/reboot_payload.bin"}, + [MainScripts] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "\n-- Scripts --"} }; void HandleSD(){ @@ -108,6 +114,13 @@ void ViewCredits(){ if (hidRead()->r) gfx_printf("%k\"I'm not even sure if it works\" - meme", COLOR_ORANGE); + +/* Leaving this here for my debugging needs :) + heap_monitor_t a = {0}; + heap_monitor(&a, false); + gfx_printf("\nUsed: %d\nTotal: %d\n", a.used, a.total); +*/ + hidWait(); } @@ -168,13 +181,60 @@ void EnterMainMenu(){ mainMenuEntries[MainRebootHekate].hide = (!sd_mounted || !FileExists("sd:/bootloader/update.bin")); mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01; + // -- Scripts -- + mainMenuEntries[MainScripts].hide = (!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")); + + Vector_t ent = vecFromArray(mainMenuEntries, ARR_LEN(mainMenuEntries), sizeof(MenuEntry_t)); + Vector_t scriptFiles = {0}; + u8 hasScripts = 0; + + if (!mainMenuEntries[MainScripts].hide){ + int res = 0; + scriptFiles = ReadFolder("sd:/tegraexplorer/scripts", &res); + if (!res){ + if (!scriptFiles.count){ + free(scriptFiles.data); + mainMenuEntries[MainScripts].hide = 1; + } + else { + hasScripts = 1; + ent = newVec(sizeof(MenuEntry_t), ARRAY_SIZE(mainMenuEntries) + scriptFiles.count); + ent.count = ARRAY_SIZE(mainMenuEntries); + memcpy(ent.data, mainMenuEntries, sizeof(MenuEntry_t) * ARRAY_SIZE(mainMenuEntries)); + vecForEach(FSEntry_t*, scriptFile, (&scriptFiles)){ + if (!scriptFile->isDir && StrEndsWith(scriptFile->name, ".te")){ + MenuEntry_t a = MakeMenuOutFSEntry(*scriptFile); + vecAdd(&ent, a); + } + } + + if (ent.count == ARRAY_SIZE(mainMenuEntries)){ + clearFileVector(&scriptFiles); + free(ent.data); + ent = vecFromArray(mainMenuEntries, ARR_LEN(mainMenuEntries), sizeof(MenuEntry_t)); + hasScripts = 0; + mainMenuEntries[MainScripts].hide = 1; + } + } + } + } + gfx_clearscreen(); gfx_putc('\n'); - Vector_t ent = vecFromArray(mainMenuEntries, ARR_LEN(mainMenuEntries), sizeof(MenuEntry_t)); res = newMenu(&ent, res, 79, 30, ALWAYSREDRAW, 0); - if (mainMenuPaths[res] != NULL) + if (res < MainScripts && mainMenuPaths[res] != NULL) mainMenuPaths[res](); + else if (hasScripts){ + vecDefArray(FSEntry_t*, scriptFilesArray, scriptFiles); + RunScript("sd:/tegraexplorer/scripts", scriptFilesArray[res - ARRAY_SIZE(mainMenuEntries)]); + hidWait(); + } + + if (hasScripts){ + clearFileVector(&scriptFiles); + free(ent.data); + } } }