fixed simplifyPath

This commit is contained in:
2026-03-16 21:57:18 +01:00
parent 841241833d
commit 3045a86cd9
3 changed files with 97 additions and 56 deletions

View File

@@ -34,7 +34,7 @@ The structures in this spec will be written as C structs. A `char` is 1 byte, a
struct nnfs_header { struct nnfs_header {
char header[5] = "NNFS\0"; // stores a 5 byte NULL-terminated string as the header of the entire file. char header[5] = "NNFS\0"; // stores a 5 byte NULL-terminated string as the header of the entire file.
varint_t version = 0; // 0 for the current version varint_t version = 0; // 0 for the current version
char label[]; // NULL-terminated string for the label char label[]; // NULL-terminated string for the label. Empty string means no label.
varint_t capacity; varint_t capacity;
varint_t flags; varint_t flags;
varint_t compression; varint_t compression;
@@ -88,7 +88,7 @@ The length of `a` would be 2, as it has `foo.txt` and `b`, and `b`'s would be 1.
struct nniso_header { struct nniso_header {
char header[6] = "NNISO\0"; // stores a 5 byte NULL-terminated string as the header of the entire file. char header[6] = "NNISO\0"; // stores a 5 byte NULL-terminated string as the header of the entire file.
varint_t version = 0; // 0 for the current version varint_t version = 0; // 0 for the current version
char label[]; // NULL-terminated string for the label char label[]; // NULL-terminated string for the label. Empty string means no label.
varint_t capacity; varint_t capacity;
varint_t sectorSize; varint_t sectorSize;
varint_t flags; varint_t flags;

View File

@@ -180,12 +180,32 @@ size_t nn_strlen(const char *s) {
return l; return l;
} }
size_t nn_strlenUntil(const char *s, char sep) {
size_t l = 0;
while(1) {
char c = s[l];
if(c == '\0') break;
if(c == sep) break;
l++;
}
return l;
}
void nn_memcpy(void *dest, const void *src, size_t len) { void nn_memcpy(void *dest, const void *src, size_t len) {
char *out = (char *)dest; char *out = (char *)dest;
const char *in = (const char *)src; const char *in = (const char *)src;
for(size_t i = 0; i < len; i++) out[i] = in[i]; for(size_t i = 0; i < len; i++) out[i] = in[i];
} }
void nn_strcpy(char *dest, const char *src) {
while(1) {
*dest = *src;
if(*src == '\0') break;
dest++;
src++;
}
}
char *nn_strdup(nn_Context *ctx, const char *s) { char *nn_strdup(nn_Context *ctx, const char *s) {
size_t l = nn_strlen(s); size_t l = nn_strlen(s);
char *buf = nn_alloc(ctx, sizeof(char) * (l+1)); char *buf = nn_alloc(ctx, sizeof(char) * (l+1));
@@ -309,43 +329,61 @@ void nn_crc32ChecksumBytes(unsigned int checksum, char out[8]) {
} }
} }
// TODO: rework completely static bool nn_isLiterallyJust(const char *s, size_t len, char c) {
// apparently can overflow?? for(size_t i = 0; i < len; i++) if(s[i] != c) return false;
bool nn_simplifyPath(const char original[NN_MAX_PATH], char simplified[NN_MAX_PATH]) { return true;
}
void nn_simplifyPath(const char original[NN_MAX_PATH], char simplified[NN_MAX_PATH]) {
// pass 1: check for valid characters, and \ becomes / // pass 1: check for valid characters, and \ becomes /
for(size_t i = 0; true; i++) { for(size_t i = 0; true; i++) {
if(original[i] == '\\') simplified[i] = '/'; if(original[i] == '\\') simplified[i] = '/';
else simplified[i] = original[i]; else simplified[i] = original[i];
if(original[i] == '\0') break; if(original[i] == '\0') break;
} }
// get rid of //, starting / and ending / // this is similar to KOCOS pathfixing
// in https://github.com/NeoFlock/onyx-os/blob/main/usr/src/kocos/fs.lua#L237
{ {
while(simplified[0] == '/') { char resolved[NN_MAX_PATH];
for(size_t i = 1; true; i++) {
simplified[i-1] = simplified[i]; struct {const char *mem; size_t len;} slices[NN_MAX_PATH];
if(simplified[i] == '\0') break; size_t slicecount = 0;
size_t i = 0;
while(1) {
if(simplified[i] == '\0') break;
char *mem = simplified + i;
size_t sublen = nn_strlenUntil(mem, '/');
if(sublen == 0) {
i++;
continue;
} }
slices[slicecount].mem = mem;
slices[slicecount].len = sublen;
slicecount++;
if(nn_isLiterallyJust(mem, sublen, '.')) {
// no underflow for u
if(slicecount < sublen) slicecount = sublen;
slicecount -= sublen;
}
if(mem[sublen] == '\0') break;
i += sublen + 1;
} }
size_t j = 0; // concat into resolved
for(size_t i = 0; simplified[i] != '\0'; i++) { size_t resolvedLen = 0;
if(simplified[i] == '/' && simplified[i+1] == '/') { for(size_t i = 0; i < slicecount; i++) {
// simply discard it bool isLast = (i == (slicecount - 1));
continue; char *dest = resolved + resolvedLen;
} else { nn_memcpy(dest, slices[i].mem, slices[i].len);
simplified[j] = simplified[i]; dest[slices[i].len] = isLast ? '\0' : '/';
j++; resolvedLen += slices[i].len + 1;
}
}
simplified[j] = '\0';
while(simplified[j-1] == '/') {
j--;
simplified[j] = '\0';
} }
// copy over
nn_strcpy(simplified, resolved);
} }
// TODO: handle ..
// valid
return true;
} }
int nn_memcmp(const char *a, const char *b, size_t len) { int nn_memcmp(const char *a, const char *b, size_t len) {
@@ -593,7 +631,13 @@ typedef struct nn_HashMap {
const nn_HashContext *hash; const nn_HashContext *hash;
} nn_HashMap; } nn_HashMap;
// tells hashmaps to scale the capacity by this much
#ifndef NN_HASH_MULTIPLIER
#define NN_HASH_MULTIPLIER 32
#endif
nn_Exit nn_hashInit(nn_HashMap *map, size_t capacity, nn_Context *ctx, const nn_HashContext *hash) { nn_Exit nn_hashInit(nn_HashMap *map, size_t capacity, nn_Context *ctx, const nn_HashContext *hash) {
capacity *= NN_HASH_MULTIPLIER;
void *buf = nn_alloc(ctx, hash->entSize * capacity); void *buf = nn_alloc(ctx, hash->entSize * capacity);
if(buf == NULL) return NN_ENOMEM; if(buf == NULL) return NN_ENOMEM;
map->buf = buf; map->buf = buf;
@@ -648,7 +692,7 @@ bool nn_hashPut(nn_HashMap *map, void *entry) {
if(entry == NULL) return false; if(entry == NULL) return false;
size_t len = map->bufsize; size_t len = map->bufsize;
if(len == 0) return false; if(len == 0) return false;
size_t base = nn_hashGetHash(map, entry) % len; size_t base = nn_hashGetHash(map, entry);
size_t entSize = map->hash->entSize; size_t entSize = map->hash->entSize;
for(size_t i = 0; i < len; i++) { for(size_t i = 0; i < len; i++) {
size_t j = (base + i) % len; size_t j = (base + i) % len;
@@ -661,8 +705,9 @@ bool nn_hashPut(nn_HashMap *map, void *entry) {
nn_memcpy(slot, entry, entSize); nn_memcpy(slot, entry, entSize);
return true; return true;
case NN_HASH_DIFFERENT: case NN_HASH_DIFFERENT:
continue; break;
} }
printf("hash put wrong\n");
} }
return false; return false;
} }
@@ -980,7 +1025,7 @@ nn_Computer *nn_createComputer(nn_Universe *universe, void *userdata, const char
c->desiredArch.name = NULL; c->desiredArch.name = NULL;
c->archState = NULL; c->archState = NULL;
c->totalCallBudget = 50000; c->totalCallBudget = 1000000;
c->callBudget = c->totalCallBudget; c->callBudget = c->totalCallBudget;
if(nn_hashInit(&c->components, maxComponents, ctx, &nn_componentHasher)) { if(nn_hashInit(&c->components, maxComponents, ctx, &nn_componentHasher)) {
@@ -1519,7 +1564,6 @@ const char *nn_getNextComponent(nn_Computer *computer, const char *prev) {
return c->address; return c->address;
} }
nn_Component *c = nn_getInternalComponent(computer, prev); nn_Component *c = nn_getInternalComponent(computer, prev);
printf("cur addr iter: %s comp: %p\n", prev == NULL ? "(null)" : prev, c);
if(c == NULL) return NULL; if(c == NULL) return NULL;
c = nn_hashIterate(&computer->components, c); c = nn_hashIterate(&computer->components, c);
if(c == NULL) return NULL; if(c == NULL) return NULL;
@@ -2309,18 +2353,7 @@ nn_Exit nn_eeprom_handler(nn_ComponentRequest *req) {
return NN_OK; return NN_OK;
} }
nn_EEPROM nn_defaultEEPROM = (nn_EEPROM) { const nn_EEPROM nn_defaultEEPROMs[4] = {
.size = 4 * NN_KiB,
.dataSize = 256,
.readEnergyCost = 1,
.writeEnergyCost = 100,
.readDataEnergyCost = 0.1,
.writeDataEnergyCost = 5,
.writeDelay = 2,
.writeDataDelay = 1,
};
nn_EEPROM nn_defaultEEPROMs[4] = {
(nn_EEPROM) { (nn_EEPROM) {
.size = 4 * NN_KiB, .size = 4 * NN_KiB,
.dataSize = 256, .dataSize = 256,
@@ -2499,7 +2532,7 @@ typedef struct nn_Filesystem_state {
nn_Filesystem fs; nn_Filesystem fs;
} nn_Filesystem_state; } nn_Filesystem_state;
nn_Filesystem nn_defaultFilesystems[4] = { const nn_Filesystem nn_defaultFilesystems[4] = {
(nn_Filesystem) { (nn_Filesystem) {
.spaceTotal = 1 * NN_MiB, .spaceTotal = 1 * NN_MiB,
.readsPerTick = 4, .readsPerTick = 4,
@@ -2527,14 +2560,14 @@ nn_Filesystem nn_defaultFilesystems[4] = {
}; };
nn_Filesystem nn_defaultFloppy = (nn_Filesystem) { const nn_Filesystem nn_defaultFloppy = (nn_Filesystem) {
.spaceTotal = 512 * NN_KiB, .spaceTotal = 512 * NN_KiB,
.readsPerTick = 1, .readsPerTick = 1,
.writesPerTick = 1, .writesPerTick = 1,
.dataEnergyCost = 8.0 / NN_MiB, .dataEnergyCost = 8.0 / NN_MiB,
}; };
nn_Filesystem nn_defaultTmpFS = (nn_Filesystem) { const nn_Filesystem nn_defaultTmpFS = (nn_Filesystem) {
.spaceTotal = 64 * NN_KiB, .spaceTotal = 64 * NN_KiB,
.readsPerTick = 1024, .readsPerTick = 1024,
.writesPerTick = 512, .writesPerTick = 512,
@@ -2880,7 +2913,7 @@ nn_ComponentState *nn_createFilesystem(nn_Universe *universe, const nn_Filesyste
return t; return t;
} }
nn_Drive nn_defaultDrives[4] = { const nn_Drive nn_defaultDrives[4] = {
(nn_Drive) { (nn_Drive) {
.capacity = 1 * NN_MiB, .capacity = 1 * NN_MiB,
.sectorSize = 512, .sectorSize = 512,
@@ -3204,7 +3237,7 @@ cleanup:
return NULL; return NULL;
} }
nn_ScreenConfig nn_defaultScreens[4] = { const nn_ScreenConfig nn_defaultScreens[4] = {
(nn_ScreenConfig) { (nn_ScreenConfig) {
.maxWidth = 50, .maxWidth = 50,
.maxHeight = 16, .maxHeight = 16,
@@ -3364,7 +3397,7 @@ nn_ComponentState *nn_createKeyboard(nn_Universe *universe) {
return nn_createComponentState(universe, "keyboard", NULL, methods, nn_keyboard_handler); return nn_createComponentState(universe, "keyboard", NULL, methods, nn_keyboard_handler);
} }
nn_GPU nn_defaultGPUs[4] = { const nn_GPU nn_defaultGPUs[4] = {
(nn_GPU) { (nn_GPU) {
.maxWidth = 50, .maxWidth = 50,
.maxHeight = 16, .maxHeight = 16,

View File

@@ -227,6 +227,14 @@ void *nn_alloc(nn_Context *ctx, size_t size);
void nn_free(nn_Context *ctx, void *memory, size_t size); void nn_free(nn_Context *ctx, void *memory, size_t size);
void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize); void *nn_realloc(nn_Context *ctx, void *memory, size_t oldSize, size_t newSize);
// Basic utils
// Does canonical path handling. Is used for sandboxing paths.
// It will turn \ to /, will turn invalid characters into spaces,
// and will resolve ...
// it also gets rid of / prefixes, / suffixes and //
void nn_simplifyPath(const char original[NN_MAX_PATH], char simplified[NN_MAX_PATH]);
typedef enum nn_Exit { typedef enum nn_Exit {
// no error // no error
NN_OK = 0, NN_OK = 0,
@@ -861,7 +869,7 @@ typedef struct nn_EEPROM {
// Tier 2 - A better EEPROM // Tier 2 - A better EEPROM
// Tier 3 - An even better EEPROM // Tier 3 - An even better EEPROM
// Tier 4- The best EEPROM // Tier 4- The best EEPROM
extern nn_EEPROM nn_defaultEEPROMs[4]; extern const nn_EEPROM nn_defaultEEPROMs[4];
typedef struct nn_VEEPROM { typedef struct nn_VEEPROM {
const char *code; const char *code;
@@ -1035,11 +1043,11 @@ typedef struct nn_Filesystem {
// 1 - Tier 2 equivalent // 1 - Tier 2 equivalent
// 2 - Tier 3 equivalent // 2 - Tier 3 equivalent
// 3 - Tier 4, a better version of Tier 3. // 3 - Tier 4, a better version of Tier 3.
extern nn_Filesystem nn_defaultFilesystems[4]; extern const nn_Filesystem nn_defaultFilesystems[4];
// a basic floppy // a basic floppy
extern nn_Filesystem nn_defaultFloppy; extern const nn_Filesystem nn_defaultFloppy;
// a generic tmpfs // a generic tmpfs
extern nn_Filesystem nn_defaultTmpFS; extern const nn_Filesystem nn_defaultTmpFS;
typedef nn_Exit nn_FilesystemHandler(nn_FilesystemRequest *request); typedef nn_Exit nn_FilesystemHandler(nn_FilesystemRequest *request);
@@ -1182,7 +1190,7 @@ typedef struct nn_VDrive {
size_t datalen; size_t datalen;
} nn_VDrive; } nn_VDrive;
extern nn_Drive nn_defaultDrives[4]; extern const nn_Drive nn_defaultDrives[4];
nn_ComponentState *nn_createDrive(nn_Universe *universe, const nn_Drive *drive, nn_DriveHandler *handler, void *userdata); nn_ComponentState *nn_createDrive(nn_Universe *universe, const nn_Drive *drive, nn_DriveHandler *handler, void *userdata);
nn_ComponentState *nn_createVDrive(nn_Universe *universe, const nn_Drive *drive, const nn_VDrive *vdrive); nn_ComponentState *nn_createVDrive(nn_Universe *universe, const nn_Drive *drive, const nn_VDrive *vdrive);
@@ -1270,7 +1278,7 @@ typedef struct nn_ScreenConfig {
} nn_ScreenConfig; } nn_ScreenConfig;
// OC has 3 tiers, NN adds a 4th one as well. // OC has 3 tiers, NN adds a 4th one as well.
extern nn_ScreenConfig nn_defaultScreens[4]; extern const nn_ScreenConfig nn_defaultScreens[4];
typedef nn_Exit nn_ScreenHandler(nn_ScreenRequest *req); typedef nn_Exit nn_ScreenHandler(nn_ScreenRequest *req);
@@ -1480,7 +1488,7 @@ typedef struct nn_GPU {
typedef nn_Exit nn_GPUHandler(nn_GPURequest *req); typedef nn_Exit nn_GPUHandler(nn_GPURequest *req);
// 1 GPU tier for every screen. // 1 GPU tier for every screen.
extern nn_GPU nn_defaultGPUs[4]; extern const nn_GPU nn_defaultGPUs[4];
nn_ComponentState *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata); nn_ComponentState *nn_createGPU(nn_Universe *universe, const nn_GPU *gpu, nn_GPUHandler *handler, void *userdata);