#include "scripting.h" void handle_tcc_error(void* opaque, const char* msg) { TraceLog(LOG_ERROR, msg); } void initScripting(SldjScripting* scripting) { *scripting = (SldjScripting){ .state = NULL, .lineScanner = NULL, .loadContext = NULL, .fileBuf = NULL, .fileSize = 0 }; } void compileScript(SldjScripting* scripting, const char filePath[SLDJ_NAMEMAX]) { scripting->lineScanner = NULL; scripting->loadContext = NULL; // Get file size. struct stat fileState; if (stat(filePath, &fileState) < 0) { TraceLog(LOG_ERROR, strerror(errno)); return; } scripting->fileSize = fileState.st_size; // Load file information into a buffer. if (scripting->fileBuf == NULL) { scripting->fileBuf = (char*)malloc(scripting->fileSize); } else { scripting->fileBuf = (char*)realloc(scripting->fileBuf, scripting->fileSize); } if (scripting->fileBuf == NULL) { TraceLog(LOG_ERROR, strerror(errno)); return; } FILE* file = fopen(filePath, "r"); if (file == NULL) { TraceLog(LOG_ERROR, strerror(errno)); return; } fread(scripting->fileBuf, scripting->fileSize, 1, file); scripting->fileBuf[scripting->fileSize - 1] = '\0'; fclose(file); // Setup compiler. if (scripting->state != NULL) { tcc_delete(scripting->state); } scripting->state = tcc_new(); if (scripting->state == NULL) { TraceLog(LOG_ERROR, "Could not open tcc state"); return; } tcc_set_error_func(scripting->state, stderr, handle_tcc_error); tcc_set_output_type(scripting->state, TCC_OUTPUT_MEMORY); tcc_add_library_path(scripting->state, "./"); tcc_add_library(scripting->state, "libsldj"); // Compile. if (tcc_compile_string(scripting->state, scripting->fileBuf) < 0) { return; } if (tcc_relocate(scripting->state) < 0) { return; } scripting->lineScanner = tcc_get_symbol(scripting->state, "lineScanner"); scripting->loadContext = tcc_get_symbol(scripting->state, "loadContext"); } void closeScripting(SldjScripting* scripting) { if (scripting->state != NULL) { tcc_delete(scripting->state); } if (scripting->fileBuf != NULL) { free(scripting->fileBuf); } }