<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39562 >

On 14/08/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
>
>  In current trunk bad choice structures cause illegal memory access
> (old iterators were more robust, but at the same time they hide bugs).
>  This patch makes easier to hunt those choice problems down.

 One very important bit was left out when I cleaned patch up.


 - ML

diff -Nurd -X.diff_ignore freeciv/ai/aicity.c freeciv/ai/aicity.c
--- freeciv/ai/aicity.c	2007-08-13 20:51:05.000000000 +0300
+++ freeciv/ai/aicity.c	2007-08-14 12:42:47.000000000 +0300
@@ -1380,7 +1380,7 @@
   }
 
   if (pcity->ai.choice.want != 0) { 
-    ASSERT_REAL_CHOICE_TYPE(pcity->ai.choice.type);
+    ASSERT_CHOICE(pcity->ai.choice);
 
     CITY_LOG(LOG_DEBUG, pcity, "wants %s with desire %d.",
 	     is_unit_choice_type(pcity->ai.choice.type)
@@ -1532,7 +1532,7 @@
     /* Not dealing with this city a second time */
     pcity->ai.choice.want = 0;
 
-    ASSERT_REAL_CHOICE_TYPE(bestchoice.type);
+    ASSERT_CHOICE(bestchoice);
 
     /* Try upgrade units at danger location (high want is usually danger) */
     if (pcity->ai.urgency > 1) {
@@ -1692,6 +1692,7 @@
         game.info.turn + myrand(RECALC_SPEED) + RECALC_SPEED;
     }
     TIMING_LOG(AIT_CITY_SETTLERS, TIMER_STOP);
+    ASSERT_CHOICE(pcity->ai.choice);
   } city_list_iterate_end;
 
   city_list_iterate(pplayer->cities, pcity) {
diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h
--- freeciv/common/city.h	2007-08-13 20:51:03.000000000 +0300
+++ freeciv/common/city.h	2007-08-14 12:42:59.000000000 +0300
@@ -150,25 +150,26 @@
 
 enum choice_type {
   CT_NONE = 0,
-  CT_BUILDING = 0,
+  CT_BUILDING = 1,
   CT_CIVILIAN,
   CT_ATTACKER,
   CT_DEFENDER,
   CT_LAST
 };
 
-/* FIXME:
-
-   This should detect also cases where type is just initialized with
-   CT_NONE (probably in order to silence compiler warnings), but no real value
-   is given. You have to change value of CT_BUILDING into 1 before you
-   can add this check. It's left this way for now, is case hardcoded
-   value 0 is still used somewhere instead of CT_BUILDING.
-
-   -- Caz
-*/
-#define ASSERT_REAL_CHOICE_TYPE(type)                                    \
-        assert(type >= 0 && type < CT_LAST /* && type != CT_NONE */ );
+#define ASSERT_CHOICE(c)                                                 \
+  do {                                                                   \
+    if ((c).want > 0) {                                                  \
+      assert((c).type >= 0 && (c).type < CT_LAST && (c).type != CT_NONE);\
+      if ((c).type == CT_BUILDING) {                                     \
+        int _iindex = improvement_index((c).value.building);             \
+        assert(_iindex >= 0 && _iindex < B_LAST);                        \
+      } else {                                                           \
+        int _uindex = utype_index((c).value.utype);                      \
+        assert(_uindex >= 0 && _uindex < U_LAST);                        \
+      }                                                                  \
+    }                                                                    \
+  } while(0);
 
 struct ai_choice {
   enum choice_type type;
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to