Each file now has a separate Parser allocated for it which holds all the

parsed objects from the file in their intermediary state. These will be
consumed by the caller into their actual in-game representations
dev
Shariq Shah 8 years ago
parent 83255ae281
commit 114d44371e
  1. 98
      src/common/parser.c
  2. 25
      src/common/parser.h
  3. 18
      src/libsymmetry/game.c

@ -1,20 +1,18 @@
#include "parser.h"
#include "hashmap.h"
#include "array.h"
#include "log.h"
#include "string_utils.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_LINE_LEN 512
#define MAX_VALUE_LEN 512
struct Parser_Object
{
int type;
char* key;
char* value;
char* object_data;
};
static int parser_object_type_from_str(const char* str);
bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line)
{
@ -37,6 +35,7 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_fun
char line_buffer[MAX_LINE_LEN];
memset(key_str, '\0', HASH_MAX_KEY_LEN);
memset(line_buffer, '\0', MAX_LINE_LEN);
memset(format_str, '\0', 64);
snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN);
while(fgets(line_buffer, MAX_LINE_LEN - 1, file))
@ -67,7 +66,7 @@ bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_fun
return true;
}
bool parser_load_objects(FILE* file, const char* filename)
struct Parser* 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
@ -82,6 +81,16 @@ bool parser_load_objects(FILE* file, const char* filename)
return false;
}
struct Parser* parser = malloc(sizeof(*parser));
if(!parser)
{
log_error("parser:load_objects", "Out of memeory");
return parser;
}
parser->filename = str_new(filename);
parser->objects = array_new(struct Parser_Object);
int current_line = 0;
char line_buffer[MAX_LINE_LEN];
char type_str[HASH_MAX_KEY_LEN];
@ -136,7 +145,7 @@ bool parser_load_objects(FILE* file, const char* filename)
if(c == '{')
{
obj_beginning = ftell(file) - 1;
obj_beginning = ftell(file);
c = ' ';
while(!feof(file))
{
@ -158,7 +167,7 @@ bool parser_load_objects(FILE* file, const char* filename)
if(c == '}')
{
obj_ending = ftell(file);
obj_ending = ftell(file) - 1;
break;
}
}
@ -185,8 +194,73 @@ bool parser_load_objects(FILE* file, const char* filename)
memset(line_buffer, '\0', MAX_LINE_LEN);
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);
fseek(file, obj_ending + 1, SEEK_SET); // Position cursor after closing brace '}'
// Read into intermediate parser object and add it to the objects list
struct Parser_Object* object = array_grow(parser->objects, struct Parser_Object);
object->type = parser_object_type_from_str(type_str);
object->data = hashmap_new();
char format_str[64];
char key_str[HASH_MAX_KEY_LEN];
char value_str[MAX_VALUE_LEN];
memset(format_str, '\0', 64);
snprintf(format_str, 64, " %%%d[^: ] : %%%d[^\n]", HASH_MAX_KEY_LEN, MAX_VALUE_LEN);
char* line = strtok(obj_str, "\n");
do
{
memset(key_str, '\0', HASH_MAX_KEY_LEN);
memset(value_str, '\0', MAX_VALUE_LEN);
if(strlen(line) == 0)
{
continue;
}
if(line[0] == '#')
continue;
if(sscanf(line, format_str, key_str, value_str) != 2)
{
log_warning("Malformed value in config file %s, line %d", filename, current_line);
continue;
}
hashmap_str_set(object->data, key_str, value_str);
}
while((line = strtok(NULL, "\n")) != NULL);
//log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str);
}
return true;
return parser;
}
int parser_object_type_from_str(const char* str)
{
int object_type = PO_UNKNOWN;
if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY;
else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL;
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
return object_type;
}
void parser_free(struct Parser *parser)
{
assert(parser);
if(parser->filename)
{
free(parser->filename);
parser->filename = NULL;
}
for(int i = 0; i < array_len(parser->objects); i++)
{
struct Parser_Object* object = &parser->objects[i];
hashmap_free(object->data);
object->data = NULL;
object->type = PO_UNKNOWN;
}
}

@ -3,11 +3,30 @@
#include "common.h"
struct Hashmap;
enum Parser_Object_Type
{
PO_ENTITY,
PO_MATERIAL,
PO_MODEL,
PO_UNKNOWN
};
struct Parser_Object
{
int type;
struct Hashmap* data;
};
struct Parser
{
char* filename;
struct Parser_Object* objects;
};
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);
bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line);
struct Parser* parser_load_objects(FILE* file, const char* filename);
void parser_free(struct Parser* parser);
#endif

@ -217,10 +217,24 @@ void scene_setup(void)
game_state->player_node = player->id;
}
FILE* obj_file = platform->file.open(DIRT_INSTALL, "test_scene.symtres", "rb");
FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "rb");
if(obj_file)
{
parser_load_objects(obj_file, "obj_test.symtres");
struct Parser* parsed_file = parser_load_objects(obj_file, "obj_test.symtres");
log_message("%d objects read from %s", array_len(parsed_file->objects), "obj_test.symtres");
for(int i = 0; i < array_len(parsed_file->objects); i++)
{
struct Parser_Object* object = &parsed_file->objects[i];
if(object->type == PO_UNKNOWN)
log_message("Type : Unknown");
else if(object->type == PO_ENTITY)
log_message("Type : Entity");
else if(object->type == PO_MATERIAL)
log_message("Type : Material");
else if(object->type == PO_MODEL)
log_message("Type : Model");
hashmap_debug_print(object->data);
}
fclose(obj_file);
}
else

Loading…
Cancel
Save