Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] Re: (PR#13488) T_UNKNOWN errors in 2.0
Home

[Freeciv-Dev] Re: (PR#13488) T_UNKNOWN errors in 2.0

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#13488) T_UNKNOWN errors in 2.0
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 18 Jul 2005 11:42:55 -0700
Reply-to: bugs@xxxxxxxxxxx

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

Here is a more extensive patch.

* The tile_types[] array is made static.
* All callers use get_tile_type().
* get_tile_type returns a dummy tile_type struct for T_UNKNOWN.
* get_tile_type has an assertion in this case, but it's disabled.

This should prevent all buffer underruns.  However the end behavior may
not be exactly what's desired since it's based on the dummy tile.
Callers should still check for T_UNKNOWN where applicable.

-jason


Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.81.2.7
diff -p -u -r1.81.2.7 helpdata.c
--- client/helpdata.c   28 Jun 2005 07:26:20 -0000      1.81.2.7
+++ client/helpdata.c   18 Jul 2005 18:41:28 -0000
@@ -106,24 +106,26 @@ static void insert_generated_table(const
     strcat(outbuf, "---------------------------------------------------"
           "------------\n");
     for (i = T_FIRST; i < T_COUNT; i++) {
-      if (*(tile_types[i].terrain_name) != '\0') {
+      struct tile_type *ptype = get_tile_type(i);
+
+      if (*(ptype->terrain_name) != '\0') {
        outbuf = strchr(outbuf, '\0');
        sprintf(outbuf,
                "%-10s %3d    %3d %-10s %3d %-10s %3d %-10s\n",
-               tile_types[i].terrain_name,
-               tile_types[i].road_time,
-               tile_types[i].irrigation_time,
-               ((tile_types[i].irrigation_result == i
-                 || tile_types[i].irrigation_result == T_NONE) ? ""
-                : tile_types[tile_types[i].irrigation_result].terrain_name),
-               tile_types[i].mining_time,
-               ((tile_types[i].mining_result == i
-                 || tile_types[i].mining_result == T_NONE) ? ""
-                : tile_types[tile_types[i].mining_result].terrain_name),
-               tile_types[i].transform_time,
-               ((tile_types[i].transform_result == i
-                || tile_types[i].transform_result == T_NONE) ? ""
-                : tile_types[tile_types[i].transform_result].terrain_name));
+               ptype->terrain_name,
+               ptype->road_time,
+               ptype->irrigation_time,
+               ((ptype->irrigation_result == i
+                 || ptype->irrigation_result == T_NONE) ? ""
+                : get_tile_type(ptype->irrigation_result)->terrain_name),
+               ptype->mining_time,
+               ((ptype->mining_result == i
+                 || ptype->mining_result == T_NONE) ? ""
+                : get_tile_type(ptype->mining_result)->terrain_name),
+               ptype->transform_time,
+               ((ptype->transform_result == i
+                || ptype->transform_result == T_NONE) ? ""
+                : get_tile_type(ptype->transform_result)->terrain_name));
       }
     }
     strcat(outbuf, "\n");
@@ -262,10 +264,12 @@ void boot_help_texts(void)
          } tech_type_iterate_end;
        } else if (current_type == HELP_TERRAIN) {
          for (i = T_FIRST; i < T_COUNT; i++) {
-           if (*(tile_types[i].terrain_name) != '\0') {
+           struct tile_type *ptype = get_tile_type(i);
+
+           if (*(ptype->terrain_name) != '\0') {
              pitem = new_help_item(current_type);
              my_snprintf(name, sizeof(name), " %s",
-                         tile_types[i].terrain_name);
+                         ptype->terrain_name);
              pitem->topic = mystrdup(name);
              pitem->text = mystrdup("");
              help_list_insert_back(&category_nodes, pitem);
@@ -1086,7 +1090,7 @@ void helptext_terrain(char *buf, int i, 
   
   if (i<0 || i>=T_COUNT)
     return;
-  pt = &tile_types[i];
+  pt = get_tile_type(i);
 
   if (terrain_has_flag(i, TER_NO_POLLUTION)) {
     sprintf(buf + strlen(buf),
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.408.2.26
diff -p -u -r1.408.2.26 packhand.c
--- client/packhand.c   14 Jul 2005 07:00:29 -0000      1.408.2.26
+++ client/packhand.c   18 Jul 2005 18:41:30 -0000
@@ -2520,7 +2520,7 @@ void handle_ruleset_terrain(struct packe
            p->id);
     return;
   }
-  t = &(tile_types[p->id]);
+  t = get_tile_type(p->id);
 
   sz_strlcpy(t->terrain_name_orig, p->terrain_name);
   t->terrain_name = t->terrain_name_orig;
Index: client/gui-gtk/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/Attic/helpdlg.c,v
retrieving revision 1.68.2.1
diff -p -u -r1.68.2.1 helpdlg.c
--- client/gui-gtk/helpdlg.c    10 Nov 2004 17:02:02 -0000      1.68.2.1
+++ client/gui-gtk/helpdlg.c    18 Jul 2005 18:41:30 -0000
@@ -916,94 +916,95 @@ static void help_update_terrain(const st
                                char *title, int i)
 {
   char *buf = &long_buffer[0];
+  struct tile_type *ptype = get_tile_type(i);
 
   create_help_page(HELP_TERRAIN);
 
   if (i < T_COUNT) {
     sprintf(buf, "%d/%d.%d",
-           tile_types[i].movement_cost,
-           (int)(tile_types[i].defense_bonus/10),
-           tile_types[i].defense_bonus%10);
+           ptype->movement_cost,
+           (int)(ptype->defense_bonus/10),
+           ptype->defense_bonus%10);
     gtk_set_label(help_tlabel[0][1], buf);
 
     sprintf(buf, "%d/%d/%d",
-           tile_types[i].food,
-           tile_types[i].shield,
-           tile_types[i].trade);
+           ptype->food,
+           ptype->shield,
+           ptype->trade);
     gtk_set_label(help_tlabel[0][4], buf);
 
-    if (*(tile_types[i].special_1_name)) {
+    if (*(ptype->special_1_name)) {
       sprintf(buf, _("%s F/R/T:"),
-             tile_types[i].special_1_name);
+             ptype->special_1_name);
       gtk_set_label(help_tlabel[1][0], buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_1,
-             tile_types[i].shield_special_1,
-             tile_types[i].trade_special_1);
+             ptype->food_special_1,
+             ptype->shield_special_1,
+             ptype->trade_special_1);
       gtk_set_label(help_tlabel[1][1], buf);
     } else {
       gtk_set_label(help_tlabel[1][0], "");
       gtk_set_label(help_tlabel[1][1], "");
     }
 
-    if (*(tile_types[i].special_2_name)) {
+    if (*(ptype->special_2_name)) {
       sprintf(buf, _("%s F/R/T:"),
-             tile_types[i].special_2_name);
+             ptype->special_2_name);
       gtk_set_label(help_tlabel[1][3], buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_2,
-             tile_types[i].shield_special_2,
-             tile_types[i].trade_special_2);
+             ptype->food_special_2,
+             ptype->shield_special_2,
+             ptype->trade_special_2);
       gtk_set_label(help_tlabel[1][4], buf);
     } else {
       gtk_set_label(help_tlabel[1][3], "");
       gtk_set_label(help_tlabel[1][4], "");
     }
 
-    if (tile_types[i].road_trade_incr > 0) {
+    if (ptype->road_trade_incr > 0) {
       sprintf(buf, _("+%d Trade / %d"),
-             tile_types[i].road_trade_incr,
-             tile_types[i].road_time);
-    } else if (tile_types[i].road_time > 0) {
+             ptype->road_trade_incr,
+             ptype->road_time);
+    } else if (ptype->road_time > 0) {
       sprintf(buf, _("no extra / %d"),
-             tile_types[i].road_time);
+             ptype->road_time);
     } else {
       strcpy(buf, _("n/a"));
     }
     gtk_set_label(help_tlabel[2][1], buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].irrigation_result == i) {
-      if (tile_types[i].irrigation_food_incr > 0) {
+    if (ptype->irrigation_result == i) {
+      if (ptype->irrigation_food_incr > 0) {
        sprintf(buf, _("+%d Food / %d"),
-               tile_types[i].irrigation_food_incr,
-               tile_types[i].irrigation_time);
+               ptype->irrigation_food_incr,
+               ptype->irrigation_time);
       }
-    } else if (tile_types[i].irrigation_result != T_NONE) {
+    } else if (ptype->irrigation_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].irrigation_result].terrain_name,
-             tile_types[i].irrigation_time);
+             get_tile_type(ptype->irrigation_result)->terrain_name,
+             ptype->irrigation_time);
     }
     gtk_set_label(help_tlabel[2][4], buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].mining_result == i) {
-      if (tile_types[i].mining_shield_incr > 0) {
+    if (ptype->mining_result == i) {
+      if (ptype->mining_shield_incr > 0) {
        sprintf(buf, _("+%d Res. / %d"),
-               tile_types[i].mining_shield_incr,
-               tile_types[i].mining_time);
+               ptype->mining_shield_incr,
+               ptype->mining_time);
       }
-    } else if (tile_types[i].mining_result != T_NONE) {
+    } else if (ptype->mining_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].mining_result].terrain_name,
-             tile_types[i].mining_time);
+             get_tile_type(ptype->mining_result)->terrain_name,
+             ptype->mining_time);
     }
     gtk_set_label(help_tlabel[3][1], buf);
 
-    if (tile_types[i].transform_result != T_NONE) {
+    if (ptype->transform_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].transform_result].terrain_name,
-             tile_types[i].transform_time);
+             get_tile_type(ptype->transform_result)->terrain_name,
+             ptype->transform_time);
     } else {
       strcpy(buf, "n/a");
     }
Index: client/gui-gtk-2.0/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/helpdlg.c,v
retrieving revision 1.35.2.5
diff -p -u -r1.35.2.5 helpdlg.c
--- client/gui-gtk-2.0/helpdlg.c        8 Dec 2004 20:48:35 -0000       1.35.2.5
+++ client/gui-gtk-2.0/helpdlg.c        18 Jul 2005 18:41:30 -0000
@@ -985,94 +985,95 @@ static void help_update_terrain(const st
                                char *title, int i)
 {
   char *buf = &long_buffer[0];
+  struct tile_type *ptype = get_tile_type(i);
 
   create_help_page(HELP_TERRAIN);
 
   if (i < T_COUNT) {
     sprintf(buf, "%d/%d.%d",
-           tile_types[i].movement_cost,
-           (int)(tile_types[i].defense_bonus/10),
-           tile_types[i].defense_bonus%10);
+           ptype->movement_cost,
+           (int)(ptype->defense_bonus/10),
+           ptype->defense_bonus%10);
     gtk_label_set_text(GTK_LABEL(help_tlabel[0][1]), buf);
 
     sprintf(buf, "%d/%d/%d",
-           tile_types[i].food,
-           tile_types[i].shield,
-           tile_types[i].trade);
+           ptype->food,
+           ptype->shield,
+           ptype->trade);
     gtk_label_set_text(GTK_LABEL(help_tlabel[0][4]), buf);
 
-    if (*(tile_types[i].special_1_name)) {
+    if (*(ptype->special_1_name)) {
       sprintf(buf, _("%s F/R/T:"),
-              tile_types[i].special_1_name);
+              ptype->special_1_name);
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][0]), buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_1,
-             tile_types[i].shield_special_1,
-             tile_types[i].trade_special_1);
+             ptype->food_special_1,
+             ptype->shield_special_1,
+             ptype->trade_special_1);
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), buf);
     } else {
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][0]), "");
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), "");
     }
 
-    if (*(tile_types[i].special_2_name)) {
+    if (*(ptype->special_2_name)) {
       sprintf(buf, _("%s F/R/T:"),
-             tile_types[i].special_2_name);
+             ptype->special_2_name);
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][3]), buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_2,
-             tile_types[i].shield_special_2,
-             tile_types[i].trade_special_2);
+             ptype->food_special_2,
+             ptype->shield_special_2,
+             ptype->trade_special_2);
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][4]), buf);
     } else {
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][3]), "");
       gtk_label_set_text(GTK_LABEL(help_tlabel[1][4]), "");
     }
 
-    if (tile_types[i].road_trade_incr > 0) {
+    if (ptype->road_trade_incr > 0) {
       sprintf(buf, _("+%d Trade / %d"),
-             tile_types[i].road_trade_incr,
-             tile_types[i].road_time);
-    } else if (tile_types[i].road_time > 0) {
+             ptype->road_trade_incr,
+             ptype->road_time);
+    } else if (ptype->road_time > 0) {
       sprintf(buf, _("no extra / %d"),
-             tile_types[i].road_time);
+             ptype->road_time);
     } else {
       strcpy(buf, _("n/a"));
     }
     gtk_label_set_text(GTK_LABEL(help_tlabel[2][1]), buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].irrigation_result == i) {
-      if (tile_types[i].irrigation_food_incr > 0) {
+    if (ptype->irrigation_result == i) {
+      if (ptype->irrigation_food_incr > 0) {
        sprintf(buf, _("+%d Food / %d"),
-               tile_types[i].irrigation_food_incr,
-               tile_types[i].irrigation_time);
+               ptype->irrigation_food_incr,
+               ptype->irrigation_time);
       }
-    } else if (tile_types[i].irrigation_result != T_NONE) {
+    } else if (ptype->irrigation_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].irrigation_result].terrain_name,
-             tile_types[i].irrigation_time);
+             get_tile_type(ptype->irrigation_result)->terrain_name,
+             ptype->irrigation_time);
     }
     gtk_label_set_text(GTK_LABEL(help_tlabel[2][4]), buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].mining_result == i) {
-      if (tile_types[i].mining_shield_incr > 0) {
+    if (ptype->mining_result == i) {
+      if (ptype->mining_shield_incr > 0) {
        sprintf(buf, _("+%d Res. / %d"),
-               tile_types[i].mining_shield_incr,
-               tile_types[i].mining_time);
+               ptype->mining_shield_incr,
+               ptype->mining_time);
       }
-    } else if (tile_types[i].mining_result != T_NONE) {
+    } else if (ptype->mining_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].mining_result].terrain_name,
-             tile_types[i].mining_time);
+             get_tile_type(ptype->mining_result)->terrain_name,
+             ptype->mining_time);
     }
     gtk_label_set_text(GTK_LABEL(help_tlabel[3][1]), buf);
 
-    if (tile_types[i].transform_result != T_NONE) {
+    if (ptype->transform_result != T_NONE) {
       sprintf(buf, "%s / %d",
-              tile_types[tile_types[i].transform_result].terrain_name,
-              tile_types[i].transform_time);
+             get_tile_type(ptype->transform_result)->terrain_name,
+              ptype->transform_time);
     } else {
       strcpy(buf, "n/a");
     }
Index: client/gui-win32/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/helpdlg.c,v
retrieving revision 1.21
diff -p -u -r1.21 helpdlg.c
--- client/gui-win32/helpdlg.c  4 Sep 2004 21:11:47 -0000       1.21
+++ client/gui-win32/helpdlg.c  18 Jul 2005 18:41:30 -0000
@@ -543,94 +543,95 @@ static void help_update_terrain(const st
                                char *title, int i)
 {
   char *buf = &long_buffer[0];
-  
+  struct tile_type *ptype = get_tile_type(i);
+
   create_help_page(HELP_TERRAIN);
 
   if (i < T_COUNT) {
     sprintf(buf, "%d/%d.%d",
-           tile_types[i].movement_cost,
-           (int)(tile_types[i].defense_bonus/10),
-           tile_types[i].defense_bonus%10);
+           ptype->movement_cost,
+           (int)(ptype->defense_bonus/10),
+           ptype->defense_bonus%10);
     SetWindowText (help_tlabel[0][1], buf);
 
     sprintf(buf, "%d/%d/%d",
-           tile_types[i].food,
-           tile_types[i].shield,
-           tile_types[i].trade);
+           ptype->food,
+           ptype->shield,
+           ptype->trade);
     SetWindowText(help_tlabel[0][4], buf);
 
-    if (*(tile_types[i].special_1_name)) {
+    if (*(ptype->special_1_name)) {
       sprintf(buf, _("%s F/R/T:"),
-             tile_types[i].special_1_name);
+             ptype->special_1_name);
       SetWindowText(help_tlabel[1][0], buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_1,
-             tile_types[i].shield_special_1,
-             tile_types[i].trade_special_1);
+             ptype->food_special_1,
+             ptype->shield_special_1,
+             ptype->trade_special_1);
       SetWindowText(help_tlabel[1][1], buf);
     } else {
       SetWindowText(help_tlabel[1][0], " ");
       SetWindowText(help_tlabel[1][1], " ");
     }
 
-    if (*(tile_types[i].special_2_name)) {
+    if (*(ptype->special_2_name)) {
       sprintf(buf, _("%s F/R/T:"),
-             tile_types[i].special_2_name);
+             ptype->special_2_name);
       SetWindowText(help_tlabel[1][3], buf);
       sprintf(buf, "%d/%d/%d",
-             tile_types[i].food_special_2,
-             tile_types[i].shield_special_2,
-             tile_types[i].trade_special_2);
+             ptype->food_special_2,
+             ptype->shield_special_2,
+             ptype->trade_special_2);
       SetWindowText(help_tlabel[1][4], buf);
     } else {
       SetWindowText(help_tlabel[1][3], " ");
       SetWindowText(help_tlabel[1][4], " ");
     }
 
-    if (tile_types[i].road_trade_incr > 0) {
+    if (ptype->road_trade_incr > 0) {
       sprintf(buf, _("+%d Trade / %d"),
-             tile_types[i].road_trade_incr,
-             tile_types[i].road_time);
-    } else if (tile_types[i].road_time > 0) {
+             ptype->road_trade_incr,
+             ptype->road_time);
+    } else if (ptype->road_time > 0) {
       sprintf(buf, _("no extra / %d"),
-             tile_types[i].road_time);
+             ptype->road_time);
     } else {
       strcpy(buf, _("n/a"));
     }
     SetWindowText(help_tlabel[2][1], buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].irrigation_result == i) {
-      if (tile_types[i].irrigation_food_incr > 0) {
+    if (ptype->irrigation_result == i) {
+      if (ptype->irrigation_food_incr > 0) {
        sprintf(buf, _("+%d Food / %d"),
-               tile_types[i].irrigation_food_incr,
-               tile_types[i].irrigation_time);
+               ptype->irrigation_food_incr,
+               ptype->irrigation_time);
       }
-    } else if (tile_types[i].irrigation_result != T_NONE) {
+    } else if (ptype->irrigation_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].irrigation_result].terrain_name,
-             tile_types[i].irrigation_time);
+             get_tile_type(ptype->irrigation_result)->terrain_name,
+             ptype->irrigation_time);
     }
     SetWindowText(help_tlabel[2][4], buf);
 
     strcpy(buf, _("n/a"));
-    if (tile_types[i].mining_result == i) {
-      if (tile_types[i].mining_shield_incr > 0) {
+    if (ptype->mining_result == i) {
+      if (ptype->mining_shield_incr > 0) {
        sprintf(buf, _("+%d Res. / %d"),
-               tile_types[i].mining_shield_incr,
-               tile_types[i].mining_time);
+               ptype->mining_shield_incr,
+               ptype->mining_time);
       }
-    } else if (tile_types[i].mining_result != T_NONE) {
+    } else if (ptype->mining_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].mining_result].terrain_name,
-             tile_types[i].mining_time);
+             get_tile_type(ptype->mining_result)->terrain_name,
+             ptype->mining_time);
     }
     SetWindowText(help_tlabel[3][1], buf);
 
-    if (tile_types[i].transform_result != T_NONE) {
+    if (ptype->transform_result != T_NONE) {
       sprintf(buf, "%s / %d",
-             tile_types[tile_types[i].transform_result].terrain_name,
-             tile_types[i].transform_time);
+             get_tile_type(ptype->transform_result)->terrain_name,
+             ptype->transform_time);
     } else {
       strcpy(buf, "n/a");
     }
Index: client/gui-xaw/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/helpdlg.c,v
retrieving revision 1.53
diff -p -u -r1.53 helpdlg.c
--- client/gui-xaw/helpdlg.c    27 Sep 2004 14:19:20 -0000      1.53
+++ client/gui-xaw/helpdlg.c    18 Jul 2005 18:41:30 -0000
@@ -937,6 +937,7 @@ static void help_update_terrain(const st
                                char *title, int i)
 {
   char *buf = &long_buffer[0];
+  struct tile_type *ptype = get_tile_type(i);
 
   create_help_page(HELP_TERRAIN);
   set_title_topic(pitem);
@@ -947,56 +948,56 @@ static void help_update_terrain(const st
   if (i < T_COUNT)
     {
       sprintf (buf, "%d/%d.%d",
-              tile_types[i].movement_cost,
-              (int)(tile_types[i].defense_bonus/10), 
tile_types[i].defense_bonus%10);
+              ptype->movement_cost,
+              (int)(ptype->defense_bonus/10), ptype->defense_bonus%10);
       xaw_set_label (help_terrain_movement_defense_data, buf);
 
       sprintf (buf, "%d/%d/%d",
-              tile_types[i].food,
-              tile_types[i].shield,
-              tile_types[i].trade);
+              ptype->food,
+              ptype->shield,
+              ptype->trade);
       xaw_set_label (help_terrain_food_shield_trade_data, buf);
 
-      if (*(tile_types[i].special_1_name))
+      if (*(ptype->special_1_name))
        {
          sprintf (buf, _("%s F/R/T:"),
-                  tile_types[i].special_1_name);
+                  ptype->special_1_name);
          xaw_set_label (help_terrain_special_1, buf);
          sprintf (buf, "%d/%d/%d",
-                  tile_types[i].food_special_1,
-                  tile_types[i].shield_special_1,
-                  tile_types[i].trade_special_1);
+                  ptype->food_special_1,
+                  ptype->shield_special_1,
+                  ptype->trade_special_1);
          xaw_set_label (help_terrain_special_1_data, buf);
        } else {
          xaw_set_label (help_terrain_special_1, "");
          xaw_set_label (help_terrain_special_1_data, "");
        }
 
-      if (*(tile_types[i].special_2_name))
+      if (*(ptype->special_2_name))
        {
          sprintf (buf, _("%s F/R/T:"),
-                  tile_types[i].special_2_name);
+                  ptype->special_2_name);
          xaw_set_label (help_terrain_special_2, buf);
          sprintf (buf, "%d/%d/%d",
-                  tile_types[i].food_special_2,
-                  tile_types[i].shield_special_2,
-                  tile_types[i].trade_special_2);
+                  ptype->food_special_2,
+                  ptype->shield_special_2,
+                  ptype->trade_special_2);
          xaw_set_label (help_terrain_special_2_data, buf);
        } else {
          xaw_set_label (help_terrain_special_2, "");
          xaw_set_label (help_terrain_special_2_data, "");
        }
 
-      if (tile_types[i].road_trade_incr > 0)
+      if (ptype->road_trade_incr > 0)
        {
          sprintf (buf, _("+%d Trade / %d"),
-                  tile_types[i].road_trade_incr,
-                  tile_types[i].road_time);
+                  ptype->road_trade_incr,
+                  ptype->road_time);
        }
-      else if (tile_types[i].road_time > 0)
+      else if (ptype->road_time > 0)
        {
          sprintf (buf, _("no extra / %d"),
-                  tile_types[i].road_time);
+                  ptype->road_time);
        }
       else
        {
@@ -1005,46 +1006,46 @@ static void help_update_terrain(const st
       xaw_set_label (help_terrain_road_result_time_data, buf);
 
       strcpy (buf, _("n/a"));
-      if (tile_types[i].irrigation_result == i)
+      if (ptype->irrigation_result == i)
        {
-         if (tile_types[i].irrigation_food_incr > 0)
+         if (ptype->irrigation_food_incr > 0)
            {
              sprintf (buf, _("+%d Food / %d"),
-                      tile_types[i].irrigation_food_incr,
-                      tile_types[i].irrigation_time);
+                      ptype->irrigation_food_incr,
+                      ptype->irrigation_time);
            }
        }
-      else if (tile_types[i].irrigation_result != T_NONE)
+      else if (ptype->irrigation_result != T_NONE)
        {
          sprintf (buf, "%s / %d",
-                  tile_types[tile_types[i].irrigation_result].terrain_name,
-                  tile_types[i].irrigation_time);
+                  get_tile_type(ptype->irrigation_result)->terrain_name,
+                  ptype->irrigation_time);
        }
       xaw_set_label (help_terrain_irrigation_result_time_data, buf);
 
       strcpy (buf, _("n/a"));
-      if (tile_types[i].mining_result == i)
+      if (ptype->mining_result == i)
        {
-         if (tile_types[i].mining_shield_incr > 0)
+         if (ptype->mining_shield_incr > 0)
            {
              sprintf (buf, _("+%d Res. / %d"),
-                      tile_types[i].mining_shield_incr,
-                      tile_types[i].mining_time);
+                      ptype->mining_shield_incr,
+                      ptype->mining_time);
            }
        }
-      else if (tile_types[i].mining_result != T_NONE)
+      else if (ptype->mining_result != T_NONE)
        {
          sprintf (buf, "%s / %d",
-                  tile_types[tile_types[i].mining_result].terrain_name,
-                  tile_types[i].mining_time);
+                  get_tile_type(ptype->mining_result)->terrain_name,
+                  ptype->mining_time);
        }
       xaw_set_label (help_terrain_mining_result_time_data, buf);
 
-      if (tile_types[i].transform_result != T_NONE)
+      if (ptype->transform_result != T_NONE)
        {
          sprintf (buf, "%s / %d",
-                  tile_types[tile_types[i].transform_result].terrain_name,
-                  tile_types[i].transform_time);
+                  get_tile_type(ptype->transform_result)->terrain_name,
+                  ptype->transform_time);
        } else {
          strcpy (buf, _("n/a"));
        }
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.187.2.3
diff -p -u -r1.187.2.3 game.c
--- common/game.c       3 May 2005 03:21:24 -0000       1.187.2.3
+++ common/game.c       18 Jul 2005 18:41:31 -0000
@@ -547,7 +547,7 @@ void translate_data_names(void)
   } impr_type_iterate_end;
 
   terrain_type_iterate(i) {
-    struct tile_type *tthis = &tile_types[i];
+    struct tile_type *tthis = get_tile_type(i);
 
     tthis->terrain_name = ((strcmp(tthis->terrain_name_orig, "") != 0)
                           ? Q_(tthis->terrain_name_orig) : "");
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.199.2.3
diff -p -u -r1.199.2.3 map.c
--- common/map.c        18 Oct 2004 22:40:33 -0000      1.199.2.3
+++ common/map.c        18 Jul 2005 18:41:31 -0000
@@ -94,8 +94,9 @@ const char *map_get_tile_info_text(const
 {
   static char s[64];
   bool first;
+  struct tile_type *ptype = get_tile_type(ptile->terrain);
 
-  sz_strlcpy(s, tile_types[ptile->terrain].terrain_name);
+  sz_strlcpy(s, ptype->terrain_name);
   if (tile_has_special(ptile, S_RIVER)) {
     sz_strlcat(s, "/");
     sz_strlcat(s, get_special_name(S_RIVER));
@@ -109,7 +110,7 @@ const char *map_get_tile_info_text(const
     } else {
       sz_strlcat(s, "/");
     }
-    sz_strlcat(s, tile_types[ptile->terrain].special_1_name);
+    sz_strlcat(s, ptype->special_1_name);
   }
   if (tile_has_special(ptile, S_SPECIAL_2)) {
     if (first) {
@@ -118,7 +119,7 @@ const char *map_get_tile_info_text(const
     } else {
       sz_strlcat(s, "/");
     }
-    sz_strlcat(s, tile_types[ptile->terrain].special_2_name);
+    sz_strlcat(s, ptype->special_2_name);
   }
   if (!first) {
     sz_strlcat(s, ")");
@@ -728,11 +729,11 @@ bool is_sea_usable(const struct tile *pt
 int get_tile_food_base(const struct tile *ptile)
 {
   if (tile_has_special(ptile, S_SPECIAL_1)) 
-    return tile_types[ptile->terrain].food_special_1;
+    return get_tile_type(ptile->terrain)->food_special_1;
   else if (tile_has_special(ptile, S_SPECIAL_2))
-    return tile_types[ptile->terrain].food_special_2;
+    return get_tile_type(ptile->terrain)->food_special_2;
   else
-    return tile_types[ptile->terrain].food;
+    return get_tile_type(ptile->terrain)->food;
 }
 
 /***************************************************************
@@ -741,11 +742,11 @@ int get_tile_food_base(const struct tile
 int get_tile_shield_base(const struct tile *ptile)
 {
   if (tile_has_special(ptile, S_SPECIAL_1))
-    return tile_types[ptile->terrain].shield_special_1;
+    return get_tile_type(ptile->terrain)->shield_special_1;
   else if(tile_has_special(ptile, S_SPECIAL_2))
-    return tile_types[ptile->terrain].shield_special_2;
+    return get_tile_type(ptile->terrain)->shield_special_2;
   else
-    return tile_types[ptile->terrain].shield;
+    return get_tile_type(ptile->terrain)->shield;
 }
 
 /***************************************************************
@@ -754,11 +755,11 @@ int get_tile_shield_base(const struct ti
 int get_tile_trade_base(const struct tile *ptile)
 {
   if (tile_has_special(ptile, S_SPECIAL_1))
-    return tile_types[ptile->terrain].trade_special_1;
+    return get_tile_type(ptile->terrain)->trade_special_1;
   else if (tile_has_special(ptile, S_SPECIAL_2))
-    return tile_types[ptile->terrain].trade_special_2;
+    return get_tile_type(ptile->terrain)->trade_special_2;
   else
-    return tile_types[ptile->terrain].trade;
+    return get_tile_type(ptile->terrain)->trade;
 }
 
 /***************************************************************
@@ -865,7 +866,7 @@ bool is_water_adjacent_to_tile(const str
 ***************************************************************/
 int map_build_road_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].road_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->road_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -873,7 +874,7 @@ int map_build_road_time(const struct til
 ***************************************************************/
 int map_build_irrigation_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].irrigation_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->irrigation_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -881,7 +882,7 @@ int map_build_irrigation_time(const stru
 ***************************************************************/
 int map_build_mine_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].mining_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->mining_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -889,7 +890,7 @@ int map_build_mine_time(const struct til
 ***************************************************************/
 int map_transform_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].transform_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->transform_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -897,7 +898,7 @@ int map_transform_time(const struct tile
 ***************************************************************/
 int map_build_rail_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].rail_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->rail_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -905,7 +906,7 @@ int map_build_rail_time(const struct til
 ***************************************************************/
 int map_build_airbase_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].airbase_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->airbase_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -913,7 +914,7 @@ int map_build_airbase_time(const struct 
 ***************************************************************/
 int map_build_fortress_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].fortress_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->fortress_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -921,7 +922,7 @@ int map_build_fortress_time(const struct
 ***************************************************************/
 int map_clean_pollution_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].clean_pollution_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->clean_pollution_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -929,7 +930,7 @@ int map_clean_pollution_time(const struc
 ***************************************************************/
 int map_clean_fallout_time(const struct tile *ptile)
 {
-  return tile_types[ptile->terrain].clean_fallout_time * ACTIVITY_FACTOR;
+  return get_tile_type(ptile->terrain)->clean_fallout_time * ACTIVITY_FACTOR;
 }
 
 /***************************************************************
@@ -985,7 +986,7 @@ void map_irrigate_tile(struct tile *ptil
   Terrain_type_id now, result;
   
   now = ptile->terrain;
-  result = tile_types[now].irrigation_result;
+  result = get_tile_type(now)->irrigation_result;
 
   if (now == result) {
     if (map_has_special(ptile, S_IRRIGATION)) {
@@ -1016,7 +1017,7 @@ void map_mine_tile(struct tile *ptile)
   Terrain_type_id now, result;
   
   now = ptile->terrain;
-  result = tile_types[now].mining_result;
+  result = get_tile_type(now)->mining_result;
   
   if (now == result) {
     map_set_special(ptile, S_MINE);
@@ -1056,10 +1057,10 @@ void change_terrain(struct tile *ptile, 
      but I'm including both cases in the most general form for possible
      future ruleset expansion. -GJW) */
   
-  if (tile_types[type].mining_result != type)
+  if (get_tile_type(type)->mining_result != type)
     map_clear_special(ptile, S_MINE);
 
-  if (tile_types[type].irrigation_result != type)
+  if (get_tile_type(type)->irrigation_result != type)
     map_clear_special(ptile, S_FARMLAND | S_IRRIGATION);
 }
 
@@ -1071,7 +1072,7 @@ void map_transform_tile(struct tile *pti
   Terrain_type_id now, result;
   
   now = ptile->terrain;
-  result = tile_types[now].transform_result;
+  result = get_tile_type(now)->transform_result;
   
   if (result != T_NONE) {
     change_terrain(ptile, result);
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.219.2.6
diff -p -u -r1.219.2.6 map.h
--- common/map.h        18 Mar 2005 19:19:04 -0000      1.219.2.6
+++ common/map.h        18 Jul 2005 18:41:31 -0000
@@ -136,7 +136,6 @@ struct tile_type {
 
   char *helptext;
 };
-extern struct tile_type tile_types[MAX_NUM_TERRAINS];
 
 /* The direction8 gives the 8 possible directions.  These may be used in
  * a number of ways, for instance as an index into the DIR_DX/DIR_DY
Index: common/terrain.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.c,v
retrieving revision 1.16
diff -p -u -r1.16 terrain.c
--- common/terrain.c    29 Sep 2004 02:24:23 -0000      1.16
+++ common/terrain.c    18 Jul 2005 18:41:31 -0000
@@ -24,13 +24,23 @@
 #include "support.h"
 #include "terrain.h"
 
-struct tile_type tile_types[MAX_NUM_TERRAINS];
+static struct tile_type tile_types[MAX_NUM_TERRAINS];
 
 /***************************************************************
 ...
 ***************************************************************/
 struct tile_type *get_tile_type(Terrain_type_id type)
 {
+  if (type < 0 || type >= T_COUNT) {
+    /* HACK: return a dummy tile for out-of-range requests.  This is
+     * designed specifically to fix this problem in 2.0. */
+    static struct tile_type t_void;
+
+#if 0 /* Currently this assertion triggers all the time. */
+    assert(type >= 0 && type < T_COUNT);
+#endif
+    return &t_void;
+  }
   return &tile_types[type];
 }
 
@@ -55,8 +65,7 @@ Terrain_type_id get_terrain_by_name(cons
 ***************************************************************/
 const char *get_terrain_name(Terrain_type_id type)
 {
-  assert(type < T_COUNT);
-  return tile_types[type].terrain_name;
+  return get_tile_type(type)->terrain_name;
 }
 
 /****************************************************************************
Index: common/terrain.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.h,v
retrieving revision 1.29.2.1
diff -p -u -r1.29.2.1 terrain.h
--- common/terrain.h    18 Mar 2005 19:19:04 -0000      1.29.2.1
+++ common/terrain.h    18 Jul 2005 18:41:31 -0000
@@ -101,7 +101,8 @@ struct tile_type *get_tile_type(Terrain_
 Terrain_type_id get_terrain_by_name(const char * name);
 const char *get_terrain_name(Terrain_type_id type);
 enum terrain_flag_id terrain_flag_from_str(const char *s);
-#define terrain_has_flag(terr, flag) BV_ISSET(tile_types[(terr)].flags, flag)
+#define terrain_has_flag(terr, flag)           \
+  BV_ISSET(get_tile_type(terr)->flags, flag)
 Terrain_type_id get_flag_terrain(enum terrain_flag_id flag);
 void tile_types_free(void);
 
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.196.2.2
diff -p -u -r1.196.2.2 ruleset.c
--- server/ruleset.c    10 Nov 2004 17:02:03 -0000      1.196.2.2
+++ server/ruleset.c    18 Jul 2005 18:41:32 -0000
@@ -491,14 +491,14 @@ static Terrain_type_id lookup_terrain(ch
   }
 
   for (i = T_FIRST; i < T_COUNT; i++) {
-    if (0 == strcmp(name, tile_types[i].terrain_name)) {
+    if (0 == strcmp(name, get_tile_type(i)->terrain_name)) {
       return i;
     }
   }
 
   /* TRANS: message for an obscure ruleset error. */
   freelog(LOG_ERROR, _("Unknown terrain %s in entry %s."),
-         name, tile_types[tthis].terrain_name);
+         name, get_tile_type(tthis)->terrain_name);
   return T_NONE;
 }
 
@@ -1523,11 +1523,11 @@ static void load_terrain_names(struct se
   terrain_type_iterate(i) {
     char *name = secfile_lookup_str(file, "%s.terrain_name", sec[i]);
 
-    name_strlcpy(tile_types[i].terrain_name_orig, name);
-    if (0 == strcmp(tile_types[i].terrain_name_orig, "unused")) {
-      tile_types[i].terrain_name_orig[0] = '\0';
+    name_strlcpy(get_tile_type(i)->terrain_name_orig, name);
+    if (0 == strcmp(get_tile_type(i)->terrain_name_orig, "unused")) {
+      get_tile_type(i)->terrain_name_orig[0] = '\0';
     }
-    tile_types[i].terrain_name = tile_types[i].terrain_name_orig;
+    get_tile_type(i)->terrain_name = get_tile_type(i)->terrain_name_orig;
   } terrain_type_iterate_end;
 
   free(sec);
@@ -1606,7 +1606,7 @@ static void load_ruleset_terrain(struct 
   /* terrain details */
 
   terrain_type_iterate(i) {
-      struct tile_type *t = &(tile_types[i]);
+    struct tile_type *t = get_tile_type(i);
       char *s1_name, *s2_name, **slist;
 
       sz_strlcpy(t->graphic_str,
@@ -1616,11 +1616,11 @@ static void load_ruleset_terrain(struct 
 
       t->identifier = secfile_lookup_str(file, "%s.identifier", sec[i])[0];
       for (j = T_FIRST; j < i; j++) {
-       if (t->identifier == tile_types[j].identifier) {
+       if (t->identifier == get_tile_type(j)->identifier) {
          freelog(LOG_FATAL,
                  /* TRANS: message for an obscure ruleset error. */
                  _("Terrains %s and %s have the same identifier."),
-                 t->terrain_name, tile_types[j].terrain_name);
+                 t->terrain_name, get_tile_type(j)->terrain_name);
          exit(EXIT_FAILURE);
        }
       }
@@ -2212,7 +2212,8 @@ static struct city_name* load_city_name_
                * However this is not a problem because we take care of rivers
                * separately.
                */
-             if (mystrcasecmp(name, tile_types[type].terrain_name) == 0) {
+             if (mystrcasecmp(name,
+                              get_tile_type(type)->terrain_name) == 0) {
                city_names[j].terrain[type] = setting;
                handled = TRUE;
              }
@@ -2946,7 +2947,7 @@ static void send_ruleset_terrain(struct 
   lsend_packet_ruleset_terrain_control(dest, &terrain_control);
 
   terrain_type_iterate(i) {
-      struct tile_type *t = &(tile_types[i]);
+    struct tile_type *t = get_tile_type(i);
 
       packet.id = i;
 
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.197.2.16
diff -p -u -r1.197.2.16 savegame.c
--- server/savegame.c   10 Jul 2005 16:04:55 -0000      1.197.2.16
+++ server/savegame.c   18 Jul 2005 18:41:33 -0000
@@ -230,7 +230,7 @@ static Terrain_type_id char2terrain(char
     return T_UNKNOWN;
   }
   terrain_type_iterate(id) {
-    if (tile_types[id].identifier == ch) {
+    if (get_tile_type(id)->identifier == ch) {
       return id;
     }
   } terrain_type_iterate_end;
@@ -250,7 +250,7 @@ static char terrain2char(Terrain_type_id
     return UNKNOWN_TERRAIN_IDENTIFIER;
   } else {
     assert(terr >= T_FIRST && terr < T_COUNT);
-    return tile_types[terr].identifier;
+    return get_tile_type(terr)->identifier;
   }
 }
 
Index: server/generator/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v
retrieving revision 1.12.2.6
diff -p -u -r1.12.2.6 mapgen.c
--- server/generator/mapgen.c   23 Jun 2005 15:34:29 -0000      1.12.2.6
+++ server/generator/mapgen.c   18 Jul 2005 18:41:33 -0000
@@ -1228,20 +1228,20 @@ static void add_specials(int prob)
     if (!is_ocean(ttype)
        && !is_special_close(ptile) 
        && myrand(1000) < prob) {
-      if (tile_types[ttype].special_1_name[0] != '\0'
-         && (tile_types[ttype].special_2_name[0] == '\0'
+      if (get_tile_type(ttype)->special_1_name[0] != '\0'
+         && (get_tile_type(ttype)->special_2_name[0] == '\0'
              || (myrand(100) < 50))) {
        map_set_special(ptile, S_SPECIAL_1);
-      } else if (tile_types[ttype].special_2_name[0] != '\0') {
+      } else if (get_tile_type(ttype)->special_2_name[0] != '\0') {
        map_set_special(ptile, S_SPECIAL_2);
       }
     } else if (is_ocean(ttype) && near_safe_tiles(ptile) 
               && myrand(1000) < prob && !is_special_close(ptile)) {
-      if (tile_types[ttype].special_1_name[0] != '\0'
-         && (tile_types[ttype].special_2_name[0] == '\0'
+      if (get_tile_type(ttype)->special_1_name[0] != '\0'
+         && (get_tile_type(ttype)->special_2_name[0] == '\0'
              || (myrand(100) < 50))) {
         map_set_special(ptile, S_SPECIAL_1);
-      } else if (tile_types[ttype].special_2_name[0] != '\0') {
+      } else if (get_tile_type(ttype)->special_2_name[0] != '\0') {
        map_set_special(ptile, S_SPECIAL_2);
       }
     }

[Prev in Thread] Current Thread [Next in Thread]