mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
removed HAL
This commit is contained in:
@@ -1,71 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// Enumeration of all file-related error codes
|
|
||||||
typedef enum hal_file_code {
|
|
||||||
HAL_SUCCESS, // Operation was successful
|
|
||||||
HAL_ERROR_INIT, // Error during initialization
|
|
||||||
HAL_ERROR_ALLOC, // Memory allocation error
|
|
||||||
HAL_ERROR_OPEN, // Error while opening a file
|
|
||||||
HAL_ERROR_INPUT, // Invalid input parameter(s)
|
|
||||||
HAL_ERROR_READ, // Error while reading from a file
|
|
||||||
HAL_ERROR_WRITE, // Error while writing to a file
|
|
||||||
HAL_ERROR_CLOSE, // Error while closing a file
|
|
||||||
HAL_ERROR_RENAME, // Error while renaming a file
|
|
||||||
HAL_ERROR_REMOVE, // Error while removing (deleting) a file
|
|
||||||
HAL_ERROR_TEARDOWN, // Error during teardown
|
|
||||||
HAL_ERROR_MAX, // Maximum error code value (used for range checking)
|
|
||||||
} hal_file_code;
|
|
||||||
|
|
||||||
// Forward declaration of the implementation defined file structure
|
|
||||||
typedef struct hal_file_type hal_file;
|
|
||||||
|
|
||||||
// Structure for different file operation functions
|
|
||||||
typedef struct hal_file_operations {
|
|
||||||
// Function: setup
|
|
||||||
// Initialize the file handling system.
|
|
||||||
// Returns: HAL_SUCCESS on successful initialization, or appropriate error code on failure.
|
|
||||||
hal_file_code (*setup)();
|
|
||||||
|
|
||||||
// Function: open
|
|
||||||
// Open a file with the specified filename and mode.
|
|
||||||
// Returns: HAL_SUCCESS on successful read, or appropriate error code on failure.
|
|
||||||
hal_file_code (*open)(hal_file** file, const char* filename, const char* mode);
|
|
||||||
|
|
||||||
// Function: read
|
|
||||||
// Read data from the file into the provided buffer.
|
|
||||||
// Returns: HAL_SUCCESS on successful read, or appropriate error code on failure.
|
|
||||||
hal_file_code (*read)(hal_file* file, char* buffer, const int size);
|
|
||||||
|
|
||||||
// Function: write
|
|
||||||
// Write the provided message to the file.
|
|
||||||
// Returns: HAL_SUCCESS on successful write, or appropriate error code on failure.
|
|
||||||
hal_file_code (*write)(hal_file* file, const char* message);
|
|
||||||
|
|
||||||
// Function: close
|
|
||||||
// Close the file and release associated resources.
|
|
||||||
// Returns: HAL_SUCCESS on successful close, or appropriate error code on failure.
|
|
||||||
hal_file_code (*close)(hal_file* file);
|
|
||||||
|
|
||||||
|
|
||||||
hal_file_code (*rename)(const char* oldname, const char* newname);
|
|
||||||
|
|
||||||
|
|
||||||
hal_file_code (*remove)(const char* filename);
|
|
||||||
|
|
||||||
// Function: teardown
|
|
||||||
// Perform necessary cleanup and teardown operations for the file handling system.
|
|
||||||
// Returns: HAL_SUCCESS on successful teardown, or appropriate error code on failure.
|
|
||||||
hal_file_code (*teardown)();
|
|
||||||
} hal_file_operations;
|
|
||||||
|
|
||||||
// Global variable to access file operations
|
|
||||||
extern hal_file_operations hal_file_manager;
|
|
||||||
|
|
||||||
// Maximum size of a filename supported by implementation
|
|
||||||
extern const int HAL_MAX_FILENAME_SIZE;
|
|
||||||
|
|
||||||
// Maximum number of files that can be open simultaneously by implementation
|
|
||||||
extern const int HAL_MAX_FILES_OPEN;
|
|
||||||
|
|
||||||
// End-of-File (EOF) indicator value defined by implementation
|
|
||||||
extern const int HAL_EOF;
|
|
||||||
25
hal/makefile
25
hal/makefile
@@ -1,25 +0,0 @@
|
|||||||
CC = gcc
|
|
||||||
CFLAGS = -Wall -Wextra -pedantic
|
|
||||||
|
|
||||||
# Library name and source files
|
|
||||||
LIB_NAME = hal.a
|
|
||||||
SRC_FILES = ports/hal_file.c
|
|
||||||
BUILD_DIR = bin
|
|
||||||
|
|
||||||
# Object files derived from source files
|
|
||||||
OBJ_FILES = $(SRC_FILES:.c=.o)
|
|
||||||
|
|
||||||
# Target: build the library
|
|
||||||
all: $(BUILD_DIR)/$(LIB_NAME)
|
|
||||||
|
|
||||||
# Build the library from object files
|
|
||||||
$(LIB_NAME): $(OBJ_FILES)
|
|
||||||
ar rcs $@ $^
|
|
||||||
|
|
||||||
# Compile from object files
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
# Clean up generated files
|
|
||||||
clean:
|
|
||||||
rm -f $(LIB_NAME) $(OBJ_FILES)
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
#include "hal_file.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
typedef struct hal_file_type {
|
|
||||||
FILE* fp;
|
|
||||||
} hal_file;
|
|
||||||
|
|
||||||
// Initialization logic, if needed
|
|
||||||
hal_file_code setup() {
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code open(hal_file** file, const char* filename, const char* mode) {
|
|
||||||
if (!file || !filename || !mode) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*file = (hal_file*)malloc(sizeof(hal_file));
|
|
||||||
if (!(*file)) {
|
|
||||||
return HAL_ERROR_ALLOC;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*file)->fp = fopen(filename, mode);
|
|
||||||
if (!(*file)->fp) {
|
|
||||||
free(*file);
|
|
||||||
return HAL_ERROR_OPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code read(hal_file* file, char* buffer, const int size) {
|
|
||||||
if (!file || !file->fp || !buffer || size <= 0) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
scanf()
|
|
||||||
|
|
||||||
if (fgets(buffer, size, file->fp) == NULL) {
|
|
||||||
return HAL_ERROR_READ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code write(hal_file* file, const char* message) {
|
|
||||||
if (!file || !file->fp || !message) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fputs(message, file->fp) == EOF) {
|
|
||||||
return HAL_ERROR_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code close(hal_file* file) {
|
|
||||||
if (!file || !file->fp) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fclose(file->fp) != 0) {
|
|
||||||
return HAL_ERROR_CLOSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(file);
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code crename(const char* oldname, const char* newname) {
|
|
||||||
if (!oldname || !newname) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rename(oldname, newname) != 0) {
|
|
||||||
return HAL_ERROR_RENAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
hal_file_code cremove(const char* filename) {
|
|
||||||
if (!filename) {
|
|
||||||
return HAL_ERROR_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove(filename) != 0) {
|
|
||||||
return HAL_ERROR_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// deletion logic, if needed
|
|
||||||
hal_file_code teardown() {
|
|
||||||
return HAL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expose into global variable
|
|
||||||
hal_file_operations hal_file_manager = {
|
|
||||||
.setup = setup,
|
|
||||||
.open = open,
|
|
||||||
.read = read,
|
|
||||||
.write = write,
|
|
||||||
.close = close,
|
|
||||||
.rename = crename,
|
|
||||||
.remove = cremove,
|
|
||||||
.teardown = teardown
|
|
||||||
};
|
|
||||||
|
|
||||||
const int HAL_MAX_FILENAME_SIZE = FILENAME_MAX;
|
|
||||||
const int HAL_MAX_FILES_OPEN = FOPEN_MAX;
|
|
||||||
const int HAL_EOF = EOF;
|
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
#include "lib_fileio.h"
|
#include "lib_fileio.h"
|
||||||
#include "toy_memory.h"
|
#include "toy_memory.h"
|
||||||
|
#include "drive_system.h"
|
||||||
|
|
||||||
#include "../hal/hal_file.h"
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef struct Toy_File
|
typedef struct Toy_File
|
||||||
{
|
{
|
||||||
hal_file* fp;
|
FILE* fp;
|
||||||
hal_file_code error;
|
int error;
|
||||||
int size;
|
int size;
|
||||||
} Toy_File;
|
} Toy_File;
|
||||||
|
|
||||||
@@ -17,18 +19,32 @@ static int nativeOpen(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal modeLiteral = arguments->count == 2? Toy_popLiteralArray(arguments) : TOY_TO_STRING_LITERAL(Toy_createRefString("r"));
|
Toy_Literal modeLiteral = arguments->count == 2? Toy_popLiteralArray(arguments) : TOY_TO_STRING_LITERAL(Toy_createRefString("r"));
|
||||||
Toy_Literal filenameLiteral = Toy_popLiteralArray(arguments);
|
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
|
||||||
// parse the filename (if it's an identifier)
|
// parse the drivePath (if it's an identifier)
|
||||||
Toy_Literal filenameLiteralIdn = filenameLiteral;
|
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
||||||
if (TOY_IS_IDENTIFIER(filenameLiteral) && Toy_parseIdentifierToValue(interpreter, &filenameLiteral)) {
|
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
||||||
Toy_freeLiteral(filenameLiteralIdn);
|
Toy_freeLiteral(drivePathLiteralIdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the filename type
|
// check the drivePath type
|
||||||
if (!TOY_IS_STRING(filenameLiteral)) {
|
if (!TOY_IS_STRING(drivePathLiteral)) {
|
||||||
interpreter->errorOutput("open(string, string) incorrect type for the first parameter expected: string\n");
|
interpreter->errorOutput("Incorrect argument type passed to open\n");
|
||||||
Toy_freeLiteral(filenameLiteral);
|
Toy_freeLiteral(drivePathLiteral);
|
||||||
|
Toy_freeLiteral(modeLiteral);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
||||||
|
|
||||||
|
if (TOY_IS_NULL(filePathLiteral)) {
|
||||||
|
interpreter->errorOutput("File not found in the specified drive\n");
|
||||||
|
Toy_freeLiteral(drivePathLiteral);
|
||||||
|
Toy_freeLiteral(filePathLiteral);
|
||||||
|
Toy_freeLiteral(modeLiteral);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the mode (if it's an identifier)
|
// parse the mode (if it's an identifier)
|
||||||
@@ -39,31 +55,42 @@ static int nativeOpen(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
|
|
||||||
// check the mode type
|
// check the mode type
|
||||||
if (!TOY_IS_STRING(modeLiteral)) {
|
if (!TOY_IS_STRING(modeLiteral)) {
|
||||||
interpreter->errorOutput("open(string, string) incorrect type for the second parameter expected: string\n");
|
interpreter->errorOutput("Incorrect argument type passed to open\n");
|
||||||
|
Toy_freeLiteral(drivePathLiteral);
|
||||||
|
Toy_freeLiteral(filePathLiteral);
|
||||||
Toy_freeLiteral(modeLiteral);
|
Toy_freeLiteral(modeLiteral);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* filename = Toy_toCString(TOY_AS_STRING(filenameLiteral));
|
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
||||||
|
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
||||||
|
|
||||||
const char* mode = Toy_toCString(TOY_AS_STRING(modeLiteral));
|
const char* mode = Toy_toCString(TOY_AS_STRING(modeLiteral));
|
||||||
|
|
||||||
|
interpreter->printOutput(filePath);
|
||||||
|
|
||||||
// build file object
|
// build file object
|
||||||
Toy_File* file = TOY_ALLOCATE(Toy_File, 1);
|
Toy_File* file = TOY_ALLOCATE(Toy_File, 1);
|
||||||
file->error = HAL_SUCCESS;
|
file->error = 0;
|
||||||
file->fp = NULL;
|
file->fp = NULL;
|
||||||
file->size = 0;
|
file->size = 0;
|
||||||
|
|
||||||
// attempt to open file
|
// attempt to open file
|
||||||
file->error = hal_file_manager.open(&file->fp, filename, mode);
|
file->fp = fopen(filePath, mode);
|
||||||
|
if (file->fp == NULL) {
|
||||||
|
file->error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// set size
|
// set size
|
||||||
// if (!error) {
|
if (!file->error) {
|
||||||
// fseek(fp, 0, SEEK_END);
|
fseek(file->fp, 0, SEEK_END);
|
||||||
|
|
||||||
// // pervent integer overflow as ftell returns a long
|
// pervent integer overflow as ftell returns a long
|
||||||
// size = ftell(fp) > INT_MAX? INT_MAX : ftell(fp);
|
file->size = ftell(file->fp) > INT_MAX? INT_MAX : ftell(file->fp);
|
||||||
|
|
||||||
// fseek(fp, 0, SEEK_SET);
|
fseek(file->fp, 0, SEEK_SET);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// result
|
// result
|
||||||
Toy_Literal fileLiteral = TOY_TO_OPAQUE_LITERAL(file, 900);
|
Toy_Literal fileLiteral = TOY_TO_OPAQUE_LITERAL(file, 900);
|
||||||
@@ -72,7 +99,8 @@ static int nativeOpen(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
Toy_freeLiteral(fileLiteral);
|
Toy_freeLiteral(fileLiteral);
|
||||||
Toy_freeLiteral(filenameLiteral);
|
Toy_freeLiteral(drivePathLiteral);
|
||||||
|
Toy_freeLiteral(filePathLiteral);
|
||||||
Toy_freeLiteral(modeLiteral);
|
Toy_freeLiteral(modeLiteral);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -136,7 +164,7 @@ static int nativeRead(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check self type
|
// check self type
|
||||||
if (!TOY_IS_OPAQUE(selfLiteral)) {
|
if (!(TOY_IS_OPAQUE(selfLiteral) || TOY_GET_OPAQUE_TAG(selfLiteral) == 900)) {
|
||||||
interpreter->errorOutput("Incorrect argument type passed to read\n");
|
interpreter->errorOutput("Incorrect argument type passed to read\n");
|
||||||
Toy_freeLiteral(selfLiteral);
|
Toy_freeLiteral(selfLiteral);
|
||||||
Toy_freeLiteral(valueLiteral);
|
Toy_freeLiteral(valueLiteral);
|
||||||
@@ -148,7 +176,7 @@ static int nativeRead(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
|
|
||||||
char buffer[256] = {0};
|
char buffer[256] = {0};
|
||||||
|
|
||||||
hal_file_manager.read(file->fp, buffer, 256);
|
// fscanf(file->fp, buffer);
|
||||||
|
|
||||||
Toy_RefString* result = Toy_createRefStringLength(buffer, 256);
|
Toy_RefString* result = Toy_createRefStringLength(buffer, 256);
|
||||||
|
|
||||||
@@ -160,7 +188,7 @@ static int nativeRead(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//call the hook
|
// call the hook
|
||||||
typedef struct Natives {
|
typedef struct Natives {
|
||||||
char* name;
|
char* name;
|
||||||
Toy_NativeFn fn;
|
Toy_NativeFn fn;
|
||||||
@@ -246,9 +274,9 @@ int Toy_hookFileIO(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Lit
|
|||||||
const int VARIABLES_SIZE = 3;
|
const int VARIABLES_SIZE = 3;
|
||||||
Variable variables[VARIABLES_SIZE];
|
Variable variables[VARIABLES_SIZE];
|
||||||
|
|
||||||
createToyVariable(&variables[0], "MAX_FILENAME_SIZE", HAL_MAX_FILENAME_SIZE);
|
createToyVariable(&variables[0], "MAX_FILENAME_SIZE", FILENAME_MAX);
|
||||||
createToyVariable(&variables[1], "MAX_FILES_OPEN", HAL_MAX_FILES_OPEN);
|
createToyVariable(&variables[1], "MAX_FILES_OPEN", FOPEN_MAX);
|
||||||
createToyVariable(&variables[2], "END_OF_FILE", HAL_EOF);
|
createToyVariable(&variables[2], "END_OF_FILE", EOF);
|
||||||
|
|
||||||
if (scopeConflict(interpreter, variables, VARIABLES_SIZE)) {
|
if (scopeConflict(interpreter, variables, VARIABLES_SIZE)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -1,19 +1,10 @@
|
|||||||
import fileio;
|
import fileio;
|
||||||
|
|
||||||
// test constants
|
|
||||||
{
|
|
||||||
// print MAX_FILENAME_SIZE;
|
|
||||||
// print MAX_FILES_OPEN;
|
|
||||||
// print END_OF_FILE;
|
|
||||||
|
|
||||||
assert END_OF_FILE < 0, "END_OF_FILE failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
// test open
|
// test open
|
||||||
{
|
{
|
||||||
var file = open("does", "r");
|
var file = open("scripts:/fileio.txt", "r");
|
||||||
|
|
||||||
file.read(string);
|
// file.read(string);
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// file.write(12, ",", 12);
|
// file.write(12, ",", 12);
|
||||||
|
|||||||
@@ -182,4 +182,6 @@ import math;
|
|||||||
assert epsilionCompare(1, 1.000001) == true, "epsilionCompare(1, 1.000001) failed";
|
assert epsilionCompare(1, 1.000001) == true, "epsilionCompare(1, 1.000001) failed";
|
||||||
assert epsilionCompare(1, 1.001) == false, "epsilionCompare(1, 1.001) failed";
|
assert epsilionCompare(1, 1.001) == false, "epsilionCompare(1, 1.001) failed";
|
||||||
assert epsilionCompare(0, 0) == true, "epsilionCompare(0, 0) failed";
|
assert epsilionCompare(0, 0) == true, "epsilionCompare(0, 0) failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print "All good";
|
||||||
Reference in New Issue
Block a user