From 9e6a0d5a83b7d917b36ddde4dd4b5c453bd1ca9c Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Mon, 13 Apr 2026 06:34:25 +1000 Subject: [PATCH] updated fileio and collections libs rewrote fileio lib to use structs and methods. i also updated collections lib to fix bugs and be more consistent --- libs/collections/list.c | 86 ++++++------ libs/collections/list.h | 2 + libs/fileio/fileio.c | 289 ++++++++++++++++++++++++++++++++++------ 3 files changed, 293 insertions(+), 84 deletions(-) diff --git a/libs/collections/list.c b/libs/collections/list.c index 77b43dd..7a3361f 100644 --- a/libs/collections/list.c +++ b/libs/collections/list.c @@ -25,9 +25,9 @@ GroundValue appendToListStruct(GroundScope* scope, List args) { ERROR("A field called \"memSize\" was not found", "FieldNotFound"); } - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -48,7 +48,7 @@ GroundValue appendToListStruct(GroundScope* scope, List args) { items = realloc(items, newSize); if (items == NULL) { - ERROR("Failed to allocate memory when increasing list size!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when increasing list size!", "AllocFail"); } ptrField->value.data.intVal = (int64_t)items; @@ -61,7 +61,7 @@ GroundValue appendToListStruct(GroundScope* scope, List args) { GroundValue listStructAt(GroundScope* scope, List args) { - uint64_t index = args.values[0].data.intVal; + int64_t index = args.values[0].data.intVal; if (index < 0) { ERROR("Attempt to access list at negative index", "OutOfBounds"); } @@ -77,9 +77,9 @@ GroundValue listStructAt(GroundScope* scope, List args) { ERROR(buffer, "OutOfBounds"); } - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -102,9 +102,9 @@ GroundValue clearListStruct(GroundScope* scope, List args) { ERROR("A field called \"memSize\" was not found", "FieldNotFound"); } - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundVariable* capacityField = groundFindVariable(scope, "capacity"); @@ -114,7 +114,7 @@ GroundValue clearListStruct(GroundScope* scope, List args) { GroundValue* newBuffer = calloc(STARTING_ELEMENTS, sizeof(GroundValue)); if (newBuffer == NULL) { - ERROR("Failed to allocate memory when clearing list!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when clearing list!", "AllocFail"); } sizeField->value.data.intVal = 0; @@ -127,7 +127,7 @@ GroundValue clearListStruct(GroundScope* scope, List args) { GroundValue insertIntoListStruct(GroundScope* scope, List args) { GroundValue value = args.values[0]; - uint64_t index = args.values[1].data.intVal; + int64_t index = args.values[1].data.intVal; if (index < 0) { ERROR("Attempt to insert element into list at negative index", "OutOfBounds"); } @@ -143,9 +143,9 @@ GroundValue insertIntoListStruct(GroundScope* scope, List args) { ERROR("A field called \"memSize\" was not found", "FieldNotFound"); } - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -172,7 +172,7 @@ GroundValue insertIntoListStruct(GroundScope* scope, List args) { // allocate new buffer GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); if (newBuffer == NULL) { - ERROR("Failed to allocate memory when increasing list size!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when increasing list size!", "AllocFail"); } ptrField->value.data.intVal = (int64_t)newBuffer; memSizeField->value.data.intVal = sizeof(GroundValue) * capacity; @@ -192,7 +192,7 @@ GroundValue insertIntoListStruct(GroundScope* scope, List args) { } GroundValue listStructDelete(GroundScope* scope, List args) { - uint64_t index = args.values[0].data.intVal; + int64_t index = args.values[0].data.intVal; if (index < 0) { ERROR("Attempt to remove element into list at negative index", "OutOfBounds"); } @@ -206,12 +206,12 @@ GroundValue listStructDelete(GroundScope* scope, List args) { GroundVariable* memSizeField = groundFindVariable(scope, "memSize"); if (memSizeField == NULL) { - ERROR("A field called \"memSize\" was not found", "FieldNotFound"); + ERROR("A field called \"memSizvoid initLists(GroundScope* scope);e\" was not found", "FieldNotFound"); } - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -242,7 +242,7 @@ GroundValue listStructDelete(GroundScope* scope, List args) { // allocate new buffer GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); if (newBuffer == NULL) { - ERROR("Failed to allocate memory when decreasing list size!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when decreasing list size!", "AllocFail"); } ptrField->value.data.intVal = (int64_t)newBuffer; memSizeField->value.data.intVal = sizeof(GroundValue) * capacity; @@ -264,7 +264,7 @@ GroundValue listStructDelete(GroundScope* scope, List args) { GroundValue listStructSet(GroundScope* scope, List args) { GroundValue value = args.values[0]; - uint64_t index = args.values[1].data.intVal; + int64_t index = args.values[1].data.intVal; if (index < 0) { ERROR("Attempt to set element in list at negative index", "OutOfBounds"); } @@ -275,9 +275,9 @@ GroundValue listStructSet(GroundScope* scope, List args) { } int64_t size = sizeField->value.data.intVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -338,13 +338,13 @@ GroundValue listStructContains(GroundScope* scope, List args) { } int64_t size = sizeField->value.data.intVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; - for (uint64_t i = 0; i < size; i++) { + for (int64_t i = 0; i < size; i++) { if (areGroundValuesEqual(items[i], targetValue)) { return groundCreateValue(BOOL, true); } @@ -366,15 +366,15 @@ GroundValue reverseListStruct(GroundScope* scope, List args) { } int64_t capacity = capacityField->value.data.intVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); if (newBuffer == NULL) { - ERROR("Failed to allocate memory when reversing list!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when reversing list!", "AllocFail"); } int z = 0; @@ -397,13 +397,13 @@ GroundValue findListStruct(GroundScope* scope, List args) { } int64_t size = sizeField->value.data.intVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; - for (uint64_t i = 0; i < size; i++) { + for (int64_t i = 0; i < size; i++) { if (areGroundValuesEqual(items[i], targetValue)) { return groundCreateValue(INT, i); } @@ -421,9 +421,9 @@ GroundValue reserveListStruct(GroundScope* scope, List args) { } int64_t capacity = capacityField->value.data.intVal; - GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); + GroundVariable* ptrField = groundFindVariable(scope, "ptr"); if (ptrField == NULL) { - ERROR("A field called \"private_ptr\" was not found", "FieldNotFound"); + ERROR("A field called \"ptr\" was not found", "FieldNotFound"); } GroundValue* items = (GroundValue*)ptrField->value.data.intVal; @@ -439,7 +439,7 @@ GroundValue reserveListStruct(GroundScope* scope, List args) { capacityField->value.data.intVal = amount; items = realloc(items, sizeof(GroundValue) * amount); if (items == NULL) { - ERROR("Failed to allocate memory when reserving list space!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory when reserving list space!", "AllocFail"); } memSizeField->value.data.intVal = sizeof(GroundValue) * amount; @@ -448,26 +448,32 @@ GroundValue reserveListStruct(GroundScope* scope, List args) { } GroundValue listStructConstructor(GroundScope* scope, List args) { - GroundValue value = groundCreateValue(CUSTOM, &listStruct); - int64_t startingCapacity = args.values[0].data.intVal; if (startingCapacity < 1) { ERROR("List can't be less than 1 element in capacity on initialization!", "OutOfBounds"); } + return createList(startingCapacity); +} + +GroundValue createList(int64_t initialCapacity) { + GroundValue value = groundCreateValue(CUSTOM, &listStruct); + + + GroundObjectField *sizeField = groundFindField(*value.data.customVal, "size"); GroundObjectField *capacityField = groundFindField(*value.data.customVal, "capacity"); GroundObjectField *memSizeField = groundFindField(*value.data.customVal, "memSize"); - GroundObjectField *ptrField = groundFindField(*value.data.customVal, "private_ptr"); + GroundObjectField *ptrField = groundFindField(*value.data.customVal, "ptr"); GroundValue* items = calloc(STARTING_ELEMENTS, sizeof(GroundValue)); if (items == NULL) { - ERROR("Failed to allocate memory while creating list!", "MemoryAllocationFailed"); + ERROR("Failed to allocate memory while creating list!", "AllocFail"); } sizeField->value.data.intVal = 0; - capacityField->value.data.intVal = startingCapacity; - memSizeField->value.data.intVal = sizeof(GroundValue) * startingCapacity; + capacityField->value.data.intVal = initialCapacity; + memSizeField->value.data.intVal = sizeof(GroundValue) * initialCapacity; ptrField->value.data.intVal = (int64_t)items; value.type = CUSTOM; @@ -480,7 +486,7 @@ void initLists(GroundScope* scope) { groundAddFieldToStruct(&listStruct, "size", groundCreateValue(INT, 0)); // number of elements groundAddFieldToStruct(&listStruct, "memSize", groundCreateValue(INT, sizeof(GroundValue) * STARTING_ELEMENTS)); // number of bytes allocated groundAddFieldToStruct(&listStruct, "capacity", groundCreateValue(INT, STARTING_ELEMENTS)); // number of elements that can fit in the currently allocated space - groundAddFieldToStruct(&listStruct, "private_ptr", groundCreateValue(INT, 0)); // pointer to internal list struct + groundAddFieldToStruct(&listStruct, "ptr", groundCreateValue(INT, 0)); // pointer to internal list struct groundAddFunctionToStruct(&listStruct, "init", listStructConstructor, INT, 1, INT, "startingCapacity"); // init struct (ground constructor) groundAddFunctionToStruct(&listStruct, "append", appendToListStruct, INT, 1, ANY, "value"); // append item to end of list diff --git a/libs/collections/list.h b/libs/collections/list.h index 644ecc3..c032da5 100644 --- a/libs/collections/list.h +++ b/libs/collections/list.h @@ -3,9 +3,11 @@ #include #include +#include extern const uint8_t STARTING_ELEMENTS; +GroundValue createList(int64_t initialCapacity); void initLists(GroundScope* scope); #endif \ No newline at end of file diff --git a/libs/fileio/fileio.c b/libs/fileio/fileio.c index 7aeaeb5..63651ed 100644 --- a/libs/fileio/fileio.c +++ b/libs/fileio/fileio.c @@ -1,57 +1,258 @@ +#include +#include +#include +#include #include #include -#include "groundext.h" +#include +#include +#include -GroundValue native_file_read(GroundScope* scope, List args) { - if (args.size < 1 || args.values[0].type != STRING) { - return groundCreateValue(NONE); +GroundStruct fileStruct = {}; + + + +GroundValue fileStructConstructor(GroundScope* scope, List args) { + GroundValue value = groundCreateValue(CUSTOM, &fileStruct); + char* filePath = args.values[0].data.stringVal; + + // do a check to make sure the file is actually a file first + struct stat st; + if (0 != lstat(filePath, &st)) { + // lstat failed, file probably doesn't exist + char buffer[256]; + sprintf(buffer, "The file \"%s\" does not exist!", filePath); + ERROR(buffer, "FileNotFound"); } - - char* path = args.values[0].data.stringVal; - FILE* f = fopen(path, "r"); - if (!f) { - ERROR("Failed to open file for reading", "FileError"); + + if (S_IFREG != (st.st_mode & S_IFMT)) { + switch (st.st_mode & S_IFMT) { + case S_IFSOCK: + ERROR("Attempt to open socket as file!", "NotAFile"); + case S_IFBLK: + ERROR("Attempt to open block device as file!", "NotAFile"); + case S_IFDIR: + ERROR("Attempt to open directory as file!", "NotAFile"); + case S_IFCHR: + ERROR("Attempt to open character device as file!", "NotAFile"); + case S_IFIFO: + ERROR("Attempt to open FIFO (pipe) as file!", "NotAFile"); + default: + break; + } } - - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - char* content = malloc(fsize + 1); - if (!content) { - fclose(f); - ERROR("Failed to allocate memory for file reading", "FileError"); + + // opens the given file in read and write mode, the file must exist or openning the file will fail + FILE* file = fopen(filePath, "r+"); + + if (file == NULL) { + ERROR("Unkown error while openning file!", "GenericFileError"); } - - fread(content, 1, fsize, f); - fclose(f); - content[fsize] = 0; - - GroundValue val = groundCreateValue(STRING, content); - free(content); - return val; + + // seek to end of file to get size + fseek(file, 0, SEEK_END); + int64_t size = ftell(file); + rewind(file); + + GroundObjectField *handleField = groundFindField(*value.data.customVal, "fileHandle"); + GroundObjectField *sizeField = groundFindField(*value.data.customVal, "size"); + GroundObjectField *filePathField = groundFindField(*value.data.customVal, "filePath"); + + handleField->value.data.intVal = (int64_t)file; + sizeField->value.data.intVal = size; + filePathField->value.data.stringVal = filePath; + + value.type = CUSTOM; + + return value; } -GroundValue native_file_write(GroundScope* scope, List args) { - if (args.size < 2 || args.values[0].type != STRING || args.values[1].type != STRING) { - return groundCreateValue(BOOL, 0); +GroundValue fileStructRead(GroundScope* scope, List args) { + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); } - - char* path = args.values[0].data.stringVal; - char* content = args.values[1].data.stringVal; - - FILE* f = fopen(path, "w"); - if (!f) { - ERROR("Failed to open file for writing", "FileError"); + FILE* file = (FILE*)handleField->value.data.intVal; + + GroundVariable* sizeField = groundFindVariable(scope, "size"); + if (sizeField == NULL) { + ERROR("A field called \"size\" was not found", "FieldNotFound"); } - - fprintf(f, "%s", content); - fclose(f); - - return groundCreateValue(BOOL, 1); + long size = sizeField->value.data.intVal; + + // allocate buffer to read file into + char* buffer = malloc(size + 1); + if (buffer == NULL) { + ERROR("Failed to allocate memory for buffer while reading file!", "AllocFail"); + } + + // read file + size_t readSize = fread(buffer, 1, size, file); + buffer[readSize] = 0; // null terminate buffer + + return groundCreateValue(STRING, buffer); +} + +GroundValue fileStructWrite(GroundScope* scope, List args) { + char* buffer = args.values[0].data.stringVal; + + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); + } + FILE* file = (FILE*)handleField->value.data.intVal; + + GroundVariable* sizeField = groundFindVariable(scope, "size"); + if (sizeField == NULL) { + ERROR("A field called \"size\" was not found", "FieldNotFound"); + } + + GroundVariable* tellField = groundFindVariable(scope, "tell"); + if (tellField == NULL) { + ERROR("A field called \"tell\" was not found", "FieldNotFound"); + } + + ftruncate(fileno(file), 0); + rewind(file); + fprintf(file, "%s", buffer); + + sizeField->value.data.intVal = strlen(buffer); + tellField->value.data.intVal = strlen(buffer); + + return groundCreateValue(INT, 0); +} + +GroundValue fileStructAppend(GroundScope* scope, List args) { + char* buffer = args.values[0].data.stringVal; + + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); + } + FILE* file = (FILE*)handleField->value.data.intVal; + + GroundVariable* sizeField = groundFindVariable(scope, "size"); + if (sizeField == NULL) { + ERROR("A field called \"size\" was not found", "FieldNotFound"); + } + int64_t size = sizeField->value.data.intVal; + + GroundVariable* tellField = groundFindVariable(scope, "tell"); + if (tellField == NULL) { + ERROR("A field called \"tell\" was not found", "FieldNotFound"); + } + + fprintf(file, "%s", buffer); + sizeField->value.data.intVal = size + strlen(buffer); + tellField->value.data.intVal = tellField->value.data.intVal + strlen(buffer); + + return groundCreateValue(INT, 0); +} + +GroundValue fileStructFlush(GroundScope* scope, List args) { + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); + } + FILE* file = (FILE*)handleField->value.data.intVal; + fflush(file); + + return groundCreateValue(INT, 0); +} + +GroundValue fileStructSeek(GroundScope* scope, List args) { + int64_t offset = args.values[0].data.intVal; + if (offset < 0) { + ERROR("Can't seek to negative offset!", "OutOfBounds"); + } + + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); + } + FILE* file = (FILE*)handleField->value.data.intVal; + + GroundVariable* tellField = groundFindVariable(scope, "tell"); + if (tellField == NULL) { + ERROR("A field called \"tell\" was not found", "FieldNotFound"); + } + + GroundVariable* sizeField = groundFindVariable(scope, "size"); + if (sizeField == NULL) { + ERROR("A field called \"size\" was not found", "FieldNotFound"); + } + int64_t size = sizeField->value.data.intVal; + + if (offset >= size) { + ERROR("Attempt to seek past file size!", "OutOfBounds"); + } + + int result = fseek(file, offset, SEEK_SET); + if (result != 0) { + char buffer[100]; + sprintf(buffer, "fseek failed with error code: \"%d\"", result); + ERROR(buffer, "SeekError"); + } + tellField->value.data.intVal = offset; + + return groundCreateValue(INT, 0); +} + +GroundValue fileStructSeekEnd(GroundScope* scope, List args) { + int64_t offset = args.values[0].data.intVal; + if (offset < 0) { + ERROR("Can't seek to negative offset!", "OutOfBounds"); + } + + GroundVariable* handleField = groundFindVariable(scope, "fileHandle"); + if (handleField == NULL) { + ERROR("A field called \"fileHandle\" was not found", "FieldNotFound"); + } + FILE* file = (FILE*)handleField->value.data.intVal; + + GroundVariable* tellField = groundFindVariable(scope, "tell"); + if (tellField == NULL) { + ERROR("A field called \"tell\" was not found", "FieldNotFound"); + } + + GroundVariable* sizeField = groundFindVariable(scope, "size"); + if (sizeField == NULL) { + ERROR("A field called \"size\" was not found", "FieldNotFound"); + } + int64_t size = sizeField->value.data.intVal; + + if (offset >= size) { + ERROR("Attempt to seek past file size!", "OutOfBounds"); + } + + int result = fseek(file, offset, SEEK_END); + if (result != 0) { + char buffer[100]; + sprintf(buffer, "fseek failed with error code: \"%d\"", result); + ERROR(buffer, "SeekError"); + } + + tellField->value.data.intVal = size - offset; + + return groundCreateValue(INT, 0); } void ground_init(GroundScope* scope) { - groundAddNativeFunction(scope, "file_Read", native_file_read, STRING, 1, STRING, "path"); - groundAddNativeFunction(scope, "file_Write", native_file_write, BOOL, 2, STRING, "path", STRING, "content"); -} + fileStruct = groundCreateStruct(); + + groundAddFieldToStruct(&fileStruct, "fileHandle", groundCreateValue(INT, 0)); + groundAddFieldToStruct(&fileStruct, "filePath", groundCreateValue(STRING, "")); + groundAddFieldToStruct(&fileStruct, "size", groundCreateValue(INT, 0)); + groundAddFieldToStruct(&fileStruct, "tell", groundCreateValue(INT, 0)); + + groundAddFunctionToStruct(&fileStruct, "read", fileStructRead, STRING, 0); // reads the file and returns the contents as a string + // readLines function implemented in solstice + groundAddFunctionToStruct(&fileStruct, "write", fileStructWrite, INT, 1, STRING, "buffer"); // wipes the file before writing the buffer to the file + groundAddFunctionToStruct(&fileStruct, "append", fileStructAppend, INT, 1, STRING, "buffer"); // appends the buffer to end of the contents in the file + groundAddFunctionToStruct(&fileStruct, "flush", fileStructFlush, INT, 0); // flush file buffer (not THAT useful tbh) + groundAddFunctionToStruct(&fileStruct, "seek", fileStructSeek, INT, 1, INT, "offset"); // jump to offset relative to start of file + groundAddFunctionToStruct(&fileStruct, "seekEnd", fileStructSeekEnd, INT, 1, INT, "offset"); // jump to offset relative to end of file + + groundAddNativeFunction(scope, "openFile", fileStructConstructor, CUSTOM, 1, STRING, "filePath"); + groundAddNativeFunction(scope, "File_SOLS_CONSTRUCTOR", fileStructConstructor, CUSTOM, 1, STRING, "filePath"); +} \ No newline at end of file