Author: pepeto Date: Thu Jan 29 21:28:58 2015 New Revision: 27897 URL: http://svn.gna.org/viewcvs/freeciv?rev=27897&view=rev Log: Use two string vector to store future technology names (one for untranslated names, one for translated name).
Side effect: make proprer string freeing, reported by mir3x <mir3x> (see bug #23220). See gna bug #23221 Modified: branches/S2_5/common/tech.c Modified: branches/S2_5/common/tech.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/tech.c?rev=27897&r1=27896&r2=27897&view=diff ============================================================================== --- branches/S2_5/common/tech.c (original) +++ branches/S2_5/common/tech.c Thu Jan 29 21:28:58 2015 @@ -50,15 +50,8 @@ static struct user_flag user_tech_flags[MAX_NUM_USER_TECH_FLAGS]; -#define SPECVEC_TAG string -#define SPECVEC_TYPE char * -#include "specvec.h" - -#define string_vector_iterate(str_vec, str) \ - TYPED_VECTOR_ITERATE(char *, str_vec, str) -#define string_vector_iterate_end VECTOR_ITERATE_END - -static struct string_vector future; +static struct strvec *future_rule_name; +static struct strvec *future_name_translation; /************************************************************************** Return the last item of advances/technologies. @@ -982,6 +975,25 @@ return tech == A_FUTURE; } +/**************************************************************************** + Set a new future tech name in the string vector, and return the string + duplicate stored inside the vector. +****************************************************************************/ +static const char *future_set_name(struct strvec *psv, int no, + const char *new_name) +{ + if (strvec_size(psv) <= no) { + /* Increase the size of the vector if needed. */ + strvec_reserve(psv, no + 1); + } + + /* Set in vector. */ + strvec_set(psv, no, new_name); + + /* Return duplicate of 'new_name'. */ + return strvec_get(psv, no); +} + /************************************************************************** Return the rule name of the given tech (including A_FUTURE). You don't have to free the return pointer. @@ -997,22 +1009,24 @@ switch (tech) { case A_FUTURE: if (pplayer) { - struct player_research *research = player_research_get(pplayer); - int i; - - /* pplayer->future_tech == 0 means "Future Tech. 1". */ - for (i = future.size; i <= research->future_tech; i++) { - string_vector_append(&future, NULL); + const int no = player_research_get(pplayer)->future_tech; + char buffer[256]; + const char *name; + + name = strvec_get(future_rule_name, no); + if (name != NULL) { + /* Already stored in string vector. */ + return name; } - if (!future.p[research->future_tech]) { - char buffer[1024]; - - fc_snprintf(buffer, sizeof(buffer), "%s %d", - advance_rule_name(&advances[tech]), - research->future_tech + 1); - future.p[research->future_tech] = fc_strdup(buffer); - } - return future.p[research->future_tech]; + + /* NB: 'presearch->future_tech == 0' means "Future Tech. 1". */ + fc_snprintf(buffer, sizeof(buffer), "%s %d", + advance_rule_name(&advances[tech]), + no + 1); + name = future_set_name(future_rule_name, no, buffer); + fc_assert(name != NULL); + fc_assert(name != buffer); + return name; } else { return advance_rule_name(&advances[tech]); } @@ -1040,21 +1054,22 @@ switch (tech) { case A_FUTURE: if (pplayer) { - struct player_research *research = player_research_get(pplayer); - int i; - - /* pplayer->future_tech == 0 means "Future Tech. 1". */ - for (i = future.size; i <= research->future_tech; i++) { - string_vector_append(&future, NULL); + const int no = player_research_get(pplayer)->future_tech; + char buffer[256]; + const char *name; + + name = strvec_get(future_name_translation, no); + if (name != NULL) { + /* Already stored in string vector. */ + return name; } - if (!future.p[research->future_tech]) { - char buffer[1024]; - - fc_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"), - research->future_tech + 1); - future.p[research->future_tech] = fc_strdup(buffer); - } - return future.p[research->future_tech]; + + /* NB: 'presearch->future_tech == 0' means "Future Tech. 1". */ + fc_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"), no + 1); + name = future_set_name(future_name_translation, no, buffer); + fc_assert(name != NULL); + fc_assert(name != buffer); + return name; } else { return advance_name_translation(&advances[tech]); } @@ -1210,7 +1225,8 @@ /* TRANS: "Unknown" advance/technology */ name_set(&advances[A_UNKNOWN].name, NULL, N_("(Unknown)")); - string_vector_init(&future); + future_rule_name = strvec_new(); + future_name_translation = strvec_new(); } /*************************************************************** @@ -1240,9 +1256,6 @@ tech_free(i); } advance_index_iterate_end; - string_vector_iterate(&future, str) { - free(str); - } string_vector_iterate_end; - - string_vector_free(&future); -} + strvec_destroy(future_rule_name); + strvec_destroy(future_name_translation); +} _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits