forked from github/server
Merge branch 'master' into develop
This commit is contained in:
commit
0bc1eb5a2b
11 changed files with 140 additions and 7 deletions
2
clibs
2
clibs
|
@ -1 +1 @@
|
||||||
Subproject commit 12139c7ce25e6731393f863e248ab16aa0578a3a
|
Subproject commit ed5c4fee3afbc3d8be79d64857f30702aed522f8
|
|
@ -723,7 +723,7 @@ int change_money(unit * u, int v)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_resourcename_cb(const void * match, const void * key,
|
static int add_resourcename_cb(void * match, const void * key,
|
||||||
size_t keylen, void *data)
|
size_t keylen, void *data)
|
||||||
{
|
{
|
||||||
struct locale * lang = (struct locale *)data;
|
struct locale * lang = (struct locale *)data;
|
||||||
|
@ -773,7 +773,7 @@ attrib_type at_showitem = {
|
||||||
"showitem"
|
"showitem"
|
||||||
};
|
};
|
||||||
|
|
||||||
static int add_itemname_cb(const void * match, const void * key,
|
static int add_itemname_cb(void * match, const void * key,
|
||||||
size_t keylen, void *data)
|
size_t keylen, void *data)
|
||||||
{
|
{
|
||||||
struct locale * lang = (struct locale *)data;
|
struct locale * lang = (struct locale *)data;
|
||||||
|
@ -919,7 +919,7 @@ void free_rtype(resource_type *rtype) {
|
||||||
free(rtype);
|
free(rtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int free_rtype_cb(const void * match, const void * key,
|
static int free_rtype_cb(void * match, const void * key,
|
||||||
size_t keylen, void *cbdata)
|
size_t keylen, void *cbdata)
|
||||||
{
|
{
|
||||||
resource_type *rtype = ((rt_entry *)match)->value;;
|
resource_type *rtype = ((rt_entry *)match)->value;;
|
||||||
|
|
|
@ -2950,7 +2950,7 @@ void free_spellbook(spellbook *sb) {
|
||||||
free(sb);
|
free(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int free_spellbook_cb(const void *match, const void *key, size_t keylen, void *data) {
|
static int free_spellbook_cb(void *match, const void *key, size_t keylen, void *data) {
|
||||||
const sb_entry *ent = (const sb_entry *)match;
|
const sb_entry *ent = (const sb_entry *)match;
|
||||||
UNUSED_ARG(data);
|
UNUSED_ARG(data);
|
||||||
UNUSED_ARG(keylen);
|
UNUSED_ARG(keylen);
|
||||||
|
|
|
@ -335,6 +335,8 @@ int main(int argc, char **argv)
|
||||||
game_done();
|
game_done();
|
||||||
lua_done(L);
|
lua_done(L);
|
||||||
log_close();
|
log_close();
|
||||||
|
stats_write(stdout, "");
|
||||||
|
stats_close();
|
||||||
if (d) {
|
if (d) {
|
||||||
iniparser_freedict(d);
|
iniparser_freedict(d);
|
||||||
}
|
}
|
||||||
|
|
|
@ -608,6 +608,7 @@ static void recruit_dracoids(unit * dragon, int size)
|
||||||
region *r = dragon->region;
|
region *r = dragon->region;
|
||||||
const struct item *weapon = NULL;
|
const struct item *weapon = NULL;
|
||||||
unit *un = create_unit(r, f, size, get_race(RC_DRACOID), 0, NULL, NULL);
|
unit *un = create_unit(r, f, size, get_race(RC_DRACOID), 0, NULL, NULL);
|
||||||
|
stats_count("monsters.create.dracoid", 1);
|
||||||
|
|
||||||
fset(un, UFL_ISNEW | UFL_MOVED);
|
fset(un, UFL_ISNEW | UFL_MOVED);
|
||||||
|
|
||||||
|
@ -868,6 +869,7 @@ static int nrand(int handle_start, int sub)
|
||||||
|
|
||||||
unit *spawn_seaserpent(region *r, faction *f) {
|
unit *spawn_seaserpent(region *r, faction *f) {
|
||||||
unit *u = create_unit(r, f, 1, get_race(RC_SEASERPENT), 0, NULL, NULL);
|
unit *u = create_unit(r, f, 1, get_race(RC_SEASERPENT), 0, NULL, NULL);
|
||||||
|
stats_count("monsters.create.seaserpent", 1);
|
||||||
fset(u, UFL_ISNEW | UFL_MOVED);
|
fset(u, UFL_ISNEW | UFL_MOVED);
|
||||||
equip_unit(u, "seed_seaserpent");
|
equip_unit(u, "seed_seaserpent");
|
||||||
return u;
|
return u;
|
||||||
|
@ -908,6 +910,7 @@ void spawn_dragons(void)
|
||||||
else {
|
else {
|
||||||
u = create_unit(r, monsters, nrand(30, 20) + 1, get_race(RC_DRAGON), 0, NULL, NULL);
|
u = create_unit(r, monsters, nrand(30, 20) + 1, get_race(RC_DRAGON), 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
stats_count("monsters.create.dragon", 1);
|
||||||
fset(u, UFL_ISNEW | UFL_MOVED);
|
fset(u, UFL_ISNEW | UFL_MOVED);
|
||||||
equip_unit(u, "seed_dragon");
|
equip_unit(u, "seed_dragon");
|
||||||
|
|
||||||
|
@ -940,7 +943,7 @@ void spawn_undead(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->land && unburied > rpeasants(r) / 20
|
if (r->land && unburied > rpeasants(r) / 20
|
||||||
&& rng_int() % 10000 < 200) {
|
&& rng_int() % 10000 < 100) {
|
||||||
message *msg;
|
message *msg;
|
||||||
unit *u;
|
unit *u;
|
||||||
/* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen.
|
/* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen.
|
||||||
|
@ -968,6 +971,7 @@ void spawn_undead(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
u = create_unit(r, monsters, undead, rc, 0, NULL, NULL);
|
u = create_unit(r, monsters, undead, rc, 0, NULL, NULL);
|
||||||
|
stats_count("monsters.create.undead", 1);
|
||||||
fset(u, UFL_ISNEW | UFL_MOVED);
|
fset(u, UFL_ISNEW | UFL_MOVED);
|
||||||
if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE))
|
if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE))
|
||||||
&& rng_int() % 10 < 4) {
|
&& rng_int() % 10 < 4) {
|
||||||
|
|
|
@ -182,6 +182,7 @@ void spawn_braineaters(float chance)
|
||||||
u = create_unit(r, f, 1 + rng_int() % 10 + rng_int() % 10,
|
u = create_unit(r, f, 1 + rng_int() % 10 + rng_int() % 10,
|
||||||
rc_brain, 0, NULL, NULL);
|
rc_brain, 0, NULL, NULL);
|
||||||
equip_unit(u, "seed_braineater");
|
equip_unit(u, "seed_braineater");
|
||||||
|
stats_count("monsters.create.braineater", 1);
|
||||||
|
|
||||||
next = rng_int() % (int)(chance * 100);
|
next = rng_int() % (int)(chance * 100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,8 @@ int RunAllTests(int argc, char *argv[])
|
||||||
fail_count = summary->failCount;
|
fail_count = summary->failCount;
|
||||||
CuSuiteDelete(summary);
|
CuSuiteDelete(summary);
|
||||||
game_done();
|
game_done();
|
||||||
|
log_close();
|
||||||
|
stats_close();
|
||||||
return fail_count;
|
return fail_count;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -234,6 +234,8 @@ static void test_reset(void) {
|
||||||
default_locale = 0;
|
default_locale = 0;
|
||||||
calendar_cleanup();
|
calendar_cleanup();
|
||||||
close_orders();
|
close_orders();
|
||||||
|
log_close();
|
||||||
|
stats_close();
|
||||||
free_special_directions();
|
free_special_directions();
|
||||||
free_locales();
|
free_locales();
|
||||||
free_spells();
|
free_spells();
|
||||||
|
|
|
@ -16,6 +16,8 @@ without prior permission by the authors of Eressea.
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
|
#include <critbit.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -318,3 +320,77 @@ int log_level(log_t * log, int flags)
|
||||||
log->flags = flags;
|
log->flags = flags;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static critbit_tree stats = CRITBIT_TREE();
|
||||||
|
|
||||||
|
int stats_count(const char *stat, int delta) {
|
||||||
|
size_t len;
|
||||||
|
char data[128];
|
||||||
|
void * match;
|
||||||
|
if (cb_find_prefix_str(&stats, stat, &match, 1, 0) == 0) {
|
||||||
|
len = cb_new_kv(stat, strlen(stat), &delta, sizeof(delta), data);
|
||||||
|
cb_insert(&stats, data, len);
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int *num;
|
||||||
|
cb_get_kv_ex(match, (void **)&num);
|
||||||
|
return *num += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define STATS_BATCH 8
|
||||||
|
void stats_walk(const char *prefix, void(*callback)(const char *, int, void *), void *udata) {
|
||||||
|
void *match[STATS_BATCH];
|
||||||
|
int n, off = 0;
|
||||||
|
do {
|
||||||
|
int i;
|
||||||
|
n = cb_find_prefix_str(&stats, prefix, match, STATS_BATCH, off);
|
||||||
|
if (n == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
off += n;
|
||||||
|
for (i = 0; i != n; ++i) {
|
||||||
|
const void *kv = match[i];
|
||||||
|
int *num;
|
||||||
|
cb_get_kv_ex(kv, &(void *)num);
|
||||||
|
callback(kv, *num, udata);
|
||||||
|
}
|
||||||
|
} while (n == STATS_BATCH);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct walk_data {
|
||||||
|
int (*callback)(const char *, int, void *);
|
||||||
|
void *udata;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int walk_cb(void * match, const void * key, size_t keylen, void *udata) {
|
||||||
|
struct walk_data *data = (struct walk_data *)udata;
|
||||||
|
int *num;
|
||||||
|
cb_get_kv_ex(match, (void **)&num);
|
||||||
|
return data->callback((const char*)match, *num, data->udata);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stats_walk(const char *prefix, int (*callback)(const char *, int, void *), void *udata) {
|
||||||
|
struct walk_data data;
|
||||||
|
data.callback = callback;
|
||||||
|
data.udata = udata;
|
||||||
|
return cb_foreach(&stats, prefix, strlen(prefix), walk_cb, &data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int write_cb(const char *key, int val, void *udata) {
|
||||||
|
FILE * F = (FILE *)udata;
|
||||||
|
fprintf(F, "%s: %d\n", (const char *)key, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats_write(FILE *F, const char *prefix) {
|
||||||
|
stats_walk(prefix, write_cb, F);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stats_close(void) {
|
||||||
|
cb_clear(&stats);
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,12 @@ extern "C" {
|
||||||
void log_printf(FILE * ios, const char *format, ...);
|
void log_printf(FILE * ios, const char *format, ...);
|
||||||
|
|
||||||
void errno_check(const char *file, int line);
|
void errno_check(const char *file, int line);
|
||||||
|
|
||||||
|
int stats_count(const char *stat, int delta);
|
||||||
|
void stats_write(FILE *F, const char *prefix);
|
||||||
|
int stats_walk(const char *prefix, int (*callback)(const char *key, int val, void * udata), void *udata);
|
||||||
|
void stats_close(void);
|
||||||
|
|
||||||
#define ERRNO_CHECK() errno_check(__FILE__, __LINE__)
|
#define ERRNO_CHECK() errno_check(__FILE__, __LINE__)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#endif
|
#endif
|
||||||
#include <CuTest.h>
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
#include <tests.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -32,9 +34,47 @@ static void test_logging(CuTest * tc)
|
||||||
CuAssertStrEquals(tc, "World", str2);
|
CuAssertStrEquals(tc, "World", str2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stats_cb(const char *stat, int num, void *udata) {
|
||||||
|
int *counter = (int *)udata;
|
||||||
|
if (counter) {
|
||||||
|
*counter += num;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_stats(CuTest * tc)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
test_setup();
|
||||||
|
CuAssertIntEquals(tc, 1, stats_count("foobar", 1));
|
||||||
|
CuAssertIntEquals(tc, 2, stats_count("test.one", 2));
|
||||||
|
CuAssertIntEquals(tc, 1, stats_count("test.two", 1));
|
||||||
|
CuAssertIntEquals(tc, 4, stats_count("test.one", 2));
|
||||||
|
CuAssertIntEquals(tc, 1, stats_count("test.two", 0));
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
CuAssertIntEquals(tc, 0, stats_walk("", stats_cb, &n));
|
||||||
|
CuAssertIntEquals(tc, 6, n);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
CuAssertIntEquals(tc, 0, stats_walk("test", stats_cb, &n));
|
||||||
|
CuAssertIntEquals(tc, 5, n);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
CuAssertIntEquals(tc, 0, stats_walk("test.one", stats_cb, &n));
|
||||||
|
CuAssertIntEquals(tc, 4, n);
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
CuAssertIntEquals(tc, 0, stats_walk("foobar", stats_cb, &n));
|
||||||
|
CuAssertIntEquals(tc, 1, n);
|
||||||
|
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_log_suite(void)
|
CuSuite *get_log_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_logging);
|
SUITE_ADD_TEST(suite, test_logging);
|
||||||
|
SUITE_ADD_TEST(suite, test_stats);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue