feature (JSON parser): implemented a tokenizer
This commit is contained in:
parent
c60e8f9564
commit
3ec2729755
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue