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

Reply via email to