From c3b5e0b68e5eb729f0f8b3e0d9fd6b643627e5e6 Mon Sep 17 00:00:00 2001 From: shariq Date: Wed, 20 Sep 2017 23:16:38 +0500 Subject: [PATCH] Initial work on unified textual resource parsing --- src/common/parser.c | 108 ++++++++++++++++++++++++++++++++++++++++- src/common/parser.h | 1 + src/libsymmetry/game.c | 12 +++++ 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/common/parser.c b/src/common/parser.c index 486c96c..87e7a84 100644 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -7,8 +7,14 @@ #define MAX_LINE_LEN 512 #define MAX_VALUE_LEN 512 -#define QUOTE(str) #str -#define KEY_LEN_STR(LEN) QUOTE(LEN) + +struct Parser_Object +{ + int type; + char* key; + char* value; + char* object_data; +}; bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line) { @@ -60,3 +66,101 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_fun } return true; } + +bool parser_load_objects(FILE* file, const char* filename) +{ + /* Note, this is isn't really a proper parser and might have lurking bugs, it just has to be + good enough for my needs. For example, multiple opening and closing braces on them + same line are fine but opening brace on the same line as type is NOT fine. There + are probably several others that i don't know of yet. This is just a temporary solution, + i may completely change the format in the future or switch to binary or use something like + JSON or TOML etc. */ + + if(!file) + { + log_error("parser:load_objects", "Invalid file handle for file %s", filename); + return false; + } + + int current_line = 0; + char line_buffer[MAX_LINE_LEN]; + char type_str[HASH_MAX_KEY_LEN]; + char obj_str[1024]; + + while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + { + current_line++; + memset(type_str, '\0', HASH_MAX_KEY_LEN); + + if(strlen(line_buffer) == 0 || isspace(line_buffer[0]) != 0) + { + continue; + } + + if(line_buffer[0] == '#') + continue; + + /* Object type */ + if(sscanf(line_buffer, "%s", type_str) != 1) + { + log_warning("Malformed line in config file %s, line %d", filename, current_line); + continue; + } + + long obj_beginning = -1; + long obj_ending = -1; + int obj_begin_expexted_at = current_line + 1; + bool found_next_before_current_ended = false; + + /* Opening brace and closing brace */ + while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + { + current_line++; + if(strchr(line_buffer, '{')) + { + obj_beginning = ftell(file) - strlen(line_buffer); + while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + { + current_line++; + /* check if we found opening brace of next object, + if this is true then it means that this object is missing + it's closing brace and we should stop */ + if(strchr(line_buffer, '{')) + { + found_next_before_current_ended = true; + break; + } + + if(strchr(line_buffer, '}')) + { + obj_ending = ftell(file); + break; + } + } + if(obj_ending) break; + } + } + + if(obj_beginning == -1) + { + log_error("parser:load_object", "Syntax error while loading %s, expected '{' at line %d", filename, obj_begin_expexted_at); + return false; + } + + if(obj_ending == -1) + { + if(found_next_before_current_ended) + log_error("parser:load_object", "Syntax error while loading %s, expected '}' before line %d but found '{'", filename, current_line); + else + log_error("parser:load_object", "Syntax error while loading %s, expected '}' at line %d", filename, current_line); + return false; + } + + memset(obj_str, '\0', 1024); + fseek(file, obj_beginning, SEEK_SET); + fread(obj_str, obj_ending - obj_beginning, 1, file); + log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str); + } + + return true; +} diff --git a/src/common/parser.h b/src/common/parser.h index 5ea0300..42fdb43 100644 --- a/src/common/parser.h +++ b/src/common/parser.h @@ -8,5 +8,6 @@ struct Hashmap; typedef void (*Parser_Assign_Func)(const char* key, const char* value, const char* filename, int current_line); bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line); +bool parser_load_objects(FILE* file, const char* filename); #endif diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index a355ee8..f0c61a7 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -24,6 +24,7 @@ #include "gl_load.h" #include "gui.h" #include "editor.h" +#include "../common/parser.h" #include "../common/hashmap.h" #include "../common/variant.h" #include "../common/common.h" @@ -215,6 +216,17 @@ void scene_setup(void) struct Entity* player = entity_find("player"); game_state->player_node = player->id; } + + FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "r"); + if(obj_file) + { + parser_load_objects(obj_file, "obj_test.symtres"); + fclose(obj_file); + } + else + { + log_warning("Failed to open obj_test.symtres"); + } } void debug(float dt)