Hooked runner's drive system into the engine paths

This commit is contained in:
2023-01-27 06:24:31 +00:00
parent 894861aaf1
commit fcefc4c5b0
8 changed files with 166 additions and 114 deletions

View File

@@ -8,6 +8,8 @@
#include "toy_console_colors.h"
#include "lib_runner.h"
//errors here should be fatal
static void fatalError(char* message) {
fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
@@ -84,17 +86,26 @@ static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
}
//extract the arguments
Toy_Literal fname = Toy_popLiteralArray(arguments);
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
Toy_Literal fnameIdn = fname;
if (TOY_IS_IDENTIFIER(fname) && Toy_parseIdentifierToValue(interpreter, &fname)) {
Toy_freeLiteral(fnameIdn);
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
Toy_freeLiteral(drivePathLiteralIdn);
}
//check argument types
if (!TOY_IS_STRING(fname)) {
if (!TOY_IS_STRING(drivePathLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to loadRootNode\n");
Toy_freeLiteral(fname);
Toy_freeLiteral(drivePathLiteral);
return -1;
}
Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral);
Toy_freeLiteral(drivePathLiteral); //not needed anymore
if (!TOY_IS_STRING(filePathLiteral)) {
Toy_freeLiteral(filePathLiteral);
return -1;
}
@@ -110,7 +121,7 @@ static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
//load the new root node
size_t size = 0;
char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(fname)), &size);
char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(filePathLiteral)), &size);
unsigned char* tb = Toy_compileString(source, &size);
free((void*)source);
@@ -142,7 +153,7 @@ static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
//cleanup
Toy_freeLiteralArray(&inner.stack);
Toy_freeLiteralArray(&inner.literalCache);
Toy_freeLiteral(fname);
Toy_freeLiteral(filePathLiteral);
return 0;
}

View File

@@ -7,6 +7,8 @@
#include "toy_literal_array.h"
#include "toy_memory.h"
#include "lib_runner.h"
#include <stdlib.h>
static int nativeLoadNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
@@ -16,23 +18,27 @@ static int nativeLoadNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
}
//extract the arguments
Toy_Literal fname = Toy_popLiteralArray(arguments);
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
Toy_Literal fnameIdn = fname;
if (TOY_IS_IDENTIFIER(fname) && Toy_parseIdentifierToValue(interpreter, &fname)) {
Toy_freeLiteral(fnameIdn);
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
Toy_freeLiteral(drivePathLiteralIdn);
}
//check argument types
if (!TOY_IS_STRING(fname)) {
if (!TOY_IS_STRING(drivePathLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to loadNode\n");
Toy_freeLiteral(fname);
Toy_freeLiteral(drivePathLiteral);
return -1;
}
Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral);
Toy_freeLiteral(drivePathLiteral); //not needed anymore
//load the new node
size_t size = 0;
char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(fname)), &size);
char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(filePathLiteral)), &size);
unsigned char* tb = Toy_compileString(source, &size);
free((void*)source);
@@ -65,7 +71,7 @@ static int nativeLoadNode(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
//cleanup
Toy_freeLiteralArray(&inner.stack);
Toy_freeLiteralArray(&inner.literalCache);
Toy_freeLiteral(fname);
Toy_freeLiteral(filePathLiteral);
Toy_freeLiteral(nodeLiteral);
return 1;

View File

@@ -24,69 +24,34 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
return -1;
}
//get the argument
//get the file path literal with a handle
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral));
Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral);
//get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library
int driveLength = 0;
while (Toy_toCString(drivePath)[driveLength] != ':') {
if (driveLength >= Toy_lengthRefString(drivePath)) {
interpreter->errorOutput("Incorrect drive path format given to loadScript\n");
Toy_deleteRefString(drivePath);
Toy_freeLiteral(drivePathLiteral);
return -1;
}
driveLength++;
}
Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength);
Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength );
//get the real drive file path
Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral);
if (!TOY_IS_STRING(realDriveLiteral)) {
interpreter->errorOutput("Incorrect literal type found for drive: ");
Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
interpreter->errorOutput("\n");
Toy_freeLiteral(realDriveLiteral);
Toy_freeLiteral(driveLiteral);
Toy_deleteRefString(path);
Toy_deleteRefString(drivePath);
if (TOY_IS_NULL(filePathLiteral)) {
Toy_freeLiteral(filePathLiteral);
Toy_freeLiteral(drivePathLiteral);
return -1;
}
//get the final real file path (concat) TODO: move this concat to refstring library
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
//clean up the drivepath stuff
Toy_deleteRefString(realDrive);
Toy_freeLiteral(realDriveLiteral);
Toy_freeLiteral(driveLiteral);
Toy_deleteRefString(path);
Toy_deleteRefString(drivePath);
Toy_freeLiteral(drivePathLiteral);
//use raw types - easier
char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
int filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
//check for file extensions
if (!(filePath[realLength - 5] == '.' && filePath[realLength - 4] == 't' && filePath[realLength - 3] == 'o' && filePath[realLength - 2] == 'y')) {
if (!(filePath[filePathLength - 5] == '.' && filePath[filePathLength - 4] == 't' && filePath[filePathLength - 3] == 'o' && filePath[filePathLength - 2] == 'y')) {
interpreter->errorOutput("Bad script file extension (expected .toy)\n");
TOY_FREE_ARRAY(char, filePath, realLength);
Toy_freeLiteral(filePathLiteral);
return -1;
}
//check for break-out attempts
for (int i = 0; i < realLength - 1; i++) {
for (int i = 0; i < filePathLength - 1; i++) {
if (filePath[i] == '.' && filePath[i + 1] == '.') {
interpreter->errorOutput("Parent directory access not allowed\n");
TOY_FREE_ARRAY(char, filePath, realLength);
Toy_freeLiteral(filePathLiteral);
return -1;
}
}
@@ -97,6 +62,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
if (!source) {
interpreter->errorOutput("Failed to load source file\n");
Toy_freeLiteral(filePathLiteral);
return -1;
}
@@ -105,6 +71,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
if (!bytecode) {
interpreter->errorOutput("Failed to compile source file\n");
Toy_freeLiteral(filePathLiteral);
return -1;
}
@@ -124,7 +91,8 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
TOY_FREE_ARRAY(char, filePath, realLength);
//free the drive path
Toy_freeLiteral(filePathLiteral);
return 1;
}
@@ -610,4 +578,65 @@ void Toy_freeDriveDictionary() {
Toy_LiteralDictionary* Toy_getDriveDictionary() {
return &Toy_driveDictionary;
}
Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* drivePathLiteral) {
//check argument types
if (!TOY_IS_STRING(*drivePathLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to Toy_getFilePathLiteral\n");
return TOY_TO_NULL_LITERAL;
}
Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(*drivePathLiteral));
//get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library
int driveLength = 0;
while (Toy_toCString(drivePath)[driveLength] != ':') {
if (driveLength >= Toy_lengthRefString(drivePath)) {
interpreter->errorOutput("Incorrect drive path format given to Toy_getFilePathLiteral\n");
return TOY_TO_NULL_LITERAL;
}
driveLength++;
}
Toy_RefString* drive = Toy_createRefStringLength(Toy_toCString(drivePath), driveLength);
Toy_RefString* path = Toy_createRefStringLength( &Toy_toCString(drivePath)[driveLength + 1], Toy_lengthRefString(drivePath) - driveLength );
//get the real drive file path
Toy_Literal driveLiteral = TOY_TO_STRING_LITERAL(drive); //NOTE: driveLiteral takes ownership of the refString
Toy_Literal realDriveLiteral = Toy_getLiteralDictionary(Toy_getDriveDictionary(), driveLiteral);
if (!TOY_IS_STRING(realDriveLiteral)) {
interpreter->errorOutput("Incorrect literal type found for drive: ");
Toy_printLiteralCustom(realDriveLiteral, interpreter->errorOutput);
interpreter->errorOutput("\n");
Toy_freeLiteral(realDriveLiteral);
Toy_freeLiteral(driveLiteral);
Toy_deleteRefString(path);
Toy_deleteRefString(drivePath);
return TOY_TO_NULL_LITERAL;
}
//get the final real file path (concat) TODO: move this concat to refstring library
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
//clean up the drivepath stuff
Toy_deleteRefString(realDrive);
Toy_freeLiteral(realDriveLiteral);
Toy_freeLiteral(driveLiteral);
Toy_deleteRefString(path);
Toy_deleteRefString(drivePath);
Toy_Literal result = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(filePath, realLength));
TOY_FREE_ARRAY(char, filePath, realLength + 1);
return result;
}

View File

@@ -10,3 +10,6 @@ void Toy_freeDriveDictionary();
Toy_LiteralDictionary* Toy_getDriveDictionary();
#define TOY_OPAQUE_TAG_RUNNER 100
//file system API - for use with other libs
Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* drivePathLiteral);