X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fmisc.c;h=3bc3299f2c70fcb5ad5427f2709021bdaa66d838;hb=7a705013e74fff7fb43ea9dd6359d033f4b0aa3f;hp=3be57faf78ea796d4bd4e638bd56b4bd72f2f829;hpb=2176d1de29652bc9e8db1baa283fdc1c4e99e674;p=rocksndiamonds.git diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 3be57faf..3bc3299f 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -2068,20 +2068,33 @@ void deleteNodeFromList(ListNode **node_first, char *key, if (strEqual((*node_first)->key, key)) { - checked_free((*node_first)->key); + // after first recursion, (*node_first)->prev->next == *node_first, + // so *node_first would be overwritten with (*node_first)->next + // => use a copy of *node_first (and later of (*node_first)->next) + ListNode *node = *node_first; + ListNode *node_next = node->next; + + checked_free(node->key); if (destructor_function) - destructor_function((*node_first)->content); + destructor_function(node->content); + + if (node->prev) + node->prev->next = node->next; - if ((*node_first)->next) - (*node_first)->next->prev = (*node_first)->prev; + if (node->next) + node->next->prev = node->prev; - checked_free(*node_first); + checked_free(node); - *node_first = (*node_first)->next; + // after removing node, set list pointer to next valid list node + // (this is important if the first node of the list was deleted) + *node_first = node_next; } else + { deleteNodeFromList(&(*node_first)->next, key, destructor_function); + } } ListNode *getNodeFromKey(ListNode *node_first, char *key) @@ -2564,6 +2577,27 @@ char *get_mapped_token(char *token) return getStringCat2(map_token_prefix[i][1], &token[len_token_prefix]); } + // change tokens containing ".gfx" by moving the "gfx" part to the very left + char *gfx_substring = ".gfx"; + char *gfx_prefix = "gfx."; + if (strstr(token, gfx_substring) != NULL) + { + char *token_prefix = getStringCopy(token); + char *token_gfx_pos = strstr(token_prefix, gfx_substring); + char *token_suffix = &token_gfx_pos[strlen(gfx_substring)]; + char *mapped_token; + + // cut off token string at ".gfx" substring position + *token_gfx_pos = '\0'; + + // put together prefix "gfx." and token prefix and suffix without ".gfx" + mapped_token = getStringCat3(gfx_prefix, token_prefix, token_suffix); + + free(token_prefix); + + return mapped_token; + } + return NULL; } @@ -2984,7 +3018,7 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, int num_ext2_suffixes = artwork_info->num_ext2_suffixes; int num_ext3_suffixes = artwork_info->num_ext3_suffixes; int num_ignore_tokens = artwork_info->num_ignore_tokens; - SetupFileHash *setup_file_hash, *valid_file_hash; + SetupFileHash *setup_file_hash, *valid_file_hash, *valid_file_hash_tmp; SetupFileHash *extra_file_hash, *empty_file_hash; char *known_token_value = KNOWN_TOKEN_VALUE; char *base_token_value = UNDEFINED_FILENAME; @@ -3011,8 +3045,20 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, /* at this point, we do not need the setup file hash anymore -- free it */ freeSetupFileHash(setup_file_hash); - /* map deprecated to current tokens (using prefix match and replace) */ + /* prevent changing hash while iterating over it by using a temporary copy */ + valid_file_hash_tmp = newSetupFileHash(); BEGIN_HASH_ITERATION(valid_file_hash, itr) + { + setHashEntry(valid_file_hash_tmp, + HASH_ITERATION_TOKEN(itr), + HASH_ITERATION_VALUE(itr)); + } + END_HASH_ITERATION(valid_file_hash, itr) + + /* (iterate over same temporary hash, as modifications are independent) */ + + /* map deprecated to current tokens (using prefix match and replace) */ + BEGIN_HASH_ITERATION(valid_file_hash_tmp, itr) { char *token = HASH_ITERATION_TOKEN(itr); char *mapped_token = get_mapped_token(token); @@ -3030,10 +3076,10 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, free(mapped_token); } } - END_HASH_ITERATION(valid_file_hash, itr) + END_HASH_ITERATION(valid_file_hash_tmp, itr) /* add special base tokens (using prefix match and replace) */ - BEGIN_HASH_ITERATION(valid_file_hash, itr) + BEGIN_HASH_ITERATION(valid_file_hash_tmp, itr) { char *token = HASH_ITERATION_TOKEN(itr); char *base_token = get_special_base_token(artwork_info, token); @@ -3047,7 +3093,10 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info, free(base_token); } } - END_HASH_ITERATION(valid_file_hash, itr) + END_HASH_ITERATION(valid_file_hash_tmp, itr) + + /* free temporary hash used for iteration */ + freeSetupFileHash(valid_file_hash_tmp); /* read parameters for all known config file tokens */ for (i = 0; i < num_file_list_entries; i++)