"Server does not compile with -fstrict-aliasing"
- fixed all the aliasing-issues that gcc reported.
This commit is contained in:
Enno Rehling 2008-05-17 15:21:17 +00:00
parent 2b913dc9e1
commit 599fa82a27
35 changed files with 439 additions and 401 deletions

View File

@ -67,7 +67,7 @@ CCFLAGS += -Wwrite-strings
# -Wconversion
# -Wunreachable-code
-Werror
-fno-strict-aliasing
-fstrict-aliasing
;
# this require the latet luabind from CVS

View File

@ -61,7 +61,9 @@ a_readgive(attrib * a, struct storage * store)
var.i = store->r_id(store);
if (var.i>0) {
gdata->building = findbuilding(var.i);
if (gdata->building==NULL) ur_add(var, (void**)&gdata->building, resolve_building);
if (gdata->building==NULL) {
ur_add(var, &gdata->building, resolve_building);
}
} else {
gdata->building=NULL;
}

View File

@ -26,13 +26,16 @@
static void
write_gm(const attrib * a, struct storage * store)
{
write_plane_reference((plane*)a->data.v, store);
write_plane_reference((plane*)a->data.v, store);
}
static int
read_gm(attrib * a, struct storage * store)
{
return read_plane_reference((plane**)&a->data.v, store);
plane * pl;
int result = read_plane_reference(&pl, store);
a->data.v = pl;
return result;
}

View File

@ -35,13 +35,16 @@ verify_hate(attrib * a)
static void
write_hate(const attrib * a, struct storage * store)
{
write_unit_reference((unit*)a->data.v, store);
write_unit_reference((unit*)a->data.v, store);
}
static int
read_hate(attrib * a, struct storage * store)
{
return read_unit_reference((unit**)&a->data.v, store);
unit * u;
int result = read_unit_reference(&u, store);
a->data.v = u;
return result;
}
attrib_type at_hate = {

View File

@ -27,13 +27,16 @@
static void
write_targetregion(const attrib * a, struct storage * store)
{
write_region_reference((region*)a->data.v, store);
write_region_reference((region*)a->data.v, store);
}
static int
read_targetregion(attrib * a, struct storage * store)
{
return read_region_reference((region**)&a->data.v, store);
region * r;
int result = read_region_reference(&r, store);
a->data.v = r;
return result;
}
attrib_type at_targetregion = {

View File

@ -1835,49 +1835,51 @@ make_cmd(unit * u, struct order * ord)
static void
free_luxuries(struct attrib * a)
{
i_freeall((item**)&a->data.v);
item * itm = (item*)a->data.v;
a->data.v = NULL;
i_freeall(&itm);
}
const attrib_type at_luxuries = {
"luxuries", NULL, free_luxuries, NULL, NULL, NULL
"luxuries", NULL, free_luxuries, NULL, NULL, NULL
};
static void
expandbuying(region * r, request * buyorders)
{
int max_products;
unit *u;
static struct trade {
const luxury_type * type;
int number;
int multi;
} *trades, *trade;
static int ntrades=0;
int i, j;
const luxury_type * ltype;
if (ntrades==0) {
for (ltype=luxurytypes;ltype;ltype=ltype->next)
++ntrades;
trades = gc_add(calloc(sizeof(struct trade), ntrades));
for (i=0, ltype=luxurytypes;i!=ntrades;++i, ltype=ltype->next)
trades[i].type = ltype;
}
for (i=0;i!=ntrades;++i) {
trades[i].number = 0;
trades[i].multi = 1;
}
if (!buyorders) return;
/* Initialisation. multiplier ist der Multiplikator auf den
* Verkaufspreis. Für max_products Produkte kauft man das Produkt zum
* einfachen Verkaufspreis, danach erhöht sich der Multiplikator um 1.
* counter ist ein Zähler, der die gekauften Produkte zählt. money
* wird für die debug message gebraucht. */
max_products = rpeasants(r) / TRADE_FRACTION;
int max_products;
unit *u;
static struct trade {
const luxury_type * type;
int number;
int multi;
} *trades, *trade;
static int ntrades=0;
int i, j;
const luxury_type * ltype;
if (ntrades==0) {
for (ltype=luxurytypes;ltype;ltype=ltype->next)
++ntrades;
trades = gc_add(calloc(sizeof(struct trade), ntrades));
for (i=0, ltype=luxurytypes;i!=ntrades;++i, ltype=ltype->next)
trades[i].type = ltype;
}
for (i=0;i!=ntrades;++i) {
trades[i].number = 0;
trades[i].multi = 1;
}
if (!buyorders) return;
/* Initialisation. multiplier ist der Multiplikator auf den
* Verkaufspreis. Für max_products Produkte kauft man das Produkt zum
* einfachen Verkaufspreis, danach erhöht sich der Multiplikator um 1.
* counter ist ein Zähler, der die gekauften Produkte zählt. money
* wird für die debug message gebraucht. */
max_products = rpeasants(r) / TRADE_FRACTION;
/* Kauf - auch so programmiert, daß er leicht erweiterbar auf mehrere
* Güter pro Monat ist. j sind die Befehle, i der Index des
* gehandelten Produktes. */
@ -1895,6 +1897,7 @@ expandbuying(region * r, request * buyorders)
if (get_pooled(oa[j].unit, oldresourcetype[R_SILVER], GET_DEFAULT, price) >= price) {
unit * u = oa[j].unit;
item * items;
/* litems zählt die Güter, die verkauft wurden, u->n das Geld, das
* verdient wurde. Dies muß gemacht werden, weil der Preis ständig sinkt,
@ -1903,42 +1906,44 @@ expandbuying(region * r, request * buyorders)
attrib * a = a_find(u->attribs, &at_luxuries);
if (a==NULL) a = a_add(&u->attribs, a_new(&at_luxuries));
i_change((item**)&a->data.v, ltype->itype, 1);
i_change(&oa[j].unit->items, ltype->itype, 1);
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, price);
if (u->n < 0)
u->n = 0;
u->n += price;
rsetmoney(r, rmoney(r) + price);
/* Falls mehr als max_products Bauern ein Produkt verkauft haben, steigt
* der Preis Multiplikator für das Produkt um den Faktor 1. Der Zähler
* wird wieder auf 0 gesetzt. */
if (++trade->number == max_products) {
trade->number = 0;
++trade->multi;
items = a->data.v;
i_change(&items, ltype->itype, 1);
a->data.v = items;
i_change(&oa[j].unit->items, ltype->itype, 1);
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, price);
if (u->n < 0)
u->n = 0;
u->n += price;
rsetmoney(r, rmoney(r) + price);
/* Falls mehr als max_products Bauern ein Produkt verkauft haben, steigt
* der Preis Multiplikator für das Produkt um den Faktor 1. Der Zähler
* wird wieder auf 0 gesetzt. */
if (++trade->number == max_products) {
trade->number = 0;
++trade->multi;
}
fset(u, UFL_LONGACTION|UFL_NOTMOVING);
}
}
free(oa);
/* Ausgabe an Einheiten */
for (u = r->units; u; u = u->next) {
attrib * a = a_find(u->attribs, &at_luxuries);
item * itm;
if (a==NULL) continue;
ADDMSG(&u->faction->msgs, msg_message("buy", "unit money", u, u->n));
for (itm=(item*)a->data.v; itm; itm=itm->next) {
if (itm->number) {
ADDMSG(&u->faction->msgs, msg_message("buyamount",
"unit amount resource", u, itm->number, itm->type->rtype));
}
}
a_remove(&u->attribs, a);
}
}
}
free(oa);
/* Ausgabe an Einheiten */
for (u = r->units; u; u = u->next) {
attrib * a = a_find(u->attribs, &at_luxuries);
item * itm;
if (a==NULL) continue;
ADDMSG(&u->faction->msgs, msg_message("buy", "unit money", u, u->n));
for (itm=(item*)a->data.v; itm; itm=itm->next) {
if (itm->number) {
ADDMSG(&u->faction->msgs, msg_message("buyamount",
"unit amount resource", u, itm->number, itm->type->rtype));
}
}
a_remove(&u->attribs, a);
}
}
}
@ -2056,182 +2061,185 @@ static int tax_per_size[7] =
static void
expandselling(region * r, request * sellorders, int limit)
{
int money, price, j, max_products;
/* int m, n = 0; */
int maxsize = 0, maxeffsize = 0;
int taxcollected = 0;
int hafencollected = 0;
unit *maxowner = (unit *) NULL;
building *maxb = (building *) NULL;
building *b;
unit *u;
unit *hafenowner;
static int *counter;
static int ncounter = 0;
int money, price, j, max_products;
/* int m, n = 0; */
int maxsize = 0, maxeffsize = 0;
int taxcollected = 0;
int hafencollected = 0;
unit *maxowner = (unit *) NULL;
building *maxb = (building *) NULL;
building *b;
unit *u;
unit *hafenowner;
static int *counter;
static int ncounter = 0;
if (ncounter==0) {
const luxury_type * ltype;
for (ltype=luxurytypes;ltype;ltype=ltype->next) ++ncounter;
counter=(int*)gc_add(calloc(sizeof(int), ncounter));
} else {
memset(counter, 0, sizeof(int)*ncounter);
}
if (!sellorders) /* NEIN, denn Insekten können in || !r->buildings) */
return; /* Sümpfen und Wüsten auch so handeln */
/* Stelle Eigentümer der größten Burg fest. Bekommt Steuern aus jedem
* Verkauf. Wenn zwei Burgen gleicher Größe bekommt gar keiner etwas. */
for (b = rbuildings(r); b; b = b->next) {
if (b->size > maxsize && buildingowner(r, b) != NULL
&& b->type == bt_find("castle")) {
maxb = b;
maxsize = b->size;
maxowner = buildingowner(r, b);
} else if (b->size == maxsize && b->type == bt_find("castle")) {
maxb = (building *) NULL;
maxowner = (unit *) NULL;
}
}
hafenowner = owner_buildingtyp(r, bt_find("harbour"));
if (maxb != (building *) NULL && maxowner != (unit *) NULL) {
maxeffsize = buildingeffsize(maxb, false);
if (maxeffsize == 0) {
maxb = (building *) NULL;
maxowner = (unit *) NULL;
}
}
/* Die Region muss genug Geld haben, um die Produkte kaufen zu können. */
money = rmoney(r);
/* max_products sind 1/100 der Bevölkerung, falls soviele Produkte
* verkauft werden - counter[] - sinkt die Nachfrage um 1 Punkt.
* multiplier speichert r->demand für die debug message ab. */
max_products = rpeasants(r) / TRADE_FRACTION;
if (max_products <= 0) return;
if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan"))) {
max_products = rpeasants(r) * 2 / TRADE_FRACTION;
}
/* Verkauf: so programmiert, dass er leicht auf mehrere Gueter pro
* Runde erweitert werden kann. */
expandorders(r, sellorders);
if (!norders) return;
for (j = 0; j != norders; j++) {
static const luxury_type * search=NULL;
const luxury_type * ltype = oa[j].type.ltype;
int multi = r_demand(r, ltype);
static int i=-1;
int use = 0;
if (search!=ltype) {
i=0;
for (search=luxurytypes;search!=ltype;search=search->next) ++i;
}
if (ncounter==0) {
const luxury_type * ltype;
for (ltype=luxurytypes;ltype;ltype=ltype->next) ++ncounter;
counter=(int*)gc_add(calloc(sizeof(int), ncounter));
} else {
memset(counter, 0, sizeof(int)*ncounter);
}
if (!sellorders) { /* NEIN, denn Insekten können in || !r->buildings) */
return; /* Sümpfen und Wüsten auch so handeln */
}
/* Stelle Eigentümer der größten Burg fest. Bekommt Steuern aus jedem
* Verkauf. Wenn zwei Burgen gleicher Größe bekommt gar keiner etwas. */
for (b = rbuildings(r); b; b = b->next) {
if (b->size > maxsize && buildingowner(r, b) != NULL
&& b->type == bt_find("castle")) {
maxb = b;
maxsize = b->size;
maxowner = buildingowner(r, b);
} else if (b->size == maxsize && b->type == bt_find("castle")) {
maxb = (building *) NULL;
maxowner = (unit *) NULL;
}
}
hafenowner = owner_buildingtyp(r, bt_find("harbour"));
if (maxb != (building *) NULL && maxowner != (unit *) NULL) {
maxeffsize = buildingeffsize(maxb, false);
if (maxeffsize == 0) {
maxb = (building *) NULL;
maxowner = (unit *) NULL;
}
}
/* Die Region muss genug Geld haben, um die Produkte kaufen zu können. */
money = rmoney(r);
/* max_products sind 1/100 der Bevölkerung, falls soviele Produkte
* verkauft werden - counter[] - sinkt die Nachfrage um 1 Punkt.
* multiplier speichert r->demand für die debug message ab. */
max_products = rpeasants(r) / TRADE_FRACTION;
if (max_products <= 0) return;
if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan"))) {
max_products = rpeasants(r) * 2 / TRADE_FRACTION;
}
/* Verkauf: so programmiert, dass er leicht auf mehrere Gueter pro
* Runde erweitert werden kann. */
expandorders(r, sellorders);
if (!norders) return;
for (j = 0; j != norders; j++) {
static const luxury_type * search=NULL;
const luxury_type * ltype = oa[j].type.ltype;
int multi = r_demand(r, ltype);
static int i=-1;
int use = 0;
if (search!=ltype) {
i=0;
for (search=luxurytypes;search!=ltype;search=search->next) ++i;
}
if (counter[i]>=limit) continue;
if (counter[i]+1 > max_products && multi > 1) --multi;
price = ltype->price * multi;
if (money >= price) {
int abgezogenhafen = 0;
int abgezogensteuer = 0;
unit * u = oa[j].unit;
attrib * a = a_find(u->attribs, &at_luxuries);
if (a==NULL) a = a_add(&u->attribs, a_new(&at_luxuries));
i_change((item**)&a->data.v, ltype->itype, 1);
++use;
if (u->n < 0)
u->n = 0;
if (hafenowner != NULL) {
if (hafenowner->faction != u->faction) {
abgezogenhafen = price / 10;
hafencollected += abgezogenhafen;
price -= abgezogenhafen;
money -= abgezogenhafen;
}
}
if (maxb != NULL) {
if (maxowner->faction != u->faction) {
abgezogensteuer = price * tax_per_size[maxeffsize] / 100;
taxcollected += abgezogensteuer;
price -= abgezogensteuer;
money -= abgezogensteuer;
}
}
u->n += price;
change_money(u, price);
if (counter[i]+1 > max_products && multi > 1) --multi;
price = ltype->price * multi;
if (money >= price) {
int abgezogenhafen = 0;
int abgezogensteuer = 0;
unit * u = oa[j].unit;
item * itm;
attrib * a = a_find(u->attribs, &at_luxuries);
if (a==NULL) a = a_add(&u->attribs, a_new(&at_luxuries));
itm = (item *)a->data.v;
i_change(&itm, ltype->itype, 1);
a->data.v = itm;
++use;
if (u->n < 0)
u->n = 0;
if (hafenowner != NULL) {
if (hafenowner->faction != u->faction) {
abgezogenhafen = price / 10;
hafencollected += abgezogenhafen;
price -= abgezogenhafen;
money -= abgezogenhafen;
}
}
if (maxb != NULL) {
if (maxowner->faction != u->faction) {
abgezogensteuer = price * tax_per_size[maxeffsize] / 100;
taxcollected += abgezogensteuer;
price -= abgezogensteuer;
money -= abgezogensteuer;
}
}
u->n += price;
change_money(u, price);
fset(u, UFL_LONGACTION|UFL_NOTMOVING);
/* r->money -= price; --- dies wird eben nicht ausgeführt, denn die
* Produkte können auch als Steuern eingetrieben werden. In der Region
* wurden Silberstücke gegen Luxusgüter des selben Wertes eingetauscht!
* Falls mehr als max_products Kunden ein Produkt gekauft haben, sinkt
* die Nachfrage für das Produkt um 1. Der Zähler wird wieder auf 0
* gesetzt. */
if (++counter[i] > max_products) {
int d = r_demand(r, ltype);
/* r->money -= price; --- dies wird eben nicht ausgeführt, denn die
* Produkte können auch als Steuern eingetrieben werden. In der Region
* wurden Silberstücke gegen Luxusgüter des selben Wertes eingetauscht!
* Falls mehr als max_products Kunden ein Produkt gekauft haben, sinkt
* die Nachfrage für das Produkt um 1. Der Zähler wird wieder auf 0
* gesetzt. */
if (++counter[i] > max_products) {
int d = r_demand(r, ltype);
if (d > 1) {
r_setdemand(r, ltype, d-1);
}
counter[i] = 0;
}
}
if (use>0) {
counter[i] = 0;
}
}
if (use>0) {
#ifdef NDEBUG
use_pooled(oa[j].unit, ltype->itype->rtype, GET_DEFAULT, use);
use_pooled(oa[j].unit, ltype->itype->rtype, GET_DEFAULT, use);
#else
/* int i = */ use_pooled(oa[j].unit, ltype->itype->rtype, GET_DEFAULT, use);
/* assert(i==use); */
/* int i = */ use_pooled(oa[j].unit, ltype->itype->rtype, GET_DEFAULT, use);
/* assert(i==use); */
#endif
}
}
free(oa);
/* Steuern. Hier werden die Steuern dem Besitzer der größten Burg gegeben. */
if (maxowner) {
if (taxcollected > 0) {
change_money(maxowner, (int) taxcollected);
add_income(maxowner, IC_TRADETAX, taxcollected, taxcollected);
/* TODO: Meldung
}
}
free(oa);
/* Steuern. Hier werden die Steuern dem Besitzer der größten Burg gegeben. */
if (maxowner) {
if (taxcollected > 0) {
change_money(maxowner, (int) taxcollected);
add_income(maxowner, IC_TRADETAX, taxcollected, taxcollected);
/* TODO: Meldung
* "%s verdient %d Silber durch den Handel in %s.",
* unitname(maxowner), (int) taxcollected, regionname(r)); */
}
}
if (hafenowner) {
if (hafencollected > 0) {
change_money(hafenowner, (int) hafencollected);
add_income(hafenowner, IC_TRADETAX, hafencollected, hafencollected);
}
}
/* Berichte an die Einheiten */
for (u = r->units; u; u = u->next) {
attrib * a = a_find(u->attribs, &at_luxuries);
item * itm;
if (a==NULL) continue;
for (itm=(item*)a->data.v; itm; itm=itm->next) {
if (itm->number) {
ADDMSG(&u->faction->msgs, msg_message("sellamount",
"unit amount resource", u, itm->number, itm->type->rtype));
}
}
a_remove(&u->attribs, a);
add_income(u, IC_TRADE, u->n, u->n);
}
}
}
if (hafenowner) {
if (hafencollected > 0) {
change_money(hafenowner, (int) hafencollected);
add_income(hafenowner, IC_TRADETAX, hafencollected, hafencollected);
}
}
/* Berichte an die Einheiten */
for (u = r->units; u; u = u->next) {
attrib * a = a_find(u->attribs, &at_luxuries);
item * itm;
if (a==NULL) continue;
for (itm=(item*)a->data.v; itm; itm=itm->next) {
if (itm->number) {
ADDMSG(&u->faction->msgs, msg_message("sellamount",
"unit amount resource", u, itm->number, itm->type->rtype));
}
}
a_remove(&u->attribs, a);
add_income(u, IC_TRADE, u->n, u->n);
}
}
static boolean
sell(unit * u, request ** sellorders, struct order * ord)
sell(unit * u, request ** sellorders, struct order * ord)
{
boolean unlimited = true;
const item_type * itype;

View File

@ -62,9 +62,9 @@ find_border(unsigned int id)
return NULL;
}
void *
resolve_borderid(variant id) {
return (void*)find_border(id.i);
void
resolve_borderid(variant id, void * addr) {
*(border**)addr = find_border(id.i);
}
static border **

View File

@ -89,7 +89,7 @@ extern "C" {
extern border * find_border(unsigned int id);
void * resolve_borderid(variant data);
void resolve_borderid(variant data, void * addr);
extern border * get_borders(const struct region * r1, const struct region * r2);
/* returns the list of borders between r1 and r2 or r2 and r1 */

View File

@ -369,9 +369,10 @@ register_buildings(void)
#endif
}
void *
resolve_building(variant id) {
return findbuilding(id.i);
void
resolve_building(variant id, void * address) {
building ** b = (building **)address;
*b = findbuilding(id.i);
}
void

View File

@ -130,7 +130,7 @@ const struct building_type * findbuildingtype(const char * name, const struct lo
#include "build.h"
#define NOBUILDING NULL
extern void * resolve_building(variant data);
extern void resolve_building(variant data, void * address);
extern void write_building_reference(const struct building * b, struct storage * store);
extern int read_building_reference(struct building ** b, struct storage * store);

View File

@ -184,7 +184,7 @@ curse_read(attrib * a, struct storage * store)
} else {
c->magician = findunit(mageid.i);
if (!c->magician) {
ur_add(mageid, (void**)&c->magician, resolve_unit);
ur_add(mageid, (void*)&c->magician, resolve_unit);
}
}
} else {
@ -210,7 +210,9 @@ curse_read(attrib * a, struct storage * store)
cc->cursedmen = store->r_int(store);
}
if (c->type->typ == CURSETYP_REGION) {
read_region_reference((region**)&c->data.v, store);
region * r;
read_region_reference(&r, store);
c->data.v = r;
}
chash(c);
@ -687,10 +689,11 @@ is_cursed_with(const attrib *ap, const curse *c)
* } curse_type;
*/
void *
resolve_curse(variant id)
void
resolve_curse(variant id, void * address)
{
return cfindhash(id.i);
curse * c = cfindhash(id.i);
*(curse**)address = c;
}
static const char * oldnames[MAXCURSE] = {

View File

@ -309,7 +309,7 @@ extern int curse_age(struct attrib * a);
extern boolean cmp_curse(const struct attrib * a, const void * data);
extern boolean cmp_cursetype(const struct attrib * a, const void * data);
extern void * resolve_curse(variant data);
extern void resolve_curse(variant data, void * address);
extern boolean is_cursed_with(const struct attrib *ap, const struct curse *c);
extern boolean curse_active(const struct curse * c);

View File

@ -99,9 +99,9 @@ factionname(const faction * f)
return ibuf;
}
void *
resolve_faction(variant id) {
return findfaction(id.i);
void
resolve_faction(variant id, void * addr) {
*(faction**)addr = findfaction(id.i);
}
#define MAX_FACTION_ID (36*36*36*36)
@ -213,7 +213,7 @@ read_faction_reference(faction ** f, struct storage * store)
return AT_READ_FAIL;
}
*f = findfaction(id.i);
if (*f==NULL) ur_add(id, (void**)f, resolve_faction);
if (*f==NULL) ur_add(id, f, resolve_faction);
return AT_READ_OK;
}

View File

@ -125,7 +125,7 @@ typedef struct faction_list {
extern const struct unit * random_unit_in_faction(const struct faction *f);
extern const char * factionname(const struct faction * f);
extern void * resolve_faction(variant data);
extern void resolve_faction(variant data, void * addr);
extern struct unit * addplayer(struct region *r, faction * f);
extern struct faction * addfaction(const char *email, const char* password,
const struct race * frace,

View File

@ -224,7 +224,7 @@ read_groups(struct storage * store, faction * f)
pa = &a->next;
a->status = store->r_int(store);
a->faction = findfaction(fid.i);
if (!a->faction) ur_add(fid, (void**)&a->faction, resolve_faction);
if (!a->faction) ur_add(fid, &a->faction, resolve_faction);
}
*pa = 0;
a_read(store, &g->attribs);

View File

@ -126,7 +126,7 @@ a_readicastle(attrib * a, struct storage * store)
data->building = findbuilding(bno.i);
if (!data->building) {
/* this shouldn't happen, but just in case it does: */
ur_add(bno, (void**)&data->building, resolve_building);
ur_add(bno, &data->building, resolve_building);
}
data->type = bt_find(token);
return AT_READ_OK;
@ -2207,10 +2207,11 @@ create_newfamiliar(unit * mage, unit * familiar)
return true;
}
static void *
resolve_familiar(variant data)
static void
resolve_familiar(variant data, void * addr)
{
unit * familiar = resolve_unit(data);
unit * familiar;
resolve_unit(data, &familiar);
if (familiar) {
attrib * a = a_find(familiar->attribs, &at_familiarmage);
if (a!=NULL && a->data.v) {
@ -2218,7 +2219,7 @@ resolve_familiar(variant data)
set_familiar(mage, familiar);
}
}
return familiar;
*(unit**)addr = familiar;
}
static int
@ -2283,10 +2284,11 @@ has_clone(unit *mage)
return NULL;
}
static void *
resolve_clone(variant data)
static void
resolve_clone(variant data, void * addr)
{
unit * clone = resolve_unit(data);
unit * clone;
resolve_unit(data, &clone);
if (clone) {
attrib * a = a_find(clone->attribs, &at_clonemage);
if (a!=NULL && a->data.v) {
@ -2294,7 +2296,7 @@ resolve_clone(variant data)
set_clone(mage, clone);
}
}
return clone;
*(unit**)addr = clone;
}
static int
@ -2308,10 +2310,11 @@ read_clone(attrib * a, struct storage * store)
/* mages */
static void *
resolve_mage(variant data)
static void
resolve_mage(variant data, void * addr)
{
unit * mage = resolve_unit(data);
unit * mage;
resolve_unit(data, &mage);
if (mage) {
attrib * a = a_find(mage->attribs, &at_familiar);
if (a!=NULL && a->data.v) {
@ -2319,7 +2322,7 @@ resolve_mage(variant data)
set_familiar(mage, familiar);
}
}
return mage;
*(unit **)addr = mage;
}
static int

View File

@ -232,10 +232,10 @@ rel_to_abs(const struct plane *pl, const struct faction * f, short rel, unsigned
}
void *
resolve_plane(variant id)
void
resolve_plane(variant id, void * addr)
{
return getplanebyid(id.i);
*(plane**)addr = getplanebyid(id.i);
}
void
@ -247,15 +247,15 @@ write_plane_reference(const plane * u, struct storage * store)
int
read_plane_reference(plane ** pp, struct storage * store)
{
variant id;
id.i = store->r_int(store);
if (id.i==0) {
*pp = NULL;
return AT_READ_FAIL;
}
*pp = getplanebyid(id.i);
if (*pp==NULL) ur_add(id, (void**)pp, resolve_plane);
return AT_READ_OK;
variant id;
id.i = store->r_int(store);
if (id.i==0) {
*pp = NULL;
return AT_READ_FAIL;
}
*pp = getplanebyid(id.i);
if (*pp==NULL) ur_add(id, pp, resolve_plane);
return AT_READ_OK;
}
boolean

View File

@ -73,7 +73,7 @@ plane * create_new_plane(int id, const char *name, short minx, short maxx, short
plane * getplanebyname(const char *);
extern short rel_to_abs(const struct plane *pl, const struct faction * f, short rel, unsigned char index);
extern boolean is_watcher(const struct plane * p, const struct faction * f);
extern void * resolve_plane(variant data);
extern void resolve_plane(variant data, void * addr);
extern void write_plane_reference(const plane * p, struct storage * store);
extern int read_plane_reference(plane ** pp, struct storage * store);

View File

@ -386,7 +386,8 @@ attrib_type at_moveblock = {
#define coor_hashkey(x, y) (unsigned int)((x<<16) + y)
#define RMAXHASH MAXREGIONS
static region * regionhash[RMAXHASH];
static region * delmarker = (region*)regionhash; /* a funny hack */
static int dummy_data;
static region * delmarker = (region*)&dummy_data; /* a funny hack */
static unsigned int uidhash[MAXREGIONS];
unsigned int
@ -1190,9 +1191,10 @@ write_region_reference(const region * r, struct storage * store)
}
}
void *
resolve_region(variant id) {
return findregion(id.sa[0], id.sa[1]);
void
resolve_region(variant id, void * address) {
region * r = findregion(id.sa[0], id.sa[1]);
*(region**)address = r;
}

View File

@ -219,7 +219,7 @@ extern int r_demand(const struct region * r, const struct luxury_type * ltype);
extern const char * regionname(const struct region * r, const struct faction * f);
extern const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size);
extern void * resolve_region(variant data);
extern void resolve_region(variant data, void * address);
extern struct region * new_region(short x, short y, unsigned int uid);
extern void terraform(struct region * r, terrain_t terrain);
extern void terraform_region(struct region * r, const struct terrain_type * terrain);

View File

@ -1430,12 +1430,13 @@ var_copy_items(variant x)
static void
var_free_resources(variant x)
{
resource ** rsrc = (resource**)&x.v;
while (*rsrc) {
resource * res = *rsrc;
*rsrc = res->next;
free(res);
resource * rsrc = (resource*)x.v;
while (rsrc) {
resource * res = rsrc->next;
free(rsrc);
rsrc = res;
}
x.v = 0;
}
static variant

View File

@ -251,10 +251,12 @@ read_enemies(struct storage * store, faction * f)
int fno = store->r_id(store);
if (fno<=0) break;
else {
variant id;
faction_list * flist = malloc(sizeof(faction_list));
flist->next = f->enemies;
f->enemies = flist;
ur_add((void*)fno, (void**)&flist->data, resolve_faction);
id.i = fno;
ur_add(id, &flist->data, resolve_faction);
}
}
}
@ -1147,7 +1149,7 @@ addally(const faction * f, ally ** sfp, int aid, int state)
if (!sf->faction) {
variant id;
id.i = aid;
ur_add(id, (void**)&sf->faction, resolve_faction);
ur_add(id, &sf->faction, resolve_faction);
}
sf->status = state & HELP_ALL;
@ -1438,7 +1440,7 @@ readgame(const char * filename, int mode, int backup)
w->mode = (unsigned char)store->r_int(store);
w->next = pl->watchers;
pl->watchers = w;
ur_add(fno, (void**)&w->faction, resolve_faction);
ur_add(fno, &w->faction, resolve_faction);
store->r_str_buf(store, token, sizeof(token));
}
}

View File

@ -502,7 +502,10 @@ a_writesiege(const attrib * a, struct storage * store)
int
a_readsiege(attrib * a, struct storage * store)
{
return read_building_reference((struct building**)&a->data.v, store);
struct building * b;
int result = read_building_reference(&b, store);
a->data.v = b;
return result;
}
attrib_type at_siege = {
@ -600,10 +603,11 @@ write_unit_reference(const unit * u, struct storage * store)
store->w_id(store, u?u->no:0);
}
void *
resolve_unit(variant id)
void
resolve_unit(variant id, void * address)
{
return ufindhash(id.i);
unit * u = ufindhash(id.i);
*(unit**)address = u;
}
int

View File

@ -181,7 +181,7 @@ extern void remove_unit(struct unit * u);
extern void distribute_items(struct unit * u);
/* see resolve.h */
extern void * resolve_unit(variant data);
extern void resolve_unit(variant data, void * address);
extern void write_unit_reference(const struct unit * u, struct storage * store);
extern int read_unit_reference(unit ** up, struct storage * store);

View File

@ -411,33 +411,35 @@ caldera_handle(trigger * t, void * data)
static void
caldera_write(const trigger * t, struct storage * store)
{
building *b = (building *)t->data.v;
write_building_reference(b, store);
building *b = (building *)t->data.v;
write_building_reference(b, store);
}
static int
caldera_read(trigger * t, struct storage * store)
{
read_building_reference((building**)&t->data.v, store);
return AT_READ_OK;
building * b;
read_building_reference(&b, store);
t->data.v = b;
return AT_READ_OK;
}
struct trigger_type tt_caldera = {
"caldera",
NULL,
NULL,
caldera_handle,
caldera_write,
caldera_read
"caldera",
NULL,
NULL,
caldera_handle,
caldera_write,
caldera_read
};
#ifdef ARENA_CREATION
static trigger *
trigger_caldera(building * b)
{
trigger * t = t_new(&tt_caldera);
t->data.v = b;
return t;
trigger * t = t_new(&tt_caldera);
t->data.v = b;
return t;
}
#endif

View File

@ -73,25 +73,9 @@ write_permissions(const attrib * a, struct storage * store)
static int
read_permissions(attrib * at, struct storage * store)
{
attrib ** p_a = (attrib**)&at->data.v;
a_read(store, p_a);
/* eliminate duplicates: */
while (*p_a) {
attrib * a = (*p_a)->next;
while (a) {
attrib * nexta = a->next;
if (a->type == (*p_a)->type && a->data.v==(*p_a)->data.v) {
static int print = 0;
a_remove((attrib**)&at->data.v, a);
if (!print) {
log_error(("duplicated entries in permission structure\n"));
print = 1;
}
}
a = nexta;
}
p_a = &(*p_a)->next;
}
attrib * attr;
a_read(store, &attr);
at->data.v = attr;
return AT_READ_OK;
}
@ -124,10 +108,9 @@ static int
read_gmcreate(attrib * a, struct storage * store)
{
char zText[32];
const item_type ** p_itype = (const item_type **)&a->data.v;
store->r_tok_buf(store, zText, sizeof(zText));
*p_itype = it_find(zText);
if (a->data.v==NULL) {
a->data.v = it_find(zText);
if (a->data.v == NULL) {
log_error(("unknown itemtype %s in gmcreate attribute\n", zText));
return AT_READ_FAIL;
}
@ -718,21 +701,22 @@ gm_addfaction(const char * email, plane * p, region * r)
/* generic permissions */
a = a_add(&f->attribs, a_new(&at_permissions));
if (a) {
attrib * ap = (attrib*)a->data.v;
const char* keys[] = { "gmterf", "gmtele", "gmgive", "gmskil", "gmtake", "gmmsgr", "gmmsgu", "gmgate", 0 };
const char ** key_p = keys;
while (*key_p) {
add_key(&ap, atoi36(*key_p));
++key_p;
}
a_add(&ap, make_atgmcreate(resource2item(r_silver)));
add_key((attrib**)&a->data.v, atoi36("gmterf"));
add_key((attrib**)&a->data.v, atoi36("gmtele"));
add_key((attrib**)&a->data.v, atoi36("gmgive"));
add_key((attrib**)&a->data.v, atoi36("gmskil"));
add_key((attrib**)&a->data.v, atoi36("gmtake"));
add_key((attrib**)&a->data.v, atoi36("gmmsgr"));
add_key((attrib**)&a->data.v, atoi36("gmmsgu"));
add_key((attrib**)&a->data.v, atoi36("gmgate"));
a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver)));
for (i=0;i<=I_HORSE;++i) {
a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i]));
for (i=0;i<=I_HORSE;++i) {
a_add(&ap, make_atgmcreate(olditemtype[i]));
}
a->data.v = ap;
}
/* one initial unit */
u = create_unit(r, f, 1, new_race[RC_TEMPLATE], 1, "quest master", NULL);
u->irace = new_race[RC_GNOME];

View File

@ -41,14 +41,17 @@ xmasgate_handle(trigger * t, void * data)
static void
xmasgate_write(const trigger * t, struct storage * store)
{
building *b = (building *)t->data.v;
store->w_tok(store, itoa36(b->no));
building *b = (building *)t->data.v;
store->w_tok(store, itoa36(b->no));
}
static int
xmasgate_read(trigger * t, struct storage * store)
{
return read_building_reference((building**)&t->data.v, store);
building * b;
int result =read_building_reference(&b, store);
t->data.v = b;
return result;
}
struct trigger_type tt_xmasgate = {

View File

@ -2678,7 +2678,7 @@ typedef struct bresvole {
curse * self;
} bresolve;
static void * resolve_buddy(variant data);
static void resolve_buddy(variant data, void * addr);
static int
cw_read(attrib * a, storage * store)
@ -2693,10 +2693,10 @@ cw_read(attrib * a, storage * store)
br->id = store->r_int(store);
var.i = br->id;
ur_add(var, (void**)&wc->wall, resolve_borderid);
ur_add(var, &wc->wall, resolve_borderid);
var.v = br;
ur_add(var, (void**)&wc->buddy, resolve_buddy);
ur_add(var, &wc->buddy, resolve_buddy);
return AT_READ_OK;
}
@ -2711,11 +2711,13 @@ attrib_type at_cursewall =
ATF_CURSE
};
static void *
resolve_buddy(variant data)
static void
resolve_buddy(variant data, void * addr)
{
curse * result = NULL;
bresolve * br = (bresolve*)data.v;
border * b = find_border(br->id);
if (b && b->from && b->to) {
attrib * a = a_find(b->from->attribs, &at_cursewall);
while (a && a->data.v!=br->self) {
@ -2736,10 +2738,10 @@ resolve_buddy(variant data)
if (a && a->type==&at_cursewall) {
curse * c = (curse*)a->data.v;
free(br);
return c;
result = c;
}
}
return NULL;
*(curse**)addr = result;
}
@ -2779,7 +2781,7 @@ wall_read(border * b, storage * store)
mno.i = store->r_int(store);
fd->mage = findunit(mno.i);
if (!fd->mage) {
ur_add(mno, (void**)&fd->mage, resolve_unit);
ur_add(mno, &fd->mage, resolve_unit);
}
} else {
read_unit_reference(&fd->mage, store);
@ -3196,7 +3198,7 @@ dc_read_compat(struct attrib * a, storage * store)
c = create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration, effect, 0);
c->data.v = r;
if (u==NULL) {
ur_add(var, (void**)&c->magician, resolve_unit);
ur_add(var, &c->magician, resolve_unit);
}
}
return AT_READ_FAIL; /* we don't care for the attribute. */

View File

@ -58,14 +58,17 @@ clonedied_handle(trigger * t, void * data)
static void
clonedied_write(const trigger * t, struct storage * store)
{
unit * u = (unit*)t->data.v;
write_unit_reference(u, store);
unit * u = (unit*)t->data.v;
write_unit_reference(u, store);
}
static int
clonedied_read(trigger * t, struct storage * store)
{
return read_unit_reference((unit**)&t->data.v, store);
unit * u;
int result = read_unit_reference(&u, store);
t->data.v = u;
return result;
}
trigger_type tt_clonedied = {

View File

@ -50,14 +50,17 @@ killunit_handle(trigger * t, void * data)
static void
killunit_write(const trigger * t, struct storage * store)
{
unit * u = (unit*)t->data.v;
write_unit_reference(u, store);
unit * u = (unit*)t->data.v;
write_unit_reference(u, store);
}
static int
killunit_read(trigger * t, struct storage * store)
{
return read_unit_reference((unit**)&t->data.v, store);
unit * u;
int result = read_unit_reference(&u, store);
t->data.v = u;
return result;
}
trigger_type tt_killunit = {

View File

@ -84,16 +84,18 @@ removecurse_write(const trigger * t, struct storage * store)
static int
removecurse_read(trigger * t, struct storage * store)
{
removecurse_data * td = (removecurse_data*)t->data.v;
variant var;
removecurse_data * td = (removecurse_data*)t->data.v;
variant var;
read_unit_reference(&td->target, store);
read_unit_reference(&td->target, store);
var.i = store->r_int(store);
td->curse = cfindhash(var.i);
if (td->curse==NULL) ur_add(var, (void**)&td->curse, resolve_curse);
return AT_READ_OK;
var.i = store->r_int(store);
td->curse = cfindhash(var.i);
if (td->curse==NULL) {
ur_add(var, &td->curse, resolve_curse);
}
return AT_READ_OK;
}
trigger_type tt_removecurse = {

View File

@ -101,26 +101,29 @@ shock_handle(trigger * t, void * data)
static void
shock_write(const trigger * t, struct storage * store)
{
unit * u = (unit*)t->data.v;
trigger * next = t->next;
while (next) {
/* make sure it is unique! */
if (next->type==t->type && next->data.v==t->data.v) break;
next=next->next;
}
if (next && u) {
log_error(("more than one shock-attribut for %s on a unit. FIXED.\n",
unitid(u)));
write_unit_reference(NULL, store);
} else {
write_unit_reference(u, store);
}
unit * u = (unit*)t->data.v;
trigger * next = t->next;
while (next) {
/* make sure it is unique! */
if (next->type==t->type && next->data.v==t->data.v) break;
next=next->next;
}
if (next && u) {
log_error(("more than one shock-attribut for %s on a unit. FIXED.\n",
unitid(u)));
write_unit_reference(NULL, store);
} else {
write_unit_reference(u, store);
}
}
static int
shock_read(trigger * t, struct storage * store)
{
return read_unit_reference((unit**)&t->data.v, store);
unit * u;
int result = read_unit_reference(&u, store);
t->data.v = u;
return result;
}
trigger_type tt_shock = {

View File

@ -43,13 +43,16 @@ unguard_handle(trigger * t, void * data)
static void
unguard_write(const trigger * t, struct storage * store)
{
write_building_reference((building*)t->data.v, store);
write_building_reference((building*)t->data.v, store);
}
static int
unguard_read(trigger * t, struct storage * store)
{
return read_building_reference((building**)&t->data.v, store);
building * b;
int result = read_building_reference(&b, store);
t->data.v = b;
return result;
}
struct trigger_type tt_unguard = {

View File

@ -26,9 +26,8 @@
#include "variant.h"
typedef struct unresolved {
void ** ptrptr;
/* pointer to the location where the unresolved object
* should be, or NULL if special handling is required */
void * ptrptr;
/* address to pass to the resolve-function */
variant data;
/* information on how to resolve the missing object */
resolve_fun resolve;
@ -41,7 +40,7 @@ static unresolved * ur_begin;
static unresolved * ur_current;
void
ur_add(variant data, void ** ptrptr, resolve_fun fun)
ur_add(variant data, void * ptrptr, resolve_fun fun)
{
if (ur_list==NULL) {
ur_list = malloc(BLOCKSIZE*sizeof(unresolved));
@ -72,8 +71,7 @@ resolve(void)
ur_list = ur;
continue;
}
if (ur->ptrptr) *ur->ptrptr = ur->resolve(ur->data);
else ur->resolve(ur->data);
ur->resolve(ur->data, ur->ptrptr);
++ur;
}
ur_list = ur_begin = ur_current;

View File

@ -21,8 +21,8 @@
extern "C" {
#endif
typedef void * (*resolve_fun)(variant data);
extern void ur_add(variant data, void ** ptrptr, resolve_fun fun);
typedef void (*resolve_fun)(variant data, void * address);
extern void ur_add(variant data, void * ptrptr, resolve_fun fun);
extern void resolve(void);
#ifdef __cplusplus