more bsdstring removal, str_replace, unit tests.

This commit is contained in:
Enno Rehling 2017-12-11 18:20:21 +01:00
parent 691dde5960
commit 9f391039b5
16 changed files with 121 additions and 59 deletions

View file

@ -7337,8 +7337,8 @@
</string>
<string name="a_road_percent">
<text locale="de">eine zu %d%% vollendete Straße</text>
<text locale="en">a road that is %d%% complete</text>
<text locale="de">eine zu $percent%% vollendete Straße</text>
<text locale="en">a road that is $percent% complete</text>
</string>
<string name="a_road_connection">

View file

@ -189,7 +189,7 @@ static char *sidename(side * s)
static char sidename_buf[4][SIDENAMEBUFLEN]; /* STATIC_RESULT: used for return, not across calls */
bufno = bufno % 4;
strlcpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN);
strncpy(sidename_buf[bufno], factionname(s->stealthfaction ? s->stealthfaction : s->faction), SIDENAMEBUFLEN);
return sidename_buf[bufno++];
}
@ -2886,10 +2886,10 @@ static void print_header(battle * b)
for (df = s->fighters; df; df = df->next) {
if (is_attacker(df)) {
if (first) {
bufp = STRLCPY(bufp, ", ", size);
strlcpy(bufp, ", ", size);
}
if (lastf) {
bufp = STRLCPY(bufp, lastf, size);
strlcpy(bufp, lastf, size);
first = true;
}
if (seematrix(f, s))
@ -3579,7 +3579,7 @@ static int battle_report(battle * b)
if (komma) {
bufp = STRLCPY(bufp, ", ", size);
}
slprintf(buffer, sizeof(buffer), "%s %2d(%s): ",
snprintf(buffer, sizeof(buffer), "%s %2d(%s): ",
loc_army, army_index(s), abbrev);
bufp = STRLCPY(bufp, buffer, size);

View file

@ -516,7 +516,7 @@ static void report_crtypes(FILE * F, const struct locale *lang)
assert(hash > 0);
fprintf(F, "MESSAGETYPE %u\n", hash);
fputc('\"', F);
fputs(escape_string(nrt_string(nrt), buffer, sizeof(buffer)), F);
fputs(str_escape(nrt_string(nrt), buffer, sizeof(buffer)), F);
fputs("\";text\n", F);
fprintf(F, "\"%s\";section\n", nrt_section(nrt));
}
@ -1067,7 +1067,7 @@ static void cr_reportspell(FILE * F, spell * sp, int level, const struct locale
const char *name =
translate(mkname("spell", sp->sname), spell_name(sp, lang));
fprintf(F, "ZAUBER %d\n", hashstring(sp->sname));
fprintf(F, "ZAUBER %d\n", str_hash(sp->sname));
fprintf(F, "\"%s\";name\n", name);
fprintf(F, "%d;level\n", level);
fprintf(F, "%d;rank\n", sp->rank);
@ -1115,7 +1115,7 @@ static char *cr_output_resource(char *buf, const resource_type *rtype,
assert(rtype);
name = resourcename(rtype, NMF_PLURAL);
assert(name);
buf += sprintf(buf, "RESOURCE %u\n", hashstring(rtype->_name));
buf += sprintf(buf, "RESOURCE %u\n", str_hash(rtype->_name));
tname = LOC(loc, name);
assert(tname);
tname = translate(name, tname);
@ -1663,7 +1663,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
if (ptype == NULL)
continue;
ch = resourcename(ptype->itype->rtype, 0);
fprintf(F, "TRANK %d\n", hashstring(ch));
fprintf(F, "TRANK %d\n", str_hash(ch));
fprintf(F, "\"%s\";Name\n", translate(ch, LOC(f->locale, ch)));
fprintf(F, "%d;Stufe\n", ptype->level);

View file

@ -50,7 +50,6 @@
#include <util/lists.h>
#include <util/rng.h>
#include <util/base36.h>
#include <util/bsdstring.h>
#include <storage.h>
#include <lua.h>
@ -58,6 +57,7 @@
#include <assert.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static int g_quit;
@ -1228,7 +1228,7 @@ static void handlekey(state * st, int c)
else if (findmode == 'F') {
faction *f = select_faction(st);
if (f != NULL) {
strlcpy(locate, itoa36(f->no), sizeof(locate));
itoab_r(f->no, 36, locate, sizeof(locate));
findmode = 'f';
}
else {
@ -1254,7 +1254,7 @@ static void handlekey(state * st, int c)
region *first = (mr && mr->r && mr->r->next) ? mr->r->next : regions;
if (findmode == 'f') {
slprintf(sbuffer, sizeof(sbuffer), "find-faction: %s", locate);
snprintf(sbuffer, sizeof(sbuffer), "find-faction: %s", locate);
statusline(st->wnd_status->handle, sbuffer);
f = findfaction(atoi36(locate));
if (f == NULL) {

View file

@ -28,7 +28,6 @@ without prior permission by the authors of Eressea.
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/bsdstring.h>
#include <util/language.h>
#include <util/parser.h>
#include <util/rng.h>
@ -40,6 +39,7 @@ without prior permission by the authors of Eressea.
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
alliance *alliances = NULL;
@ -422,7 +422,7 @@ const char *alliancename(const alliance * al)
char *ibuf = idbuf[(++nextbuf) % 8];
if (al && al->name) {
slprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", al->name, itoa36(al->id));
snprintf(ibuf, sizeof(idbuf[0]), "%s (%s)", al->name, itoa36(al->id));
}
else {
return NULL;

View file

@ -38,7 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/bsdstring.h>
#include <util/event.h>
#include <util/functions.h>
#include <util/gamedata.h>
@ -54,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* libc includes */
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
@ -372,7 +372,7 @@ building *new_building(const struct building_type * btype, region * r,
bname = parameters[P_GEBAEUDE];
}
assert(bname);
slprintf(buffer, sizeof(buffer), "%s %s", bname, itoa36(b->no));
snprintf(buffer, sizeof(buffer), "%s %s", bname, itoa36(b->no));
b->name = strdup(bname);
return b;
}
@ -489,7 +489,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize)
const char *write_buildingname(const building * b, char *ibuf, size_t size)
{
slprintf(ibuf, size, "%s (%s)", b->name, itoa36(b->no));
snprintf(ibuf, size, "%s (%s)", b->name, itoa36(b->no));
return ibuf;
}

View file

@ -25,19 +25,21 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "unit.h"
#include <util/attrib.h>
#include <util/bsdstring.h>
#include <util/base36.h>
#include <util/gamedata.h>
#include <util/language.h>
#include <util/log.h>
#include <selist.h>
#include <util/rng.h>
#include <util/strings.h>
#include <selist.h>
#include <storage.h>
/* libc includes */
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int nextborder = 0;
@ -514,8 +516,8 @@ static const char *b_nameroad(const connection * b, const region * r,
else {
int percent = MAX(1, 100 * local / r->terrain->max_road);
if (local) {
slprintf(buffer, sizeof(buffer), LOC(f->locale, mkname("border",
"a_road_percent")), percent);
const char *temp = LOC(f->locale, mkname("border", "a_road_percent"));
str_replace(buffer, sizeof(buffer), temp, "$percent", itoa10(percent));
}
else {
return LOC(f->locale, mkname("border", "a_road_connection"));

View file

@ -170,7 +170,7 @@ int stream_order(struct stream *out, const struct order *ord, const struct local
char obuf[1024];
swrite(" ", 1, 1, out);
if (escape) {
text = escape_string(text, obuf, sizeof(obuf));
text = str_escape(text, obuf, sizeof(obuf));
}
swrite(text, 1, strlen(text), out);
}

View file

@ -51,7 +51,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/bsdstring.h>
#include <util/event.h>
#include <util/gamedata.h>
#include <util/strings.h>
@ -1458,9 +1457,7 @@ void default_name(const unit *u, char name[], int len) {
else {
result = parameters[P_UNIT];
}
strlcpy(name, result, len);
strlcat(name, " ", len);
strlcat(name, itoa36(u->no), len);
snprintf(name, len, "%s %s", result, itoa36(u->no));
}
void name_unit(unit * u)
@ -1874,7 +1871,7 @@ static int nextbuf = 0;
char *write_unitname(const unit * u, char *buffer, size_t size)
{
const char * name = unit_getname(u);
slprintf(buffer, size, "%s (%s)", name, itoa36(u->no));
snprintf(buffer, size, "%s (%s)", name, itoa36(u->no));
buffer[size - 1] = 0;
return buffer;
}

View file

@ -52,16 +52,14 @@ int atoi36(const char *str)
return i * sign;
}
const char *itoab(int i, int base)
const char *itoab_r(int i, int base, char *s, size_t len)
{
static char sstr[80];
char *s, *dst;
char *dst;
static int index = 0; /* STATIC_XCALL: used across calls */
s = sstr + (index * 20);
index = (index + 1) & 3; /* quick for % 4 */
dst = s + 19;
(*dst--) = 0;
assert(len > 2);
dst = s + len - 2;
*dst = 0;
if (i != 0) {
int neg = 0;
@ -101,6 +99,18 @@ const char *itoab(int i, int base)
return dst;
}
const char *itoab(int i, int base)
{
static char sstr[80];
char *s;
static int index = 0; /* STATIC_XCALL: used across calls */
s = sstr + (index * 20);
index = (index + 1) & 3; /* quick for % 4 */
return itoab_r(i, base, s, 20);
}
const char *itoa36(int i)
{
return itoab(i, 36);

View file

@ -18,15 +18,19 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef H_UTIL_BASE36
#define H_UTIL_BASE36
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
const char *itoab_r(int i, int base, char *result, size_t len);
const char *itoab(int i, int base);
const char *itoa36(int i);
const char *itoa10(int i);
extern int atoi36(const char *s);
extern const char *itoab(int i, int base);
extern const char *itoa36(int i);
extern const char *itoa10(int i);
extern int i10toi36(int i);
int i10toi36(int i);
#ifdef __cplusplus
}

View file

@ -56,7 +56,7 @@ unsigned int locale_index(const locale * lang)
locale *get_locale(const char *name)
{
unsigned int hkey = hashstring(name);
unsigned int hkey = str_hash(name);
locale *l = locales;
while (l && l->hashkey != hkey)
l = l->next;
@ -68,7 +68,7 @@ static unsigned int nextlocaleindex = 0;
locale *get_or_create_locale(const char *name)
{
locale *l;
unsigned int hkey = hashstring(name);
unsigned int hkey = str_hash(name);
locale **lp = &locales;
if (!locales) {
@ -120,7 +120,7 @@ void make_locales(const char *str)
const char *locale_getstring(const locale * lang, const char *key)
{
unsigned int hkey = hashstring(key);
unsigned int hkey = str_hash(key);
unsigned int id = hkey & (SMAXHASH - 1);
const struct locale_str *find;
@ -150,7 +150,7 @@ const char *locale_string(const locale * lang, const char *key, bool warn)
assert(key);
if (key != NULL) {
unsigned int hkey = hashstring(key);
unsigned int hkey = str_hash(key);
unsigned int id = hkey & (SMAXHASH - 1);
struct locale_str *find;
@ -188,7 +188,7 @@ const char *locale_string(const locale * lang, const char *key, bool warn)
void locale_setstring(locale * lang, const char *key, const char *value)
{
unsigned int hkey = hashstring(key);
unsigned int hkey = str_hash(key);
unsigned int id = hkey & (SMAXHASH - 1);
struct locale_str *find;
if (!lang) {

View file

@ -192,7 +192,7 @@ void mt_clear(void) {
const message_type *mt_find(const char *name)
{
unsigned int hash = hashstring(name) % MT_MAXHASH;
unsigned int hash = str_hash(name) % MT_MAXHASH;
selist *ql = messagetypes[hash];
int qi;
@ -218,7 +218,7 @@ static unsigned int mt_id(const message_type * mtype)
const message_type *mt_register(message_type * type)
{
unsigned int hash = hashstring(type->name) % MT_MAXHASH;
unsigned int hash = str_hash(type->name) % MT_MAXHASH;
selist **qlp = messagetypes + hash;
if (selist_set_insert(qlp, type, NULL)) {

View file

@ -45,7 +45,40 @@ char *set_string(char **s, const char *neu)
return *s;
}
unsigned int hashstring(const char *s)
void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value)
{
size_t val_len = strlen(value);
size_t var_len = strlen(var);
char *s = buffer;
while (buffer + size > s) {
char *p = strstr(tmpl, var);
size_t len;
if (p) {
len = p - tmpl;
}
else {
len = strlen(tmpl);
}
if (len < size) {
memmove(s, tmpl, len);
tmpl += len;
s += len;
size -= len;
if (p && val_len < size) {
tmpl += var_len;
memmove(s, value, val_len);
s += val_len;
size -= val_len;
}
}
if (!p) {
break;
}
}
*s = 0;
}
unsigned int str_hash(const char *s)
{
unsigned int key = 0;
assert(s);
@ -55,7 +88,7 @@ unsigned int hashstring(const char *s)
return key & 0x7FFFFFFF;
}
const char *escape_string(const char *str, char *buffer,
const char *str_escape(const char *str, char *buffer,
size_t len)
{
const char *start = strchr(str, '\"');

View file

@ -25,9 +25,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
void str_replace(char *buffer, size_t size, const char *tmpl, const char *var, const char *value);
const char *str_escape(const char *str, char *buffer, size_t len);
char *set_string(char **s, const char *neu);
unsigned int hashstring(const char *s);
const char *escape_string(const char *str, char *buffer, size_t len);
unsigned int str_hash(const char *s);
unsigned int jenkins_hash(unsigned int a);
unsigned int wang_hash(unsigned int a);

View file

@ -4,21 +4,36 @@
#include <string.h>
#include "strings.h"
static void test_escape_string(CuTest * tc)
static void test_str_escape(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)));
CuAssertStrEquals(tc, "\\\\", escape_string("\\", scratch, sizeof(scratch)));
CuAssertStrEquals(tc, "12345678901234567890", str_escape("12345678901234567890", scratch, 16));
CuAssertStrEquals(tc, "123456789\\\"12345", str_escape("123456789\"1234567890", scratch, 16));
CuAssertStrEquals(tc, "1234567890123456", str_escape("1234567890123456\"890", scratch, 16));
CuAssertStrEquals(tc, "hello world", str_escape("hello world", scratch, sizeof(scratch)));
CuAssertStrEquals(tc, "hello \\\"world\\\"", str_escape("hello \"world\"", scratch, sizeof(scratch)));
CuAssertStrEquals(tc, "\\\"\\\\", str_escape("\"\\", scratch, sizeof(scratch)));
CuAssertStrEquals(tc, "\\\\", str_escape("\\", scratch, sizeof(scratch)));
}
static void test_str_replace(CuTest * tc)
{
char result[64];
str_replace(result, sizeof(result), "Hello $who!", "$who", "World");
CuAssertStrEquals(tc, "Hello World!", result);
}
static void test_str_hash(CuTest * tc)
{
CuAssertIntEquals(tc, 0, str_hash(""));
CuAssertIntEquals(tc, 140703196, str_hash("Hodor"));
}
CuSuite *get_strings_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_escape_string);
SUITE_ADD_TEST(suite, test_str_hash);
SUITE_ADD_TEST(suite, test_str_escape);
SUITE_ADD_TEST(suite, test_str_replace);
return suite;
}