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

View File

@ -34,20 +34,20 @@ static int
use_studypotion(struct unit *u, const struct item_type *itype, int amount, use_studypotion(struct unit *u, const struct item_type *itype, int amount,
struct order *ord) struct order *ord)
{ {
if (getkeyword(u->thisorder) == K_STUDY) { if (init_order(u->thisorder) == K_STUDY) {
skill_t sk; skill_t sk;
skill *sv; skill *sv;
init_tokens(u->thisorder);
skip_token();
sk = get_skill(getstrtoken(), u->faction->locale); sk = get_skill(getstrtoken(), u->faction->locale);
sv = unit_skill(u, sk); sv = unit_skill(u, sk);
if (sv && sv->level > 2) { if (sv && sv->level > 2) {
/* TODO: message */ /* TODO: message */
} else if (study_cost(u, sk) > 0) { }
else if (study_cost(u, sk) > 0) {
/* TODO: message */ /* TODO: message */
} else { }
else {
attrib *a = a_find(u->attribs, &at_learning); attrib *a = a_find(u->attribs, &at_learning);
teaching_info *teach; teaching_info *teach;
if (a == NULL) { if (a == NULL) {

View File

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

View File

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

View File

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

View File

@ -146,8 +146,7 @@ int destroy_cmd(unit * u, struct order *ord)
if (u->number < 1) if (u->number < 1)
return 0; return 0;
init_tokens(ord); init_order(ord);
skip_token();
s = getstrtoken(); s = getstrtoken();
if (findparam(s, u->faction->locale) == P_ROAD) { 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) void do_command(const void *keys, struct unit *u, struct order *ord)
{ {
init_tokens(ord); init_order(ord);
skip_token();
if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) { if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) {
char cmd[ORDERSIZE]; char cmd[ORDERSIZE];
get_command(ord, cmd, sizeof(cmd)); get_command(ord, cmd, sizeof(cmd));

View File

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

View File

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

View File

@ -1,11 +1,39 @@
#include <platform.h> #include <platform.h>
#include <kernel/types.h> #include <kernel/types.h>
#include <kernel/race.h>
#include <kernel/config.h> #include <kernel/config.h>
#include <util/language.h>
#include "faction.h" #include "faction.h"
#include <CuTest.h> #include <CuTest.h>
#include <stdio.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; faction *f;
CuAssertPtrEquals(tc, NULL, get_monsters()); CuAssertPtrEquals(tc, NULL, get_monsters());
f = get_or_create_monsters(); f = get_or_create_monsters();
@ -22,6 +50,7 @@ void test_get_monsters(CuTest *tc) {
CuSuite *get_faction_suite(void) CuSuite *get_faction_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_addfaction);
SUITE_ADD_TEST(suite, test_get_monsters); SUITE_ADD_TEST(suite, test_get_monsters);
return suite; return suite;
} }

View File

@ -74,7 +74,8 @@ static int res_changeperson(unit * u, const resource_type * rtype, int delta)
assert(rtype != NULL || !"not implemented"); assert(rtype != NULL || !"not implemented");
if (u->number + delta >= 0) { if (u->number + delta >= 0) {
scale_number(u, u->number + delta); scale_number(u, u->number + delta);
} else { }
else {
scale_number(u, 0); scale_number(u, 0);
} }
return u->number; return u->number;
@ -110,14 +111,16 @@ static int res_changeitem(unit * u, const resource_type * rtype, int delta)
--reduce; --reduce;
scale_number(u, u->number + reduce); scale_number(u, u->number + reduce);
num = u->number * GOLEM_STONE; num = u->number * GOLEM_STONE;
} else if (rtype == get_resourcetype(R_IRON) }
else if (rtype == get_resourcetype(R_IRON)
&& u_race(u) == get_race(RC_IRONGOLEM) && delta <= 0) { && u_race(u) == get_race(RC_IRONGOLEM) && delta <= 0) {
int reduce = delta / GOLEM_IRON; int reduce = delta / GOLEM_IRON;
if (delta % GOLEM_IRON != 0) if (delta % GOLEM_IRON != 0)
--reduce; --reduce;
scale_number(u, u->number + reduce); scale_number(u, u->number + reduce);
num = u->number * GOLEM_IRON; num = u->number * GOLEM_IRON;
} else { }
else {
const item_type *itype = resource2item(rtype); const item_type *itype = resource2item(rtype);
item *i; item *i;
assert(itype != NULL); assert(itype != NULL);
@ -410,7 +413,8 @@ item *i_add(item ** pi, item * i)
(*pi)->number += i->number; (*pi)->number += i->number;
assert((*pi)->number >= 0); assert((*pi)->number >= 0);
i_free(i); i_free(i);
} else { }
else {
i->next = *pi; i->next = *pi;
*pi = i; *pi = i;
} }
@ -432,7 +436,8 @@ void i_merge(item ** pi, item ** si)
(*pi)->number += i->number; (*pi)->number += i->number;
assert((*pi)->number >= 0); assert((*pi)->number >= 0);
i_free(i_remove(&i, i)); i_free(i_remove(&i, i));
} else { }
else {
itmp = i->next; itmp = i->next;
i->next = *pi; i->next = *pi;
*pi = i; *pi = i;
@ -458,7 +463,8 @@ item *i_change(item ** pi, const item_type * itype, int delta)
i = i_new(itype, delta); i = i_new(itype, delta);
i->next = *pi; i->next = *pi;
*pi = i; *pi = i;
} else { }
else {
item *i = *pi; item *i = *pi;
i->number += delta; i->number += delta;
if (i->number < 0) { if (i->number < 0) {
@ -496,7 +502,8 @@ void i_free(item * i)
{ {
if (icache_size >= ICACHE_MAX) { if (icache_size >= ICACHE_MAX) {
free(i); free(i);
} else { }
else {
i->next = icache; i->next = icache;
icache = i; icache = i;
++icache_size; ++icache_size;
@ -521,7 +528,8 @@ item *i_new(const item_type * itype, int size)
i = icache; i = icache;
icache = i->next; icache = i->next;
--icache_size; --icache_size;
} else { }
else {
i = malloc(sizeof(item)); i = malloc(sizeof(item));
} }
assert(itype); assert(itype);
@ -620,7 +628,8 @@ int set_item(unit * u, const item_type *itype, int value)
i = *i_find(&u->items, itype); i = *i_find(&u->items, itype);
if (!i) { if (!i) {
i = i_add(&u->items, i_new(itype, value)); i = i_add(&u->items, i_new(itype, value));
} else { }
else {
i->number = value; i->number = value;
assert(i->number >= 0); assert(i->number >= 0);
} }
@ -778,7 +787,8 @@ use_warmthpotion(struct unit *u, const struct item_type *itype, int amount,
{ {
if (u->faction->race == get_race(RC_INSECT)) { if (u->faction->race == get_race(RC_INSECT)) {
fset(u, UFL_WARMTH); fset(u, UFL_WARMTH);
} else { }
else {
/* nur fuer insekten: */ /* nur fuer insekten: */
cmistake(u, ord, 163, MSG_EVENT); cmistake(u, ord, 163, MSG_EVENT);
return ECUSTOM; return ECUSTOM;
@ -820,7 +830,8 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount,
{ {
if (u_race(u) == get_race(RC_DAEMON)) { if (u_race(u) == get_race(RC_DAEMON)) {
change_effect(u, itype->rtype->ptype, 100 * amount); change_effect(u, itype->rtype->ptype, 100 * amount);
} else { }
else {
const race *irace = u_irace(u); const race *irace = u_irace(u);
if (irace == u_race(u)) { if (irace == u_race(u)) {
static const race *rcfailure; static const race *rcfailure;
@ -985,7 +996,8 @@ int set_money(unit * u, int v)
if (v) { if (v) {
(*ip)->number = v; (*ip)->number = v;
assert((*ip)->number >= 0); assert((*ip)->number >= 0);
} else { }
else {
i_remove(ip, *ip); i_remove(ip, *ip);
} }
} }
@ -1009,7 +1021,8 @@ int change_money(unit * u, int v)
i->number += v; i->number += v;
assert(i->number >= 0); assert(i->number >= 0);
return i->number; return i->number;
} else { }
else {
i_free(i_remove(ip, *ip)); i_free(i_remove(ip, *ip));
} }
} }
@ -1055,7 +1068,8 @@ const resource_type *findresourcetype(const char *name, const struct locale *lan
cb_get_kv(match, (void*)&rtype, sizeof(rtype)); cb_get_kv(match, (void*)&rtype, sizeof(rtype));
return rtype; return rtype;
} }
} else { }
else {
log_debug("findresourcetype: transliterate failed for '%s'\n", name); log_debug("findresourcetype: transliterate failed for '%s'\n", name);
} }
return 0; return 0;
@ -1095,6 +1109,7 @@ const item_type *finditemtype(const char *name, const struct locale *lang)
critbit_tree * cb = inames + i; critbit_tree * cb = inames + i;
char buffer[128]; char buffer[128];
assert(name);
if (transliterate(buffer, sizeof(buffer), name)) { if (transliterate(buffer, sizeof(buffer), name)) {
const void * match; const void * match;
if (!cb->root) { if (!cb->root) {
@ -1106,7 +1121,8 @@ const item_type *finditemtype(const char *name, const struct locale *lang)
cb_get_kv(match, (void*)&itype, sizeof(itype)); cb_get_kv(match, (void*)&itype, sizeof(itype));
return itype; return itype;
} }
} else { }
else {
log_debug("finditemtype: transliterate failed for '%s'\n", name); log_debug("finditemtype: transliterate failed for '%s'\n", name);
} }
return 0; return 0;

View File

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

View File

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

View File

@ -256,7 +256,7 @@ static order *create_order_i(keyword_t kwd, const char *sptr, int persistent,
order *ord = NULL; order *ord = NULL;
int lindex; 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)); log_error("trying to create an order for disabled keyword %s.", keyword(kwd));
return NULL; return NULL;
} }
@ -295,6 +295,7 @@ order *create_order(keyword_t kwd, const struct locale * lang,
const char *params, ...) const char *params, ...)
{ {
char zBuffer[DISPLAYSIZE]; char zBuffer[DISPLAYSIZE];
assert(lang);
if (params) { if (params) {
char *bufp = zBuffer; char *bufp = zBuffer;
int bytes; int bytes;
@ -356,17 +357,19 @@ order *parse_order(const char *s, const struct locale * lang)
keyword_t kwd; keyword_t kwd;
const char *sptr; const char *sptr;
int persistent = 0; int persistent = 0;
const char * p;
while (*s == '@') { while (*s == '@') {
persistent = 1; persistent = 1;
++s; ++s;
} }
sptr = 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) { if (kwd == K_MAKE) {
const char *s, *sp = sptr; const char *s, *sp = sptr;
s = parse_token(&sp); s = parse_token(&sp);
if (isparam(s, lang, P_TEMP)) { if (s && isparam(s, lang, P_TEMP)) {
kwd = K_MAKETEMP; kwd = K_MAKETEMP;
sptr = sp; sptr = sp;
} }
@ -563,8 +566,11 @@ static char *getcommand(const order * ord)
return _strdup(get_command(ord, cmd, sizeof(cmd))); 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); 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_repeated(const order * ord);
bool is_long(const order * ord); bool is_long(const order * ord);
extern char *write_order(const order * ord, char *buffer, size_t size); char *write_order(const order * ord, char *buffer, size_t size);
extern void init_tokens(const struct order *ord); /* initialize token parsing */ keyword_t init_order(const struct order *ord);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -17,9 +17,9 @@ static void test_create_order(CuTest *tc) {
ord = create_order(K_MOVE, lang, "NORTH"); ord = create_order(K_MOVE, lang, "NORTH");
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); 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()); CuAssertStrEquals(tc, "NORTH", getstrtoken());
free_order(ord); free_order(ord);
} }
@ -33,9 +33,9 @@ static void test_parse_order(CuTest *tc) {
ord = parse_order("MOVE NORTH", lang); ord = parse_order("MOVE NORTH", lang);
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord)); CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd))); 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()); CuAssertStrEquals(tc, "NORTH", getstrtoken());
free_order(ord); free_order(ord);
} }
@ -51,9 +51,9 @@ static void test_parse_make(CuTest *tc) {
ord = parse_order("M hurrdurr", lang); ord = parse_order("M hurrdurr", lang);
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MAKE, getkeyword(ord)); CuAssertIntEquals(tc, K_MAKE, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MAKE hurrdurr", get_command(ord, cmd, sizeof(cmd))); 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()); CuAssertStrEquals(tc, "hurrdurr", getstrtoken());
free_order(ord); free_order(ord);
} }
@ -71,9 +71,9 @@ static void test_parse_make_temp(CuTest *tc) {
ord = parse_order("M T herp", lang); ord = parse_order("M T herp", lang);
CuAssertPtrNotNull(tc, ord); CuAssertPtrNotNull(tc, ord);
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord)); CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
init_tokens(ord);
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd))); 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()); CuAssertStrEquals(tc, "herp", getstrtoken());
free_order(ord); free_order(ord);
} }
@ -90,14 +90,43 @@ static void test_parse_maketemp(CuTest *tc) {
ord = parse_order("MAKET herp", lang); ord = parse_order("MAKET herp", lang);
CuAssertPtrNotNull(tc, ord); 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 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()); CuAssertStrEquals(tc, "herp", getstrtoken());
free_order(ord); 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 *get_order_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); 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);
SUITE_ADD_TEST(suite, test_parse_make_temp); SUITE_ADD_TEST(suite, test_parse_make_temp);
SUITE_ADD_TEST(suite, test_parse_maketemp); 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; 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

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

View File

@ -243,6 +243,29 @@ static void test_reserve_cmd(CuTest *tc) {
test_cleanup(); 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) { static void test_reserve_self(CuTest *tc) {
unit *u1, *u2; unit *u1, *u2;
faction *f; faction *f;
@ -286,6 +309,7 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_unit_limit); SUITE_ADD_TEST(suite, test_unit_limit);
SUITE_ADD_TEST(suite, test_reserve_self); SUITE_ADD_TEST(suite, test_reserve_self);
SUITE_ADD_TEST(suite, test_reserve_cmd); SUITE_ADD_TEST(suite, test_reserve_cmd);
SUITE_ADD_TEST(suite, test_new_units);
SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit); SUITE_ADD_TEST(suite, test_cannot_create_unit_above_limit);
return suite; return suite;
} }

View File

@ -92,9 +92,9 @@ skill_t get_skill(const char *s, const struct locale * lang)
{ {
skill_t result = NOSKILL; skill_t result = NOSKILL;
char buffer[64]; 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; int i;
const void * match; const void * match;
void **tokens = get_translations(lang, UT_SKILLS); void **tokens = get_translations(lang, UT_SKILLS);

View File

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

View File

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

View File

@ -91,7 +91,8 @@ const char *itoab(int i, int base)
*(dst) = '-'; *(dst) = '-';
else else
++dst; ++dst;
} else }
else
*dst = '0'; *dst = '0';
return dst; return dst;

View File

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

View File

@ -48,6 +48,7 @@ char * transliterate(char * out, size_t size, const char * in)
const char *src = in; const char *src = in;
char *dst = out; char *dst = out;
assert(in && size > 0);
--size; /* need space for a final 0-byte */ --size; /* need space for a final 0-byte */
while (*src && size) { while (*src && size) {
size_t len; size_t len;
@ -62,23 +63,30 @@ char * transliterate(char * out, size_t size, const char * in)
if (src[0] == '\xc3') { if (src[0] == '\xc3') {
if (src[1] == '\xa4' || src[1] == '\x84') { if (src[1] == '\xa4' || src[1] == '\x84') {
memcpy(dst, "ae", 2); memcpy(dst, "ae", 2);
} else if (src[1]=='\xb6' || src[1]=='\x96') { }
else if (src[1] == '\xb6' || src[1] == '\x96') {
memcpy(dst, "oe", 2); memcpy(dst, "oe", 2);
} else if (src[1]=='\xbc' || src[1]=='\x9c') { }
else if (src[1] == '\xbc' || src[1] == '\x9c') {
memcpy(dst, "ue", 2); memcpy(dst, "ue", 2);
} else if (src[1]=='\x9f') { }
else if (src[1] == '\x9f') {
memcpy(dst, "ss", 2); memcpy(dst, "ss", 2);
} else { }
else {
advance = 0; advance = 0;
} }
} else if (src[0]=='\xe1') { }
else if (src[0] == '\xe1') {
if (src[1] == '\xba' && src[2] == '\x9e') { if (src[1] == '\xba' && src[2] == '\x9e') {
memcpy(dst, "ss", 2); memcpy(dst, "ss", 2);
++src; ++src;
} else { }
else {
advance = 0; advance = 0;
} }
} else { }
else {
advance = 0; advance = 0;
} }
@ -86,7 +94,8 @@ char * transliterate(char * out, size_t size, const char * in)
src += advance; src += advance;
dst += advance; dst += advance;
size -= advance; size -= advance;
} else { }
else {
ucs4_t ucs; ucs4_t ucs;
unicode_utf8_to_ucs4(&ucs, src, &len); unicode_utf8_to_ucs4(&ucs, src, &len);
src += len; src += len;
@ -128,14 +137,16 @@ void addtoken(void ** root, const char *str, variant id)
assert(root && str); assert(root && str);
if (!*root) { if (!*root) {
tk = *root = calloc(1, sizeof(tnode)); tk = *root = calloc(1, sizeof(tnode));
} else { }
else {
tk = *root; tk = *root;
} }
assert(tk && tk == *root); assert(tk && tk == *root);
if (!*str) { if (!*str) {
tk->id = id; tk->id = id;
tk->flags |= LEAF; tk->flags |= LEAF;
} else { }
else {
tref *next; tref *next;
int ret, index, i = 0; int ret, index, i = 0;
ucs4_t ucs, lcs; ucs4_t ucs, lcs;
@ -187,7 +198,8 @@ void addtoken(void ** root, const char *str, variant id)
tk->next[index] = ref; tk->next[index] = ref;
} }
next = ref; next = ref;
} else { }
else {
tnode * next_node = (tnode *)next->node; tnode * next_node = (tnode *)next->node;
next_node->flags |= SHARED; next_node->flags |= SHARED;
if ((next_node->flags & LEAF) == 0) if ((next_node->flags & LEAF) == 0)