Merge branch 'master' of github.com:badgerman/eressea

This commit is contained in:
Enno Rehling 2014-08-23 09:18:45 +02:00
commit ad903e83e3
27 changed files with 1285 additions and 1355 deletions

View File

@ -502,8 +502,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
const struct race *rc = u_race(u);
const char *str;
init_tokens(ord);
skip_token();
init_order(ord);
n = getuint();
if (u->number == 0) {
@ -666,8 +665,7 @@ int give_control_cmd(unit * u, order * ord)
const char *s;
param_t p;
init_tokens(ord);
skip_token();
init_order(ord);
u2 = getunit(r, u->faction);
s = getstrtoken();
p = findparam(s, u->faction->locale);
@ -730,11 +728,10 @@ static void give_cmd(unit * u, order * ord)
plane *pl;
message *msg;
init_tokens(ord);
skip_token();
init_order(ord);
u2 = getunit(r, u->faction);
s = getstrtoken();
n = atoip(s);
n = s ? atoip(s) : 0;
p = (n > 0) ? NOPARAM : findparam(s, u->faction->locale);
/* first, do all the ones that do not require HELP_GIVE or CONTACT */
@ -857,7 +854,7 @@ static void give_cmd(unit * u, order * ord)
return;
}
s = getstrtoken();
if (*s == 0) { /* GIVE ALL items that you have */
if (!s || *s == 0) { /* GIVE ALL items that you have */
/* do these checks once, not for each item we have: */
if (!(u_race(u)->ec_flags & GIVEITEM) && u2 != NULL) {
@ -990,8 +987,7 @@ static int forget_cmd(unit * u, order * ord)
return 0;
}
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) {
@ -1800,9 +1796,10 @@ int make_cmd(unit * u, struct order *ord)
const char *s;
const struct locale *lang = u->faction->locale;
char ibuf[16];
keyword_t kwd;
init_tokens(ord);
skip_token();
kwd = init_order(ord);
assert(kwd == K_MAKE);
s = getstrtoken();
m = atoi((const char *)s);
@ -2060,6 +2057,8 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
attrib *a;
const item_type *itype = NULL;
const luxury_type *ltype = NULL;
keyword_t kwd;
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, ord, 69, MSG_INCOME);
return;
@ -2071,8 +2070,8 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
/* Im Augenblick kann man nur 1 Produkt kaufen. expandbuying ist aber
* schon dafür ausgerüstet, mehrere Produkte zu kaufen. */
init_tokens(ord);
skip_token();
kwd = init_order(ord);
assert(kwd == K_BUY);
n = getuint();
if (!n) {
cmistake(u, ord, 26, MSG_COMMERCE);
@ -2351,10 +2350,11 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
{
bool unlimited = true;
const item_type *itype;
const luxury_type *ltype = NULL;
const luxury_type *ltype;
int n;
region *r = u->region;
const char *s;
keyword_t kwd;
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, ord, 69, MSG_INCOME);
@ -2363,8 +2363,8 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
/* sellorders sind KEIN array, weil für alle items DIE SELBE resource
* (das geld der region) aufgebraucht wird. */
init_tokens(ord);
skip_token();
kwd = init_order(ord);
assert(kwd == K_SELL);
s = getstrtoken();
if (findparam(s, u->faction->locale) == P_ANY) {
@ -2424,9 +2424,8 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
return false;
}
s = getstrtoken();
itype = finditemtype(s, u->faction->locale);
if (itype != NULL)
ltype = resource2luxury(itype->rtype);
itype = s ? finditemtype(s, u->faction->locale) : 0;
ltype = itype ? resource2luxury(itype->rtype) : 0;
if (ltype == NULL) {
cmistake(u, ord, 126, MSG_COMMERCE);
return false;
@ -2764,8 +2763,7 @@ static void breed_cmd(unit * u, struct order *ord)
}
/* züchte [<anzahl>] <parameter> */
init_tokens(ord);
skip_token();
(void)init_order(ord);
s = getstrtoken();
m = atoi((const char *)s);
@ -2830,9 +2828,10 @@ static const char *rough_amount(int a, int m)
static void research_cmd(unit * u, struct order *ord)
{
region *r = u->region;
keyword_t kwd;
init_tokens(ord);
skip_token();
kwd = init_order(ord);
assert(kwd == K_RESEARCH);
/*
const char *s = getstrtoken();
@ -2908,6 +2907,10 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders)
region *r = u->region;
faction *f = NULL;
message * msg;
keyword_t kwd;
kwd = init_order(ord);
assert(kwd == K_STEAL);
assert(skill_enabled(SK_PERCEPTION) && skill_enabled(SK_STEALTH));
@ -2916,8 +2919,6 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders)
ADDMSG(&u->faction->msgs, msg);
return;
}
init_tokens(ord);
skip_token();
id = read_unitid(u->faction, r);
u2 = findunitr(r, id);
@ -3040,7 +3041,10 @@ void entertain_cmd(unit * u, struct order *ord)
request *o;
static int entertainbase = 0;
static int entertainperlevel = 0;
keyword_t kwd;
kwd = init_order(ord);
assert(kwd == K_ENTERTAIN);
if (!entertainbase) {
const char *str = get_param(global.parameters, "entertain.base");
entertainbase = str ? atoi(str) : 0;
@ -3073,8 +3077,6 @@ void entertain_cmd(unit * u, struct order *ord)
u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT)
* entertainperlevel);
init_tokens(ord);
skip_token();
max_e = getuint();
if (max_e != 0) {
u->wants = _min(u->wants, max_e);
@ -3214,6 +3216,10 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders)
int n;
request *o;
int max;
keyword_t kwd;
kwd = init_order(ord);
assert(kwd == K_TAX);
if (!humanoidrace(u_race(u)) && !is_monsters(u->faction)) {
cmistake(u, ord, 228, MSG_INCOME);
@ -3236,8 +3242,6 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders)
return;
}
init_tokens(ord);
skip_token();
max = getuint();
if (max == 0)

View File

@ -32,39 +32,39 @@
#define MAXGAIN 15
static int
use_studypotion(struct unit *u, const struct item_type *itype, int amount,
struct order *ord)
struct order *ord)
{
if (getkeyword(u->thisorder) == K_STUDY) {
skill_t sk;
skill *sv;
if (init_order(u->thisorder) == K_STUDY) {
skill_t sk;
skill *sv;
init_tokens(u->thisorder);
skip_token();
sk = get_skill(getstrtoken(), u->faction->locale);
sv = unit_skill(u, sk);
sk = get_skill(getstrtoken(), u->faction->locale);
sv = unit_skill(u, sk);
if (sv && sv->level > 2) {
/* TODO: message */
} else if (study_cost(u, sk) > 0) {
/* TODO: message */
} else {
attrib *a = a_find(u->attribs, &at_learning);
teaching_info *teach;
if (a == NULL) {
a = a_add(&u->attribs, a_new(&at_learning));
}
teach = (teaching_info *) a->data.v;
if (amount > MAXGAIN)
amount = MAXGAIN;
teach->value += amount * 30;
if (teach->value > MAXGAIN * 30) {
teach->value = MAXGAIN * 30;
}
i_change(&u->items, itype, -amount);
return 0;
if (sv && sv->level > 2) {
/* TODO: message */
}
else if (study_cost(u, sk) > 0) {
/* TODO: message */
}
else {
attrib *a = a_find(u->attribs, &at_learning);
teaching_info *teach;
if (a == NULL) {
a = a_add(&u->attribs, a_new(&at_learning));
}
teach = (teaching_info *)a->data.v;
if (amount > MAXGAIN)
amount = MAXGAIN;
teach->value += amount * 30;
if (teach->value > MAXGAIN * 30) {
teach->value = MAXGAIN * 30;
}
i_change(&u->items, itype, -amount);
return 0;
}
}
}
return EUNUSABLE;
return EUNUSABLE;
}
/* END studypotion */
@ -73,27 +73,27 @@ use_studypotion(struct unit *u, const struct item_type *itype, int amount,
#define SPEEDSAIL_EFFECT 1
static int
use_speedsail(struct unit *u, const struct item_type *itype, int amount,
struct order *ord)
struct order *ord)
{
curse *c;
float effect;
ship *sh = u->ship;
if (!sh) {
cmistake(u, ord, 20, MSG_MOVE);
return -1;
}
curse *c;
float effect;
ship *sh = u->ship;
if (!sh) {
cmistake(u, ord, 20, MSG_MOVE);
return -1;
}
effect = SPEEDSAIL_EFFECT;
c =
create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect,
0);
c_setflag(c, CURSE_NOAGE);
effect = SPEEDSAIL_EFFECT;
c =
create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect,
0);
c_setflag(c, CURSE_NOAGE);
ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u,
SPEEDSAIL_EFFECT));
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u,
SPEEDSAIL_EFFECT));
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
return 0;
return 0;
}
/* END speedsail */
@ -103,113 +103,113 @@ use_speedsail(struct unit *u, const struct item_type *itype, int amount,
* Antimagiezone, die zwei Runden bestehen bleibt */
static int
use_antimagiccrystal(unit * u, const struct item_type *itype, int amount,
struct order *ord)
struct order *ord)
{
region *r = u->region;
const resource_type *rt_crystal = NULL;
int i;
region *r = u->region;
const resource_type *rt_crystal = NULL;
int i;
if (rt_crystal == NULL) {
rt_crystal = rt_find("antimagic");
assert(rt_crystal != NULL);
}
for (i = 0; i != amount; ++i) {
int effect, duration = 2;
float force;
spell *sp = find_spell("antimagiczone");
attrib **ap = &r->attribs;
unused_arg(ord);
assert(sp);
/* Reduziert die Stärke jedes Spruchs um effect */
effect = 5;
/* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus.
* Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone
* um seine Stufe */
force = (float)effect * 20; /* Stufe 5 =~ 100 */
/* Regionszauber auflösen */
while (*ap && force > 0) {
curse *c;
attrib *a = *ap;
if (!fval(a->type, ATF_CURSE)) {
do {
ap = &(*ap)->next;
} while (*ap && a->type == (*ap)->type);
continue;
}
c = (curse *) a->data.v;
/* Immunität prüfen */
if (c_flags(c) & CURSE_IMMUNE) {
do {
ap = &(*ap)->next;
} while (*ap && a->type == (*ap)->type);
continue;
}
force = destr_curse(c, effect, force);
if (c->vigour <= 0) {
a_remove(&r->attribs, a);
}
if (*ap)
ap = &(*ap)->next;
if (rt_crystal == NULL) {
rt_crystal = rt_find("antimagic");
assert(rt_crystal != NULL);
}
for (i = 0; i != amount; ++i) {
int effect, duration = 2;
float force;
spell *sp = find_spell("antimagiczone");
attrib **ap = &r->attribs;
unused_arg(ord);
assert(sp);
if (force > 0) {
create_curse(u, &r->attribs, ct_find("antimagiczone"), (float)force, duration,
(float)effect, 0);
/* Reduziert die Stärke jedes Spruchs um effect */
effect = 5;
/* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus.
* Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone
* um seine Stufe */
force = (float)effect * 20; /* Stufe 5 =~ 100 */
/* Regionszauber auflösen */
while (*ap && force > 0) {
curse *c;
attrib *a = *ap;
if (!fval(a->type, ATF_CURSE)) {
do {
ap = &(*ap)->next;
} while (*ap && a->type == (*ap)->type);
continue;
}
c = (curse *)a->data.v;
/* Immunität prüfen */
if (c_flags(c) & CURSE_IMMUNE) {
do {
ap = &(*ap)->next;
} while (*ap && a->type == (*ap)->type);
continue;
}
force = destr_curse(c, effect, force);
if (c->vigour <= 0) {
a_remove(&r->attribs, a);
}
if (*ap)
ap = &(*ap)->next;
}
if (force > 0) {
create_curse(u, &r->attribs, ct_find("antimagiczone"), (float)force, duration,
(float)effect, 0);
}
}
}
use_pooled(u, rt_crystal, GET_DEFAULT, amount);
ADDMSG(&u->faction->msgs, msg_message("use_antimagiccrystal",
"unit region", u, r));
return 0;
use_pooled(u, rt_crystal, GET_DEFAULT, amount);
ADDMSG(&u->faction->msgs, msg_message("use_antimagiccrystal",
"unit region", u, r));
return 0;
}
static int
use_instantartsculpture(struct unit *u, const struct item_type *itype,
int amount, struct order *ord)
int amount, struct order *ord)
{
building *b;
building *b;
if (u->region->land == NULL) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
return -1;
}
if (u->region->land == NULL) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
return -1;
}
b = new_building(bt_find("artsculpture"), u->region, u->faction->locale);
b->size = 100;
b = new_building(bt_find("artsculpture"), u->region, u->faction->locale);
b->size = 100;
ADDMSG(&u->region->msgs, msg_message("artsculpture_create", "unit region",
u, u->region));
ADDMSG(&u->region->msgs, msg_message("artsculpture_create", "unit region",
u, u->region));
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
return 0;
return 0;
}
static int
use_instantartacademy(struct unit *u, const struct item_type *itype,
int amount, struct order *ord)
int amount, struct order *ord)
{
building *b;
building *b;
if (u->region->land == NULL) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
return -1;
}
if (u->region->land == NULL) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
return -1;
}
b = new_building(bt_find("artacademy"), u->region, u->faction->locale);
b->size = 100;
b = new_building(bt_find("artacademy"), u->region, u->faction->locale);
b->size = 100;
ADDMSG(&u->region->msgs, msg_message("artacademy_create", "unit region", u,
u->region));
ADDMSG(&u->region->msgs, msg_message("artacademy_create", "unit region", u,
u->region));
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
return 0;
return 0;
}
#define BAGPIPEFRACTION dice_rand("2d4+2")
@ -217,58 +217,58 @@ use_instantartacademy(struct unit *u, const struct item_type *itype,
static int
use_bagpipeoffear(struct unit *u, const struct item_type *itype,
int amount, struct order *ord)
int amount, struct order *ord)
{
int money;
int money;
if (get_curse(u->region->attribs, ct_find("depression"))) {
cmistake(u, ord, 58, MSG_MAGIC);
return -1;
}
if (get_curse(u->region->attribs, ct_find("depression"))) {
cmistake(u, ord, 58, MSG_MAGIC);
return -1;
}
money = entertainmoney(u->region) / BAGPIPEFRACTION;
change_money(u, money);
rsetmoney(u->region, rmoney(u->region) - money);
money = entertainmoney(u->region) / BAGPIPEFRACTION;
change_money(u, money);
rsetmoney(u->region, rmoney(u->region) - money);
create_curse(u, &u->region->attribs, ct_find("depression"),
20, BAGPIPEDURATION, 0.0, 0);
create_curse(u, &u->region->attribs, ct_find("depression"),
20, BAGPIPEDURATION, 0.0, 0);
ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
"unit region command money", u, u->region, ord, money));
ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
"unit region command money", u, u->region, ord, money));
ADDMSG(&u->region->msgs, msg_message("bagpipeoffear_region",
"unit money", u, money));
ADDMSG(&u->region->msgs, msg_message("bagpipeoffear_region",
"unit money", u, money));
return 0;
return 0;
}
static int
use_aurapotion50(struct unit *u, const struct item_type *itype,
int amount, struct order *ord)
int amount, struct order *ord)
{
if (!is_mage(u)) {
cmistake(u, ord, 214, MSG_MAGIC);
return -1;
}
if (!is_mage(u)) {
cmistake(u, ord, 214, MSG_MAGIC);
return -1;
}
change_spellpoints(u, 50);
change_spellpoints(u, 50);
ADDMSG(&u->faction->msgs, msg_message("aurapotion50",
"unit region command", u, u->region, ord));
ADDMSG(&u->faction->msgs, msg_message("aurapotion50",
"unit region command", u, u->region, ord));
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
return 0;
return 0;
}
void register_itemfunctions(void)
{
register_demonseye();
register_item_use(use_antimagiccrystal, "use_antimagiccrystal");
register_item_use(use_instantartsculpture, "use_instantartsculpture");
register_item_use(use_studypotion, "use_studypotion");
register_item_use(use_speedsail, "use_speedsail");
register_item_use(use_instantartacademy, "use_instantartacademy");
register_item_use(use_bagpipeoffear, "use_bagpipeoffear");
register_item_use(use_aurapotion50, "use_aurapotion50");
register_demonseye();
register_item_use(use_antimagiccrystal, "use_antimagiccrystal");
register_item_use(use_instantartsculpture, "use_instantartsculpture");
register_item_use(use_studypotion, "use_studypotion");
register_item_use(use_speedsail, "use_speedsail");
register_item_use(use_instantartacademy, "use_instantartacademy");
register_item_use(use_bagpipeoffear, "use_bagpipeoffear");
register_item_use(use_aurapotion50, "use_aurapotion50");
}

View File

@ -46,7 +46,6 @@ names.c
order.c
pathfinder.c
plane.c
player.c
pool.c
race.c
region.c

View File

@ -158,8 +158,7 @@ static void perform_kick(void)
if (al && alliance_get_leader(al) == ta->u->faction) {
faction *f;
init_tokens(ta->ord);
skip_token();
init_order(ta->ord);
skip_token();
f = getfaction();
if (f && f_get_alliance(f) == al) {
@ -180,8 +179,7 @@ static void perform_new(void)
int id;
faction *f = ta->u->faction;
init_tokens(ta->ord);
skip_token();
init_order(ta->ord);
skip_token();
id = getid();
@ -216,8 +214,7 @@ static void perform_transfer(void)
if (al && alliance_get_leader(al) == ta->u->faction) {
faction *f;
init_tokens(ta->ord);
skip_token();
init_order(ta->ord);
skip_token();
f = getfaction();
if (f && f_get_alliance(f) == al) {
@ -237,8 +234,7 @@ static void perform_join(void)
faction *fj = ta->u->faction;
int aid;
init_tokens(ta->ord);
skip_token();
init_order(ta->ord);
skip_token();
aid = getid();
if (aid) {
@ -250,8 +246,7 @@ static void perform_join(void)
faction *fi = ti->u->faction;
if (fi && f_get_alliance(fi) == al) {
int fid;
init_tokens(ti->ord);
skip_token();
init_order(ti->ord);
skip_token();
fid = getid();
if (fid == fj->no) {

View File

@ -3967,8 +3967,7 @@ static bool start_battle(region * r, battle ** bp)
/* Ende Fehlerbehandlung Angreifer */
init_tokens(ord);
skip_token();
init_order(ord);
/* attackierte Einheit ermitteln */
u2 = getunit(r, u->faction);

View File

@ -146,8 +146,7 @@ int destroy_cmd(unit * u, struct order *ord)
if (u->number < 1)
return 0;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (findparam(s, u->faction->locale) == P_ROAD) {

View File

@ -92,8 +92,7 @@ static int do_command_i(const void *keys, struct unit *u, struct order *ord)
void do_command(const void *keys, struct unit *u, struct order *ord)
{
init_tokens(ord);
skip_token();
init_order(ord);
if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) {
char cmd[ORDERSIZE];
get_command(ord, cmd, sizeof(cmd));

View File

@ -637,6 +637,7 @@ unsigned int atoip(const char *s)
{
int n;
assert(s);
n = atoi(s);
if (n < 0)
@ -1137,12 +1138,13 @@ const char *igetstrtoken(const char *initstr)
unsigned int getuint(void)
{
return atoip((const char *)getstrtoken());
const char *s = getstrtoken();
return s ? atoip(s) : 0;
}
int getint(void)
{
return atoi((const char *)getstrtoken());
return atoi(getstrtoken());
}
const struct race *findrace(const char *s, const struct locale *lang)
@ -1172,7 +1174,7 @@ param_t findparam(const char *s, const struct locale * lang)
{
param_t result = NOPARAM;
char buffer[64];
char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s);
char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0;
if (str && *str) {
int i;
@ -1204,6 +1206,7 @@ param_t findparam_ex(const char *s, const struct locale * lang)
bool isparam(const char *s, const struct locale * lang, param_t param)
{
assert(s);
if (s[0] > '@') {
param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang);
return p == param;
@ -1855,8 +1858,8 @@ typedef struct param {
int getid(void)
{
const char *str = (const char *)getstrtoken();
int i = atoi36(str);
const char *str = getstrtoken();
int i = str ? atoi36(str) : 0;
if (i < 0) {
return -1;
}
@ -2686,7 +2689,7 @@ int movewhere(const unit * u, const char *token, region * r, region ** resultp)
region *r2;
direction_t d;
if (*token == '\0') {
if (!token || *token == '\0') {
*resultp = NULL;
return E_MOVE_OK;
}

View File

@ -25,7 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
struct player;
struct alliance;
struct item;
struct seen_region;
@ -60,7 +59,6 @@ typedef struct faction {
struct faction *next;
struct faction *nexthash;
struct player *owner;
#ifdef SMART_INTERVALS
struct region *first;
struct region *last;

View File

@ -1,11 +1,39 @@
#include <platform.h>
#include <kernel/types.h>
#include <kernel/race.h>
#include <kernel/config.h>
#include <util/language.h>
#include "faction.h"
#include <CuTest.h>
#include <stdio.h>
void test_get_monsters(CuTest *tc) {
static void test_addfaction(CuTest *tc) {
faction *f = 0;
const struct race *rc = rc_get_or_create("human");
const struct locale *lang = get_or_create_locale("en");
f = addfaction("test@eressea.de", "hurrdurr", rc, lang, 1234);
CuAssertPtrNotNull(tc, f);
CuAssertPtrNotNull(tc, f->name);
CuAssertPtrEquals(tc, NULL, (void *)f->units);
CuAssertPtrEquals(tc, NULL, (void *)f->next);
CuAssertPtrEquals(tc, NULL, (void *)f->banner);
CuAssertPtrEquals(tc, NULL, (void *)f->spellbook);
CuAssertPtrEquals(tc, NULL, (void *)f->ursprung);
CuAssertPtrEquals(tc, (void *)factions, (void *)f);
CuAssertStrEquals(tc, "test@eressea.de", f->email);
CuAssertStrEquals(tc, "hurrdurr", f->passw);
CuAssertPtrEquals(tc, (void *)lang, (void *)f->locale);
CuAssertIntEquals(tc, 1234, f->subscription);
CuAssertIntEquals(tc, 0, f->flags);
CuAssertIntEquals(tc, 0, f->age);
CuAssertIntEquals(tc, 1, f->alive);
CuAssertIntEquals(tc, M_GRAY, f->magiegebiet);
CuAssertIntEquals(tc, turn, f->lastorders);
CuAssertPtrEquals(tc, f, findfaction(f->no));
}
static void test_get_monsters(CuTest *tc) {
faction *f;
CuAssertPtrEquals(tc, NULL, get_monsters());
f = get_or_create_monsters();
@ -22,6 +50,7 @@ void test_get_monsters(CuTest *tc) {
CuSuite *get_faction_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_addfaction);
SUITE_ADD_TEST(suite, test_get_monsters);
return suite;
}

File diff suppressed because it is too large Load Diff

View File

@ -2535,8 +2535,7 @@ static castorder *cast_cmd(unit * u, order * ord)
}
level = eff_skill(u, SK_MAGIC, r);
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
param = findparam(s, u->faction->locale);
/* für Syntax ' STUFE x REGION y z ' */
@ -2712,7 +2711,7 @@ static castorder *cast_cmd(unit * u, order * ord)
int p = 0, size = 2;
for (;;) {
s = getstrtoken();
if (*s == 0)
if (!s || *s == 0)
break;
if (p + 1 >= size) {
size *= 2;

View File

@ -1060,8 +1060,7 @@ static void cycle_route(order * ord, unit * u, int gereist)
return;
tail[0] = '\0';
init_tokens(ord);
skip_token();
init_order(ord);
neworder[0] = 0;
for (cm = 0;; ++cm) {
@ -1142,8 +1141,7 @@ static bool transport(unit * ut, unit * u)
for (ord = ut->orders; ord; ord = ord->next) {
if (getkeyword(ord) == K_TRANSPORT) {
init_tokens(ord);
skip_token();
init_order(ord);
if (getunit(ut->region, ut->faction) == u) {
return true;
}
@ -1176,8 +1174,7 @@ static void init_transportation(void)
&& !fval(u, UFL_NOTMOVING) && !LongHunger(u)) {
unit *ut;
init_tokens(u->thisorder);
skip_token();
init_order(u->thisorder);
ut = getunit(r, u->faction);
if (ut == NULL) {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
@ -1207,8 +1204,7 @@ static void init_transportation(void)
for (ord = u->orders; ord; ord = ord->next) {
if (getkeyword(ord) == K_TRANSPORT) {
init_tokens(ord);
skip_token();
init_order(ord);
for (;;) {
unit *ut = getunit(r, u->faction);
@ -1216,8 +1212,7 @@ static void init_transportation(void)
break;
if (getkeyword(ut->thisorder) == K_DRIVE && can_move(ut)
&& !fval(ut, UFL_NOTMOVING) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
init_order(ut->thisorder);
if (getunit(r, ut->faction) == u) {
w += weight(ut);
}
@ -2088,8 +2083,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
if (getkeyword(ord) != K_TRANSPORT)
continue;
init_tokens(ord);
skip_token();
init_order(ord);
ut = getunit(r, u->faction);
if (ut != NULL) {
if (getkeyword(ut->thisorder) == K_DRIVE) {
@ -2104,8 +2098,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
bool found = false;
if (!fval(ut, UFL_NOTMOVING) && !LongHunger(ut)) {
init_tokens(ut->thisorder);
skip_token();
init_order(ut->thisorder);
if (getunit(u->region, ut->faction) == u) {
const region_list *route_to =
travel_route(ut, route_begin, route_end, ord,
@ -2301,8 +2294,7 @@ static void piracy_cmd(unit * u, struct order *ord)
/* Feststellen, ob schon ein anderer alliierter Pirat ein
* Ziel gefunden hat. */
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (s != NULL && *s) {
il = intlist_init();
@ -2389,8 +2381,7 @@ static void piracy_cmd(unit * u, struct order *ord)
LOC(u->faction->locale, directions[target_dir])));
/* Bewegung ausführen */
init_tokens(u->thisorder);
skip_token();
init_order(u->thisorder);
move(u, true);
}
@ -2543,8 +2534,7 @@ static void move_hunters(void)
if (getkeyword(ord) == K_FOLLOW) {
param_t p;
init_tokens(ord);
skip_token();
init_order(ord);
p = getparam(u->faction->locale);
if (p != P_SHIP) {
if (p != P_UNIT) {
@ -2666,15 +2656,13 @@ void movement(void)
else {
if (ships) {
if (u->ship && ship_owner(u->ship) == u) {
init_tokens(u->thisorder);
skip_token();
init_order(u->thisorder);
move(u, false);
}
}
else {
if (!u->ship || ship_owner(u->ship) != u) {
init_tokens(u->thisorder);
skip_token();
init_order(u->thisorder);
move(u, false);
}
}
@ -2729,10 +2717,10 @@ void follow_unit(unit * u)
const struct locale *lang = u->faction->locale;
if (getkeyword(ord) == K_FOLLOW) {
init_tokens(ord);
skip_token();
int id;
param_t p = getparam(lang);
param_t p;
init_order(ord);
p = getparam(lang);
if (p == P_UNIT) {
id = read_unitid(u->faction, r);
if (a != NULL) {
@ -2753,7 +2741,7 @@ void follow_unit(unit * u)
a = NULL;
}
}
if (p == P_SHIP) {
else if (p == P_SHIP) {
id = getshipid();
if (id <= 0) {
/* cmistake(u, ord, 20, MSG_MOVE); */

View File

@ -256,11 +256,11 @@ static order *create_order_i(keyword_t kwd, const char *sptr, int persistent,
order *ord = NULL;
int lindex;
if (keyword_disabled(kwd)) {
if ((int)kwd>0 && keyword_disabled(kwd)) {
log_error("trying to create an order for disabled keyword %s.", keyword(kwd));
return NULL;
}
/* if this is just nonsense, then we skip it. */
if (lomem) {
switch (kwd) {
@ -295,6 +295,7 @@ order *create_order(keyword_t kwd, const struct locale * lang,
const char *params, ...)
{
char zBuffer[DISPLAYSIZE];
assert(lang);
if (params) {
char *bufp = zBuffer;
int bytes;
@ -356,17 +357,19 @@ order *parse_order(const char *s, const struct locale * lang)
keyword_t kwd;
const char *sptr;
int persistent = 0;
const char * p;
while (*s == '@') {
persistent = 1;
++s;
}
sptr = s;
kwd = get_keyword(parse_token(&sptr), lang);
p = *sptr ? parse_token(&sptr) : 0;
kwd = p ? get_keyword(p, lang) : NOKEYWORD;
if (kwd == K_MAKE) {
const char *s, *sp = sptr;
s = parse_token(&sp);
if (isparam(s, lang, P_TEMP)) {
if (s && isparam(s, lang, P_TEMP)) {
kwd = K_MAKETEMP;
sptr = sp;
}
@ -563,8 +566,11 @@ static char *getcommand(const order * ord)
return _strdup(get_command(ord, cmd, sizeof(cmd)));
}
void init_tokens(const struct order *ord)
keyword_t init_order(const struct order *ord)
{
char *cmd = getcommand(ord);
char *cmd = 0;
if (ord->data->_str) cmd = _strdup(ord->data->_str);
init_tokens_str(cmd, cmd);
return ord->data->_keyword;
}

View File

@ -58,8 +58,8 @@ extern "C" {
bool is_repeated(const order * ord);
bool is_long(const order * ord);
extern char *write_order(const order * ord, char *buffer, size_t size);
extern void init_tokens(const struct order *ord); /* initialize token parsing */
char *write_order(const order * ord, char *buffer, size_t size);
keyword_t init_order(const struct order *ord);
#ifdef __cplusplus
}

View File

@ -17,9 +17,9 @@ static void test_create_order(CuTest *tc) {
ord = create_order(K_MOVE, lang, "NORTH");
CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd)));
CuAssertStrEquals(tc, "MOVE", getstrtoken());
CuAssertIntEquals(tc, K_MOVE, init_order(ord));
CuAssertStrEquals(tc, "NORTH", getstrtoken());
free_order(ord);
}
@ -33,9 +33,9 @@ static void test_parse_order(CuTest *tc) {
ord = parse_order("MOVE NORTH", lang);
CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd)));
CuAssertStrEquals(tc, "MOVE", getstrtoken());
CuAssertIntEquals(tc, K_MOVE, init_order(ord));
CuAssertStrEquals(tc, "NORTH", getstrtoken());
free_order(ord);
}
@ -51,9 +51,9 @@ static void test_parse_make(CuTest *tc) {
ord = parse_order("M hurrdurr", lang);
CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MAKE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MAKE hurrdurr", get_command(ord, cmd, sizeof(cmd)));
CuAssertStrEquals(tc, "MAKE", getstrtoken());
CuAssertIntEquals(tc, K_MAKE, init_order(ord));
CuAssertStrEquals(tc, "hurrdurr", getstrtoken());
free_order(ord);
}
@ -71,9 +71,9 @@ static void test_parse_make_temp(CuTest *tc) {
ord = parse_order("M T herp", lang);
CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd)));
CuAssertStrEquals(tc, "MAKETEMP", getstrtoken());
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
CuAssertStrEquals(tc, "herp", getstrtoken());
free_order(ord);
}
@ -90,14 +90,43 @@ static void test_parse_maketemp(CuTest *tc) {
ord = parse_order("MAKET herp", lang);
CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd)));
CuAssertStrEquals(tc, "MAKETEMP", getstrtoken());
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
CuAssertStrEquals(tc, "herp", getstrtoken());
free_order(ord);
}
static void test_init_order(CuTest *tc) {
order *ord;
struct locale * lang = get_or_create_locale("en");
ord = create_order(K_MAKETEMP, lang, "hurr durr");
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
CuAssertStrEquals(tc, "hurr", getstrtoken());
CuAssertStrEquals(tc, "durr", getstrtoken());
}
static void test_getstrtoken(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\" \"\" \'\'");
init_tokens_str(cmd, cmd);
CuAssertStrEquals(tc, "hurr", getstrtoken());
CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, "", getstrtoken());
CuAssertStrEquals(tc, "", getstrtoken());
CuAssertStrEquals(tc, 0, getstrtoken());
init_tokens_str(0, 0);
CuAssertStrEquals(tc, 0, getstrtoken());
}
static void test_skip_token(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\"");
init_tokens_str(cmd, cmd);
skip_token();
CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, 0, getstrtoken());
}
CuSuite *get_order_suite(void)
{
CuSuite *suite = CuSuiteNew();
@ -106,5 +135,8 @@ CuSuite *get_order_suite(void)
SUITE_ADD_TEST(suite, test_parse_make);
SUITE_ADD_TEST(suite, test_parse_make_temp);
SUITE_ADD_TEST(suite, test_parse_maketemp);
SUITE_ADD_TEST(suite, test_init_order);
SUITE_ADD_TEST(suite, test_skip_token);
SUITE_ADD_TEST(suite, test_getstrtoken);
return suite;
}

View File

@ -1,103 +0,0 @@
/* vi: set ts=2:
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
+-------------------+ Stefan Reich <reich@halbling.de>
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <platform.h>
#include "player.h"
#include <util/goodies.h>
#include <util/rng.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define PMAXHASH 1021
typedef struct player_hash {
struct player *entries;
} player_hash;
static player_hash *players[PMAXHASH];
player *make_player(const struct faction *f)
{
player *p = calloc(sizeof(player), 1);
unsigned int hash;
for (p->id = rng_int();; p->id++) {
/* if there is a hashing conflict, resolve it */
player *pi = get_player(p->id);
if (pi)
p->id++;
else
break;
}
hash = p->id % PMAXHASH;
p->faction = f;
p->nexthash = players[hash]->entries;
players[hash]->entries = p;
return p;
}
player *next_player(player * p)
{
if (p->nexthash)
return p->nexthash;
else {
unsigned int hash = p->id % PMAXHASH;
p = NULL;
while (++hash != PMAXHASH) {
if (players[hash]->entries != NULL) {
p = players[hash]->entries;
break;
}
}
return p;
}
}
player *get_player(unsigned int id)
{
unsigned int hash = id % PMAXHASH;
struct player *p = players[hash]->entries;
while (p && p->id != id)
p = p->nexthash;
return p;
}
player *get_players(void)
{
struct player *p = NULL;
unsigned int hash = 0;
while (p != NULL && hash != PMAXHASH) {
p = players[hash++]->entries;
}
return p;
}
void players_done(void)
{
int i;
for (i = 0; i != PMAXHASH; ++i) {
player *p = players[i]->entries;
players[i]->entries = p->nexthash;
free(p->name);
if (p->email)
free(p->email);
if (p->name)
free(p->name);
free(p);
}
}

View File

@ -1,43 +0,0 @@
/* vi: set ts=2:
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
| | Enno Rehling <enno@eressea.de>
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
+-------------------+ Stefan Reich <reich@halbling.de>
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#ifndef H_KRNL_PLAYER
#define H_KRNL_PLAYER
#ifdef __cplusplus
extern "C" {
#endif
struct faction;
typedef struct player {
unsigned int id;
char *name;
char *email;
char *address;
struct vacation {
int weeks;
char *email;
} *vacation;
const struct faction *faction;
struct player *nexthash; /* don't use! */
} player;
extern struct player *get_players(void);
extern struct player *get_player(unsigned int id);
extern struct player *make_player(const struct faction *f);
extern struct player *next_player(struct player *p);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -16,7 +16,7 @@ const char * keyword(keyword_t kwd)
if (!result[0]) {
strcpy(result, "keyword::");
}
strcpy(result+9, keywords[kwd]);
strcpy(result + 9, keywords[kwd]);
return result;
}

View File

@ -1090,8 +1090,7 @@ int contact_cmd(unit * u, order * ord)
unit *u2;
region *r = u->region;
init_tokens(ord);
skip_token();
init_order(ord);
u2 = getunitg(r, u->faction);
if (u2 != NULL) {
@ -1147,10 +1146,10 @@ int quit_cmd(unit * u, struct order *ord)
{
faction *f = u->faction;
const char *passwd;
init_tokens(ord);
skip_token(); /* skip keyword */
keyword_t kwd;
kwd = init_order(ord);
assert(kwd == K_PASSWORD);
passwd = getstrtoken();
if (checkpasswd(f, (const char *)passwd, false)) {
if (EnhancedQuit()) {
@ -1359,8 +1358,7 @@ void do_enter(struct region *r, bool is_final_attempt)
unit *ulast = NULL;
const char * s;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
p = findparam_ex(s, u->faction->locale);
id = getid();
@ -1540,8 +1538,7 @@ int ally_cmd(unit * u, struct order *ord)
int keyword, not_kw;
const char *s;
init_tokens(ord);
skip_token();
init_order(ord);
f = getfaction();
if (f == NULL || is_monsters(f)) {
@ -1707,8 +1704,7 @@ int prefix_cmd(unit * u, struct order *ord)
for (in = pnames; in->lang != lang; in = in->next);
}
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (!*s) {
@ -1761,8 +1757,7 @@ int display_cmd(unit * u, struct order *ord)
const char *str;
region *r = u->region;
init_tokens(ord);
skip_token();
init_order(ord);
str = getstrtoken();
switch (findparam_ex(str, u->faction->locale)) {
@ -1933,8 +1928,7 @@ int name_cmd(struct unit *u, struct order *ord)
bool foreign = false;
const char *str;
init_tokens(ord);
skip_token();
init_order(ord);
str = getstrtoken();
p = findparam_ex(str, u->faction->locale);
@ -2193,8 +2187,7 @@ int mail_cmd(unit * u, struct order *ord)
const char *s;
int n, cont;
init_tokens(ord);
skip_token(); /* skip the keyword */
init_order(ord);
s = getstrtoken();
/* Falls kein Parameter, ist das eine Einheitsnummer;
@ -2357,8 +2350,7 @@ int mail_cmd(unit * u, struct order *ord)
int banner_cmd(unit * u, struct order *ord)
{
init_tokens(ord);
skip_token();
init_order(ord);
free(u->faction->banner);
u->faction->banner = _strdup(getstrtoken());
@ -2372,8 +2364,7 @@ int email_cmd(unit * u, struct order *ord)
{
const char *s;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (!s[0]) {
@ -2399,8 +2390,7 @@ int password_cmd(unit * u, struct order *ord)
const char *s;
bool pwok = true;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (!s || !*s) {
@ -2438,8 +2428,7 @@ int send_cmd(unit * u, struct order *ord)
const char *s;
int option;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
option = findoption(s, u->faction->locale);
@ -2778,9 +2767,10 @@ int promotion_cmd(unit * u, struct order *ord)
int group_cmd(unit * u, struct order *ord)
{
const char *s;
keyword_t kwd;
init_tokens(ord);
skip_token();
kwd = init_order(ord);
assert(kwd == K_GROUP);
s = getstrtoken();
join_group(u, s);
@ -2791,8 +2781,7 @@ int origin_cmd(unit * u, struct order *ord)
{
short px, py;
init_tokens(ord);
skip_token();
init_order(ord);
px = (short)getint();
py = (short)getint();
@ -2804,8 +2793,7 @@ int origin_cmd(unit * u, struct order *ord)
int guard_off_cmd(unit * u, struct order *ord)
{
assert(getkeyword(ord) == K_GUARD);
init_tokens(ord);
skip_token();
init_order(ord);
if (getparam(u->faction->locale) == P_NOT) {
setguard(u, GUARD_NONE);
@ -2818,8 +2806,7 @@ int reshow_cmd(unit * u, struct order *ord)
const char *s;
param_t p = NOPARAM;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
if (isparam(s, u->faction->locale, P_ANY)) {
@ -2835,8 +2822,7 @@ int status_cmd(unit * u, struct order *ord)
{
const char *param;
init_tokens(ord);
skip_token();
init_order(ord);
param = getstrtoken();
switch (findparam(param, u->faction->locale)) {
@ -2867,7 +2853,7 @@ int status_cmd(unit * u, struct order *ord)
}
break;
default:
if (param[0]) {
if (param && param[0]) {
add_message(&u->faction->msgs,
msg_feedback(u, ord, "unknown_status", ""));
}
@ -2884,8 +2870,7 @@ int combatspell_cmd(unit * u, struct order *ord)
int level = 0;
spell *sp = 0;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
@ -2970,8 +2955,7 @@ int guard_on_cmd(unit * u, struct order *ord)
{
assert(getkeyword(ord) == K_GUARD);
init_tokens(ord);
skip_token();
init_order(ord);
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
if (getparam(u->faction->locale) == P_NOT)
@ -3132,8 +3116,7 @@ void restack_units(void)
int id;
unit *v;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
p = findparam(s, u->faction->locale);
id = getid();
@ -3208,8 +3191,7 @@ int renumber_cmd(unit * u, order * ord)
int i;
faction *f = u->faction;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
switch (findparam_ex(s, u->faction->locale)) {
@ -3627,8 +3609,7 @@ void new_units(void)
}
continue;
}
init_tokens(makeord);
skip_token();
init_order(makeord);
alias = getid();
token = getstrtoken();
@ -3943,8 +3924,7 @@ void defaultorders(void)
if (getkeyword(ord) == K_DEFAULT) {
char lbuf[8192];
order *new_order;
init_tokens(ord);
skip_token(); /* skip the keyword */
init_order(ord);
strcpy(lbuf, getstrtoken());
new_order = parse_order(lbuf, u->faction->locale);
*ordp = ord->next;
@ -4056,8 +4036,7 @@ int use_cmd(unit * u, struct order *ord)
int n, err = ENOITEM;
const item_type *itype;
init_tokens(ord);
skip_token();
init_order(ord);
t = getstrtoken();
n = atoi((const char *)t);
@ -4106,8 +4085,7 @@ int pay_cmd(unit * u, struct order *ord)
}
else {
param_t p;
init_tokens(ord);
skip_token();
init_order(ord);
p = getparam(u->faction->locale);
if (p == P_NOT) {
unit *owner = building_owner(u->building);
@ -4129,16 +4107,16 @@ static int reserve_i(unit * u, struct order *ord, int flags)
const resource_type *rtype;
const char *s;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
count = atoip((const char *)s);
count = s ? atoip(s) : 0;
para = findparam(s, u->faction->locale);
if (count == 0 && para == P_EACH) {
count = getint() * u->number;
}
rtype = findresourcetype(getstrtoken(), u->faction->locale);
s = getstrtoken();
rtype = s ? findresourcetype(s, u->faction->locale) : 0;
if (rtype == NULL)
return 0;
@ -4171,8 +4149,7 @@ int claim_cmd(unit * u, struct order *ord)
int n;
const item_type *itype;
init_tokens(ord);
skip_token();
init_order(ord);
t = getstrtoken();
n = atoi((const char *)t);
@ -4438,8 +4415,7 @@ int siege_cmd(unit * u, order * ord)
resource_type *rt_catapultammo = NULL;
resource_type *rt_catapult = NULL;
init_tokens(ord);
skip_token();
init_order(ord);
b = getbuilding(r);
if (!b) {

View File

@ -243,6 +243,29 @@ static void test_reserve_cmd(CuTest *tc) {
test_cleanup();
}
static void test_new_units(CuTest *tc) {
unit *u;
faction *f;
region *r;
order *ord;
const struct locale *loc;
test_cleanup();
test_create_world();
f = test_create_faction(rc_find("human"));
r = findregion(0, 0);
assert(r && f);
u = test_create_unit(f, r);
assert(u && !u->next);
loc = get_locale("de");
assert(loc);
ord = create_order(K_MAKETEMP, loc, "hurr");
assert(ord);
u->orders = ord;
new_units();
CuAssertPtrNotNull(tc, u->next);
test_cleanup();
}
static void test_reserve_self(CuTest *tc) {
unit *u1, *u2;
faction *f;
@ -286,6 +309,7 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_unit_limit);
SUITE_ADD_TEST(suite, test_reserve_self);
SUITE_ADD_TEST(suite, test_reserve_cmd);
SUITE_ADD_TEST(suite, test_new_units);
SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit);
return suite;
}

View File

@ -92,9 +92,9 @@ skill_t get_skill(const char *s, const struct locale * lang)
{
skill_t result = NOSKILL;
char buffer[64];
char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), s);
if (str) {
if (s) {
char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s);
int i;
const void * match;
void **tokens = get_translations(lang, UT_SKILLS);

View File

@ -120,8 +120,7 @@ int spy_cmd(unit * u, struct order *ord)
double spychance, observechance;
region *r = u->region;
init_tokens(ord);
skip_token();
init_order(ord);
target = getunit(r, u->faction);
if (!target) {
@ -213,8 +212,7 @@ int setstealth_cmd(unit * u, struct order *ord)
int level, rule;
const race *trace;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
/* Tarne ohne Parameter: Setzt maximale Tarnung */
@ -298,7 +296,7 @@ int setstealth_cmd(unit * u, struct order *ord)
}
if (rule&2) {
if (get_keyword(s, u->faction->locale) == K_NUMBER) {
const char *s2 = (const char *)getstrtoken();
const char *s2 = getstrtoken();
int nr = -1;
if (s2) {
@ -484,8 +482,7 @@ int sabotage_cmd(unit * u, struct order *ord)
region *r = u->region;
int skdiff;
init_tokens(ord);
skip_token();
init_order(ord);
s = getstrtoken();
i = findparam(s, u->faction->locale);

View File

@ -315,8 +315,7 @@ int teach_cmd(unit * u, struct order *ord)
count = 0;
init_tokens(ord);
skip_token();
init_order(ord);
#if TEACH_ALL
if (getparam(u->faction->locale) == P_ANY) {
@ -338,8 +337,7 @@ int teach_cmd(unit * u, struct order *ord)
#endif
if (getkeyword(student->thisorder) == K_STUDY) {
/* Input ist nun von student->thisorder !! */
init_tokens(student->thisorder);
skip_token();
init_order(student->thisorder);
sk = getskill(student->faction->locale);
if (sk != NOSKILL && teachskill[0] != NOSKILL) {
for (i = 0; teachskill[i] != NOSKILL; ++i)
@ -369,8 +367,7 @@ int teach_cmd(unit * u, struct order *ord)
#endif
if (getkeyword(student->thisorder) == K_STUDY) {
/* Input ist nun von student->thisorder !! */
init_tokens(student->thisorder);
skip_token();
init_order(student->thisorder);
sk = getskill(student->faction->locale);
if (sk != NOSKILL
&& eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student,
@ -390,8 +387,7 @@ int teach_cmd(unit * u, struct order *ord)
order *new_order;
zOrder[0] = '\0';
init_tokens(ord);
skip_token();
init_order(ord);
while (!parser_end()) {
unit *u2 = getunit(r, u->faction);
@ -406,8 +402,7 @@ int teach_cmd(unit * u, struct order *ord)
const char *token;
/* Finde den string, der den Fehler verursacht hat */
parser_pushstate();
init_tokens(ord);
skip_token();
init_order(ord);
for (j = 0; j != count - 1; ++j) {
/* skip over the first 'count' units */
@ -450,8 +445,7 @@ int teach_cmd(unit * u, struct order *ord)
/* Input ist nun von u2->thisorder !! */
parser_pushstate();
init_tokens(u2->thisorder);
skip_token();
init_order(u2->thisorder);
sk = getskill(u2->faction->locale);
parser_popstate();
@ -551,8 +545,7 @@ int learn_cmd(unit * u, order * ord)
return 0;
}
init_tokens(ord);
skip_token();
init_order(ord);
sk = getskill(u->faction->locale);
if (sk < 0) {

View File

@ -1,7 +1,7 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -25,94 +25,95 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
int atoi36(const char *str)
{
/* cannot use strtol, because invalid strings will cause crash */
const unsigned char *s = (const unsigned char *)str;
int i = 0, sign = 1;
assert(s);
if (!(*s))
return 0;
/* cannot use strtol, because invalid strings will cause crash */
const unsigned char *s = (const unsigned char *)str;
int i = 0, sign = 1;
assert(s);
if (!(*s))
return 0;
while (isxspace(*(unsigned char *)s))
++s;
if (*s == '-') {
sign = -1;
++s;
}
while (isalnum(*(unsigned char *)s)) {
if (isupper(*(unsigned char *)s))
i = i * 36 + (*s) - 'A' + 10;
else if (islower(*(unsigned char *)s))
i = i * 36 + (*s) - 'a' + 10;
else if (isdigit(*(unsigned char *)s))
i = i * 36 + (*s) - '0';
else
break;
++s;
}
if (i < 0)
return 0;
return i * sign;
while (isxspace(*(unsigned char *)s))
++s;
if (*s == '-') {
sign = -1;
++s;
}
while (isalnum(*(unsigned char *)s)) {
if (isupper(*(unsigned char *)s))
i = i * 36 + (*s) - 'A' + 10;
else if (islower(*(unsigned char *)s))
i = i * 36 + (*s) - 'a' + 10;
else if (isdigit(*(unsigned char *)s))
i = i * 36 + (*s) - '0';
else
break;
++s;
}
if (i < 0)
return 0;
return i * sign;
}
const char *itoab(int i, int base)
{
static char **as = NULL; /* STATIC_RETURN: used for return, not across calls */
char *s, *dst;
static int index = 0; /* STATIC_XCALL: used across calls */
int neg = 0;
static char **as = NULL; /* STATIC_RETURN: used for return, not across calls */
char *s, *dst;
static int index = 0; /* STATIC_XCALL: used across calls */
int neg = 0;
if (!as) {
int j;
char *x = (char *)calloc(sizeof(char), 8 * 4); /* STATIC_LEAK: malloc in static variable */
as = (char **)calloc(sizeof(char *), 4);
for (j = 0; j != 4; ++j)
as[j] = x + j * 8;
}
s = as[index];
index = (index + 1) & 3; /* quick for % 4 */
dst = s + 7;
(*dst--) = 0;
if (i != 0) {
if (i < 0) {
i = -i;
neg = 1;
if (!as) {
int j;
char *x = (char *)calloc(sizeof(char), 8 * 4); /* STATIC_LEAK: malloc in static variable */
as = (char **)calloc(sizeof(char *), 4);
for (j = 0; j != 4; ++j)
as[j] = x + j * 8;
}
while (i) {
int x = i % base;
i = i / base;
if (x < 10)
*(dst--) = (char)('0' + x);
else if ('a' + x - 10 == 'l')
*(dst--) = 'L';
else
*(dst--) = (char)('a' + (x - 10));
s = as[index];
index = (index + 1) & 3; /* quick for % 4 */
dst = s + 7;
(*dst--) = 0;
if (i != 0) {
if (i < 0) {
i = -i;
neg = 1;
}
while (i) {
int x = i % base;
i = i / base;
if (x < 10)
*(dst--) = (char)('0' + x);
else if ('a' + x - 10 == 'l')
*(dst--) = 'L';
else
*(dst--) = (char)('a' + (x - 10));
}
if (neg)
*(dst) = '-';
else
++dst;
}
if (neg)
*(dst) = '-';
else
++dst;
} else
*dst = '0';
*dst = '0';
return dst;
return dst;
}
const char *itoa36(int i)
{
return itoab(i, 36);
return itoab(i, 36);
}
const char *itoa10(int i)
{
return itoab(i, 10);
return itoab(i, 10);
}
int i10toi36(int i)
{
int r = 0;
while (i) {
r = r * 36 + i % 10;
i = i / 10;
}
return r;
int r = 0;
while (i) {
r = r * 36 + i % 10;
i = i / 10;
}
return r;
}

View File

@ -81,8 +81,11 @@ void parser_popstate(void)
bool parser_end(void)
{
eatwhitespace_c(&states->current_token);
return *states->current_token == 0;
if (states->current_token) {
eatwhitespace_c(&states->current_token);
return *states->current_token == 0;
}
return true;
}
void skip_token(void)
@ -132,9 +135,13 @@ const char *parse_token(const char **str)
bool escape = false;
const char *ctoken = *str;
assert(ctoken);
if (!ctoken) {
return 0;
}
eatwhitespace_c(&ctoken);
if (!*ctoken) {
return 0;
}
while (*ctoken && cursor - lbuf < MAXTOKENSIZE - 1) {
ucs4_t ucs;
size_t len;

View File

@ -1,7 +1,7 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -29,235 +29,247 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <assert.h>
typedef struct tref {
struct tref *nexthash;
ucs4_t ucs;
void *node;
struct tref *nexthash;
ucs4_t ucs;
void *node;
} tref;
#define LEAF 1 /* leaf node for a word. always matches */
#define SHARED 2 /* at least two words share the node */
typedef struct tnode {
struct tref *next[NODEHASHSIZE];
unsigned char flags;
variant id;
struct tref *next[NODEHASHSIZE];
unsigned char flags;
variant id;
} tnode;
char * transliterate(char * out, size_t size, const char * in)
{
const char *src = in;
char *dst = out;
const char *src = in;
char *dst = out;
--size; /* need space for a final 0-byte */
while (*src && size) {
size_t len;
const char * p = src;
while ((p+size>src) && *src && (~*src & 0x80)) {
*dst++ = (char)tolower(*src++);
}
len = src-p;
size -= len;
while (size>0 && *src && (*src & 0x80)) {
unsigned int advance = 2;
if (src[0]=='\xc3') {
if (src[1]=='\xa4' || src[1]=='\x84') {
memcpy(dst, "ae", 2);
} else if (src[1]=='\xb6' || src[1]=='\x96') {
memcpy(dst, "oe", 2);
} else if (src[1]=='\xbc' || src[1]=='\x9c') {
memcpy(dst, "ue", 2);
} else if (src[1]=='\x9f') {
memcpy(dst, "ss", 2);
} else {
advance = 0;
assert(in && size > 0);
--size; /* need space for a final 0-byte */
while (*src && size) {
size_t len;
const char * p = src;
while ((p + size > src) && *src && (~*src & 0x80)) {
*dst++ = (char)tolower(*src++);
}
} else if (src[0]=='\xe1') {
if (src[1]=='\xba' && src[2]=='\x9e') {
memcpy(dst, "ss", 2);
++src;
} else {
advance = 0;
}
} else {
advance = 0;
}
len = src - p;
size -= len;
while (size > 0 && *src && (*src & 0x80)) {
unsigned int advance = 2;
if (src[0] == '\xc3') {
if (src[1] == '\xa4' || src[1] == '\x84') {
memcpy(dst, "ae", 2);
}
else if (src[1] == '\xb6' || src[1] == '\x96') {
memcpy(dst, "oe", 2);
}
else if (src[1] == '\xbc' || src[1] == '\x9c') {
memcpy(dst, "ue", 2);
}
else if (src[1] == '\x9f') {
memcpy(dst, "ss", 2);
}
else {
advance = 0;
}
}
else if (src[0] == '\xe1') {
if (src[1] == '\xba' && src[2] == '\x9e') {
memcpy(dst, "ss", 2);
++src;
}
else {
advance = 0;
}
}
else {
advance = 0;
}
if (advance && advance<=size) {
src+=advance;
dst+=advance;
size-=advance;
} else {
ucs4_t ucs;
unicode_utf8_to_ucs4(&ucs, src, &len);
src+=len;
*dst++='?';
--size;
}
if (advance && advance <= size) {
src += advance;
dst += advance;
size -= advance;
}
else {
ucs4_t ucs;
unicode_utf8_to_ucs4(&ucs, src, &len);
src += len;
*dst++ = '?';
--size;
}
}
}
}
*dst = 0;
return *src ? 0 : out;
*dst = 0;
return *src ? 0 : out;
}
void addtoken(void ** root, const char *str, variant id)
{
tnode * tk;
static const struct replace { /* STATIC_CONST: constant value */
ucs4_t ucs;
const char str[3];
} replace[] = {
/* match lower-case (!) umlauts and others to transcriptions */
{
228, "AE"}, /* auml */
{
246, "OE"}, /* ouml */
{
252, "UE"}, /* uuml */
{
223, "SS"}, /* szlig */
{
230, "AE"}, /* norsk */
{
248, "OE"}, /* norsk */
{
229, "AA"}, /* norsk */
{
0, ""}
};
tnode * tk;
static const struct replace { /* STATIC_CONST: constant value */
ucs4_t ucs;
const char str[3];
} replace[] = {
/* match lower-case (!) umlauts and others to transcriptions */
{
228, "AE" }, /* auml */
{
246, "OE" }, /* ouml */
{
252, "UE" }, /* uuml */
{
223, "SS" }, /* szlig */
{
230, "AE" }, /* norsk */
{
248, "OE" }, /* norsk */
{
229, "AA" }, /* norsk */
{
0, "" }
};
assert(root && str);
if (!*root) {
tk = *root = calloc(1, sizeof(tnode));
} else {
tk = *root;
}
assert(tk && tk==*root);
if (!*str) {
tk->id = id;
tk->flags |= LEAF;
} else {
tref *next;
int ret, index, i = 0;
ucs4_t ucs, lcs;
size_t len;
assert(root && str);
if (!*root) {
tk = *root = calloc(1, sizeof(tnode));
}
else {
tk = *root;
}
assert(tk && tk == *root);
if (!*str) {
tk->id = id;
tk->flags |= LEAF;
}
else {
tref *next;
int ret, index, i = 0;
ucs4_t ucs, lcs;
size_t len;
ret = unicode_utf8_to_ucs4(&ucs, str, &len);
assert(ret == 0 || !"invalid utf8 string");
lcs = ucs;
ret = unicode_utf8_to_ucs4(&ucs, str, &len);
assert(ret == 0 || !"invalid utf8 string");
lcs = ucs;
#if NODEHASHSIZE == 8
index = ucs & 7;
index = ucs & 7;
#else
index = ucs % NODEHASHSIZE;
index = ucs % NODEHASHSIZE;
#endif
assert(index >= 0);
next = tk->next[index];
if (!(tk->flags & LEAF))
tk->id = id;
while (next && next->ucs != ucs)
next = next->nexthash;
if (!next) {
tref *ref;
tnode *node = (tnode *)calloc(1, sizeof(tnode));
assert(index >= 0);
next = tk->next[index];
if (!(tk->flags & LEAF))
tk->id = id;
while (next && next->ucs != ucs)
next = next->nexthash;
if (!next) {
tref *ref;
tnode *node = (tnode *)calloc(1, sizeof(tnode));
if (ucs < 'a' || ucs > 'z') {
lcs = towlower((wint_t) ucs);
}
if (ucs == lcs) {
ucs = towupper((wint_t) ucs);
}
if (ucs < 'a' || ucs > 'z') {
lcs = towlower((wint_t)ucs);
}
if (ucs == lcs) {
ucs = towupper((wint_t)ucs);
}
ref = (tref *)malloc(sizeof(tref));
ref->ucs = ucs;
ref->node = node;
ref->nexthash = tk->next[index];
tk->next[index] = ref;
ref = (tref *)malloc(sizeof(tref));
ref->ucs = ucs;
ref->node = node;
ref->nexthash = tk->next[index];
tk->next[index] = ref;
/* try lower/upper casing the character, and try again */
if (ucs != lcs) {
/* try lower/upper casing the character, and try again */
if (ucs != lcs) {
#if NODEHASHSIZE == 8
index = lcs & 7;
index = lcs & 7;
#else
index = lcs % NODEHASHSIZE;
index = lcs % NODEHASHSIZE;
#endif
ref = (tref *)malloc(sizeof(tref));
ref->ucs = lcs;
ref->node = node;
ref->nexthash = tk->next[index];
tk->next[index] = ref;
}
next = ref;
} else {
tnode * next_node = (tnode *)next->node;
next_node->flags |= SHARED;
if ((next_node->flags & LEAF) == 0)
next_node->id.v = NULL; /* why? */
ref = (tref *)malloc(sizeof(tref));
ref->ucs = lcs;
ref->node = node;
ref->nexthash = tk->next[index];
tk->next[index] = ref;
}
next = ref;
}
else {
tnode * next_node = (tnode *)next->node;
next_node->flags |= SHARED;
if ((next_node->flags & LEAF) == 0)
next_node->id.v = NULL; /* why? */
}
addtoken(&next->node, str + len, id);
while (replace[i].str[0]) {
if (lcs == replace[i].ucs) {
char zText[1024];
memcpy(zText, replace[i].str, 3);
strcpy(zText + 2, (const char *)str + len);
addtoken(root, zText, id);
break;
}
++i;
}
}
addtoken(&next->node, str + len, id);
while (replace[i].str[0]) {
if (lcs == replace[i].ucs) {
char zText[1024];
memcpy(zText, replace[i].str, 3);
strcpy(zText + 2, (const char *)str + len);
addtoken(root, zText, id);
break;
}
++i;
}
}
}
void freetokens(void * root)
{
tnode * node = (tnode *)root;
int i;
for (i=0;node && i!=NODEHASHSIZE;++i) {
if (node->next[i]) {
freetokens(node->next[i]->node);
tnode * node = (tnode *)root;
int i;
for (i = 0; node && i != NODEHASHSIZE; ++i) {
if (node->next[i]) {
freetokens(node->next[i]->node);
}
}
}
free(node);
free(node);
}
int findtoken(const void * root, const char *key, variant * result)
{
const char * str = key;
const tnode * tk = (const tnode *)root;
const char * str = key;
const tnode * tk = (const tnode *)root;
if (!tk || !str || *str == 0) {
return E_TOK_NOMATCH;
}
do {
int index;
const tref *ref;
ucs4_t ucs;
size_t len;
int ret = unicode_utf8_to_ucs4(&ucs, str, &len);
if (ret != 0) {
/* encoding is broken. youch */
log_error("findtoken | encoding error in '%s'\n", key);
return E_TOK_NOMATCH;
if (!tk || !str || *str == 0) {
return E_TOK_NOMATCH;
}
do {
int index;
const tref *ref;
ucs4_t ucs;
size_t len;
int ret = unicode_utf8_to_ucs4(&ucs, str, &len);
if (ret != 0) {
/* encoding is broken. youch */
log_error("findtoken | encoding error in '%s'\n", key);
return E_TOK_NOMATCH;
}
#if NODEHASHSIZE == 8
index = ucs & 7;
index = ucs & 7;
#else
index = ucs % NODEHASHSIZE;
index = ucs % NODEHASHSIZE;
#endif
ref = tk->next[index];
while (ref && ref->ucs != ucs)
ref = ref->nexthash;
str += len;
if (!ref) {
log_info("findtoken | token not found '%s'\n", key);
return E_TOK_NOMATCH;
ref = tk->next[index];
while (ref && ref->ucs != ucs)
ref = ref->nexthash;
str += len;
if (!ref) {
log_info("findtoken | token not found '%s'\n", key);
return E_TOK_NOMATCH;
}
tk = ref->node;
} while (*str);
if (tk) {
*result = tk->id;
return E_TOK_SUCCESS;
}
tk = ref->node;
} while (*str);
if (tk) {
*result = tk->id;
return E_TOK_SUCCESS;
}
log_info("findtoken | token not found '%s'\n", key);
return E_TOK_NOMATCH;
log_info("findtoken | token not found '%s'\n", key);
return E_TOK_NOMATCH;
}