diff --git a/src/Jamrules b/src/Jamrules index 8bd03e4b3..a6344b7d7 100644 --- a/src/Jamrules +++ b/src/Jamrules @@ -67,7 +67,7 @@ CCFLAGS += -Wwrite-strings # -Wconversion # -Wunreachable-code -Werror - -fno-strict-aliasing + -fstrict-aliasing ; # this require the latet luabind from CVS diff --git a/src/common/attributes/giveitem.c b/src/common/attributes/giveitem.c index 9fb31fca3..bff90ebdc 100644 --- a/src/common/attributes/giveitem.c +++ b/src/common/attributes/giveitem.c @@ -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; } diff --git a/src/common/attributes/gm.c b/src/common/attributes/gm.c index 9cfcb9b71..e3bec9010 100644 --- a/src/common/attributes/gm.c +++ b/src/common/attributes/gm.c @@ -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; } diff --git a/src/common/attributes/hate.c b/src/common/attributes/hate.c index 55806058e..5ca54e0ee 100644 --- a/src/common/attributes/hate.c +++ b/src/common/attributes/hate.c @@ -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 = { diff --git a/src/common/attributes/targetregion.c b/src/common/attributes/targetregion.c index f0e0f77c3..c554834dc 100644 --- a/src/common/attributes/targetregion.c +++ b/src/common/attributes/targetregion.c @@ -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 = { diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 2b95d4e7e..b2ece0c4d 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -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; diff --git a/src/common/kernel/border.c b/src/common/kernel/border.c index 41290a37a..7b9b30831 100644 --- a/src/common/kernel/border.c +++ b/src/common/kernel/border.c @@ -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 ** diff --git a/src/common/kernel/border.h b/src/common/kernel/border.h index 90cdd3522..a88bc74db 100644 --- a/src/common/kernel/border.h +++ b/src/common/kernel/border.h @@ -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 */ diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index d0c5dbea3..def3e82ff 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -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 diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index eaa8d8447..ac1d1866c 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -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); diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index 289dd044f..9448ec848 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -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] = { diff --git a/src/common/kernel/curse.h b/src/common/kernel/curse.h index 623e769aa..e44807d4d 100644 --- a/src/common/kernel/curse.h +++ b/src/common/kernel/curse.h @@ -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); diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 16962261d..704e4aa32 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -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; } diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index 21deb3f00..b0ccf5dd0 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -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, diff --git a/src/common/kernel/group.c b/src/common/kernel/group.c index 28a16bbfc..ae7da0a79 100644 --- a/src/common/kernel/group.c +++ b/src/common/kernel/group.c @@ -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); diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 7a4b6fc53..a049f4c8e 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -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 diff --git a/src/common/kernel/plane.c b/src/common/kernel/plane.c index 13c2a0d49..c26ff0c22 100644 --- a/src/common/kernel/plane.c +++ b/src/common/kernel/plane.c @@ -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 diff --git a/src/common/kernel/plane.h b/src/common/kernel/plane.h index 59d6446ea..412345e14 100644 --- a/src/common/kernel/plane.h +++ b/src/common/kernel/plane.h @@ -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); diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 2d6b0d880..21dcb6f03 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -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; } diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index f611813d6..591f1c3a1 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -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); diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 4cf8794b7..cbb7eb382 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -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 diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 02c1facf9..49cb56b5a 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -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)); } } diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 00014990c..b45c9e037 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -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 diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 9a75e0cff..84b754561 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -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); diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index 0c5bd56a6..1c1500cdb 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -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 diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index 1041ac1e6..cb063a56c 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -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]; diff --git a/src/common/modules/xmas.c b/src/common/modules/xmas.c index dfc969ce9..6a3e9c408 100644 --- a/src/common/modules/xmas.c +++ b/src/common/modules/xmas.c @@ -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 = { diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 4f0cf5958..3c237b125 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -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. */ diff --git a/src/common/triggers/clonedied.c b/src/common/triggers/clonedied.c index 79f95384f..8848a32ff 100644 --- a/src/common/triggers/clonedied.c +++ b/src/common/triggers/clonedied.c @@ -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 = { diff --git a/src/common/triggers/killunit.c b/src/common/triggers/killunit.c index 7e85aa863..cbe6d013c 100644 --- a/src/common/triggers/killunit.c +++ b/src/common/triggers/killunit.c @@ -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 = { diff --git a/src/common/triggers/removecurse.c b/src/common/triggers/removecurse.c index df9cf6c18..e0a5fb202 100644 --- a/src/common/triggers/removecurse.c +++ b/src/common/triggers/removecurse.c @@ -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 = { diff --git a/src/common/triggers/shock.c b/src/common/triggers/shock.c index 5758ab5df..434872719 100644 --- a/src/common/triggers/shock.c +++ b/src/common/triggers/shock.c @@ -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 = { diff --git a/src/common/triggers/unguard.c b/src/common/triggers/unguard.c index e5fe8f04d..c2fa34d13 100644 --- a/src/common/triggers/unguard.c +++ b/src/common/triggers/unguard.c @@ -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 = { diff --git a/src/common/util/resolve.c b/src/common/util/resolve.c index 42710794c..f496c5b5c 100644 --- a/src/common/util/resolve.c +++ b/src/common/util/resolve.c @@ -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; diff --git a/src/common/util/resolve.h b/src/common/util/resolve.h index d76663da1..bbb75442d 100644 --- a/src/common/util/resolve.h +++ b/src/common/util/resolve.h @@ -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