commit 5ac8360cb5b2f222ac5223599560dffce88a5ae0
parent 2f977f26b6e7326baf4b7b60d3c9ffe7b01112b8
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 13 Jan 2023 11:41:07 +0100
Add detection of duplicate building names in the city map file
Diffstat:
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/cg_city.c b/src/cg_city.c
@@ -31,11 +31,24 @@
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
#include <rsys/double4.h>
+#include <rsys/hash_table.h>
#include <star/scpr.h>
#include <string.h>
+#define HTABLE_NAME names
+#define HTABLE_DATA char
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_COPY_AND_CLEAR str_copy_and_clear
+#define HTABLE_KEY_FUNCTOR_EQ str_eq
+#define HTABLE_KEY_FUNCTOR_HASH str_hash
+#include <rsys/hash_table.h>
+
res_T
create_city
(struct mem_allocator* allocator,
@@ -46,8 +59,10 @@ create_city
struct city** out_city)
{
res_T res = RES_OK;
- size_t i=0;
+ size_t i = 0;
struct city* city = NULL;
+ struct htable_names names;
+ int initialized = 0;
(void)logger;
ASSERT(logger && allocator && args && parsed_city && catalog && out_city);
@@ -58,6 +73,9 @@ create_city
goto error;
}
+ htable_names_init(allocator, &names);
+ initialized = 1;
+
city->buildings_count = parsed_city->city_building_list_count;
city->buildings = MEM_CALLOC(allocator, city->buildings_count,
sizeof(*city->buildings));
@@ -78,6 +96,7 @@ create_city
for (i = 0; i < city->buildings_count ; i++) {
struct parsed_city_building* parsed_data = parsed_city->city_building_list + i;
struct building* building = city->buildings + i;
+ char one = 1;
switch(parsed_data->cmode_type) {
case PARSED_CMODE_0:
ERR(init_cmode_0(building, allocator, logger, parsed_data, catalog));
@@ -89,14 +108,25 @@ create_city
res = RES_BAD_ARG;
goto error;
}
+ /* Check name unicity. The error case is Not supposed to happen: can be
+ * tested after building creation as this simplifies the process */
+ if(htable_names_find(&names, &building->name)) {
+ logger_print(logger, LOG_ERROR,
+ "Duplicate building name: '%s' in file '%s'.\n",
+ parsed_data->name, str_cget(&parsed_city->filename));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ ERR(htable_names_set(&names, &building->name, &one));
}
exit:
+ if(initialized) htable_names_release(&names);
*out_city = city;
return res;
error:
release_city(city);
- out_city = NULL;
+ city = NULL;
goto exit;
}