forked from github/server
fix escape_string mmeory corruption error.
fix a number of small stuff that happens when loading very old data files (like 572).
This commit is contained in:
parent
4c5f4c5e20
commit
cd70b8684d
|
@ -685,13 +685,16 @@ static void
|
|||
fwriteorder(FILE * F, const struct order *ord, const struct locale *lang,
|
||||
bool escape)
|
||||
{
|
||||
char ebuf[1024];
|
||||
char ebuf[1025];
|
||||
char obuf[1024];
|
||||
const char *str = obuf;
|
||||
fputc('"', F);
|
||||
write_order(ord, obuf, sizeof(obuf));
|
||||
if (escape) {
|
||||
str = escape_string(obuf, ebuf, sizeof(ebuf));
|
||||
if (str == ebuf) {
|
||||
ebuf[1024] = 0;
|
||||
}
|
||||
}
|
||||
if (str[0])
|
||||
fputs(str, F);
|
||||
|
|
12
src/give.c
12
src/give.c
|
@ -165,7 +165,7 @@ struct order *ord)
|
|||
return -1;
|
||||
}
|
||||
else if (n == 0) {
|
||||
int reserve = get_reservation(src, itype->rtype);
|
||||
int reserve = get_reservation(src, itype);
|
||||
if (reserve) {
|
||||
msg_feedback(src, ord, "nogive_reserved", "resource reservation",
|
||||
itype->rtype, reserve);
|
||||
|
@ -187,7 +187,7 @@ struct order *ord)
|
|||
i_change(&dest->items, itype, r);
|
||||
#ifdef RESERVE_GIVE
|
||||
#ifdef RESERVE_DONATIONS
|
||||
change_reservation(dest, item2resource(itype), r);
|
||||
change_reservation(dest, itype, r);
|
||||
#else
|
||||
if (src->faction == dest->faction) {
|
||||
change_reservation(dest, item2resource(itype), r);
|
||||
|
@ -516,7 +516,7 @@ void give_unit(unit * u, unit * u2, order * ord)
|
|||
cmistake(u, ord, 156, MSG_COMMERCE);
|
||||
return;
|
||||
}
|
||||
// TODO: add_give(u, u2, 1, 1, get_resourcetype(R_UNIT), ord, 0);
|
||||
add_give(u, u2, n, n, get_resourcetype(R_PERSON), ord, 0);
|
||||
u_setfaction(u, u2->faction);
|
||||
u2->faction->newbies += n;
|
||||
}
|
||||
|
@ -680,8 +680,8 @@ void give_cmd(unit * u, order * ord)
|
|||
item *itm = *itmp;
|
||||
const item_type *itype = itm->type;
|
||||
if (itm->number > 0
|
||||
&& itm->number - get_reservation(u, itype->rtype) > 0) {
|
||||
n = itm->number - get_reservation(u, itype->rtype);
|
||||
&& itm->number - get_reservation(u, itype) > 0) {
|
||||
n = itm->number - get_reservation(u, itype);
|
||||
if (give_item(n, itype, u, u2, ord) == 0) {
|
||||
if (*itmp != itm)
|
||||
continue;
|
||||
|
@ -719,7 +719,7 @@ void give_cmd(unit * u, order * ord)
|
|||
item *i = *i_find(&u->items, itype);
|
||||
if (i != NULL) {
|
||||
if (can_give(u, u2, itype, 0)) {
|
||||
n = i->number - get_reservation(u, itype->rtype);
|
||||
n = i->number - get_reservation(u, itype);
|
||||
give_item(n, itype, u, u2, ord);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -604,7 +604,7 @@ static const char *resourcenames[MAX_RESOURCES] = {
|
|||
"aurafocus", "sphereofinv", "magicbag",
|
||||
"magicherbbag", "dreameye", "p2", "seed", "mallornseed",
|
||||
"money", "aura", "permaura",
|
||||
"hp", "peasant"
|
||||
"hp", "peasant", "person"
|
||||
};
|
||||
|
||||
const resource_type *get_resourcetype(resource_t type) {
|
||||
|
@ -949,6 +949,8 @@ void init_resources(void)
|
|||
{
|
||||
resource_type *rtype;
|
||||
|
||||
rtype = rt_get_or_create(resourcenames[R_PERSON]); // lousy hack
|
||||
|
||||
rtype = rt_get_or_create(resourcenames[R_PEASANT]);
|
||||
rtype->uchange = res_changepeasants;
|
||||
|
||||
|
|
|
@ -298,6 +298,7 @@ extern "C" {
|
|||
R_PERMAURA, /* Permanente Aura */
|
||||
R_LIFE,
|
||||
R_PEASANT,
|
||||
R_PERSON,
|
||||
|
||||
MAX_RESOURCES, /* do not use outside item.c ! */
|
||||
NORESOURCE = -1
|
||||
|
|
|
@ -84,34 +84,34 @@ int change_resource(unit * u, const resource_type * rtype, int change)
|
|||
return i;
|
||||
}
|
||||
|
||||
int get_reservation(const unit * u, const resource_type * rtype)
|
||||
int get_reservation(const unit * u, const item_type * itype)
|
||||
{
|
||||
reservation *res = u->reservations;
|
||||
|
||||
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM))
|
||||
if (itype->rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM))
|
||||
return (u->number * GOLEM_STONE);
|
||||
if (rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM))
|
||||
if (itype->rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM))
|
||||
return (u->number * GOLEM_IRON);
|
||||
while (res && res->type != rtype)
|
||||
while (res && res->type != itype)
|
||||
res = res->next;
|
||||
if (res)
|
||||
return res->value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int change_reservation(unit * u, const resource_type * rtype, int value)
|
||||
int change_reservation(unit * u, const item_type * itype, int value)
|
||||
{
|
||||
reservation *res, **rp = &u->reservations;
|
||||
|
||||
if (!value)
|
||||
return 0;
|
||||
|
||||
while (*rp && (*rp)->type != rtype)
|
||||
while (*rp && (*rp)->type != itype)
|
||||
rp = &(*rp)->next;
|
||||
res = *rp;
|
||||
if (!res) {
|
||||
*rp = res = calloc(sizeof(reservation), 1);
|
||||
res->type = rtype;
|
||||
res->type = itype;
|
||||
res->value = value;
|
||||
}
|
||||
else if (res && res->value + value <= 0) {
|
||||
|
@ -125,18 +125,18 @@ int change_reservation(unit * u, const resource_type * rtype, int value)
|
|||
return res->value;
|
||||
}
|
||||
|
||||
int set_resvalue(unit * u, const resource_type * rtype, int value)
|
||||
int set_resvalue(unit * u, const item_type * itype, int value)
|
||||
{
|
||||
reservation *res, **rp = &u->reservations;
|
||||
assert(rtype->itype);
|
||||
while (*rp && (*rp)->type != rtype)
|
||||
|
||||
while (*rp && (*rp)->type != itype)
|
||||
rp = &(*rp)->next;
|
||||
res = *rp;
|
||||
if (!res) {
|
||||
if (!value)
|
||||
return 0;
|
||||
*rp = res = calloc(sizeof(reservation), 1);
|
||||
res->type = rtype;
|
||||
res->type = itype;
|
||||
res->value = value;
|
||||
}
|
||||
else if (res && value <= 0) {
|
||||
|
@ -166,8 +166,8 @@ int count)
|
|||
|
||||
if ((mode & GET_SLACK) && (mode & GET_RESERVE))
|
||||
use = have;
|
||||
else if (mode & (GET_SLACK|GET_RESERVE)) {
|
||||
int reserve = get_reservation(u, rtype);
|
||||
else if (rtype->itype && mode & (GET_SLACK | GET_RESERVE)) {
|
||||
int reserve = get_reservation(u, rtype->itype);
|
||||
int slack = _max(0, have - reserve);
|
||||
if (mode & GET_RESERVE)
|
||||
use = have - slack;
|
||||
|
@ -211,13 +211,13 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
|
|||
if ((mode & GET_SLACK) && (mode & GET_RESERVE)) {
|
||||
n = _min(use, have);
|
||||
}
|
||||
else {
|
||||
int reserve = get_reservation(u, rtype);
|
||||
else if (rtype->itype) {
|
||||
int reserve = get_reservation(u, rtype->itype);
|
||||
int slack = _max(0, have - reserve);
|
||||
if (mode & GET_RESERVE) {
|
||||
n = have - slack;
|
||||
n = _min(use, n);
|
||||
change_reservation(u, rtype, -n);
|
||||
change_reservation(u, rtype->itype, -n);
|
||||
}
|
||||
else if (mode & GET_SLACK) {
|
||||
n = _min(use, slack);
|
||||
|
@ -229,23 +229,24 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
|
|||
}
|
||||
|
||||
if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK | GET_RESERVE)) {
|
||||
for (v = r->units; use > 0 && v != NULL; v = v->next)
|
||||
for (v = r->units; use > 0 && v != NULL; v = v->next) {
|
||||
if (u != v) {
|
||||
int mask;
|
||||
if ((urace(v)->ec_flags & GIVEITEM) == 0)
|
||||
continue;
|
||||
if (v->items == NULL && rtype->uget == NULL)
|
||||
continue;
|
||||
int mask;
|
||||
if ((urace(v)->ec_flags & GIVEITEM) == 0)
|
||||
continue;
|
||||
if (v->items == NULL && rtype->uget == NULL)
|
||||
continue;
|
||||
|
||||
if (v->faction == f) {
|
||||
mask = (mode >> 3) & (GET_SLACK | GET_RESERVE);
|
||||
}
|
||||
else if (alliedunit(v, f, HELP_MONEY))
|
||||
mask = (mode >> 6) & (GET_SLACK | GET_RESERVE);
|
||||
else
|
||||
continue;
|
||||
use -= use_pooled(v, rtype, mask, use);
|
||||
if (v->faction == f) {
|
||||
mask = (mode >> 3) & (GET_SLACK | GET_RESERVE);
|
||||
}
|
||||
else if (alliedunit(v, f, HELP_MONEY))
|
||||
mask = (mode >> 6) & (GET_SLACK | GET_RESERVE);
|
||||
else
|
||||
continue;
|
||||
use -= use_pooled(v, rtype, mask, use);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count - use;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
|
||||
struct unit;
|
||||
struct resource_type;
|
||||
struct item_type;
|
||||
struct region;
|
||||
|
||||
/* bitfield values for get/use/change operations */
|
||||
|
@ -54,11 +55,11 @@ extern "C" {
|
|||
int change_resource(struct unit *u, const struct resource_type *res,
|
||||
int change);
|
||||
|
||||
int get_reservation(const struct unit *u, const struct resource_type *res);
|
||||
int change_reservation(struct unit *u, const struct resource_type *res,
|
||||
int get_reservation(const struct unit *u, const struct item_type *res);
|
||||
int change_reservation(struct unit *u, const struct item_type *res,
|
||||
int value);
|
||||
|
||||
int set_resvalue(struct unit * u, const struct resource_type * rtype, int value);
|
||||
int set_resvalue(struct unit * u, const struct item_type * rtype, int value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -30,10 +30,10 @@ void test_reservation(CuTest *tc) {
|
|||
assert(u);
|
||||
i_change(&u->items, rtype->itype, 100);
|
||||
CuAssertIntEquals(tc, 100, get_resource(u, rtype));
|
||||
CuAssertIntEquals(tc, 0, get_reservation(u, rtype));
|
||||
CuAssertIntEquals(tc, 50, change_reservation(u, rtype, 50));
|
||||
CuAssertIntEquals(tc, 100, change_reservation(u, rtype, 50));
|
||||
CuAssertIntEquals(tc, 50, set_resvalue(u, rtype, 50));
|
||||
CuAssertIntEquals(tc, 0, get_reservation(u, rtype->itype));
|
||||
CuAssertIntEquals(tc, 50, change_reservation(u, rtype->itype, 50));
|
||||
CuAssertIntEquals(tc, 100, change_reservation(u, rtype->itype, 50));
|
||||
CuAssertIntEquals(tc, 50, set_resvalue(u, rtype->itype, 50));
|
||||
CuAssertIntEquals(tc, 100, get_resource(u, rtype));
|
||||
CuAssertIntEquals(tc, 200, change_resource(u, rtype, 100));
|
||||
CuAssertIntEquals(tc, 200, get_resource(u, rtype));
|
||||
|
@ -61,11 +61,11 @@ void test_pool(CuTest *tc) {
|
|||
u3 = test_create_unit(test_create_faction(0), r);
|
||||
assert(u1 && u2);
|
||||
i_change(&u1->items, rtype->itype, 100);
|
||||
set_resvalue(u1, rtype, 50);
|
||||
set_resvalue(u1, rtype->itype, 50);
|
||||
i_change(&u2->items, rtype->itype, 200);
|
||||
set_resvalue(u2, rtype, 100);
|
||||
set_resvalue(u2, rtype->itype, 100);
|
||||
i_change(&u3->items, rtype->itype, 400);
|
||||
set_resvalue(u3, rtype, 200);
|
||||
set_resvalue(u3, rtype->itype, 200);
|
||||
|
||||
CuAssertIntEquals(tc, 50, get_pooled(u1, rtype, GET_SLACK, 40));
|
||||
CuAssertIntEquals(tc, 50, get_pooled(u1, rtype, GET_SLACK, INT_MAX));
|
||||
|
@ -112,46 +112,45 @@ void test_pool_use(CuTest *tc) {
|
|||
unit *u1, *u2, *u3;
|
||||
faction *f;
|
||||
region *r;
|
||||
struct resource_type *rtype;
|
||||
struct item_type *itype;
|
||||
ally *al;
|
||||
|
||||
test_cleanup();
|
||||
test_create_world();
|
||||
rtype = rt_get_or_create("money");
|
||||
it_get_or_create(rtype);
|
||||
itype = it_get_or_create(rt_get_or_create("money"));
|
||||
f = test_create_faction(0);
|
||||
r = findregion(0, 0);
|
||||
assert(r && f && rtype && rtype->itype);
|
||||
assert(r && f && itype);
|
||||
u1 = test_create_unit(f, r);
|
||||
u2 = test_create_unit(f, r);
|
||||
u3 = test_create_unit(test_create_faction(0), r);
|
||||
assert(u1 && u2);
|
||||
i_change(&u1->items, rtype->itype, 100);
|
||||
set_resvalue(u1, rtype, 50);
|
||||
i_change(&u2->items, rtype->itype, 200);
|
||||
set_resvalue(u2, rtype, 100);
|
||||
i_change(&u3->items, rtype->itype, 400);
|
||||
set_resvalue(u3, rtype, 200);
|
||||
i_change(&u1->items, itype, 100);
|
||||
set_resvalue(u1, itype, 50);
|
||||
i_change(&u2->items, itype, 200);
|
||||
set_resvalue(u2, itype, 100);
|
||||
i_change(&u3->items, itype, 400);
|
||||
set_resvalue(u3, itype, 200);
|
||||
al = ally_add(&u3->faction->allies, f);
|
||||
al->status = HELP_MONEY;
|
||||
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_SLACK, 10));
|
||||
CuAssertIntEquals(tc, 40, use_pooled(u1, rtype, GET_SLACK, 50));
|
||||
CuAssertIntEquals(tc, 50, i_get(u1->items, rtype->itype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, itype->rtype, GET_SLACK, 10));
|
||||
CuAssertIntEquals(tc, 40, use_pooled(u1, itype->rtype, GET_SLACK, 50));
|
||||
CuAssertIntEquals(tc, 50, i_get(u1->items, itype));
|
||||
|
||||
CuAssertIntEquals(tc, 50, get_reservation(u1, rtype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_RESERVE, 10));
|
||||
CuAssertIntEquals(tc, 40, i_get(u1->items, rtype->itype));
|
||||
CuAssertIntEquals(tc, 40, get_reservation(u1, rtype));
|
||||
CuAssertIntEquals(tc, 40, use_pooled(u1, rtype, GET_RESERVE, 50));
|
||||
CuAssertIntEquals(tc, 50, get_reservation(u1, itype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, itype->rtype, GET_RESERVE, 10));
|
||||
CuAssertIntEquals(tc, 40, i_get(u1->items, itype));
|
||||
CuAssertIntEquals(tc, 40, get_reservation(u1, itype));
|
||||
CuAssertIntEquals(tc, 40, use_pooled(u1, itype->rtype, GET_RESERVE, 50));
|
||||
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_POOLED_SLACK, 10));
|
||||
CuAssertIntEquals(tc, 90, use_pooled(u1, rtype, GET_POOLED_SLACK, 100));
|
||||
CuAssertIntEquals(tc, 100, i_get(u2->items, rtype->itype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, rtype, GET_POOLED_RESERVE, 10));
|
||||
CuAssertIntEquals(tc, 90, get_reservation(u2, rtype));
|
||||
CuAssertIntEquals(tc, 90, use_pooled(u1, rtype, GET_POOLED_RESERVE, 100));
|
||||
CuAssertIntEquals(tc, 0, i_get(u2->items, rtype->itype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, itype->rtype, GET_POOLED_SLACK, 10));
|
||||
CuAssertIntEquals(tc, 90, use_pooled(u1, itype->rtype, GET_POOLED_SLACK, 100));
|
||||
CuAssertIntEquals(tc, 100, i_get(u2->items, itype));
|
||||
CuAssertIntEquals(tc, 10, use_pooled(u1, itype->rtype, GET_POOLED_RESERVE, 10));
|
||||
CuAssertIntEquals(tc, 90, get_reservation(u2, itype));
|
||||
CuAssertIntEquals(tc, 90, use_pooled(u1, itype->rtype, GET_POOLED_RESERVE, 100));
|
||||
CuAssertIntEquals(tc, 0, i_get(u2->items, itype));
|
||||
}
|
||||
|
||||
void test_change_resource(CuTest * tc)
|
||||
|
|
|
@ -154,6 +154,9 @@ static race *rc_find_i(const char *name)
|
|||
while (rc && !strcmp(rname, rc->_name) == 0) {
|
||||
rc = rc->next;
|
||||
}
|
||||
if (!rc && strcmp(name, "uruk") == 0) {
|
||||
rc = rc_find_i("orc");
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -401,25 +401,25 @@ void read_items(struct storage *store, item ** ilist)
|
|||
{
|
||||
for (;;) {
|
||||
char ibuf[32];
|
||||
const resource_type *rtype;
|
||||
const item_type *itype;
|
||||
int i;
|
||||
READ_STR(store, ibuf, sizeof(ibuf));
|
||||
if (!strcmp("end", ibuf)) {
|
||||
break;
|
||||
}
|
||||
rtype = rt_find(ibuf);
|
||||
itype = it_find(ibuf);
|
||||
READ_INT(store, &i);
|
||||
if (i <= 0) {
|
||||
log_error("data contains an entry with %d %s\n", i, resourcename(rtype, NMF_PLURAL));
|
||||
log_error("data contains an entry with %d %s\n", i, resourcename(itype->rtype, NMF_PLURAL));
|
||||
}
|
||||
else {
|
||||
if (rtype && rtype->itype) {
|
||||
i_change(ilist, rtype->itype, i);
|
||||
if (itype && itype->rtype) {
|
||||
i_change(ilist, itype, i);
|
||||
}
|
||||
else {
|
||||
log_error("data contains unknown item type %s.\n", ibuf);
|
||||
}
|
||||
assert(rtype && rtype->itype);
|
||||
assert(itype && itype->rtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
|
||||
typedef struct reservation {
|
||||
struct reservation *next;
|
||||
const struct resource_type *type;
|
||||
const struct item_type *type;
|
||||
int value;
|
||||
} reservation;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
#define SAVEGAMEID_VERSION 343 /* instead of XMLNAME, save the game.id parameter from the config */
|
||||
#define BUILDNO_VERSION 344 /* storing the build number in the save */
|
||||
#define AUTO_RACENAME_VERSION 345 /* NPC units with name==NULL will automatically get their race for a name */
|
||||
#define MIN_VERSION CURSETYPE_VERSION /* minimal datafile we support */
|
||||
#define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */
|
||||
#define RELEASE_VERSION AUTO_RACENAME_VERSION /* current datafile */
|
||||
|
||||
#define STREAM_VERSION 2 /* internal encoding of binary files */
|
||||
|
|
18
src/laws.c
18
src/laws.c
|
@ -1972,7 +1972,7 @@ int mail_cmd(unit * u, struct order *ord)
|
|||
case P_REGION:
|
||||
/* können alle Einheiten in der Region sehen */
|
||||
s = getstrtoken();
|
||||
if (!s[0]) {
|
||||
if (!s || !s[0]) {
|
||||
cmistake(u, ord, 30, MSG_MESSAGE);
|
||||
break;
|
||||
}
|
||||
|
@ -3850,7 +3850,7 @@ static int reserve_i(unit * u, struct order *ord, int flags)
|
|||
{
|
||||
if (u->number > 0 && (urace(u)->ec_flags & GETITEM)) {
|
||||
int use, count, para;
|
||||
const resource_type *rtype;
|
||||
const item_type *itype;
|
||||
const char *s;
|
||||
|
||||
init_order(ord);
|
||||
|
@ -3862,19 +3862,19 @@ static int reserve_i(unit * u, struct order *ord, int flags)
|
|||
count = getint() * u->number;
|
||||
}
|
||||
s = getstrtoken();
|
||||
rtype = s ? findresourcetype(s, u->faction->locale) : 0;
|
||||
if (rtype == NULL)
|
||||
itype = s ? finditemtype(s, u->faction->locale) : 0;
|
||||
if (itype == NULL)
|
||||
return 0;
|
||||
|
||||
set_resvalue(u, rtype, 0); /* make sure the pool is empty */
|
||||
set_resvalue(u, itype, 0); /* make sure the pool is empty */
|
||||
|
||||
if (count == 0 && para == P_ANY) {
|
||||
count = get_resource(u, rtype);
|
||||
count = get_resource(u, itype->rtype);
|
||||
}
|
||||
use = use_pooled(u, rtype, flags, count);
|
||||
use = use_pooled(u, itype->rtype, flags, count);
|
||||
if (use) {
|
||||
set_resvalue(u, rtype, use);
|
||||
change_resource(u, rtype, use);
|
||||
set_resvalue(u, itype, use);
|
||||
change_resource(u, itype->rtype, use);
|
||||
return use;
|
||||
}
|
||||
}
|
||||
|
|
19
src/skill.c
19
src/skill.c
|
@ -95,13 +95,18 @@ skill_t get_skill(const char *s, const struct locale * lang)
|
|||
|
||||
if (s) {
|
||||
char * str = transliterate(buffer, sizeof(buffer) - sizeof(int), s);
|
||||
int i;
|
||||
const void * match;
|
||||
void **tokens = get_translations(lang, UT_SKILLS);
|
||||
struct critbit_tree *cb = (critbit_tree *)*tokens;
|
||||
if (cb && cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) {
|
||||
cb_get_kv(match, &i, sizeof(int));
|
||||
result = (skill_t)i;
|
||||
if (str) {
|
||||
int i;
|
||||
const void * match;
|
||||
void **tokens = get_translations(lang, UT_SKILLS);
|
||||
struct critbit_tree *cb = (critbit_tree *)*tokens;
|
||||
if (cb && cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) {
|
||||
cb_get_kv(match, &i, sizeof(int));
|
||||
result = (skill_t)i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_warning("could not transliterate skill: %s", s);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -42,9 +42,13 @@ const char *escape_string(const char *str, char *buffer,
|
|||
char *o;
|
||||
size_t skip = start - str;
|
||||
|
||||
if (skip > len) {
|
||||
skip = len;
|
||||
}
|
||||
memcpy(buffer, str, skip);
|
||||
o = buffer + skip;
|
||||
p = str + skip;
|
||||
len -= skip;
|
||||
do {
|
||||
if (*p == '\"' || *p == '\\') {
|
||||
if (len < 2) {
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
static void test_escape_string(CuTest * tc)
|
||||
{
|
||||
char scratch[64];
|
||||
CuAssertStrEquals(tc, "12345678901234567890", escape_string("12345678901234567890", scratch, 16));
|
||||
CuAssertStrEquals(tc, "123456789\\\"12345", escape_string("123456789\"1234567890", scratch, 16));
|
||||
CuAssertStrEquals(tc, "1234567890123456", escape_string("1234567890123456\"890", scratch, 16));
|
||||
CuAssertStrEquals(tc, "hello world", escape_string("hello world", scratch, sizeof(scratch)));
|
||||
CuAssertStrEquals(tc, "hello \\\"world\\\"", escape_string("hello \"world\"", scratch, sizeof(scratch)));
|
||||
CuAssertStrEquals(tc, "\\\"\\\\", escape_string("\"\\", scratch, sizeof(scratch)));
|
||||
|
|
Loading…
Reference in New Issue