From bb45b99e8a842d937358ae2be219f43723370056 Mon Sep 17 00:00:00 2001 From: IonutParau Date: Tue, 15 Jul 2025 18:54:44 +0200 Subject: [PATCH] enabled stricter warnings and improved error handling in eeproms --- build.zig | 4 + src/components/drive.c | 20 ++--- src/components/eeprom.c | 147 +++++++++++++++++++++++++++++++----- src/components/filesystem.c | 72 +++++++++--------- src/components/gpu.c | 38 +++++----- src/components/screen.c | 6 +- src/emulator.c | 58 +++++++++----- src/lock.c | 4 +- src/neonucleus.h | 50 ++++++------ src/utils.c | 30 ++++++-- src/value.c | 2 +- 11 files changed, 296 insertions(+), 135 deletions(-) diff --git a/build.zig b/build.zig index b7b9728..fa37ecc 100644 --- a/build.zig +++ b/build.zig @@ -40,6 +40,10 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module { .flags = &.{ if(opts.baremetal) "-DNN_BAREMETAL" else "", if(opts.bit32) "-DNN_BIT32" else "", + "-Wall", + "-Werror", + "-std=gnu23", + "-Wno-keyword-macro", // cuz bools }, }); diff --git a/src/components/drive.c b/src/components/drive.c index 5b5dcd0..6a0ea8d 100644 --- a/src/components/drive.c +++ b/src/components/drive.c @@ -236,18 +236,18 @@ void nn_drive_writeByte(nn_drive *drive, void *_, nn_component *component, nn_co } void nn_loadDriveTable(nn_universe *universe) { - nn_componentTable *driveTable = nn_newComponentTable(nn_getAllocator(universe), "drive", NULL, NULL, (void *)nn_drive_destroy); + nn_componentTable *driveTable = nn_newComponentTable(nn_getAllocator(universe), "drive", NULL, NULL, (nn_componentDestructor *)nn_drive_destroy); nn_storeUserdata(universe, "NN:DRIVE", driveTable); - nn_defineMethod(driveTable, "getLabel", false, (void *)nn_drive_getLabel, NULL, "getLabel():string - Get the current label of the drive."); - nn_defineMethod(driveTable, "setLabel", false, (void *)nn_drive_setLabel, NULL, "setLabel(value:string):string - Sets the label of the drive. Returns the new value, which may be truncated."); - nn_defineMethod(driveTable, "getSectorSize", true, (void *)nn_drive_getSectorSize, NULL, "getSectorSize():number - Returns the size of a single sector on the drive, in bytes."); - nn_defineMethod(driveTable, "getPlatterCount", true, (void *)nn_drive_getPlatterCount, NULL, "getPlatterCount():number - Returns the number of platters in the drive."); - nn_defineMethod(driveTable, "getCapacity", true, (void *)nn_drive_getCapacity, NULL, "getCapacity():number - Returns the total capacity of the drive, in bytes."); - nn_defineMethod(driveTable, "readSector", false, (void *)nn_drive_readSector, NULL, "readSector(sector:number):string - Read the current contents of the specified sector."); - nn_defineMethod(driveTable, "writeSector", false, (void *)nn_drive_writeSector, NULL, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); - nn_defineMethod(driveTable, "readByte", false, (void *)nn_drive_readByte, NULL, "readByte(offset:number):number - Read a single byte at the specified offset."); - nn_defineMethod(driveTable, "writeByte", false, (void *)nn_drive_writeByte, NULL, "writeByte(offset:number, value:number) - Write a single byte to the specified offset."); + nn_defineMethod(driveTable, "getLabel", false, (nn_componentMethod *)nn_drive_getLabel, NULL, "getLabel():string - Get the current label of the drive."); + nn_defineMethod(driveTable, "setLabel", false, (nn_componentMethod *)nn_drive_setLabel, NULL, "setLabel(value:string):string - Sets the label of the drive. Returns the new value, which may be truncated."); + nn_defineMethod(driveTable, "getSectorSize", true, (nn_componentMethod *)nn_drive_getSectorSize, NULL, "getSectorSize():number - Returns the size of a single sector on the drive, in bytes."); + nn_defineMethod(driveTable, "getPlatterCount", true, (nn_componentMethod *)nn_drive_getPlatterCount, NULL, "getPlatterCount():number - Returns the number of platters in the drive."); + nn_defineMethod(driveTable, "getCapacity", true, (nn_componentMethod *)nn_drive_getCapacity, NULL, "getCapacity():number - Returns the total capacity of the drive, in bytes."); + nn_defineMethod(driveTable, "readSector", false, (nn_componentMethod *)nn_drive_readSector, NULL, "readSector(sector:number):string - Read the current contents of the specified sector."); + nn_defineMethod(driveTable, "writeSector", false, (nn_componentMethod *)nn_drive_writeSector, NULL, "writeSector(sector:number, value:string) - Write the specified contents to the specified sector."); + nn_defineMethod(driveTable, "readByte", false, (nn_componentMethod *)nn_drive_readByte, NULL, "readByte(offset:number):number - Read a single byte at the specified offset."); + nn_defineMethod(driveTable, "writeByte", false, (nn_componentMethod *)nn_drive_writeByte, NULL, "writeByte(offset:number, value:number) - Write a single byte to the specified offset."); } nn_component *nn_addDrive(nn_computer *computer, nn_address address, int slot, nn_drive *drive) { diff --git a/src/components/eeprom.c b/src/components/eeprom.c index 35f959b..db0a3f0 100644 --- a/src/components/eeprom.c +++ b/src/components/eeprom.c @@ -79,7 +79,14 @@ void nn_eeprom_getDataSize(nn_eeprom *eeprom, void *_, nn_component *component, void nn_eeprom_getLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { char buf[NN_LABEL_SIZE]; nn_size_t l = NN_LABEL_SIZE; - eeprom->table.getLabel(eeprom->table.userdata, buf, &l); + nn_errorbuf_t err = ""; + nn_lock(&eeprom->ctx, eeprom->lock); + eeprom->table.getLabel(eeprom->table.userdata, buf, &l, err); + nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } if(l == 0) { nn_return(computer, nn_values_nil()); } else { @@ -98,9 +105,14 @@ void nn_eeprom_setLabel(nn_eeprom *eeprom, void *_, nn_component *component, nn_ nn_setCError(computer, "bad label (string expected)"); return; } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - l = eeprom->table.setLabel(eeprom->table.userdata, buf, l); + l = eeprom->table.setLabel(eeprom->table.userdata, buf, l, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } nn_return_string(computer, buf, l); // Latency, energy costs and stuff @@ -115,9 +127,14 @@ void nn_eeprom_get(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu nn_setCError(computer, "out of memory"); return; } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - nn_size_t len = eeprom->table.get(eeprom->table.userdata, buf); + nn_size_t len = eeprom->table.get(eeprom->table.userdata, buf, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } nn_return_string(computer, buf, len); nn_dealloc(alloc, buf, cap); @@ -141,14 +158,24 @@ void nn_eeprom_set(nn_eeprom *eeprom, void *_, nn_component *component, nn_compu return; } } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - if(eeprom->table.isReadonly(eeprom->table.userdata)) { + if(eeprom->table.isReadonly(eeprom->table.userdata, err)) { nn_unlock(&eeprom->ctx, eeprom->lock); nn_setCError(computer, "readonly"); return; } - eeprom->table.set(eeprom->table.userdata, buf, len); + if(!nn_error_isEmpty(err)) { + nn_unlock(&eeprom->ctx, eeprom->lock); + nn_setError(computer, err); + return; + } + eeprom->table.set(eeprom->table.userdata, buf, len, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } nn_eeprom_writeCost(component, len); } @@ -161,14 +188,15 @@ void nn_eeprom_getData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c nn_setCError(computer, "out of memory"); return; } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - int len = eeprom->table.getData(eeprom->table.userdata, buf); + nn_size_t len = eeprom->table.getData(eeprom->table.userdata, buf, err); nn_unlock(&eeprom->ctx, eeprom->lock); - if(len < 0) { - nn_return(computer, nn_values_nil()); - } else { - nn_return_string(computer, buf, len); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; } + nn_return_string(computer, buf, len); nn_dealloc(alloc, buf, cap); nn_eeprom_readCost(component, len); @@ -191,28 +219,104 @@ void nn_eeprom_setData(nn_eeprom *eeprom, void *_, nn_component *component, nn_c nn_setCError(computer, "out of space"); return; } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - if(eeprom->table.isReadonly(eeprom->table.userdata)) { + if(eeprom->table.isReadonly(eeprom->table.userdata, err)) { nn_unlock(&eeprom->ctx, eeprom->lock); nn_setCError(computer, "readonly"); return; } - eeprom->table.setData(eeprom->table.userdata, buf, len); + if(!nn_error_isEmpty(err)) { + nn_unlock(&eeprom->ctx, eeprom->lock); + nn_setError(computer, err); + return; + } + eeprom->table.setData(eeprom->table.userdata, buf, len, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } nn_eeprom_writeCost(component, len); } -void nn_eeprom_isReadOnly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { +void nn_eeprom_getArchitecture(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { + nn_Alloc *alloc = nn_getAllocator(nn_getUniverse(computer)); + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - nn_return(computer, nn_values_boolean(eeprom->table.isReadonly(eeprom->table.userdata))); + char *s = eeprom->table.getArchitecture(alloc, eeprom->table.userdata, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + if(s == NULL) { + nn_return_nil(computer); + return; + } + + nn_size_t l = nn_strlen(s); + + nn_return_string(computer, s, nn_strlen(s)); + + nn_deallocStr(alloc, s); + + nn_eeprom_readCost(component, l); +} + +void nn_eeprom_setArchitecture(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { + nn_value data = nn_getArgument(computer, 0); + const char *buf = nn_toCString(data); + if(buf == NULL) { + nn_setCError(computer, "bad data (string expected)"); + return; + } + nn_errorbuf_t err = ""; + nn_lock(&eeprom->ctx, eeprom->lock); + if(eeprom->table.isReadonly(eeprom->table.userdata, err)) { + nn_unlock(&eeprom->ctx, eeprom->lock); + nn_setCError(computer, "readonly"); + return; + } + if(!nn_error_isEmpty(err)) { + nn_unlock(&eeprom->ctx, eeprom->lock); + nn_setError(computer, err); + return; + } + eeprom->table.setArchitecture(eeprom->table.userdata, buf, err); + nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + nn_eeprom_writeCost(component, nn_strlen(buf)); +} + +void nn_eeprom_isReadOnly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { + nn_errorbuf_t err = ""; + nn_lock(&eeprom->ctx, eeprom->lock); + nn_return(computer, nn_values_boolean(eeprom->table.isReadonly(eeprom->table.userdata, err))); + nn_unlock(&eeprom->ctx, eeprom->lock); + + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } } void nn_eeprom_makeReadonly(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - eeprom->table.makeReadonly(eeprom->table.userdata); + nn_bool_t done =eeprom->table.makeReadonly(eeprom->table.userdata, err); nn_unlock(&eeprom->ctx, eeprom->lock); + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + nn_return_boolean(computer, done); } void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component, nn_computer *computer) { @@ -224,17 +328,20 @@ void nn_eeprom_getChecksum(nn_eeprom *eeprom, void *_, nn_component *component, nn_setCError(computer, "out of memory"); return; } + nn_errorbuf_t err = ""; nn_lock(&eeprom->ctx, eeprom->lock); - int dataLen = eeprom->table.getData(eeprom->table.userdata, buf); - if(dataLen < 0) { + nn_size_t dataLen = eeprom->table.getData(eeprom->table.userdata, buf, err); + if(!nn_error_isEmpty(err)) { nn_unlock(&eeprom->ctx, eeprom->lock); nn_dealloc(alloc, buf, dataCap + codeCap); + nn_setError(computer, err); return; } - int codeLen = eeprom->table.get(eeprom->table.userdata, buf + dataLen); - if(codeLen < 0) { + int codeLen = eeprom->table.get(eeprom->table.userdata, buf + dataLen, err); + if(!nn_error_isEmpty(err)) { nn_unlock(&eeprom->ctx, eeprom->lock); nn_dealloc(alloc, buf, dataCap + codeCap); + nn_setError(computer, err); return; } nn_unlock(&eeprom->ctx, eeprom->lock); @@ -268,6 +375,8 @@ void nn_loadEepromTable(nn_universe *universe) { nn_defineMethod(eepromTable, "set", true, (void *)nn_eeprom_set, NULL, "set(data: string) - Sets the current code contents."); nn_defineMethod(eepromTable, "getData", true, (void *)nn_eeprom_getData, NULL, "getData(): string - Reads the current data contents."); nn_defineMethod(eepromTable, "setData", true, (void *)nn_eeprom_setData, NULL, "setData(data: string) - Sets the current data contents."); + nn_defineMethod(eepromTable, "getArchitecture", true, (void *)nn_eeprom_getArchitecture, NULL, "getArchitecture(): string - Gets the intended architecture."); + nn_defineMethod(eepromTable, "setArchitecture", true, (void *)nn_eeprom_setArchitecture, NULL, "setArchitecture(data: string) - Sets the intended architecture."); nn_defineMethod(eepromTable, "isReadOnly", true, (void *)nn_eeprom_isReadOnly, NULL, "isReadOnly(): boolean - Returns whether this EEPROM is read-only."); nn_defineMethod(eepromTable, "makeReadOnly", false, (void *)nn_eeprom_makeReadonly, NULL, "makeReadOnly() - Makes the current EEPROM read-only. Normally, this cannot be undone."); nn_defineMethod(eepromTable, "makeReadonly", false, (void *)nn_eeprom_makeReadonly, NULL, "makeReadonly() - Legacy alias to makeReadOnly()"); diff --git a/src/components/filesystem.c b/src/components/filesystem.c index 27c5f3b..77f09e4 100644 --- a/src/components/filesystem.c +++ b/src/components/filesystem.c @@ -12,7 +12,7 @@ typedef struct nn_filesystem { void *files[NN_MAX_OPEN_FILES]; } nn_filesystem; -void nn_fs_destroy(void *_, nn_component *component, nn_filesystem *fs) { +void nn_fs_destroy(nn_componentMethod *_, nn_component *component, nn_filesystem *fs) { nn_destroyFilesystem(fs); } @@ -179,22 +179,22 @@ void nn_fs_setLabel(nn_filesystem *fs, void *_, nn_component *component, nn_comp nn_fs_writeCost(fs, l, component); } -void nn_fs_spaceUsed(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_spaceUsed(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_size_t space = nn_fs_getSpaceUsed(fs); nn_return(computer, nn_values_integer(space)); } -void nn_fs_spaceTotal(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_spaceTotal(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_return(computer, nn_values_integer(fs->table.spaceTotal)); } -void nn_fs_isReadOnly(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_isReadOnly(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_lock(&fs->ctx, fs->lock); nn_return_boolean(computer, fs->table.isReadOnly(fs->table.userdata)); nn_unlock(&fs->ctx, fs->lock); } -void nn_fs_size(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_size(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -213,7 +213,7 @@ void nn_fs_size(nn_filesystem *fs, void *_, nn_component *component, nn_computer nn_return(computer, nn_values_integer(byteSize)); } -void nn_fs_remove(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_remove(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -233,7 +233,7 @@ void nn_fs_remove(nn_filesystem *fs, void *_, nn_component *component, nn_comput nn_fs_removeCost(fs, removed, component); } -void nn_fs_lastModified(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_lastModified(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -257,7 +257,7 @@ void nn_fs_lastModified(nn_filesystem *fs, void *_, nn_component *component, nn_ nn_return(computer, nn_values_integer(t)); } -void nn_fs_rename(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_rename(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value fromValue = nn_getArgument(computer, 0); const char *from = nn_toCString(fromValue); if(from == NULL) { @@ -289,7 +289,7 @@ void nn_fs_rename(nn_filesystem *fs, void *_, nn_component *component, nn_comput nn_fs_createCost(fs, movedCount, component); } -void nn_fs_exists(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_exists(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -306,7 +306,7 @@ void nn_fs_exists(nn_filesystem *fs, void *_, nn_component *component, nn_comput nn_unlock(&fs->ctx, fs->lock); } -void nn_fs_isDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_isDirectory(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -323,7 +323,7 @@ void nn_fs_isDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_c nn_unlock(&fs->ctx, fs->lock); } -void nn_fs_makeDirectory(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_makeDirectory(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -342,7 +342,7 @@ void nn_fs_makeDirectory(nn_filesystem *fs, void *_, nn_component *component, nn nn_fs_createCost(fs, 1, component); } -void nn_fs_list(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_list(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -373,7 +373,7 @@ void nn_fs_list(nn_filesystem *fs, void *_, nn_component *component, nn_computer } } -void nn_fs_open(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_open(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value pathValue = nn_getArgument(computer, 0); const char *path = nn_toCString(pathValue); if(path == NULL) { @@ -417,7 +417,7 @@ void nn_fs_open(nn_filesystem *fs, void *_, nn_component *component, nn_computer nn_return(computer, nn_values_integer(fd)); } -void nn_fs_close(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_close(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value fdValue = nn_getArgument(computer, 0); nn_size_t fd = nn_toInt(fdValue); void *file = nn_fs_unwrapFD(fs, fd); @@ -435,7 +435,7 @@ void nn_fs_close(nn_filesystem *fs, void *_, nn_component *component, nn_compute nn_return(computer, nn_values_boolean(closed)); } -void nn_fs_write(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_write(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value fdValue = nn_getArgument(computer, 0); nn_size_t fd = nn_toInt(fdValue); @@ -471,7 +471,7 @@ void nn_fs_write(nn_filesystem *fs, void *_, nn_component *component, nn_compute nn_fs_writeCost(fs, len, component); } -void nn_fs_read(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_read(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_value fdValue = nn_getArgument(computer, 0); int fd = nn_toInt(fdValue); @@ -516,7 +516,7 @@ nn_bool_t nn_fs_validWhence(const char *s) { nn_strcmp(s, "end") == 0; } -void nn_fs_seek(nn_filesystem *fs, void *_, nn_component *component, nn_computer *computer) { +void nn_fs_seek(nn_filesystem *fs, nn_componentMethod *_, nn_component *component, nn_computer *computer) { nn_size_t fd = nn_toInt(nn_getArgument(computer, 0)); const char *whence = nn_toCString(nn_getArgument(computer, 1)); @@ -548,27 +548,27 @@ void nn_fs_seek(nn_filesystem *fs, void *_, nn_component *component, nn_computer } void nn_loadFilesystemTable(nn_universe *universe) { - nn_componentTable *fsTable = nn_newComponentTable(nn_getAllocator(universe), "filesystem", NULL, NULL, (void *)nn_fs_destroy); + nn_componentTable *fsTable = nn_newComponentTable(nn_getAllocator(universe), "filesystem", NULL, NULL, (nn_componentDestructor *)nn_fs_destroy); nn_storeUserdata(universe, "NN:FILESYSTEM", fsTable); - nn_defineMethod(fsTable, "getLabel", true, (void *)nn_fs_getLabel, NULL, "getLabel(): string - Returns the label of the filesystem."); - nn_defineMethod(fsTable, "setLabel", true, (void *)nn_fs_setLabel, NULL, "setLabel(label: string): string - Sets a new label for the filesystem and returns the new label of the filesystem, which may have been truncated."); - nn_defineMethod(fsTable, "spaceUsed", true, (void *)nn_fs_spaceUsed, NULL, "spaceUsed(): integer - Returns the amounts of bytes used."); - nn_defineMethod(fsTable, "spaceTotal", true, (void *)nn_fs_spaceTotal, NULL, "spaceTotal(): integer - Returns the capacity of the filesystem."); - nn_defineMethod(fsTable, "isReadOnly", true, (void *)nn_fs_isReadOnly, NULL, "isReadOnly(): boolean - Returns whether the filesystem is in read-only mode."); - nn_defineMethod(fsTable, "size", true, (void *)nn_fs_size, NULL, "size(path: string): integer - Gets the size, in bytes, of a file."); - nn_defineMethod(fsTable, "remove", true, (void *)nn_fs_remove, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); - nn_defineMethod(fsTable, "lastModified", true, (void *)nn_fs_lastModified, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); - nn_defineMethod(fsTable, "rename", true, (void *)nn_fs_rename, NULL, "rename(from: string, to: string): boolean - Moves files from one path to another."); - nn_defineMethod(fsTable, "exists", true, (void *)nn_fs_exists, NULL, "exists(path: string): boolean - Checks whether a file exists."); - nn_defineMethod(fsTable, "isDirectory", true, (void *)nn_fs_isDirectory, NULL, "isDirectory(path: string): boolean - Returns whether a file is actually a directory."); - nn_defineMethod(fsTable, "makeDirectory", true, (void *)nn_fs_makeDirectory, NULL, "makeDirectory(path: string): boolean - Creates a new directory at the given path. Returns whether it succeeded."); - nn_defineMethod(fsTable, "list", true, (void *)nn_fs_list, NULL, "list(path: string): string[] - Returns a list of file paths. Directories will have a / after them"); - nn_defineMethod(fsTable, "open", true, (void *)nn_fs_open, NULL, "open(path: string[, mode: string = \"r\"]): integer - Opens a file, may create it."); - nn_defineMethod(fsTable, "close", true, (void *)nn_fs_close, NULL, "close(fd: integer): boolean - Closes a file."); - nn_defineMethod(fsTable, "write", true, (void *)nn_fs_write, NULL, "write(fd: integer, data: string): boolean - Writes data to a file."); - nn_defineMethod(fsTable, "read", true, (void *)nn_fs_read, NULL, "read(fd: integer, len: number): string - Reads bytes from a file. Infinity is a valid length, in which case it reads as much as possible."); - nn_defineMethod(fsTable, "seek", true, (void *)nn_fs_seek, NULL, "seek(fd: integer, whence: string, offset: integer): integer - Seeks a file. Returns the new position. Valid whences are set, cur and end."); + nn_defineMethod(fsTable, "getLabel", true, (nn_componentMethod *)nn_fs_getLabel, NULL, "getLabel(): string - Returns the label of the filesystem."); + nn_defineMethod(fsTable, "setLabel", true, (nn_componentMethod *)nn_fs_setLabel, NULL, "setLabel(label: string): string - Sets a new label for the filesystem and returns the new label of the filesystem, which may have been truncated."); + nn_defineMethod(fsTable, "spaceUsed", true, (nn_componentMethod *)nn_fs_spaceUsed, NULL, "spaceUsed(): integer - Returns the amounts of bytes used."); + nn_defineMethod(fsTable, "spaceTotal", true, (nn_componentMethod *)nn_fs_spaceTotal, NULL, "spaceTotal(): integer - Returns the capacity of the filesystem."); + nn_defineMethod(fsTable, "isReadOnly", true, (nn_componentMethod *)nn_fs_isReadOnly, NULL, "isReadOnly(): boolean - Returns whether the filesystem is in read-only mode."); + nn_defineMethod(fsTable, "size", true, (nn_componentMethod *)nn_fs_size, NULL, "size(path: string): integer - Gets the size, in bytes, of a file."); + nn_defineMethod(fsTable, "remove", true, (nn_componentMethod *)nn_fs_remove, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); + nn_defineMethod(fsTable, "lastModified", true, (nn_componentMethod *)nn_fs_lastModified, NULL, "remove(path: string): boolean - Removes a file. Returns whether the operation succeeded."); + nn_defineMethod(fsTable, "rename", true, (nn_componentMethod *)nn_fs_rename, NULL, "rename(from: string, to: string): boolean - Moves files from one path to another."); + nn_defineMethod(fsTable, "exists", true, (nn_componentMethod *)nn_fs_exists, NULL, "exists(path: string): boolean - Checks whether a file exists."); + nn_defineMethod(fsTable, "isDirectory", true, (nn_componentMethod *)nn_fs_isDirectory, NULL, "isDirectory(path: string): boolean - Returns whether a file is actually a directory."); + nn_defineMethod(fsTable, "makeDirectory", true, (nn_componentMethod *)nn_fs_makeDirectory, NULL, "makeDirectory(path: string): boolean - Creates a new directory at the given path. Returns whether it succeeded."); + nn_defineMethod(fsTable, "list", true, (nn_componentMethod *)nn_fs_list, NULL, "list(path: string): string[] - Returns a list of file paths. Directories will have a / after them"); + nn_defineMethod(fsTable, "open", true, (nn_componentMethod *)nn_fs_open, NULL, "open(path: string[, mode: string = \"r\"]): integer - Opens a file, may create it."); + nn_defineMethod(fsTable, "close", true, (nn_componentMethod *)nn_fs_close, NULL, "close(fd: integer): boolean - Closes a file."); + nn_defineMethod(fsTable, "write", true, (nn_componentMethod *)nn_fs_write, NULL, "write(fd: integer, data: string): boolean - Writes data to a file."); + nn_defineMethod(fsTable, "read", true, (nn_componentMethod *)nn_fs_read, NULL, "read(fd: integer, len: number): string - Reads bytes from a file. Infinity is a valid length, in which case it reads as much as possible."); + nn_defineMethod(fsTable, "seek", true, (nn_componentMethod *)nn_fs_seek, NULL, "seek(fd: integer, whence: string, offset: integer): integer - Seeks a file. Returns the new position. Valid whences are set, cur and end."); } nn_component *nn_addFileSystem(nn_computer *computer, nn_address address, int slot, nn_filesystem *filesystem) { diff --git a/src/components/gpu.c b/src/components/gpu.c index 31036d2..76d4fcd 100644 --- a/src/components/gpu.c +++ b/src/components/gpu.c @@ -423,7 +423,7 @@ void nni_gpu_setDepth(nni_gpu *gpu, void *_, nn_component *component, nn_compute int old = nn_getDepth(gpu->currentScreen); nn_setDepth(gpu->currentScreen, depth); - nn_return_cstring(computer, nn_depthName(depth)); + nn_return_cstring(computer, nn_depthName(old)); } void nni_gpu_maxDepth(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) { @@ -432,26 +432,26 @@ void nni_gpu_maxDepth(nni_gpu *gpu, void *_, nn_component *component, nn_compute } void nn_loadGraphicsCardTable(nn_universe *universe) { - nn_componentTable *gpuTable = nn_newComponentTable(nn_getAllocator(universe), "gpu", NULL, NULL, (void *)nni_gpuDeinit); + nn_componentTable *gpuTable = nn_newComponentTable(nn_getAllocator(universe), "gpu", NULL, NULL, (nn_componentDestructor *)nni_gpuDeinit); nn_storeUserdata(universe, "NN:GPU", gpuTable); - nn_defineMethod(gpuTable, "bind", false, (void *)nni_gpu_bind, NULL, "bind(addr: string[, reset: boolean = false]): boolean - Bind a GPU to a screen. Very expensive. If reset is true, it will clear the screen."); - nn_defineMethod(gpuTable, "getScreen", true, (void *)nni_gpu_getScreen, NULL, "getScreen(): string"); - nn_defineMethod(gpuTable, "set", true, (void *)nni_gpu_set, NULL, "set(x: integer, y: integer, text: string[, vertical: boolean = false]) - Modifies the screen at a specific x or y. If vertical is false, it will display it horizontally. If it is true, it will display it vertically."); - nn_defineMethod(gpuTable, "get", true, (void *)nni_gpu_get, NULL, "get(x: integer, y: integer): string, integer, integer, integer?, integer? - Returns the character, foreground color, background color, foreground palette index (if applicable), background palette index (if applicable) of a pixel"); - nn_defineMethod(gpuTable, "maxResolution", true, (void *)nni_gpu_maxResolution, NULL, "maxResolution(): integer, integer - Gets the maximum resolution supported by the bound screen."); - nn_defineMethod(gpuTable, "getResolution", true, (void *)nni_gpu_getResolution, NULL, "getResolution(): integer, integer - Gets the current resolution of the bound screen."); - nn_defineMethod(gpuTable, "setResolution", true, (void *)nni_gpu_setResolution, NULL, "maxResolution(): integer, integer - Changes the resolution of the bound screen."); - nn_defineMethod(gpuTable, "setBackground", true, (void *)nni_gpu_setBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "setForeground", true, (void *)nni_gpu_setForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getBackground", true, (void *)nni_gpu_getBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getForeground", true, (void *)nni_gpu_getForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); - nn_defineMethod(gpuTable, "getDepth", true, (void *)nni_gpu_getDepth, NULL, "getDepth(): number - The currently set color depth of the screen, in bits. Can be 1, 4 or 8."); - nn_defineMethod(gpuTable, "setDepth", true, (void *)nni_gpu_setDepth, NULL, "setDepth(depth: integer): string - Changes the screen depth. Valid values can be 1, 4, 8, 16 or 24, however check maxDepth for the maximum supported value of the screen. Using a depth higher than what is supported by the screen will error. Returns the name of the new depth."); - nn_defineMethod(gpuTable, "maxDepth", true, (void *)nni_gpu_maxDepth, NULL, "maxDepth(): number - The maximum supported depth of the screen."); - nn_defineMethod(gpuTable, "fill", true, (void *)nni_gpu_fill, NULL, "fill(x: integer, y: integer, w: integer, h: integer, s: string)"); - nn_defineMethod(gpuTable, "copy", true, (void *)nni_gpu_copy, NULL, "copy(x: integer, y: integer, w: integer, h: integer, tx: integer, ty: integer) - Copies stuff"); - nn_defineMethod(gpuTable, "getViewport", true, (void *)nni_gpu_getViewport, NULL, "getViewport(): integer, integer - Gets the current viewport resolution"); + nn_defineMethod(gpuTable, "bind", false, (nn_componentMethod *)nni_gpu_bind, NULL, "bind(addr: string[, reset: boolean = false]): boolean - Bind a GPU to a screen. Very expensive. If reset is true, it will clear the screen."); + nn_defineMethod(gpuTable, "getScreen", true, (nn_componentMethod *)nni_gpu_getScreen, NULL, "getScreen(): string"); + nn_defineMethod(gpuTable, "set", true, (nn_componentMethod *)nni_gpu_set, NULL, "set(x: integer, y: integer, text: string[, vertical: boolean = false]) - Modifies the screen at a specific x or y. If vertical is false, it will display it horizontally. If it is true, it will display it vertically."); + nn_defineMethod(gpuTable, "get", true, (nn_componentMethod *)nni_gpu_get, NULL, "get(x: integer, y: integer): string, integer, integer, integer?, integer? - Returns the character, foreground color, background color, foreground palette index (if applicable), background palette index (if applicable) of a pixel"); + nn_defineMethod(gpuTable, "maxResolution", true, (nn_componentMethod *)nni_gpu_maxResolution, NULL, "maxResolution(): integer, integer - Gets the maximum resolution supported by the bound screen."); + nn_defineMethod(gpuTable, "getResolution", true, (nn_componentMethod *)nni_gpu_getResolution, NULL, "getResolution(): integer, integer - Gets the current resolution of the bound screen."); + nn_defineMethod(gpuTable, "setResolution", true, (nn_componentMethod *)nni_gpu_setResolution, NULL, "maxResolution(): integer, integer - Changes the resolution of the bound screen."); + nn_defineMethod(gpuTable, "setBackground", true, (nn_componentMethod *)nni_gpu_setBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "setForeground", true, (nn_componentMethod *)nni_gpu_setForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getBackground", true, (nn_componentMethod *)nni_gpu_getBackground, NULL, "setBackground(color: integer, isPalette: boolean): integer, integer? - Sets the current background color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getForeground", true, (nn_componentMethod *)nni_gpu_getForeground, NULL, "setForeground(color: integer, isPalette: boolean): integer, integer? - Sets the current foreground color. Returns the old one and palette index if applicable."); + nn_defineMethod(gpuTable, "getDepth", true, (nn_componentMethod *)nni_gpu_getDepth, NULL, "getDepth(): number - The currently set color depth of the screen, in bits. Can be 1, 4 or 8."); + nn_defineMethod(gpuTable, "setDepth", true, (nn_componentMethod *)nni_gpu_setDepth, NULL, "setDepth(depth: integer): string - Changes the screen depth. Valid values can be 1, 4, 8, 16 or 24, however check maxDepth for the maximum supported value of the screen. Using a depth higher than what is supported by the screen will error. Returns the name of the new depth."); + nn_defineMethod(gpuTable, "maxDepth", true, (nn_componentMethod *)nni_gpu_maxDepth, NULL, "maxDepth(): number - The maximum supported depth of the screen."); + nn_defineMethod(gpuTable, "fill", true, (nn_componentMethod *)nni_gpu_fill, NULL, "fill(x: integer, y: integer, w: integer, h: integer, s: string)"); + nn_defineMethod(gpuTable, "copy", true, (nn_componentMethod *)nni_gpu_copy, NULL, "copy(x: integer, y: integer, w: integer, h: integer, tx: integer, ty: integer) - Copies stuff"); + nn_defineMethod(gpuTable, "getViewport", true, (nn_componentMethod *)nni_gpu_getViewport, NULL, "getViewport(): integer, integer - Gets the current viewport resolution"); } nn_component *nn_addGPU(nn_computer *computer, nn_address address, int slot, nn_gpuControl *control) { diff --git a/src/components/screen.c b/src/components/screen.c index 262ae01..4ac668c 100644 --- a/src/components/screen.c +++ b/src/components/screen.c @@ -237,11 +237,11 @@ void nn_screenComp_getAspectRatio(nn_screen *screen, void *_, nn_component *comp } void nn_loadScreenTable(nn_universe *universe) { - nn_componentTable *screenTable = nn_newComponentTable(nn_getAllocator(universe), "screen", NULL, NULL, (void *)nn_screenComp_destroy); + nn_componentTable *screenTable = nn_newComponentTable(nn_getAllocator(universe), "screen", NULL, NULL, (nn_componentDestructor *)nn_screenComp_destroy); nn_storeUserdata(universe, "NN:SCREEN", screenTable); - nn_defineMethod(screenTable, "getKeyboards", true, (void *)nn_screenComp_getKeyboards, NULL, "getKeyboards(): string[] - Returns the keyboards registered to this screen."); - nn_defineMethod(screenTable, "getAspectRatio", true, (void *)nn_screenComp_getAspectRatio, NULL, ""); + nn_defineMethod(screenTable, "getKeyboards", true, (nn_componentMethod *)nn_screenComp_getKeyboards, NULL, "getKeyboards(): string[] - Returns the keyboards registered to this screen."); + nn_defineMethod(screenTable, "getAspectRatio", true, (nn_componentMethod *)nn_screenComp_getAspectRatio, NULL, ""); } nn_componentTable *nn_getScreenTable(nn_universe *universe) { diff --git a/src/emulator.c b/src/emulator.c index 4933077..32fc37d 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -6,6 +6,7 @@ #include "neonucleus.h" #include "testLuaArch.h" #include +#include #ifdef NN_BAREMETAL @@ -104,25 +105,34 @@ nn_eepromControl ne_eeprom_ctrl = { .bytesWrittenPerTick = 4096, }; -void ne_eeprom_getLabel(void *_, char *buf, size_t *buflen) { +void ne_eeprom_getLabel(void *_, char *buf, size_t *buflen, nn_errorbuf_t err) { *buflen = 0; } -size_t ne_eeprom_setLabel(void *_, const char *buf, size_t buflen) { +nn_size_t ne_eeprom_setLabel(void *_, const char *buf, size_t buflen, nn_errorbuf_t err) { + nn_error_write(err, "unsupported"); return 0; } +char *ne_eeprom_getArchitecture(nn_Alloc *alloc, void *_, nn_errorbuf_t err) { + return NULL; +} + +void ne_eeprom_setArchitecture(void *_, const char *buf, nn_errorbuf_t err) { + nn_error_write(err, "unsupported"); +} + const char *ne_location(nn_address address) { static char buffer[256]; snprintf(buffer, 256, "data/%s", address); return buffer; } -size_t ne_eeprom_get(void *addr, char *buf) { +size_t ne_eeprom_get(void *addr, char *buf, nn_errorbuf_t err) { FILE *f = fopen(ne_location(addr), "rb"); if (f == NULL) { - printf("couldn't read eeprom"); - exit(1); + nn_error_write(err, strerror(errno)); + return 0; } fseek(f, 0, SEEK_END); size_t len = ftell(f); @@ -132,27 +142,35 @@ size_t ne_eeprom_get(void *addr, char *buf) { return len; } -void ne_eeprom_set(void *addr, const char *buf, size_t len) { +nn_bool_t ne_eeprom_set(void *addr, const char *buf, size_t len, nn_errorbuf_t err) { FILE *f = fopen(ne_location(addr), "wb"); if (f == NULL) { - printf("couldn't write eeprom"); - exit(1); + nn_error_write(err, strerror(errno)); + return false; } fwrite(buf, sizeof(char), len, f); fclose(f); + return true; } -int ne_eeprom_getData(void *_, char *buf) { +nn_size_t ne_eeprom_getData(void *_, char *buf, nn_errorbuf_t err) { + nn_error_write(err, "unsupported"); return 0; } -void ne_eeprom_setData(void *_, const char *buf, size_t len) {} +nn_bool_t ne_eeprom_setData(void *_, const char *buf, size_t len, nn_errorbuf_t err) { + nn_error_write(err, "unsupported"); + return false; +} -nn_bool_t ne_eeprom_isReadonly(void *userdata) { +nn_bool_t ne_eeprom_isReadonly(void *userdata, nn_errorbuf_t err) { return false; } -void ne_eeprom_makeReadonly(void *userdata) {} +nn_bool_t ne_eeprom_makeReadonly(void *userdata, nn_errorbuf_t err) { + nn_error_write(err, "unsupported"); + return false; +} nn_filesystemControl ne_fs_ctrl = { .readBytesPerTick = 65536, @@ -171,14 +189,18 @@ nn_filesystemControl ne_fs_ctrl = { .createEnergy = 0.325, }; -void ne_fs_getLabel(nn_component *component, void *_, char *buf, size_t *buflen) { +void ne_fs_getLabel(void *_, char *buf, size_t *buflen) { *buflen = 0; } -nn_size_t ne_fs_setLabel(nn_component *component, void *_, const char *buf, size_t buflen) { +nn_size_t ne_fs_setLabel(void *_, const char *buf, size_t buflen) { return 0; } +nn_bool_t ne_fs_isReadOnly(void *_) { + return false; +} + size_t ne_fs_spaceUsed(void *_) { return 0; // ultra accurate } @@ -608,6 +630,8 @@ int main() { .set = ne_eeprom_set, .getData = ne_eeprom_getData, .setData = ne_eeprom_setData, + .getArchitecture = ne_eeprom_getArchitecture, + .setArchitecture = ne_eeprom_setArchitecture, .isReadonly = ne_eeprom_isReadonly, .makeReadonly = ne_eeprom_makeReadonly, }; @@ -620,11 +644,11 @@ int main() { nn_filesystemTable genericFSTable = { .userdata = fsFolder, .deinit = NULL, - .getLabel = ne_eeprom_getLabel, - .setLabel = ne_eeprom_setLabel, + .getLabel = ne_fs_getLabel, + .setLabel = ne_fs_setLabel, .spaceUsed = ne_fs_spaceUsed, .spaceTotal = 1*1024*1024, - .isReadOnly = ne_eeprom_isReadonly, + .isReadOnly = ne_fs_isReadOnly, .size = (void *)ne_fs_size, .remove = NULL, .lastModified = (void *)ne_fs_lastModified, diff --git a/src/lock.c b/src/lock.c index c16885d..0790c1c 100644 --- a/src/lock.c +++ b/src/lock.c @@ -19,7 +19,7 @@ static nn_bool_t nni_libcLock(void *_, mtx_t *lock, int action, int flags) { return NN_TRUE; } -nn_LockManager nn_libcMutex() { +nn_LockManager nn_libcMutex(void) { nn_LockManager mgr = {}; mgr.lockSize = sizeof(mtx_t); mgr.userdata = NULL; @@ -33,7 +33,7 @@ static nn_bool_t nni_noLock(void *_, void *__, int action, int flags) { return NN_TRUE; } -nn_LockManager nn_noMutex() { +nn_LockManager nn_noMutex(void) { return (nn_LockManager) { .userdata = NULL, .lockSize = 0, diff --git a/src/neonucleus.h b/src/neonucleus.h index 96f953b..09c28dd 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -13,13 +13,9 @@ #ifdef NN_BIT32 typedef int nn_intptr_t; typedef unsigned int nn_size_t; -#elif defined(__LP64__) || defined(_LP64) - // long is ptr sized - typedef long nn_intptr_t; - typedef unsigned long nn_size_t; #else - typedef long long nn_intptr_t; - typedef unsigned long long nn_size_t; + typedef __INTPTR_TYPE__ nn_intptr_t; + typedef __SIZE_TYPE__ nn_size_t; #endif #else #include @@ -129,6 +125,7 @@ extern "C" { #define NN_LABEL_SIZE 128 #define NN_MAXIMUM_UNICODE_BUFFER 4 +#define NN_MAX_ERROR_BUFFER 128 typedef struct nn_guard nn_guard; #ifdef __STDC_NO_ATOMICS__ @@ -201,7 +198,6 @@ double nn_randf(nn_Rng *rng); // returns from 0 to 1 (exclusive) double nn_randfe(nn_Rng *rng); - typedef struct nn_Context { nn_Alloc allocator; nn_LockManager lockManager; @@ -219,14 +215,21 @@ int nn_strcmp(const char *a, const char *b); nn_size_t nn_strlen(const char *a); #ifndef NN_BAREMETAL -nn_Alloc nn_libcAllocator(); -nn_Clock nn_libcRealTime(); -nn_LockManager nn_libcMutex(); -nn_Rng nn_libcRng(); -nn_Context nn_libcContext(); +nn_Alloc nn_libcAllocator(void); +nn_Clock nn_libcRealTime(void); +nn_LockManager nn_libcMutex(void); +nn_Rng nn_libcRng(void); +nn_Context nn_libcContext(void); #endif -nn_LockManager nn_noMutex(); +nn_LockManager nn_noMutex(void); + +// Error buffers!!! +typedef char nn_errorbuf_t[NN_MAX_ERROR_BUFFER]; + +nn_bool_t nn_error_isEmpty(nn_errorbuf_t buf); +void nn_error_write(nn_errorbuf_t buf, const char *s); +void nn_error_clear(nn_errorbuf_t buf); // Values for architectures @@ -532,7 +535,7 @@ nn_size_t nn_getReturnCount(nn_computer *computer); // Value stuff -nn_value nn_values_nil(); +nn_value nn_values_nil(void); nn_value nn_values_integer(nn_intptr_t integer); nn_value nn_values_number(double num); nn_value nn_values_boolean(nn_bool_t boolean); @@ -609,14 +612,17 @@ typedef struct nn_eepromTable { // methods nn_size_t size; nn_size_t dataSize; - void (*getLabel)(void *userdata, char *buf, nn_size_t *buflen); - nn_size_t (*setLabel)(void *userdata, const char *buf, nn_size_t buflen); - nn_size_t (*get)(void *userdata, char *buf); - void (*set)(void *userdata, const char *buf, nn_size_t len); - int (*getData)(void *userdata, char *buf); - void (*setData)(void *userdata, const char *buf, nn_size_t len); - nn_bool_t (*isReadonly)(void *userdata); - void (*makeReadonly)(void *userdata); + void (*getLabel)(void *userdata, char *buf, nn_size_t *buflen, nn_errorbuf_t error); + nn_size_t (*setLabel)(void *userdata, const char *buf, nn_size_t buflen, nn_errorbuf_t error); + nn_size_t (*get)(void *userdata, char *buf, nn_errorbuf_t error); + nn_bool_t (*set)(void *userdata, const char *buf, nn_size_t len, nn_errorbuf_t error); + nn_size_t (*getData)(void *userdata, char *buf, nn_errorbuf_t error); + nn_bool_t (*setData)(void *userdata, const char *buf, nn_size_t len, nn_errorbuf_t error); + // allocate the string with alloc. We recommend using nn_strdup() + char *(*getArchitecture)(nn_Alloc *alloc, void *userdata, nn_errorbuf_t error); + void (*setArchitecture)(void *userdata, const char *buf, nn_errorbuf_t error); + nn_bool_t (*isReadonly)(void *userdata, nn_errorbuf_t error); + nn_bool_t (*makeReadonly)(void *userdata, nn_errorbuf_t error); } nn_eepromTable; typedef struct nn_eeprom nn_eeprom; diff --git a/src/utils.c b/src/utils.c index c4d15b5..e6bfdf7 100644 --- a/src/utils.c +++ b/src/utils.c @@ -54,7 +54,7 @@ static void *nn_libcAllocProc(void *_, void *ptr, nn_size_t oldSize, nn_size_t n } } -nn_Alloc nn_libcAllocator() { +nn_Alloc nn_libcAllocator(void) { return (nn_Alloc) { .userdata = NULL, .proc = nn_libcAllocProc, @@ -65,7 +65,7 @@ static nn_size_t nni_rand(void *userdata) { return rand(); } -nn_Rng nn_libcRng() { +nn_Rng nn_libcRng(void) { srand(time(NULL)); return (nn_Rng) { .userdata = NULL, @@ -74,7 +74,7 @@ nn_Rng nn_libcRng() { }; } -nn_Context nn_libcContext() { +nn_Context nn_libcContext(void) { return (nn_Context) { .allocator = nn_libcAllocator(), .clock = nn_libcRealTime(), @@ -84,6 +84,7 @@ nn_Context nn_libcContext() { } #endif + // Utilities, both internal and external char *nn_strdup(nn_Alloc *alloc, const char *s) { nn_size_t l = nn_strlen(s); @@ -155,7 +156,7 @@ double nn_randfe(nn_Rng *rng) { #ifdef NN_POSIX -static double nni_realTime() { +static double nni_realTime(void) { struct timespec time; if(clock_gettime(CLOCK_MONOTONIC, &time) < 0) return 0; // oh no return time.tv_sec + ((double)time.tv_nsec) / 1e9; @@ -163,7 +164,7 @@ static double nni_realTime() { #else -static double nni_realTime() { +static double nni_realTime(void) { LARGE_INTEGER frequency = {0}; if(!QueryPerformanceFrequency(&frequency)) return 0; @@ -179,7 +180,7 @@ static double nni_realTimeClock(void *_) { return nni_realTime(); } -nn_Clock nn_libcRealTime() { +nn_Clock nn_libcRealTime(void) { return (nn_Clock) { .userdata = NULL, .proc = nni_realTimeClock, @@ -292,3 +293,20 @@ nn_size_t nn_strlen(const char *a) { while(a[l]) l++; return l; } + +nn_bool_t nn_error_isEmpty(nn_errorbuf_t buf) { + return buf[0] == 0; +} + +void nn_error_write(nn_errorbuf_t buf, const char *s) { + for(nn_size_t i = 0; i < NN_MAX_ERROR_BUFFER; i++) { + buf[i] = s[i]; + if(s[i] == 0) break; + } + // just to be sure + buf[NN_MAX_ERROR_BUFFER-1] = 0; +} + +void nn_error_clear(nn_errorbuf_t buf) { + buf[0] = 0; +} diff --git a/src/value.c b/src/value.c index 4d4877e..246a3bc 100644 --- a/src/value.c +++ b/src/value.c @@ -1,6 +1,6 @@ #include "neonucleus.h" -nn_value nn_values_nil() { +nn_value nn_values_nil(void) { return (nn_value) {.tag = NN_VALUE_NIL}; }