Merge pull request #93 from badgerman/master

E3 Lua Tests & memory leaks removed
This commit is contained in:
Enno Rehling 2014-12-31 21:26:48 +01:00
commit 64ac0ae5e4
48 changed files with 2221 additions and 2118 deletions

View File

@ -19,4 +19,5 @@ $ROOT/$BIN_DIR/eressea/test_eressea
cd $ROOT
[ -e eressea.ini ] || ln -sf conf/eressea.ini
$ROOT/$BIN_DIR/eressea/eressea -v0 scripts/run-tests.lua
$ROOT/$BIN_DIR/eressea/eressea -v0 scripts/run-tests-e3.lua
cd $OLDWPD

19
scripts/run-tests-e3.lua Normal file
View File

@ -0,0 +1,19 @@
-- new tests 2014-06-11
path = 'scripts'
if config.source_dir ~= nil then
path = config.source_dir .. '/' .. path
end
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
config.rules = 'e3'
require 'eressea'
require 'eressea.path'
require 'eressea.xmlconf'
require 'tests.e3'
require 'lunit'
eressea.settings.set("rules.alliances", "0")
rules = require('eressea.' .. config.rules)
lunit.main()

View File

@ -3,7 +3,7 @@ require "lunit"
module("tests.e3.castles", package.seeall, lunit.testcase )
function setup()
eressea.free_game()
eressea.game.reset()
end
function test_small_castles()

View File

@ -0,0 +1,3 @@
require 'tests.e3.castles'
require 'tests.e3.stealth'
require 'tests.e3.spells'

View File

@ -3,7 +3,7 @@ require "lunit"
module("tests.e3.spells", package.seeall, lunit.testcase)
function setup()
eressea.free_game()
eressea.game.reset()
eressea.settings.set("magic.fumble.enable", "0")
eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0")
@ -11,7 +11,6 @@ function setup()
end
function test_blessedharvest_lasts_n_turn()
eressea.free_game()
local r = region.create(0, 0, "plain")
local f = faction.create("noreply@eressea.de", "halfling", "de")
local u = unit.create(f, r)

View File

@ -6,18 +6,18 @@ local f
local u
function setup()
eressea.free_game()
eressea.game.reset()
eressea.settings.set("rules.economy.food", "4")
local r = region.create(0,0, "plain")
f = faction.create("stealthy@eressea.de", "human", "de")
f = faction.create("stealth1@eressea.de", "human", "de")
u = unit.create(f, r, 1)
f = faction.create("stealth@eressea.de", "human", "de")
f = faction.create("stealth2@eressea.de", "human", "de")
end
function test_stealth_faction_on()
u:clear_orders()
u:add_order("TARNEN PARTEI")
u:add_order("TARNE PARTEI")
eressea.settings.set("rules.stealth.faction", 1)
process_orders()
@ -27,7 +27,7 @@ end
function test_stealth_faction_off()
u:clear_orders()
u:add_order("TARNEN PARTEI")
u:add_order("TARNE PARTEI")
eressea.settings.set("rules.stealth.faction", 0)
process_orders()

View File

@ -7,4 +7,3 @@ require 'tests.locale'
require 'tests.regions'
require 'tests.study'
require 'tests.movement'

View File

@ -4,7 +4,7 @@ module("tests.eressea.pool", package.seeall, lunit.testcase )
function setup()
eressea.game.reset()
eressea.config.reset();
eressea.config.reset()
eressea.settings.set("rules.economy.food", "0")
eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0")

View File

@ -5,6 +5,7 @@
#include "json.h"
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/config.h>
#include <kernel/save.h>
@ -14,6 +15,7 @@
void eressea_free_game(void) {
free_gamedata();
init_resources();
}
int eressea_read_game(const char * filename) {

View File

@ -514,6 +514,7 @@ static void reset_game(void)
for (f = factions; f; f = f->next) {
f->flags &= FFL_SAVEMASK;
}
init_locales();
}
static int tolua_process_orders(lua_State * L)

View File

@ -45,6 +45,7 @@ static void test_export_no_regions(CuTest * tc) {
buf[len] = '\0';
CuAssertStrEquals(tc, "{}", strip(buf));
mstream_done(&out);
test_cleanup();
}
static cJSON *export_a_region(CuTest * tc, const struct terrain_type *terrain, region **_r) {
@ -93,6 +94,7 @@ static void test_export_land_region(CuTest * tc) {
CuAssertPtrNotNull(tc, attr = cJSON_GetObjectItem(json, "name"));
CuAssertStrEquals(tc, r->land->name, attr->valuestring);
cJSON_Delete(json);
test_cleanup();
}
static void test_export_ocean_region(CuTest * tc) {
@ -103,6 +105,7 @@ static void test_export_ocean_region(CuTest * tc) {
json = export_a_region(tc, terrain, 0);
CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "name"));
cJSON_Delete(json);
test_cleanup();
}
static void test_export_no_factions(CuTest * tc) {
@ -119,6 +122,7 @@ static void test_export_no_factions(CuTest * tc) {
buf[len]=0;
CuAssertStrEquals(tc, "{}", strip(buf));
mstream_done(&out);
test_cleanup();
}
CuSuite *get_json_suite(void) {

View File

@ -57,6 +57,7 @@ static void test_build_requires_materials(CuTest *tc) {
i_change(&u->items, itype, 2);
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
test_cleanup();
}
static void test_build_requires_building(CuTest *tc) {
@ -78,6 +79,7 @@ static void test_build_requires_building(CuTest *tc) {
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
btype->maxcapacity = 0;
CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1));
test_cleanup();
}
static void test_build_failure_missing_skill(CuTest *tc) {
@ -89,6 +91,7 @@ static void test_build_failure_missing_skill(CuTest *tc) {
rtype = bf.cons.materials[0].rtype;
i_change(&u->items, rtype->itype, 1);
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1));
test_cleanup();
}
static void test_build_failure_low_skill(CuTest *tc) {
@ -101,6 +104,7 @@ static void test_build_failure_low_skill(CuTest *tc) {
i_change(&u->items, rtype->itype, 1);
set_level(u, SK_ARMORER, bf.cons.minskill-1);
CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10));
test_cleanup();
}
static void test_build_failure_completed(CuTest *tc) {
@ -115,6 +119,7 @@ static void test_build_failure_completed(CuTest *tc) {
bf.cons.maxsize = 1;
CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10));
CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype));
test_cleanup();
}
static void test_build_limits(CuTest *tc) {
@ -202,6 +207,7 @@ static void test_build_building_no_materials(CuTest *tc) {
CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, 0));
CuAssertPtrEquals(tc, 0, u->region->buildings);
CuAssertPtrEquals(tc, 0, u->building);
test_cleanup();
}
static void test_build_building_with_golem(CuTest *tc) {
@ -220,6 +226,7 @@ static void test_build_building_with_golem(CuTest *tc) {
CuAssertPtrNotNull(tc, u->region->buildings);
CuAssertIntEquals(tc, 1, u->region->buildings->size);
CuAssertIntEquals(tc, 0, u->number);
test_cleanup();
}
static void test_build_building_success(CuTest *tc) {
@ -243,6 +250,7 @@ static void test_build_building_success(CuTest *tc) {
CuAssertPtrEquals(tc, u->region->buildings, u->building);
CuAssertIntEquals(tc, 1, u->building->size);
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
test_cleanup();
}
CuSuite *get_build_suite(void)

View File

@ -92,8 +92,14 @@ void bt_register(building_type * type)
ql_push(&buildingtypes, (void *)type);
}
void free_buildingtype(void *ptr) {
building_type *btype =(building_type *)ptr;
free(btype->_name);
free(btype);
}
void free_buildingtypes(void) {
ql_foreach(buildingtypes, free);
ql_foreach(buildingtypes, free_buildingtype);
ql_free(buildingtypes);
buildingtypes = 0;
}

View File

@ -49,7 +49,7 @@ extern "C" {
#define BTF_NAMECHANGE 0x100 /* name and description can be changed more than once */
typedef struct building_type {
const char *_name;
char *_name;
int flags; /* flags */
int capacity; /* Kapazität pro Größenpunkt */

View File

@ -22,6 +22,9 @@ static void test_register_building(CuTest * tc)
bt_register(btype);
CuAssertPtrNotNull(tc, bt_find("herp"));
// free(btype->_name);
// free(btype);
test_cleanup();
}
static void test_building_set_owner(CuTest * tc)
@ -51,6 +54,7 @@ static void test_building_set_owner(CuTest * tc)
CuAssertPtrEquals(tc, u1, building_owner(bld));
building_set_owner(u2);
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_next_when_empty(CuTest * tc)
@ -85,6 +89,7 @@ static void test_buildingowner_goes_to_next_when_empty(CuTest * tc)
CuAssertPtrEquals(tc, u, building_owner(bld));
u->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_other_when_empty(CuTest * tc)
@ -120,6 +125,7 @@ static void test_buildingowner_goes_to_other_when_empty(CuTest * tc)
CuAssertPtrEquals(tc, u, building_owner(bld));
u->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_same_faction_when_empty(CuTest * tc)
@ -159,6 +165,7 @@ static void test_buildingowner_goes_to_same_faction_when_empty(CuTest * tc)
CuAssertPtrEquals(tc, u3, building_owner(bld));
u3->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_next_after_leave(CuTest * tc)
@ -193,6 +200,7 @@ static void test_buildingowner_goes_to_next_after_leave(CuTest * tc)
CuAssertPtrEquals(tc, u, building_owner(bld));
leave_building(u);
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_other_after_leave(CuTest * tc)
@ -227,6 +235,7 @@ static void test_buildingowner_goes_to_other_after_leave(CuTest * tc)
CuAssertPtrEquals(tc, u, building_owner(bld));
leave_building(u);
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_goes_to_same_faction_after_leave(CuTest * tc)
@ -268,6 +277,7 @@ static void test_buildingowner_goes_to_same_faction_after_leave(CuTest * tc)
CuAssertPtrEquals(tc, u2, building_owner(bld));
leave_building(u2);
CuAssertPtrEquals(tc, 0, building_owner(bld));
test_cleanup();
}
static void test_buildingowner_resets_when_empty(CuTest * tc)
@ -302,6 +312,7 @@ static void test_buildingowner_resets_when_empty(CuTest * tc)
CuAssertPtrEquals(tc, 0, building_owner(bld));
u->number = 1;
CuAssertPtrEquals(tc, u, building_owner(bld));
test_cleanup();
}
void test_buildingowner_goes_to_empty_unit_after_leave(CuTest * tc)
@ -343,6 +354,7 @@ void test_buildingowner_goes_to_empty_unit_after_leave(CuTest * tc)
CuAssertPtrEquals(tc, 0, building_owner(bld));
u2->number = 1;
CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
}
CuSuite *get_building_suite(void)

View File

@ -1047,23 +1047,24 @@ int get_param_int(const struct param *p, const char *key, int def)
int check_param(const struct param *p, const char *key, const char *searchvalue)
{
int result = 0;
const char *value = get_param(p, key);
if (!value) {
return 0;
}
char *p_value = malloc(sizeof(char)* (strlen(value) + 1));
strcpy(p_value, value);
char *p_value = _strdup(value);
const char *delimiter = " ,;";
char *v = strtok(p_value, delimiter);
while (v != NULL) {
if (strcmp(v, searchvalue) == 0)
{
return 1;
if (strcmp(v, searchvalue) == 0) {
result = 1;
break;
}
v = strtok(NULL, delimiter);
}
return 0;
free(p_value);
return result;
}
static const char *g_datadir;
@ -1143,6 +1144,7 @@ void kernel_done(void)
* calling it is optional, e.g. a release server will most likely not do it.
*/
translation_done();
free_attribs();
}
attrib_type at_germs = {
@ -1759,8 +1761,6 @@ void free_gamedata(void)
a_remove(&global.attribs, global.attribs);
}
++global.cookie; /* readgame() already does this, but sjust in case */
init_resources();
}
const char * game_name(void) {

View File

@ -1167,10 +1167,7 @@ static item *default_spoil(const struct race *rc, int size)
return itm;
}
#ifndef DISABLE_TESTS
int free_itype_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
item_type *itype;
cb_get_kv(match, &itype, sizeof(itype));
int free_itype(item_type *itype) {
free(itype->construction);
free(itype->_appearance[0]);
free(itype->_appearance[1]);
@ -1182,16 +1179,23 @@ int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbd
resource_type *rtype;
cb_get_kv(match, &rtype, sizeof(rtype));
free(rtype->_name);
if (rtype->itype) {
free_itype(rtype->itype);
}
free(rtype);
return 0;
}
void test_clear_resources(void)
void free_resources(void)
{
int i;
memset((void *)oldpotiontype, 0, sizeof(oldpotiontype));
while (luxurytypes) {
luxury_type * next = luxurytypes->next;
free(luxurytypes);
luxurytypes = next;
}
cb_foreach(&cb_resources, "", 0, free_rtype_cb, 0);
cb_clear(&cb_resources);
++num_resources;
@ -1201,7 +1205,6 @@ void test_clear_resources(void)
cb_clear(rnames + i);
}
}
#endif
void register_resources(void)
{

View File

@ -313,9 +313,9 @@ extern "C" {
extern struct attrib_type at_showitem; /* show this potion's description */
extern void register_resources(void);
extern void init_resources(void);
extern void init_itemtypes(void);
void register_resources(void);
void init_resources(void);
void init_itemtypes(void);
extern void register_item_give(int (*foo) (struct unit *, struct unit *,
const struct item_type *, int, struct order *), const char *name);
@ -324,9 +324,7 @@ extern "C" {
extern void register_item_useonother(int (*foo) (struct unit *, int,
const struct item_type *, int, struct order *), const char *name);
#ifndef DISABLE_TESTS
void test_clear_resources(void);
#endif
void free_resources(void);
#ifdef __cplusplus
}

View File

@ -2,6 +2,8 @@
#include <kernel/item.h>
#include <kernel/pool.h>
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <util/language.h>
#include <util/functions.h>
@ -116,6 +118,31 @@ void test_findresourcetype(CuTest * tc)
CuAssertPtrNotNull(tc, findresourcetype("Bauer", lang));
}
#include <modules/autoseed.h>
static void test_fix_demand(CuTest *tc) {
region *r;
terrain_type *tplain;
item_type *ltype;
test_cleanup();
ltype = test_create_itemtype("balm");
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
new_luxurytype(ltype, 0);
ltype = test_create_itemtype("oint");
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
new_luxurytype(ltype, 0);
tplain = test_create_terrain("plain", LAND_REGION);
r = new_region(0, 0, NULL, 0);
CuAssertPtrNotNull(tc, r);
terraform_region(r, tplain);
CuAssertPtrNotNull(tc, r->land);
CuAssertIntEquals(tc, 0, fix_demand(r));
CuAssertPtrNotNull(tc, r->land->demands);
CuAssertPtrNotNull(tc, r->land->demands->next);
CuAssertPtrNotNull(tc, r_luxury(r));
test_cleanup();
}
CuSuite *get_item_suite(void)
{
CuSuite *suite = CuSuiteNew();
@ -125,5 +152,6 @@ CuSuite *get_item_suite(void)
SUITE_ADD_TEST(suite, test_resource_type);
SUITE_ADD_TEST(suite, test_finditemtype);
SUITE_ADD_TEST(suite, test_findresourcetype);
SUITE_ADD_TEST(suite, test_fix_demand);
return suite;
}

View File

@ -155,7 +155,7 @@ static void json_construction(cJSON *json, construction **consp) {
return;
}
if (json->type != cJSON_Object) {
log_error("building %s is not a json object: %d", json->string, json->type);
log_error("construction %s is not a json object: %d", json->string, json->type);
return;
}
construction * cons = (construction *)calloc(sizeof(construction), 1);
@ -178,7 +178,7 @@ static void json_construction(cJSON *json, construction **consp) {
}
break;
default:
log_error("building %s contains unknown attribute %s", json->string, child->string);
log_error("construction %s contains unknown attribute %s", json->string, child->string);
}
}
*consp = cons;
@ -304,7 +304,7 @@ static void json_ship(cJSON *json, ship_type *st) {
}
break;
case cJSON_Array:
st->coasts = (const terrain_type **)
st->coasts = (terrain_type **)
malloc(sizeof(terrain_type *) * (1+cJSON_GetArraySize(child)));
for (i=0,iter=child->child;iter;iter=iter->next) {
if (iter->type==cJSON_String) {

View File

@ -40,8 +40,7 @@ typedef struct locale_data {
const struct locale *lang;
} locale_data;
static struct locale_data *locale_array[16];
static int nlocales = 0;
static struct locale_data *locale_array[MAXLOCALES];
typedef struct order_data {
const char *_str;
@ -272,15 +271,10 @@ static order *create_order_i(keyword_t kwd, const char *sptr, int persistent,
}
}
for (lindex = 0; lindex != nlocales; ++lindex) {
if (locale_array[lindex]->lang == lang)
break;
}
if (lindex == nlocales) {
locale_array[nlocales] = (locale_data *)calloc(1, sizeof(locale_data));
locale_array[nlocales]->lang = lang;
++nlocales;
}
lindex = locale_index(lang);
assert(lindex < MAXLOCALES);
locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data));
locale_array[lindex]->lang = lang;
ord = (order *)malloc(sizeof(order));
ord->_persistent = persistent;
@ -569,10 +563,7 @@ void push_order(order ** ordp, order * ord)
keyword_t init_order(const struct order *ord)
{
char *cmd = 0;
assert(ord && ord->data);
if (ord->data->_str) cmd = _strdup(ord->data->_str);
init_tokens_str(cmd);
init_tokens_str(ord->data->_str);
return ord->data->_keyword;
}

View File

@ -9,7 +9,6 @@
#include <tests.h>
#include <CuTest.h>
#include <stdlib.h>
#include <string.h>
static void test_create_order(CuTest *tc) {
char cmd[32];
@ -127,8 +126,7 @@ static void test_init_order(CuTest *tc) {
}
static void test_getstrtoken(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\" \"\" \'\'");
init_tokens_str(cmd);
init_tokens_str("hurr \"durr\" \"\" \'\'");
CuAssertStrEquals(tc, "hurr", getstrtoken());
CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, "", getstrtoken());
@ -139,8 +137,7 @@ static void test_getstrtoken(CuTest *tc) {
}
static void test_skip_token(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\"");
init_tokens_str(cmd);
init_tokens_str("hurr \"durr\"");
skip_token();
CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, 0, getstrtoken());

View File

@ -141,6 +141,8 @@ void racelist_insert(struct race_list **rl, const struct race *r)
void free_races(void) {
while (races) {
race * rc = races->next;
free(races->_name);
free(races->def_damage);
free(races);
races = rc;
}

View File

@ -119,7 +119,7 @@ extern "C" {
typedef struct race {
struct param *parameters;
const char *_name;
char *_name;
float magres;
float maxaura; /* Faktor auf Maximale Aura */
float regaura; /* Faktor auf Regeneration */
@ -133,7 +133,7 @@ extern "C" {
float speed;
float aggression; /* chance that a monster will attack */
int hitpoints;
const char *def_damage;
char *def_damage;
int armor;
int at_default; /* Angriffsskill Unbewaffnet (default: -2) */
int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */

View File

@ -69,11 +69,9 @@ region *regions;
int get_maxluxuries(void)
{
static int maxluxuries = -1;
if (maxluxuries == -1) {
const luxury_type *ltype;
maxluxuries = 0;
for (ltype = luxurytypes; ltype; ltype = ltype->next)
int maxluxuries = 0;
for (ltype = luxurytypes; ltype; ltype = ltype->next) {
++maxluxuries;
}
return maxluxuries;

View File

@ -238,8 +238,15 @@ void free_ship(ship * s)
free(s);
}
static void free_shiptype(void *ptr) {
ship_type *stype = (ship_type *)ptr;
free(stype->_name);
free(stype->coasts);
free(stype);
}
void free_shiptypes(void) {
ql_foreach(shiptypes, free);
ql_foreach(shiptypes, free_shiptype);
ql_free(shiptypes);
shiptypes = 0;
}

View File

@ -33,7 +33,7 @@ extern "C" {
#define SFL_NOCOAST 0x04
typedef struct ship_type {
const char *_name;
char *_name;
int range; /* range in regions */
int flags; /* flags */
@ -55,7 +55,7 @@ extern "C" {
int df_bonus; /* Verändert den Verteidigungskill (default: 0) */
float tac_bonus;
const struct terrain_type **coasts; /* coast that this ship can land on */
struct terrain_type ** coasts; /* coast that this ship can land on */
struct construction *construction; /* how to build a ship */
} ship_type;

View File

@ -45,6 +45,7 @@ void spellbook_clear(spellbook *sb)
free(sbe);
}
ql_free(sb->spells);
free(sb->name);
}
int spellbook_foreach(spellbook *sb, int (*callback)(spellbook_entry *, void *), void * data)

View File

@ -27,6 +27,8 @@ void test_named_spellbooks(CuTest * tc)
sb = create_spellbook(0);
CuAssertPtrNotNull(tc, sb);
CuAssertPtrEquals(tc, 0, sb->name);
spellbook_clear(sb);
free(sb);
sb = create_spellbook("spells");
CuAssertPtrNotNull(tc, sb);

View File

@ -63,8 +63,7 @@ const char *terraindata[MAXTERRAINS] = {
static terrain_type *registered_terrains;
#ifndef DISABLE_TESTS
void test_clear_terrains(void)
void free_terrains(void)
{
while (registered_terrains) {
terrain_type * t = registered_terrains;
@ -74,7 +73,6 @@ void test_clear_terrains(void)
free(t);
}
}
#endif
const terrain_type *terrains(void)
{

View File

@ -75,10 +75,7 @@ extern "C" {
extern const char *terrain_name(const struct region *r);
extern void init_terrains(void);
#ifndef DISABLE_TESTS
void test_clear_terrains(void);
#endif
void free_terrains(void);
#ifdef __cplusplus
}

View File

@ -289,17 +289,23 @@ static int parse_buildings(xmlDocPtr doc)
btype->name =
(const char *(*)(const struct building_type *,
const struct building *, int))fun;
} else if (strcmp((const char *)propValue, "init") == 0) {
}
else if (strcmp((const char *)propValue, "init") == 0) {
btype->init = (void(*)(struct building_type *))fun;
} else if (strcmp((const char *)propValue, "age") == 0) {
}
else if (strcmp((const char *)propValue, "age") == 0) {
btype->age = (void(*)(struct building *))fun;
} else if (strcmp((const char *)propValue, "protection") == 0) {
}
else if (strcmp((const char *)propValue, "protection") == 0) {
btype->protection = (int(*)(struct building *, struct unit *))fun;
} else if (strcmp((const char *)propValue, "taxes") == 0) {
}
else if (strcmp((const char *)propValue, "taxes") == 0) {
btype->taxes = (double(*)(const struct building *, int))fun;
} else if (strcmp((const char *)propValue, "age") == 0) {
}
else if (strcmp((const char *)propValue, "age") == 0) {
btype->age = (void(*)(struct building *))fun;
} else {
}
else {
log_error("unknown function type '%s' for building %s\n", (const char *)propValue, btype->_name);
}
xmlFree(propValue);
@ -357,7 +363,8 @@ static int parse_calendar(xmlDocPtr doc)
months_per_year = 0;
if (nsetCalendars == NULL || nsetCalendars->nodeNr == 0) {
rv = -1;
} else
}
else
for (c = 0; c != nsetCalendars->nodeNr; ++c) {
xmlNodePtr calendar = nsetCalendars->nodeTab[c];
xmlXPathObjectPtr xpathWeeks, xpathMonths, xpathSeasons;
@ -528,14 +535,14 @@ static int parse_ships(xmlDocPtr doc)
if (k == 0) {
assert(st->coasts == NULL);
st->coasts =
(const terrain_type **)malloc(sizeof(const terrain_type *) *
(terrain_type **)malloc(sizeof(terrain_type *) *
(result->nodesetval->nodeNr + 1));
st->coasts[result->nodesetval->nodeNr] = NULL;
}
propValue = xmlGetProp(node, BAD_CAST "terrain");
assert(propValue != NULL);
st->coasts[c] = get_terrain((const char *)propValue);
st->coasts[c] = get_or_create_terrain((const char *)propValue);
if (st->coasts[c] != NULL)
++c;
else {
@ -723,7 +730,8 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
wtype->attack =
(bool(*)(const struct troop *, const struct weapon_type *,
int *))fun;
} else {
}
else {
log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, itype->rtype->_name);
}
xmlFree(propValue);
@ -827,18 +835,22 @@ static item_type *xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype)
itype->give =
(int(*)(struct unit *, struct unit *, const struct item_type *, int,
struct order *))fun;
} else if (strcmp((const char *)propValue, "use") == 0) {
}
else if (strcmp((const char *)propValue, "use") == 0) {
itype->use =
(int(*)(struct unit *, const struct item_type *, int,
struct order *))fun;
} else if (strcmp((const char *)propValue, "canuse") == 0) {
}
else if (strcmp((const char *)propValue, "canuse") == 0) {
itype->canuse =
(bool(*)(const struct unit *, const struct item_type *))fun;
} else if (strcmp((const char *)propValue, "useonother") == 0) {
}
else if (strcmp((const char *)propValue, "useonother") == 0) {
itype->useonother =
(int(*)(struct unit *, int, const struct item_type *, int,
struct order *))fun;
} else {
}
else {
log_error("unknown function type '%s' for item '%s'\n", (const char *)propValue, rtype->_name);
}
xmlFree(propValue);
@ -875,9 +887,11 @@ static int parse_rules(xmlDocPtr doc)
global.functions.wage =
(int(*)(const struct region *, const struct faction *,
const struct race *, int))fun;
} else if (strcmp((const char *)propValue, "maintenance") == 0) {
}
else if (strcmp((const char *)propValue, "maintenance") == 0) {
global.functions.maintenance = (int(*)(const struct unit *))fun;
} else {
}
else {
log_error("unknown function for rule '%s'\n", (const char *)propValue);
}
xmlFree(propValue);
@ -943,11 +957,14 @@ static int parse_resources(xmlDocPtr doc)
assert(propValue != NULL);
if (strcmp((const char *)propValue, "change") == 0) {
rtype->uchange = (rtype_uchange)fun;
} else if (strcmp((const char *)propValue, "get") == 0) {
}
else if (strcmp((const char *)propValue, "get") == 0) {
rtype->uget = (rtype_uget)fun;
} else if (strcmp((const char *)propValue, "name") == 0) {
}
else if (strcmp((const char *)propValue, "name") == 0) {
rtype->name = (rtype_name)fun;
} else {
}
else {
log_error("unknown function type '%s' for resource %s\n", (const char *)propValue, rtype->_name);
}
xmlFree(propValue);
@ -1000,13 +1017,16 @@ static int parse_resources(xmlDocPtr doc)
if (strcmp((const char *)propValue, "skill") == 0) {
rdata->modifiers[k].value.i = xml_ivalue(node, "value", 0);
rdata->modifiers[k].flags = RMF_SKILL;
} else if (strcmp((const char *)propValue, "material") == 0) {
}
else if (strcmp((const char *)propValue, "material") == 0) {
rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0);
rdata->modifiers[k].flags = RMF_SAVEMATERIAL;
} else if (strcmp((const char *)propValue, "resource") == 0) {
}
else if (strcmp((const char *)propValue, "resource") == 0) {
rdata->modifiers[k].value.f = (float)xml_fvalue(node, "value", 0);
rdata->modifiers[k].flags = RMF_SAVERESOURCE;
} else if (strcmp((const char *)propValue, "require") == 0) {
}
else if (strcmp((const char *)propValue, "require") == 0) {
xmlChar *propBldg = xmlGetProp(node, BAD_CAST "building");
if (propBldg != NULL) {
btype = bt_get_or_create((const char *)propBldg);
@ -1014,7 +1034,8 @@ static int parse_resources(xmlDocPtr doc)
rdata->modifiers[k].flags = RMF_REQUIREDBUILDING;
xmlFree(propBldg);
}
} else {
}
else {
log_error("unknown type '%s' for resourcelimit-modifier '%s'\n", (const char *)propValue, rtype->_name);
}
xmlFree(propValue);
@ -1031,7 +1052,8 @@ static int parse_resources(xmlDocPtr doc)
if (propFlag != NULL) {
if (strcmp((const char *)propFlag, "logging") == 0) {
rdata->guard |= GUARD_TREES;
} else if (strcmp((const char *)propFlag, "mining") == 0) {
}
else if (strcmp((const char *)propFlag, "mining") == 0) {
rdata->guard |= GUARD_MINING;
}
xmlFree(propFlag);
@ -1060,9 +1082,11 @@ static int parse_resources(xmlDocPtr doc)
assert(propValue != NULL);
if (strcmp((const char *)propValue, "produce") == 0) {
rdata->produce = (rlimit_produce)fun;
} else if (strcmp((const char *)propValue, "limit") == 0) {
}
else if (strcmp((const char *)propValue, "limit") == 0) {
rdata->limit = (rlimit_limit)fun;
} else {
}
else {
log_error("unknown limit '%s' for resource %s\n", (const char *)propValue, rtype->_name);
}
xmlFree(propValue);
@ -1162,11 +1186,13 @@ static void add_spells(equipment * eq, xmlNodeSetPtr nsetItems)
sp = find_spell((const char *)propValue);
if (!sp) {
log_error("no spell '%s' for equipment-set '%s'\n", (const char *)propValue, eq->name);
} else {
}
else {
int level = xml_ivalue(node, "level", 0);
if (level > 0) {
equipment_addspell(eq, sp, level);
} else {
}
else {
log_error("spell '%s' for equipment-set '%s' has no level\n", sp->sname, eq->name);
}
}
@ -1190,7 +1216,8 @@ static void add_skills(equipment * eq, xmlNodeSetPtr nsetSkills)
if (sk == NOSKILL) {
log_error("unknown skill '%s' in equipment-set %s\n", (const char *)propValue, eq->name);
xmlFree(propValue);
} else {
}
else {
xmlFree(propValue);
propValue = xmlGetProp(node, BAD_CAST "level");
if (propValue != NULL) {
@ -1338,7 +1365,8 @@ static int parse_spellbooks(xmlDocPtr doc)
if (propValue) {
sb = get_spellbook((const char *)propValue);
xmlFree(propValue);
} else {
}
else {
log_error("spellbook at index '%d' has n name\n", i);
continue;
}
@ -1359,7 +1387,8 @@ static int parse_spellbooks(xmlDocPtr doc)
}
if (sp && level > 0) {
spellbook_add(sb, sp, level);
} else {
}
else {
log_error("invalid entry at index '%d' in spellbook '%s'\n", k, sb->name);
}
}
@ -1459,7 +1488,8 @@ static int parse_spells(xmlDocPtr doc)
}
strlcpy(zText + 7, sp->sname, sizeof(zText) - 7);
fumble = get_function(zText);
} else {
}
else {
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
xmlNodePtr node = result->nodesetval->nodeTab[k];
pf_generic fun;
@ -1469,12 +1499,15 @@ static int parse_spells(xmlDocPtr doc)
if (strcmp((const char *)propValue, "cast") == 0) {
if (fun) {
cast = fun;
} else {
}
else {
log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname);
}
} else if (fun && strcmp((const char *)propValue, "fumble") == 0) {
}
else if (fun && strcmp((const char *)propValue, "fumble") == 0) {
fumble = fun;
} else {
}
else {
log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname);
}
xmlFree(propValue);
@ -1516,7 +1549,8 @@ static int parse_spells(xmlDocPtr doc)
log_error("spell '%s' has linear cost but fixed level\n", sp->sname);
}
component->cost = SPC_LINEAR;
} else if (strcmp((const char *)propValue, "level") == 0) {
}
else if (strcmp((const char *)propValue, "level") == 0) {
if ((sp->sptyp&SPELLLEVEL) == 0) {
log_error("spell '%s' has levelled cost but fixed level\n", sp->sname);
}
@ -1692,7 +1726,8 @@ static int parse_races(xmlDocPtr doc)
for (child = node->children; child; child = child->next) {
if (strcmp((const char *)child->name, "ai") == 0) {
parse_ai(rc, child);
} else if (strcmp((const char *)child->name, "param") == 0) {
}
else if (strcmp((const char *)child->name, "param") == 0) {
parse_param(&rc->parameters, child);
}
}
@ -1718,7 +1753,8 @@ static int parse_races(xmlDocPtr doc)
rc->study_speed = calloc(1, MAXSKILLS);
rc->study_speed[sk] = (char)speed;
}
} else {
}
else {
log_error("unknown skill '%s' in race '%s'\n", (const char *)propValue, rc->_name);
}
xmlFree(propValue);
@ -1741,19 +1777,25 @@ static int parse_races(xmlDocPtr doc)
assert(propValue != NULL);
if (strcmp((const char *)propValue, "name") == 0) {
rc->generate_name = (const char *(*)(const struct unit *))fun;
} else if (strcmp((const char *)propValue, "describe") == 0) {
}
else if (strcmp((const char *)propValue, "describe") == 0) {
rc->describe =
(const char *(*)(const struct unit *, const struct locale *))fun;
} else if (strcmp((const char *)propValue, "age") == 0) {
}
else if (strcmp((const char *)propValue, "age") == 0) {
rc->age = (void(*)(struct unit *))fun;
} else if (strcmp((const char *)propValue, "move") == 0) {
}
else if (strcmp((const char *)propValue, "move") == 0) {
rc->move_allowed =
(bool(*)(const struct region *, const struct region *))fun;
} else if (strcmp((const char *)propValue, "itemdrop") == 0) {
}
else if (strcmp((const char *)propValue, "itemdrop") == 0) {
rc->itemdrop = (struct item * (*)(const struct race *, int))fun;
} else if (strcmp((const char *)propValue, "initfamiliar") == 0) {
}
else if (strcmp((const char *)propValue, "initfamiliar") == 0) {
rc->init_familiar = (void(*)(struct unit *))fun;
} else {
}
else {
log_error("unknown function type '%s' for race %s\n", (const char *)propValue, rc->_name);
}
xmlFree(propValue);
@ -1773,7 +1815,8 @@ static int parse_races(xmlDocPtr doc)
if (xml_bvalue(node, "default", false)) {
rc->familiars[k] = rc->familiars[0];
rc->familiars[0] = frc;
} else {
}
else {
rc->familiars[k] = frc;
}
xmlFree(propValue);
@ -1804,7 +1847,8 @@ static int parse_races(xmlDocPtr doc)
if (propValue != NULL) {
attack->data.dice = _strdup((const char *)propValue);
xmlFree(propValue);
} else {
}
else {
attack->data.sp = xml_spell(node, "spell");
if (attack->data.sp) {
attack->level = xml_ivalue(node, "level", 0);
@ -2000,7 +2044,8 @@ static int parse_messages(xmlDocPtr doc)
mtype = mt_find((const char *)propValue);
if (mtype == NULL) {
mtype = mt_register(mt_new((const char *)propValue, (const char **)argv));
} else {
}
else {
assert(argv != NULL || !"cannot redefine arguments of message now");
}
xmlFree(propValue);
@ -2087,7 +2132,8 @@ xml_readstrings(xmlXPathContextPtr xpath, xmlNodePtr * nodeTab, int nodeNr,
locale_setstring(lang, zName, (const char *)propText);
}
xmlFree(propText);
} else {
}
else {
log_warning("string %s has no text in locale %s\n", zName, locale_name(lang));
}
}

View File

@ -2979,7 +2979,16 @@ spellbook * get_spellbook(const char * name)
return result;
}
int free_spellbook_cb(const void *match, const void *key, size_t keylen, void *data) {
spellbook *sb;
cb_get_kv(match, &sb, sizeof(sb));
spellbook_clear(sb);
free(sb);
return 0;
}
void free_spellbooks(void)
{
cb_foreach(&cb_spellbooks, "", 0, free_spellbook_cb, NULL);
cb_clear(&cb_spellbooks);
}

View File

@ -39,6 +39,7 @@ void test_updatespells(CuTest * tc)
CuAssertPtrNotNull(tc, f->spellbook);
CuAssertIntEquals(tc, 1, ql_length(f->spellbook->spells));
CuAssertPtrNotNull(tc, spellbook_get(f->spellbook, sp));
test_cleanup();
}
void test_spellbooks(CuTest * tc)
@ -63,12 +64,11 @@ void test_spellbooks(CuTest * tc)
entry = spellbook_get(herp, sp);
CuAssertPtrNotNull(tc, entry);
CuAssertPtrEquals(tc, sp, entry->sp);
/* CuAssertPtrEquals(tc, 0, spellbook_get(derp, sname)); */
test_cleanup();
herp = get_spellbook("herp");
CuAssertPtrNotNull(tc, herp);
/* CuAssertPtrEquals(tc, 0, spellbook_get(herp, sname)); */
test_cleanup();
}
static spell * test_magic_create_spell(void)
@ -120,6 +120,7 @@ void test_pay_spell(CuTest * tc)
CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_SILVER)));
CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_AURA)));
CuAssertIntEquals(tc, 0, get_resource(u, get_resourcetype(R_HORSE)));
test_cleanup();
}
void test_pay_spell_failure(CuTest * tc)
@ -157,6 +158,7 @@ void test_pay_spell_failure(CuTest * tc)
CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 3, 1));
CuAssertIntEquals(tc, 0, change_resource(u, get_resourcetype(R_SILVER), -1));
CuAssertIntEquals(tc, 0, eff_spelllevel(u, sp, 2, 1));
test_cleanup();
}
void test_getspell_unit(CuTest * tc)
@ -185,6 +187,7 @@ void test_getspell_unit(CuTest * tc)
unit_add_spell(u, 0, sp, 1);
CuAssertPtrNotNull(tc, unit_getspell(u, "Herp-a-derp", lang));
test_cleanup();
}
void test_getspell_faction(CuTest * tc)
@ -215,6 +218,7 @@ void test_getspell_faction(CuTest * tc)
f->spellbook = create_spellbook(0);
spellbook_add(f->spellbook, sp, 1);
CuAssertPtrEquals(tc, sp, unit_getspell(u, "Herp-a-derp", lang));
test_cleanup();
}
void test_getspell_school(CuTest * tc)
@ -246,6 +250,7 @@ void test_getspell_school(CuTest * tc)
CuAssertPtrNotNull(tc, book);
spellbook_add(book, sp, 1);
CuAssertPtrEquals(tc, sp, unit_getspell(u, "Herp-a-derp", lang));
test_cleanup();
}
void test_set_pre_combatspell(CuTest * tc)
@ -278,6 +283,7 @@ void test_set_pre_combatspell(CuTest * tc)
unset_combatspell(u, sp);
CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index));
CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index));
test_cleanup();
}
void test_set_main_combatspell(CuTest * tc)
@ -310,6 +316,7 @@ void test_set_main_combatspell(CuTest * tc)
unset_combatspell(u, sp);
CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index));
CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index));
test_cleanup();
}
void test_set_post_combatspell(CuTest * tc)
@ -342,6 +349,7 @@ void test_set_post_combatspell(CuTest * tc)
unset_combatspell(u, sp);
CuAssertIntEquals(tc, 0, get_combatspelllevel(u, index));
CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index));
test_cleanup();
}
void test_hasspell(CuTest * tc)
@ -371,6 +379,7 @@ void test_hasspell(CuTest * tc)
set_level(u, SK_MAGIC, 1);
CuAssertTrue(tc, !u_hasspell(u, sp));
test_cleanup();
}
CuSuite *get_magic_suite(void)

View File

@ -17,6 +17,7 @@
#include <tests.h>
#include <stdlib.h>
#include <string.h>
static void test_market_curse(CuTest * tc)
{
@ -45,7 +46,7 @@ static void test_market_curse(CuTest * tc)
set_param(&global.parameters, "rules.region_owners", "1");
btype = (building_type *)calloc(1, sizeof(building_type));
btype->_name = "market";
btype->_name = _strdup("market");
bt_register(btype);
terrain = get_terrain("plain");

View File

@ -127,90 +127,32 @@ bool(*fun) (const region * r))
static bool f_nolux(const region * r)
{
if (r->land && count_demand(r) != get_maxluxuries())
return true;
return false;
return (r->land && count_demand(r) != get_maxluxuries());
}
int fix_demand(region * rd)
{
region_list *rl, *rlist = NULL;
static const luxury_type *mlux[MAXLUXURIES];
const luxury_type *ltypes[MAXLUXURIES];
const luxury_type *sale = NULL;
int maxlux = 0;
static int maxluxuries = -1;
// TODO: this entire function is impossible to understand
recurse_regions(rd, &rlist, f_nolux);
if (maxluxuries < 0) {
int i = 0;
for (sale = luxurytypes; sale; sale = sale->next) {
ltypes[i++] = sale;
int fix_demand(region * rd) {
luxury_type * ltype;
int maxluxuries = get_maxluxuries();
if (maxluxuries > 0) {
int sale = rng_int() % maxluxuries;
for (ltype = luxurytypes; sale != 0 && ltype; ltype = ltype->next) {
--sale;
}
maxluxuries = i;
setluxuries(rd, ltype);
return 0;
}
if (maxluxuries == 0) {
return -1;
}
else {
int i;
for (i = 0; i != maxluxuries; ++i) {
mlux[i] = 0;
}
}
int fix_all_demand(region *rd) {
region_list *rl, *rlist = NULL;
recurse_regions(rd, &rlist, f_nolux);
for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data;
direction_t d;
for (d = 0; d != MAXDIRECTIONS; ++d) {
region *nr = rconnect(r, d);
if (nr && nr->land && nr->land->demands) {
struct demand *dmd;
for (dmd = nr->land->demands; dmd; dmd = dmd->next) {
if (dmd->value == 0) {
int i;
for (i = 0; i != maxluxuries; ++i) {
if (mlux[i] == NULL) {
maxlux = i;
mlux[i] = dmd->type;
break;
}
else if (mlux[i] == dmd->type) {
break;
}
}
break;
}
}
}
}
freset(r, RF_MARK); /* undo recursive marker */
if (!fix_demand(r)) {
return -1;
}
if (maxlux < 2) {
int i;
for (i = maxlux; i != 2; ++i) {
int j;
do {
int k = rng_int() % maxluxuries;
mlux[i] = ltypes[k];
for (j = 0; j != i; ++j) {
if (mlux[j] == mlux[i])
break;
}
} while (j != i);
}
maxlux = 2;
}
for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data;
sale = mlux[rng_int() % maxlux];
if (sale)
setluxuries(r, sale);
}
while (rlist) {
rl = rlist->next;
free(rlist);
rlist = rl;
}
return 0;
}

View File

@ -28,7 +28,7 @@ static void test_ship_not_allowed_in_coast(CuTest * tc)
ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO);
otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO);
stype = test_create_shiptype("derp");
stype->coasts = (const struct terrain_type **)calloc(2, sizeof(const struct terrain_type *));
stype->coasts = (struct terrain_type **)calloc(2, sizeof(struct terrain_type *));
r1 = test_create_region(0, 0, ttype);
r2 = test_create_region(1, 0, otype);

View File

@ -210,12 +210,13 @@ void set_factionstealth(unit * u, faction * f)
int setstealth_cmd(unit * u, struct order *ord)
{
char token[64];
const char *s;
int level, rule;
const race *trace;
init_order(ord);
s = getstrtoken();
s = gettoken(token, sizeof(token));
/* Tarne ohne Parameter: Setzt maximale Tarnung */
@ -286,7 +287,7 @@ int setstealth_cmd(unit * u, struct order *ord)
/* TARNE PARTEI is disabled */
break;
}
s = getstrtoken();
s = gettoken(token, sizeof(token));
if (rule & 1) {
if (!s || *s == 0) {
fset(u, UFL_ANON_FACTION);
@ -299,13 +300,13 @@ int setstealth_cmd(unit * u, struct order *ord)
}
if (rule & 2) {
if (get_keyword(s, u->faction->locale) == K_NUMBER) {
const char *s2 = getstrtoken();
s = gettoken(token, sizeof(token));
int nr = -1;
if (s2) {
nr = atoi36(s2);
if (s) {
nr = atoi36(s);
}
if (!s2 || *s2 == 0 || nr == u->faction->no) {
if (!s || *s == 0 || nr == u->faction->no) {
a_removeall(&u->attribs, &at_otherfaction);
break;
}

View File

@ -86,6 +86,7 @@ int RunAllTests(void)
log_flags = flags;
fail_count = suite->failCount;
CuSuiteDelete(suite);
kernel_done();
return fail_count;
}

View File

@ -57,8 +57,8 @@ struct unit *test_create_unit(struct faction *f, struct region *r)
void test_cleanup(void)
{
test_clear_terrains();
test_clear_resources();
free_terrains();
free_resources();
global.functions.maintenance = NULL;
global.functions.wage = NULL;
default_locale = 0;
@ -75,7 +75,6 @@ terrain_type *
test_create_terrain(const char * name, unsigned int flags)
{
terrain_type * t = get_or_create_terrain(name);
t->_name = _strdup(name);
t->flags = flags;
return t;
}

View File

@ -3,6 +3,7 @@
#include <kernel/types.h>
#include <kernel/item.h>
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <util/language.h>
@ -12,6 +13,7 @@
static void test_resources(CuTest *tc) {
resource_type *rtype;
test_cleanup();
init_resources();
CuAssertPtrNotNull(tc, rt_find("hp"));
CuAssertPtrEquals(tc, rt_find("hp"), (void *)get_resourcetype(R_LIFE));
CuAssertPtrNotNull(tc, rt_find("peasant"));
@ -27,6 +29,7 @@ static void test_resources(CuTest *tc) {
CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE));
test_cleanup();
CuAssertPtrEquals(tc, 0, rt_find("stone"));
CuAssertPtrEquals(tc, 0, rt_find("peasant"));
rtype = rt_get_or_create("stone");
CuAssertPtrEquals(tc, (void *)rtype, (void *)get_resourcetype(R_STONE));
}
@ -36,15 +39,13 @@ static void test_recreate_world(CuTest * tc)
test_cleanup();
CuAssertPtrEquals(tc, 0, get_locale("de"));
CuAssertPtrEquals(tc, 0, (void *)rt_find("horse"));
CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE));
CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA));
CuAssertPtrNotNull(tc, get_resourcetype(R_AURA));
CuAssertPtrNotNull(tc, (void *)rt_find("money"));
test_create_world();
CuAssertPtrEquals(tc, default_locale, get_locale("de"));
CuAssertPtrNotNull(tc, default_locale);
CuAssertPtrNotNull(tc, findregion(0, 0));
CuAssertPtrNotNull(tc, get_terrain("plain"));
CuAssertPtrNotNull(tc, get_terrain("ocean"));
CuAssertPtrNotNull(tc, (void *)rt_find("horse"));
CuAssertPtrNotNull(tc, get_resourcetype(R_HORSE));
CuAssertPtrNotNull(tc, (void *)rt_find("money"));
@ -56,14 +57,16 @@ static void test_recreate_world(CuTest * tc)
test_cleanup();
CuAssertPtrEquals(tc, 0, get_locale("de"));
CuAssertPtrEquals(tc, 0, (void*)get_terrain("plain"));
CuAssertPtrEquals(tc, 0, (void*)get_terrain("ocean"));
CuAssertPtrEquals(tc, 0, (void*)rt_find("horse"));
CuAssertPtrEquals(tc, 0, (void*)get_resourcetype(R_HORSE));
CuAssertPtrNotNull(tc, (void *)rt_find("money"));
CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE));
CuAssertPtrNotNull(tc, get_resourcetype(R_SILVER));
CuAssertPtrNotNull(tc, get_resourcetype(R_AURA));
CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA));
CuAssertPtrNotNull(tc, get_resourcetype(R_PEASANT));
CuAssertPtrEquals(tc, 0, (void *)rt_find("money"));
CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_LIFE));
CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_SILVER));
CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_AURA));
CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_PERMAURA));
CuAssertPtrEquals(tc, 0, (void *)get_resourcetype(R_PEASANT));
CuAssertPtrEquals(tc, 0, findregion(0, 0));
}

View File

@ -355,3 +355,7 @@ void a_write(struct storage *store, const attrib * attribs, const void *owner)
}
WRITE_TOK(store, "end");
}
void free_attribs(void) {
cb_clear(&cb_deprecated);
}

View File

@ -79,6 +79,8 @@ extern "C" {
extern void a_write(struct storage *store, const attrib * attribs,
const void *owner);
void free_attribs(void);
#define DEFAULT_AGE NULL
#define DEFAULT_INIT NULL
#define DEFAULT_FINALIZE NULL

View File

@ -147,14 +147,13 @@ const char *locale_string(const locale * lang, const char *key)
}
find = find->nexthash;
}
if (!find) {
log_warning("missing translation for \"%s\" in locale %s\n", key, lang->name);
if (find) {
return find->str;
}
log_error("missing translation for \"%s\" in locale %s\n", key, lang->name);
if (lang->fallback) {
return locale_string(lang->fallback, key);
}
return 0;
}
return find->str;
}
return 0;
}
@ -242,6 +241,7 @@ void add_translation(struct critbit_tree **cbp, const char *key, int i) {
if (str) {
size_t len = strlen(str);
if (!cb) {
// TODO: this will leak, because we do not know how to clean it up */
*cbp = cb = (struct critbit_tree *)calloc(1, sizeof(struct critbit_tree *));
}
len = cb_new_kv(str, len, &i, sizeof(int), buffer);
@ -319,6 +319,7 @@ void free_locales(void) {
free(strings);
}
}
free(locales->name);
free(locales);
locales = next;
}

View File

@ -14,7 +14,7 @@ typedef struct locale_str {
} locale_str;
typedef struct locale {
const char *name;
char *name;
unsigned int index;
struct locale *next;
unsigned int hashkey;

View File

@ -211,7 +211,13 @@ void freetokens(void * root)
int i;
for (i = 0; node && i != NODEHASHSIZE; ++i) {
if (node->next[i]) {
tref ** refs = &node->next[i];
freetokens(node->next[i]->node);
while (*refs) {
tref * ref = *refs;
*refs = ref->nexthash;
free(ref);
}
}
}
free(node);

View File

@ -61,7 +61,10 @@ static void a_initdirection(attrib * a)
static void a_freedirection(attrib * a)
{
free(a->data.v);
spec_direction *d = (spec_direction *)(a->data.v);
free(d->desc);
free(d->keyword);
free(d);
}
static int a_agedirection(attrib * a)