feature (JSON parser): implemented a tokenizer

This commit is contained in:
antifallobst 2023-05-19 02:17:15 +02:00
parent c60e8f9564
commit 3ec2729755
6 changed files with 245 additions and 4 deletions

View File

@ -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;

32
inc/drivers/json/json.h Normal file
View File

@ -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 <utils/string.h>
#include <utils/stdtypes.h>
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

13
ramdisk/noxos.json Normal file
View File

@ -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"
}
}

View File

@ -1,10 +1,32 @@
// This file is part of noxos and licensed under the MIT open source license
#include "boot/config.h"
#include <boot/config.h>
#include <drivers/fs/vfs.h>
#include <drivers/json/json.h>
#include <utils/logger.h>
#include <utils/memory.h>
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);
}

View File

@ -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);

173
src/drivers/json/json.c Normal file
View File

@ -0,0 +1,173 @@
// This file is part of cmlc and licensed under the MIT open source license
#include <drivers/json/json.h>
#include <utils/memory.h>
#include <utils/logger.h>
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++;
}
}