Skip to content

Commit

Permalink
#897 empty separator string prevents tokenization of entity name
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Dec 28, 2022
1 parent cbeb463 commit ddf4dfc
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 109 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ Module | Description
The following language bindings have been developed with Flecs! Note that these are projects built and maintained by helpful community members, and may not always be up to date with the latest commit from master!
- [Lua](https://github.com/flecs-hub/flecs-lua)
- [Zig #1](https://github.com/foxnne/zig-flecs) [#2](https://github.com/prime31/zig-flecs)
- [C#](https://github.com/flecs-hub/flecs-cs) [#2](https://git.mcft.net/copygirl/gaemstone.ECS)
- [C# #1](https://github.com/flecs-hub/flecs-cs) [#2](https://git.mcft.net/copygirl/gaemstone.ECS)
- [Rust](https://github.com/jazzay/flecs-rs)
## Supporting Flecs ♥️
Expand Down
111 changes: 59 additions & 52 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -55091,10 +55091,6 @@ ecs_entity_t ecs_lookup_path_w_sep(
return 0;
}

if (!sep) {
sep = ".";
}

ecs_check(world != NULL, ECS_INTERNAL_ERROR, NULL);
const ecs_world_t *stage = world;
world = ecs_get_world(world);
Expand Down Expand Up @@ -55128,6 +55124,10 @@ ecs_entity_t ecs_lookup_path_w_sep(

parent = flecs_get_parent_from_path(stage, parent, &path, prefix, true);

if (!sep[0]) {
return ecs_lookup_child(world, parent, path);
}

retry:
cur = parent;
ptr_start = ptr = path;
Expand Down Expand Up @@ -55282,69 +55282,76 @@ ecs_entity_t ecs_add_path_w_sep(

char *name = NULL;

while ((ptr = flecs_path_elem(ptr, sep, &len))) {
if (len < size) {
ecs_os_memcpy(elem, ptr_start, len);
} else {
if (size == ECS_NAME_BUFFER_LENGTH) {
elem = NULL;
if (sep[0]) {
while ((ptr = flecs_path_elem(ptr, sep, &len))) {
if (len < size) {
ecs_os_memcpy(elem, ptr_start, len);
} else {
if (size == ECS_NAME_BUFFER_LENGTH) {
elem = NULL;
}

elem = ecs_os_realloc(elem, len + 1);
ecs_os_memcpy(elem, ptr_start, len);
size = len + 1;
}

elem = ecs_os_realloc(elem, len + 1);
ecs_os_memcpy(elem, ptr_start, len);
size = len + 1;
}
elem[len] = '\0';
ptr_start = ptr;

elem[len] = '\0';
ptr_start = ptr;
ecs_entity_t e = ecs_lookup_child(world, cur, elem);
if (!e) {
if (name) {
ecs_os_free(name);
}

ecs_entity_t e = ecs_lookup_child(world, cur, elem);
if (!e) {
if (name) {
ecs_os_free(name);
}
name = ecs_os_strdup(elem);

name = ecs_os_strdup(elem);
/* If this is the last entity in the path, use the provided id */
bool last_elem = false;
if (!flecs_path_elem(ptr, sep, NULL)) {
e = entity;
last_elem = true;
}

/* If this is the last entity in the path, use the provided id */
bool last_elem = false;
if (!flecs_path_elem(ptr, sep, NULL)) {
e = entity;
last_elem = true;
}
if (!e) {
if (last_elem) {
ecs_entity_t prev = ecs_set_scope(world, 0);
e = ecs_new(world, 0);
ecs_set_scope(world, prev);
} else {
e = ecs_new_id(world);
}
}

if (!e) {
if (last_elem) {
ecs_entity_t prev = ecs_set_scope(world, 0);
e = ecs_new(world, 0);
ecs_set_scope(world, prev);
} else {
e = ecs_new_id(world);
if (cur) {
ecs_add_pair(world, e, EcsChildOf, cur);
} else if (last_elem && root_path) {
ecs_remove_pair(world, e, EcsChildOf, EcsWildcard);
}
}

if (cur) {
ecs_add_pair(world, e, EcsChildOf, cur);
} else if (last_elem && root_path) {
ecs_remove_pair(world, e, EcsChildOf, EcsWildcard);
ecs_set_name(world, e, name);
}

ecs_set_name(world, e, name);
cur = e;
}

cur = e;
}

if (entity && (cur != entity)) {
ecs_throw(ECS_ALREADY_DEFINED, name);
}
if (entity && (cur != entity)) {
ecs_throw(ECS_ALREADY_DEFINED, name);
}

if (name) {
ecs_os_free(name);
}
if (name) {
ecs_os_free(name);
}

if (elem != buff) {
ecs_os_free(elem);
if (elem != buff) {
ecs_os_free(elem);
}
} else {
if (parent) {
ecs_add_pair(world, entity, EcsChildOf, parent);
}
ecs_set_name(world, entity, path);
}

return cur;
Expand Down
5 changes: 4 additions & 1 deletion flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3899,7 +3899,10 @@ typedef struct ecs_entity_desc_t {
* an entity is provided, the name will be verified
* with the existing entity. */

const char *sep; /**< Optional custom separator for hierarchical names */
const char *sep; /**< Optional custom separator for hierarchical names.
* Leave to NULL for default ('.') separator. Set to
* an empty string to prevent tokenization of name. */

const char *root_sep; /**< Optional, used for identifiers relative to root */

const char *symbol; /**< Optional entity symbol. A symbol is an unscoped
Expand Down
5 changes: 4 additions & 1 deletion include/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,10 @@ typedef struct ecs_entity_desc_t {
* an entity is provided, the name will be verified
* with the existing entity. */

const char *sep; /**< Optional custom separator for hierarchical names */
const char *sep; /**< Optional custom separator for hierarchical names.
* Leave to NULL for default ('.') separator. Set to
* an empty string to prevent tokenization of name. */

const char *root_sep; /**< Optional, used for identifiers relative to root */

const char *symbol; /**< Optional entity symbol. A symbol is an unscoped
Expand Down
111 changes: 59 additions & 52 deletions src/hierarchy.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,6 @@ ecs_entity_t ecs_lookup_path_w_sep(
return 0;
}

if (!sep) {
sep = ".";
}

ecs_check(world != NULL, ECS_INTERNAL_ERROR, NULL);
const ecs_world_t *stage = world;
world = ecs_get_world(world);
Expand Down Expand Up @@ -420,6 +416,10 @@ ecs_entity_t ecs_lookup_path_w_sep(

parent = flecs_get_parent_from_path(stage, parent, &path, prefix, true);

if (!sep[0]) {
return ecs_lookup_child(world, parent, path);
}

retry:
cur = parent;
ptr_start = ptr = path;
Expand Down Expand Up @@ -574,69 +574,76 @@ ecs_entity_t ecs_add_path_w_sep(

char *name = NULL;

while ((ptr = flecs_path_elem(ptr, sep, &len))) {
if (len < size) {
ecs_os_memcpy(elem, ptr_start, len);
} else {
if (size == ECS_NAME_BUFFER_LENGTH) {
elem = NULL;
if (sep[0]) {
while ((ptr = flecs_path_elem(ptr, sep, &len))) {
if (len < size) {
ecs_os_memcpy(elem, ptr_start, len);
} else {
if (size == ECS_NAME_BUFFER_LENGTH) {
elem = NULL;
}

elem = ecs_os_realloc(elem, len + 1);
ecs_os_memcpy(elem, ptr_start, len);
size = len + 1;
}

elem = ecs_os_realloc(elem, len + 1);
ecs_os_memcpy(elem, ptr_start, len);
size = len + 1;
}
elem[len] = '\0';
ptr_start = ptr;

elem[len] = '\0';
ptr_start = ptr;
ecs_entity_t e = ecs_lookup_child(world, cur, elem);
if (!e) {
if (name) {
ecs_os_free(name);
}

ecs_entity_t e = ecs_lookup_child(world, cur, elem);
if (!e) {
if (name) {
ecs_os_free(name);
}
name = ecs_os_strdup(elem);

name = ecs_os_strdup(elem);
/* If this is the last entity in the path, use the provided id */
bool last_elem = false;
if (!flecs_path_elem(ptr, sep, NULL)) {
e = entity;
last_elem = true;
}

/* If this is the last entity in the path, use the provided id */
bool last_elem = false;
if (!flecs_path_elem(ptr, sep, NULL)) {
e = entity;
last_elem = true;
}
if (!e) {
if (last_elem) {
ecs_entity_t prev = ecs_set_scope(world, 0);
e = ecs_new(world, 0);
ecs_set_scope(world, prev);
} else {
e = ecs_new_id(world);
}
}

if (!e) {
if (last_elem) {
ecs_entity_t prev = ecs_set_scope(world, 0);
e = ecs_new(world, 0);
ecs_set_scope(world, prev);
} else {
e = ecs_new_id(world);
if (cur) {
ecs_add_pair(world, e, EcsChildOf, cur);
} else if (last_elem && root_path) {
ecs_remove_pair(world, e, EcsChildOf, EcsWildcard);
}
}

if (cur) {
ecs_add_pair(world, e, EcsChildOf, cur);
} else if (last_elem && root_path) {
ecs_remove_pair(world, e, EcsChildOf, EcsWildcard);
ecs_set_name(world, e, name);
}

ecs_set_name(world, e, name);
cur = e;
}

cur = e;
}

if (entity && (cur != entity)) {
ecs_throw(ECS_ALREADY_DEFINED, name);
}
if (entity && (cur != entity)) {
ecs_throw(ECS_ALREADY_DEFINED, name);
}

if (name) {
ecs_os_free(name);
}
if (name) {
ecs_os_free(name);
}

if (elem != buff) {
ecs_os_free(elem);
if (elem != buff) {
ecs_os_free(elem);
}
} else {
if (parent) {
ecs_add_pair(world, entity, EcsChildOf, parent);
}
ecs_set_name(world, entity, path);
}

return cur;
Expand Down
5 changes: 4 additions & 1 deletion test/api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@
"get_depth",
"get_depth_non_acyclic",
"get_depth_empty",
"get_depth_2_paths"
"get_depth_2_paths",
"entity_init_w_empty_sep",
"entity_init_w_empty_sep_from_scope",
"entity_init_w_empty_sep_w_prefix"
]
}, {
"id": "Search",
Expand Down

0 comments on commit ddf4dfc

Please sign in to comment.