Merge pull request #88 from badgerman/parser-static-removal

parser refactoring, tests and cleanup.
This commit is contained in:
Enno Rehling 2014-12-23 13:27:35 +01:00
commit 1ba7248e48
22 changed files with 1074 additions and 959 deletions

View File

@ -476,7 +476,8 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
n = getuint(); n = getuint();
if (u->number == 0) { if (u->number == 0) {
str = getstrtoken(); char token[128];
str = gettoken(token, sizeof(token));
if (str && str[0]) { if (str && str[0]) {
/* Monsters can RECRUIT 15 DRACOID /* Monsters can RECRUIT 15 DRACOID
* also: secondary race */ * also: secondary race */
@ -626,6 +627,7 @@ void give_control(unit * u, unit * u2)
int give_control_cmd(unit * u, order * ord) int give_control_cmd(unit * u, order * ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
unit *u2; unit *u2;
const char *s; const char *s;
@ -633,7 +635,7 @@ int give_control_cmd(unit * u, order * ord)
init_order(ord); init_order(ord);
getunit(r, u->faction, &u2); getunit(r, u->faction, &u2);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s && isparam(s, u->faction->locale, P_CONTROL)) { if (s && isparam(s, u->faction->locale, P_CONTROL)) {
message *msg = 0; message *msg = 0;
@ -676,6 +678,7 @@ int give_control_cmd(unit * u, order * ord)
static int forget_cmd(unit * u, order * ord) static int forget_cmd(unit * u, order * ord)
{ {
char token[128];
skill_t sk; skill_t sk;
const char *s; const char *s;
@ -685,7 +688,7 @@ static int forget_cmd(unit * u, order * ord)
} }
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) { if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) {
ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk)); ADDMSG(&u->faction->msgs, msg_message("forget", "unit skill", u, sk));
@ -1485,6 +1488,7 @@ static void create_item(unit * u, const item_type * itype, int want)
int make_cmd(unit * u, struct order *ord) int make_cmd(unit * u, struct order *ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
const building_type *btype = 0; const building_type *btype = 0;
const ship_type *stype = 0; const ship_type *stype = 0;
@ -1498,15 +1502,16 @@ int make_cmd(unit * u, struct order *ord)
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_MAKE); assert(kwd == K_MAKE);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s) { if (s) {
m = atoi((const char *)s); m = atoi((const char *)s);
sprintf(ibuf, "%d", m); sprintf(ibuf, "%d", m);
if (!strcmp(ibuf, (const char *)s)) { if (!strcmp(ibuf, (const char *)s)) {
/* a quantity was given */ /* a quantity was given */
s = getstrtoken(); s = gettoken(token, sizeof(token));
} else { }
else {
m = INT_MAX; m = INT_MAX;
} }
if (s) { if (s) {
@ -1520,7 +1525,7 @@ int make_cmd(unit * u, struct order *ord)
cmistake(u, ord, 275, MSG_PRODUCE); cmistake(u, ord, 275, MSG_PRODUCE);
} }
else { else {
const char * s = getstrtoken(); const char * s = gettoken(token, sizeof(token));
direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION; direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION;
if (d != NODIRECTION) { if (d != NODIRECTION) {
build_road(r, u, m, d); build_road(r, u, m, d);
@ -1753,6 +1758,7 @@ attrib_type at_trades = {
static void buy(unit * u, request ** buyorders, struct order *ord) static void buy(unit * u, request ** buyorders, struct order *ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
int n, k; int n, k;
request *o; request *o;
@ -1836,7 +1842,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
/* die Menge der verkauften Güter merken */ /* die Menge der verkauften Güter merken */
a->data.i += n; a->data.i += n;
s = getstrtoken(); s = gettoken(token, sizeof(token));
itype = s ? finditemtype(s, u->faction->locale) : 0; itype = s ? finditemtype(s, u->faction->locale) : 0;
if (itype != NULL) { if (itype != NULL) {
ltype = resource2luxury(itype->rtype); ltype = resource2luxury(itype->rtype);
@ -2059,6 +2065,7 @@ static void expandselling(region * r, request * sellorders, int limit)
static bool sell(unit * u, request ** sellorders, struct order *ord) static bool sell(unit * u, request ** sellorders, struct order *ord)
{ {
char token[128];
bool unlimited = true; bool unlimited = true;
const item_type *itype; const item_type *itype;
const luxury_type *ltype; const luxury_type *ltype;
@ -2076,7 +2083,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_SELL); assert(kwd == K_SELL);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (findparam(s, u->faction->locale) == P_ANY) { if (findparam(s, u->faction->locale) == P_ANY) {
unlimited = false; unlimited = false;
@ -2134,7 +2141,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
cmistake(u, ord, 54, MSG_COMMERCE); cmistake(u, ord, 54, MSG_COMMERCE);
return false; return false;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
itype = s ? finditemtype(s, u->faction->locale) : 0; itype = s ? finditemtype(s, u->faction->locale) : 0;
ltype = itype ? resource2luxury(itype->rtype) : 0; ltype = itype ? resource2luxury(itype->rtype) : 0;
if (ltype == NULL) { if (ltype == NULL) {
@ -2462,6 +2469,7 @@ static void breedhorses(region * r, unit * u)
static void breed_cmd(unit * u, struct order *ord) static void breed_cmd(unit * u, struct order *ord)
{ {
char token[128];
int m; int m;
const char *s; const char *s;
param_t p; param_t p;
@ -2475,12 +2483,12 @@ static void breed_cmd(unit * u, struct order *ord)
/* züchte [<anzahl>] <parameter> */ /* züchte [<anzahl>] <parameter> */
(void)init_order(ord); (void)init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
m = s ? atoi((const char *)s) : 0; m = s ? atoi((const char *)s) : 0;
if (m != 0) { if (m != 0) {
/* first came a want-paramter */ /* first came a want-paramter */
s = getstrtoken(); s = gettoken(token, sizeof(token));
} }
else { else {
m = INT_MAX; m = INT_MAX;
@ -2543,10 +2551,6 @@ static void research_cmd(unit * u, struct order *ord)
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_RESEARCH); assert(kwd == K_RESEARCH);
/*
const char *s = getstrtoken();
if (findparam(s, u->faction->locale) == P_HERBS) { */
if (eff_skill(u, SK_HERBALISM, r) < 7) { if (eff_skill(u, SK_HERBALISM, r) < 7) {
cmistake(u, ord, 227, MSG_EVENT); cmistake(u, ord, 227, MSG_EVENT);

View File

@ -531,6 +531,7 @@ bool can_give_to(unit *u, unit *u2) {
void give_cmd(unit * u, order * ord) void give_cmd(unit * u, order * ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
unit *u2; unit *u2;
const char *s; const char *s;
@ -544,7 +545,7 @@ void give_cmd(unit * u, order * ord)
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_GIVE); assert(kwd == K_GIVE);
err = getunit(r, u->faction, &u2); err = getunit(r, u->faction, &u2);
s = getstrtoken(); s = gettoken(token, sizeof(token));
n = s ? atoip(s) : 0; n = s ? atoip(s) : 0;
p = (n > 0) ? NOPARAM : findparam(s, u->faction->locale); p = (n > 0) ? NOPARAM : findparam(s, u->faction->locale);
@ -652,7 +653,7 @@ void give_cmd(unit * u, order * ord)
feedback_give_not_allowed(u, ord); feedback_give_not_allowed(u, ord);
return; return;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (!s || *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: */
@ -732,11 +733,11 @@ void give_cmd(unit * u, order * ord)
msg_feedback(u, ord, "peasants_give_invalid", "")); msg_feedback(u, ord, "peasants_give_invalid", ""));
return; return;
} }
s = getstrtoken(); /* skip one ahead to get the amount. */ s = gettoken(token, sizeof(token)); /* skip one ahead to get the amount. */
n = atoip(s); /* n: Anzahl */ n = s ? atoip(s) : 0; /* n: Anzahl */
n *= u2->number; n *= u2->number;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s == NULL) { if (s == NULL) {
cmistake(u, ord, 113, MSG_COMMERCE); cmistake(u, ord, 113, MSG_COMMERCE);

View File

@ -35,9 +35,10 @@ use_studypotion(struct unit *u, const struct item_type *itype, int amount,
struct order *ord) struct order *ord)
{ {
if (init_order(u->thisorder) == K_STUDY) { if (init_order(u->thisorder) == K_STUDY) {
char token[128];
skill_t sk = NOSKILL; skill_t sk = NOSKILL;
skill *sv = 0; skill *sv = 0;
const char * s = getstrtoken(); const char * s = gettoken(token, sizeof(token));
if (s) { if (s) {
sk = get_skill(s, u->faction->locale); sk = get_skill(s, u->faction->locale);

View File

@ -91,19 +91,22 @@ ship *getship(const struct region * r)
static void destroy_road(unit * u, int nmax, struct order *ord) static void destroy_road(unit * u, int nmax, struct order *ord)
{ {
const char *s = getstrtoken(); char token[128];
const char *s = gettoken(token, sizeof(token));
direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION; direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION;
if (d == NODIRECTION) { if (d == NODIRECTION) {
/* Die Richtung wurde nicht erkannt */ /* Die Richtung wurde nicht erkannt */
cmistake(u, ord, 71, MSG_PRODUCE); cmistake(u, ord, 71, MSG_PRODUCE);
} else { }
else {
unit *u2; unit *u2;
region *r = u->region; region *r = u->region;
short road, n = (short)nmax; short road, n = (short)nmax;
if (nmax > SHRT_MAX) { if (nmax > SHRT_MAX) {
n = SHRT_MAX; n = SHRT_MAX;
} else if (nmax < 0) { }
else if (nmax < 0) {
n = 0; n = 0;
} }
@ -138,6 +141,7 @@ static void destroy_road(unit * u, int nmax, struct order *ord)
int destroy_cmd(unit * u, struct order *ord) int destroy_cmd(unit * u, struct order *ord)
{ {
char token[128];
ship *sh; ship *sh;
unit *u2; unit *u2;
region *r = u->region; region *r = u->region;
@ -150,7 +154,7 @@ int destroy_cmd(unit * u, struct order *ord)
return 0; return 0;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (findparam(s, u->faction->locale) == P_ROAD) { if (findparam(s, u->faction->locale) == P_ROAD) {
destroy_road(u, INT_MAX, ord); destroy_road(u, INT_MAX, ord);
@ -192,13 +196,15 @@ int destroy_cmd(unit * u, struct order *ord)
ADDMSG(&u->faction->msgs, msg_message("destroy", "building unit", b, u)); ADDMSG(&u->faction->msgs, msg_message("destroy", "building unit", b, u));
con = b->type->construction; con = b->type->construction;
remove_building(&r->buildings, b); remove_building(&r->buildings, b);
} else { }
else {
/* partial destroy */ /* partial destroy */
b->size -= n; b->size -= n;
ADDMSG(&u->faction->msgs, msg_message("destroy_partial", ADDMSG(&u->faction->msgs, msg_message("destroy_partial",
"building unit", b, u)); "building unit", b, u));
} }
} else if (u->ship) { }
else if (u->ship) {
sh = u->ship; sh = u->ship;
if (u != ship_owner(sh)) { if (u != ship_owner(sh)) {
@ -222,13 +228,15 @@ int destroy_cmd(unit * u, struct order *ord)
"unit region ship", u, r, sh)); "unit region ship", u, r, sh));
con = sh->type->construction; con = sh->type->construction;
remove_ship(&sh->region->ships, sh); remove_ship(&sh->region->ships, sh);
} else { }
else {
/* partial destroy */ /* partial destroy */
sh->size -= (sh->type->construction->maxsize * n) / 100; sh->size -= (sh->type->construction->maxsize * n) / 100;
ADDMSG(&u->faction->msgs, msg_message("shipdestroy_partial", ADDMSG(&u->faction->msgs, msg_message("shipdestroy_partial",
"unit region ship", u, r, sh)); "unit region ship", u, r, sh));
} }
} else { }
else {
cmistake(u, ord, 138, MSG_PRODUCE); cmistake(u, ord, 138, MSG_PRODUCE);
return 0; return 0;
} }
@ -281,14 +289,16 @@ void build_road(region * r, unit * u, int size, direction_t d)
cmistake(u, u->thisorder, 132, MSG_PRODUCE); cmistake(u, u->thisorder, 132, MSG_PRODUCE);
return; return;
} }
} else if (r->terrain == newterrain(T_DESERT)) { }
else if (r->terrain == newterrain(T_DESERT)) {
const struct building_type *bt_caravan = bt_find("caravan"); const struct building_type *bt_caravan = bt_find("caravan");
/* wenn keine Karawanserei existiert */ /* wenn keine Karawanserei existiert */
if (!bt_caravan || !buildingtype_exists(r, bt_caravan, true)) { if (!bt_caravan || !buildingtype_exists(r, bt_caravan, true)) {
cmistake(u, u->thisorder, 133, MSG_PRODUCE); cmistake(u, u->thisorder, 133, MSG_PRODUCE);
return; return;
} }
} else if (r->terrain == newterrain(T_GLACIER)) { }
else if (r->terrain == newterrain(T_GLACIER)) {
const struct building_type *bt_tunnel = bt_find("tunnel"); const struct building_type *bt_tunnel = bt_find("tunnel");
/* wenn kein Tunnel existiert */ /* wenn kein Tunnel existiert */
if (!bt_tunnel || !buildingtype_exists(r, bt_tunnel, true)) { if (!bt_tunnel || !buildingtype_exists(r, bt_tunnel, true)) {
@ -312,7 +322,8 @@ void build_road(region * r, unit * u, int size, direction_t d)
/* baumaximum anhand der rohstoffe */ /* baumaximum anhand der rohstoffe */
if (u_race(u) == get_race(RC_STONEGOLEM)) { if (u_race(u) == get_race(RC_STONEGOLEM)) {
n = u->number * GOLEM_STONE; n = u->number * GOLEM_STONE;
} else { }
else {
n = get_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, left); n = get_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, left);
if (n == 0) { if (n == 0) {
cmistake(u, u->thisorder, 151, MSG_PRODUCE); cmistake(u, u->thisorder, 151, MSG_PRODUCE);
@ -357,7 +368,8 @@ void build_road(region * r, unit * u, int size, direction_t d)
++golemsused; ++golemsused;
} }
scale_number(u, u->number - golemsused); scale_number(u, u->number - golemsused);
} else { }
else {
use_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, n); use_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, n);
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */ /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
produceexp(u, SK_ROAD_BUILDING, _min(n, u->number)); produceexp(u, SK_ROAD_BUILDING, _min(n, u->number));
@ -496,7 +508,8 @@ int build(unit * u, const construction * ctype, int completed, int want)
*/ */
if (type->maxsize > 1) { if (type->maxsize > 1) {
completed = completed % type->maxsize; completed = completed % type->maxsize;
} else { }
else {
completed = 0; completed = 0;
assert(type->reqsize >= 1); assert(type->reqsize >= 1);
} }
@ -509,7 +522,8 @@ int build(unit * u, const construction * ctype, int completed, int want)
/* n = maximum buildable size */ /* n = maximum buildable size */
if (type->minskill > 1) { if (type->minskill > 1) {
n = skills / type->minskill; n = skills / type->minskill;
} else { }
else {
n = skills; n = skills;
} }
/* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische) /* Flinkfingerring wirkt nicht auf Mengenbegrenzte (magische)
@ -556,7 +570,8 @@ int build(unit * u, const construction * ctype, int completed, int want)
break; break;
--n; /* TODO: optimieren? */ --n; /* TODO: optimieren? */
} }
} else { }
else {
int maxn = canuse / type->materials[c].number; int maxn = canuse / type->materials[c].number;
if (maxn < n) if (maxn < n)
n = maxn; n = maxn;
@ -634,7 +649,8 @@ int maxbuild(const unit * u, const construction * cons)
int need = required(1, cons->reqsize, cons->materials[c].number); int need = required(1, cons->reqsize, cons->materials[c].number);
if (have < need) { if (have < need) {
return 0; return 0;
} else }
else
maximum = _min(maximum, have / need); maximum = _min(maximum, have / need);
} }
return maximum; return maximum;
@ -673,13 +689,15 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
/* vieleicht Tippfehler und die eigene Burg ist gemeint? */ /* vieleicht Tippfehler und die eigene Burg ist gemeint? */
if (u->building && u->building->type == btype) { if (u->building && u->building->type == btype) {
b = u->building; b = u->building;
} else { }
else {
/* keine neue Burg anfangen wenn eine Nummer angegeben war */ /* keine neue Burg anfangen wenn eine Nummer angegeben war */
cmistake(u, ord, 6, MSG_PRODUCE); cmistake(u, ord, 6, MSG_PRODUCE);
return 0; return 0;
} }
} }
} else if (u->building && u->building->type == btype) { }
else if (u->building && u->building->type == btype) {
b = u->building; b = u->building;
} }
@ -733,13 +751,16 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
if (b == NULL) { if (b == NULL) {
if (btype->maxsize > 0) { if (btype->maxsize > 0) {
n = btype->maxsize - built; n = btype->maxsize - built;
} else { }
else {
n = INT_MAX; n = INT_MAX;
} }
} else { }
else {
if (b->type->maxsize > 0) { if (b->type->maxsize > 0) {
n = b->type->maxsize - built; n = b->type->maxsize - built;
} else { }
else {
n = INT_MAX; n = INT_MAX;
} }
} }
@ -782,22 +803,26 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
if (want - built <= 0) { if (want - built <= 0) {
/* gebäude fertig */ /* gebäude fertig */
new_order = default_order(lang); new_order = default_order(lang);
} else if (want != INT_MAX) { }
else if (want != INT_MAX) {
/* reduzierte restgröße */ /* reduzierte restgröße */
const char *hasspace = strchr(btname, ' '); const char *hasspace = strchr(btname, ' ');
if (hasspace) { if (hasspace) {
new_order = new_order =
create_order(K_MAKE, lang, "%d \"%s\" %i", n - built, btname, b->no); create_order(K_MAKE, lang, "%d \"%s\" %i", n - built, btname, b->no);
} else { }
else {
new_order = new_order =
create_order(K_MAKE, lang, "%d %s %i", n - built, btname, b->no); create_order(K_MAKE, lang, "%d %s %i", n - built, btname, b->no);
} }
} else if (btname) { }
else if (btname) {
/* Neues Haus, Befehl mit Gebäudename */ /* Neues Haus, Befehl mit Gebäudename */
const char *hasspace = strchr(btname, ' '); const char *hasspace = strchr(btname, ' ');
if (hasspace) { if (hasspace) {
new_order = create_order(K_MAKE, lang, "\"%s\" %i", btname, b->no); new_order = create_order(K_MAKE, lang, "\"%s\" %i", btname, b->no);
} else { }
else {
new_order = create_order(K_MAKE, lang, "%s %i", btname, b->no); new_order = create_order(K_MAKE, lang, "%s %i", btname, b->no);
} }
} }
@ -828,7 +853,8 @@ static void build_ship(unit * u, ship * sh, int want)
if (can >= n) { if (can >= n) {
sh->size += n; sh->size += n;
can -= n; can -= n;
} else { }
else {
sh->size += can; sh->size += can;
n = can; n = can;
can = 0; can = 0;

View File

@ -73,10 +73,11 @@ const char *str, parser fun)
static int do_command_i(const void *keys, struct unit *u, struct order *ord) static int do_command_i(const void *keys, struct unit *u, struct order *ord)
{ {
char token[128];
const char *c; const char *c;
variant var; variant var;
c = getstrtoken(); c = gettoken(token, sizeof(token));
if (findtoken(keys, c, &var) == E_TOK_SUCCESS) { if (findtoken(keys, c, &var) == E_TOK_SUCCESS) {
command *cmd = (command *)var.v; command *cmd = (command *)var.v;
if (cmd->nodes && *c) { if (cmd->nodes && *c) {

View File

@ -587,19 +587,6 @@ int change_hitpoints(unit * u, int value)
return hp; return hp;
} }
unsigned int atoip(const char *s)
{
int n;
assert(s);
n = atoi(s);
if (n < 0)
n = 0;
return n;
}
bool unit_has_cursed_item(const unit * u) bool unit_has_cursed_item(const unit * u)
{ {
item *itm = u->items; item *itm = u->items;
@ -794,18 +781,6 @@ parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder)
} }
} }
unsigned int getuint(void)
{
const char *s = getstrtoken();
return s ? atoip(s) : 0;
}
int getint(void)
{
const char * s = getstrtoken();
return s ? atoi(s) : 0;
}
const struct race *findrace(const char *s, const struct locale *lang) const struct race *findrace(const char *s, const struct locale *lang)
{ {
void **tokens = get_translations(lang, UT_RACES); void **tokens = get_translations(lang, UT_RACES);
@ -875,7 +850,8 @@ bool isparam(const char *s, const struct locale * lang, param_t param)
param_t getparam(const struct locale * lang) param_t getparam(const struct locale * lang)
{ {
const char *s = getstrtoken(); char token[64];
const char *s = gettoken(token, sizeof(token));
return s ? findparam(s, lang) : NOPARAM; return s ? findparam(s, lang) : NOPARAM;
} }
@ -909,7 +885,8 @@ static int read_newunitid(const faction * f, const region * r)
int read_unitid(const faction * f, const region * r) int read_unitid(const faction * f, const region * r)
{ {
const char *s = getstrtoken(); char token[8];
const char *s = gettoken(token, sizeof(token));
/* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der /* Da s nun nur einen string enthaelt, suchen wir ihn direkt in der
* paramliste. machen wir das nicht, dann wird getnewunit in s nach der * paramliste. machen wir das nicht, dann wird getnewunit in s nach der

View File

@ -108,10 +108,6 @@ extern "C" {
/* special units */ /* special units */
void make_undead_unit(struct unit *); void make_undead_unit(struct unit *);
unsigned int atoip(const char *s);
unsigned int getuint(void);
int getint(void);
param_t findparam(const char *s, const struct locale *lang); param_t findparam(const char *s, const struct locale *lang);
param_t findparam_ex(const char *s, const struct locale * lang); 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);

View File

@ -278,9 +278,9 @@ unit *addplayer(region * r, faction * f)
return u; return u;
} }
bool checkpasswd(const faction * f, const char *passwd, bool shortp) bool checkpasswd(const faction * f, const char *passwd)
{ {
if (unicode_utf8_strcasecmp(f->passw, passwd) == 0) if (passwd && unicode_utf8_strcasecmp(f->passw, passwd) == 0)
return true; return true;
return false; return false;
} }

View File

@ -120,7 +120,7 @@ const char *factionname(const struct faction *f);
struct unit *addplayer(struct region *r, faction * f); struct unit *addplayer(struct region *r, faction * f);
struct faction *addfaction(const char *email, const char *password, struct faction *addfaction(const char *email, const char *password,
const struct race *frace, const struct locale *loc, int subscription); const struct race *frace, const struct locale *loc, int subscription);
bool checkpasswd(const faction * f, const char *passwd, bool shortp); bool checkpasswd(const faction * f, const char *passwd);
void destroyfaction(faction * f); void destroyfaction(faction * f);
extern void set_alliance(struct faction *a, struct faction *b, int status); extern void set_alliance(struct faction *a, struct faction *b, int status);

View File

@ -207,7 +207,7 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
/* learning, only one order_data per skill required */ /* learning, only one order_data per skill required */
if (kwd == K_STUDY) { if (kwd == K_STUDY) {
skill_t sk = get_skill(parse_token(&sptr), lang); skill_t sk = get_skill(parse_token_depr(&sptr), lang);
switch (sk) { switch (sk) {
case NOSKILL: /* fehler */ case NOSKILL: /* fehler */
break; break;
@ -364,11 +364,11 @@ order *parse_order(const char *s, const struct locale * lang)
++s; ++s;
} }
sptr = s; sptr = s;
p = *sptr ? parse_token(&sptr) : 0; p = *sptr ? parse_token_depr(&sptr) : 0;
kwd = p ? get_keyword(p, lang) : NOKEYWORD; 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_depr(&sp);
if (s && isparam(s, lang, P_TEMP)) { if (s && isparam(s, lang, P_TEMP)) {
kwd = K_MAKETEMP; kwd = K_MAKETEMP;
sptr = sp; sptr = sp;
@ -570,6 +570,6 @@ keyword_t init_order(const struct order *ord)
assert(ord && ord->data); assert(ord && ord->data);
if (ord->data->_str) cmd = _strdup(ord->data->_str); if (ord->data->_str) cmd = _strdup(ord->data->_str);
init_tokens_str(cmd, cmd); init_tokens_str(cmd);
return ord->data->_keyword; return ord->data->_keyword;
} }

View File

@ -128,19 +128,19 @@ static void test_init_order(CuTest *tc) {
static void test_getstrtoken(CuTest *tc) { static void test_getstrtoken(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\" \"\" \'\'"); char *cmd = _strdup("hurr \"durr\" \"\" \'\'");
init_tokens_str(cmd, cmd); init_tokens_str(cmd);
CuAssertStrEquals(tc, "hurr", getstrtoken()); CuAssertStrEquals(tc, "hurr", getstrtoken());
CuAssertStrEquals(tc, "durr", getstrtoken()); CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, "", getstrtoken()); CuAssertStrEquals(tc, "", getstrtoken());
CuAssertStrEquals(tc, "", getstrtoken()); CuAssertStrEquals(tc, "", getstrtoken());
CuAssertStrEquals(tc, 0, getstrtoken()); CuAssertStrEquals(tc, 0, getstrtoken());
init_tokens_str(0, 0); init_tokens_str(0);
CuAssertStrEquals(tc, 0, getstrtoken()); CuAssertStrEquals(tc, 0, getstrtoken());
} }
static void test_skip_token(CuTest *tc) { static void test_skip_token(CuTest *tc) {
char *cmd = _strdup("hurr \"durr\""); char *cmd = _strdup("hurr \"durr\"");
init_tokens_str(cmd, cmd); init_tokens_str(cmd);
skip_token(); skip_token();
CuAssertStrEquals(tc, "durr", getstrtoken()); CuAssertStrEquals(tc, "durr", getstrtoken());
CuAssertStrEquals(tc, 0, getstrtoken()); CuAssertStrEquals(tc, 0, getstrtoken());

View File

@ -169,7 +169,7 @@ static unit *unitorders(FILE * F, int enc, struct faction *f)
if (s[0]) { if (s[0]) {
if (s[0] != '@') { if (s[0] != '@') {
const char *stok = s; const char *stok = s;
stok = parse_token(&stok); stok = parse_token_depr(&stok);
if (stok) { if (stok) {
bool quit = false; bool quit = false;
@ -224,9 +224,10 @@ static faction *factionorders(void)
f = findfaction(fid); f = findfaction(fid);
if (f != NULL && !fval(f, FFL_NPC)) { if (f != NULL && !fval(f, FFL_NPC)) {
const char *pass = getstrtoken(); char token[128];
const char *pass = gettoken(token, sizeof(token));
if (!checkpasswd(f, (const char *)pass, true)) { if (!checkpasswd(f, (const char *)pass)) {
log_debug("Invalid password for faction %s\n", itoa36(fid)); log_debug("Invalid password for faction %s\n", itoa36(fid));
ADDMSG(&f->msgs, msg_message("wrongpasswd", "faction password", ADDMSG(&f->msgs, msg_message("wrongpasswd", "faction password",
f->no, pass)); f->no, pass));
@ -267,11 +268,12 @@ int readorders(const char *filename)
* Partei */ * Partei */
while (b) { while (b) {
char token[128];
const struct locale *lang = f ? f->locale : default_locale; const struct locale *lang = f ? f->locale : default_locale;
param_t p; param_t p;
const char *s; const char *s;
init_tokens_str(b, NULL); init_tokens_str(b);
s = getstrtoken(); s = gettoken(token, sizeof(token));
p = s ? findparam(s, lang) : NOPARAM; p = s ? findparam(s, lang) : NOPARAM;
switch (p) { switch (p) {
#undef LOCALE_CHANGE #undef LOCALE_CHANGE
@ -308,7 +310,7 @@ int readorders(const char *filename)
if (!b) { if (!b) {
break; break;
} }
init_tokens_str(b, NULL); init_tokens_str(b);
b = getstrtoken(); b = getstrtoken();
p = (!b || b[0] == '@') ? NOPARAM : findparam(b, lang); p = (!b || b[0] == '@') ? NOPARAM : findparam(b, lang);
} while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT

View File

@ -491,16 +491,19 @@ void usetprivate(unit * u, const char *str)
{ {
attrib *a = a_find(u->attribs, &at_private); attrib *a = a_find(u->attribs, &at_private);
if (str == NULL) { if (str == NULL || *str == 0) {
if (a) if (a) {
a_remove(&u->attribs, a); a_remove(&u->attribs, a);
}
return; return;
} }
if (!a) if (!a) {
a = a_add(&u->attribs, a_new(&at_private)); a = a_add(&u->attribs, a_new(&at_private));
if (a->data.v) }
if (a->data.v) {
free(a->data.v); free(a->data.v);
a->data.v = _strdup((const char *)str); }
a->data.v = _strdup(str);
} }
/*********************/ /*********************/

View File

@ -946,14 +946,15 @@ static bool EnhancedQuit(void)
int quit_cmd(unit * u, struct order *ord) int quit_cmd(unit * u, struct order *ord)
{ {
char token[128];
faction *f = u->faction; faction *f = u->faction;
const char *passwd; const char *passwd;
keyword_t kwd; keyword_t kwd;
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_QUIT); assert(kwd == K_QUIT);
passwd = getstrtoken(); passwd = gettoken(token, sizeof(token));
if (checkpasswd(f, (const char *)passwd, false)) { if (checkpasswd(f, (const char *)passwd)) {
if (EnhancedQuit()) { if (EnhancedQuit()) {
int f2_id = getid(); int f2_id = getid();
if (f2_id > 0) { if (f2_id > 0) {
@ -1159,13 +1160,14 @@ void do_enter(struct region *r, bool is_final_attempt)
while (*ordp) { while (*ordp) {
order *ord = *ordp; order *ord = *ordp;
if (getkeyword(ord) == K_ENTER) { if (getkeyword(ord) == K_ENTER) {
char token[128];
param_t p; param_t p;
int id; int id;
unit *ulast = NULL; unit *ulast = NULL;
const char * s; const char * s;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
p = findparam_ex(s, u->faction->locale); p = findparam_ex(s, u->faction->locale);
id = getid(); id = getid();
@ -1339,6 +1341,7 @@ void quit(void)
int ally_cmd(unit * u, struct order *ord) int ally_cmd(unit * u, struct order *ord)
{ {
char token[128];
ally *sf, **sfp; ally *sf, **sfp;
faction *f; faction *f;
int keyword, not_kw; int keyword, not_kw;
@ -1354,7 +1357,7 @@ int ally_cmd(unit * u, struct order *ord)
if (f == u->faction) if (f == u->faction)
return 0; return 0;
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (!s[0]) if (!s[0])
keyword = P_ANY; keyword = P_ANY;
@ -1492,6 +1495,7 @@ static void init_prefixnames(void)
int prefix_cmd(unit * u, struct order *ord) int prefix_cmd(unit * u, struct order *ord)
{ {
char token[128];
attrib **ap; attrib **ap;
const char *s; const char *s;
local_names *in = pnames; local_names *in = pnames;
@ -1509,7 +1513,7 @@ int prefix_cmd(unit * u, struct order *ord)
} }
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (!s || !*s) { if (!s || !*s) {
attrib *a = NULL; attrib *a = NULL;
@ -1556,13 +1560,14 @@ static cmp_building_cb get_cmp_region_owner(void)
int display_cmd(unit * u, struct order *ord) int display_cmd(unit * u, struct order *ord)
{ {
char token[128];
char **s = NULL; char **s = NULL;
const char *str; const char *str;
region *r = u->region; region *r = u->region;
init_order(ord); init_order(ord);
str = getstrtoken(); str = gettoken(token, sizeof(token));
switch (findparam_ex(str, u->faction->locale)) { switch (findparam_ex(str, u->faction->locale)) {
case P_BUILDING: case P_BUILDING:
case P_GEBAEUDE: case P_GEBAEUDE:
@ -1598,15 +1603,7 @@ int display_cmd(unit * u, struct order *ord)
break; break;
case P_PRIVAT: case P_PRIVAT:
{ usetprivate(u, getstrtoken());
const char *d = getstrtoken();
if (d == NULL || *d == 0) {
usetprivate(u, NULL);
}
else {
usetprivate(u, d);
}
}
break; break;
case P_REGION: case P_REGION:
@ -1729,6 +1726,7 @@ rename_building(unit * u, order * ord, building * b, const char *name)
int name_cmd(struct unit *u, struct order *ord) int name_cmd(struct unit *u, struct order *ord)
{ {
char token[128];
building *b = u->building; building *b = u->building;
region *r = u->region; region *r = u->region;
char **s = NULL; char **s = NULL;
@ -1737,11 +1735,11 @@ int name_cmd(struct unit *u, struct order *ord)
const char *str; const char *str;
init_order(ord); init_order(ord);
str = getstrtoken(); str = gettoken(token, sizeof(token));
p = findparam_ex(str, u->faction->locale); p = findparam_ex(str, u->faction->locale);
if (p == P_FOREIGN) { if (p == P_FOREIGN) {
str = getstrtoken(); str = gettoken(token, sizeof(token));
foreign = true; foreign = true;
p = findparam_ex(str, u->faction->locale); p = findparam_ex(str, u->faction->locale);
} }
@ -1991,13 +1989,14 @@ static void mailfaction(unit * u, int n, struct order *ord, const char *s)
int mail_cmd(unit * u, struct order *ord) int mail_cmd(unit * u, struct order *ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
unit *u2; unit *u2;
const char *s; const char *s;
int n, cont; int n, cont;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
/* Falls kein Parameter, ist das eine Einheitsnummer; /* Falls kein Parameter, ist das eine Einheitsnummer;
* das Füllwort "AN" muß wegfallen, da gültige Nummer! */ * das Füllwort "AN" muß wegfallen, da gültige Nummer! */
@ -2018,19 +2017,15 @@ int mail_cmd(unit * u, struct order *ord)
} }
case P_FACTION: case P_FACTION:
{
bool see = false;
n = getfactionid(); n = getfactionid();
for (u2 = r->units; u2; u2 = u2->next) { for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction->no == n && seefaction(u->faction, r, u2, 0)) { if (u2->faction->no == n && seefaction(u->faction, r, u2, 0)) {
see = true;
break; break;
} }
} }
if (!see) { if (!u2) {
cmistake(u, ord, 66, MSG_MESSAGE); cmistake(u, ord, 66, MSG_MESSAGE);
break; break;
} }
@ -2042,21 +2037,17 @@ int mail_cmd(unit * u, struct order *ord)
} }
mailfaction(u, n, ord, s); mailfaction(u, n, ord, s);
return 0; return 0;
}
case P_UNIT: case P_UNIT:
{
bool see = false;
n = getid(); n = getid();
for (u2 = r->units; u2; u2 = u2->next) { for (u2 = r->units; u2; u2 = u2->next) {
if (u2->no == n && cansee(u->faction, r, u2, 0)) { if (u2->no == n && cansee(u->faction, r, u2, 0)) {
see = true;
break; break;
} }
} }
if (!see) { if (!u2) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
"feedback_unit_not_found", "")); "feedback_unit_not_found", ""));
return 0; return 0;
@ -2082,7 +2073,6 @@ int mail_cmd(unit * u, struct order *ord)
mailunit(r, u, n, ord, s); mailunit(r, u, n, ord, s);
} }
return 0; return 0;
}
case P_BUILDING: case P_BUILDING:
case P_GEBAEUDE: case P_GEBAEUDE:
@ -2182,7 +2172,7 @@ int email_cmd(unit * u, struct order *ord)
} }
else { else {
faction *f = u->faction; faction *f = u->faction;
if (set_email(&f->email, (const char *)s) != 0) { if (set_email(&f->email, s) != 0) {
log_error("Invalid email address for faction %s: %s\n", itoa36(f->no), s); log_error("Invalid email address for faction %s: %s\n", itoa36(f->no), s);
ADDMSG(&f->msgs, msg_message("changemail_invalid", "value", s)); ADDMSG(&f->msgs, msg_message("changemail_invalid", "value", s));
} }
@ -2201,7 +2191,7 @@ int password_cmd(unit * u, struct order *ord)
bool pwok = true; bool pwok = true;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(pwbuf, sizeof(pwbuf));
if (!s || !*s) { if (!s || !*s) {
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
@ -2210,14 +2200,10 @@ int password_cmd(unit * u, struct order *ord)
} }
else { else {
char *c; char *c;
for (c = pwbuf; *c && pwok; ++c) {
strlcpy(pwbuf, (const char *)s, 31); if (!isalnum(*(unsigned char *)c)) {
pwbuf[31] = 0;
c = pwbuf;
while (*c && pwok) {
if (!isalnum(*(unsigned char *)c))
pwok = false; pwok = false;
c++; }
} }
} }
free(u->faction->passw); free(u->faction->passw);
@ -2235,11 +2221,12 @@ int password_cmd(unit * u, struct order *ord)
int send_cmd(unit * u, struct order *ord) int send_cmd(unit * u, struct order *ord)
{ {
char token[128];
const char *s; const char *s;
int option; int option;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
option = findoption(s, u->faction->locale); option = findoption(s, u->faction->locale);
@ -2576,14 +2563,11 @@ 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;
keyword_t kwd; keyword_t kwd;
kwd = init_order(ord); kwd = init_order(ord);
assert(kwd == K_GROUP); assert(kwd == K_GROUP);
s = getstrtoken(); join_group(u, getstrtoken());
join_group(u, s);
return 0; return 0;
} }
@ -2613,11 +2597,12 @@ int guard_off_cmd(unit * u, struct order *ord)
int reshow_cmd(unit * u, struct order *ord) int reshow_cmd(unit * u, struct order *ord)
{ {
char lbuf[64];
const char *s; const char *s;
param_t p = NOPARAM; param_t p = NOPARAM;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(lbuf, sizeof(lbuf));
if (s && isparam(s, u->faction->locale, P_ANY)) { if (s && isparam(s, u->faction->locale, P_ANY)) {
p = getparam(u->faction->locale); p = getparam(u->faction->locale);
@ -2630,12 +2615,12 @@ int reshow_cmd(unit * u, struct order *ord)
int status_cmd(unit * u, struct order *ord) int status_cmd(unit * u, struct order *ord)
{ {
const char *param; char token[128];
const char *s;
init_order(ord); init_order(ord);
s = gettoken(token, sizeof(token));
param = getstrtoken(); switch (findparam(s, u->faction->locale)) {
switch (findparam(param, u->faction->locale)) {
case P_NOT: case P_NOT:
setstatus(u, ST_AVOID); setstatus(u, ST_AVOID);
break; break;
@ -2663,7 +2648,7 @@ int status_cmd(unit * u, struct order *ord)
} }
break; break;
default: default:
if (param && param[0]) { if (s && s[0]) {
add_message(&u->faction->msgs, add_message(&u->faction->msgs,
msg_feedback(u, ord, "unknown_status", "")); msg_feedback(u, ord, "unknown_status", ""));
} }
@ -2676,12 +2661,13 @@ int status_cmd(unit * u, struct order *ord)
int combatspell_cmd(unit * u, struct order *ord) int combatspell_cmd(unit * u, struct order *ord)
{ {
char token[128];
const char *s; const char *s;
int level = 0; int level = 0;
spell *sp = 0; spell *sp = 0;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */ /* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
if (!s || *s == 0 || findparam(s, u->faction->locale) == P_NOT) { if (!s || *s == 0 || findparam(s, u->faction->locale) == P_NOT) {
@ -2694,7 +2680,7 @@ int combatspell_cmd(unit * u, struct order *ord)
/* Merken, setzen kommt erst später */ /* Merken, setzen kommt erst später */
level = getint(); level = getint();
level = _max(0, level); level = _max(0, level);
s = getstrtoken(); s = gettoken(token, sizeof(token));
} }
sp = unit_getspell(u, s, u->faction->locale); sp = unit_getspell(u, s, u->faction->locale);
@ -2703,7 +2689,7 @@ int combatspell_cmd(unit * u, struct order *ord)
return 0; return 0;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (findparam(s, u->faction->locale) == P_NOT) { if (findparam(s, u->faction->locale) == P_NOT) {
/* KAMPFZAUBER "<Spruchname>" NICHT löscht diesen speziellen /* KAMPFZAUBER "<Spruchname>" NICHT löscht diesen speziellen
@ -2921,13 +2907,14 @@ void restack_units(void)
struct order *ord; struct order *ord;
for (ord = u->orders; ord; ord = ord->next) { for (ord = u->orders; ord; ord = ord->next) {
if (getkeyword(ord) == K_SORT) { if (getkeyword(ord) == K_SORT) {
char token[128];
const char *s; const char *s;
param_t p; param_t p;
int id; int id;
unit *v; unit *v;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
p = findparam(s, u->faction->locale); p = findparam(s, u->faction->locale);
id = getid(); id = getid();
v = findunit(id); v = findunit(id);
@ -2997,16 +2984,17 @@ void restack_units(void)
int renumber_cmd(unit * u, order * ord) int renumber_cmd(unit * u, order * ord)
{ {
char token[128];
const char *s; const char *s;
int i; int i;
faction *f = u->faction; faction *f = u->faction;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
switch (findparam_ex(s, u->faction->locale)) { switch (findparam_ex(s, u->faction->locale)) {
case P_FACTION: case P_FACTION:
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s && *s) { if (s && *s) {
int id = atoi36((const char *)s); int id = atoi36((const char *)s);
attrib *a = a_find(f->attribs, &at_number); attrib *a = a_find(f->attribs, &at_number);
@ -3017,7 +3005,7 @@ int renumber_cmd(unit * u, order * ord)
break; break;
case P_UNIT: case P_UNIT:
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s == NULL || *s == 0) { if (s == NULL || *s == 0) {
i = newunitid(); i = newunitid();
} }
@ -3060,7 +3048,7 @@ int renumber_cmd(unit * u, order * ord)
cmistake(u, ord, 116, MSG_EVENT); cmistake(u, ord, 116, MSG_EVENT);
break; break;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (s == NULL || *s == 0) { if (s == NULL || *s == 0) {
i = newcontainerid(); i = newcontainerid();
} }
@ -3089,7 +3077,7 @@ int renumber_cmd(unit * u, order * ord)
cmistake(u, ord, 148, MSG_EVENT); cmistake(u, ord, 148, MSG_EVENT);
break; break;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (*s == 0) { if (*s == 0) {
i = newcontainerid(); i = newcontainerid();
} }
@ -3355,8 +3343,8 @@ void new_units(void)
while (*ordp) { while (*ordp) {
order *makeord = *ordp; order *makeord = *ordp;
if (getkeyword(makeord) == K_MAKETEMP) { if (getkeyword(makeord) == K_MAKETEMP) {
const char *token; char token[128], *name = NULL;
char *name = NULL; const char *s;
int alias; int alias;
ship *sh; ship *sh;
order **newordersp; order **newordersp;
@ -3390,9 +3378,9 @@ void new_units(void)
init_order(makeord); init_order(makeord);
alias = getid(); alias = getid();
token = getstrtoken(); s = gettoken(token, sizeof(token));
if (token && token[0]) { if (s && s[0]) {
name = _strdup(token); name = _strdup(s);
} }
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u); u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
if (name != NULL) if (name != NULL)
@ -3700,10 +3688,9 @@ void defaultorders(void)
order *new_order = 0; order *new_order = 0;
const char *s; const char *s;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(lbuf, sizeof(lbuf));
if (s) { if (s) {
strcpy(lbuf, s); new_order = parse_order(s, u->faction->locale);
new_order = parse_order(lbuf, u->faction->locale);
} }
*ordp = ord->next; *ordp = ord->next;
ord->next = NULL; ord->next = NULL;
@ -3810,19 +3797,20 @@ static void update_spells(void)
int use_cmd(unit * u, struct order *ord) int use_cmd(unit * u, struct order *ord)
{ {
char token[128];
const char *t; const char *t;
int n, err = ENOITEM; int n, err = ENOITEM;
const item_type *itype; const item_type *itype;
init_order(ord); init_order(ord);
t = getstrtoken(); t = gettoken(token, sizeof(token));
n = atoi((const char *)t); n = atoi((const char *)t);
if (n == 0) { if (n == 0) {
if (isparam(t, u->faction->locale, P_ANY)) { if (isparam(t, u->faction->locale, P_ANY)) {
/* BENUTZE ALLES Yanxspirit */ /* BENUTZE ALLES Yanxspirit */
n = INT_MAX; n = INT_MAX;
t = getstrtoken(); t = gettoken(token, sizeof(token));
} }
else { else {
/* BENUTZE Yanxspirit */ /* BENUTZE Yanxspirit */
@ -3831,7 +3819,7 @@ int use_cmd(unit * u, struct order *ord)
} }
else { else {
/* BENUTZE 42 Yanxspirit */ /* BENUTZE 42 Yanxspirit */
t = getstrtoken(); t = gettoken(token, sizeof(token));
} }
itype = t ? finditemtype(t, u->faction->locale) : NULL; itype = t ? finditemtype(t, u->faction->locale) : NULL;
@ -3913,20 +3901,21 @@ int pay_cmd(unit * u, struct order *ord)
static int reserve_i(unit * u, struct order *ord, int flags) static int reserve_i(unit * u, struct order *ord, int flags)
{ {
char token[128];
if (u->number > 0 && (urace(u)->ec_flags & GETITEM)) { if (u->number > 0 && (urace(u)->ec_flags & GETITEM)) {
int use, count, para; int use, count, para;
const item_type *itype; const item_type *itype;
const char *s; const char *s;
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
count = s ? atoip(s) : 0; 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;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
itype = s ? finditemtype(s, u->faction->locale) : 0; itype = s ? finditemtype(s, u->faction->locale) : 0;
if (itype == NULL) if (itype == NULL)
return 0; return 0;
@ -3956,19 +3945,20 @@ int reserve_self(unit * u, struct order *ord) {
int claim_cmd(unit * u, struct order *ord) int claim_cmd(unit * u, struct order *ord)
{ {
char token[128];
const char *t; const char *t;
int n; int n;
const item_type *itype; const item_type *itype;
init_order(ord); init_order(ord);
t = getstrtoken(); t = gettoken(token, sizeof(token));
n = atoi((const char *)t); n = atoi((const char *)t);
if (n == 0) { if (n == 0) {
n = 1; n = 1;
} }
else { else {
t = getstrtoken(); t = gettoken(token, sizeof(token));
} }
itype = finditemtype(t, u->faction->locale); itype = finditemtype(t, u->faction->locale);

View File

@ -2495,6 +2495,7 @@ static bool is_moving_ship(const region * r, ship * sh)
static castorder *cast_cmd(unit * u, order * ord) static castorder *cast_cmd(unit * u, order * ord)
{ {
char token[128];
region *r = u->region; region *r = u->region;
region *target_r = r; region *target_r = r;
int level, range; int level, range;
@ -2518,7 +2519,7 @@ static castorder *cast_cmd(unit * u, order * ord)
level = eff_skill(u, SK_MAGIC, r); level = eff_skill(u, SK_MAGIC, r);
init_order(ord); init_order(ord);
s = getstrtoken(); s = gettoken(token, sizeof(token));
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 ' */
if (param == P_LEVEL) { if (param == P_LEVEL) {
@ -2529,7 +2530,7 @@ static castorder *cast_cmd(unit * u, order * ord)
cmistake(u, ord, 10, MSG_MAGIC); cmistake(u, ord, 10, MSG_MAGIC);
return 0; return 0;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
param = findparam(s, u->faction->locale); param = findparam(s, u->faction->locale);
} }
if (param == P_REGION) { if (param == P_REGION) {
@ -2546,7 +2547,7 @@ static castorder *cast_cmd(unit * u, order * ord)
"unit region command", u, u->region, ord)); "unit region command", u, u->region, ord));
return 0; return 0;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
param = findparam(s, u->faction->locale); param = findparam(s, u->faction->locale);
} }
/* für Syntax ' REGION x y STUFE z ' /* für Syntax ' REGION x y STUFE z '
@ -2559,7 +2560,7 @@ static castorder *cast_cmd(unit * u, order * ord)
cmistake(u, ord, 10, MSG_MAGIC); cmistake(u, ord, 10, MSG_MAGIC);
return 0; return 0;
} }
s = getstrtoken(); s = gettoken(token, sizeof(token));
} }
if (!s || !s[0] || strlen(s) == 0) { if (!s || !s[0] || strlen(s) == 0) {
/* Fehler "Es wurde kein Zauber angegeben" */ /* Fehler "Es wurde kein Zauber angegeben" */
@ -2692,7 +2693,7 @@ static castorder *cast_cmd(unit * u, order * ord)
char **params = (char**)malloc(2 * sizeof(char *)); char **params = (char**)malloc(2 * sizeof(char *));
int p = 0, size = 2; int p = 0, size = 2;
for (;;) { for (;;) {
s = getstrtoken(); s = gettoken(token, sizeof(token));
if (!s || *s == 0) if (!s || *s == 0)
break; break;
if (p + 1 >= size) { if (p + 1 >= size) {
@ -2935,7 +2936,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
if (sb) { if (sb) {
select_spellbook(&tokens, sb, lang); select_spellbook(&tokens, sb, lang);
} }
#if 0 // TODO: some familiars can cast spells from the mage's spellbook?
u = get_familiar_mage(u); u = get_familiar_mage(u);
if (u) { if (u) {
sb = unit_get_spellbook(u); sb = unit_get_spellbook(u);
@ -2943,6 +2944,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
select_spellbook(&tokens, sb, lang); select_spellbook(&tokens, sb, lang);
} }
} }
#endif
if (tokens) { if (tokens) {
variant token; variant token;

View File

@ -1156,7 +1156,7 @@ static void cycle_route(order * ord, unit * u, int gereist)
int bytes, cm = 0; int bytes, cm = 0;
char tail[1024], *bufp = tail; char tail[1024], *bufp = tail;
char neworder[2048]; char neworder[2048];
const char *token; char token[128];
direction_t d = NODIRECTION; direction_t d = NODIRECTION;
bool paused = false; bool paused = false;
bool pause; bool pause;
@ -1171,11 +1171,12 @@ static void cycle_route(order * ord, unit * u, int gereist)
neworder[0] = 0; neworder[0] = 0;
for (cm = 0;; ++cm) { for (cm = 0;; ++cm) {
const char *s;
const struct locale *lang = u->faction->locale; const struct locale *lang = u->faction->locale;
pause = false; pause = false;
token = getstrtoken(); s = gettoken(token, sizeof(token));
if (token && *token) { if (s && *s) {
d = get_direction(token, lang); d = get_direction(s, lang);
if (d == D_PAUSE) { if (d == D_PAUSE) {
pause = true; pause = true;
} }
@ -1448,11 +1449,12 @@ static void make_route(unit * u, order * ord, region_list ** routep)
region_list **iroute = routep; region_list **iroute = routep;
region *current = u->region; region *current = u->region;
region *next = NULL; region *next = NULL;
const char *token = getstrtoken(); char token[128];
int error = movewhere(u, token, current, &next); const char *s = gettoken(token, sizeof(token));
int error = movewhere(u, s, current, &next);
if (error != E_MOVE_OK) { if (error != E_MOVE_OK) {
message *msg = movement_error(u, token, ord, error); message *msg = movement_error(u, s, ord, error);
if (msg != NULL) { if (msg != NULL) {
add_message(&u->faction->msgs, msg); add_message(&u->faction->msgs, msg);
msg_release(msg); msg_release(msg);
@ -1471,10 +1473,10 @@ static void make_route(unit * u, order * ord, region_list ** routep)
iroute = &(*iroute)->next; iroute = &(*iroute)->next;
current = next; current = next;
token = getstrtoken(); s = gettoken(token, sizeof(token));
error = movewhere(u, token, current, &next); error = movewhere(u, s, current, &next);
if (error) { if (error) {
message *msg = movement_error(u, token, ord, error); message *msg = movement_error(u, s, ord, error);
if (msg != NULL) { if (msg != NULL) {
add_message(&u->faction->msgs, msg); add_message(&u->faction->msgs, msg);
msg_release(msg); msg_release(msg);
@ -2615,7 +2617,7 @@ static int hunt(unit * u, order * ord)
/* In command steht jetzt das NACH-Kommando. */ /* In command steht jetzt das NACH-Kommando. */
/* NACH ignorieren und Parsing initialisieren. */ /* NACH ignorieren und Parsing initialisieren. */
init_tokens_str(command, NULL); init_tokens_str(command);
getstrtoken(); getstrtoken();
/* NACH ausführen */ /* NACH ausführen */
move(u, false); move(u, false);

View File

@ -58,7 +58,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
static skill_t getskill(const struct locale *lang) static skill_t getskill(const struct locale *lang)
{ {
const char * s = getstrtoken(); char token[128];
const char * s = gettoken(token, sizeof(token));
return s ? get_skill(s, lang) : NOSKILL; return s ? get_skill(s, lang) : NOSKILL;
} }

View File

@ -48,6 +48,7 @@ int RunAllTests(void)
RUN_TESTS(suite, base36); RUN_TESTS(suite, base36);
RUN_TESTS(suite, bsdstring); RUN_TESTS(suite, bsdstring);
RUN_TESTS(suite, functions); RUN_TESTS(suite, functions);
RUN_TESTS(suite, parser);
RUN_TESTS(suite, umlaut); RUN_TESTS(suite, umlaut);
RUN_TESTS(suite, unicode); RUN_TESTS(suite, unicode);
RUN_TESTS(suite, strings); RUN_TESTS(suite, strings);

View File

@ -2,6 +2,7 @@ project(util C)
SET(_TEST_FILES SET(_TEST_FILES
base36.test.c base36.test.c
parser.test.c
attrib.test.c attrib.test.c
strings.test.c strings.test.c
bsdstring.test.c bsdstring.test.c

View File

@ -15,7 +15,6 @@
typedef struct parser_state { typedef struct parser_state {
const char *current_token; const char *current_token;
char *current_cmd;
struct parser_state *next; struct parser_state *next;
} parser_state; } parser_state;
@ -50,22 +49,17 @@ static int eatwhitespace_c(const char **str_p)
return ret; return ret;
} }
void init_tokens_str(const char *initstr, char *cmd) void init_tokens_str(const char *initstr)
{ {
if (states == NULL) { if (states == NULL) {
states = malloc(sizeof(parser_state)); states = malloc(sizeof(parser_state));
} }
else if (states->current_cmd && states->current_cmd!=cmd) {
free(states->current_cmd);
}
states->current_cmd = cmd;
states->current_token = initstr; states->current_token = initstr;
} }
void parser_pushstate(void) void parser_pushstate(void)
{ {
parser_state *new_state = malloc(sizeof(parser_state)); parser_state *new_state = malloc(sizeof(parser_state));
new_state->current_cmd = NULL;
new_state->current_token = NULL; new_state->current_token = NULL;
new_state->next = states; new_state->next = states;
states = new_state; states = new_state;
@ -74,8 +68,6 @@ void parser_pushstate(void)
void parser_popstate(void) void parser_popstate(void)
{ {
parser_state *new_state = states->next; parser_state *new_state = states->next;
if (states->current_cmd != NULL)
free(states->current_cmd);
free(states); free(states);
states = new_state; states = new_state;
} }
@ -128,9 +120,8 @@ void skip_token(void)
} }
} }
const char *parse_token(const char **str) char *parse_token(const char **str, char *lbuf, size_t len)
{ {
static char lbuf[MAXTOKENSIZE]; /* STATIC_RESULT: used for return, not across calls */
char *cursor = lbuf; char *cursor = lbuf;
char quotechar = 0; char quotechar = 0;
bool escape = false; bool escape = false;
@ -141,9 +132,12 @@ const char *parse_token(const char **str)
} }
eatwhitespace_c(&ctoken); eatwhitespace_c(&ctoken);
if (!*ctoken) { if (!*ctoken) {
if (len > 0) {
*cursor = 0;
}
return 0; return 0;
} }
while (*ctoken && cursor - lbuf < MAXTOKENSIZE - 1) { while (*ctoken && cursor-len < lbuf-1) {
ucs4_t ucs; ucs4_t ucs;
size_t len; size_t len;
bool copy = false; bool copy = false;
@ -152,7 +146,8 @@ const char *parse_token(const char **str)
if (~utf8_character & 0x80) { if (~utf8_character & 0x80) {
ucs = utf8_character; ucs = utf8_character;
len = 1; len = 1;
} else { }
else {
int ret = unicode_utf8_to_ucs4(&ucs, ctoken, &len); int ret = unicode_utf8_to_ucs4(&ucs, ctoken, &len);
if (ret != 0) { if (ret != 0) {
log_warning("illegal character sequence in UTF8 string: %s\n", ctoken); log_warning("illegal character sequence in UTF8 string: %s\n", ctoken);
@ -162,27 +157,34 @@ const char *parse_token(const char **str)
if (escape) { if (escape) {
copy = true; copy = true;
escape = false; escape = false;
} else if (iswxspace((wint_t) ucs)) { }
else if (iswxspace((wint_t)ucs)) {
if (quotechar == 0) if (quotechar == 0)
break; break;
copy = true; copy = true;
} else if (utf8_character == '"' || utf8_character == '\'') { }
else if (utf8_character == '"' || utf8_character == '\'') {
if (utf8_character == quotechar) { if (utf8_character == quotechar) {
++ctoken; ++ctoken;
break; break;
} else if (quotechar == 0) { }
else if (quotechar == 0) {
quotechar = utf8_character; quotechar = utf8_character;
++ctoken; ++ctoken;
} else { }
else {
*cursor++ = *ctoken++; *cursor++ = *ctoken++;
} }
} else if (utf8_character == SPACE_REPLACEMENT) { }
else if (utf8_character == SPACE_REPLACEMENT) {
*cursor++ = ' '; *cursor++ = ' ';
++ctoken; ++ctoken;
} else if (utf8_character == ESCAPE_CHAR) { }
else if (utf8_character == ESCAPE_CHAR) {
escape = true; escape = true;
++ctoken; ++ctoken;
} else { }
else {
copy = true; copy = true;
} }
if (copy) { if (copy) {
@ -192,22 +194,62 @@ const char *parse_token(const char **str)
} }
} }
assert(cursor - len < lbuf - 1); // TODO: handle too-small buffers
*cursor = '\0'; *cursor = '\0';
*str = ctoken; *str = ctoken;
return lbuf; return lbuf;
} }
const char *parse_token_depr(const char **str)
{
static char lbuf[MAXTOKENSIZE]; /* STATIC_RESULT: used for return, not across calls */
return parse_token(str, lbuf, MAXTOKENSIZE);
}
const char *getstrtoken(void) const char *getstrtoken(void)
{ {
return parse_token((const char **)&states->current_token); char lbuf[MAXTOKENSIZE];
return parse_token((const char **)&states->current_token, lbuf, MAXTOKENSIZE);
}
const char *gettoken(char *lbuf, size_t bufsize)
{
return parse_token((const char **)&states->current_token, lbuf, bufsize);
}
int getint(void)
{
char token[16];
const char * s = gettoken(token, sizeof(token));
return s ? atoi(s) : 0;
}
unsigned int getuint(void)
{
int n = getint();
return (n < 0) ? 0 : n;
} }
int getid(void) int getid(void)
{ {
const char *str = getstrtoken(); char token[16];
const char *str = gettoken(token, sizeof(token));
int i = str ? atoi36(str) : 0; int i = str ? atoi36(str) : 0;
if (i < 0) { if (i < 0) {
return -1; return -1;
} }
return i; return i;
} }
unsigned int atoip(const char *s)
{
int n;
assert(s);
n = atoi(s);
if (n < 0)
n = 0;
return n;
}

View File

@ -14,14 +14,20 @@
extern "C" { extern "C" {
#endif #endif
void init_tokens_str(const char *initstr, char *cmd); /* initialize token parsing, take ownership of cmd */ void init_tokens_str(const char *initstr); /* initialize token parsing */
void skip_token(void); void skip_token(void);
const char *parse_token(const char **str); const char *parse_token_depr(const char **str);
char *parse_token(const char **str, char *buffer, size_t bufsize);
void parser_pushstate(void); void parser_pushstate(void);
void parser_popstate(void); void parser_popstate(void);
bool parser_end(void); bool parser_end(void);
const char *getstrtoken(void); const char *getstrtoken(void);
const char *gettoken(char *lbuf, size_t bufsize);
unsigned int getuint(void);
int getint(void);
int getid(void); int getid(void);
unsigned int atoip(const char *s);
#define getshipid() getid() #define getshipid() getid()
#define getfactionid() getid() #define getfactionid() getid()

59
src/util/parser.test.c Normal file
View File

@ -0,0 +1,59 @@
#include <platform.h>
#include "parser.h"
#include <CuTest.h>
static void test_gettoken(CuTest *tc) {
char token[128];
init_tokens_str("HELP ONE TWO THREE");
CuAssertStrEquals(tc, "HELP", gettoken(token, sizeof(token)));
CuAssertStrEquals(tc, "HELP", token);
CuAssertStrEquals(tc, "ONE", gettoken(token, sizeof(token)));
CuAssertStrEquals(tc, "TWO", gettoken(token, sizeof(token)));
CuAssertStrEquals(tc, "THREE", gettoken(token, sizeof(token)));
CuAssertPtrEquals(tc, NULL, (void *)gettoken(token, sizeof(token)));
CuAssertStrEquals(tc, "", token);
}
static void test_skip_token(CuTest *tc) {
char token[128];
init_tokens_str("HELP ONE TWO THREE");
skip_token();
CuAssertStrEquals(tc, "ONE", gettoken(token, sizeof(token)));
}
static void test_getintegers(CuTest *tc) {
init_tokens_str("ii 666 666 -42 -42");
CuAssertIntEquals(tc, 666, getid());
CuAssertIntEquals(tc, 666, getint());
CuAssertIntEquals(tc, 666, getuint());
CuAssertIntEquals(tc, -42, getint());
CuAssertIntEquals(tc, 0, getuint());
CuAssertIntEquals(tc, 0, getint());
}
static void test_getstrtoken(CuTest *tc) {
init_tokens_str("HELP ONE TWO THREE");
CuAssertStrEquals(tc, "HELP", getstrtoken());
CuAssertStrEquals(tc, "ONE", getstrtoken());
CuAssertStrEquals(tc, "TWO", getstrtoken());
CuAssertStrEquals(tc, "THREE", getstrtoken());
CuAssertPtrEquals(tc, NULL, (void *)getstrtoken());
}
static void test_atoip(CuTest *tc) {
CuAssertIntEquals(tc, 42, atoip("42"));
CuAssertIntEquals(tc, 0, atoip("-42"));
CuAssertIntEquals(tc, 0, atoip("NOPE"));
}
CuSuite *get_parser_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_atoip);
SUITE_ADD_TEST(suite, test_skip_token);
SUITE_ADD_TEST(suite, test_gettoken);
SUITE_ADD_TEST(suite, test_getintegers);
SUITE_ADD_TEST(suite, test_getstrtoken);
return suite;
}