Initial work on unified textual resource parsing

dev
shariq 8 years ago
parent ce88b828d7
commit c3b5e0b68e
  1. 108
      src/common/parser.c
  2. 1
      src/common/parser.h
  3. 12
      src/libsymmetry/game.c

@ -7,8 +7,14 @@
#define MAX_LINE_LEN 512 #define MAX_LINE_LEN 512
#define MAX_VALUE_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) 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; 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;
}

@ -8,5 +8,6 @@ struct Hashmap;
typedef void (*Parser_Assign_Func)(const char* key, const char* value, const char* filename, int current_line); 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(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 #endif

@ -24,6 +24,7 @@
#include "gl_load.h" #include "gl_load.h"
#include "gui.h" #include "gui.h"
#include "editor.h" #include "editor.h"
#include "../common/parser.h"
#include "../common/hashmap.h" #include "../common/hashmap.h"
#include "../common/variant.h" #include "../common/variant.h"
#include "../common/common.h" #include "../common/common.h"
@ -215,6 +216,17 @@ void scene_setup(void)
struct Entity* player = entity_find("player"); struct Entity* player = entity_find("player");
game_state->player_node = player->id; 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) void debug(float dt)

Loading…
Cancel
Save