From 3ec27297557b95dfaa080427093cefa524209932 Mon Sep 17 00:00:00 2001 From: antifallobst Date: Fri, 19 May 2023 02:17:15 +0200 Subject: [PATCH] feature (JSON parser): implemented a tokenizer --- inc/boot/config.h | 3 +- inc/drivers/json/json.h | 32 ++++++++ ramdisk/noxos.json | 13 +++ src/boot/config.c | 26 +++++- src/boot/kmain.c | 2 +- src/drivers/json/json.c | 173 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 inc/drivers/json/json.h create mode 100644 ramdisk/noxos.json create mode 100644 src/drivers/json/json.c diff --git a/inc/boot/config.h b/inc/boot/config.h index 13dd990..b75771b 100644 --- a/inc/boot/config.h +++ b/inc/boot/config.h @@ -7,9 +7,10 @@ typedef struct { bool ps2_acpi_validation; + bool log_graphical; } sysconfig_T; -void sysconfig_default_init(); +void sysconfig_init(); extern sysconfig_T* g_sysconfig; diff --git a/inc/drivers/json/json.h b/inc/drivers/json/json.h new file mode 100644 index 0000000..f357cd2 --- /dev/null +++ b/inc/drivers/json/json.h @@ -0,0 +1,32 @@ +// This file is part of noxos and licensed under the MIT open source license + +#ifndef NOXOS_JSON_H +#define NOXOS_JSON_H + +#include +#include + +typedef enum { + JSON_TOKEN_NUMERIC, + JSON_TOKEN_TEXT, + JSON_TOKEN_STRING, + JSON_TOKEN_SPECIAL +} json_token_type_E; + +typedef struct { + json_token_type_E type; + uint64_t value; + string_t string; +} json_token_T; + +typedef struct { + json_token_T* tokens; + uint64_t num_tokens; + void* string_buffer; +} json_T; + +json_T* json_from_string(string_t str); +void json_destruct (json_T* json); +void json_tokenize (json_T* json, string_t str); + +#endif //NOXOS_JSON_H diff --git a/ramdisk/noxos.json b/ramdisk/noxos.json new file mode 100644 index 0000000..277337a --- /dev/null +++ b/ramdisk/noxos.json @@ -0,0 +1,13 @@ +{ + "PS2_ACPI_VALIDATION": true, + "LOG_GRAPHICAL": false, + + "dec": 1312, + "hex": 0x520, + "bin": 0b10100100000, + "oct": 0o2440, + + "modules": { + "FAT32": "/initrd/modules/fat32.nxmod" + } +} \ No newline at end of file diff --git a/src/boot/config.c b/src/boot/config.c index f179a5f..8641346 100644 --- a/src/boot/config.c +++ b/src/boot/config.c @@ -1,10 +1,32 @@ // This file is part of noxos and licensed under the MIT open source license -#include "boot/config.h" +#include +#include +#include +#include +#include sysconfig_T G_sysconfig; sysconfig_T* g_sysconfig = &G_sysconfig; -void sysconfig_default_init() { +void sysconfig_init() { g_sysconfig->ps2_acpi_validation = true; + g_sysconfig->log_graphical = false; + + vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/noxos.json"); + if (node == NULL || node->type != VFS_NODE_FILE) { + log(LOG_WARNING, "No system config file found, falling back to standard values"); + return; + } + + char* buffer = memory_allocate(node->size + 1); + vfs_file_read(node, 0, node->size, buffer); + buffer[node->size] = 0; + + json_T* json = json_from_string(buffer); + + + json_destruct(json); + + memory_free(buffer); } \ No newline at end of file diff --git a/src/boot/kmain.c b/src/boot/kmain.c index a8b3301..61c1e92 100644 --- a/src/boot/kmain.c +++ b/src/boot/kmain.c @@ -45,7 +45,7 @@ void kernel_init(boot_info_T* boot_info) { vfs_init(boot_info); - sysconfig_default_init(); + sysconfig_init(); scheduler_init(boot_info); diff --git a/src/drivers/json/json.c b/src/drivers/json/json.c new file mode 100644 index 0000000..f0e91e7 --- /dev/null +++ b/src/drivers/json/json.c @@ -0,0 +1,173 @@ +// This file is part of cmlc and licensed under the MIT open source license + +#include +#include +#include + +json_T* json_from_string(string_t str) { + json_T* json = memory_allocate(sizeof(json_T)); + + DEBUG("%s", str); + + json_tokenize(json, str); + + return json; +} + +void json_destruct(json_T* json) { + memory_free(json->string_buffer); + memory_free(json->tokens); + memory_free(json); +} + +uint64_t json_get_num_tokens(string_t str) { + uint32_t num = 0; + + while (*str != '\0') { + if (*str == '"') { + str++; + while (*str != '\0' && *str != '"') { + str++; + } + num++; + str++; + continue; + } + + if (string_is_char_special(*str)) { + num++; + str++; + continue; + } + + if (string_is_char_number(*str)) { + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'b' || str[1] == 'o')) { + str += 2; + } + while (*str != '\0' && string_is_char_number(*str)) { + str++; + } + num++; + continue; + } + + if (string_is_char_alpha(*str)) { + while (*str != '\0' && string_is_char_alpha(*str)) { + str++; + } + num++; + continue; + } + + str++; + } + + return num; +} + +void json_tokenize(json_T* json, string_t str) { + json->num_tokens = json_get_num_tokens(str); + json->tokens = memory_allocate(json->num_tokens * sizeof(json_token_T)); + json->string_buffer = memory_allocate(string_length(str) + json->num_tokens); + + string_t string = json->string_buffer; + json_token_T* token = &json->tokens[0]; + uint32_t i = 0; + while (*str != '\0') { + if (*str == '"') { + token->type = JSON_TOKEN_STRING; + token->value = 0; + + str++; + + uint32_t length = 0; + while (str[length] != '\0' && str[length] != '"') { + length++; + } + + token->string = string; + memory_copy(str, string, length); + ((char*)string)[length] = '\0'; + DEBUG("token: %d STRING %s", i++, token->string); + + string = &string[length + 1]; + token = &token[1]; + str += length + 1; + continue; + } + + if (string_is_char_special(*str)) { + token->type = JSON_TOKEN_SPECIAL; + token->value = 0; + + token->string = string; + *(char*)string = *str; + ((char*)string)[1] = '\0'; + + DEBUG("token: %d SPECIAL %s", i++, token->string); + + string = &string[2]; + token = &token[1]; + str += 1; + continue; + } + + if (string_is_char_number(*str)) { + token->type = JSON_TOKEN_NUMERIC; + token->value = 0; + + uint8_t base = 10; + uint32_t length = 0; + + if (str[0] == '0' && str[1] == 'x') { + base = 16; + length = 2; + } else if (str[0] == '0' && str[1] == 'b') { + base = 2; + length = 2; + } else if (str[0] == '0' && str[1] == 'o') { + base = 8; + length = 2; + } + + while (str[length] != '\0' && string_is_char_number(str[length])) { + token->value *= base; + token->value += str[length] - '0'; + length++; + } + + token->string = string; + memory_copy(str, string, length); + ((char*)string)[length] = '\0'; + DEBUG("token: %d NUM %s %d", i++, token->string, token->value); + + string = &string[length + 1]; + token = &token[1]; + str += length; + continue; + } + + if (string_is_char_alpha(*str)) { + token->type = JSON_TOKEN_TEXT; + token->value = 0; + + uint32_t length = 0; + while (str[length] != '\0' && string_is_char_alpha(str[length])) { + length++; + } + + token->string = string; + memory_copy(str, string, length); + ((char*)string)[length] = '\0'; + DEBUG("token: %d TEXT %s", i++, token->string); + + string = &string[length]; + token = &token[1]; + str += length; + continue; + } + + str++; + } + +} \ No newline at end of file