forked from github/server
make getstrtoken() return null at EOL, kill init_tokens.
init_order all the things! added a bunch of new assertions to cover for oversights. added some new tests for order parsing.
This commit is contained in:
parent
ee2363a4d9
commit
808f343e34
|
@ -502,8 +502,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
const struct race *rc = u_race(u);
|
||||
const char *str;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
n = getuint();
|
||||
|
||||
if (u->number == 0) {
|
||||
|
@ -666,8 +665,7 @@ int give_control_cmd(unit * u, order * ord)
|
|||
const char *s;
|
||||
param_t p;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
u2 = getunit(r, u->faction);
|
||||
s = getstrtoken();
|
||||
p = findparam(s, u->faction->locale);
|
||||
|
@ -730,11 +728,10 @@ static void give_cmd(unit * u, order * ord)
|
|||
plane *pl;
|
||||
message *msg;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
u2 = getunit(r, u->faction);
|
||||
s = getstrtoken();
|
||||
n = atoip(s);
|
||||
n = s ? atoip(s) : 0;
|
||||
p = (n > 0) ? NOPARAM : findparam(s, u->faction->locale);
|
||||
|
||||
/* first, do all the ones that do not require HELP_GIVE or CONTACT */
|
||||
|
@ -857,7 +854,7 @@ static void give_cmd(unit * u, order * ord)
|
|||
return;
|
||||
}
|
||||
s = getstrtoken();
|
||||
if (*s == 0) { /* GIVE ALL items that you have */
|
||||
if (!s || *s == 0) { /* GIVE ALL items that you have */
|
||||
|
||||
/* do these checks once, not for each item we have: */
|
||||
if (!(u_race(u)->ec_flags & GIVEITEM) && u2 != NULL) {
|
||||
|
@ -990,8 +987,7 @@ static int forget_cmd(unit * u, order * ord)
|
|||
return 0;
|
||||
}
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) {
|
||||
|
@ -1800,9 +1796,10 @@ int make_cmd(unit * u, struct order *ord)
|
|||
const char *s;
|
||||
const struct locale *lang = u->faction->locale;
|
||||
char ibuf[16];
|
||||
keyword_t kwd;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_MAKE);
|
||||
s = getstrtoken();
|
||||
|
||||
m = atoi((const char *)s);
|
||||
|
@ -2060,6 +2057,8 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|||
attrib *a;
|
||||
const item_type *itype = NULL;
|
||||
const luxury_type *ltype = NULL;
|
||||
keyword_t kwd;
|
||||
|
||||
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
|
||||
cmistake(u, ord, 69, MSG_INCOME);
|
||||
return;
|
||||
|
@ -2071,8 +2070,8 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|||
/* Im Augenblick kann man nur 1 Produkt kaufen. expandbuying ist aber
|
||||
* schon dafür ausgerüstet, mehrere Produkte zu kaufen. */
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_BUY);
|
||||
n = getuint();
|
||||
if (!n) {
|
||||
cmistake(u, ord, 26, MSG_COMMERCE);
|
||||
|
@ -2351,10 +2350,11 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
{
|
||||
bool unlimited = true;
|
||||
const item_type *itype;
|
||||
const luxury_type *ltype = NULL;
|
||||
const luxury_type *ltype;
|
||||
int n;
|
||||
region *r = u->region;
|
||||
const char *s;
|
||||
keyword_t kwd;
|
||||
|
||||
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
|
||||
cmistake(u, ord, 69, MSG_INCOME);
|
||||
|
@ -2363,8 +2363,8 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
/* sellorders sind KEIN array, weil für alle items DIE SELBE resource
|
||||
* (das geld der region) aufgebraucht wird. */
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_SELL);
|
||||
s = getstrtoken();
|
||||
|
||||
if (findparam(s, u->faction->locale) == P_ANY) {
|
||||
|
@ -2424,9 +2424,8 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
return false;
|
||||
}
|
||||
s = getstrtoken();
|
||||
itype = finditemtype(s, u->faction->locale);
|
||||
if (itype != NULL)
|
||||
ltype = resource2luxury(itype->rtype);
|
||||
itype = s ? finditemtype(s, u->faction->locale) : 0;
|
||||
ltype = itype ? resource2luxury(itype->rtype) : 0;
|
||||
if (ltype == NULL) {
|
||||
cmistake(u, ord, 126, MSG_COMMERCE);
|
||||
return false;
|
||||
|
@ -2764,8 +2763,7 @@ static void breed_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
|
||||
/* züchte [<anzahl>] <parameter> */
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
(void)init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
m = atoi((const char *)s);
|
||||
|
@ -2830,9 +2828,10 @@ static const char *rough_amount(int a, int m)
|
|||
static void research_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
region *r = u->region;
|
||||
keyword_t kwd;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_RESEARCH);
|
||||
/*
|
||||
const char *s = getstrtoken();
|
||||
|
||||
|
@ -2908,6 +2907,10 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders)
|
|||
region *r = u->region;
|
||||
faction *f = NULL;
|
||||
message * msg;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_STEAL);
|
||||
|
||||
assert(skill_enabled(SK_PERCEPTION) && skill_enabled(SK_STEALTH));
|
||||
|
||||
|
@ -2916,8 +2919,6 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders)
|
|||
ADDMSG(&u->faction->msgs, msg);
|
||||
return;
|
||||
}
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
id = read_unitid(u->faction, r);
|
||||
u2 = findunitr(r, id);
|
||||
|
||||
|
@ -3040,7 +3041,10 @@ void entertain_cmd(unit * u, struct order *ord)
|
|||
request *o;
|
||||
static int entertainbase = 0;
|
||||
static int entertainperlevel = 0;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_ENTERTAIN);
|
||||
if (!entertainbase) {
|
||||
const char *str = get_param(global.parameters, "entertain.base");
|
||||
entertainbase = str ? atoi(str) : 0;
|
||||
|
@ -3073,8 +3077,6 @@ void entertain_cmd(unit * u, struct order *ord)
|
|||
u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT)
|
||||
* entertainperlevel);
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
max_e = getuint();
|
||||
if (max_e != 0) {
|
||||
u->wants = _min(u->wants, max_e);
|
||||
|
@ -3214,6 +3216,10 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders)
|
|||
int n;
|
||||
request *o;
|
||||
int max;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_TAX);
|
||||
|
||||
if (!humanoidrace(u_race(u)) && !is_monsters(u->faction)) {
|
||||
cmistake(u, ord, 228, MSG_INCOME);
|
||||
|
@ -3236,8 +3242,6 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders)
|
|||
return;
|
||||
}
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
max = getuint();
|
||||
|
||||
if (max == 0)
|
||||
|
|
324
src/items.c
324
src/items.c
|
@ -32,39 +32,39 @@
|
|||
#define MAXGAIN 15
|
||||
static int
|
||||
use_studypotion(struct unit *u, const struct item_type *itype, int amount,
|
||||
struct order *ord)
|
||||
struct order *ord)
|
||||
{
|
||||
if (getkeyword(u->thisorder) == K_STUDY) {
|
||||
skill_t sk;
|
||||
skill *sv;
|
||||
if (init_order(u->thisorder) == K_STUDY) {
|
||||
skill_t sk;
|
||||
skill *sv;
|
||||
|
||||
init_tokens(u->thisorder);
|
||||
skip_token();
|
||||
sk = get_skill(getstrtoken(), u->faction->locale);
|
||||
sv = unit_skill(u, sk);
|
||||
sk = get_skill(getstrtoken(), u->faction->locale);
|
||||
sv = unit_skill(u, sk);
|
||||
|
||||
if (sv && sv->level > 2) {
|
||||
/* TODO: message */
|
||||
} else if (study_cost(u, sk) > 0) {
|
||||
/* TODO: message */
|
||||
} else {
|
||||
attrib *a = a_find(u->attribs, &at_learning);
|
||||
teaching_info *teach;
|
||||
if (a == NULL) {
|
||||
a = a_add(&u->attribs, a_new(&at_learning));
|
||||
}
|
||||
teach = (teaching_info *) a->data.v;
|
||||
if (amount > MAXGAIN)
|
||||
amount = MAXGAIN;
|
||||
teach->value += amount * 30;
|
||||
if (teach->value > MAXGAIN * 30) {
|
||||
teach->value = MAXGAIN * 30;
|
||||
}
|
||||
i_change(&u->items, itype, -amount);
|
||||
return 0;
|
||||
if (sv && sv->level > 2) {
|
||||
/* TODO: message */
|
||||
}
|
||||
else if (study_cost(u, sk) > 0) {
|
||||
/* TODO: message */
|
||||
}
|
||||
else {
|
||||
attrib *a = a_find(u->attribs, &at_learning);
|
||||
teaching_info *teach;
|
||||
if (a == NULL) {
|
||||
a = a_add(&u->attribs, a_new(&at_learning));
|
||||
}
|
||||
teach = (teaching_info *)a->data.v;
|
||||
if (amount > MAXGAIN)
|
||||
amount = MAXGAIN;
|
||||
teach->value += amount * 30;
|
||||
if (teach->value > MAXGAIN * 30) {
|
||||
teach->value = MAXGAIN * 30;
|
||||
}
|
||||
i_change(&u->items, itype, -amount);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return EUNUSABLE;
|
||||
return EUNUSABLE;
|
||||
}
|
||||
|
||||
/* END studypotion */
|
||||
|
@ -73,27 +73,27 @@ use_studypotion(struct unit *u, const struct item_type *itype, int amount,
|
|||
#define SPEEDSAIL_EFFECT 1
|
||||
static int
|
||||
use_speedsail(struct unit *u, const struct item_type *itype, int amount,
|
||||
struct order *ord)
|
||||
struct order *ord)
|
||||
{
|
||||
curse *c;
|
||||
float effect;
|
||||
ship *sh = u->ship;
|
||||
if (!sh) {
|
||||
cmistake(u, ord, 20, MSG_MOVE);
|
||||
return -1;
|
||||
}
|
||||
curse *c;
|
||||
float effect;
|
||||
ship *sh = u->ship;
|
||||
if (!sh) {
|
||||
cmistake(u, ord, 20, MSG_MOVE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
effect = SPEEDSAIL_EFFECT;
|
||||
c =
|
||||
create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect,
|
||||
0);
|
||||
c_setflag(c, CURSE_NOAGE);
|
||||
effect = SPEEDSAIL_EFFECT;
|
||||
c =
|
||||
create_curse(u, &sh->attribs, ct_find("shipspeedup"), 20, INT_MAX, effect,
|
||||
0);
|
||||
c_setflag(c, CURSE_NOAGE);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u,
|
||||
SPEEDSAIL_EFFECT));
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit speed", u,
|
||||
SPEEDSAIL_EFFECT));
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* END speedsail */
|
||||
|
@ -103,113 +103,113 @@ use_speedsail(struct unit *u, const struct item_type *itype, int amount,
|
|||
* Antimagiezone, die zwei Runden bestehen bleibt */
|
||||
static int
|
||||
use_antimagiccrystal(unit * u, const struct item_type *itype, int amount,
|
||||
struct order *ord)
|
||||
struct order *ord)
|
||||
{
|
||||
region *r = u->region;
|
||||
const resource_type *rt_crystal = NULL;
|
||||
int i;
|
||||
region *r = u->region;
|
||||
const resource_type *rt_crystal = NULL;
|
||||
int i;
|
||||
|
||||
if (rt_crystal == NULL) {
|
||||
rt_crystal = rt_find("antimagic");
|
||||
assert(rt_crystal != NULL);
|
||||
}
|
||||
for (i = 0; i != amount; ++i) {
|
||||
int effect, duration = 2;
|
||||
float force;
|
||||
spell *sp = find_spell("antimagiczone");
|
||||
attrib **ap = &r->attribs;
|
||||
unused_arg(ord);
|
||||
assert(sp);
|
||||
|
||||
/* Reduziert die Stärke jedes Spruchs um effect */
|
||||
effect = 5;
|
||||
|
||||
/* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus.
|
||||
* Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone
|
||||
* um seine Stufe */
|
||||
force = (float)effect * 20; /* Stufe 5 =~ 100 */
|
||||
|
||||
/* Regionszauber auflösen */
|
||||
while (*ap && force > 0) {
|
||||
curse *c;
|
||||
attrib *a = *ap;
|
||||
if (!fval(a->type, ATF_CURSE)) {
|
||||
do {
|
||||
ap = &(*ap)->next;
|
||||
} while (*ap && a->type == (*ap)->type);
|
||||
continue;
|
||||
}
|
||||
c = (curse *) a->data.v;
|
||||
|
||||
/* Immunität prüfen */
|
||||
if (c_flags(c) & CURSE_IMMUNE) {
|
||||
do {
|
||||
ap = &(*ap)->next;
|
||||
} while (*ap && a->type == (*ap)->type);
|
||||
continue;
|
||||
}
|
||||
|
||||
force = destr_curse(c, effect, force);
|
||||
if (c->vigour <= 0) {
|
||||
a_remove(&r->attribs, a);
|
||||
}
|
||||
if (*ap)
|
||||
ap = &(*ap)->next;
|
||||
if (rt_crystal == NULL) {
|
||||
rt_crystal = rt_find("antimagic");
|
||||
assert(rt_crystal != NULL);
|
||||
}
|
||||
for (i = 0; i != amount; ++i) {
|
||||
int effect, duration = 2;
|
||||
float force;
|
||||
spell *sp = find_spell("antimagiczone");
|
||||
attrib **ap = &r->attribs;
|
||||
unused_arg(ord);
|
||||
assert(sp);
|
||||
|
||||
if (force > 0) {
|
||||
create_curse(u, &r->attribs, ct_find("antimagiczone"), (float)force, duration,
|
||||
(float)effect, 0);
|
||||
/* Reduziert die Stärke jedes Spruchs um effect */
|
||||
effect = 5;
|
||||
|
||||
/* Hält Sprüche bis zu einem summierten Gesamtlevel von power aus.
|
||||
* Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone
|
||||
* um seine Stufe */
|
||||
force = (float)effect * 20; /* Stufe 5 =~ 100 */
|
||||
|
||||
/* Regionszauber auflösen */
|
||||
while (*ap && force > 0) {
|
||||
curse *c;
|
||||
attrib *a = *ap;
|
||||
if (!fval(a->type, ATF_CURSE)) {
|
||||
do {
|
||||
ap = &(*ap)->next;
|
||||
} while (*ap && a->type == (*ap)->type);
|
||||
continue;
|
||||
}
|
||||
c = (curse *)a->data.v;
|
||||
|
||||
/* Immunität prüfen */
|
||||
if (c_flags(c) & CURSE_IMMUNE) {
|
||||
do {
|
||||
ap = &(*ap)->next;
|
||||
} while (*ap && a->type == (*ap)->type);
|
||||
continue;
|
||||
}
|
||||
|
||||
force = destr_curse(c, effect, force);
|
||||
if (c->vigour <= 0) {
|
||||
a_remove(&r->attribs, a);
|
||||
}
|
||||
if (*ap)
|
||||
ap = &(*ap)->next;
|
||||
}
|
||||
|
||||
if (force > 0) {
|
||||
create_curse(u, &r->attribs, ct_find("antimagiczone"), (float)force, duration,
|
||||
(float)effect, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
use_pooled(u, rt_crystal, GET_DEFAULT, amount);
|
||||
ADDMSG(&u->faction->msgs, msg_message("use_antimagiccrystal",
|
||||
"unit region", u, r));
|
||||
return 0;
|
||||
use_pooled(u, rt_crystal, GET_DEFAULT, amount);
|
||||
ADDMSG(&u->faction->msgs, msg_message("use_antimagiccrystal",
|
||||
"unit region", u, r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
use_instantartsculpture(struct unit *u, const struct item_type *itype,
|
||||
int amount, struct order *ord)
|
||||
int amount, struct order *ord)
|
||||
{
|
||||
building *b;
|
||||
building *b;
|
||||
|
||||
if (u->region->land == NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
|
||||
return -1;
|
||||
}
|
||||
if (u->region->land == NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
|
||||
return -1;
|
||||
}
|
||||
|
||||
b = new_building(bt_find("artsculpture"), u->region, u->faction->locale);
|
||||
b->size = 100;
|
||||
b = new_building(bt_find("artsculpture"), u->region, u->faction->locale);
|
||||
b->size = 100;
|
||||
|
||||
ADDMSG(&u->region->msgs, msg_message("artsculpture_create", "unit region",
|
||||
u, u->region));
|
||||
ADDMSG(&u->region->msgs, msg_message("artsculpture_create", "unit region",
|
||||
u, u->region));
|
||||
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
use_instantartacademy(struct unit *u, const struct item_type *itype,
|
||||
int amount, struct order *ord)
|
||||
int amount, struct order *ord)
|
||||
{
|
||||
building *b;
|
||||
building *b;
|
||||
|
||||
if (u->region->land == NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
|
||||
return -1;
|
||||
}
|
||||
if (u->region->land == NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_onlandonly", ""));
|
||||
return -1;
|
||||
}
|
||||
|
||||
b = new_building(bt_find("artacademy"), u->region, u->faction->locale);
|
||||
b->size = 100;
|
||||
b = new_building(bt_find("artacademy"), u->region, u->faction->locale);
|
||||
b->size = 100;
|
||||
|
||||
ADDMSG(&u->region->msgs, msg_message("artacademy_create", "unit region", u,
|
||||
u->region));
|
||||
ADDMSG(&u->region->msgs, msg_message("artacademy_create", "unit region", u,
|
||||
u->region));
|
||||
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BAGPIPEFRACTION dice_rand("2d4+2")
|
||||
|
@ -217,58 +217,58 @@ use_instantartacademy(struct unit *u, const struct item_type *itype,
|
|||
|
||||
static int
|
||||
use_bagpipeoffear(struct unit *u, const struct item_type *itype,
|
||||
int amount, struct order *ord)
|
||||
int amount, struct order *ord)
|
||||
{
|
||||
int money;
|
||||
int money;
|
||||
|
||||
if (get_curse(u->region->attribs, ct_find("depression"))) {
|
||||
cmistake(u, ord, 58, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
if (get_curse(u->region->attribs, ct_find("depression"))) {
|
||||
cmistake(u, ord, 58, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
money = entertainmoney(u->region) / BAGPIPEFRACTION;
|
||||
change_money(u, money);
|
||||
rsetmoney(u->region, rmoney(u->region) - money);
|
||||
money = entertainmoney(u->region) / BAGPIPEFRACTION;
|
||||
change_money(u, money);
|
||||
rsetmoney(u->region, rmoney(u->region) - money);
|
||||
|
||||
create_curse(u, &u->region->attribs, ct_find("depression"),
|
||||
20, BAGPIPEDURATION, 0.0, 0);
|
||||
create_curse(u, &u->region->attribs, ct_find("depression"),
|
||||
20, BAGPIPEDURATION, 0.0, 0);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
|
||||
"unit region command money", u, u->region, ord, money));
|
||||
ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
|
||||
"unit region command money", u, u->region, ord, money));
|
||||
|
||||
ADDMSG(&u->region->msgs, msg_message("bagpipeoffear_region",
|
||||
"unit money", u, money));
|
||||
ADDMSG(&u->region->msgs, msg_message("bagpipeoffear_region",
|
||||
"unit money", u, money));
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
use_aurapotion50(struct unit *u, const struct item_type *itype,
|
||||
int amount, struct order *ord)
|
||||
int amount, struct order *ord)
|
||||
{
|
||||
if (!is_mage(u)) {
|
||||
cmistake(u, ord, 214, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
if (!is_mage(u)) {
|
||||
cmistake(u, ord, 214, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
|
||||
change_spellpoints(u, 50);
|
||||
change_spellpoints(u, 50);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("aurapotion50",
|
||||
"unit region command", u, u->region, ord));
|
||||
ADDMSG(&u->faction->msgs, msg_message("aurapotion50",
|
||||
"unit region command", u, u->region, ord));
|
||||
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
use_pooled(u, itype->rtype, GET_DEFAULT, 1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void register_itemfunctions(void)
|
||||
{
|
||||
register_demonseye();
|
||||
register_item_use(use_antimagiccrystal, "use_antimagiccrystal");
|
||||
register_item_use(use_instantartsculpture, "use_instantartsculpture");
|
||||
register_item_use(use_studypotion, "use_studypotion");
|
||||
register_item_use(use_speedsail, "use_speedsail");
|
||||
register_item_use(use_instantartacademy, "use_instantartacademy");
|
||||
register_item_use(use_bagpipeoffear, "use_bagpipeoffear");
|
||||
register_item_use(use_aurapotion50, "use_aurapotion50");
|
||||
register_demonseye();
|
||||
register_item_use(use_antimagiccrystal, "use_antimagiccrystal");
|
||||
register_item_use(use_instantartsculpture, "use_instantartsculpture");
|
||||
register_item_use(use_studypotion, "use_studypotion");
|
||||
register_item_use(use_speedsail, "use_speedsail");
|
||||
register_item_use(use_instantartacademy, "use_instantartacademy");
|
||||
register_item_use(use_bagpipeoffear, "use_bagpipeoffear");
|
||||
register_item_use(use_aurapotion50, "use_aurapotion50");
|
||||
}
|
||||
|
|
|
@ -158,8 +158,7 @@ static void perform_kick(void)
|
|||
|
||||
if (al && alliance_get_leader(al) == ta->u->faction) {
|
||||
faction *f;
|
||||
init_tokens(ta->ord);
|
||||
skip_token();
|
||||
init_order(ta->ord);
|
||||
skip_token();
|
||||
f = getfaction();
|
||||
if (f && f_get_alliance(f) == al) {
|
||||
|
@ -180,8 +179,7 @@ static void perform_new(void)
|
|||
int id;
|
||||
faction *f = ta->u->faction;
|
||||
|
||||
init_tokens(ta->ord);
|
||||
skip_token();
|
||||
init_order(ta->ord);
|
||||
skip_token();
|
||||
id = getid();
|
||||
|
||||
|
@ -216,8 +214,7 @@ static void perform_transfer(void)
|
|||
|
||||
if (al && alliance_get_leader(al) == ta->u->faction) {
|
||||
faction *f;
|
||||
init_tokens(ta->ord);
|
||||
skip_token();
|
||||
init_order(ta->ord);
|
||||
skip_token();
|
||||
f = getfaction();
|
||||
if (f && f_get_alliance(f) == al) {
|
||||
|
@ -237,8 +234,7 @@ static void perform_join(void)
|
|||
faction *fj = ta->u->faction;
|
||||
int aid;
|
||||
|
||||
init_tokens(ta->ord);
|
||||
skip_token();
|
||||
init_order(ta->ord);
|
||||
skip_token();
|
||||
aid = getid();
|
||||
if (aid) {
|
||||
|
@ -250,8 +246,7 @@ static void perform_join(void)
|
|||
faction *fi = ti->u->faction;
|
||||
if (fi && f_get_alliance(fi) == al) {
|
||||
int fid;
|
||||
init_tokens(ti->ord);
|
||||
skip_token();
|
||||
init_order(ti->ord);
|
||||
skip_token();
|
||||
fid = getid();
|
||||
if (fid == fj->no) {
|
||||
|
|
|
@ -3967,8 +3967,7 @@ static bool start_battle(region * r, battle ** bp)
|
|||
|
||||
/* Ende Fehlerbehandlung Angreifer */
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
/* attackierte Einheit ermitteln */
|
||||
u2 = getunit(r, u->faction);
|
||||
|
||||
|
|
|
@ -146,8 +146,7 @@ int destroy_cmd(unit * u, struct order *ord)
|
|||
if (u->number < 1)
|
||||
return 0;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if (findparam(s, u->faction->locale) == P_ROAD) {
|
||||
|
|
|
@ -92,8 +92,7 @@ static int do_command_i(const void *keys, struct unit *u, struct order *ord)
|
|||
|
||||
void do_command(const void *keys, struct unit *u, struct order *ord)
|
||||
{
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) {
|
||||
char cmd[ORDERSIZE];
|
||||
get_command(ord, cmd, sizeof(cmd));
|
||||
|
|
|
@ -637,6 +637,7 @@ unsigned int atoip(const char *s)
|
|||
{
|
||||
int n;
|
||||
|
||||
assert(s);
|
||||
n = atoi(s);
|
||||
|
||||
if (n < 0)
|
||||
|
@ -1137,12 +1138,13 @@ const char *igetstrtoken(const char *initstr)
|
|||
|
||||
unsigned int getuint(void)
|
||||
{
|
||||
return atoip((const char *)getstrtoken());
|
||||
const char *s = getstrtoken();
|
||||
return s ? atoip(s) : 0;
|
||||
}
|
||||
|
||||
int getint(void)
|
||||
{
|
||||
return atoi((const char *)getstrtoken());
|
||||
return atoi(getstrtoken());
|
||||
}
|
||||
|
||||
const struct race *findrace(const char *s, const struct locale *lang)
|
||||
|
@ -1172,7 +1174,7 @@ param_t findparam(const char *s, const struct locale * lang)
|
|||
{
|
||||
param_t result = NOPARAM;
|
||||
char buffer[64];
|
||||
char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s);
|
||||
char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0;
|
||||
|
||||
if (str && *str) {
|
||||
int i;
|
||||
|
@ -1204,6 +1206,7 @@ param_t findparam_ex(const char *s, const struct locale * lang)
|
|||
|
||||
bool isparam(const char *s, const struct locale * lang, param_t param)
|
||||
{
|
||||
assert(s);
|
||||
if (s[0] > '@') {
|
||||
param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang);
|
||||
return p == param;
|
||||
|
@ -1855,8 +1858,8 @@ typedef struct param {
|
|||
|
||||
int getid(void)
|
||||
{
|
||||
const char *str = (const char *)getstrtoken();
|
||||
int i = atoi36(str);
|
||||
const char *str = getstrtoken();
|
||||
int i = str ? atoi36(str) : 0;
|
||||
if (i < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -2686,7 +2689,7 @@ int movewhere(const unit * u, const char *token, region * r, region ** resultp)
|
|||
region *r2;
|
||||
direction_t d;
|
||||
|
||||
if (*token == '\0') {
|
||||
if (!token || *token == '\0') {
|
||||
*resultp = NULL;
|
||||
return E_MOVE_OK;
|
||||
}
|
||||
|
|
1206
src/kernel/item.c
1206
src/kernel/item.c
File diff suppressed because it is too large
Load Diff
|
@ -2535,8 +2535,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
|||
}
|
||||
level = eff_skill(u, SK_MAGIC, r);
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
param = findparam(s, u->faction->locale);
|
||||
/* für Syntax ' STUFE x REGION y z ' */
|
||||
|
@ -2712,7 +2711,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
|||
int p = 0, size = 2;
|
||||
for (;;) {
|
||||
s = getstrtoken();
|
||||
if (*s == 0)
|
||||
if (!s || *s == 0)
|
||||
break;
|
||||
if (p + 1 >= size) {
|
||||
size *= 2;
|
||||
|
|
|
@ -1060,8 +1060,7 @@ static void cycle_route(order * ord, unit * u, int gereist)
|
|||
return;
|
||||
tail[0] = '\0';
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
neworder[0] = 0;
|
||||
for (cm = 0;; ++cm) {
|
||||
|
@ -1142,8 +1141,7 @@ static bool transport(unit * ut, unit * u)
|
|||
|
||||
for (ord = ut->orders; ord; ord = ord->next) {
|
||||
if (getkeyword(ord) == K_TRANSPORT) {
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
if (getunit(ut->region, ut->faction) == u) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1176,8 +1174,7 @@ static void init_transportation(void)
|
|||
&& !fval(u, UFL_NOTMOVING) && !LongHunger(u)) {
|
||||
unit *ut;
|
||||
|
||||
init_tokens(u->thisorder);
|
||||
skip_token();
|
||||
init_order(u->thisorder);
|
||||
ut = getunit(r, u->faction);
|
||||
if (ut == NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
|
||||
|
@ -1207,8 +1204,7 @@ static void init_transportation(void)
|
|||
|
||||
for (ord = u->orders; ord; ord = ord->next) {
|
||||
if (getkeyword(ord) == K_TRANSPORT) {
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
for (;;) {
|
||||
unit *ut = getunit(r, u->faction);
|
||||
|
||||
|
@ -1216,8 +1212,7 @@ static void init_transportation(void)
|
|||
break;
|
||||
if (getkeyword(ut->thisorder) == K_DRIVE && can_move(ut)
|
||||
&& !fval(ut, UFL_NOTMOVING) && !LongHunger(ut)) {
|
||||
init_tokens(ut->thisorder);
|
||||
skip_token();
|
||||
init_order(ut->thisorder);
|
||||
if (getunit(r, ut->faction) == u) {
|
||||
w += weight(ut);
|
||||
}
|
||||
|
@ -2088,8 +2083,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
|
|||
if (getkeyword(ord) != K_TRANSPORT)
|
||||
continue;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
ut = getunit(r, u->faction);
|
||||
if (ut != NULL) {
|
||||
if (getkeyword(ut->thisorder) == K_DRIVE) {
|
||||
|
@ -2104,8 +2098,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
|
|||
bool found = false;
|
||||
|
||||
if (!fval(ut, UFL_NOTMOVING) && !LongHunger(ut)) {
|
||||
init_tokens(ut->thisorder);
|
||||
skip_token();
|
||||
init_order(ut->thisorder);
|
||||
if (getunit(u->region, ut->faction) == u) {
|
||||
const region_list *route_to =
|
||||
travel_route(ut, route_begin, route_end, ord,
|
||||
|
@ -2301,8 +2294,7 @@ static void piracy_cmd(unit * u, struct order *ord)
|
|||
/* Feststellen, ob schon ein anderer alliierter Pirat ein
|
||||
* Ziel gefunden hat. */
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
if (s != NULL && *s) {
|
||||
il = intlist_init();
|
||||
|
@ -2389,8 +2381,7 @@ static void piracy_cmd(unit * u, struct order *ord)
|
|||
LOC(u->faction->locale, directions[target_dir])));
|
||||
|
||||
/* Bewegung ausführen */
|
||||
init_tokens(u->thisorder);
|
||||
skip_token();
|
||||
init_order(u->thisorder);
|
||||
move(u, true);
|
||||
}
|
||||
|
||||
|
@ -2543,8 +2534,7 @@ static void move_hunters(void)
|
|||
if (getkeyword(ord) == K_FOLLOW) {
|
||||
param_t p;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
p = getparam(u->faction->locale);
|
||||
if (p != P_SHIP) {
|
||||
if (p != P_UNIT) {
|
||||
|
@ -2666,15 +2656,13 @@ void movement(void)
|
|||
else {
|
||||
if (ships) {
|
||||
if (u->ship && ship_owner(u->ship) == u) {
|
||||
init_tokens(u->thisorder);
|
||||
skip_token();
|
||||
init_order(u->thisorder);
|
||||
move(u, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!u->ship || ship_owner(u->ship) != u) {
|
||||
init_tokens(u->thisorder);
|
||||
skip_token();
|
||||
init_order(u->thisorder);
|
||||
move(u, false);
|
||||
}
|
||||
}
|
||||
|
@ -2729,10 +2717,10 @@ void follow_unit(unit * u)
|
|||
const struct locale *lang = u->faction->locale;
|
||||
|
||||
if (getkeyword(ord) == K_FOLLOW) {
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
int id;
|
||||
param_t p = getparam(lang);
|
||||
param_t p;
|
||||
init_order(ord);
|
||||
p = getparam(lang);
|
||||
if (p == P_UNIT) {
|
||||
id = read_unitid(u->faction, r);
|
||||
if (a != NULL) {
|
||||
|
@ -2753,7 +2741,7 @@ void follow_unit(unit * u)
|
|||
a = NULL;
|
||||
}
|
||||
}
|
||||
if (p == P_SHIP) {
|
||||
else if (p == P_SHIP) {
|
||||
id = getshipid();
|
||||
if (id <= 0) {
|
||||
/* cmistake(u, ord, 20, MSG_MOVE); */
|
||||
|
|
|
@ -357,17 +357,19 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
keyword_t kwd;
|
||||
const char *sptr;
|
||||
int persistent = 0;
|
||||
const char * p;
|
||||
|
||||
while (*s == '@') {
|
||||
persistent = 1;
|
||||
++s;
|
||||
}
|
||||
sptr = s;
|
||||
kwd = get_keyword(parse_token(&sptr), lang);
|
||||
p = *sptr ? parse_token(&sptr) : 0;
|
||||
kwd = p ? get_keyword(p, lang) : NOKEYWORD;
|
||||
if (kwd == K_MAKE) {
|
||||
const char *s, *sp = sptr;
|
||||
s = parse_token(&sp);
|
||||
if (isparam(s, lang, P_TEMP)) {
|
||||
if (s && isparam(s, lang, P_TEMP)) {
|
||||
kwd = K_MAKETEMP;
|
||||
sptr = sp;
|
||||
}
|
||||
|
@ -564,15 +566,11 @@ static char *getcommand(const order * ord)
|
|||
return _strdup(get_command(ord, cmd, sizeof(cmd)));
|
||||
}
|
||||
|
||||
void init_tokens(const struct order *ord)
|
||||
{
|
||||
char *cmd = getcommand(ord);
|
||||
init_tokens_str(cmd, cmd);
|
||||
}
|
||||
|
||||
keyword_t init_order(const struct order *ord)
|
||||
{
|
||||
char *cmd = _strdup(ord->data->_str);
|
||||
char *cmd = 0;
|
||||
|
||||
if (ord->data->_str) cmd = _strdup(ord->data->_str);
|
||||
init_tokens_str(cmd, cmd);
|
||||
return ord->data->_keyword;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ extern "C" {
|
|||
bool is_long(const order * ord);
|
||||
|
||||
char *write_order(const order * ord, char *buffer, size_t size);
|
||||
void init_tokens(const struct order *ord); /* initialize token parsing */
|
||||
keyword_t init_order(const struct order *ord);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -17,9 +17,9 @@ static void test_create_order(CuTest *tc) {
|
|||
ord = create_order(K_MOVE, lang, "NORTH");
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||
init_tokens(ord);
|
||||
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd)));
|
||||
CuAssertStrEquals(tc, "MOVE", getstrtoken());
|
||||
|
||||
CuAssertIntEquals(tc, K_MOVE, init_order(ord));
|
||||
CuAssertStrEquals(tc, "NORTH", getstrtoken());
|
||||
free_order(ord);
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ static void test_parse_order(CuTest *tc) {
|
|||
ord = parse_order("MOVE NORTH", lang);
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||
init_tokens(ord);
|
||||
CuAssertStrEquals(tc, "MOVE NORTH", get_command(ord, cmd, sizeof(cmd)));
|
||||
CuAssertStrEquals(tc, "MOVE", getstrtoken());
|
||||
|
||||
CuAssertIntEquals(tc, K_MOVE, init_order(ord));
|
||||
CuAssertStrEquals(tc, "NORTH", getstrtoken());
|
||||
free_order(ord);
|
||||
}
|
||||
|
@ -51,9 +51,9 @@ static void test_parse_make(CuTest *tc) {
|
|||
ord = parse_order("M hurrdurr", lang);
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MAKE, getkeyword(ord));
|
||||
init_tokens(ord);
|
||||
CuAssertStrEquals(tc, "MAKE hurrdurr", get_command(ord, cmd, sizeof(cmd)));
|
||||
CuAssertStrEquals(tc, "MAKE", getstrtoken());
|
||||
|
||||
CuAssertIntEquals(tc, K_MAKE, init_order(ord));
|
||||
CuAssertStrEquals(tc, "hurrdurr", getstrtoken());
|
||||
free_order(ord);
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ static void test_parse_make_temp(CuTest *tc) {
|
|||
ord = parse_order("M T herp", lang);
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
|
||||
init_tokens(ord);
|
||||
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd)));
|
||||
CuAssertStrEquals(tc, "MAKETEMP", getstrtoken());
|
||||
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
|
||||
CuAssertStrEquals(tc, "herp", getstrtoken());
|
||||
free_order(ord);
|
||||
}
|
||||
|
@ -90,25 +90,13 @@ static void test_parse_maketemp(CuTest *tc) {
|
|||
|
||||
ord = parse_order("MAKET herp", lang);
|
||||
CuAssertPtrNotNull(tc, ord);
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
|
||||
init_tokens(ord);
|
||||
CuAssertStrEquals(tc, "MAKETEMP herp", get_command(ord, cmd, sizeof(cmd)));
|
||||
CuAssertStrEquals(tc, "MAKETEMP", getstrtoken());
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, getkeyword(ord));
|
||||
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
|
||||
CuAssertStrEquals(tc, "herp", getstrtoken());
|
||||
free_order(ord);
|
||||
}
|
||||
|
||||
static void test_init_tokens(CuTest *tc) {
|
||||
order *ord;
|
||||
struct locale * lang = get_or_create_locale("en");
|
||||
|
||||
ord = create_order(K_MAKETEMP, lang, "hurr durr");
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
CuAssertStrEquals(tc, "hurr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
}
|
||||
|
||||
static void test_init_order(CuTest *tc) {
|
||||
order *ord;
|
||||
struct locale * lang = get_or_create_locale("en");
|
||||
|
@ -119,6 +107,26 @@ static void test_init_order(CuTest *tc) {
|
|||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
}
|
||||
|
||||
static void test_getstrtoken(CuTest *tc) {
|
||||
char *cmd = _strdup("hurr \"durr\" \"\" \'\'");
|
||||
init_tokens_str(cmd, cmd);
|
||||
CuAssertStrEquals(tc, "hurr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "", getstrtoken());
|
||||
CuAssertStrEquals(tc, "", getstrtoken());
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
init_tokens_str(0, 0);
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
}
|
||||
|
||||
static void test_skip_token(CuTest *tc) {
|
||||
char *cmd = _strdup("hurr \"durr\"");
|
||||
init_tokens_str(cmd, cmd);
|
||||
skip_token();
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
}
|
||||
|
||||
CuSuite *get_order_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -127,7 +135,8 @@ CuSuite *get_order_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_parse_make);
|
||||
SUITE_ADD_TEST(suite, test_parse_make_temp);
|
||||
SUITE_ADD_TEST(suite, test_parse_maketemp);
|
||||
SUITE_ADD_TEST(suite, test_init_tokens);
|
||||
SUITE_ADD_TEST(suite, test_init_order);
|
||||
SUITE_ADD_TEST(suite, test_skip_token);
|
||||
SUITE_ADD_TEST(suite, test_getstrtoken);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ const char * keyword(keyword_t kwd)
|
|||
if (!result[0]) {
|
||||
strcpy(result, "keyword::");
|
||||
}
|
||||
strcpy(result+9, keywords[kwd]);
|
||||
strcpy(result + 9, keywords[kwd]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
95
src/laws.c
95
src/laws.c
|
@ -1090,8 +1090,7 @@ int contact_cmd(unit * u, order * ord)
|
|||
unit *u2;
|
||||
region *r = u->region;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
u2 = getunitg(r, u->faction);
|
||||
|
||||
if (u2 != NULL) {
|
||||
|
@ -1147,10 +1146,10 @@ int quit_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
faction *f = u->faction;
|
||||
const char *passwd;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token(); /* skip keyword */
|
||||
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_PASSWORD);
|
||||
passwd = getstrtoken();
|
||||
if (checkpasswd(f, (const char *)passwd, false)) {
|
||||
if (EnhancedQuit()) {
|
||||
|
@ -1359,8 +1358,7 @@ void do_enter(struct region *r, bool is_final_attempt)
|
|||
unit *ulast = NULL;
|
||||
const char * s;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
p = findparam_ex(s, u->faction->locale);
|
||||
id = getid();
|
||||
|
@ -1540,8 +1538,7 @@ int ally_cmd(unit * u, struct order *ord)
|
|||
int keyword, not_kw;
|
||||
const char *s;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
f = getfaction();
|
||||
|
||||
if (f == NULL || is_monsters(f)) {
|
||||
|
@ -1707,8 +1704,7 @@ int prefix_cmd(unit * u, struct order *ord)
|
|||
for (in = pnames; in->lang != lang; in = in->next);
|
||||
}
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if (!*s) {
|
||||
|
@ -1761,8 +1757,7 @@ int display_cmd(unit * u, struct order *ord)
|
|||
const char *str;
|
||||
region *r = u->region;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
str = getstrtoken();
|
||||
switch (findparam_ex(str, u->faction->locale)) {
|
||||
|
@ -1933,8 +1928,7 @@ int name_cmd(struct unit *u, struct order *ord)
|
|||
bool foreign = false;
|
||||
const char *str;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
str = getstrtoken();
|
||||
p = findparam_ex(str, u->faction->locale);
|
||||
|
||||
|
@ -2193,8 +2187,7 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
const char *s;
|
||||
int n, cont;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token(); /* skip the keyword */
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
||||
|
@ -2357,8 +2350,7 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
|
||||
int banner_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
free(u->faction->banner);
|
||||
u->faction->banner = _strdup(getstrtoken());
|
||||
|
@ -2372,8 +2364,7 @@ int email_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
const char *s;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if (!s[0]) {
|
||||
|
@ -2399,8 +2390,7 @@ int password_cmd(unit * u, struct order *ord)
|
|||
const char *s;
|
||||
bool pwok = true;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if (!s || !*s) {
|
||||
|
@ -2438,8 +2428,7 @@ int send_cmd(unit * u, struct order *ord)
|
|||
const char *s;
|
||||
int option;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
option = findoption(s, u->faction->locale);
|
||||
|
@ -2778,9 +2767,10 @@ int promotion_cmd(unit * u, struct order *ord)
|
|||
int group_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
const char *s;
|
||||
keyword_t kwd;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_GROUP);
|
||||
s = getstrtoken();
|
||||
|
||||
join_group(u, s);
|
||||
|
@ -2791,8 +2781,7 @@ int origin_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
short px, py;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
px = (short)getint();
|
||||
py = (short)getint();
|
||||
|
@ -2804,8 +2793,7 @@ int origin_cmd(unit * u, struct order *ord)
|
|||
int guard_off_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
assert(getkeyword(ord) == K_GUARD);
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
if (getparam(u->faction->locale) == P_NOT) {
|
||||
setguard(u, GUARD_NONE);
|
||||
|
@ -2818,8 +2806,7 @@ int reshow_cmd(unit * u, struct order *ord)
|
|||
const char *s;
|
||||
param_t p = NOPARAM;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
if (isparam(s, u->faction->locale, P_ANY)) {
|
||||
|
@ -2835,8 +2822,7 @@ int status_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
const char *param;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
param = getstrtoken();
|
||||
switch (findparam(param, u->faction->locale)) {
|
||||
|
@ -2867,7 +2853,7 @@ int status_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (param[0]) {
|
||||
if (param && param[0]) {
|
||||
add_message(&u->faction->msgs,
|
||||
msg_feedback(u, ord, "unknown_status", ""));
|
||||
}
|
||||
|
@ -2884,8 +2870,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
|||
int level = 0;
|
||||
spell *sp = 0;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
|
||||
|
@ -2970,8 +2955,7 @@ int guard_on_cmd(unit * u, struct order *ord)
|
|||
{
|
||||
assert(getkeyword(ord) == K_GUARD);
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
|
||||
if (getparam(u->faction->locale) == P_NOT)
|
||||
|
@ -3132,8 +3116,7 @@ void restack_units(void)
|
|||
int id;
|
||||
unit *v;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
p = findparam(s, u->faction->locale);
|
||||
id = getid();
|
||||
|
@ -3208,8 +3191,7 @@ int renumber_cmd(unit * u, order * ord)
|
|||
int i;
|
||||
faction *f = u->faction;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
switch (findparam_ex(s, u->faction->locale)) {
|
||||
|
||||
|
@ -3942,8 +3924,7 @@ void defaultorders(void)
|
|||
if (getkeyword(ord) == K_DEFAULT) {
|
||||
char lbuf[8192];
|
||||
order *new_order;
|
||||
init_tokens(ord);
|
||||
skip_token(); /* skip the keyword */
|
||||
init_order(ord);
|
||||
strcpy(lbuf, getstrtoken());
|
||||
new_order = parse_order(lbuf, u->faction->locale);
|
||||
*ordp = ord->next;
|
||||
|
@ -4055,8 +4036,7 @@ int use_cmd(unit * u, struct order *ord)
|
|||
int n, err = ENOITEM;
|
||||
const item_type *itype;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
t = getstrtoken();
|
||||
n = atoi((const char *)t);
|
||||
|
@ -4105,8 +4085,7 @@ int pay_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
else {
|
||||
param_t p;
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
p = getparam(u->faction->locale);
|
||||
if (p == P_NOT) {
|
||||
unit *owner = building_owner(u->building);
|
||||
|
@ -4128,16 +4107,16 @@ static int reserve_i(unit * u, struct order *ord, int flags)
|
|||
const resource_type *rtype;
|
||||
const char *s;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
count = atoip((const char *)s);
|
||||
count = s ? atoip(s) : 0;
|
||||
para = findparam(s, u->faction->locale);
|
||||
|
||||
if (count == 0 && para == P_EACH) {
|
||||
count = getint() * u->number;
|
||||
}
|
||||
rtype = findresourcetype(getstrtoken(), u->faction->locale);
|
||||
s = getstrtoken();
|
||||
rtype = s ? findresourcetype(s, u->faction->locale) : 0;
|
||||
if (rtype == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -4170,8 +4149,7 @@ int claim_cmd(unit * u, struct order *ord)
|
|||
int n;
|
||||
const item_type *itype;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
t = getstrtoken();
|
||||
n = atoi((const char *)t);
|
||||
|
@ -4437,8 +4415,7 @@ int siege_cmd(unit * u, order * ord)
|
|||
resource_type *rt_catapultammo = NULL;
|
||||
resource_type *rt_catapult = NULL;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
b = getbuilding(r);
|
||||
|
||||
if (!b) {
|
||||
|
|
|
@ -92,9 +92,9 @@ skill_t get_skill(const char *s, const struct locale * lang)
|
|||
{
|
||||
skill_t result = NOSKILL;
|
||||
char buffer[64];
|
||||
char * str = transliterate(buffer, sizeof(buffer)-sizeof(int), s);
|
||||
|
||||
if (str) {
|
||||
if (s) {
|
||||
char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s);
|
||||
int i;
|
||||
const void * match;
|
||||
void **tokens = get_translations(lang, UT_SKILLS);
|
||||
|
|
11
src/spy.c
11
src/spy.c
|
@ -120,8 +120,7 @@ int spy_cmd(unit * u, struct order *ord)
|
|||
double spychance, observechance;
|
||||
region *r = u->region;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
target = getunit(r, u->faction);
|
||||
|
||||
if (!target) {
|
||||
|
@ -213,8 +212,7 @@ int setstealth_cmd(unit * u, struct order *ord)
|
|||
int level, rule;
|
||||
const race *trace;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
/* Tarne ohne Parameter: Setzt maximale Tarnung */
|
||||
|
@ -298,7 +296,7 @@ int setstealth_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
if (rule&2) {
|
||||
if (get_keyword(s, u->faction->locale) == K_NUMBER) {
|
||||
const char *s2 = (const char *)getstrtoken();
|
||||
const char *s2 = getstrtoken();
|
||||
int nr = -1;
|
||||
|
||||
if (s2) {
|
||||
|
@ -484,8 +482,7 @@ int sabotage_cmd(unit * u, struct order *ord)
|
|||
region *r = u->region;
|
||||
int skdiff;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
|
||||
i = findparam(s, u->faction->locale);
|
||||
|
|
21
src/study.c
21
src/study.c
|
@ -315,8 +315,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
|
||||
count = 0;
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
#if TEACH_ALL
|
||||
if (getparam(u->faction->locale) == P_ANY) {
|
||||
|
@ -338,8 +337,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
#endif
|
||||
if (getkeyword(student->thisorder) == K_STUDY) {
|
||||
/* Input ist nun von student->thisorder !! */
|
||||
init_tokens(student->thisorder);
|
||||
skip_token();
|
||||
init_order(student->thisorder);
|
||||
sk = getskill(student->faction->locale);
|
||||
if (sk != NOSKILL && teachskill[0] != NOSKILL) {
|
||||
for (i = 0; teachskill[i] != NOSKILL; ++i)
|
||||
|
@ -369,8 +367,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
#endif
|
||||
if (getkeyword(student->thisorder) == K_STUDY) {
|
||||
/* Input ist nun von student->thisorder !! */
|
||||
init_tokens(student->thisorder);
|
||||
skip_token();
|
||||
init_order(student->thisorder);
|
||||
sk = getskill(student->faction->locale);
|
||||
if (sk != NOSKILL
|
||||
&& eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student,
|
||||
|
@ -390,8 +387,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
order *new_order;
|
||||
|
||||
zOrder[0] = '\0';
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
while (!parser_end()) {
|
||||
unit *u2 = getunit(r, u->faction);
|
||||
|
@ -406,8 +402,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
const char *token;
|
||||
/* Finde den string, der den Fehler verursacht hat */
|
||||
parser_pushstate();
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
|
||||
for (j = 0; j != count - 1; ++j) {
|
||||
/* skip over the first 'count' units */
|
||||
|
@ -450,8 +445,7 @@ int teach_cmd(unit * u, struct order *ord)
|
|||
|
||||
/* Input ist nun von u2->thisorder !! */
|
||||
parser_pushstate();
|
||||
init_tokens(u2->thisorder);
|
||||
skip_token();
|
||||
init_order(u2->thisorder);
|
||||
sk = getskill(u2->faction->locale);
|
||||
parser_popstate();
|
||||
|
||||
|
@ -551,8 +545,7 @@ int learn_cmd(unit * u, order * ord)
|
|||
return 0;
|
||||
}
|
||||
|
||||
init_tokens(ord);
|
||||
skip_token();
|
||||
init_order(ord);
|
||||
sk = getskill(u->faction->locale);
|
||||
|
||||
if (sk < 0) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -25,94 +25,95 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
int atoi36(const char *str)
|
||||
{
|
||||
/* cannot use strtol, because invalid strings will cause crash */
|
||||
const unsigned char *s = (const unsigned char *)str;
|
||||
int i = 0, sign = 1;
|
||||
assert(s);
|
||||
if (!(*s))
|
||||
return 0;
|
||||
/* cannot use strtol, because invalid strings will cause crash */
|
||||
const unsigned char *s = (const unsigned char *)str;
|
||||
int i = 0, sign = 1;
|
||||
assert(s);
|
||||
if (!(*s))
|
||||
return 0;
|
||||
|
||||
while (isxspace(*(unsigned char *)s))
|
||||
++s;
|
||||
if (*s == '-') {
|
||||
sign = -1;
|
||||
++s;
|
||||
}
|
||||
while (isalnum(*(unsigned char *)s)) {
|
||||
if (isupper(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - 'A' + 10;
|
||||
else if (islower(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - 'a' + 10;
|
||||
else if (isdigit(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - '0';
|
||||
else
|
||||
break;
|
||||
++s;
|
||||
}
|
||||
if (i < 0)
|
||||
return 0;
|
||||
return i * sign;
|
||||
while (isxspace(*(unsigned char *)s))
|
||||
++s;
|
||||
if (*s == '-') {
|
||||
sign = -1;
|
||||
++s;
|
||||
}
|
||||
while (isalnum(*(unsigned char *)s)) {
|
||||
if (isupper(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - 'A' + 10;
|
||||
else if (islower(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - 'a' + 10;
|
||||
else if (isdigit(*(unsigned char *)s))
|
||||
i = i * 36 + (*s) - '0';
|
||||
else
|
||||
break;
|
||||
++s;
|
||||
}
|
||||
if (i < 0)
|
||||
return 0;
|
||||
return i * sign;
|
||||
}
|
||||
|
||||
const char *itoab(int i, int base)
|
||||
{
|
||||
static char **as = NULL; /* STATIC_RETURN: used for return, not across calls */
|
||||
char *s, *dst;
|
||||
static int index = 0; /* STATIC_XCALL: used across calls */
|
||||
int neg = 0;
|
||||
static char **as = NULL; /* STATIC_RETURN: used for return, not across calls */
|
||||
char *s, *dst;
|
||||
static int index = 0; /* STATIC_XCALL: used across calls */
|
||||
int neg = 0;
|
||||
|
||||
if (!as) {
|
||||
int j;
|
||||
char *x = (char *)calloc(sizeof(char), 8 * 4); /* STATIC_LEAK: malloc in static variable */
|
||||
as = (char **)calloc(sizeof(char *), 4);
|
||||
for (j = 0; j != 4; ++j)
|
||||
as[j] = x + j * 8;
|
||||
}
|
||||
s = as[index];
|
||||
index = (index + 1) & 3; /* quick for % 4 */
|
||||
dst = s + 7;
|
||||
(*dst--) = 0;
|
||||
if (i != 0) {
|
||||
if (i < 0) {
|
||||
i = -i;
|
||||
neg = 1;
|
||||
if (!as) {
|
||||
int j;
|
||||
char *x = (char *)calloc(sizeof(char), 8 * 4); /* STATIC_LEAK: malloc in static variable */
|
||||
as = (char **)calloc(sizeof(char *), 4);
|
||||
for (j = 0; j != 4; ++j)
|
||||
as[j] = x + j * 8;
|
||||
}
|
||||
while (i) {
|
||||
int x = i % base;
|
||||
i = i / base;
|
||||
if (x < 10)
|
||||
*(dst--) = (char)('0' + x);
|
||||
else if ('a' + x - 10 == 'l')
|
||||
*(dst--) = 'L';
|
||||
else
|
||||
*(dst--) = (char)('a' + (x - 10));
|
||||
s = as[index];
|
||||
index = (index + 1) & 3; /* quick for % 4 */
|
||||
dst = s + 7;
|
||||
(*dst--) = 0;
|
||||
if (i != 0) {
|
||||
if (i < 0) {
|
||||
i = -i;
|
||||
neg = 1;
|
||||
}
|
||||
while (i) {
|
||||
int x = i % base;
|
||||
i = i / base;
|
||||
if (x < 10)
|
||||
*(dst--) = (char)('0' + x);
|
||||
else if ('a' + x - 10 == 'l')
|
||||
*(dst--) = 'L';
|
||||
else
|
||||
*(dst--) = (char)('a' + (x - 10));
|
||||
}
|
||||
if (neg)
|
||||
*(dst) = '-';
|
||||
else
|
||||
++dst;
|
||||
}
|
||||
if (neg)
|
||||
*(dst) = '-';
|
||||
else
|
||||
++dst;
|
||||
} else
|
||||
*dst = '0';
|
||||
*dst = '0';
|
||||
|
||||
return dst;
|
||||
return dst;
|
||||
}
|
||||
|
||||
const char *itoa36(int i)
|
||||
{
|
||||
return itoab(i, 36);
|
||||
return itoab(i, 36);
|
||||
}
|
||||
|
||||
const char *itoa10(int i)
|
||||
{
|
||||
return itoab(i, 10);
|
||||
return itoab(i, 10);
|
||||
}
|
||||
|
||||
int i10toi36(int i)
|
||||
{
|
||||
int r = 0;
|
||||
while (i) {
|
||||
r = r * 36 + i % 10;
|
||||
i = i / 10;
|
||||
}
|
||||
return r;
|
||||
int r = 0;
|
||||
while (i) {
|
||||
r = r * 36 + i % 10;
|
||||
i = i / 10;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -81,8 +81,11 @@ void parser_popstate(void)
|
|||
|
||||
bool parser_end(void)
|
||||
{
|
||||
eatwhitespace_c(&states->current_token);
|
||||
return *states->current_token == 0;
|
||||
if (states->current_token) {
|
||||
eatwhitespace_c(&states->current_token);
|
||||
return *states->current_token == 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void skip_token(void)
|
||||
|
@ -132,9 +135,13 @@ const char *parse_token(const char **str)
|
|||
bool escape = false;
|
||||
const char *ctoken = *str;
|
||||
|
||||
assert(ctoken);
|
||||
|
||||
if (!ctoken) {
|
||||
return 0;
|
||||
}
|
||||
eatwhitespace_c(&ctoken);
|
||||
if (!*ctoken) {
|
||||
return 0;
|
||||
}
|
||||
while (*ctoken && cursor - lbuf < MAXTOKENSIZE - 1) {
|
||||
ucs4_t ucs;
|
||||
size_t len;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -29,235 +29,247 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <assert.h>
|
||||
|
||||
typedef struct tref {
|
||||
struct tref *nexthash;
|
||||
ucs4_t ucs;
|
||||
void *node;
|
||||
struct tref *nexthash;
|
||||
ucs4_t ucs;
|
||||
void *node;
|
||||
} tref;
|
||||
|
||||
#define LEAF 1 /* leaf node for a word. always matches */
|
||||
#define SHARED 2 /* at least two words share the node */
|
||||
|
||||
typedef struct tnode {
|
||||
struct tref *next[NODEHASHSIZE];
|
||||
unsigned char flags;
|
||||
variant id;
|
||||
struct tref *next[NODEHASHSIZE];
|
||||
unsigned char flags;
|
||||
variant id;
|
||||
} tnode;
|
||||
|
||||
char * transliterate(char * out, size_t size, const char * in)
|
||||
{
|
||||
const char *src = in;
|
||||
char *dst = out;
|
||||
const char *src = in;
|
||||
char *dst = out;
|
||||
|
||||
--size; /* need space for a final 0-byte */
|
||||
while (*src && size) {
|
||||
size_t len;
|
||||
const char * p = src;
|
||||
while ((p+size>src) && *src && (~*src & 0x80)) {
|
||||
*dst++ = (char)tolower(*src++);
|
||||
}
|
||||
len = src-p;
|
||||
size -= len;
|
||||
while (size>0 && *src && (*src & 0x80)) {
|
||||
unsigned int advance = 2;
|
||||
if (src[0]=='\xc3') {
|
||||
if (src[1]=='\xa4' || src[1]=='\x84') {
|
||||
memcpy(dst, "ae", 2);
|
||||
} else if (src[1]=='\xb6' || src[1]=='\x96') {
|
||||
memcpy(dst, "oe", 2);
|
||||
} else if (src[1]=='\xbc' || src[1]=='\x9c') {
|
||||
memcpy(dst, "ue", 2);
|
||||
} else if (src[1]=='\x9f') {
|
||||
memcpy(dst, "ss", 2);
|
||||
} else {
|
||||
advance = 0;
|
||||
assert(in && size > 0);
|
||||
--size; /* need space for a final 0-byte */
|
||||
while (*src && size) {
|
||||
size_t len;
|
||||
const char * p = src;
|
||||
while ((p + size > src) && *src && (~*src & 0x80)) {
|
||||
*dst++ = (char)tolower(*src++);
|
||||
}
|
||||
} else if (src[0]=='\xe1') {
|
||||
if (src[1]=='\xba' && src[2]=='\x9e') {
|
||||
memcpy(dst, "ss", 2);
|
||||
++src;
|
||||
} else {
|
||||
advance = 0;
|
||||
}
|
||||
} else {
|
||||
advance = 0;
|
||||
}
|
||||
len = src - p;
|
||||
size -= len;
|
||||
while (size > 0 && *src && (*src & 0x80)) {
|
||||
unsigned int advance = 2;
|
||||
if (src[0] == '\xc3') {
|
||||
if (src[1] == '\xa4' || src[1] == '\x84') {
|
||||
memcpy(dst, "ae", 2);
|
||||
}
|
||||
else if (src[1] == '\xb6' || src[1] == '\x96') {
|
||||
memcpy(dst, "oe", 2);
|
||||
}
|
||||
else if (src[1] == '\xbc' || src[1] == '\x9c') {
|
||||
memcpy(dst, "ue", 2);
|
||||
}
|
||||
else if (src[1] == '\x9f') {
|
||||
memcpy(dst, "ss", 2);
|
||||
}
|
||||
else {
|
||||
advance = 0;
|
||||
}
|
||||
}
|
||||
else if (src[0] == '\xe1') {
|
||||
if (src[1] == '\xba' && src[2] == '\x9e') {
|
||||
memcpy(dst, "ss", 2);
|
||||
++src;
|
||||
}
|
||||
else {
|
||||
advance = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
advance = 0;
|
||||
}
|
||||
|
||||
if (advance && advance<=size) {
|
||||
src+=advance;
|
||||
dst+=advance;
|
||||
size-=advance;
|
||||
} else {
|
||||
ucs4_t ucs;
|
||||
unicode_utf8_to_ucs4(&ucs, src, &len);
|
||||
src+=len;
|
||||
*dst++='?';
|
||||
--size;
|
||||
}
|
||||
if (advance && advance <= size) {
|
||||
src += advance;
|
||||
dst += advance;
|
||||
size -= advance;
|
||||
}
|
||||
else {
|
||||
ucs4_t ucs;
|
||||
unicode_utf8_to_ucs4(&ucs, src, &len);
|
||||
src += len;
|
||||
*dst++ = '?';
|
||||
--size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return *src ? 0 : out;
|
||||
*dst = 0;
|
||||
return *src ? 0 : out;
|
||||
}
|
||||
|
||||
void addtoken(void ** root, const char *str, variant id)
|
||||
{
|
||||
tnode * tk;
|
||||
static const struct replace { /* STATIC_CONST: constant value */
|
||||
ucs4_t ucs;
|
||||
const char str[3];
|
||||
} replace[] = {
|
||||
/* match lower-case (!) umlauts and others to transcriptions */
|
||||
{
|
||||
228, "AE"}, /* auml */
|
||||
{
|
||||
246, "OE"}, /* ouml */
|
||||
{
|
||||
252, "UE"}, /* uuml */
|
||||
{
|
||||
223, "SS"}, /* szlig */
|
||||
{
|
||||
230, "AE"}, /* norsk */
|
||||
{
|
||||
248, "OE"}, /* norsk */
|
||||
{
|
||||
229, "AA"}, /* norsk */
|
||||
{
|
||||
0, ""}
|
||||
};
|
||||
tnode * tk;
|
||||
static const struct replace { /* STATIC_CONST: constant value */
|
||||
ucs4_t ucs;
|
||||
const char str[3];
|
||||
} replace[] = {
|
||||
/* match lower-case (!) umlauts and others to transcriptions */
|
||||
{
|
||||
228, "AE" }, /* auml */
|
||||
{
|
||||
246, "OE" }, /* ouml */
|
||||
{
|
||||
252, "UE" }, /* uuml */
|
||||
{
|
||||
223, "SS" }, /* szlig */
|
||||
{
|
||||
230, "AE" }, /* norsk */
|
||||
{
|
||||
248, "OE" }, /* norsk */
|
||||
{
|
||||
229, "AA" }, /* norsk */
|
||||
{
|
||||
0, "" }
|
||||
};
|
||||
|
||||
assert(root && str);
|
||||
if (!*root) {
|
||||
tk = *root = calloc(1, sizeof(tnode));
|
||||
} else {
|
||||
tk = *root;
|
||||
}
|
||||
assert(tk && tk==*root);
|
||||
if (!*str) {
|
||||
tk->id = id;
|
||||
tk->flags |= LEAF;
|
||||
} else {
|
||||
tref *next;
|
||||
int ret, index, i = 0;
|
||||
ucs4_t ucs, lcs;
|
||||
size_t len;
|
||||
assert(root && str);
|
||||
if (!*root) {
|
||||
tk = *root = calloc(1, sizeof(tnode));
|
||||
}
|
||||
else {
|
||||
tk = *root;
|
||||
}
|
||||
assert(tk && tk == *root);
|
||||
if (!*str) {
|
||||
tk->id = id;
|
||||
tk->flags |= LEAF;
|
||||
}
|
||||
else {
|
||||
tref *next;
|
||||
int ret, index, i = 0;
|
||||
ucs4_t ucs, lcs;
|
||||
size_t len;
|
||||
|
||||
ret = unicode_utf8_to_ucs4(&ucs, str, &len);
|
||||
assert(ret == 0 || !"invalid utf8 string");
|
||||
lcs = ucs;
|
||||
ret = unicode_utf8_to_ucs4(&ucs, str, &len);
|
||||
assert(ret == 0 || !"invalid utf8 string");
|
||||
lcs = ucs;
|
||||
|
||||
#if NODEHASHSIZE == 8
|
||||
index = ucs & 7;
|
||||
index = ucs & 7;
|
||||
#else
|
||||
index = ucs % NODEHASHSIZE;
|
||||
index = ucs % NODEHASHSIZE;
|
||||
#endif
|
||||
assert(index >= 0);
|
||||
next = tk->next[index];
|
||||
if (!(tk->flags & LEAF))
|
||||
tk->id = id;
|
||||
while (next && next->ucs != ucs)
|
||||
next = next->nexthash;
|
||||
if (!next) {
|
||||
tref *ref;
|
||||
tnode *node = (tnode *)calloc(1, sizeof(tnode));
|
||||
assert(index >= 0);
|
||||
next = tk->next[index];
|
||||
if (!(tk->flags & LEAF))
|
||||
tk->id = id;
|
||||
while (next && next->ucs != ucs)
|
||||
next = next->nexthash;
|
||||
if (!next) {
|
||||
tref *ref;
|
||||
tnode *node = (tnode *)calloc(1, sizeof(tnode));
|
||||
|
||||
if (ucs < 'a' || ucs > 'z') {
|
||||
lcs = towlower((wint_t) ucs);
|
||||
}
|
||||
if (ucs == lcs) {
|
||||
ucs = towupper((wint_t) ucs);
|
||||
}
|
||||
if (ucs < 'a' || ucs > 'z') {
|
||||
lcs = towlower((wint_t)ucs);
|
||||
}
|
||||
if (ucs == lcs) {
|
||||
ucs = towupper((wint_t)ucs);
|
||||
}
|
||||
|
||||
ref = (tref *)malloc(sizeof(tref));
|
||||
ref->ucs = ucs;
|
||||
ref->node = node;
|
||||
ref->nexthash = tk->next[index];
|
||||
tk->next[index] = ref;
|
||||
ref = (tref *)malloc(sizeof(tref));
|
||||
ref->ucs = ucs;
|
||||
ref->node = node;
|
||||
ref->nexthash = tk->next[index];
|
||||
tk->next[index] = ref;
|
||||
|
||||
/* try lower/upper casing the character, and try again */
|
||||
if (ucs != lcs) {
|
||||
/* try lower/upper casing the character, and try again */
|
||||
if (ucs != lcs) {
|
||||
#if NODEHASHSIZE == 8
|
||||
index = lcs & 7;
|
||||
index = lcs & 7;
|
||||
#else
|
||||
index = lcs % NODEHASHSIZE;
|
||||
index = lcs % NODEHASHSIZE;
|
||||
#endif
|
||||
ref = (tref *)malloc(sizeof(tref));
|
||||
ref->ucs = lcs;
|
||||
ref->node = node;
|
||||
ref->nexthash = tk->next[index];
|
||||
tk->next[index] = ref;
|
||||
}
|
||||
next = ref;
|
||||
} else {
|
||||
tnode * next_node = (tnode *)next->node;
|
||||
next_node->flags |= SHARED;
|
||||
if ((next_node->flags & LEAF) == 0)
|
||||
next_node->id.v = NULL; /* why? */
|
||||
ref = (tref *)malloc(sizeof(tref));
|
||||
ref->ucs = lcs;
|
||||
ref->node = node;
|
||||
ref->nexthash = tk->next[index];
|
||||
tk->next[index] = ref;
|
||||
}
|
||||
next = ref;
|
||||
}
|
||||
else {
|
||||
tnode * next_node = (tnode *)next->node;
|
||||
next_node->flags |= SHARED;
|
||||
if ((next_node->flags & LEAF) == 0)
|
||||
next_node->id.v = NULL; /* why? */
|
||||
}
|
||||
addtoken(&next->node, str + len, id);
|
||||
while (replace[i].str[0]) {
|
||||
if (lcs == replace[i].ucs) {
|
||||
char zText[1024];
|
||||
memcpy(zText, replace[i].str, 3);
|
||||
strcpy(zText + 2, (const char *)str + len);
|
||||
addtoken(root, zText, id);
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
addtoken(&next->node, str + len, id);
|
||||
while (replace[i].str[0]) {
|
||||
if (lcs == replace[i].ucs) {
|
||||
char zText[1024];
|
||||
memcpy(zText, replace[i].str, 3);
|
||||
strcpy(zText + 2, (const char *)str + len);
|
||||
addtoken(root, zText, id);
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void freetokens(void * root)
|
||||
{
|
||||
tnode * node = (tnode *)root;
|
||||
int i;
|
||||
for (i=0;node && i!=NODEHASHSIZE;++i) {
|
||||
if (node->next[i]) {
|
||||
freetokens(node->next[i]->node);
|
||||
tnode * node = (tnode *)root;
|
||||
int i;
|
||||
for (i = 0; node && i != NODEHASHSIZE; ++i) {
|
||||
if (node->next[i]) {
|
||||
freetokens(node->next[i]->node);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(node);
|
||||
free(node);
|
||||
}
|
||||
|
||||
int findtoken(const void * root, const char *key, variant * result)
|
||||
{
|
||||
const char * str = key;
|
||||
const tnode * tk = (const tnode *)root;
|
||||
const char * str = key;
|
||||
const tnode * tk = (const tnode *)root;
|
||||
|
||||
if (!tk || !str || *str == 0) {
|
||||
return E_TOK_NOMATCH;
|
||||
}
|
||||
do {
|
||||
int index;
|
||||
const tref *ref;
|
||||
ucs4_t ucs;
|
||||
size_t len;
|
||||
int ret = unicode_utf8_to_ucs4(&ucs, str, &len);
|
||||
|
||||
if (ret != 0) {
|
||||
/* encoding is broken. youch */
|
||||
log_error("findtoken | encoding error in '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
if (!tk || !str || *str == 0) {
|
||||
return E_TOK_NOMATCH;
|
||||
}
|
||||
do {
|
||||
int index;
|
||||
const tref *ref;
|
||||
ucs4_t ucs;
|
||||
size_t len;
|
||||
int ret = unicode_utf8_to_ucs4(&ucs, str, &len);
|
||||
|
||||
if (ret != 0) {
|
||||
/* encoding is broken. youch */
|
||||
log_error("findtoken | encoding error in '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
}
|
||||
#if NODEHASHSIZE == 8
|
||||
index = ucs & 7;
|
||||
index = ucs & 7;
|
||||
#else
|
||||
index = ucs % NODEHASHSIZE;
|
||||
index = ucs % NODEHASHSIZE;
|
||||
#endif
|
||||
ref = tk->next[index];
|
||||
while (ref && ref->ucs != ucs)
|
||||
ref = ref->nexthash;
|
||||
str += len;
|
||||
if (!ref) {
|
||||
log_info("findtoken | token not found '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
ref = tk->next[index];
|
||||
while (ref && ref->ucs != ucs)
|
||||
ref = ref->nexthash;
|
||||
str += len;
|
||||
if (!ref) {
|
||||
log_info("findtoken | token not found '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
}
|
||||
tk = ref->node;
|
||||
} while (*str);
|
||||
if (tk) {
|
||||
*result = tk->id;
|
||||
return E_TOK_SUCCESS;
|
||||
}
|
||||
tk = ref->node;
|
||||
} while (*str);
|
||||
if (tk) {
|
||||
*result = tk->id;
|
||||
return E_TOK_SUCCESS;
|
||||
}
|
||||
log_info("findtoken | token not found '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
log_info("findtoken | token not found '%s'\n", key);
|
||||
return E_TOK_NOMATCH;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue