commit d4796cc65e60ae8fba8e1e570135c3d746ed769d
parent 55dfefbb3da4c763960946467649e387ad1477c7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 18 Nov 2016 14:53:15 +0100
Implement and test the solstice_parser_find_entity function
Diffstat:
3 files changed, 115 insertions(+), 21 deletions(-)
diff --git a/src/solstice_parser.c b/src/solstice_parser.c
@@ -169,8 +169,6 @@ struct solstice_parser {
struct htable_str2sols str2entities;
struct darray_entity entities;
- /* Miscellaneous */
-
ref_T ref;
struct mem_allocator* allocator;
};
@@ -1998,6 +1996,30 @@ error:
goto exit;
}
+static res_T
+parse_entity_name
+ (struct solstice_parser* parser,
+ yaml_node_t* name,
+ struct str* str)
+{
+ res_T res = RES_OK;
+ ASSERT(parser && name && str);
+
+ res = parse_string(parser, name, str);
+ if(res != RES_OK) goto error;
+
+ if(strchr(str_cget(str), '.')) {
+ log_err(parser, name, "invalid character `.' in the entity name `%s'.\n",
+ str_cget(str));
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
res_T
parse_entity
(struct solstice_parser* parser,
@@ -2070,7 +2092,7 @@ parse_entity
res = parse_geometry(parser, doc, val, &solent->geometry);
} else if(!strcmp((char*)key->data.scalar.value, "name")) {
SETUP_MASK(NAME, "name");
- res = parse_string(parser, val, &solent->name);
+ res = parse_entity_name(parser, val, &solent->name);
} else if(!strcmp((char*)key->data.scalar.value, "pivot")) {
SETUP_MASK(DATA, "data");
res = parse_pivot(parser, doc, val);
@@ -2764,6 +2786,60 @@ error:
}
const struct solstice_entity*
+solstice_parser_find_entity
+ (struct solstice_parser* parser, const char* name)
+{
+ struct htable_str2sols* htable = NULL;
+ struct solstice_entity* entity = NULL;
+ struct str str;
+ struct str str_tk;
+ char* cstr;
+ char* tk;
+ res_T res = RES_OK;
+ ASSERT(parser && name);
+
+ str_init(parser->allocator, &str);
+ str_init(parser->allocator, &str_tk);
+
+ res = str_set(&str, name);
+ if(res != RES_OK) {
+ fprintf(stderr, "%s: could not copy the input string.\n",
+ FUNC_NAME);
+ goto error;
+ }
+ res = str_reserve(&str_tk, str_len(&str));
+ if(res != RES_OK) {
+ fprintf(stderr, "%s: could not allocate the temporary token sting.\n",
+ FUNC_NAME);
+ goto error;
+ }
+
+ cstr = str_get(&str);
+ tk = strtok(cstr, ".");
+ htable = &parser->str2entities;
+ while(tk) {
+ size_t* pientity;
+ str_set(&str_tk, tk);
+ pientity = htable_str2sols_find(htable, &str_tk);
+ if(!pientity) {
+ tk = NULL;
+ } else {
+ tk = strtok(NULL, ".");
+ entity = darray_entity_data_get(&parser->entities) + *pientity;
+ htable = &entity->str2children;
+ }
+ }
+
+exit:
+ str_release(&str);
+ str_release(&str_tk);
+ return entity;
+error:
+ entity = NULL;
+ goto exit;
+}
+
+const struct solstice_entity*
solstice_parser_get_entity
(const struct solstice_parser* parser,
const struct solstice_entity_id entity)
diff --git a/src/solstice_parser.h b/src/solstice_parser.h
@@ -53,6 +53,12 @@ extern LOCAL_SYM res_T
solstice_parser_load
(struct solstice_parser* parser);
+/* Return NULL if the no entity is found */
+extern LOCAL_SYM const struct solstice_entity*
+solstice_parser_find_entity
+ (struct solstice_parser* parser,
+ const char* entity_name);
+
extern LOCAL_SYM const struct solstice_entity*
solstice_parser_get_entity
(const struct solstice_parser* parser,
diff --git a/src/test_solstice_parser2.c b/src/test_solstice_parser2.c
@@ -25,7 +25,7 @@ main(int argc, char** argv)
struct solstice_entity_id entity_id;
struct solstice_object_id obj_id;
struct solstice_geometry_id geom_id;
- const struct solstice_entity* entity, *entity1, *entity2;
+ const struct solstice_entity* entity, *entity1a, *entity1b, *entity2, *entity3;
const struct solstice_geometry* geom;
const struct solstice_object* obj;
const struct solstice_shape* shape;
@@ -49,7 +49,7 @@ main(int argc, char** argv)
fprintf(stream, " - sphere: { radius: 1 }\n");
fprintf(stream, " material: { matte: { reflectivity: 1 } }\n");
fprintf(stream, "- entity:\n");
- fprintf(stream, " name: lvl0\n");
+ fprintf(stream, " name: lvl 0\n");
fprintf(stream, " geometry: *sphere\n");
fprintf(stream, " transform: { translation: [1,2,3], rotation: [4,5,6]}\n");
fprintf(stream, " children:\n");
@@ -84,7 +84,7 @@ main(int argc, char** argv)
CHECK(d3_eq(entity->translation, d3(tmp, 1, 2, 3)), 1);
CHECK(d3_eq(entity->rotation, d3(tmp, 4, 5, 6)), 1);
- CHECK(strcmp("lvl0", str_cget(&entity->name)), 0);
+ CHECK(strcmp("lvl 0", str_cget(&entity->name)), 0);
CHECK(solstice_entity_get_children_count(entity), 2);
geom_id = entity->geometry;
geom = solstice_parser_get_geometry(parser, entity->geometry);
@@ -105,13 +105,13 @@ main(int argc, char** argv)
CHECK(matte->reflectivity, 1);
entity_id = solstice_entity_get_child(entity, 0);
- entity1 = solstice_parser_get_entity(parser, entity_id);
- CHECK(d3_eq(entity1->translation, d3_splat(tmp, 0)), 1);
- CHECK(d3_eq(entity1->rotation, d3_splat(tmp, 0)), 1);
- CHECK(strcmp("lvl1a", str_cget(&entity1->name)), 0);
- CHECK(solstice_entity_get_children_count(entity1), 0);
- NCHECK(entity1->geometry.i, geom_id.i);
- geom = solstice_parser_get_geometry(parser, entity1->geometry);
+ entity1a = solstice_parser_get_entity(parser, entity_id);
+ CHECK(d3_eq(entity1a->translation, d3_splat(tmp, 0)), 1);
+ CHECK(d3_eq(entity1a->rotation, d3_splat(tmp, 0)), 1);
+ CHECK(strcmp("lvl1a", str_cget(&entity1a->name)), 0);
+ CHECK(solstice_entity_get_children_count(entity1a), 0);
+ NCHECK(entity1a->geometry.i, geom_id.i);
+ geom = solstice_parser_get_geometry(parser, entity1a->geometry);
CHECK(solstice_geometry_get_objects_count(geom), 1);
obj_id = solstice_geometry_get_object(geom, 0);
obj = solstice_parser_get_object(parser, obj_id);
@@ -130,14 +130,14 @@ main(int argc, char** argv)
CHECK(mirror->roughness, 0.1);
entity_id = solstice_entity_get_child(entity, 1);
- entity1 = solstice_parser_get_entity(parser, entity_id);
- CHECK(d3_eq(entity1->translation, d3_splat(tmp, 0)), 1);
- CHECK(d3_eq(entity1->rotation, d3(tmp, 3.14, 0, -1)), 1);
- CHECK(strcmp("lvl1b", str_cget(&entity1->name)), 0);
- CHECK(solstice_entity_get_children_count(entity1), 1);
- CHECK(entity1->geometry.i, geom_id.i);
-
- entity_id = solstice_entity_get_child(entity1, 0);
+ entity1b = solstice_parser_get_entity(parser, entity_id);
+ CHECK(d3_eq(entity1b->translation, d3_splat(tmp, 0)), 1);
+ CHECK(d3_eq(entity1b->rotation, d3(tmp, 3.14, 0, -1)), 1);
+ CHECK(strcmp("lvl1b", str_cget(&entity1b->name)), 0);
+ CHECK(solstice_entity_get_children_count(entity1b), 1);
+ CHECK(entity1b->geometry.i, geom_id.i);
+
+ entity_id = solstice_entity_get_child(entity1b, 0);
entity2 = solstice_parser_get_entity(parser, entity_id);
CHECK(d3_eq(entity2->translation, d3_splat(tmp, 0)), 1);
CHECK(d3_eq(entity2->rotation, d3_splat(tmp, 0)), 1);
@@ -145,6 +145,17 @@ main(int argc, char** argv)
CHECK(solstice_entity_get_children_count(entity2), 0);
CHECK(entity2->geometry.i, geom_id.i);
+ entity3 = solstice_parser_find_entity(parser, "lvl 0");
+ CHECK(entity3, entity);
+ entity3 = solstice_parser_find_entity(parser, "lvl1a");
+ CHECK(entity3, NULL);
+ entity3 = solstice_parser_find_entity(parser, "lvl 0.lvl1a");
+ CHECK(entity3, entity1a);
+ entity3 = solstice_parser_find_entity(parser, "lvl 0.lvl1b");
+ CHECK(entity3, entity1b);
+ entity3 = solstice_parser_find_entity(parser, "lvl 0.lvl1b.lvl2");
+ CHECK(entity3, entity2);
+
CHECK(solstice_parser_load(parser), RES_BAD_OP);
solstice_parser_ref_put(parser);
@@ -155,3 +166,4 @@ main(int argc, char** argv)
CHECK(mem_allocated_size(), 0);
return 0;
}
+