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 cd $ROOT
[ -e eressea.ini ] || ln -sf conf/eressea.ini [ -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.lua
$ROOT/$BIN_DIR/eressea/eressea -v0 scripts/run-tests-e3.lua
cd $OLDWPD 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,25 +3,25 @@ require "lunit"
module("tests.e3.castles", package.seeall, lunit.testcase ) module("tests.e3.castles", package.seeall, lunit.testcase )
function setup() function setup()
eressea.free_game() eressea.game.reset()
end end
function test_small_castles() function test_small_castles()
local r = region.create(0, 0, "plain") local r = region.create(0, 0, "plain")
local f1 = faction.create("noreply@eressea.de", "human", "de") local f1 = faction.create("noreply@eressea.de", "human", "de")
local u1 = unit.create(f1, r, 1) local u1 = unit.create(f1, r, 1)
local f2 = faction.create("noreply@eressea.de", "halfling", "de") local f2 = faction.create("noreply@eressea.de", "halfling", "de")
local u2 = unit.create(f2, r, 1) local u2 = unit.create(f2, r, 1)
u1:add_item("money", 10000) u1:add_item("money", 10000)
local b = building.create(r, "castle") local b = building.create(r, "castle")
u2.building = b u2.building = b
u1.building = b u1.building = b
b.owner = u2 b.owner = u2
assert_equal("site", b:get_typename(7)) assert_equal("site", b:get_typename(7))
assert_equal("fortification", b:get_typename(8)) assert_equal("fortification", b:get_typename(8))
b.owner = u1 b.owner = u1
assert_equal("site", b:get_typename(9)) assert_equal("site", b:get_typename(9))
assert_equal("fortification", b:get_typename(10)) assert_equal("fortification", b:get_typename(10))
end end

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

View File

@ -6,20 +6,20 @@ local f
local u local u
function setup() function setup()
eressea.free_game() eressea.game.reset()
eressea.settings.set("rules.economy.food", "4") eressea.settings.set("rules.economy.food", "4")
local r = region.create(0,0, "plain") 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) u = unit.create(f, r, 1)
f = faction.create("stealth@eressea.de", "human", "de") f = faction.create("stealth2@eressea.de", "human", "de")
end end
function test_stealth_faction_on() function test_stealth_faction_on()
u:clear_orders() u:clear_orders()
u:add_order("TARNEN PARTEI") u:add_order("TARNE PARTEI")
eressea.settings.set("rules.stealth.faction", 1) eressea.settings.set("rules.stealth.faction", 1)
process_orders() process_orders()
assert_not_match("Partei", report.report_unit(u, f)) assert_not_match("Partei", report.report_unit(u, f))
assert_match("anonym", report.report_unit(u, f)) assert_match("anonym", report.report_unit(u, f))
@ -27,9 +27,9 @@ end
function test_stealth_faction_off() function test_stealth_faction_off()
u:clear_orders() u:clear_orders()
u:add_order("TARNEN PARTEI") u:add_order("TARNE PARTEI")
eressea.settings.set("rules.stealth.faction", 0) eressea.settings.set("rules.stealth.faction", 0)
process_orders() process_orders()
assert_match("Partei", report.report_unit(u, f)) assert_match("Partei", report.report_unit(u, f))
assert_not_match("anonym", report.report_unit(u, f)) assert_not_match("anonym", report.report_unit(u, f))

View File

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

View File

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

View File

@ -5,6 +5,7 @@
#include "json.h" #include "json.h"
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/save.h> #include <kernel/save.h>
@ -14,6 +15,7 @@
void eressea_free_game(void) { void eressea_free_game(void) {
free_gamedata(); free_gamedata();
init_resources();
} }
int eressea_read_game(const char * filename) { 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) { for (f = factions; f; f = f->next) {
f->flags &= FFL_SAVEMASK; f->flags &= FFL_SAVEMASK;
} }
init_locales();
} }
static int tolua_process_orders(lua_State * L) 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'; buf[len] = '\0';
CuAssertStrEquals(tc, "{}", strip(buf)); CuAssertStrEquals(tc, "{}", strip(buf));
mstream_done(&out); mstream_done(&out);
test_cleanup();
} }
static cJSON *export_a_region(CuTest * tc, const struct terrain_type *terrain, region **_r) { 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")); CuAssertPtrNotNull(tc, attr = cJSON_GetObjectItem(json, "name"));
CuAssertStrEquals(tc, r->land->name, attr->valuestring); CuAssertStrEquals(tc, r->land->name, attr->valuestring);
cJSON_Delete(json); cJSON_Delete(json);
test_cleanup();
} }
static void test_export_ocean_region(CuTest * tc) { 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); json = export_a_region(tc, terrain, 0);
CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "name")); CuAssertPtrEquals(tc, 0, cJSON_GetObjectItem(json, "name"));
cJSON_Delete(json); cJSON_Delete(json);
test_cleanup();
} }
static void test_export_no_factions(CuTest * tc) { static void test_export_no_factions(CuTest * tc) {
@ -119,6 +122,7 @@ static void test_export_no_factions(CuTest * tc) {
buf[len]=0; buf[len]=0;
CuAssertStrEquals(tc, "{}", strip(buf)); CuAssertStrEquals(tc, "{}", strip(buf));
mstream_done(&out); mstream_done(&out);
test_cleanup();
} }
CuSuite *get_json_suite(void) { 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); i_change(&u->items, itype, 2);
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1)); CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
CuAssertIntEquals(tc, 1, i_get(u->items, itype)); CuAssertIntEquals(tc, 1, i_get(u->items, itype));
test_cleanup();
} }
static void test_build_requires_building(CuTest *tc) { 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)); CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
btype->maxcapacity = 0; btype->maxcapacity = 0;
CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1)); 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) { 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; rtype = bf.cons.materials[0].rtype;
i_change(&u->items, rtype->itype, 1); i_change(&u->items, rtype->itype, 1);
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1)); CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1));
test_cleanup();
} }
static void test_build_failure_low_skill(CuTest *tc) { 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); i_change(&u->items, rtype->itype, 1);
set_level(u, SK_ARMORER, bf.cons.minskill-1); set_level(u, SK_ARMORER, bf.cons.minskill-1);
CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10)); CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10));
test_cleanup();
} }
static void test_build_failure_completed(CuTest *tc) { static void test_build_failure_completed(CuTest *tc) {
@ -115,6 +119,7 @@ static void test_build_failure_completed(CuTest *tc) {
bf.cons.maxsize = 1; bf.cons.maxsize = 1;
CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10)); CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10));
CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype)); CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype));
test_cleanup();
} }
static void test_build_limits(CuTest *tc) { 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)); CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, 0));
CuAssertPtrEquals(tc, 0, u->region->buildings); CuAssertPtrEquals(tc, 0, u->region->buildings);
CuAssertPtrEquals(tc, 0, u->building); CuAssertPtrEquals(tc, 0, u->building);
test_cleanup();
} }
static void test_build_building_with_golem(CuTest *tc) { 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); CuAssertPtrNotNull(tc, u->region->buildings);
CuAssertIntEquals(tc, 1, u->region->buildings->size); CuAssertIntEquals(tc, 1, u->region->buildings->size);
CuAssertIntEquals(tc, 0, u->number); CuAssertIntEquals(tc, 0, u->number);
test_cleanup();
} }
static void test_build_building_success(CuTest *tc) { 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); CuAssertPtrEquals(tc, u->region->buildings, u->building);
CuAssertIntEquals(tc, 1, u->building->size); CuAssertIntEquals(tc, 1, u->building->size);
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype)); CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
test_cleanup();
} }
CuSuite *get_build_suite(void) CuSuite *get_build_suite(void)

View File

@ -92,8 +92,14 @@ void bt_register(building_type * type)
ql_push(&buildingtypes, (void *)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) { void free_buildingtypes(void) {
ql_foreach(buildingtypes, free); ql_foreach(buildingtypes, free_buildingtype);
ql_free(buildingtypes); ql_free(buildingtypes);
buildingtypes = 0; buildingtypes = 0;
} }

View File

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

View File

@ -22,6 +22,9 @@ static void test_register_building(CuTest * tc)
bt_register(btype); bt_register(btype);
CuAssertPtrNotNull(tc, bt_find("herp")); CuAssertPtrNotNull(tc, bt_find("herp"));
// free(btype->_name);
// free(btype);
test_cleanup();
} }
static void test_building_set_owner(CuTest * tc) 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)); CuAssertPtrEquals(tc, u1, building_owner(bld));
building_set_owner(u2); building_set_owner(u2);
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_next_when_empty(CuTest * tc) 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)); CuAssertPtrEquals(tc, u, building_owner(bld));
u->number = 0; u->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_other_when_empty(CuTest * tc) 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)); CuAssertPtrEquals(tc, u, building_owner(bld));
u->number = 0; u->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_same_faction_when_empty(CuTest * tc) 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)); CuAssertPtrEquals(tc, u3, building_owner(bld));
u3->number = 0; u3->number = 0;
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_next_after_leave(CuTest * tc) 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)); CuAssertPtrEquals(tc, u, building_owner(bld));
leave_building(u); leave_building(u);
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_other_after_leave(CuTest * tc) 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)); CuAssertPtrEquals(tc, u, building_owner(bld));
leave_building(u); leave_building(u);
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_goes_to_same_faction_after_leave(CuTest * tc) 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)); CuAssertPtrEquals(tc, u2, building_owner(bld));
leave_building(u2); leave_building(u2);
CuAssertPtrEquals(tc, 0, building_owner(bld)); CuAssertPtrEquals(tc, 0, building_owner(bld));
test_cleanup();
} }
static void test_buildingowner_resets_when_empty(CuTest * tc) 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)); CuAssertPtrEquals(tc, 0, building_owner(bld));
u->number = 1; u->number = 1;
CuAssertPtrEquals(tc, u, building_owner(bld)); CuAssertPtrEquals(tc, u, building_owner(bld));
test_cleanup();
} }
void test_buildingowner_goes_to_empty_unit_after_leave(CuTest * tc) 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)); CuAssertPtrEquals(tc, 0, building_owner(bld));
u2->number = 1; u2->number = 1;
CuAssertPtrEquals(tc, u2, building_owner(bld)); CuAssertPtrEquals(tc, u2, building_owner(bld));
test_cleanup();
} }
CuSuite *get_building_suite(void) 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 check_param(const struct param *p, const char *key, const char *searchvalue)
{ {
int result = 0;
const char *value = get_param(p, key); const char *value = get_param(p, key);
if (!value) { if (!value) {
return 0; return 0;
} }
char *p_value = malloc(sizeof(char)* (strlen(value) + 1)); char *p_value = _strdup(value);
strcpy(p_value, value);
const char *delimiter = " ,;"; const char *delimiter = " ,;";
char *v = strtok(p_value, delimiter); char *v = strtok(p_value, delimiter);
while (v != NULL) { while (v != NULL) {
if (strcmp(v, searchvalue) == 0) if (strcmp(v, searchvalue) == 0) {
{ result = 1;
return 1; break;
} }
v = strtok(NULL, delimiter); v = strtok(NULL, delimiter);
} }
return 0; free(p_value);
return result;
} }
static const char *g_datadir; 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. * calling it is optional, e.g. a release server will most likely not do it.
*/ */
translation_done(); translation_done();
free_attribs();
} }
attrib_type at_germs = { attrib_type at_germs = {
@ -1759,8 +1761,6 @@ void free_gamedata(void)
a_remove(&global.attribs, global.attribs); a_remove(&global.attribs, global.attribs);
} }
++global.cookie; /* readgame() already does this, but sjust in case */ ++global.cookie; /* readgame() already does this, but sjust in case */
init_resources();
} }
const char * game_name(void) { const char * game_name(void) {

View File

@ -1167,10 +1167,7 @@ static item *default_spoil(const struct race *rc, int size)
return itm; return itm;
} }
#ifndef DISABLE_TESTS int free_itype(item_type *itype) {
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));
free(itype->construction); free(itype->construction);
free(itype->_appearance[0]); free(itype->_appearance[0]);
free(itype->_appearance[1]); 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; resource_type *rtype;
cb_get_kv(match, &rtype, sizeof(rtype)); cb_get_kv(match, &rtype, sizeof(rtype));
free(rtype->_name); free(rtype->_name);
if (rtype->itype) {
free_itype(rtype->itype);
}
free(rtype); free(rtype);
return 0; return 0;
} }
void test_clear_resources(void) void free_resources(void)
{ {
int i; int i;
memset((void *)oldpotiontype, 0, sizeof(oldpotiontype)); 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_foreach(&cb_resources, "", 0, free_rtype_cb, 0);
cb_clear(&cb_resources); cb_clear(&cb_resources);
++num_resources; ++num_resources;
@ -1201,7 +1205,6 @@ void test_clear_resources(void)
cb_clear(rnames + i); cb_clear(rnames + i);
} }
} }
#endif
void register_resources(void) void register_resources(void)
{ {

View File

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

View File

@ -2,6 +2,8 @@
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/pool.h> #include <kernel/pool.h>
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <util/language.h> #include <util/language.h>
#include <util/functions.h> #include <util/functions.h>
@ -116,6 +118,31 @@ void test_findresourcetype(CuTest * tc)
CuAssertPtrNotNull(tc, findresourcetype("Bauer", lang)); 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 *get_item_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
@ -125,5 +152,6 @@ CuSuite *get_item_suite(void)
SUITE_ADD_TEST(suite, test_resource_type); SUITE_ADD_TEST(suite, test_resource_type);
SUITE_ADD_TEST(suite, test_finditemtype); SUITE_ADD_TEST(suite, test_finditemtype);
SUITE_ADD_TEST(suite, test_findresourcetype); SUITE_ADD_TEST(suite, test_findresourcetype);
SUITE_ADD_TEST(suite, test_fix_demand);
return suite; return suite;
} }

View File

@ -155,7 +155,7 @@ static void json_construction(cJSON *json, construction **consp) {
return; return;
} }
if (json->type != cJSON_Object) { 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; return;
} }
construction * cons = (construction *)calloc(sizeof(construction), 1); construction * cons = (construction *)calloc(sizeof(construction), 1);
@ -178,7 +178,7 @@ static void json_construction(cJSON *json, construction **consp) {
} }
break; break;
default: 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; *consp = cons;
@ -304,7 +304,7 @@ static void json_ship(cJSON *json, ship_type *st) {
} }
break; break;
case cJSON_Array: case cJSON_Array:
st->coasts = (const terrain_type **) st->coasts = (terrain_type **)
malloc(sizeof(terrain_type *) * (1+cJSON_GetArraySize(child))); malloc(sizeof(terrain_type *) * (1+cJSON_GetArraySize(child)));
for (i=0,iter=child->child;iter;iter=iter->next) { for (i=0,iter=child->child;iter;iter=iter->next) {
if (iter->type==cJSON_String) { if (iter->type==cJSON_String) {

View File

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

View File

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

View File

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

View File

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

View File

@ -238,8 +238,15 @@ void free_ship(ship * s)
free(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) { void free_shiptypes(void) {
ql_foreach(shiptypes, free); ql_foreach(shiptypes, free_shiptype);
ql_free(shiptypes); ql_free(shiptypes);
shiptypes = 0; shiptypes = 0;
} }

View File

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -27,46 +27,46 @@ extern "C" {
#define DAMAGE_SCALE 100 /* multiplier for sh->damage */ #define DAMAGE_SCALE 100 /* multiplier for sh->damage */
/* ship_type::flags */ /* ship_type::flags */
#define SFL_OPENSEA 0x01 #define SFL_OPENSEA 0x01
#define SFL_FLY 0x02 #define SFL_FLY 0x02
#define SFL_NOCOAST 0x04 #define SFL_NOCOAST 0x04
typedef struct ship_type { typedef struct ship_type {
const char *_name; char *_name;
int range; /* range in regions */ int range; /* range in regions */
int flags; /* flags */ int flags; /* flags */
int combat; /* modifier for combat */ int combat; /* modifier for combat */
double storm; /* multiplier for chance to drift in storm */ double storm; /* multiplier for chance to drift in storm */
double damage; /* multiplier for damage taken by the ship */ double damage; /* multiplier for damage taken by the ship */
int cabins; /* max. cabins (weight) */ int cabins; /* max. cabins (weight) */
int cargo; /* max. cargo (weight) */ int cargo; /* max. cargo (weight) */
int cptskill; /* min. skill of captain */ int cptskill; /* min. skill of captain */
int minskill; /* min. skill to sail this (crew) */ int minskill; /* min. skill to sail this (crew) */
int sumskill; /* min. sum of crew+captain */ int sumskill; /* min. sum of crew+captain */
int fishing; /* weekly income from fishing */ int fishing; /* weekly income from fishing */
int at_bonus; /* Verändert den Angriffsskill (default: 0) */ int at_bonus; /* Verändert den Angriffsskill (default: 0) */
int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ int df_bonus; /* Verändert den Verteidigungskill (default: 0) */
float tac_bonus; 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 */ struct construction *construction; /* how to build a ship */
} ship_type; } ship_type;
extern struct quicklist *shiptypes; extern struct quicklist *shiptypes;
/* Alte Schiffstypen: */ /* Alte Schiffstypen: */
const ship_type *st_find(const char *name); const ship_type *st_find(const char *name);
ship_type *st_get_or_create(const char *name); ship_type *st_get_or_create(const char *name);
void free_shiptypes(void); void free_shiptypes(void);
#define NOSHIP NULL #define NOSHIP NULL
@ -80,51 +80,51 @@ extern "C" {
#define SFL_SAVEMASK (SF_FLYING) #define SFL_SAVEMASK (SF_FLYING)
#define INCOME_FISHING 10 #define INCOME_FISHING 10
typedef struct ship { typedef struct ship {
struct ship *next; struct ship *next;
struct ship *nexthash; struct ship *nexthash;
struct unit * _owner; /* never use directly, always use ship_owner() */ struct unit * _owner; /* never use directly, always use ship_owner() */
int no; int no;
struct region *region; struct region *region;
char *name; char *name;
char *display; char *display;
struct attrib *attribs; struct attrib *attribs;
int size; int size;
int damage; /* damage in 100th of a point of size */ int damage; /* damage in 100th of a point of size */
int flags; int flags;
const struct ship_type *type; const struct ship_type *type;
direction_t coast; direction_t coast;
} ship; } ship;
void damage_ship(struct ship * sh, double percent); void damage_ship(struct ship * sh, double percent);
void ship_set_owner(struct unit * u); void ship_set_owner(struct unit * u);
struct unit *ship_owner(const struct ship *sh); struct unit *ship_owner(const struct ship *sh);
void ship_update_owner(struct ship * sh); void ship_update_owner(struct ship * sh);
extern const char *shipname(const struct ship *self); extern const char *shipname(const struct ship *self);
extern int shipcapacity(const struct ship *sh); extern int shipcapacity(const struct ship *sh);
extern void getshipweight(const struct ship *sh, int *weight, int *cabins); extern void getshipweight(const struct ship *sh, int *weight, int *cabins);
extern ship *new_ship(const struct ship_type *stype, struct region *r, extern ship *new_ship(const struct ship_type *stype, struct region *r,
const struct locale *lang); const struct locale *lang);
extern const char *write_shipname(const struct ship *sh, char *buffer, extern const char *write_shipname(const struct ship *sh, char *buffer,
size_t size); size_t size);
extern struct ship *findship(int n); extern struct ship *findship(int n);
extern struct ship *findshipr(const struct region *r, int n); extern struct ship *findshipr(const struct region *r, int n);
extern const struct ship_type *findshiptype(const char *s, extern const struct ship_type *findshiptype(const char *s,
const struct locale *lang); const struct locale *lang);
extern void write_ship_reference(const struct ship *sh, extern void write_ship_reference(const struct ship *sh,
struct storage *store); struct storage *store);
extern void remove_ship(struct ship **slist, struct ship *s); extern void remove_ship(struct ship **slist, struct ship *s);
extern void free_ship(struct ship *s); extern void free_ship(struct ship *s);
extern void free_ships(void); extern void free_ships(void);
extern const char *ship_getname(const struct ship *self); extern const char *ship_getname(const struct ship *self);
extern void ship_setname(struct ship *self, const char *name); extern void ship_setname(struct ship *self, const char *name);
int shipspeed(const struct ship *sh, const struct unit *u); int shipspeed(const struct ship *sh, const struct unit *u);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -45,6 +45,7 @@ void spellbook_clear(spellbook *sb)
free(sbe); free(sbe);
} }
ql_free(sb->spells); ql_free(sb->spells);
free(sb->name);
} }
int spellbook_foreach(spellbook *sb, int (*callback)(spellbook_entry *, void *), void * data) 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); sb = create_spellbook(0);
CuAssertPtrNotNull(tc, sb); CuAssertPtrNotNull(tc, sb);
CuAssertPtrEquals(tc, 0, sb->name); CuAssertPtrEquals(tc, 0, sb->name);
spellbook_clear(sb);
free(sb);
sb = create_spellbook("spells"); sb = create_spellbook("spells");
CuAssertPtrNotNull(tc, sb); CuAssertPtrNotNull(tc, sb);

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -15,10 +15,10 @@ without prior permission by the authors of Eressea.
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern void register_xmlreader(void); extern void register_xmlreader(void);
/* game-specific callbacks */ /* game-specific callbacks */
extern void (*set_spelldata_cb) (struct spell * sp); extern void(*set_spelldata_cb) (struct spell * sp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -2979,7 +2979,16 @@ spellbook * get_spellbook(const char * name)
return result; 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) void free_spellbooks(void)
{ {
cb_foreach(&cb_spellbooks, "", 0, free_spellbook_cb, NULL);
cb_clear(&cb_spellbooks); cb_clear(&cb_spellbooks);
} }

View File

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

View File

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

View File

@ -127,90 +127,32 @@ bool(*fun) (const region * r))
static bool f_nolux(const region * r) static bool f_nolux(const region * r)
{ {
if (r->land && count_demand(r) != get_maxluxuries()) return (r->land && count_demand(r) != get_maxluxuries());
return true;
return false;
} }
int fix_demand(region * rd) int fix_demand(region * rd) {
{ luxury_type * ltype;
region_list *rl, *rlist = NULL; int maxluxuries = get_maxluxuries();
static const luxury_type *mlux[MAXLUXURIES]; if (maxluxuries > 0) {
const luxury_type *ltypes[MAXLUXURIES]; int sale = rng_int() % maxluxuries;
const luxury_type *sale = NULL; for (ltype = luxurytypes; sale != 0 && ltype; ltype = ltype->next) {
int maxlux = 0; --sale;
static int maxluxuries = -1; }
setluxuries(rd, ltype);
return 0;
}
return -1;
}
// TODO: this entire function is impossible to understand int fix_all_demand(region *rd) {
region_list *rl, *rlist = NULL;
recurse_regions(rd, &rlist, f_nolux); recurse_regions(rd, &rlist, f_nolux);
if (maxluxuries < 0) {
int i = 0;
for (sale = luxurytypes; sale; sale = sale->next) {
ltypes[i++] = sale;
}
maxluxuries = i;
}
if (maxluxuries == 0) {
return -1;
}
else {
int i;
for (i = 0; i != maxluxuries; ++i) {
mlux[i] = 0;
}
}
for (rl = rlist; rl; rl = rl->next) { for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data; 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 */ freset(r, RF_MARK); /* undo recursive marker */
} if (!fix_demand(r)) {
if (maxlux < 2) { return -1;
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; 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); ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO);
otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO); otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO);
stype = test_create_shiptype("derp"); 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); r1 = test_create_region(0, 0, ttype);
r2 = test_create_region(1, 0, otype); 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) int setstealth_cmd(unit * u, struct order *ord)
{ {
char token[64];
const char *s; const char *s;
int level, rule; int level, rule;
const race *trace; const race *trace;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
/* Tarne ohne Parameter: Setzt maximale Tarnung */ /* Tarne ohne Parameter: Setzt maximale Tarnung */
@ -286,7 +287,7 @@ int setstealth_cmd(unit * u, struct order *ord)
/* TARNE PARTEI is disabled */ /* TARNE PARTEI is disabled */
break; break;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (rule & 1) { if (rule & 1) {
if (!s || *s == 0) { if (!s || *s == 0) {
fset(u, UFL_ANON_FACTION); fset(u, UFL_ANON_FACTION);
@ -299,13 +300,13 @@ int setstealth_cmd(unit * u, struct order *ord)
} }
if (rule & 2) { if (rule & 2) {
if (get_keyword(s, u->faction->locale) == K_NUMBER) { if (get_keyword(s, u->faction->locale) == K_NUMBER) {
const char *s2 = getstrtoken(); s = gettoken(token, sizeof(token));
int nr = -1; int nr = -1;
if (s2) { if (s) {
nr = atoi36(s2); 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); a_removeall(&u->attribs, &at_otherfaction);
break; break;
} }

View File

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

View File

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

View File

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

View File

@ -147,14 +147,13 @@ const char *locale_string(const locale * lang, const char *key)
} }
find = find->nexthash; find = find->nexthash;
} }
if (!find) { if (find) {
log_warning("missing translation for \"%s\" in locale %s\n", key, lang->name); return find->str;
if (lang->fallback) { }
return locale_string(lang->fallback, key); log_error("missing translation for \"%s\" in locale %s\n", key, lang->name);
} if (lang->fallback) {
return 0; return locale_string(lang->fallback, key);
} }
return find->str;
} }
return 0; return 0;
} }
@ -242,6 +241,7 @@ void add_translation(struct critbit_tree **cbp, const char *key, int i) {
if (str) { if (str) {
size_t len = strlen(str); size_t len = strlen(str);
if (!cb) { 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 *)); *cbp = cb = (struct critbit_tree *)calloc(1, sizeof(struct critbit_tree *));
} }
len = cb_new_kv(str, len, &i, sizeof(int), buffer); len = cb_new_kv(str, len, &i, sizeof(int), buffer);
@ -319,6 +319,7 @@ void free_locales(void) {
free(strings); free(strings);
} }
} }
free(locales->name);
free(locales); free(locales);
locales = next; locales = next;
} }

View File

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

View File

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

View File

@ -61,7 +61,10 @@ static void a_initdirection(attrib * a)
static void a_freedirection(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) static int a_agedirection(attrib * a)