forked from github/server
Merge pull request #88 from badgerman/parser-static-removal
parser refactoring, tests and cleanup.
This commit is contained in:
commit
1ba7248e48
|
@ -476,7 +476,8 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
n = getuint();
|
||||
|
||||
if (u->number == 0) {
|
||||
str = getstrtoken();
|
||||
char token[128];
|
||||
str = gettoken(token, sizeof(token));
|
||||
if (str && str[0]) {
|
||||
/* Monsters can RECRUIT 15 DRACOID
|
||||
* also: secondary race */
|
||||
|
@ -626,6 +627,7 @@ void give_control(unit * u, unit * u2)
|
|||
|
||||
int give_control_cmd(unit * u, order * ord)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
unit *u2;
|
||||
const char *s;
|
||||
|
@ -633,7 +635,7 @@ int give_control_cmd(unit * u, order * ord)
|
|||
init_order(ord);
|
||||
getunit(r, u->faction, &u2);
|
||||
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s && isparam(s, u->faction->locale, P_CONTROL)) {
|
||||
message *msg = 0;
|
||||
|
||||
|
@ -676,6 +678,7 @@ int give_control_cmd(unit * u, order * ord)
|
|||
|
||||
static int forget_cmd(unit * u, order * ord)
|
||||
{
|
||||
char token[128];
|
||||
skill_t sk;
|
||||
const char *s;
|
||||
|
||||
|
@ -685,7 +688,7 @@ static int forget_cmd(unit * u, order * ord)
|
|||
}
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if ((sk = get_skill(s, u->faction->locale)) != NOSKILL) {
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
const building_type *btype = 0;
|
||||
const ship_type *stype = 0;
|
||||
|
@ -1498,15 +1502,16 @@ int make_cmd(unit * u, struct order *ord)
|
|||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_MAKE);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (s) {
|
||||
m = atoi((const char *)s);
|
||||
sprintf(ibuf, "%d", m);
|
||||
if (!strcmp(ibuf, (const char *)s)) {
|
||||
/* a quantity was given */
|
||||
s = getstrtoken();
|
||||
} else {
|
||||
s = gettoken(token, sizeof(token));
|
||||
}
|
||||
else {
|
||||
m = INT_MAX;
|
||||
}
|
||||
if (s) {
|
||||
|
@ -1520,7 +1525,7 @@ int make_cmd(unit * u, struct order *ord)
|
|||
cmistake(u, ord, 275, MSG_PRODUCE);
|
||||
}
|
||||
else {
|
||||
const char * s = getstrtoken();
|
||||
const char * s = gettoken(token, sizeof(token));
|
||||
direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION;
|
||||
if (d != NODIRECTION) {
|
||||
build_road(r, u, m, d);
|
||||
|
@ -1753,6 +1758,7 @@ attrib_type at_trades = {
|
|||
|
||||
static void buy(unit * u, request ** buyorders, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
int n, k;
|
||||
request *o;
|
||||
|
@ -1836,7 +1842,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|||
/* die Menge der verkauften Güter merken */
|
||||
a->data.i += n;
|
||||
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
itype = s ? finditemtype(s, u->faction->locale) : 0;
|
||||
if (itype != NULL) {
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
bool unlimited = true;
|
||||
const item_type *itype;
|
||||
const luxury_type *ltype;
|
||||
|
@ -2076,7 +2083,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_SELL);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (findparam(s, u->faction->locale) == P_ANY) {
|
||||
unlimited = false;
|
||||
|
@ -2134,7 +2141,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|||
cmistake(u, ord, 54, MSG_COMMERCE);
|
||||
return false;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
itype = s ? finditemtype(s, u->faction->locale) : 0;
|
||||
ltype = itype ? resource2luxury(itype->rtype) : 0;
|
||||
if (ltype == NULL) {
|
||||
|
@ -2462,6 +2469,7 @@ static void breedhorses(region * r, unit * u)
|
|||
|
||||
static void breed_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
int m;
|
||||
const char *s;
|
||||
param_t p;
|
||||
|
@ -2475,12 +2483,12 @@ static void breed_cmd(unit * u, struct order *ord)
|
|||
|
||||
/* züchte [<anzahl>] <parameter> */
|
||||
(void)init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
m = s ? atoi((const char *)s) : 0;
|
||||
if (m != 0) {
|
||||
/* first came a want-paramter */
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
}
|
||||
else {
|
||||
m = INT_MAX;
|
||||
|
@ -2543,10 +2551,6 @@ static void research_cmd(unit * u, struct order *ord)
|
|||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_RESEARCH);
|
||||
/*
|
||||
const char *s = getstrtoken();
|
||||
|
||||
if (findparam(s, u->faction->locale) == P_HERBS) { */
|
||||
|
||||
if (eff_skill(u, SK_HERBALISM, r) < 7) {
|
||||
cmistake(u, ord, 227, MSG_EVENT);
|
||||
|
|
11
src/give.c
11
src/give.c
|
@ -531,6 +531,7 @@ bool can_give_to(unit *u, unit *u2) {
|
|||
|
||||
void give_cmd(unit * u, order * ord)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
unit *u2;
|
||||
const char *s;
|
||||
|
@ -544,7 +545,7 @@ void give_cmd(unit * u, order * ord)
|
|||
kwd = init_order(ord);
|
||||
assert(kwd == K_GIVE);
|
||||
err = getunit(r, u->faction, &u2);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
n = s ? atoip(s) : 0;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (!s || *s == 0) { /* GIVE ALL items that you 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", ""));
|
||||
return;
|
||||
}
|
||||
s = getstrtoken(); /* skip one ahead to get the amount. */
|
||||
n = atoip(s); /* n: Anzahl */
|
||||
s = gettoken(token, sizeof(token)); /* skip one ahead to get the amount. */
|
||||
n = s ? atoip(s) : 0; /* n: Anzahl */
|
||||
n *= u2->number;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (s == NULL) {
|
||||
cmistake(u, ord, 113, MSG_COMMERCE);
|
||||
|
|
|
@ -35,9 +35,10 @@ use_studypotion(struct unit *u, const struct item_type *itype, int amount,
|
|||
struct order *ord)
|
||||
{
|
||||
if (init_order(u->thisorder) == K_STUDY) {
|
||||
char token[128];
|
||||
skill_t sk = NOSKILL;
|
||||
skill *sv = 0;
|
||||
const char * s = getstrtoken();
|
||||
const char * s = gettoken(token, sizeof(token));
|
||||
|
||||
if (s) {
|
||||
sk = get_skill(s, u->faction->locale);
|
||||
|
|
1442
src/kernel/build.c
1442
src/kernel/build.c
File diff suppressed because it is too large
Load Diff
|
@ -73,10 +73,11 @@ const char *str, parser fun)
|
|||
|
||||
static int do_command_i(const void *keys, struct unit *u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
const char *c;
|
||||
variant var;
|
||||
|
||||
c = getstrtoken();
|
||||
c = gettoken(token, sizeof(token));
|
||||
if (findtoken(keys, c, &var) == E_TOK_SUCCESS) {
|
||||
command *cmd = (command *)var.v;
|
||||
if (cmd->nodes && *c) {
|
||||
|
|
|
@ -587,19 +587,6 @@ int change_hitpoints(unit * u, int value)
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const char *s = getstrtoken();
|
||||
char token[64];
|
||||
const char *s = gettoken(token, sizeof(token));
|
||||
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)
|
||||
{
|
||||
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
|
||||
* paramliste. machen wir das nicht, dann wird getnewunit in s nach der
|
||||
|
|
|
@ -108,10 +108,6 @@ extern "C" {
|
|||
/* special units */
|
||||
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_ex(const char *s, const struct locale * lang);
|
||||
bool isparam(const char *s, const struct locale * lang, param_t param);
|
||||
|
|
|
@ -278,9 +278,9 @@ unit *addplayer(region * r, faction * f)
|
|||
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 false;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ const char *factionname(const struct faction *f);
|
|||
struct unit *addplayer(struct region *r, faction * f);
|
||||
struct faction *addfaction(const char *email, const char *password,
|
||||
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);
|
||||
|
||||
extern void set_alliance(struct faction *a, struct faction *b, int status);
|
||||
|
|
|
@ -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 */
|
||||
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) {
|
||||
case NOSKILL: /* fehler */
|
||||
break;
|
||||
|
@ -364,11 +364,11 @@ order *parse_order(const char *s, const struct locale * lang)
|
|||
++s;
|
||||
}
|
||||
sptr = s;
|
||||
p = *sptr ? parse_token(&sptr) : 0;
|
||||
p = *sptr ? parse_token_depr(&sptr) : 0;
|
||||
kwd = p ? get_keyword(p, lang) : NOKEYWORD;
|
||||
if (kwd == K_MAKE) {
|
||||
const char *s, *sp = sptr;
|
||||
s = parse_token(&sp);
|
||||
s = parse_token_depr(&sp);
|
||||
if (s && isparam(s, lang, P_TEMP)) {
|
||||
kwd = K_MAKETEMP;
|
||||
sptr = sp;
|
||||
|
@ -570,6 +570,6 @@ keyword_t init_order(const struct order *ord)
|
|||
|
||||
assert(ord && ord->data);
|
||||
if (ord->data->_str) cmd = _strdup(ord->data->_str);
|
||||
init_tokens_str(cmd, cmd);
|
||||
init_tokens_str(cmd);
|
||||
return ord->data->_keyword;
|
||||
}
|
||||
|
|
|
@ -128,19 +128,19 @@ static void test_init_order(CuTest *tc) {
|
|||
|
||||
static void test_getstrtoken(CuTest *tc) {
|
||||
char *cmd = _strdup("hurr \"durr\" \"\" \'\'");
|
||||
init_tokens_str(cmd, cmd);
|
||||
init_tokens_str(cmd);
|
||||
CuAssertStrEquals(tc, "hurr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
CuAssertStrEquals(tc, "", getstrtoken());
|
||||
CuAssertStrEquals(tc, "", getstrtoken());
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
init_tokens_str(0, 0);
|
||||
init_tokens_str(0);
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
}
|
||||
|
||||
static void test_skip_token(CuTest *tc) {
|
||||
char *cmd = _strdup("hurr \"durr\"");
|
||||
init_tokens_str(cmd, cmd);
|
||||
init_tokens_str(cmd);
|
||||
skip_token();
|
||||
CuAssertStrEquals(tc, "durr", getstrtoken());
|
||||
CuAssertStrEquals(tc, 0, getstrtoken());
|
||||
|
|
|
@ -169,7 +169,7 @@ static unit *unitorders(FILE * F, int enc, struct faction *f)
|
|||
if (s[0]) {
|
||||
if (s[0] != '@') {
|
||||
const char *stok = s;
|
||||
stok = parse_token(&stok);
|
||||
stok = parse_token_depr(&stok);
|
||||
|
||||
if (stok) {
|
||||
bool quit = false;
|
||||
|
@ -224,9 +224,10 @@ static faction *factionorders(void)
|
|||
f = findfaction(fid);
|
||||
|
||||
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));
|
||||
ADDMSG(&f->msgs, msg_message("wrongpasswd", "faction password",
|
||||
f->no, pass));
|
||||
|
@ -267,11 +268,12 @@ int readorders(const char *filename)
|
|||
* Partei */
|
||||
|
||||
while (b) {
|
||||
char token[128];
|
||||
const struct locale *lang = f ? f->locale : default_locale;
|
||||
param_t p;
|
||||
const char *s;
|
||||
init_tokens_str(b, NULL);
|
||||
s = getstrtoken();
|
||||
init_tokens_str(b);
|
||||
s = gettoken(token, sizeof(token));
|
||||
p = s ? findparam(s, lang) : NOPARAM;
|
||||
switch (p) {
|
||||
#undef LOCALE_CHANGE
|
||||
|
@ -308,7 +310,7 @@ int readorders(const char *filename)
|
|||
if (!b) {
|
||||
break;
|
||||
}
|
||||
init_tokens_str(b, NULL);
|
||||
init_tokens_str(b);
|
||||
b = getstrtoken();
|
||||
p = (!b || b[0] == '@') ? NOPARAM : findparam(b, lang);
|
||||
} while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT
|
||||
|
|
|
@ -491,16 +491,19 @@ void usetprivate(unit * u, const char *str)
|
|||
{
|
||||
attrib *a = a_find(u->attribs, &at_private);
|
||||
|
||||
if (str == NULL) {
|
||||
if (a)
|
||||
if (str == NULL || *str == 0) {
|
||||
if (a) {
|
||||
a_remove(&u->attribs, a);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!a)
|
||||
if (!a) {
|
||||
a = a_add(&u->attribs, a_new(&at_private));
|
||||
if (a->data.v)
|
||||
}
|
||||
if (a->data.v) {
|
||||
free(a->data.v);
|
||||
a->data.v = _strdup((const char *)str);
|
||||
}
|
||||
a->data.v = _strdup(str);
|
||||
}
|
||||
|
||||
/*********************/
|
||||
|
|
136
src/laws.c
136
src/laws.c
|
@ -946,14 +946,15 @@ static bool EnhancedQuit(void)
|
|||
|
||||
int quit_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
faction *f = u->faction;
|
||||
const char *passwd;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_QUIT);
|
||||
passwd = getstrtoken();
|
||||
if (checkpasswd(f, (const char *)passwd, false)) {
|
||||
passwd = gettoken(token, sizeof(token));
|
||||
if (checkpasswd(f, (const char *)passwd)) {
|
||||
if (EnhancedQuit()) {
|
||||
int f2_id = getid();
|
||||
if (f2_id > 0) {
|
||||
|
@ -1159,13 +1160,14 @@ void do_enter(struct region *r, bool is_final_attempt)
|
|||
while (*ordp) {
|
||||
order *ord = *ordp;
|
||||
if (getkeyword(ord) == K_ENTER) {
|
||||
char token[128];
|
||||
param_t p;
|
||||
int id;
|
||||
unit *ulast = NULL;
|
||||
const char * s;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
p = findparam_ex(s, u->faction->locale);
|
||||
id = getid();
|
||||
|
||||
|
@ -1339,6 +1341,7 @@ void quit(void)
|
|||
|
||||
int ally_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
ally *sf, **sfp;
|
||||
faction *f;
|
||||
int keyword, not_kw;
|
||||
|
@ -1354,7 +1357,7 @@ int ally_cmd(unit * u, struct order *ord)
|
|||
if (f == u->faction)
|
||||
return 0;
|
||||
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (!s[0])
|
||||
keyword = P_ANY;
|
||||
|
@ -1492,6 +1495,7 @@ static void init_prefixnames(void)
|
|||
|
||||
int prefix_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
attrib **ap;
|
||||
const char *s;
|
||||
local_names *in = pnames;
|
||||
|
@ -1509,7 +1513,7 @@ int prefix_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (!s || !*s) {
|
||||
attrib *a = NULL;
|
||||
|
@ -1556,13 +1560,14 @@ static cmp_building_cb get_cmp_region_owner(void)
|
|||
|
||||
int display_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
char **s = NULL;
|
||||
const char *str;
|
||||
region *r = u->region;
|
||||
|
||||
init_order(ord);
|
||||
|
||||
str = getstrtoken();
|
||||
str = gettoken(token, sizeof(token));
|
||||
switch (findparam_ex(str, u->faction->locale)) {
|
||||
case P_BUILDING:
|
||||
case P_GEBAEUDE:
|
||||
|
@ -1598,15 +1603,7 @@ int display_cmd(unit * u, struct order *ord)
|
|||
break;
|
||||
|
||||
case P_PRIVAT:
|
||||
{
|
||||
const char *d = getstrtoken();
|
||||
if (d == NULL || *d == 0) {
|
||||
usetprivate(u, NULL);
|
||||
}
|
||||
else {
|
||||
usetprivate(u, d);
|
||||
}
|
||||
}
|
||||
usetprivate(u, getstrtoken());
|
||||
break;
|
||||
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
building *b = u->building;
|
||||
region *r = u->region;
|
||||
char **s = NULL;
|
||||
|
@ -1737,11 +1735,11 @@ int name_cmd(struct unit *u, struct order *ord)
|
|||
const char *str;
|
||||
|
||||
init_order(ord);
|
||||
str = getstrtoken();
|
||||
str = gettoken(token, sizeof(token));
|
||||
p = findparam_ex(str, u->faction->locale);
|
||||
|
||||
if (p == P_FOREIGN) {
|
||||
str = getstrtoken();
|
||||
str = gettoken(token, sizeof(token));
|
||||
foreign = true;
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
unit *u2;
|
||||
const char *s;
|
||||
int n, cont;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
||||
* 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:
|
||||
{
|
||||
bool see = false;
|
||||
|
||||
n = getfactionid();
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (u2->faction->no == n && seefaction(u->faction, r, u2, 0)) {
|
||||
see = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!see) {
|
||||
if (!u2) {
|
||||
cmistake(u, ord, 66, MSG_MESSAGE);
|
||||
break;
|
||||
}
|
||||
|
@ -2042,21 +2037,17 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
mailfaction(u, n, ord, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case P_UNIT:
|
||||
{
|
||||
bool see = false;
|
||||
n = getid();
|
||||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (u2->no == n && cansee(u->faction, r, u2, 0)) {
|
||||
see = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!see) {
|
||||
if (!u2) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord,
|
||||
"feedback_unit_not_found", ""));
|
||||
return 0;
|
||||
|
@ -2082,7 +2073,6 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
mailunit(r, u, n, ord, s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case P_BUILDING:
|
||||
case P_GEBAEUDE:
|
||||
|
@ -2182,7 +2172,7 @@ int email_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
else {
|
||||
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);
|
||||
ADDMSG(&f->msgs, msg_message("changemail_invalid", "value", s));
|
||||
}
|
||||
|
@ -2201,7 +2191,7 @@ int password_cmd(unit * u, struct order *ord)
|
|||
bool pwok = true;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(pwbuf, sizeof(pwbuf));
|
||||
|
||||
if (!s || !*s) {
|
||||
for (i = 0; i < 6; i++)
|
||||
|
@ -2210,14 +2200,10 @@ int password_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
else {
|
||||
char *c;
|
||||
|
||||
strlcpy(pwbuf, (const char *)s, 31);
|
||||
pwbuf[31] = 0;
|
||||
c = pwbuf;
|
||||
while (*c && pwok) {
|
||||
if (!isalnum(*(unsigned char *)c))
|
||||
for (c = pwbuf; *c && pwok; ++c) {
|
||||
if (!isalnum(*(unsigned char *)c)) {
|
||||
pwok = false;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(u->faction->passw);
|
||||
|
@ -2235,11 +2221,12 @@ int password_cmd(unit * u, struct order *ord)
|
|||
|
||||
int send_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
const char *s;
|
||||
int option;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
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)
|
||||
{
|
||||
const char *s;
|
||||
keyword_t kwd;
|
||||
|
||||
kwd = init_order(ord);
|
||||
assert(kwd == K_GROUP);
|
||||
s = getstrtoken();
|
||||
|
||||
join_group(u, s);
|
||||
join_group(u, getstrtoken());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2613,11 +2597,12 @@ int guard_off_cmd(unit * u, struct order *ord)
|
|||
|
||||
int reshow_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char lbuf[64];
|
||||
const char *s;
|
||||
param_t p = NOPARAM;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(lbuf, sizeof(lbuf));
|
||||
|
||||
if (s && isparam(s, u->faction->locale, P_ANY)) {
|
||||
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)
|
||||
{
|
||||
const char *param;
|
||||
char token[128];
|
||||
const char *s;
|
||||
|
||||
init_order(ord);
|
||||
|
||||
param = getstrtoken();
|
||||
switch (findparam(param, u->faction->locale)) {
|
||||
s = gettoken(token, sizeof(token));
|
||||
switch (findparam(s, u->faction->locale)) {
|
||||
case P_NOT:
|
||||
setstatus(u, ST_AVOID);
|
||||
break;
|
||||
|
@ -2663,7 +2648,7 @@ int status_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (param && param[0]) {
|
||||
if (s && s[0]) {
|
||||
add_message(&u->faction->msgs,
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
const char *s;
|
||||
int level = 0;
|
||||
spell *sp = 0;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
|
||||
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 */
|
||||
level = getint();
|
||||
level = _max(0, level);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
}
|
||||
|
||||
sp = unit_getspell(u, s, u->faction->locale);
|
||||
|
@ -2703,7 +2689,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
|||
return 0;
|
||||
}
|
||||
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
|
||||
if (findparam(s, u->faction->locale) == P_NOT) {
|
||||
/* KAMPFZAUBER "<Spruchname>" NICHT löscht diesen speziellen
|
||||
|
@ -2921,13 +2907,14 @@ void restack_units(void)
|
|||
struct order *ord;
|
||||
for (ord = u->orders; ord; ord = ord->next) {
|
||||
if (getkeyword(ord) == K_SORT) {
|
||||
char token[128];
|
||||
const char *s;
|
||||
param_t p;
|
||||
int id;
|
||||
unit *v;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
p = findparam(s, u->faction->locale);
|
||||
id = getid();
|
||||
v = findunit(id);
|
||||
|
@ -2997,16 +2984,17 @@ void restack_units(void)
|
|||
|
||||
int renumber_cmd(unit * u, order * ord)
|
||||
{
|
||||
char token[128];
|
||||
const char *s;
|
||||
int i;
|
||||
faction *f = u->faction;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
switch (findparam_ex(s, u->faction->locale)) {
|
||||
|
||||
case P_FACTION:
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s && *s) {
|
||||
int id = atoi36((const char *)s);
|
||||
attrib *a = a_find(f->attribs, &at_number);
|
||||
|
@ -3017,7 +3005,7 @@ int renumber_cmd(unit * u, order * ord)
|
|||
break;
|
||||
|
||||
case P_UNIT:
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s == NULL || *s == 0) {
|
||||
i = newunitid();
|
||||
}
|
||||
|
@ -3060,7 +3048,7 @@ int renumber_cmd(unit * u, order * ord)
|
|||
cmistake(u, ord, 116, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s == NULL || *s == 0) {
|
||||
i = newcontainerid();
|
||||
}
|
||||
|
@ -3089,7 +3077,7 @@ int renumber_cmd(unit * u, order * ord)
|
|||
cmistake(u, ord, 148, MSG_EVENT);
|
||||
break;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (*s == 0) {
|
||||
i = newcontainerid();
|
||||
}
|
||||
|
@ -3355,8 +3343,8 @@ void new_units(void)
|
|||
while (*ordp) {
|
||||
order *makeord = *ordp;
|
||||
if (getkeyword(makeord) == K_MAKETEMP) {
|
||||
const char *token;
|
||||
char *name = NULL;
|
||||
char token[128], *name = NULL;
|
||||
const char *s;
|
||||
int alias;
|
||||
ship *sh;
|
||||
order **newordersp;
|
||||
|
@ -3390,9 +3378,9 @@ void new_units(void)
|
|||
init_order(makeord);
|
||||
alias = getid();
|
||||
|
||||
token = getstrtoken();
|
||||
if (token && token[0]) {
|
||||
name = _strdup(token);
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s && s[0]) {
|
||||
name = _strdup(s);
|
||||
}
|
||||
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
|
||||
if (name != NULL)
|
||||
|
@ -3700,10 +3688,9 @@ void defaultorders(void)
|
|||
order *new_order = 0;
|
||||
const char *s;
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(lbuf, sizeof(lbuf));
|
||||
if (s) {
|
||||
strcpy(lbuf, s);
|
||||
new_order = parse_order(lbuf, u->faction->locale);
|
||||
new_order = parse_order(s, u->faction->locale);
|
||||
}
|
||||
*ordp = ord->next;
|
||||
ord->next = NULL;
|
||||
|
@ -3810,19 +3797,20 @@ static void update_spells(void)
|
|||
|
||||
int use_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
const char *t;
|
||||
int n, err = ENOITEM;
|
||||
const item_type *itype;
|
||||
|
||||
init_order(ord);
|
||||
|
||||
t = getstrtoken();
|
||||
t = gettoken(token, sizeof(token));
|
||||
n = atoi((const char *)t);
|
||||
if (n == 0) {
|
||||
if (isparam(t, u->faction->locale, P_ANY)) {
|
||||
/* BENUTZE ALLES Yanxspirit */
|
||||
n = INT_MAX;
|
||||
t = getstrtoken();
|
||||
t = gettoken(token, sizeof(token));
|
||||
}
|
||||
else {
|
||||
/* BENUTZE Yanxspirit */
|
||||
|
@ -3831,7 +3819,7 @@ int use_cmd(unit * u, struct order *ord)
|
|||
}
|
||||
else {
|
||||
/* BENUTZE 42 Yanxspirit */
|
||||
t = getstrtoken();
|
||||
t = gettoken(token, sizeof(token));
|
||||
}
|
||||
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)
|
||||
{
|
||||
char token[128];
|
||||
if (u->number > 0 && (urace(u)->ec_flags & GETITEM)) {
|
||||
int use, count, para;
|
||||
const item_type *itype;
|
||||
const char *s;
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
count = s ? atoip(s) : 0;
|
||||
para = findparam(s, u->faction->locale);
|
||||
|
||||
if (count == 0 && para == P_EACH) {
|
||||
count = getint() * u->number;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
itype = s ? finditemtype(s, u->faction->locale) : 0;
|
||||
if (itype == NULL)
|
||||
return 0;
|
||||
|
@ -3956,19 +3945,20 @@ int reserve_self(unit * u, struct order *ord) {
|
|||
|
||||
int claim_cmd(unit * u, struct order *ord)
|
||||
{
|
||||
char token[128];
|
||||
const char *t;
|
||||
int n;
|
||||
const item_type *itype;
|
||||
|
||||
init_order(ord);
|
||||
|
||||
t = getstrtoken();
|
||||
t = gettoken(token, sizeof(token));
|
||||
n = atoi((const char *)t);
|
||||
if (n == 0) {
|
||||
n = 1;
|
||||
}
|
||||
else {
|
||||
t = getstrtoken();
|
||||
t = gettoken(token, sizeof(token));
|
||||
}
|
||||
itype = finditemtype(t, u->faction->locale);
|
||||
|
||||
|
|
14
src/magic.c
14
src/magic.c
|
@ -2495,6 +2495,7 @@ static bool is_moving_ship(const region * r, ship * sh)
|
|||
|
||||
static castorder *cast_cmd(unit * u, order * ord)
|
||||
{
|
||||
char token[128];
|
||||
region *r = u->region;
|
||||
region *target_r = r;
|
||||
int level, range;
|
||||
|
@ -2518,7 +2519,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
|||
level = eff_skill(u, SK_MAGIC, r);
|
||||
|
||||
init_order(ord);
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
param = findparam(s, u->faction->locale);
|
||||
/* für Syntax ' STUFE x REGION y z ' */
|
||||
if (param == P_LEVEL) {
|
||||
|
@ -2529,7 +2530,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
|||
cmistake(u, ord, 10, MSG_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
param = findparam(s, u->faction->locale);
|
||||
}
|
||||
if (param == P_REGION) {
|
||||
|
@ -2546,7 +2547,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
|||
"unit region command", u, u->region, ord));
|
||||
return 0;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
param = findparam(s, u->faction->locale);
|
||||
}
|
||||
/* 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);
|
||||
return 0;
|
||||
}
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
}
|
||||
if (!s || !s[0] || strlen(s) == 0) {
|
||||
/* 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 *));
|
||||
int p = 0, size = 2;
|
||||
for (;;) {
|
||||
s = getstrtoken();
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (!s || *s == 0)
|
||||
break;
|
||||
if (p + 1 >= size) {
|
||||
|
@ -2935,7 +2936,7 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
|
|||
if (sb) {
|
||||
select_spellbook(&tokens, sb, lang);
|
||||
}
|
||||
|
||||
#if 0 // TODO: some familiars can cast spells from the mage's spellbook?
|
||||
u = get_familiar_mage(u);
|
||||
if (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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tokens) {
|
||||
variant token;
|
||||
|
|
24
src/move.c
24
src/move.c
|
@ -1156,7 +1156,7 @@ static void cycle_route(order * ord, unit * u, int gereist)
|
|||
int bytes, cm = 0;
|
||||
char tail[1024], *bufp = tail;
|
||||
char neworder[2048];
|
||||
const char *token;
|
||||
char token[128];
|
||||
direction_t d = NODIRECTION;
|
||||
bool paused = false;
|
||||
bool pause;
|
||||
|
@ -1171,11 +1171,12 @@ static void cycle_route(order * ord, unit * u, int gereist)
|
|||
|
||||
neworder[0] = 0;
|
||||
for (cm = 0;; ++cm) {
|
||||
const char *s;
|
||||
const struct locale *lang = u->faction->locale;
|
||||
pause = false;
|
||||
token = getstrtoken();
|
||||
if (token && *token) {
|
||||
d = get_direction(token, lang);
|
||||
s = gettoken(token, sizeof(token));
|
||||
if (s && *s) {
|
||||
d = get_direction(s, lang);
|
||||
if (d == D_PAUSE) {
|
||||
pause = true;
|
||||
}
|
||||
|
@ -1448,11 +1449,12 @@ static void make_route(unit * u, order * ord, region_list ** routep)
|
|||
region_list **iroute = routep;
|
||||
region *current = u->region;
|
||||
region *next = NULL;
|
||||
const char *token = getstrtoken();
|
||||
int error = movewhere(u, token, current, &next);
|
||||
char token[128];
|
||||
const char *s = gettoken(token, sizeof(token));
|
||||
int error = movewhere(u, s, current, &next);
|
||||
|
||||
if (error != E_MOVE_OK) {
|
||||
message *msg = movement_error(u, token, ord, error);
|
||||
message *msg = movement_error(u, s, ord, error);
|
||||
if (msg != NULL) {
|
||||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
|
@ -1471,10 +1473,10 @@ static void make_route(unit * u, order * ord, region_list ** routep)
|
|||
iroute = &(*iroute)->next;
|
||||
|
||||
current = next;
|
||||
token = getstrtoken();
|
||||
error = movewhere(u, token, current, &next);
|
||||
s = gettoken(token, sizeof(token));
|
||||
error = movewhere(u, s, current, &next);
|
||||
if (error) {
|
||||
message *msg = movement_error(u, token, ord, error);
|
||||
message *msg = movement_error(u, s, ord, error);
|
||||
if (msg != NULL) {
|
||||
add_message(&u->faction->msgs, msg);
|
||||
msg_release(msg);
|
||||
|
@ -2615,7 +2617,7 @@ static int hunt(unit * u, order * ord)
|
|||
/* In command steht jetzt das NACH-Kommando. */
|
||||
|
||||
/* NACH ignorieren und Parsing initialisieren. */
|
||||
init_tokens_str(command, NULL);
|
||||
init_tokens_str(command);
|
||||
getstrtoken();
|
||||
/* NACH ausführen */
|
||||
move(u, false);
|
||||
|
|
|
@ -58,7 +58,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ int RunAllTests(void)
|
|||
RUN_TESTS(suite, base36);
|
||||
RUN_TESTS(suite, bsdstring);
|
||||
RUN_TESTS(suite, functions);
|
||||
RUN_TESTS(suite, parser);
|
||||
RUN_TESTS(suite, umlaut);
|
||||
RUN_TESTS(suite, unicode);
|
||||
RUN_TESTS(suite, strings);
|
||||
|
|
|
@ -2,6 +2,7 @@ project(util C)
|
|||
|
||||
SET(_TEST_FILES
|
||||
base36.test.c
|
||||
parser.test.c
|
||||
attrib.test.c
|
||||
strings.test.c
|
||||
bsdstring.test.c
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
typedef struct parser_state {
|
||||
const char *current_token;
|
||||
char *current_cmd;
|
||||
struct parser_state *next;
|
||||
} parser_state;
|
||||
|
||||
|
@ -50,22 +49,17 @@ static int eatwhitespace_c(const char **str_p)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void init_tokens_str(const char *initstr, char *cmd)
|
||||
void init_tokens_str(const char *initstr)
|
||||
{
|
||||
if (states == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
void parser_pushstate(void)
|
||||
{
|
||||
parser_state *new_state = malloc(sizeof(parser_state));
|
||||
new_state->current_cmd = NULL;
|
||||
new_state->current_token = NULL;
|
||||
new_state->next = states;
|
||||
states = new_state;
|
||||
|
@ -74,8 +68,6 @@ void parser_pushstate(void)
|
|||
void parser_popstate(void)
|
||||
{
|
||||
parser_state *new_state = states->next;
|
||||
if (states->current_cmd != NULL)
|
||||
free(states->current_cmd);
|
||||
free(states);
|
||||
states = new_state;
|
||||
}
|
||||
|
@ -128,86 +120,136 @@ void skip_token(void)
|
|||
}
|
||||
}
|
||||
|
||||
const char *parse_token(const char **str)
|
||||
char *parse_token(const char **str, char *lbuf, size_t len)
|
||||
{
|
||||
char *cursor = lbuf;
|
||||
char quotechar = 0;
|
||||
bool escape = false;
|
||||
const char *ctoken = *str;
|
||||
|
||||
if (!ctoken) {
|
||||
return 0;
|
||||
}
|
||||
eatwhitespace_c(&ctoken);
|
||||
if (!*ctoken) {
|
||||
if (len > 0) {
|
||||
*cursor = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
while (*ctoken && cursor-len < lbuf-1) {
|
||||
ucs4_t ucs;
|
||||
size_t len;
|
||||
bool copy = false;
|
||||
|
||||
unsigned char utf8_character = *(unsigned char *)ctoken;
|
||||
if (~utf8_character & 0x80) {
|
||||
ucs = utf8_character;
|
||||
len = 1;
|
||||
}
|
||||
else {
|
||||
int ret = unicode_utf8_to_ucs4(&ucs, ctoken, &len);
|
||||
if (ret != 0) {
|
||||
log_warning("illegal character sequence in UTF8 string: %s\n", ctoken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (escape) {
|
||||
copy = true;
|
||||
escape = false;
|
||||
}
|
||||
else if (iswxspace((wint_t)ucs)) {
|
||||
if (quotechar == 0)
|
||||
break;
|
||||
copy = true;
|
||||
}
|
||||
else if (utf8_character == '"' || utf8_character == '\'') {
|
||||
if (utf8_character == quotechar) {
|
||||
++ctoken;
|
||||
break;
|
||||
}
|
||||
else if (quotechar == 0) {
|
||||
quotechar = utf8_character;
|
||||
++ctoken;
|
||||
}
|
||||
else {
|
||||
*cursor++ = *ctoken++;
|
||||
}
|
||||
}
|
||||
else if (utf8_character == SPACE_REPLACEMENT) {
|
||||
*cursor++ = ' ';
|
||||
++ctoken;
|
||||
}
|
||||
else if (utf8_character == ESCAPE_CHAR) {
|
||||
escape = true;
|
||||
++ctoken;
|
||||
}
|
||||
else {
|
||||
copy = true;
|
||||
}
|
||||
if (copy) {
|
||||
memcpy(cursor, ctoken, len);
|
||||
cursor += len;
|
||||
ctoken += len;
|
||||
}
|
||||
}
|
||||
|
||||
assert(cursor - len < lbuf - 1); // TODO: handle too-small buffers
|
||||
*cursor = '\0';
|
||||
*str = ctoken;
|
||||
return lbuf;
|
||||
}
|
||||
|
||||
const char *parse_token_depr(const char **str)
|
||||
{
|
||||
static char lbuf[MAXTOKENSIZE]; /* STATIC_RESULT: used for return, not across calls */
|
||||
char *cursor = lbuf;
|
||||
char quotechar = 0;
|
||||
bool escape = false;
|
||||
const char *ctoken = *str;
|
||||
|
||||
if (!ctoken) {
|
||||
return 0;
|
||||
}
|
||||
eatwhitespace_c(&ctoken);
|
||||
if (!*ctoken) {
|
||||
return 0;
|
||||
}
|
||||
while (*ctoken && cursor - lbuf < MAXTOKENSIZE - 1) {
|
||||
ucs4_t ucs;
|
||||
size_t len;
|
||||
bool copy = false;
|
||||
|
||||
unsigned char utf8_character = *(unsigned char *)ctoken;
|
||||
if (~utf8_character & 0x80) {
|
||||
ucs = utf8_character;
|
||||
len = 1;
|
||||
} else {
|
||||
int ret = unicode_utf8_to_ucs4(&ucs, ctoken, &len);
|
||||
if (ret != 0) {
|
||||
log_warning("illegal character sequence in UTF8 string: %s\n", ctoken);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (escape) {
|
||||
copy = true;
|
||||
escape = false;
|
||||
} else if (iswxspace((wint_t) ucs)) {
|
||||
if (quotechar == 0)
|
||||
break;
|
||||
copy = true;
|
||||
} else if (utf8_character == '"' || utf8_character == '\'') {
|
||||
if (utf8_character == quotechar) {
|
||||
++ctoken;
|
||||
break;
|
||||
} else if (quotechar == 0) {
|
||||
quotechar = utf8_character;
|
||||
++ctoken;
|
||||
} else {
|
||||
*cursor++ = *ctoken++;
|
||||
}
|
||||
} else if (utf8_character == SPACE_REPLACEMENT) {
|
||||
*cursor++ = ' ';
|
||||
++ctoken;
|
||||
} else if (utf8_character == ESCAPE_CHAR) {
|
||||
escape = true;
|
||||
++ctoken;
|
||||
} else {
|
||||
copy = true;
|
||||
}
|
||||
if (copy) {
|
||||
memcpy(cursor, ctoken, len);
|
||||
cursor += len;
|
||||
ctoken += len;
|
||||
}
|
||||
}
|
||||
|
||||
*cursor = '\0';
|
||||
*str = ctoken;
|
||||
return lbuf;
|
||||
return parse_token(str, lbuf, MAXTOKENSIZE);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const char *str = getstrtoken();
|
||||
char token[16];
|
||||
const char *str = gettoken(token, sizeof(token));
|
||||
int i = str ? atoi36(str) : 0;
|
||||
if (i < 0) {
|
||||
return -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned int atoip(const char *s)
|
||||
{
|
||||
int n;
|
||||
|
||||
assert(s);
|
||||
n = atoi(s);
|
||||
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
* | | Enno Rehling <enno@eressea.de>
|
||||
* | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||
* | (c) 1998 - 2007 |
|
||||
* | (c) 1998 - 2007 |
|
||||
* | | This program may not be used, modified or distributed
|
||||
* +-------------------+ without prior permission by the authors of Eressea.
|
||||
*
|
||||
|
@ -14,14 +14,20 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void init_tokens_str(const char *initstr, char *cmd); /* initialize token parsing, take ownership of cmd */
|
||||
void skip_token(void);
|
||||
const char *parse_token(const char **str);
|
||||
void parser_pushstate(void);
|
||||
void parser_popstate(void);
|
||||
bool parser_end(void);
|
||||
const char *getstrtoken(void);
|
||||
int getid(void);
|
||||
void init_tokens_str(const char *initstr); /* initialize token parsing */
|
||||
void skip_token(void);
|
||||
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_popstate(void);
|
||||
bool parser_end(void);
|
||||
const char *getstrtoken(void);
|
||||
const char *gettoken(char *lbuf, size_t bufsize);
|
||||
unsigned int getuint(void);
|
||||
int getint(void);
|
||||
int getid(void);
|
||||
unsigned int atoip(const char *s);
|
||||
|
||||
#define getshipid() getid()
|
||||
#define getfactionid() getid()
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue