fixed simplifyPath
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
125
src/neonucleus.c
125
src/neonucleus.c
@@ -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];
|
||||||
|
size_t slicecount = 0;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while(1) {
|
||||||
if(simplified[i] == '\0') break;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy over
|
||||||
|
nn_strcpy(simplified, resolved);
|
||||||
}
|
}
|
||||||
simplified[j] = '\0';
|
|
||||||
while(simplified[j-1] == '/') {
|
|
||||||
j--;
|
|
||||||
simplified[j] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user