diff --git a/source/tegraexplorer/common/common.h b/source/tegraexplorer/common/common.h index 31c7b61..d163e58 100644 --- a/source/tegraexplorer/common/common.h +++ b/source/tegraexplorer/common/common.h @@ -20,7 +20,8 @@ enum utils_err_codes_te_call { ERR_EMMC_READ_FAILED, ERR_EMMC_WRITE_FAILED, ERR_FILE_TOO_BIG_FOR_DEST, - ERR_SD_EJECTED + ERR_SD_EJECTED, + ERR_PARSE_FAIL }; extern const char *utils_err_codes_te[]; diff --git a/source/tegraexplorer/common/strings.c b/source/tegraexplorer/common/strings.c index 6271bf7..5d25aee 100644 --- a/source/tegraexplorer/common/strings.c +++ b/source/tegraexplorer/common/strings.c @@ -49,7 +49,8 @@ const char *utils_err_codes_te[] = { // these start at 50 "EMMC READ FAILED", "EMMC WRITE FAILED", "FILE TOO BIG FOR DEST", - "SD EJECTED" + "SD EJECTED", + "PARSING FAILED" }; const char *pkg2names[] = { diff --git a/source/tegraexplorer/emmc/emmc.c b/source/tegraexplorer/emmc/emmc.c index 7485a92..60b2fc2 100644 --- a/source/tegraexplorer/emmc/emmc.c +++ b/source/tegraexplorer/emmc/emmc.c @@ -67,7 +67,7 @@ int connect_part(const char *partition){ system_part = nx_emmc_part_find(&gpt, partition); if (!system_part) { gfx_errDisplay("connect_mmc_part", ERR_PART_NOT_FOUND, 0); - return -1; + return 1; } return 0; @@ -81,11 +81,11 @@ int mount_mmc(const char *partition, const int biskeynumb){ se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10); if (connect_part(partition)) - return -1; + return 1; if ((res = f_mount(&emmc, "emmc:", 1))) { gfx_errDisplay("mount_mmc", res, 0); - return -1; + return 1; } return 0; diff --git a/source/tegraexplorer/fs/filemenu.c b/source/tegraexplorer/fs/filemenu.c index d2792a0..8a52f0e 100644 --- a/source/tegraexplorer/fs/filemenu.c +++ b/source/tegraexplorer/fs/filemenu.c @@ -13,7 +13,7 @@ #include "../gfx/menu.h" #include "../common/types.h" #include "../../utils/sprintf.h" -#include "../utils/script.h" +#include "../script/parser.h" #include "../emmc/emmcoperations.h" extern char *currentpath; @@ -145,7 +145,7 @@ int filemenu(menu_entry file){ } SETBIT(fs_menu_file[7].property, ISHIDE, !(strstr(file.name, ".bin") != NULL && file.property & ISKB)); - SETBIT(fs_menu_file[8].property, ISHIDE, !(strstr(file.name, ".tegrascript") != NULL)); + SETBIT(fs_menu_file[8].property, ISHIDE, !(strstr(file.name, ".te") != NULL)); SETBIT(fs_menu_file[10].property, ISHIDE, !(strstr(file.name, ".bis") != NULL)); SETBIT(fs_menu_file[11].property, ISHIDE, !(strstr(file.name, ".bis") != NULL)); @@ -165,7 +165,9 @@ int filemenu(menu_entry file){ launch_payload(fsutil_getnextloc(currentpath, file.name)); break; case FILE_SCRIPT: - ParseScript(fsutil_getnextloc(currentpath, file.name)); + //ParseScript(fsutil_getnextloc(currentpath, file.name)); + runScript(fsutil_getnextloc(currentpath, file.name)); + fsreader_readfolder(currentpath); break; case FILE_HEXVIEW: viewbytes(fsutil_getnextloc(currentpath, file.name)); diff --git a/source/tegraexplorer/fs/fsactions.c b/source/tegraexplorer/fs/fsactions.c index d193d89..63200aa 100644 --- a/source/tegraexplorer/fs/fsactions.c +++ b/source/tegraexplorer/fs/fsactions.c @@ -23,22 +23,22 @@ int fsact_copy(const char *locin, const char *locout, u8 options){ if (!strcmp(locin, locout)){ gfx_errDisplay("copy", ERR_SAME_LOC, 1); - return -1; + return 1; } if ((res = f_open(&in, locin, FA_READ | FA_OPEN_EXISTING))){ gfx_errDisplay("copy", res, 2); - return -1; + return 1; } if (f_stat(locin, &in_info)){ gfx_errDisplay("copy", res, 3); - return -1; + return 1; } if (f_open(&out, locout, FA_CREATE_ALWAYS | FA_WRITE)){ gfx_errDisplay("copy", res, 4); - return -1; + return 1; } buff = malloc (BUFSIZE); @@ -48,17 +48,17 @@ int fsact_copy(const char *locin, const char *locout, u8 options){ while (sizeoffile > 0){ if ((res = f_read(&in, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp1))){ gfx_errDisplay("copy", res, 5); - return -1; + return 1; } if ((res = f_write(&out, buff, (sizeoffile > BUFSIZE) ? BUFSIZE : sizeoffile, &temp2))){ gfx_errDisplay("copy", res, 6); - return -1; + return 1; } if (temp1 != temp2){ gfx_errDisplay("copy", ERR_DISK_WRITE_FAILED, 7); - return -1; + return 1; } sizeoffile -= temp1; @@ -84,7 +84,7 @@ int fsact_copy(const char *locin, const char *locout, u8 options){ if ((res = f_chmod(locout, in_info.fattrib, 0x3A))){ gfx_errDisplay("copy", res, 8); - return -1; + return 1; } f_stat(locin, &in_info); //somehow stops fatfs from being weird @@ -103,7 +103,7 @@ int fsact_del_recursive(char *path){ if ((res = f_opendir(&dir, localpath))){ gfx_errDisplay("del_recursive", res, 1); - return -1; + return 1; } while (!f_readdir(&dir, &fno) && fno.fname[0]){ @@ -117,7 +117,7 @@ int fsact_del_recursive(char *path){ if ((res = f_unlink(fsutil_getnextloc(localpath, fno.fname)))){ gfx_errDisplay("del_recursive", res, 2); - return -1; + return 1; } } } @@ -126,7 +126,7 @@ int fsact_del_recursive(char *path){ if ((res = f_unlink(localpath))){ gfx_errDisplay("del_recursive", res, 3); - return -1; + return 1; } free(localpath); @@ -148,7 +148,7 @@ int fsact_copy_recursive(char *path, char *dstpath){ if ((res = f_opendir(&dir, startpath))){ gfx_errDisplay("copy_recursive", res, 1); - return -1; + return 1; } f_mkdir(destpath); @@ -166,7 +166,7 @@ int fsact_copy_recursive(char *path, char *dstpath){ if ((res = fsact_copy(temp, fsutil_getnextloc(destpath, fno.fname), COPY_MODE_PRINT))){ gfx_errDisplay("copy_recursive", res, 2); - return -1; + return 1; } free(temp); @@ -177,12 +177,12 @@ int fsact_copy_recursive(char *path, char *dstpath){ if ((res = (f_stat(startpath, &fno)))){ gfx_errDisplay("copy_recursive", res, 3); - return -1; + return 1; } if ((res = f_chmod(destpath, fno.fattrib, 0x3A))){ gfx_errDisplay("copy_recursive", res, 4); - return -1; + return 1; } free(startpath); diff --git a/source/tegraexplorer/gfx/gfxutils.c b/source/tegraexplorer/gfx/gfxutils.c index 144b126..72a04f9 100644 --- a/source/tegraexplorer/gfx/gfxutils.c +++ b/source/tegraexplorer/gfx/gfxutils.c @@ -54,7 +54,7 @@ int gfx_errDisplay(char *src_func, int err, int loc){ if (err < 15) gfx_printf("Desc: %s\n", utils_err_codes[err]); - else if (err >= ERR_SAME_LOC && err <= ERR_SD_EJECTED) + else if (err >= ERR_SAME_LOC && err <= ERR_PARSE_FAIL) gfx_printf("Desc: %s\n", utils_err_codes_te[err - 50]); if (loc) @@ -63,6 +63,9 @@ int gfx_errDisplay(char *src_func, int err, int loc){ gfx_printf("\nPress any button to return"); RESETCOLOR; + + while (btn_read() != 0); + return btn_wait(); } diff --git a/source/tegraexplorer/gfx/menu.c b/source/tegraexplorer/gfx/menu.c index c10c300..a85e6df 100644 --- a/source/tegraexplorer/gfx/menu.c +++ b/source/tegraexplorer/gfx/menu.c @@ -73,7 +73,7 @@ int menu_make(menu_entry *entries, int amount, char *toptext){ if (calculatedamount){ SWAPCOLOR(COLOR_DEFAULT); SWAPBGCOLOR(COLOR_WHITE); - gfx_printf("%3d entries\n", amount); + gfx_printf("%3d entries\n", calculatedamount); RESETCOLOR; } else diff --git a/source/tegraexplorer/mainmenu.c b/source/tegraexplorer/mainmenu.c index f76b381..5991df2 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -6,7 +6,7 @@ #include "../utils/btn.h" #include "emmc/emmc.h" #include "../storage/emummc.h" -#include "utils/script.h" +#include "script/functions.h" #include "common/common.h" #include "gfx/menu.h" @@ -127,7 +127,7 @@ void MainMenu_Exit(){ } //todo declock bpmp } -part_handler mainmenu_functions[] = { +func_void_ptr mainmenu_functions[] = { MainMenu_SDCard, MainMenu_EMMC, MainMenu_EMMC, diff --git a/source/tegraexplorer/script/functions.c b/source/tegraexplorer/script/functions.c new file mode 100644 index 0000000..0efd63a --- /dev/null +++ b/source/tegraexplorer/script/functions.c @@ -0,0 +1,512 @@ +#include +#include +#include "../../mem/heap.h" +#include "../gfx/gfxutils.h" +#include "../emmc/emmc.h" +#include "../../utils/types.h" +#include "../../libs/fatfs/ff.h" +#include "../../utils/sprintf.h" +#include "../../utils/btn.h" +#include "../../gfx/gfx.h" +#include "../../utils/util.h" +#include "../../storage/emummc.h" +#include "parser.h" +#include "../common/common.h" +#include "../fs/fsactions.h" +#include "variables.h" +#include "../utils/utils.h" +#include "functions.h" +#include "../fs/fsutils.h" +#include "../../utils/sprintf.h" +#include "../fs/fsactions.h" + +extern FIL scriptin; +extern char **argv; +extern u32 argc; +extern int forceExit; + +int parseIntInput(char *in, int *out){ + if (in[0] == '@'){ + if (str_int_find(argv[0], out)) + return -1; + } + else + *out = atoi(in); + + return 0; +} + +int parseJmpInput(char *in, u64 *out){ + if (in[0] == '?'){ + if (str_jmp_find(argv[0], out)) + return -1; + else + return 0; + } + else + return -1; +} + +int parseStringInput(char *in, char **out){ + if (in[0] == '$'){ + if (str_str_find(in, out)) + return -1; + else + return 0; + } + else{ + *out = in; + return 0; + } +} + +u32 currentcolor = COLOR_WHITE; +int part_printf(){ + char *toprint; + if (parseStringInput(argv[0], &toprint)) + return -1; + + SWAPCOLOR(currentcolor); + gfx_printf(toprint); + gfx_printf("\n"); + return 0; +} + +int part_print_int(){ + int toprint; + if (parseIntInput(argv[0], &toprint)) + return -1; + + SWAPCOLOR(currentcolor); + gfx_printf("%s: %d\n", argv[0], toprint); + return 0; +} + +int part_Wait(){ + int arg; + u32 begintime; + SWAPCOLOR(currentcolor); + + if (parseIntInput(argv[0], &arg)) + return -1; + + begintime = get_tmr_s(); + + while (begintime + arg > get_tmr_s()){ + gfx_printf("\r ", (begintime + arg) - get_tmr_s()); + } + + gfx_printf("\r \r"); + return 0; +} + +int part_if(){ + int condition; + if (parseIntInput(argv[0], &condition)) + return -1; + + getfollowingchar('{'); + + if (!condition) + skipbrackets(); + + return 0; + + /* + if (condition) + return 0; + else { + skipbrackets(); + return 0; + } + */ +} + +int part_Math(){ + int left, right; + if (parseIntInput(argv[0], &left)) + return -1; + if (parseIntInput(argv[2], &right)) + return -1; + + switch (argv[1][0]){ + case '+': + return left + right; + case '-': + return left - right; + case '*': + return left * right; + case '/': + return left / right; + } + return -1; +} + +int part_Check(){ + int left, right; + if (parseIntInput(argv[0], &left)) + return -1; + if (parseIntInput(argv[2], &right)) + return -1; + + if (!strcmp(argv[1], "==")) + return (left == right); + else if (!strcmp(argv[1], "!=")) + return (left != right); + else if (!strcmp(argv[1], ">=")) + return (left >= right); + else if (!strcmp(argv[1], "<=")) + return (left <= right); + else if (!strcmp(argv[1], ">")) + return (left > right); + else if (!strcmp(argv[1], "<")) + return (left < right); + else + return -1; +} + +int part_SetInt(){ + int out; + parseIntInput(argv[0], &out); + return out; +} + +int part_SetString(){ + char *arg0; + if (parseStringInput(argv[0], &arg0)) + return -1; + if (argv[1][0] != '$') + return -1; + + str_str_add(argv[1], arg0); + return 0; +} + +int part_SetStringIndex(){ + int index; + char *out; + if (parseIntInput(argv[0], &index)) + return -1; + if (argv[1][0] != '$') + return -1; + if (str_str_index(index, &out)) + return -1; + str_str_add(argv[1], out); + return 0; +} + +int part_goto(){ + u64 target = 0; + if (parseJmpInput(argv[0], &target)) + return -1; + f_lseek(&scriptin, target); + return 0; +} + +int part_invert(){ + int arg; + if (parseIntInput(argv[0], &arg)) + return -1; + return (arg) ? 0 : 1; +} + +int part_fs_exists(){ + char *path; + if (parseStringInput(argv[0], &path)) + return -1; + + return fsutil_checkfile(path); +} + +int part_ConnectMMC(){ + char *arg; + parseStringInput(argv[0], &arg); + + if (!strcmp(arg, "SYSMMC")) + connect_mmc(SYSMMC); + else if (!strcmp(arg, "EMUMMC")) + connect_mmc(EMUMMC); + else + return -1; + + return 0; +} + +int part_MountMMC(){ + char *arg; + parseStringInput(argv[0], &arg); + return mount_mmc(arg, 2); +} + +int part_Pause(){ + int res; + + while (btn_read() != 0); + + res = btn_wait(); + + str_int_add("@BTN_POWER", (res & BTN_POWER)); + str_int_add("@BTN_VOL+", (res & BTN_VOL_UP)); + str_int_add("@BTN_VOL-", (res & BTN_VOL_DOWN)); + + return res; +} + +int part_addstrings(){ + char *combined, *left, *middle; + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &middle)) + return -1; + if (argv[2][0] != '$') + return -1; + + combined = calloc(strlen(left) + strlen(middle) + 1, sizeof(char)); + sprintf(combined, "%s%s", left, middle); + + str_str_add(argv[2], combined); + free(combined); + return 0; +} + +int part_setColor(){ + char *arg; + if (parseStringInput(argv[0], &arg)) + return -1; + + if (!strcmp(arg, "RED")) + currentcolor = COLOR_RED; + else if (!strcmp(arg, "ORANGE")) + currentcolor = COLOR_ORANGE; + else if (!strcmp(arg, "YELLOW")) + currentcolor = COLOR_YELLOW; + else if (!strcmp(arg, "GREEN")) + currentcolor = COLOR_GREEN; + else if (!strcmp(arg, "BLUE")) + currentcolor = COLOR_BLUE; + else if (!strcmp(arg, "VIOLET")) + currentcolor = COLOR_VIOLET; + else if (!strcmp(arg, "WHITE")) + currentcolor = COLOR_WHITE; + else + return -1; + + return 0; +} + +int part_Exit(){ + forceExit = true; + return 0; +} + +int part_fs_Move(){ + char *left, *right; + + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &right)) + return -1; + + int res; + res = f_rename(left, right); + if (res) + res = f_rename(left, right); + + return res; +} + +int part_fs_Delete(){ + char *arg; + + if (parseStringInput(argv[0], &arg)) + return -1; + + int res; + res = f_unlink(arg); + if (res) + res = f_unlink(arg); + + return res; +} + +int part_fs_DeleteRecursive(){ + char *arg; + + if (parseStringInput(argv[0], &arg)) + return -1; + + return fsact_del_recursive(arg); +} + +int part_fs_Copy(){ + char *left, *right; + + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &right)) + return -1; + + return fsact_copy(left, right, COPY_MODE_PRINT); +} + +int part_fs_CopyRecursive(){ + char *left, *right; + + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &right)) + return -1; + + return fsact_copy_recursive(left, right); +} + +int part_fs_MakeDir(){ + char *arg; + + if (parseStringInput(argv[0], &arg)) + return -1; + + int res; + res = f_mkdir(arg); + if (res) + res = f_mkdir(arg); + + return res; +} + +DIR dir; +FILINFO fno; +int isdirvalid = false; +int part_fs_OpenDir(){ + char *path; + + if (parseStringInput(argv[0], &path)) + return -1; + + if (f_opendir(&dir, path)) + return -1; + + isdirvalid = true; + str_int_add("@ISDIRVALID", isdirvalid); + return 0; +} + +int part_fs_CloseDir(){ + if (!isdirvalid) + return 0; + + f_closedir(&dir); + isdirvalid = false; + str_int_add("@ISDIRVALID", isdirvalid); + return 0; +} + +int part_fs_ReadDir(){ + if (!isdirvalid) + return -1; + + if (!f_readdir(&dir, &fno) && fno.fname[0]){ + str_str_add("$FILENAME", fno.fname); + str_int_add("@ISDIR", (fno.fattrib & AM_DIR) ? 1 : 0); + } + else { + part_fs_CloseDir(); + } + + return 0; +} + +int part_setPrintPos(){ + int left, right; + + if (parseIntInput(argv[0], &left)) + return -1; + + if (parseIntInput(argv[1], &right)) + return -1; + + if (left > 42) + return -1; + + if (right > 78) + return -1; + + gfx_con_setpos(left * 16, right * 16); + return 0; +} + +int part_stringcompare(){ + char *left, *right; + + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &right)) + return -1; + + return (strcmp(left, right)) ? 0 : 1; +} + +int part_fs_combinePath(){ + char *combined, *left, *middle; + if (parseStringInput(argv[0], &left)) + return -1; + if (parseStringInput(argv[1], &middle)) + return -1; + if (argv[2][0] != '$') + return -1; + + combined = fsutil_getnextloc(left, middle); + + str_str_add(argv[2], combined); + free(combined); + return 0; +} + +str_fnc_struct functions[] = { + {"printf", part_printf, 1}, + {"printInt", part_print_int, 1}, + {"setPrintPos", part_setPrintPos, 2}, + {"if", part_if, 1}, + {"math", part_Math, 3}, + {"check", part_Check, 3}, + {"setInt", part_SetInt, 1}, + {"goto", part_goto, 1}, + {"setString", part_SetString, 2}, + {"setStringIndex", part_SetStringIndex, 2}, + {"setColor", part_setColor, 1}, + {"combineStrings", part_addstrings, 3}, + {"compareStrings", part_stringcompare, 2}, + {"invert", part_invert, 1}, + {"fs_exists", part_fs_exists, 1}, + {"fs_move", part_fs_Move, 2}, + {"fs_mkdir", part_fs_MakeDir, 1}, + {"fs_del", part_fs_Delete, 1}, + {"fs_delRecursive", part_fs_DeleteRecursive, 1}, + {"fs_copy", part_fs_Copy, 2}, + {"fs_copyRecursive", part_fs_CopyRecursive, 2}, + {"fs_openDir", part_fs_OpenDir, 1}, + {"fs_closeDir", part_fs_CloseDir, 0}, + {"fs_readDir", part_fs_ReadDir, 0}, + {"fs_combinePath", part_fs_combinePath, 3}, + {"mmc_connect", part_ConnectMMC, 1}, + {"mmc_mount", part_MountMMC, 1}, + {"pause", part_Pause, 0}, + {"wait", part_Wait, 1}, + {"exit", part_Exit, 0}, + {NULL, NULL, 0} +}; + +int run_function(char *func_name, int *out){ + for (u32 i = 0; functions[i].key != NULL; i++){ + if (!strcmp(functions[i].key, func_name)){ + if (argc != functions[i].arg_count) + return -2; + + *out = functions[i].value(); + if (*out < 0) + return -1; + return 0; + } + } + return -1; +} \ No newline at end of file diff --git a/source/tegraexplorer/script/functions.h b/source/tegraexplorer/script/functions.h new file mode 100644 index 0000000..ac9e03d --- /dev/null +++ b/source/tegraexplorer/script/functions.h @@ -0,0 +1,13 @@ +#pragma once +#include "../../utils/types.h" + +typedef void (*func_void_ptr)(); +typedef int (*func_int_ptr)(); + +typedef struct { + char *key; + func_int_ptr value; + u8 arg_count; +} str_fnc_struct; + +int run_function(char *func_name, int *out); \ No newline at end of file diff --git a/source/tegraexplorer/script/parser.c b/source/tegraexplorer/script/parser.c new file mode 100644 index 0000000..13ffb64 --- /dev/null +++ b/source/tegraexplorer/script/parser.c @@ -0,0 +1,308 @@ +#include +#include "../../mem/heap.h" +#include "../gfx/gfxutils.h" +#include "../emmc/emmc.h" +#include "../../utils/types.h" +#include "../../libs/fatfs/ff.h" +#include "../../utils/sprintf.h" +#include "../../utils/btn.h" +#include "../../gfx/gfx.h" +#include "../../utils/util.h" +#include "../../storage/emummc.h" +#include "parser.h" +#include "../common/common.h" +#include "../fs/fsactions.h" +#include "functions.h" +#include "variables.h" +#include "../fs/fsreader.h" +#include "../utils/utils.h" + +u32 countchars(char* in, char target) { + u32 len = strlen(in); + u32 count = 0; + for (u32 i = 0; i < len; i++) { + if (in[i] == '"'){ + i++; + while (in[i] != '"'){ + i++; + if (i >= len) + return -1; + } + } + if (in[i] == target) + count++; + } + return count; +} + +char **argv = NULL; +u32 argc; +u32 splitargs(char* in) { + // arg like '5, "6", @arg7' + u32 i, current = 0, count = 1, len = strlen(in), curcount = 0; + + if ((count += countchars(in, ',')) < 0){ + return 0; + } + + /* + if (argv != NULL) { + for (i = 0; argv[i] != NULL; i++) + free(argv[i]); + free(argv); + } + */ + + argv = calloc(count + 1, sizeof(char*)); + + for (i = 0; i < count; i++) + argv[i] = calloc(128, sizeof(char)); + + + for (i = 0; i < len && curcount < count; i++) { + if (in[i] == ',') { + curcount++; + current = 0; + } + else if (in[i] == '@' || in[i] == '$' || in[i] == '?') { + while (in[i] != ',' && in[i] != ' ' && in[i] != ')' && i < len) { + argv[curcount][current++] = in[i++]; + } + i--; + } + else if (in[i] >= '0' && in[i] <= '9') + argv[curcount][current++] = in[i]; + else if (in[i] == '"') { + i++; + while (in[i] != '"') { + argv[curcount][current++] = in[i++]; + } + } + } + return count; +} + +FIL scriptin; +UINT endByte = 0; +int forceExit = false; +char currentchar = 0; + +char getnextchar(){ + f_read(&scriptin, ¤tchar, sizeof(char), &endByte); + + if (sizeof(char) != endByte) + forceExit = true; + + //gfx_printf("|%c|", currentchar); + return currentchar; +} + +void getfollowingchar(char end){ + while (currentchar != end && !f_eof(&scriptin)){ + if (currentchar == '"'){ + while (getnextchar() != '"' && !f_eof(&scriptin)); + } + getnextchar(); + } +} + +void getnextvalidchar(){ + while ((!((currentchar >= '?' && currentchar <= 'Z') || (currentchar >= 'a' && currentchar <= 'z') || currentchar == '#') && !f_eof(&scriptin)) /*|| currentchar == ';' */) + getnextchar(); +} + +char *makestr(u32 size, char ignore){ + char *str; + u32 count = 0; + + str = calloc(size + 1, sizeof(char)); + for (u32 i = 0; i < size; i++){ + getnextchar(); + if (ignore != 0 && ignore == currentchar) + continue; + + str[count++] = currentchar; + } + + return str; +} + +char *readtilchar(char end, char ignore){ + FSIZE_t offset, size; + + offset = f_tell(&scriptin); + getfollowingchar(end); + size = f_tell(&scriptin) - offset; + + if (size <= 0) + return NULL; + + f_lseek(&scriptin, offset - 1); + + return makestr((u32)size, ignore); +} + + +char *funcbuff = NULL; +void functionparser(){ + char *unsplitargs; + + /* + if (funcbuff != NULL) + free(funcbuff); + */ + + funcbuff = readtilchar('(', ' '); + + getfollowingchar('('); + getnextchar(); + + unsplitargs = readtilchar(')', 0); + + if (unsplitargs != NULL){ + argc = splitargs(unsplitargs); + getnextchar(); + } + else { + argc = 0; + } + getnextchar(); + + free(unsplitargs); +} + +char *gettargetvar(){ + char *variable = NULL; + + variable = readtilchar('=', ' '); + + getfollowingchar('='); + getnextchar(); + + return variable; +} + +void mainparser(){ + char *variable = NULL; + int res, out = 0; + + getnextvalidchar(); + + if (f_eof(&scriptin)) + return; + + if (currentchar == '#'){ + getfollowingchar('\n'); + return; + } + + if (currentchar == '@'){ + variable = gettargetvar(); + getnextvalidchar(); + } + + if (currentchar == '?'){ + char *jumpname; + jumpname = readtilchar(';', ' '); + getnextchar(); + str_jmp_add(jumpname, f_tell(&scriptin)); + getfollowingchar('\n'); + return; + } + + functionparser(); + + res = run_function(funcbuff, &out); + if (res < 0){ + printerrors = true; + //gfx_printf("%s|%s|%d", funcbuff, argv[0], argc); + //btn_wait(); + gfx_errDisplay("mainparser", ERR_PARSE_FAIL, f_tell(&scriptin)); + forceExit = true; + //gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]); + } + else { + str_int_add("@RESULT", out); + + if (variable != NULL) + str_int_add(variable, out); + } + + //gfx_printf("\nGoing to next func %c\n", currentchar); + + if (funcbuff != NULL){ + free(funcbuff); + funcbuff = NULL; + } + + if (argv != NULL) { + for (int i = 0; argv[i] != NULL; i++) + free(argv[i]); + free(argv); + argv = NULL; + } + + if (variable != NULL){ + free(variable); + } +} + +void skipbrackets(){ + u32 bracketcounter = 0; + + getfollowingchar('{'); + getnextchar(); + + while ((currentchar != '}' || bracketcounter != 0) && !f_eof(&scriptin)){ + if (currentchar == '{') + bracketcounter++; + else if (currentchar == '}') + bracketcounter--; + + getnextchar(); + } +} + +extern u32 currentcolor; +extern char *currentpath; +void runScript(char *path){ + int res; + char *path_local = NULL; + forceExit = false; + currentchar = 0; + currentcolor = COLOR_WHITE; + gfx_clearscreen(); + utils_copystring(path, &path_local); + + res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING); + if (res != FR_OK){ + gfx_errDisplay("ParseScript", res, 1); + return; + } + + printerrors = false; + + //add builtin vars + str_int_add("@EMUMMC", emu_cfg.enabled); + str_int_add("@RESULT", 0); + str_int_add("@BTN_POWER", 0); + str_int_add("@BTN_VOL+", 0); + str_int_add("@BTN_VOL-", 0); + str_str_add("$CURRENTPATH", currentpath); + + //str_int_printall(); + + while (!f_eof(&scriptin) && !forceExit){ + mainparser(); + } + + printerrors = true; + //str_int_printall(); + + f_close(&scriptin); + str_int_clear(); + str_jmp_clear(); + str_str_clear(); + free(path_local); + //btn_wait(); +} \ No newline at end of file diff --git a/source/tegraexplorer/script/parser.h b/source/tegraexplorer/script/parser.h new file mode 100644 index 0000000..8df9fea --- /dev/null +++ b/source/tegraexplorer/script/parser.h @@ -0,0 +1,5 @@ +#pragma once + +void runScript(char *path); +void skipbrackets(); +void getfollowingchar(char end); \ No newline at end of file diff --git a/source/tegraexplorer/script/variables.c b/source/tegraexplorer/script/variables.c new file mode 100644 index 0000000..26cb559 --- /dev/null +++ b/source/tegraexplorer/script/variables.c @@ -0,0 +1,249 @@ +#include +#include "../../mem/heap.h" +#include "../gfx/gfxutils.h" +#include "../emmc/emmc.h" +#include "../../utils/types.h" +#include "../../libs/fatfs/ff.h" +#include "../../utils/sprintf.h" +#include "../../utils/btn.h" +#include "../../gfx/gfx.h" +#include "../../utils/util.h" +#include "../../storage/emummc.h" +#include "parser.h" +#include "../common/common.h" +#include "../fs/fsactions.h" +#include "variables.h" +#include "../utils/utils.h" + +static dict_str_int *str_int_table = NULL; +static dict_str_str *str_str_table = NULL; +static dict_str_loc *str_jmp_table = NULL; + +int str_int_add(char *key, int value){ + char *key_local; + dict_str_int *keyvaluepair; + + utils_copystring(key, &key_local); + + keyvaluepair = calloc(1, sizeof(dict_str_int)); + keyvaluepair->key = key_local; + keyvaluepair->value = value; + keyvaluepair->next = NULL; + + if (str_int_table == NULL){ + str_int_table = keyvaluepair; + } + else { + dict_str_int *temp; + temp = str_int_table; + while (temp != NULL){ + if (!strcmp(temp->key, key_local)){ + free(keyvaluepair); + free(key_local); + temp->value = value; + return 0; + } + + if (temp->next == NULL){ + temp->next = keyvaluepair; + return 0; + } + + temp = temp->next; + } + } + + return 0; +} + +int str_int_find(char *key, int *out){ + dict_str_int *temp; + temp = str_int_table; + while (temp != NULL){ + if (!strcmp(temp->key, key)){ + *out = temp->value; + return 0; + } + temp = temp->next; + } + + return -1; +} + +void str_int_clear(){ + dict_str_int *cur, *next; + cur = str_int_table; + + while (cur != NULL){ + next = cur->next; + free(cur->key); + free(cur); + cur = next; + } + str_int_table = NULL; +} + +void str_int_printall(){ + dict_str_int *temp; + temp = str_int_table; + while (temp != NULL){ + gfx_printf("%s -> %d\n", temp->key, temp->value); + temp = temp->next; + } +} + +int str_jmp_add(char *key, u64 value){ + char *key_local; + dict_str_loc *keyvaluepair; + + //gfx_printf("Adding |%s|\n", key_local); + + utils_copystring(key, &key_local); + + keyvaluepair = calloc(1, sizeof(dict_str_loc)); + keyvaluepair->key = key_local; + keyvaluepair->value = value; + keyvaluepair->next = NULL; + + if (str_jmp_table == NULL){ + str_jmp_table = keyvaluepair; + } + else { + dict_str_loc *temp; + temp = str_jmp_table; + while (temp != NULL){ + if (!strcmp(temp->key, key_local)){ + free(keyvaluepair); + free(key_local); + + temp->value = value; + return 0; + } + + if (temp->next == NULL){ + temp->next = keyvaluepair; + return 0; + } + + temp = temp->next; + } + } + + return 0; +} + +int str_jmp_find(char *key, u64 *out){ + dict_str_loc *temp; + temp = str_jmp_table; + //gfx_printf("Searching |%s|\n", key); + while (temp != NULL){ + if (!strcmp(temp->key, key)){ + //gfx_printf("Key found!\n", temp->value); + *out = temp->value; + return 0; + } + temp = temp->next; + } + + //gfx_printf("no key!\n"); + return -1; +} + +void str_jmp_clear(){ + dict_str_loc *cur, *next; + cur = str_jmp_table; + + while (cur != NULL){ + next = cur->next; + free(cur->key); + free(cur); + cur = next; + } + str_jmp_table = NULL; +} + +int str_str_add(char *key, char *value){ + char *key_local, *value_local; + dict_str_str *keyvaluepair; + //gfx_printf("Adding |%s|\n", key_local); + utils_copystring(value, &value_local); + utils_copystring(key, &key_local); + + keyvaluepair = calloc(1, sizeof(dict_str_str)); + keyvaluepair->key = key_local; + keyvaluepair->value = value_local; + keyvaluepair->next = NULL; + + if (str_str_table == NULL){ + str_str_table = keyvaluepair; + } + else { + dict_str_str *temp; + temp = str_str_table; + while (temp != NULL){ + if (!strcmp(temp->key, key_local)){ + free(keyvaluepair); + free(key_local); + + free(temp->value); + temp->value = value_local; + return 0; + } + + if (temp->next == NULL){ + temp->next = keyvaluepair; + return 0; + } + + temp = temp->next; + } + } + + return 0; +} + +int str_str_find(char *key, char **out){ + dict_str_str *temp; + temp = str_str_table; + + while (temp != NULL){ + if (!strcmp(temp->key, key)){ + *out = temp->value; + return 0; + } + temp = temp->next; + } + + return -1; +} + +int str_str_index(int index, char **out){ + dict_str_str *temp; + temp = str_str_table; + + for (int i = 0; i < index; i++){ + if (temp == NULL) + return -1; + temp = temp->next; + } + + if (temp == NULL) + return -1; + + *out = temp->value; + return 0; +} + +void str_str_clear(){ + dict_str_str *cur, *next; + cur = str_str_table; + + while (cur != NULL){ + next = cur->next; + free(cur->key); + free(cur->value); + free(cur); + cur = next; + } + str_str_table = NULL; +} \ No newline at end of file diff --git a/source/tegraexplorer/script/variables.h b/source/tegraexplorer/script/variables.h new file mode 100644 index 0000000..61c7612 --- /dev/null +++ b/source/tegraexplorer/script/variables.h @@ -0,0 +1,32 @@ +#pragma once +#include "../../utils/types.h" + +typedef struct _dict_str_int { + char *key; + int value; + struct _dict_str_int *next; +} dict_str_int; + +typedef struct _dict_str_str { + char *key; + char *value; + struct _dict_str_str *next; +} dict_str_str; + +typedef struct _dict_str_loc { + char *key; + u64 value; + struct _dict_str_loc *next; +} dict_str_loc; + +int str_int_add(char *key, int value); +int str_int_find(char *key, int *out); +void str_int_clear(); +void str_int_printall(); +int str_jmp_add(char *key, u64 value); +int str_jmp_find(char *key, u64 *out); +void str_jmp_clear(); +int str_str_add(char *key, char *value); +int str_str_find(char *key, char **out); +int str_str_index(int index, char **out); +void str_str_clear(); \ No newline at end of file diff --git a/source/tegraexplorer/utils/script.c b/source/tegraexplorer/utils/script.c deleted file mode 100644 index 6caa565..0000000 --- a/source/tegraexplorer/utils/script.c +++ /dev/null @@ -1,287 +0,0 @@ -#include -#include "../../mem/heap.h" -#include "../gfx/gfxutils.h" -#include "../emmc/emmc.h" -#include "../../utils/types.h" -#include "../../libs/fatfs/ff.h" -#include "../../utils/sprintf.h" -#include "../../utils/btn.h" -#include "../../gfx/gfx.h" -#include "../../utils/util.h" -#include "../../storage/emummc.h" -#include "script.h" -#include "../common/common.h" -#include "../fs/fsactions.h" - -#include - -char func[11] = "", args[2][128] = {"", ""}; -int res, errcode; -const int scriptver = 140; -bool forceExit = false; -u32 currentcolor; - -void Part_CheckFile(){ - FILINFO fno; - errcode = f_stat(args[0], &fno); -} - -void Part_SetColor(){ - if (strcmpcheck(args[0], "RED")) - currentcolor = COLOR_RED; - else if (strcmpcheck(args[0], "ORANGE")) - currentcolor = COLOR_ORANGE; - else if (strcmpcheck(args[0], "YELLOW")) - currentcolor = COLOR_YELLOW; - else if (strcmpcheck(args[0], "GREEN")) - currentcolor = COLOR_GREEN; - else if (strcmpcheck(args[0], "BLUE")) - currentcolor = COLOR_BLUE; - else if (strcmpcheck(args[0], "VIOLET")) - currentcolor = COLOR_VIOLET; - else if (strcmpcheck(args[0], "WHITE")) - currentcolor = COLOR_WHITE; -} - -void Part_Wait(){ - int waitamount, begintime; - SWAPCOLOR(currentcolor); - - waitamount = atoi(args[0]); - begintime = get_tmr_s(); - - while (begintime + waitamount > get_tmr_s()){ - gfx_printf("\r ", (begintime + waitamount) - get_tmr_s()); - } - - gfx_printf("\r \r"); -} - -void Part_VersionCheck(){ - int givenversion = atoi(args[0]); - - if (givenversion > scriptver){ - gfx_printf("Script required version is too high\nUpdate TegraExplorer!"); - btn_wait(); - forceExit = true; - } -} - -void Part_Move(){ - errcode = f_rename(args[0], args[1]); - if (errcode) - f_rename(args[0], args[1]); -} - -void Part_Delete(){ - errcode = f_unlink(args[0]); - if (errcode) - f_unlink(args[0]); -} - -void Part_DeleteRecursive(){ - errcode = fsact_del_recursive(args[0]); -} - -void Part_Copy(){ - errcode = fsact_copy(args[0], args[1], COPY_MODE_PRINT); -} - -void Part_RecursiveCopy(){ - errcode = fsact_copy_recursive(args[0], args[1]); -} - -void Part_MakeFolder(){ - errcode = f_mkdir(args[0]); - if (errcode) - f_mkdir(args[0]); -} - -void Part_ConnectMMC(){ - if (strcmpcheck(args[0], "SYSMMC")) - connect_mmc(SYSMMC); - if (strcmpcheck(args[0], "EMUMMC")) - connect_mmc(EMUMMC); -} - -void Part_MountMMC(){ - errcode = mount_mmc(args[0], 2); -} - -void Part_Print(){ - RESETCOLOR; - SWAPCOLOR(currentcolor); - gfx_printf("%s\n", args[0]); -} - -void Part_ErrorPrint(){ - RESETCOLOR; - SWAPCOLOR(COLOR_RED); - gfx_printf("Errorcode: %d\n", errcode); -} - -void Part_Exit(){ - forceExit = true; -} - -u8 buttons_pressed = 0; -void Part_WaitOnUser(){ - buttons_pressed = btn_wait(); -} - -script_parts parts[] = { - {"COPY", Part_Copy, 2}, - {"COPY-R", Part_RecursiveCopy, 2}, - {"MKDIR", Part_MakeFolder, 1}, - {"CON_MMC", Part_ConnectMMC, 1}, - {"MNT_MMC", Part_MountMMC, 1}, - {"PRINT", Part_Print, 1}, - {"ERRPRINT", Part_ErrorPrint, 0}, - {"EXIT", Part_Exit, 0}, - {"PAUSE", Part_WaitOnUser, 0}, - {"DEL", Part_Delete, 1}, - {"DEL-R", Part_DeleteRecursive, 1}, - {"MOVE", Part_Move, 2}, - {"VERSION", Part_VersionCheck, 1}, - {"WAIT", Part_Wait, 1}, - {"COLOR", Part_SetColor, 1}, - {"CHECKPATH", Part_CheckFile, 1}, - {"NULL", NULL, -1} -}; - -int ParsePart(){ - int i; - for (i = 0; parts[i].arg_amount != -1; i++){ - if (strcmpcheck(func, parts[i].name)) - return i; - } - gfx_printf("Parsing error...\nPress any key to continue"); - btn_wait(); - forceExit = true; - printerrors = true; - return -1; -} - -FIL in; -UINT endByte = 0; - -char GetNextByte(){ - char single; - f_read(&in, &single, sizeof(char), &endByte); - - if (sizeof(char) != endByte) - forceExit = true; - - return single; -} - -void ParseScript(char* path){ - char currentchar; - int strlength; - bool inifstatement = false; - forceExit = false; - currentcolor = COLOR_WHITE; - - gfx_clearscreen(); - - res = f_open(&in, path, FA_READ | FA_OPEN_EXISTING); - if (res != FR_OK){ - gfx_errDisplay("ParseScript", res, 1); - return; - } - - printerrors = false; - - while (!forceExit){ - currentchar = GetNextByte(); - - if (endByte == 0 || currentchar == (char)EOF) - break; - - switch(currentchar){ - case '{': - if (!inifstatement) - while (currentchar != '}') - currentchar = GetNextByte(); - - break; - case '}': - if (inifstatement) - inifstatement = false; - - break; - case '<': - strlength = 0; - currentchar = GetNextByte(); - - while (currentchar != '>'){ - func[strlength++] = currentchar; - currentchar = GetNextByte(); - } - func[strlength] = '\0'; - - res = ParsePart(); - if (res == -1) - break; - - for (int i = 0; i < parts[res].arg_amount; i++){ - while (currentchar != 0x22) - currentchar = GetNextByte(); - - strlength = 0; - currentchar = GetNextByte(); - while (currentchar != 0x22){ - args[i][strlength++] = currentchar; - currentchar = GetNextByte(); - } - args[i][strlength] = '\0'; - - if (i < parts[res].arg_amount) - currentchar = GetNextByte(); - } - parts[res].handler(); - break; - case '$': - strlength = 0; - currentchar = GetNextByte(); - - while (currentchar != '$'){ - func[strlength++] = currentchar; - currentchar = GetNextByte(); - } - func[strlength] = '\0'; - - if (strcmpcheck(func, "ERROR") || strcmpcheck(func, "TRUE")){ - inifstatement = (errcode); - } - else if (strcmpcheck(func, "NOERROR") || strcmpcheck(func, "FALSE")){ - inifstatement = (!errcode); - } - else if (strcmpcheck(func, "BTN_POWER")){ - inifstatement = (buttons_pressed & BTN_POWER); - } - else if (strcmpcheck(func, "BTN_VOL+")){ - inifstatement = (buttons_pressed & BTN_VOL_UP); - } - else if (strcmpcheck(func, "BTN_VOL-")){ - inifstatement = (buttons_pressed & BTN_VOL_DOWN); - } - else if (strcmpcheck(func, "EMUMMC")){ - inifstatement = (emu_cfg.enabled); - } - else if (strcmpcheck(func, "NOEMUMMC")){ - inifstatement = (!emu_cfg.enabled); - } - - if (inifstatement) - while(currentchar != '{') - currentchar = GetNextByte(); - - break; - - } - } - - printerrors = true; - f_close(&in); -} \ No newline at end of file diff --git a/source/tegraexplorer/utils/script.h b/source/tegraexplorer/utils/script.h deleted file mode 100644 index 079ca92..0000000 --- a/source/tegraexplorer/utils/script.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#define strcmpcheck(x, y) (!strcmp(x, y)) - -typedef void (*part_handler)(); -typedef struct _script_parts { - char name[11]; - part_handler handler; - short arg_amount; -} script_parts; - -void ParseScript(char* path);