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
This commit is contained in:
2026-04-13 06:34:25 +10:00
parent aa0c71a47b
commit 9e6a0d5a83
3 changed files with 293 additions and 84 deletions

View File

@@ -25,9 +25,9 @@ GroundValue appendToListStruct(GroundScope* scope, List args) {
ERROR("A field called \"memSize\" was not found", "FieldNotFound"); ERROR("A field called \"memSize\" was not found", "FieldNotFound");
} }
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* items = (GroundValue*)ptrField->value.data.intVal;
@@ -48,7 +48,7 @@ GroundValue appendToListStruct(GroundScope* scope, List args) {
items = realloc(items, newSize); items = realloc(items, newSize);
if (items == NULL) { 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; ptrField->value.data.intVal = (int64_t)items;
@@ -61,7 +61,7 @@ GroundValue appendToListStruct(GroundScope* scope, List args) {
GroundValue listStructAt(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) { if (index < 0) {
ERROR("Attempt to access list at negative index", "OutOfBounds"); ERROR("Attempt to access list at negative index", "OutOfBounds");
} }
@@ -77,9 +77,9 @@ GroundValue listStructAt(GroundScope* scope, List args) {
ERROR(buffer, "OutOfBounds"); ERROR(buffer, "OutOfBounds");
} }
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* 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"); ERROR("A field called \"memSize\" was not found", "FieldNotFound");
} }
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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"); GroundVariable* capacityField = groundFindVariable(scope, "capacity");
@@ -114,7 +114,7 @@ GroundValue clearListStruct(GroundScope* scope, List args) {
GroundValue* newBuffer = calloc(STARTING_ELEMENTS, sizeof(GroundValue)); GroundValue* newBuffer = calloc(STARTING_ELEMENTS, sizeof(GroundValue));
if (newBuffer == NULL) { 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; sizeField->value.data.intVal = 0;
@@ -127,7 +127,7 @@ GroundValue clearListStruct(GroundScope* scope, List args) {
GroundValue insertIntoListStruct(GroundScope* scope, List args) { GroundValue insertIntoListStruct(GroundScope* scope, List args) {
GroundValue value = args.values[0]; GroundValue value = args.values[0];
uint64_t index = args.values[1].data.intVal; int64_t index = args.values[1].data.intVal;
if (index < 0) { if (index < 0) {
ERROR("Attempt to insert element into list at negative index", "OutOfBounds"); 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"); ERROR("A field called \"memSize\" was not found", "FieldNotFound");
} }
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* items = (GroundValue*)ptrField->value.data.intVal;
@@ -172,7 +172,7 @@ GroundValue insertIntoListStruct(GroundScope* scope, List args) {
// allocate new buffer // allocate new buffer
GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue));
if (newBuffer == NULL) { 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; ptrField->value.data.intVal = (int64_t)newBuffer;
memSizeField->value.data.intVal = sizeof(GroundValue) * capacity; memSizeField->value.data.intVal = sizeof(GroundValue) * capacity;
@@ -192,7 +192,7 @@ GroundValue insertIntoListStruct(GroundScope* scope, List args) {
} }
GroundValue listStructDelete(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) { if (index < 0) {
ERROR("Attempt to remove element into list at negative index", "OutOfBounds"); 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"); GroundVariable* memSizeField = groundFindVariable(scope, "memSize");
if (memSizeField == NULL) { 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) { 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* items = (GroundValue*)ptrField->value.data.intVal;
@@ -242,7 +242,7 @@ GroundValue listStructDelete(GroundScope* scope, List args) {
// allocate new buffer // allocate new buffer
GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue));
if (newBuffer == NULL) { 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; ptrField->value.data.intVal = (int64_t)newBuffer;
memSizeField->value.data.intVal = sizeof(GroundValue) * capacity; memSizeField->value.data.intVal = sizeof(GroundValue) * capacity;
@@ -264,7 +264,7 @@ GroundValue listStructDelete(GroundScope* scope, List args) {
GroundValue listStructSet(GroundScope* scope, List args) { GroundValue listStructSet(GroundScope* scope, List args) {
GroundValue value = args.values[0]; GroundValue value = args.values[0];
uint64_t index = args.values[1].data.intVal; int64_t index = args.values[1].data.intVal;
if (index < 0) { if (index < 0) {
ERROR("Attempt to set element in list at negative index", "OutOfBounds"); 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; int64_t size = sizeField->value.data.intVal;
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* items = (GroundValue*)ptrField->value.data.intVal;
@@ -338,13 +338,13 @@ GroundValue listStructContains(GroundScope* scope, List args) {
} }
int64_t size = sizeField->value.data.intVal; int64_t size = sizeField->value.data.intVal;
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* 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)) { if (areGroundValuesEqual(items[i], targetValue)) {
return groundCreateValue(BOOL, true); return groundCreateValue(BOOL, true);
} }
@@ -366,15 +366,15 @@ GroundValue reverseListStruct(GroundScope* scope, List args) {
} }
int64_t capacity = capacityField->value.data.intVal; int64_t capacity = capacityField->value.data.intVal;
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* items = (GroundValue*)ptrField->value.data.intVal;
GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue)); GroundValue* newBuffer = calloc(capacity, sizeof(GroundValue));
if (newBuffer == NULL) { if (newBuffer == NULL) {
ERROR("Failed to allocate memory when reversing list!", "MemoryAllocationFailed"); ERROR("Failed to allocate memory when reversing list!", "AllocFail");
} }
int z = 0; int z = 0;
@@ -397,13 +397,13 @@ GroundValue findListStruct(GroundScope* scope, List args) {
} }
int64_t size = sizeField->value.data.intVal; int64_t size = sizeField->value.data.intVal;
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* 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)) { if (areGroundValuesEqual(items[i], targetValue)) {
return groundCreateValue(INT, i); return groundCreateValue(INT, i);
} }
@@ -421,9 +421,9 @@ GroundValue reserveListStruct(GroundScope* scope, List args) {
} }
int64_t capacity = capacityField->value.data.intVal; int64_t capacity = capacityField->value.data.intVal;
GroundVariable* ptrField = groundFindVariable(scope, "private_ptr"); GroundVariable* ptrField = groundFindVariable(scope, "ptr");
if (ptrField == NULL) { 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* items = (GroundValue*)ptrField->value.data.intVal;
@@ -439,7 +439,7 @@ GroundValue reserveListStruct(GroundScope* scope, List args) {
capacityField->value.data.intVal = amount; capacityField->value.data.intVal = amount;
items = realloc(items, sizeof(GroundValue) * amount); items = realloc(items, sizeof(GroundValue) * amount);
if (items == NULL) { 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; memSizeField->value.data.intVal = sizeof(GroundValue) * amount;
@@ -448,26 +448,32 @@ GroundValue reserveListStruct(GroundScope* scope, List args) {
} }
GroundValue listStructConstructor(GroundScope* scope, List args) { GroundValue listStructConstructor(GroundScope* scope, List args) {
GroundValue value = groundCreateValue(CUSTOM, &listStruct);
int64_t startingCapacity = args.values[0].data.intVal; int64_t startingCapacity = args.values[0].data.intVal;
if (startingCapacity < 1) { if (startingCapacity < 1) {
ERROR("List can't be less than 1 element in capacity on initialization!", "OutOfBounds"); 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 *sizeField = groundFindField(*value.data.customVal, "size");
GroundObjectField *capacityField = groundFindField(*value.data.customVal, "capacity"); GroundObjectField *capacityField = groundFindField(*value.data.customVal, "capacity");
GroundObjectField *memSizeField = groundFindField(*value.data.customVal, "memSize"); 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)); GroundValue* items = calloc(STARTING_ELEMENTS, sizeof(GroundValue));
if (items == NULL) { 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; sizeField->value.data.intVal = 0;
capacityField->value.data.intVal = startingCapacity; capacityField->value.data.intVal = initialCapacity;
memSizeField->value.data.intVal = sizeof(GroundValue) * startingCapacity; memSizeField->value.data.intVal = sizeof(GroundValue) * initialCapacity;
ptrField->value.data.intVal = (int64_t)items; ptrField->value.data.intVal = (int64_t)items;
value.type = CUSTOM; value.type = CUSTOM;
@@ -480,7 +486,7 @@ void initLists(GroundScope* scope) {
groundAddFieldToStruct(&listStruct, "size", groundCreateValue(INT, 0)); // number of elements groundAddFieldToStruct(&listStruct, "size", groundCreateValue(INT, 0)); // number of elements
groundAddFieldToStruct(&listStruct, "memSize", groundCreateValue(INT, sizeof(GroundValue) * STARTING_ELEMENTS)); // number of bytes allocated 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, "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, "init", listStructConstructor, INT, 1, INT, "startingCapacity"); // init struct (ground constructor)
groundAddFunctionToStruct(&listStruct, "append", appendToListStruct, INT, 1, ANY, "value"); // append item to end of list groundAddFunctionToStruct(&listStruct, "append", appendToListStruct, INT, 1, ANY, "value"); // append item to end of list

View File

@@ -3,9 +3,11 @@
#include <groundext.h> #include <groundext.h>
#include <groundvm.h> #include <groundvm.h>
#include <stddef.h>
extern const uint8_t STARTING_ELEMENTS; extern const uint8_t STARTING_ELEMENTS;
GroundValue createList(int64_t initialCapacity);
void initLists(GroundScope* scope); void initLists(GroundScope* scope);
#endif #endif

View File

@@ -1,57 +1,258 @@
#include <groundext.h>
#include <groundvm.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "groundext.h" #include <string.h>
#include <sys/stat.h>
#include <unistd.h>
GroundValue native_file_read(GroundScope* scope, List args) { GroundStruct fileStruct = {};
if (args.size < 1 || args.values[0].type != STRING) {
return groundCreateValue(NONE);
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; if (S_IFREG != (st.st_mode & S_IFMT)) {
FILE* f = fopen(path, "r"); switch (st.st_mode & S_IFMT) {
if (!f) { case S_IFSOCK:
ERROR("Failed to open file for reading", "FileError"); 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); // opens the given file in read and write mode, the file must exist or openning the file will fail
long fsize = ftell(f); FILE* file = fopen(filePath, "r+");
fseek(f, 0, SEEK_SET);
char* content = malloc(fsize + 1); if (file == NULL) {
if (!content) { ERROR("Unkown error while openning file!", "GenericFileError");
fclose(f);
ERROR("Failed to allocate memory for file reading", "FileError");
} }
fread(content, 1, fsize, f); // seek to end of file to get size
fclose(f); fseek(file, 0, SEEK_END);
content[fsize] = 0; int64_t size = ftell(file);
rewind(file);
GroundValue val = groundCreateValue(STRING, content); GroundObjectField *handleField = groundFindField(*value.data.customVal, "fileHandle");
free(content); GroundObjectField *sizeField = groundFindField(*value.data.customVal, "size");
return val; 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) { GroundValue fileStructRead(GroundScope* scope, List args) {
if (args.size < 2 || args.values[0].type != STRING || args.values[1].type != STRING) { GroundVariable* handleField = groundFindVariable(scope, "fileHandle");
return groundCreateValue(BOOL, 0); 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");
}
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");
} }
char* path = args.values[0].data.stringVal; // read file
char* content = args.values[1].data.stringVal; size_t readSize = fread(buffer, 1, size, file);
buffer[readSize] = 0; // null terminate buffer
FILE* f = fopen(path, "w"); return groundCreateValue(STRING, buffer);
if (!f) { }
ERROR("Failed to open file for writing", "FileError");
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");
} }
fprintf(f, "%s", content); GroundVariable* tellField = groundFindVariable(scope, "tell");
fclose(f); if (tellField == NULL) {
ERROR("A field called \"tell\" was not found", "FieldNotFound");
}
return groundCreateValue(BOOL, 1); 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) { void ground_init(GroundScope* scope) {
groundAddNativeFunction(scope, "file_Read", native_file_read, STRING, 1, STRING, "path"); fileStruct = groundCreateStruct();
groundAddNativeFunction(scope, "file_Write", native_file_write, BOOL, 2, STRING, "path", STRING, "content");
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");
} }