1
0
Fork 0
mirror of https://github.com/suchmememanyskill/TegraExplorer.git synced 2024-11-26 22:02:08 +00:00
TegraExplorer/source/tegraexplorer/script/parser.c

310 lines
6.6 KiB
C
Raw Normal View History

2020-03-30 19:15:07 +01:00
#include <string.h>
#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"
2020-03-31 13:24:34 +01:00
#include "parser.h"
2020-03-30 19:15:07 +01:00
#include "../common/common.h"
#include "../fs/fsactions.h"
2020-03-31 13:24:34 +01:00
#include "functions.h"
#include "variables.h"
2020-04-01 12:57:25 +01:00
#include "../fs/fsreader.h"
2020-04-03 18:07:42 +01:00
#include "../utils/utils.h"
2020-03-30 19:15:07 +01:00
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;
}
}
2020-03-30 19:15:07 +01:00
if (in[i] == target)
count++;
}
return count;
}
char **argv = NULL;
u32 argc;
2020-03-30 19:15:07 +01:00
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;
}
2020-03-30 19:15:07 +01:00
2020-03-31 21:01:20 +01:00
/*
if (argv != NULL) {
for (i = 0; argv[i] != NULL; i++)
free(argv[i]);
free(argv);
2020-03-30 19:15:07 +01:00
}
2020-03-31 21:01:20 +01:00
*/
2020-03-30 19:15:07 +01:00
argv = calloc(count + 1, sizeof(char*));
2020-03-30 19:15:07 +01:00
for (i = 0; i < count; i++)
argv[i] = calloc(96, sizeof(char));
2020-03-30 19:15:07 +01:00
for (i = 0; i < len && curcount < count; i++) {
if (in[i] == ',') {
curcount++;
current = 0;
}
2020-03-31 16:58:09 +01:00
else if (in[i] == '@' || in[i] == '$' || in[i] == '?') {
2020-03-30 19:15:07 +01:00
while (in[i] != ',' && in[i] != ' ' && in[i] != ')' && i < len) {
argv[curcount][current++] = in[i++];
2020-03-30 19:15:07 +01:00
}
i--;
}
else if ((in[i] >= '0' && in[i] <= '9') || (in[i] >= '<' && in[i] <= '>') || in[i] == '+' || in[i] == '-' || in[i] == '*' || in[i] == '/')
argv[curcount][current++] = in[i];
2020-03-30 19:15:07 +01:00
else if (in[i] == '"') {
i++;
while (in[i] != '"') {
argv[curcount][current++] = in[i++];
2020-03-30 19:15:07 +01:00
}
}
}
return count;
}
FIL scriptin;
UINT endByte = 0;
int forceExit = false;
char currentchar = 0;
char getnextchar(){
f_read(&scriptin, &currentchar, sizeof(char), &endByte);
if (sizeof(char) != endByte)
forceExit = true;
//gfx_printf("|%c|", currentchar);
2020-03-30 19:15:07 +01:00
return currentchar;
}
void getfollowingchar(char end){
while (currentchar != end && !f_eof(&scriptin)){
2020-03-30 19:15:07 +01:00
if (currentchar == '"'){
while (getnextchar() != '"' && !f_eof(&scriptin));
2020-03-30 19:15:07 +01:00
}
getnextchar();
2020-03-30 19:15:07 +01:00
}
}
void getnextvalidchar(){
2020-03-31 16:58:09 +01:00
while ((!((currentchar >= '?' && currentchar <= 'Z') || (currentchar >= 'a' && currentchar <= 'z') || currentchar == '#') && !f_eof(&scriptin)) /*|| currentchar == ';' */)
2020-03-30 19:15:07 +01:00
getnextchar();
}
2020-03-30 23:09:23 +01:00
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){
2020-03-30 23:09:23 +01:00
FSIZE_t offset, size;
offset = f_tell(&scriptin);
getfollowingchar(end);
size = f_tell(&scriptin) - offset;
2020-03-31 23:17:45 +01:00
if (size <= 0)
return NULL;
2020-03-30 23:09:23 +01:00
f_lseek(&scriptin, offset - 1);
return makestr((u32)size, ignore);
}
2020-03-31 13:24:34 +01:00
char *funcbuff = NULL;
void functionparser(){
2020-03-30 19:15:07 +01:00
char *unsplitargs;
2020-03-31 21:01:20 +01:00
/*
2020-03-31 13:24:34 +01:00
if (funcbuff != NULL)
free(funcbuff);
2020-03-31 21:01:20 +01:00
*/
2020-03-31 13:24:34 +01:00
funcbuff = readtilchar('(', ' ');
2020-03-30 23:09:23 +01:00
2020-03-30 19:15:07 +01:00
getfollowingchar('(');
getnextchar();
2020-03-30 23:09:23 +01:00
unsplitargs = readtilchar(')', 0);
2020-03-30 19:15:07 +01:00
2020-03-31 23:17:45 +01:00
if (unsplitargs != NULL){
argc = splitargs(unsplitargs);
getnextchar();
}
else {
argc = 0;
}
2020-03-30 23:09:23 +01:00
getnextchar();
2020-03-30 19:15:07 +01:00
free(unsplitargs);
}
char *gettargetvar(){
char *variable = NULL;
2020-03-30 23:09:23 +01:00
variable = readtilchar('=', ' ');
getfollowingchar('=');
getnextchar();
return variable;
}
void mainparser(){
char *variable = NULL;
2020-03-31 13:24:34 +01:00
int res, out = 0;
getnextvalidchar();
if (f_eof(&scriptin))
return;
if (currentchar == '#'){
getfollowingchar('\n');
return;
}
if (currentchar == '@'){
variable = gettargetvar();
getnextvalidchar();
}
/*
2020-03-31 16:58:09 +01:00
if (currentchar == '?'){
char *jumpname;
jumpname = readtilchar(';', ' ');
getnextchar();
str_jmp_add(jumpname, f_tell(&scriptin));
getfollowingchar('\n');
return;
}
*/
2020-03-31 16:58:09 +01:00
functionparser();
2020-03-31 13:24:34 +01:00
res = run_function(funcbuff, &out);
if (res < 0){
printerrors = true;
2020-03-31 23:17:45 +01:00
//gfx_printf("%s|%s|%d", funcbuff, argv[0], argc);
//btn_wait();
2020-03-31 21:01:20 +01:00
gfx_errDisplay("mainparser", ERR_PARSE_FAIL, f_tell(&scriptin));
forceExit = true;
2020-03-31 16:58:09 +01:00
//gfx_printf("Func: %s\nArg1: %s\n", funcbuff, argv[0]);
}
else {
str_int_add("@RESULT", out);
2020-03-31 13:24:34 +01:00
if (variable != NULL)
str_int_add(variable, out);
}
2020-03-31 13:24:34 +01:00
//gfx_printf("\nGoing to next func %c\n", currentchar);
2020-03-31 21:01:20 +01:00
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);
}
}
2020-03-31 13:24:34 +01:00
void skipbrackets(){
u32 bracketcounter = 0;
getfollowingchar('{');
getnextchar();
while ((currentchar != '}' || bracketcounter != 0) && !f_eof(&scriptin)){
2020-03-31 13:24:34 +01:00
if (currentchar == '{')
bracketcounter++;
else if (currentchar == '}')
bracketcounter--;
getnextchar();
}
}
2020-03-31 23:17:45 +01:00
extern u32 currentcolor;
2020-04-01 12:57:25 +01:00
extern char *currentpath;
2020-04-01 15:48:36 +01:00
void runScript(char *path){
2020-03-30 19:15:07 +01:00
int res;
2020-04-03 18:07:42 +01:00
char *path_local = NULL;
forceExit = false;
2020-03-31 21:01:20 +01:00
currentchar = 0;
2020-03-31 23:17:45 +01:00
currentcolor = COLOR_WHITE;
2020-03-30 19:15:07 +01:00
gfx_clearscreen();
2020-04-03 18:07:42 +01:00
utils_copystring(path, &path_local);
2020-03-30 19:15:07 +01:00
res = f_open(&scriptin, path, FA_READ | FA_OPEN_EXISTING);
if (res != FR_OK){
gfx_errDisplay("ParseScript", res, 1);
return;
}
2020-03-31 23:17:45 +01:00
printerrors = false;
2020-03-31 13:24:34 +01:00
//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);
2020-04-01 12:57:25 +01:00
str_str_add("$CURRENTPATH", currentpath);
2020-03-30 19:15:07 +01:00
2020-03-31 21:01:20 +01:00
//str_int_printall();
2020-03-30 19:15:07 +01:00
while (!f_eof(&scriptin) && !forceExit){
mainparser();
}
2020-03-30 19:15:07 +01:00
2020-03-31 13:24:34 +01:00
printerrors = true;
//str_int_printall();
f_close(&scriptin);
2020-03-31 13:24:34 +01:00
str_int_clear();
//str_jmp_clear();
2020-03-31 19:13:39 +01:00
str_str_clear();
2020-04-03 18:07:42 +01:00
free(path_local);
2020-03-31 23:17:45 +01:00
//btn_wait();
2020-03-30 19:15:07 +01:00
}