Merge pull request #835 from ennorehling/develop

ongoing changes
This commit is contained in:
Enno Rehling 2019-02-03 04:23:31 +01:00 committed by GitHub
commit 1ea064d1f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 169 additions and 132 deletions

View File

@ -1182,3 +1182,21 @@ function test_cartmaking()
assert_equal(1, u:get_item('cart'))
assert_equal(5, u:get_item('log'))
end
function test_promote_after_recruit()
local f = faction.create('human')
local r1 = region.create(0, 0, 'plain')
local r2 = region.create(1, 0, 'plain')
local u1 = unit.create(f, r1, 1)
u1.name = 'Xolgrim'
local u2 = unit.create(f, r2, 55)
u2:add_order('REKRUTIERE 1')
u1:add_order('BEFOERDERE')
u1:add_item('money', 57)
u2:add_item('money', 150)
local fl = u1.flags
process_orders()
assert_equal(56, u2.number)
assert_equal(fl + 128, u1.flags) -- UFL_HERO
assert_equal(0, u1:get_item('money'))
end

View File

@ -27,7 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "study.h"
void academy_teaching_bonus(struct unit *u, skill_t sk, int students) {
if (students && sk != NOSKILL) {
if (students > 0 && sk != NOSKILL) {
/* actually students * EXPERIENCEDAYS / MAX_STUDENTS */
learn_skill(u, sk, students);
}

View File

@ -16,7 +16,10 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include <kernel/config.h>
#include "battle.h"
#include "alchemy.h"
@ -436,7 +439,8 @@ static int get_row(const side * s, int row, const side * vs)
/* every entry in the size[] array means someone trying to defend us.
* 'retreat' is the number of rows falling.
*/
result = MAX(FIRST_ROW, row - retreat);
result = row - retreat;
if (result < FIRST_ROW) result = FIRST_ROW;
return result;
}
@ -587,50 +591,27 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking)
* are taken into account, e.g. no horses, magic, etc. */
{
int skill;
const race * rc = u_race(u);
if (wtype == NULL) {
skill = effskill(u, SK_WEAPONLESS, NULL);
int def = attacking ? rc->at_default : rc->df_default;
if (skill <= 0) {
/* wenn kein waffenloser kampf, dann den rassen-defaultwert */
if (u_race(u) == get_race(RC_ORC)) {
if (rc == get_race(RC_ORC)) {
int sword = effskill(u, SK_MELEE, NULL);
int spear = effskill(u, SK_SPEAR, NULL);
skill = MAX(sword, spear) - 3;
if (attacking) {
skill = MAX(skill, u_race(u)->at_default);
}
else {
skill = MAX(skill, u_race(u)->df_default);
}
}
else {
if (attacking) {
skill = u_race(u)->at_default;
}
else {
skill = u_race(u)->df_default;
}
}
}
else {
/* der rassen-defaultwert kann h<>her sein als der Talentwert von
* waffenloser kampf */
if (attacking) {
if (skill < u_race(u)->at_default)
skill = u_race(u)->at_default;
}
else {
if (skill < u_race(u)->df_default)
skill = u_race(u)->df_default;
skill = ((sword > spear) ? sword : spear) - 3;
}
}
if (def > skill) skill = def;
if (attacking) {
skill += u_race(u)->at_bonus;
skill += rc->at_bonus;
if (fval(u->region->terrain, SEA_REGION) && u->ship)
skill += u->ship->type->at_bonus;
}
else {
skill += u_race(u)->df_bonus;
skill += rc->df_bonus;
if (fval(u->region->terrain, SEA_REGION) && u->ship)
skill += u->ship->type->df_bonus;
}
@ -642,10 +623,10 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking)
skill = effskill(u, wtype->skill, NULL);
if (skill > 0) {
if (attacking) {
skill += u_race(u)->at_bonus;
skill += rc->at_bonus;
}
else {
skill += u_race(u)->df_bonus;
skill += rc->df_bonus;
}
}
if (attacking) {
@ -1261,32 +1242,33 @@ static int apply_race_resistance(int reduced_damage, fighter *df,
static int apply_magicshield(int reduced_damage, fighter *df,
const weapon_type *awtype, battle *b, bool magic) {
side *ds = df->side;
selist *ql;
int qi;
side *ds = df->side;
selist *ql;
int qi;
if (reduced_damage <= 0)
return 0;
if (reduced_damage <= 0)
return 0;
/* Schilde */
for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
meffect *me = (meffect *) selist_get(ql, qi);
if (meffect_protection(b, me, ds) != 0) {
assert(0 <= reduced_damage); /* rda sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE) {
int hp = reduced_damage * (me->effect / 100);
reduced_damage -= hp;
me->duration -= hp;
}
/* gibt R<>stung +effect f<>r duration Treffer */
if (me->typ == SHIELD_ARMOR) {
reduced_damage = MAX(reduced_damage - me->effect, 0);
me->duration--;
}
/* Schilde */
for (qi = 0, ql = b->meffects; ql; selist_advance(&ql, &qi, 1)) {
meffect *me = (meffect *)selist_get(ql, qi);
if (meffect_protection(b, me, ds) != 0) {
assert(0 <= reduced_damage); /* rda sollte hier immer mindestens 0 sein */
/* jeder Schaden wird um effect% reduziert bis der Schild duration
* Trefferpunkte aufgefangen hat */
if (me->typ == SHIELD_REDUCE) {
int hp = reduced_damage * (me->effect / 100);
reduced_damage -= hp;
me->duration -= hp;
}
/* gibt R<>stung +effect f<>r duration Treffer */
if (me->typ == SHIELD_ARMOR) {
reduced_damage -= me->effect;
if (reduced_damage < 0) reduced_damage = 0;
me->duration--;
}
}
}
}
return reduced_damage;
}
@ -1347,11 +1329,13 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile
/* Skilldifferenzbonus */
if (rule_damage & DAMAGE_SKILL_BONUS) {
damage += MAX(0, (attskill - defskill) / DAMAGE_QUOTIENT);
int b = (attskill - defskill) / DAMAGE_QUOTIENT;
if (b > 0) damage += b;
}
}
reduced_damage = MAX(damage - armor_value, 0);
reduced_damage = damage - armor_value;
if (reduced_damage < 0) reduced_damage = 0;
reduced_damage = apply_race_resistance(reduced_damage, df, awtype, magic);
reduced_damage = apply_magicshield(reduced_damage, df, awtype, b, magic);
@ -1500,7 +1484,8 @@ troop select_enemy(fighter * af, int minrow, int maxrow, int select)
minrow = FIGHT_ROW;
maxrow = BEHIND_ROW;
}
minrow = MAX(minrow, FIGHT_ROW);
if (minrow < FIGHT_ROW) minrow = FIGHT_ROW;
enemies = count_enemies(b, af, minrow, maxrow, select);
@ -1611,7 +1596,7 @@ static troop select_opponent(battle * b, troop at, int mindist, int maxdist)
dt = select_enemy(at.fighter, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
}
else {
mindist = MAX(mindist, FIGHT_ROW);
if (mindist < FIGHT_ROW) mindist = FIGHT_ROW;
dt = select_enemy(at.fighter, mindist, maxdist, SELECT_ADVANCE);
}
@ -2078,7 +2063,8 @@ void dazzle(battle * b, troop * td)
void damage_building(battle * b, building * bldg, int damage_abs)
{
assert(bldg);
bldg->size = MAX(1, bldg->size - damage_abs);
bldg->size -= damage_abs;
if (bldg->size < 1) bldg->size = 1;
/* Wenn Burg, dann gucken, ob die Leute alle noch in das Geb<65>ude passen. */
@ -3020,7 +3006,9 @@ static void print_stats(battle * b)
for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (!selist_empty(s->leader.fighters)) {
b->max_tactics = MAX(b->max_tactics, s->leader.value);
if (s->leader.value > b->max_tactics) {
b->max_tactics = s->leader.value;
}
}
}
@ -3371,7 +3359,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
else
p_bonus += 3;
} while (rnd >= 97);
bonus = MAX(p_bonus, bonus);
if (p_bonus > bonus) p_bonus = bonus;
}
tactics += bonus;
}

View File

@ -16,7 +16,10 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#ifdef _MSC_VER
# include <platform.h>
#endif
#include "weapons.h"
#include "battle.h"
@ -106,7 +109,7 @@ int *casualties)
}
enemies = count_enemies(b, af, FIGHT_ROW, FIGHT_ROW, SELECT_ADVANCE);
enemies = MIN(enemies, CATAPULT_ATTACKS);
if (enemies > CATAPULT_ATTACKS) enemies = CATAPULT_ATTACKS;
if (enemies == 0) {
return true; /* allow further attacks */
}

View File

@ -75,8 +75,9 @@ use_manacrystal(struct unit *u, const struct item_type *itype, int amount,
}
msp = max_spellpoints_depr(u->region, u) / 2;
if (msp < 25) msp = 25;
for (i = 0; i != amount; ++i) {
sp += MAX(25, msp);
sp += msp;
change_spellpoints(u, sp);
}

View File

@ -60,7 +60,7 @@ group *new_group(faction * f, const char *name, int gid)
gp = &(*gp)->next;
*gp = g;
maxgid = MAX(gid, maxgid);
if (gid > maxgid) maxgid = gid;
g->name = str_strdup(name);
g->gid = gid;

View File

@ -10,7 +10,10 @@
without prior permission by the authors of Eressea.
*/
#ifdef _MSC_VER
#include <platform.h>
#endif
#include <kernel/config.h>
#include "order.h"
@ -398,6 +401,7 @@ order *parse_order(const char *s, const struct locale * lang)
}
if (kwd != NOKEYWORD) {
order *ord = (order *)malloc(sizeof(order));
if (ord == NULL) abort();
create_order_i(ord, kwd, sptr, persistent, noerror, lang);
return ord;
}

View File

@ -156,7 +156,7 @@ int set_resvalue(unit * u, const item_type * itype, int value)
}
int
get_pooled(const unit * u, const resource_type * rtype, unsigned int mode,
get_pooled(const unit * u, const resource_type * rtype, int mode,
int count)
{
const faction *f = u->faction;
@ -199,7 +199,7 @@ int count)
}
int
use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
use_pooled(unit * u, const resource_type * rtype, int mode, int count)
{
const faction *f = u->faction;
unit *v;

View File

@ -42,9 +42,9 @@ extern "C" {
#define GET_ALL (GET_SLACK|GET_RESERVE|GET_POOLED_SLACK|GET_POOLED_RESERVE|GET_POOLED_FORCE)
int get_pooled(const struct unit *u, const struct resource_type *res,
unsigned int mode, int count);
int mode, int count);
int use_pooled(struct unit *u, const struct resource_type *res,
unsigned int mode, int count);
int mode, int count);
/** use_pooled
* verbraucht 'count' Objekte der resource 'itm'
* unter zuhilfenahme des Pools der struct region und Aufbrauch des

View File

@ -16,7 +16,10 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#ifdef _MSC_VER
# include <platform.h>
#endif
#include "region.h"
/* kernel includes */
@ -141,8 +144,11 @@ const char *regionname(const region * r, const faction * f)
int region_maxworkers(const region *r)
{
int size = max_production(r);
int treespace = (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
return MAX(size - treespace, MIN(size / 10, 200));
int treespace = size - (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
size /=10;
if (size > 200) size = 200;
if (treespace < size) treespace = size;
return treespace;
}
int deathcount(const region * r)
@ -400,7 +406,7 @@ koor_distance_wrap_xy(int x1, int y1, int x2, int y2, int width, int height)
int dx = x1 - x2;
int dy = y1 - y2;
int result, dist;
int mindist = MIN(width, height) >> 1;
int mindist = ((width > height) ? height : width) / 2;
/* Bei negativem dy am Ursprung spiegeln, das veraendert
* den Abstand nicht
@ -423,13 +429,15 @@ koor_distance_wrap_xy(int x1, int y1, int x2, int y2, int width, int height)
if (result <= mindist)
return result;
}
dist = MAX(dx, height - dy);
dist = height - dy;
if (dist < dx) dist = dx;
if (dist >= 0 && dist < result) {
result = dist;
if (result <= mindist)
return result;
}
dist = MAX(width - dx, dy);
dist = width - dx;
if (dist < dy) dist = dy;
if (dist >= 0 && dist < result)
result = dist;
return result;
@ -1097,7 +1105,8 @@ void init_region(region *r)
if (!fval(r, RF_CHAOTIC)) {
int peasants;
peasants = (region_maxworkers(r) * (20 + dice(6, 10))) / 100;
rsetpeasants(r, MAX(100, peasants));
if (peasants < 100) peasants = 100;
rsetpeasants(r, peasants);
rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL,
INT_MAX) + 1) + rng_int() % 5));
}
@ -1419,7 +1428,8 @@ faction *update_owners(region * r)
else if (f || new_owner->faction != region_get_last_owner(r)) {
alliance *al = region_get_alliance(r);
if (al && new_owner->faction->alliance == al) {
int morale = MAX(0, region_get_morale(r) - MORALE_TRANSFER);
int morale = region_get_morale(r) - MORALE_TRANSFER;
if (morale < 0) morale = 0;
region_set_morale(r, morale, turn);
}
else {

View File

@ -448,7 +448,7 @@ unit *read_unit(gamedata *data)
set_number(u, number);
READ_INT(data->store, &n);
u->age = (short)n;
u->age = n;
READ_TOK(data->store, rname, sizeof(rname));
rc = rc_find(rname);
@ -775,7 +775,8 @@ static region *readregion(gamedata *data, int x, int y)
}
if (data->version >= REGIONOWNER_VERSION) {
READ_INT(data->store, &n);
region_set_morale(r, MAX(0, (short)n), -1);
if (n < 0) n = 0;
region_set_morale(r, n, -1);
read_owner(data, &r->land->ownership);
}
}

View File

@ -278,13 +278,11 @@ static void test_readwrite_dead_faction_group(CuTest *tc) {
CuAssertPtrEquals(tc, f2, factions);
write_game(&data);
free_gamedata();
f = f2 = NULL;
data.strm.api->rewind(data.strm.handle);
read_game(&data);
CuAssertPtrEquals(tc, NULL, findfaction(fno));
f2 = factions;
CuAssertPtrNotNull(tc, f2);
u = f2->units;
CuAssertPtrNotNull(tc, factions);
u = factions->units;
CuAssertPtrNotNull(tc, u);
g = get_group(u);
CuAssertPtrNotNull(tc, g);
@ -313,13 +311,11 @@ static void test_readwrite_dead_faction_regionowner(CuTest *tc) {
remove_empty_units();
write_game(&data);
free_gamedata();
f = NULL;
data.strm.api->rewind(data.strm.handle);
read_game(&data);
mstream_done(&data.strm);
gamedata_done(&data);
f = factions;
CuAssertPtrEquals(tc, NULL, f);
CuAssertPtrEquals(tc, NULL, factions);
r = regions;
CuAssertPtrNotNull(tc, r);
CuAssertPtrEquals(tc, NULL, region_get_owner(r));

View File

@ -16,7 +16,9 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#ifdef _MSC_VER
# include <platform.h>
#endif
#include <kernel/config.h>
#include "ship.h"
@ -359,8 +361,9 @@ int shipspeed(const ship * sh, const unit * u)
int crew = crew_skill(sh);
int crew_bonus = (crew / sh->type->sumskill / 2) - 1;
if (crew_bonus > 0) {
bonus = MIN(bonus, crew_bonus);
bonus = MIN(bonus, sh->type->range_max - sh->type->range);
int sbonus = sh->type->range_max - sh->type->range;
if (bonus > sbonus) bonus = sbonus;
if (bonus > crew_bonus) bonus = crew_bonus;
}
else {
bonus = 0;

View File

@ -16,7 +16,9 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#ifdef _MSC_VER
# include <platform.h>
#endif
#include <kernel/config.h>
#include "unit.h"
@ -1229,7 +1231,7 @@ int invisible(const unit * target, const unit * viewer)
else {
int hidden = item_invis(target);
if (hidden) {
hidden = MIN(hidden, target->number);
if (hidden > target->number) hidden = target->number;
if (viewer) {
const resource_type *rtype = get_resourcetype(R_AMULET_OF_TRUE_SEEING);
hidden -= i_get(viewer->items, rtype->itype);

View File

@ -3840,6 +3840,10 @@ void init_processor(void)
add_proc_region(p, do_force_leave, "kick non-allies out of buildings/ships");
}
add_proc_region(p, economics, "Zerstoeren, Geben, Rekrutieren, Vergessen");
/* all recruitment must be finished before we can calculate
* promotion cost of ability */
p += 10;
add_proc_order(p, K_PROMOTION, promotion_cmd, 0, "Heldenbefoerderung");
p += 10;

View File

@ -268,10 +268,10 @@ static int parse_args(int argc, char **argv)
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
#include <signal.h>
static void *btrace[50];
static void report_segfault(int signo, siginfo_t * sinf, void *arg)
{
void *btrace[50];
size_t size;
int fd = fileno(stderr);

View File

@ -76,7 +76,8 @@ void morale_update(region *r) {
void morale_change(region *r, int value) {
int morale = region_get_morale(r);
if (morale > 0) {
morale = MAX(0, morale - value);
morale = morale - value;
if (morale < 0) morale = 0;
region_set_morale(r, morale, turn);
}
}

View File

@ -14,6 +14,3 @@
#pragma warning(disable: 4224) // formal parameter was previously defined as a type
#pragma warning(disable: 4214) // bit field types other than int
#endif
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

View File

@ -22,7 +22,10 @@
/* util includes */
#include <util/rng.h>
#define age_chance(a,b,p) (MAX(0,a-b)*p)
static int age_chance(int a, int b, int p) {
int r = (a - b) * p;
return (r < 0) ? 0 : r;
}
#define DRAGONAGE 27
#define WYRMAGE 68

View File

@ -31,7 +31,10 @@
#define UNDEAD_BREAKUP 25 /* chance dafuer */
#define UNDEAD_BREAKUP_FRACTION (25+rng_int()%70) /* anteil der weg geht */
#define age_chance(a,b,p) (MAX(0,a-b)*p)
static int age_chance(int a, int b, int p) {
int r = (a - b) * p;
return (r < 0) ? 0 : r;
}
void make_undead_unit(unit * u)
{
@ -43,8 +46,9 @@ void make_undead_unit(unit * u)
void age_skeleton(unit * u)
{
if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) {
int n = MAX(1, u->number / 2);
int n = u->number / 2;
double q = (double)u->hp / (double)(unit_max_hp(u) * u->number);
if (n < 1) n = 1;
u_setrace(u, get_race(RC_SKELETON_LORD));
u->irace = NULL;
scale_number(u, n);
@ -55,8 +59,9 @@ void age_skeleton(unit * u)
void age_zombie(unit * u)
{
if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) {
int n = MAX(1, u->number / 2);
int n = u->number / 2;
double q = (double)u->hp / (double)(unit_max_hp(u) * u->number);
if (n < 1) n = 1;
u_setrace(u, get_race(RC_ZOMBIE_LORD));
u->irace = NULL;
scale_number(u, n);
@ -67,11 +72,11 @@ void age_zombie(unit * u)
void age_ghoul(unit * u)
{
if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) {
int n = MAX(1, u->number / 2);
int n = u->number / 2;
double q = (double)u->hp / (double)(unit_max_hp(u) * u->number);
u_setrace(u, get_race(RC_GHOUL_LORD));
u->irace = NULL;
scale_number(u, n);
scale_number(u, (n > 0) ? n : 1);
u->hp = (int)(unit_max_hp(u) * u->number * q);
}
}

View File

@ -4089,7 +4089,7 @@ static int sp_pump(castorder * co)
* Betoert eine Einheit, so das sie ihm den groe<EFBFBD>ten Teil ihres Bargelds
* und 50% ihres Besitzes schenkt. Sie behaelt jedoch immer soviel, wie
* sie zum ueberleben braucht. Wirkt gegen Magieresistenz.
* MIN(Stufe*1000$, u->money - maintenance)
* min(Stufe*1000$, u->money - maintenance)
* Von jedem Item wird 50% abgerundet ermittelt und uebergeben. Dazu
* kommt Itemzahl%2 mit 50% chance
*

View File

@ -16,7 +16,10 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#ifdef _MSC_VER
# include <platform.h>
#endif
#include "shock.h"
#include <magic.h>
@ -61,8 +64,8 @@ static void do_shock(unit * u, const char *reason)
if (u->number > 0) {
/* HP - Verlust */
int hp = (unit_max_hp(u) * u->number) / 10;
hp = MIN(u->hp, hp);
u->hp = MAX(1, hp);
if (hp > u->hp) hp = u->hp;
u->hp = (hp > 1) ? hp : 1;
}
/* Aura - Verlust */

View File

@ -306,8 +306,8 @@ char *str_unescape(char *str) {
char *read = str, *write = str;
while (*read) {
char * pos = strchr(read, '\\');
if (pos) {
size_t len = pos - read;
if (pos >= read) {
size_t len = (size_t)(pos - read);
memmove(write, read, len);
write += len;
read += (len + 1);
@ -341,14 +341,14 @@ const char *str_escape_ex(const char *str, char *buffer, size_t size, const char
{
size_t slen = strlen(str);
const char *read = str;
char *write = buffer;
unsigned char *write = (unsigned char *)buffer;
if (size < 1) {
return NULL;
}
while (slen > 0 && size > 1 && *read) {
const char *pos = strpbrk(read, chars);
size_t len = size;
if (pos) {
if (pos >= read) {
len = pos - read;
}
if (len < size) {
@ -399,7 +399,7 @@ const char *str_escape_ex(const char *str, char *buffer, size_t size, const char
break;
default:
if (size > 5) {
int n = sprintf(write, "\\%03o", ch);
int n = snprintf((char *)write, size, "\\%03o", ch);
if (n > 0) {
assert(n == 5);
write += n;

View File

@ -164,10 +164,10 @@ static void free_functions(void)
void add_function(const char *symbol, evalfun parse)
{
char token[64];
char token[64]; /* Flawfinder: ignore */
size_t len = strlen(symbol);
assert(len + 1 + sizeof(parse) <= sizeof(token));
assert(len + sizeof(parse) < sizeof(token));
len = cb_new_kv(symbol, len, &parse, sizeof(parse), token);
cb_insert(&functions, token, len);
}
@ -193,15 +193,17 @@ static const char *parse_symbol(opstack ** stack, const char *in,
*/
{
bool braces = false;
char symbol[32];
char symbol[32]; /* Flawfinder: ignore */
char *cp = symbol; /* current position */
if (*in == '{') {
braces = true;
++in;
}
while (isalnum(*in) || *in == '.')
while (isalnum(*in) || *in == '.') {
*cp++ = *in++;
assert(cp < symbol + sizeof(symbol));
}
*cp = '\0';
/* symbol will now contain the symbol name */
if (*in == '(') {
@ -371,7 +373,7 @@ const char *translate(const char *format, const void *userdata,
{
unsigned int i = 0;
const char *ic = vars;
char symbol[32];
char symbol[32]; /* Flawfinder: ignore */
char *oc = symbol;
opstack *stack = NULL;
const char *rv;
@ -383,11 +385,15 @@ const char *translate(const char *format, const void *userdata,
assert(*ic == 0 || isalnum(*ic));
while (*ic) {
*oc++ = *ic++;
assert(oc < symbol + sizeof(symbol));
if (!isalnum(*ic)) {
size_t len;
variant x = args[i++];
*oc = '\0';
len = oc - symbol + 1;
str_strlcpy(oc = balloc(len), symbol, len);
add_variable(oc, x);
oc = symbol;
add_variable(strcpy(balloc(strlen(symbol) + 1), symbol), x);
while (*ic && !isalnum(*ic))
++ic;
}
@ -452,22 +458,15 @@ static void eval_if(opstack ** stack, const void *userdata)
UNUSED_ARG(userdata);
}
static void eval_strlen(opstack ** stack, const void *userdata)
{ /* string -> int */
const char *c = (const char *)opop_v(stack);
opush_i(stack, c ? (int)strlen(c) : 0);
UNUSED_ARG(userdata);
}
#include "base36.h"
static void eval_int(opstack ** stack, const void *userdata)
{
int i = opop_i(stack);
const char *c = itoa10(i);
size_t len = strlen(c);
size_t size = strlen(c) + 1; /* Flawfinder: ignore */
variant var;
var.v = strcpy(balloc(len + 1), c);
str_strlcpy(var.v = balloc(size), c, size);
opush(stack, var);
}
@ -477,7 +476,6 @@ void translation_init(void)
add_function("eq", &eval_eq);
add_function("int", &eval_int);
add_function("add", &eval_add);
add_function("strlen", &eval_strlen);
add_function("if", &eval_if);
add_function("isnull", &eval_isnull);
}

View File

@ -91,7 +91,7 @@ static int a_readdirection(variant *var, void *owner, struct gamedata *data)
{
struct storage *store = data->store;
spec_direction *d = (spec_direction *)(var->v);
char lbuf[32];
char lbuf[32]; /* Flawfinder: ignore */
(void)owner;
READ_INT(store, &d->x);
@ -130,7 +130,7 @@ region *find_special_direction(const region * r, const char *token)
{
attrib *a;
if (strlen(token) == 0)
if (*token == '\0')
return NULL;
for (a = a_find(r->attribs, &at_direction); a && a->type == &at_direction;
a = a->next) {