Merge pull request #561 from ennorehling/develop

memory leaks and unwanted test dependencies
This commit is contained in:
Enno Rehling 2016-09-08 19:55:16 +02:00 committed by GitHub
commit 7a2614a7fe
28 changed files with 162 additions and 127 deletions

View File

@ -14,23 +14,27 @@
#include <triggers/triggers.h>
#include <util/language.h>
#include <util/functions.h>
#include <kernel/xmlreader.h>
#include <kernel/item.h>
#include <kernel/curse.h>
#include <kernel/building.h>
#include <kernel/curse.h>
#include <kernel/equipment.h>
#include <kernel/item.h>
#include <kernel/xmlreader.h>
#include <modules/gmcmd.h>
#include <modules/xmas.h>
#include <items/itemtypes.h>
#include <attributes/attributes.h>
#include <util/message.h>
#include <races/races.h>
#include "chaos.h"
#include "report.h"
#include "items.h"
#include "creport.h"
#include "items.h"
#include "jsreport.h"
#include "names.h"
#include "wormhole.h"
#include "report.h"
#include "reports.h"
#include "spells.h"
#include "wormhole.h"
void game_done(void)
{
@ -51,7 +55,6 @@ void game_done(void)
free_functions();
free_config();
free_locales();
curses_done();
kernel_done();
}

View File

@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "building.h"
#include "calendar.h"
#include "direction.h"
#include "equipment.h"
#include "faction.h"
#include "group.h"
#include "item.h"
@ -400,24 +401,24 @@ building *largestbuilding(const region * r, cmp_building_cb cmp_gt,
static const char *forbidden[] = { "t", "te", "tem", "temp", NULL };
// PEASANT: "b", "ba", "bau", "baue", "p", "pe", "pea", "peas"
static int *forbidden_ids;
int forbiddenid(int id)
{
static int *forbid = NULL;
static size_t len;
size_t i;
if (id <= 0)
return 1;
if (!forbid) {
if (!forbidden_ids) {
while (forbidden[len])
++len;
forbid = calloc(len, sizeof(int));
forbidden_ids = calloc(len, sizeof(int));
for (i = 0; i != len; ++i) {
forbid[i] = atoi36(forbidden[i]);
forbidden_ids[i] = atoi36(forbidden[i]);
}
}
for (i = 0; i != len; ++i)
if (id == forbid[i])
if (id == forbidden_ids[i])
return 1;
return 0;
}
@ -738,8 +739,15 @@ void kernel_done(void)
/* calling this function releases memory assigned to static variables, etc.
* calling it is optional, e.g. a release server will most likely not do it.
*/
xml_done();
attrib_done();
item_done();
message_done();
equipment_done();
reports_done();
curses_done();
crmessage_done();
translation_done();
free_attribs();
}
#ifndef HAVE_STRDUP
@ -1078,7 +1086,6 @@ void free_config(void) {
void free_gamedata(void)
{
int i;
free_donations();
for (i = 0; i != MAXLOCALES; ++i) {
if (defaults[i]) {
@ -1086,21 +1093,25 @@ void free_gamedata(void)
defaults[i] = 0;
}
}
free(forbidden_ids);
forbidden_ids = NULL;
free_donations();
free_factions();
free_units();
free_regions();
free_borders();
free_alliances();
while (global.attribs) {
a_remove(&global.attribs, global.attribs);
}
while (planes) {
plane *pl = planes;
planes = planes->next;
free_plane(pl);
}
while (global.attribs) {
a_remove(&global.attribs, global.attribs);
}
}
const char * game_name(void) {

View File

@ -223,3 +223,28 @@ void equip_items(struct item **items, const struct equipment *eq)
}
}
}
void equipment_done(void) {
equipment **eqp = &equipment_sets;
while (*eqp) {
int i;
equipment *eq = *eqp;
*eqp = eq->next;
free(eq->name);
if (eq->spellbook) {
spellbook_clear(eq->spellbook);
free(eq->spellbook);
}
while (eq->items) {
itemdata *next = eq->items->next;
free(eq->items->value);
free(eq->items);
eq->items = next;
}
// TODO: subsets, skills
for (i=0;i!=MAXSKILLS;++i) {
free(eq->skills[i]);
}
free(eq);
}
}

View File

@ -54,6 +54,8 @@ extern "C" {
void(*callback) (const struct equipment *, struct unit *);
} equipment;
void equipment_done(void);
struct equipment *create_equipment(const char *eqname);
struct equipment *get_equipment(const char *eqname);

View File

@ -20,7 +20,7 @@ void test_equipment(CuTest * tc)
spell *sp;
sc_mage * mage;
test_cleanup();
test_setup();
test_create_race("human");
enable_skill(SK_MAGIC, true);
it_horses = test_create_itemtype("horse");
@ -36,7 +36,7 @@ void test_equipment(CuTest * tc)
equipment_setskill(eq, SK_MAGIC, "5");
equipment_addspell(eq, sp, 1);
u = test_create_unit(test_create_faction(0), 0);
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
equip_unit_mask(u, eq, EQUIP_ALL);
CuAssertIntEquals(tc, 1, i_get(u->items, it_horses));
CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC));
@ -45,6 +45,7 @@ void test_equipment(CuTest * tc)
CuAssertPtrNotNull(tc, mage);
CuAssertPtrNotNull(tc, mage->spellbook);
CuAssertTrue(tc, u_hasspell(u, sp));
test_cleanup();
}
CuSuite *get_equipment_suite(void)

View File

@ -518,6 +518,11 @@ static item *icache;
static int icache_size;
#define ICACHE_MAX 100
void item_done(void) {
i_freeall(&icache);
icache_size = 0;
}
void i_free(item * i)
{
if (icache_size >= ICACHE_MAX) {

View File

@ -59,6 +59,8 @@ extern "C" {
#define NMF_PLURAL 0x01
#define NMF_APPEARANCE 0x02
void item_done(void);
typedef int(*rtype_uchange) (struct unit * user,
const struct resource_type * rtype, int delta);
typedef int(*rtype_uget) (const struct unit * user,

View File

@ -74,7 +74,7 @@ void test_change_item(CuTest * tc)
test_create_itemtype("iron");
init_resources();
u = test_create_unit(test_create_faction(0), 0);
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
test_uchange(tc, u, get_resourcetype(R_IRON));
test_cleanup();
}

View File

@ -623,6 +623,7 @@ static void write_owner(struct gamedata *data, region_owner * owner)
if (owner) {
faction *f;
WRITE_INT(data->store, owner->since_turn);
if (owner->since_turn >= 0) {
WRITE_INT(data->store, owner->morale_turn);
WRITE_INT(data->store, owner->flags);
f = owner->last_owner;
@ -630,6 +631,7 @@ static void write_owner(struct gamedata *data, region_owner * owner)
f = owner->owner;
write_faction_reference((f && f->_alive) ? f : NULL, data->store);
}
}
else {
WRITE_INT(data->store, -1);
}

View File

@ -155,14 +155,14 @@ static void test_readwrite_dead_faction_regionowner(CuTest *tc) {
gamedata data;
storage store;
test_setup();
mstream_init(&data.strm);
gamedata_init(&data, &store, RELEASE_VERSION);
test_cleanup();
config_set("rules.region_owners", "1");
f = test_create_faction(0);
test_create_unit(f, r = test_create_region(0, 0, 0));
region_set_owner(r, f, turn);
region_set_owner(r, f, 0);
destroyfaction(&factions);
CuAssertTrue(tc, !f->_alive);
remove_empty_units();

View File

@ -27,7 +27,7 @@ void test_updatespells(CuTest * tc)
spell * sp;
spellbook *book = 0;
test_cleanup();
test_setup();
test_create_race("human");
f = test_create_faction(0);
@ -53,7 +53,7 @@ void test_spellbooks(CuTest * tc)
spellbook *herp, *derp;
spellbook_entry *entry;
const char * sname = "herpderp";
test_cleanup();
test_setup();
herp = get_spellbook("herp");
CuAssertPtrNotNull(tc, herp);
@ -85,7 +85,7 @@ void test_pay_spell(CuTest * tc)
region * r;
int level;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -119,7 +119,7 @@ void test_pay_spell_failure(CuTest * tc)
struct region * r;
int level;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -157,7 +157,7 @@ void test_getspell_unit(CuTest * tc)
struct region * r;
struct locale * lang;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -186,7 +186,7 @@ void test_getspell_faction(CuTest * tc)
struct region * r;
struct locale * lang;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -218,7 +218,7 @@ void test_getspell_school(CuTest * tc)
struct locale * lang;
struct spellbook * book;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -249,7 +249,7 @@ void test_set_pre_combatspell(CuTest * tc)
struct region * r;
const int index = 0;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -282,7 +282,7 @@ void test_set_main_combatspell(CuTest * tc)
struct region * r;
const int index = 1;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -315,7 +315,7 @@ void test_set_post_combatspell(CuTest * tc)
struct region * r;
const int index = 2;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -347,7 +347,7 @@ void test_hasspell(CuTest * tc)
struct faction * f;
struct region * r;
test_cleanup();
test_setup();
test_create_world();
r = findregion(0, 0);
f = test_create_faction(0);
@ -382,7 +382,7 @@ void test_multi_cast(CuTest *tc) {
spell *sp;
struct locale * lang;
test_cleanup();
test_setup();
sp = create_spell("fireball", 0);
sp->cast = cast_fireball;
CuAssertPtrEquals(tc, sp, find_spell("fireball"));
@ -410,7 +410,7 @@ static void test_magic_resistance(CuTest *tc) {
unit *u;
race *rc;
test_cleanup();
test_setup();
rc = test_create_race("human");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
CuAssertDblEquals(tc, rc->magres, magic_resistance(u), 0.01);

View File

@ -2493,68 +2493,6 @@ unit *can_find(faction * f, faction * f2)
return NULL;
}
static void add_find(faction * f, unit * u, faction * f2)
{
/* faction f sees f2 through u */
int key = f->no % FMAXHASH;
struct fsee **fp = &fsee[key];
struct fsee *fs;
struct see **sp;
struct see *ss;
while (*fp && (*fp)->f != f)
fp = &(*fp)->nexthash;
if (!*fp) {
fs = *fp = calloc(sizeof(struct fsee), 1);
fs->f = f;
}
else
fs = *fp;
sp = &fs->see;
while (*sp && (*sp)->seen != f2)
sp = &(*sp)->next;
if (!*sp) {
ss = *sp = calloc(sizeof(struct see), 1);
ss->proof = u;
ss->seen = f2;
}
else
ss = *sp;
ss->proof = u;
}
static void update_find(void)
{
region *r;
static bool initial = true;
if (initial)
for (r = regions; r; r = r->next) {
unit *u;
for (u = r->units; u; u = u->next) {
faction *lastf = u->faction;
unit *u2;
for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction == lastf || u2->faction == u->faction)
continue;
if (seefaction(u->faction, r, u2, 0)) {
faction *fv = visible_faction(u->faction, u2);
lastf = fv;
add_find(u->faction, u2, fv);
}
}
}
}
initial = false;
}
bool kann_finden(faction * f1, faction * f2)
{
update_find();
return (bool)(can_find(f1, f2) != NULL);
}
/******* end summary ******/
void register_nr(void)
{
if (!nocr)

View File

@ -1094,6 +1094,15 @@ void register_reporttype(const char *extension, report_fun write, int flag)
report_types = type;
}
void reports_done(void) {
report_type **rtp = &report_types;
while (*rtp) {
report_type *rt = *rtp;
*rtp = rt->next;
free(rt);
}
}
static quicklist *get_regions_distance(region * root, int radius)
{
quicklist *ql, *rlist = NULL;

View File

@ -44,8 +44,8 @@ extern "C" {
extern bool noreports;
extern const char *visibility[];
/* kann_finden speedups */
bool kann_finden(struct faction *f1, struct faction *f2);
void reports_done(void);
struct unit *can_find(struct faction *, struct faction *);
/* funktionen zum schreiben eines reports */

View File

@ -220,7 +220,7 @@ static void test_write_travelthru(CuTest *tc) {
r->flags |= RF_TRAVELUNIT;
f = test_create_faction(0);
f->locale = lang;
u = test_create_unit(f, 0);
u = test_create_unit(f, test_create_region(0, 1, 0));
unit_setname(u, "Hodor");
unit_setid(u, 1);

View File

@ -92,9 +92,9 @@ static void test_seen_travelthru(CuTest *tc) {
test_setup();
setup_seen(0, 0);
r = test_create_region(0, 0, 0);
f = test_create_faction(0);
u = test_create_unit(f, 0);
u = test_create_unit(f, test_create_region(0, 0, 0));
r = test_create_region(0, 1, 0);
travelthru_add(r, u);
init_reports();
view_default(f->seen, r, f);
@ -190,10 +190,10 @@ static void test_seenhash_map(CuTest *tc) {
CuSuite *get_seen_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_add_seen);
SUITE_ADD_TEST(suite, test_faction_add_seen);
SUITE_ADD_TEST(suite, test_prepare_seen);
SUITE_ADD_TEST(suite, test_seen_travelthru);
SUITE_ADD_TEST(suite, test_add_seen);
SUITE_ADD_TEST(suite, test_faction_add_seen);
SUITE_ADD_TEST(suite, test_seen_region);
SUITE_ADD_TEST(suite, test_seen_interval_backward);
SUITE_ADD_TEST(suite, test_seen_interval_forward);

View File

@ -295,7 +295,7 @@ static void test_demon_skillchanges(CuTest *tc) {
test_setup();
rc = test_create_race("demon");
CuAssertPtrEquals(tc, rc, get_race(RC_DAEMON));
u = test_create_unit(test_create_faction(rc), 0);
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
CuAssertPtrNotNull(tc, u);
set_level(u, SK_CROSSBOW, 1);
demon_skillchange(u);

View File

@ -119,7 +119,7 @@ struct faction *test_create_faction(const struct race *rc)
struct unit *test_create_unit(struct faction *f, struct region *r)
{
const struct race * rc = f ? f->race : 0;
assert(f || !r);
assert(f && r);
if (!rc) rc = rc_get_or_create("human");
return create_unit(r, f, 1, rc ? rc : rc_get_or_create("human"), 0, 0, 0);
}
@ -161,6 +161,7 @@ void test_log_stderr(int flags) {
static void test_reset(void) {
int i;
turn = 0;
default_locale = 0;
free_gamedata();
free_terrains();

View File

@ -12,7 +12,7 @@
static void test_resources(CuTest *tc) {
resource_type *rtype;
test_cleanup();
test_setup();
init_resources();
CuAssertPtrNotNull(tc, rt_find("hp"));
CuAssertPtrEquals(tc, rt_find("hp"), (void *)get_resourcetype(R_LIFE));
@ -36,7 +36,7 @@ static void test_resources(CuTest *tc) {
static void test_recreate_world(CuTest * tc)
{
test_cleanup();
test_setup();
CuAssertPtrEquals(tc, 0, get_locale("de"));
CuAssertPtrEquals(tc, 0, (void *)rt_find("horse"));

View File

@ -412,6 +412,7 @@ void a_write_orig(struct storage *store, const attrib * attribs, const void *own
WRITE_TOK(store, "end");
}
void free_attribs(void) {
void attrib_done(void) {
cb_clear(&cb_deprecated);
memset(at_hash, 0, sizeof at_hash);
}

View File

@ -81,7 +81,7 @@ extern "C" {
int a_read(struct gamedata *data, attrib ** attribs, void *owner);
void a_write(struct storage *store, const attrib * attribs, const void *owner);
void free_attribs(void);
void attrib_done(void);
#define DEFAULT_AGE NULL
#define DEFAULT_INIT NULL

View File

@ -32,6 +32,15 @@ typedef struct tsf_list {
static tsf_list *tostringfs;
void crmessage_done(void) {
tsf_list **tsp = &tostringfs;
while (*tsp) {
tsf_list *ts = *tsp;
*tsp = ts->next;
free(ts);
}
}
static tostring_f tsf_find(const char *name)
{
if (name != NULL) {

View File

@ -22,6 +22,8 @@ extern "C" {
struct message;
struct message_type;
void crmessage_done(void);
typedef int(*tostring_f) (variant data, char *buffer, const void *userdata);
void tsf_register(const char *name, tostring_f fun);
/* registers a new type->string-function */

View File

@ -32,7 +32,7 @@ const char *mt_name(const message_type * mtype)
return mtype->name;
}
arg_type *argtypes = NULL;
static arg_type *argtypes = NULL;
void
register_argtype(const char *name, void(*free_arg) (variant),
@ -246,3 +246,12 @@ struct message *msg_addref(struct message *msg)
++msg->refcount;
return msg;
}
void message_done(void) {
arg_type **atp = &argtypes;
while (*atp) {
arg_type *at = *atp;
*atp = at->next;
free(at);
}
}

View File

@ -40,8 +40,10 @@ extern "C" {
int refcount;
} message;
void message_done(void);
void mt_clear(void);
struct message_type *mt_new(const char *name, const char **args);
struct message_type *mt_new(const char *name, const char *args[]);
struct message_type *mt_new_va(const char *name, ...);
/* mt_new("simple_sentence", "subject:string", "predicate:string",
* "object:string", "lang:locale", NULL); */

View File

@ -89,6 +89,15 @@ typedef struct xml_reader {
static xml_reader *xmlReaders;
void xml_done(void) {
xml_reader ** xrp = &xmlReaders;
while (*xrp) {
xml_reader *xr = *xrp;
*xrp = xr->next;
free(xr);
}
}
void xml_register_callback(xml_callback callback)
{
xml_reader *reader = (xml_reader *)malloc(sizeof(xml_reader));

View File

@ -21,13 +21,17 @@ extern "C" {
/* new xml functions: */
#include <libxml/tree.h>
typedef int (*xml_callback) (xmlDocPtr);
extern void xml_register_callback(xml_callback callback);
extern double xml_fvalue(xmlNodePtr node, const char *name, double dflt);
extern int xml_ivalue(xmlNodePtr node, const char *name, int dflt);
extern bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt);
void xml_register_callback(xml_callback callback);
double xml_fvalue(xmlNodePtr node, const char *name, double dflt);
int xml_ivalue(xmlNodePtr node, const char *name, int dflt);
bool xml_bvalue(xmlNodePtr node, const char *name, bool dflt);
#endif
extern int read_xml(const char *filename, const char *catalog);
void xml_done(void);
int read_xml(const char *filename, const char *catalog);
#ifdef __cplusplus
}

View File

@ -19,7 +19,7 @@ static void test_volcano_update(CuTest *tc) {
message *m;
const struct terrain_type *t_volcano, *t_active;
test_cleanup();
test_setup();
mt_register(mt_new_va("volcanostopsmoke", "region:region", 0));
t_volcano = test_create_terrain("volcano", LAND_REGION);
t_active = test_create_terrain("activevolcano", LAND_REGION);
@ -41,7 +41,7 @@ static void test_volcano_outbreak(CuTest *tc) {
message *m;
const struct terrain_type *t_volcano, *t_active;
test_cleanup();
test_setup();
mt_register(mt_new_va("volcanooutbreak", "regionv:region", "regionn:region", 0));
mt_register(mt_new_va("volcano_dead", "unit:unit", "region:region", "dead:int", 0));
t_volcano = test_create_terrain("volcano", LAND_REGION);