From 830ba23cda7f3b4d4616111cc12d124c8f91cba4 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 3 Sep 2022 02:45:19 +0300 Subject: [PATCH 19/19] Call log callback from ruleset_error() This provides information to ruledit "Sanity Check" window. See osdn #45395 Signed-off-by: Marko Lindqvist --- server/rscompat.c | 21 +- server/rssanity.c | 235 ++++++++------- server/ruleset.c | 718 ++++++++++++++++++++++++++-------------------- server/ruleset.h | 13 +- 4 files changed, 546 insertions(+), 441 deletions(-) diff --git a/server/rscompat.c b/server/rscompat.c index 0fb4556fea..0f774a29d9 100644 --- a/server/rscompat.c +++ b/server/rscompat.c @@ -60,7 +60,7 @@ int rscompat_check_capabilities(struct section_file *file, if (!(datafile_options = secfile_lookup_str(file, "datafile.options"))) { log_fatal("\"%s\": ruleset capability problem:", filename); - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); return 0; } @@ -81,7 +81,7 @@ int rscompat_check_capabilities(struct section_file *file, log_fatal("\"%s\": ruleset datafile appears incompatible:", filename); log_fatal(" datafile options: %s", datafile_options); log_fatal(" supported options: %s", RULESET_CAPABILITIES); - ruleset_error(LOG_ERROR, "Capability problem"); + ruleset_error(NULL, LOG_ERROR, "Capability problem"); return 0; } @@ -90,7 +90,7 @@ int rscompat_check_capabilities(struct section_file *file, " that we don't support:", filename); log_fatal(" datafile options: %s", datafile_options); log_fatal(" supported options: %s", RULESET_CAPABILITIES); - ruleset_error(LOG_ERROR, "Capability problem"); + ruleset_error(NULL, LOG_ERROR, "Capability problem"); return 0; } @@ -209,7 +209,7 @@ bool rscompat_names(struct rscompat_info *info) for (i = 0; i < ARRAY_SIZE(new_flags_30); i++) { if (UTYF_USER_FLAG_1 + MAX_NUM_USER_UNIT_FLAGS <= first_free + i) { /* Can't add the user unit type flags. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Can't upgrade the ruleset. Not enough free unit type " "user flags to add user flags for the unit type flags " "that used to be hardcoded."); @@ -219,7 +219,7 @@ bool rscompat_names(struct rscompat_info *info) * clash with these ones */ if (unit_type_flag_id_by_name(new_flags_30[i].name, fc_strcasecmp) != unit_type_flag_id_invalid()) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Ruleset had illegal user unit type flag '%s'", new_flags_30[i].name); return FALSE; @@ -235,7 +235,7 @@ bool rscompat_names(struct rscompat_info *info) for (i = 0; i < ARRAY_SIZE(new_class_flags_30); i++) { if (UCF_USER_FLAG_1 + MAX_NUM_USER_UCLASS_FLAGS <= first_free + i) { /* Can't add the user unit type class flags. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Can't upgrade the ruleset. Not enough free unit " "type class user flags to add user flags for the " "unit type class flags that used to be hardcoded."); @@ -245,7 +245,7 @@ bool rscompat_names(struct rscompat_info *info) * clash with these ones */ if (unit_class_flag_id_by_name(new_class_flags_30[i].name, fc_strcasecmp) != unit_class_flag_id_invalid()) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Ruleset had illegal user unit class flag '%s'", new_class_flags_30[i].name); return FALSE; @@ -280,7 +280,7 @@ bool rscompat_names(struct rscompat_info *info) for (i = 0; i < ARRAY_SIZE(new_extra_flags_30); i++) { if (EF_USER_FLAG_1 + MAX_NUM_USER_EXTRA_FLAGS <= first_free + i) { /* Can't add the user extra flags. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Can't upgrade the ruleset. Not enough free extra " "user flags to add user flags for the extra flags " "that used to be hardcoded."); @@ -291,7 +291,7 @@ bool rscompat_names(struct rscompat_info *info) * clash with these ones */ if (extra_flag_id_by_name(new_extra_flags_30[i].name, fc_strcasecmp) != extra_flag_id_invalid()) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Ruleset had illegal user extra flag '%s'", new_extra_flags_30[i].name); return FALSE; @@ -1596,7 +1596,8 @@ struct extra_type *rscompat_extra_from_resource_3_0(struct section_file *sfile, const char *sec_name) { if (game.control.num_extra_types >= MAX_EXTRA_TYPES) { - ruleset_error(LOG_ERROR, "Can't convert resource from %s to an extra. No free slots.", + ruleset_error(NULL, LOG_ERROR, + "Can't convert resource from %s to an extra. No free slots.", sec_name); } else { struct extra_type *pextra = extra_by_number(game.control.num_extra_types++); diff --git a/server/rssanity.c b/server/rssanity.c index 179ae3c83e..415488382b 100644 --- a/server/rssanity.c +++ b/server/rssanity.c @@ -40,11 +40,11 @@ /************************************************************************** Is non-rule data in ruleset sane? **************************************************************************/ -static bool sanity_check_metadata(void) +static bool sanity_check_metadata(rs_conversion_logger logger) { if (game.ruleset_summary != NULL && strlen(game.ruleset_summary) > MAX_LEN_CONTENT) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Too long ruleset summary. It can be only %d bytes long. " "Put longer explanations to ruleset description.", MAX_LEN_CONTENT); @@ -149,7 +149,8 @@ bool sanity_check_server_setting_value_in_req(ssetv ssetval) ruleset load time because they would have referenced things not yet loaded from the ruleset. **************************************************************************/ -static bool sanity_check_req_individual(struct requirement *preq, +static bool sanity_check_req_individual(rs_conversion_logger logger, + struct requirement *preq, const char *list_for) { switch (preq->source.kind) { @@ -160,13 +161,13 @@ static bool sanity_check_req_individual(struct requirement *preq, { struct impr_type *pimprove = preq->source.value.building; if (preq->range == REQ_RANGE_WORLD && !is_great_wonder(pimprove)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: World-ranged requirement not supported for " "%s (only great wonders supported)", list_for, improvement_name_translation(pimprove)); return FALSE; } else if (preq->range > REQ_RANGE_TRADEROUTE && !is_wonder(pimprove)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: %s-ranged requirement not supported for " "%s (only wonders supported)", list_for, req_range_name(preq->range), @@ -179,12 +180,12 @@ static bool sanity_check_req_individual(struct requirement *preq, /* Currently [calendar] is loaded after some requirements are * parsed, so we can't do this in universal_value_from_str(). */ if (game.calendar.calendar_fragments < 1) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: MinCalFrag requirement used in ruleset without " "calendar fragments", list_for); return FALSE; } else if (preq->source.value.mincalfrag >= game.calendar.calendar_fragments) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: MinCalFrag requirement %d out of range (max %d in " "this ruleset)", list_for, preq->source.value.mincalfrag, game.calendar.calendar_fragments-1); @@ -203,7 +204,7 @@ static bool sanity_check_req_individual(struct requirement *preq, pset = setting_by_number(id); if (!sanity_check_setting_is_seen(pset)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: ServerSetting requirement %s isn't visible enough " "to appear in a requirement. Everyone should be able to " "see the value of a server setting that appears in a " @@ -214,7 +215,7 @@ static bool sanity_check_req_individual(struct requirement *preq, if (!sanity_check_setting_is_game_rule(pset)) { /* This is a server operator related setting (like the compression * type of savegames), not a game rule. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: ServerSetting requirement setting %s isn't about a " "game rule.", list_for, server_setting_name_get(id)); @@ -233,7 +234,9 @@ static bool sanity_check_req_individual(struct requirement *preq, /************************************************************************** Helper function for sanity_check_req_vec() **************************************************************************/ -static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], +static bool sanity_check_req_set(rs_conversion_logger logger, + int reqs_of_type[], + int local_reqs_of_type[], struct requirement *preq, bool conjunctive, int max_tiles, const char *list_for) { @@ -241,7 +244,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], fc_assert_ret_val(universals_n_is_valid(preq->source.kind), FALSE); - if (!sanity_check_req_individual(preq, list_for)) { + if (!sanity_check_req_individual(logger, preq, list_for)) { return FALSE; } @@ -263,7 +266,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], switch (preq->source.kind) { case VUT_TERRAINCLASS: if (local_reqs_of_type[VUT_TERRAIN] > 0) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has both local terrain and terrainclass requirement", list_for); return FALSE; @@ -271,7 +274,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], break; case VUT_TERRAIN: if (local_reqs_of_type[VUT_TERRAINCLASS] > 0) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has both local terrain and terrainclass requirement", list_for); return FALSE; @@ -307,7 +310,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], * Requirements might be identical, but we consider multiple * declarations error anyway. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has multiple %s requirements", list_for, universal_type_rule_name(&preq->source)); return FALSE; @@ -316,7 +319,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], case VUT_TERRAIN: /* There can be only up to max_tiles requirements of these types */ if (max_tiles != -1 && rc > max_tiles) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has more %s requirements than " "can ever be fulfilled.", list_for, universal_type_rule_name(&preq->source)); @@ -326,7 +329,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], case VUT_TERRAINCLASS: if (rc > 2 || (max_tiles != -1 && rc > max_tiles)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has more %s requirements than " "can ever be fulfilled.", list_for, universal_type_rule_name(&preq->source)); @@ -337,7 +340,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], case VUT_AGE: /* There can be age of the city, unit, and player */ if (rc > 3) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has more %s requirements than " "can ever be fulfilled.", list_for, universal_type_rule_name(&preq->source)); @@ -348,7 +351,7 @@ static bool sanity_check_req_set(int reqs_of_type[], int local_reqs_of_type[], case VUT_MINTECHS: /* At ranges 'Player' and 'World' */ if (rc > 2) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s: Requirement list has more %s requirements than " "can ever be fulfilled.", list_for, universal_type_rule_name(&preq->source)); @@ -467,7 +470,8 @@ sanity_check_req_vec_singlepole(const struct requirement_vector *preqs, - This function should check also problems caused by defining range to less than hardcoded max for requirement type **************************************************************************/ -static bool sanity_check_req_vec(const struct requirement_vector *preqs, +static bool sanity_check_req_vec(rs_conversion_logger logger, + const struct requirement_vector *preqs, bool conjunctive, int max_tiles, const char *list_for) { @@ -480,7 +484,8 @@ static bool sanity_check_req_vec(const struct requirement_vector *preqs, memset(local_reqs_of_type, 0, sizeof(local_reqs_of_type)); requirement_vector_iterate(preqs, preq) { - if (!sanity_check_req_set(reqs_of_type, local_reqs_of_type, preq, + if (!sanity_check_req_set(logger, + reqs_of_type, local_reqs_of_type, preq, conjunctive, max_tiles, list_for)) { return FALSE; } @@ -491,7 +496,7 @@ static bool sanity_check_req_vec(const struct requirement_vector *preqs, problem = req_vec_get_first_contradiction(preqs, req_vec_vector_number, preqs); if (problem != NULL) { - ruleset_error(LOG_ERROR, "%s: %s.", list_for, problem->description); + ruleset_error(logger, LOG_ERROR, "%s: %s.", list_for, problem->description); req_vec_problem_free(problem); return FALSE; } @@ -499,6 +504,10 @@ static bool sanity_check_req_vec(const struct requirement_vector *preqs, return TRUE; } +typedef struct { + rs_conversion_logger logger; +} els_data; + /************************************************************************** Sanity check callback for iterating effects cache. **************************************************************************/ @@ -506,27 +515,29 @@ static bool effect_list_sanity_cb(struct effect *peffect, void *data) { int one_tile = -1; /* TODO: Determine correct value from effect. * -1 disables checking */ + els_data *els = (els_data *)data; - return sanity_check_req_vec(&peffect->reqs, TRUE, one_tile, + return sanity_check_req_vec(els->logger, + &peffect->reqs, TRUE, one_tile, effect_type_name(peffect->type)); } /************************************************************************** Sanity check barbarian unit types **************************************************************************/ -static bool rs_barbarian_units(void) +static bool rs_barbarian_units(rs_conversion_logger logger) { if (num_role_units(L_BARBARIAN) > 0) { if (num_role_units(L_BARBARIAN_LEADER) == 0) { - ruleset_error(LOG_ERROR, "No role barbarian leader units"); + ruleset_error(logger, LOG_ERROR, "No role barbarian leader units"); return FALSE; } if (num_role_units(L_BARBARIAN_BUILD) == 0) { - ruleset_error(LOG_ERROR, "No role barbarian build units"); + ruleset_error(logger, LOG_ERROR, "No role barbarian build units"); return FALSE; } if (num_role_units(L_BARBARIAN_BOAT) == 0) { - ruleset_error(LOG_ERROR, "No role barbarian ship units"); + ruleset_error(logger, LOG_ERROR, "No role barbarian ship units"); return FALSE; } else if (num_role_units(L_BARBARIAN_BOAT) > 0) { bool sea_capable = FALSE; @@ -541,21 +552,21 @@ static bool rs_barbarian_units(void) } terrain_type_iterate_end; if (!sea_capable) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Barbarian boat (%s) needs to be able to move at sea.", utype_rule_name(u)); return FALSE; } } if (num_role_units(L_BARBARIAN_SEA) == 0) { - ruleset_error(LOG_ERROR, "No role sea raider barbarian units"); + ruleset_error(logger, LOG_ERROR, "No role sea raider barbarian units"); return FALSE; } unit_type_iterate(ptype) { if (utype_has_role(ptype, L_BARBARIAN_BOAT)) { if (ptype->transport_capacity <= 1) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Barbarian boat %s has no capacity for both " "leader and at least one man.", utype_rule_name(ptype)); @@ -567,7 +578,7 @@ static bool rs_barbarian_units(void) || utype_has_role(pbarb, L_BARBARIAN_SEA_TECH) || utype_has_role(pbarb, L_BARBARIAN_LEADER)) { if (!can_unit_type_transport(ptype, utype_class(pbarb))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Barbarian boat %s cannot transport " "barbarian cargo %s.", utype_rule_name(ptype), @@ -586,21 +597,21 @@ static bool rs_barbarian_units(void) /************************************************************************** Sanity check common unit types **************************************************************************/ -static bool rs_common_units(void) +static bool rs_common_units(rs_conversion_logger logger) { /* Check some required flags and roles etc: */ if (num_role_units(UTYF_SETTLERS) == 0) { - ruleset_error(LOG_ERROR, "No flag Settler units"); + ruleset_error(logger, LOG_ERROR, "No flag Settler units"); return FALSE; } if (num_role_units(L_START_EXPLORER) == 0) { - ruleset_error(LOG_ERROR, "No role Start Explorer units"); + ruleset_error(logger, LOG_ERROR, "No role Start Explorer units"); } if (num_role_units(L_FERRYBOAT) == 0) { - ruleset_error(LOG_ERROR, "No role Ferryboat units"); + ruleset_error(logger, LOG_ERROR, "No role Ferryboat units"); } if (num_role_units(L_FIRSTBUILD) == 0) { - ruleset_error(LOG_ERROR, "No role Firstbuild units"); + ruleset_error(logger, LOG_ERROR, "No role Firstbuild units"); } if (num_role_units(L_FERRYBOAT) > 0) { @@ -616,7 +627,7 @@ static bool rs_common_units(void) } terrain_type_iterate_end; if (!sea_capable) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Ferryboat (%s) needs to be able to move at sea.", utype_rule_name(u)); return FALSE; @@ -625,7 +636,7 @@ static bool rs_common_units(void) if (num_role_units(L_PARTISAN) == 0 && effect_cumulative_max(EFT_INSPIRE_PARTISANS, NULL) > 0) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Inspire_Partisans effect present, but no units with partisan role."); return FALSE; } @@ -636,13 +647,13 @@ static bool rs_common_units(void) /************************************************************************** Sanity check buildings **************************************************************************/ -static bool rs_buildings(void) +static bool rs_buildings(rs_conversion_logger logger) { /* Special Genus */ improvement_iterate(pimprove) { if (improvement_has_flag(pimprove, IF_GOLD) && pimprove->genus != IG_SPECIAL) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Gold producing improvement %s with genus other than \"Special\"", improvement_rule_name(pimprove)); @@ -650,7 +661,7 @@ static bool rs_buildings(void) } if (improvement_has_flag(pimprove, IF_DISASTER_PROOF) && pimprove->genus != IG_IMPROVEMENT) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Disasterproof improvement %s with genus other than \"Improvement\"", improvement_rule_name(pimprove)); @@ -663,7 +674,7 @@ static bool rs_buildings(void) RPT_POSSIBLE, FALSE) || get_potential_improvement_bonus(pimprove, NULL, EFT_SS_MODULE, RPT_POSSIBLE, FALSE))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Space part %s with genus other than \"Special\"", improvement_rule_name(pimprove)); return FALSE; @@ -684,7 +695,7 @@ static bool rs_buildings(void) /************************************************************************** Check that boolean effect types have sensible effects. **************************************************************************/ -static bool sanity_check_boolean_effects(void) +static bool sanity_check_boolean_effects(rs_conversion_logger logger) { enum effect_type boolean_effects[] = { @@ -724,7 +735,8 @@ static bool sanity_check_boolean_effects(void) for (i = 0; boolean_effects[i] != EFT_COUNT; i++) { if (effect_cumulative_min(boolean_effects[i], NULL) < 0 && effect_cumulative_max(boolean_effects[i], NULL) == 0) { - ruleset_error(LOG_ERROR, "Boolean effect %s can get disabled, but it can't get " + ruleset_error(logger, LOG_ERROR, + "Boolean effect %s can get disabled, but it can't get " "enabled before that.", effect_type_name(boolean_effects[i])); ret = FALSE; } @@ -750,14 +762,17 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) bool default_gov_failed = FALSE; bool obsoleted_by_loop = FALSE; bool ignore_retired = (compat != NULL && compat->compat_mode); + els_data els; + rs_conversion_logger logger = ((compat != NULL) ? compat->log_cb : NULL); - if (!sanity_check_metadata()) { + if (!sanity_check_metadata(logger)) { ok = FALSE; } if (game.info.tech_cost_style == TECH_COST_CIV1CIV2 && game.info.free_tech_method == FTM_CHEAPEST) { - ruleset_error(LOG_ERROR, "Cost based free tech method, but tech cost style " + ruleset_error(logger, LOG_ERROR, + "Cost based free tech method, but tech cost style " "\"Civ I|II\" so all techs cost the same."); ok = FALSE; } @@ -777,7 +792,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (A_NEVER == preq) { continue; } else if (preq == padvance) { - ruleset_error(LOG_ERROR, "Tech \"%s\" requires itself.", + ruleset_error(logger, LOG_ERROR, "Tech \"%s\" requires itself.", advance_rule_name(padvance)); ok = FALSE; continue; @@ -785,7 +800,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) advance_req_iterate(preq, preqreq) { if (preqreq == padvance) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech \"%s\" requires itself indirectly via \"%s\".", advance_rule_name(padvance), advance_rule_name(preq)); @@ -799,7 +814,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Don't allow this even if allowing changing reqs. Players will * expect all tech reqs to appear in the client tech tree. That * should be taken care of first. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech \"%s\" requires a tech in its research_reqs." " This isn't supported yet. Please keep using req1" " and req2 like before.", @@ -809,7 +824,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Only support unchanging requirements until the reachability code * can handle it and the tech tree can display changing * requirements. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech \"%s\" has the requirement %s in its" " research_reqs. This requirement may change during" " the game. Changing requirements aren't supported" @@ -822,7 +837,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (padvance->bonus_message != NULL) { if (!formats_match(padvance->bonus_message, "%s")) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech \"%s\" bonus message is not format with %%s for a bonus tech name.", advance_rule_name(padvance)); ok = FALSE; @@ -831,7 +846,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } advance_iterate_end; if (game.default_government == game.government_during_revolution) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "The government form %s reserved for revolution handling has been set as " "default_government.", government_rule_name(game.government_during_revolution)); @@ -850,7 +865,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) struct advance *a = valid_advance_by_number(tech); if (a == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech %s does not exist, but is initial " "tech for everyone.", advance_rule_name(advance_by_number(tech))); @@ -858,7 +873,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } else if (advance_by_number(A_NONE) != a->require[AR_ROOT] && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) { /* Nation has no root_req for tech */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech %s is initial for everyone, but %s has " "no root_req for it.", advance_rule_name(a), @@ -875,7 +890,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) struct advance *a = valid_advance_by_number(tech); if (a == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech %s does not exist, but is tech for %s.", advance_rule_name(advance_by_number(tech)), nation_rule_name(pnation)); @@ -883,7 +898,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } else if (advance_by_number(A_NONE) != a->require[AR_ROOT] && !nation_has_initial_tech(pnation, a->require[AR_ROOT])) { /* Nation has no root_req for tech */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Tech %s is initial for %s, but they have " "no root_req for it.", advance_rule_name(a), @@ -895,13 +910,13 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Check national initial buildings */ if (nation_barbarian_type(pnation) != NOT_A_BARBARIAN && pnation->init_buildings[0] != B_LAST) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Barbarian nation %s has init_buildings set but will " "never see them", nation_rule_name(pnation)); } if (!default_gov_failed && pnation->init_government == game.government_during_revolution) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "The government form %s reserved for revolution handling has been set as " "initial government for %s.", government_rule_name(game.government_during_revolution), @@ -920,7 +935,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) upgraded = upgraded->obsoleted_by; chain_length++; if (chain_length > num_utypes) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "There seems to be obsoleted_by loop in update " "chain that starts from %s", utype_rule_name(putype)); ok = FALSE; @@ -937,7 +952,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) * kept. */ if (utype_has_flag(putype, UTYF_SPY) && !utype_has_flag(putype, UTYF_DIPLOMAT)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "The unit type '%s' has the 'Spy' unit type flag but " "not the 'Diplomat' unit type flag.", utype_rule_name(putype)); @@ -950,7 +965,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (putype->paratroopers_range < 0 || putype->paratroopers_range > UNIT_MAX_PARADROP_RANGE) { /* Paradrop range is limited by the network protocol. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "The paratroopers_range of the unit type '%s' is %d. " "That is out of range. Max range is %d.", utype_rule_name(putype), @@ -960,7 +975,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* never fires if game.scenario.prevent_new_cities is TRUE */ if ((putype->city_size <= 0 || putype->city_size > MAX_CITY_SIZE) && utype_is_cityfounder(putype)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Unit type '%s' would build size %d cities. " "City sizes must be from 1 to %d.", utype_rule_name(putype), putype->city_size, @@ -969,15 +984,17 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } } unit_type_iterate_end; + els.logger = logger; + /* Check requirement sets against conflicting requirements. * Effects use requirement lists */ - if (!iterate_effect_cache(effect_list_sanity_cb, NULL)) { - ruleset_error(LOG_ERROR, + if (!iterate_effect_cache(effect_list_sanity_cb, &els)) { + ruleset_error(logger, LOG_ERROR, "Effects have conflicting or invalid requirements!"); ok = FALSE; } - if (!sanity_check_boolean_effects()) { + if (!sanity_check_boolean_effects(logger)) { ok = FALSE; } @@ -985,9 +1002,9 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Disasters */ disaster_type_iterate(pdis) { - if (!sanity_check_req_vec(&pdis->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pdis->reqs, TRUE, -1, disaster_rule_name(pdis))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Disasters have conflicting or invalid requirements!"); ok = FALSE; } @@ -995,9 +1012,9 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Goods */ goods_type_iterate(pgood) { - if (!sanity_check_req_vec(&pgood->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pgood->reqs, TRUE, -1, goods_rule_name(pgood))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Goods have conflicting or invalid requirements!"); ok = FALSE; } @@ -1005,15 +1022,15 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Buildings */ improvement_iterate(pimprove) { - if (!sanity_check_req_vec(&pimprove->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pimprove->reqs, TRUE, -1, improvement_rule_name(pimprove))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Buildings have conflicting or invalid requirements!"); ok = FALSE; } - if (!sanity_check_req_vec(&pimprove->obsolete_by, FALSE, -1, + if (!sanity_check_req_vec(logger, &pimprove->obsolete_by, FALSE, -1, improvement_rule_name(pimprove))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Buildings have conflicting or invalid obsolescence req!"); ok = FALSE; } @@ -1021,9 +1038,9 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Governments */ governments_iterate(pgov) { - if (!sanity_check_req_vec(&pgov->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pgov->reqs, TRUE, -1, government_rule_name(pgov))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Governments have conflicting or invalid requirements!"); ok = FALSE; } @@ -1033,9 +1050,9 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) specialist_type_iterate(sp) { struct specialist *psp = specialist_by_number(sp); - if (!sanity_check_req_vec(&psp->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &psp->reqs, TRUE, -1, specialist_rule_name(psp))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Specialists have conflicting or invalid requirements!"); ok = FALSE; } @@ -1043,15 +1060,15 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Extras */ extra_type_iterate(pextra) { - if (!sanity_check_req_vec(&pextra->reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pextra->reqs, TRUE, -1, extra_rule_name(pextra))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Extras have conflicting or invalid requirements!"); ok = FALSE; } - if (!sanity_check_req_vec(&pextra->rmreqs, TRUE, -1, + if (!sanity_check_req_vec(logger, &pextra->rmreqs, TRUE, -1, extra_rule_name(pextra))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Extras have conflicting or invalid removal requirements!"); ok = FALSE; } @@ -1068,7 +1085,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (pnbr != road_number(iroad) && !BV_ISSET(iroad->integrates, pnbr)) { /* We don't support non-symmetric integrator relationships yet. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Road '%s' integrates with '%s' but not vice versa!", extra_rule_name(pextra), extra_rule_name(iextra)); @@ -1094,7 +1111,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } if (BV_ISSET(pbase->flags, bfi)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Base %s uses the retired base flag %s!", extra_name_translation(pextra), base_flag_id_name(bfi)); @@ -1104,9 +1121,10 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* City styles */ for (i = 0; i < game.control.styles_count; i++) { - if (!sanity_check_req_vec(&city_styles[i].reqs, TRUE, -1, + if (!sanity_check_req_vec(logger, + &city_styles[i].reqs, TRUE, -1, city_style_rule_name(i))) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "City styles have conflicting or invalid requirements!"); ok = FALSE; } @@ -1117,28 +1135,31 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) struct action *paction = action_by_number(act); if (paction->min_distance < 0) { - ruleset_error(LOG_ERROR, "Action %s: negative min distance (%d).", + ruleset_error(logger, LOG_ERROR, + "Action %s: negative min distance (%d).", action_id_rule_name(act), paction->min_distance); ok = FALSE; } if (paction->min_distance > ACTION_DISTANCE_LAST_NON_SIGNAL) { - ruleset_error(LOG_ERROR, "Action %s: min distance (%d) larger than " - "any distance on a map can be (%d).", + ruleset_error(logger, LOG_ERROR, + "Action %s: min distance (%d) larger than " + "any distance on a map can be (%d).", action_id_rule_name(act), paction->min_distance, ACTION_DISTANCE_LAST_NON_SIGNAL); ok = FALSE; } if (paction->max_distance > ACTION_DISTANCE_MAX) { - ruleset_error(LOG_ERROR, "Action %s: max distance is %d. " + ruleset_error(logger, LOG_ERROR, + "Action %s: max distance is %d. " "A map can't be that big.", action_id_rule_name(act), paction->max_distance); ok = FALSE; } if (!action_distance_inside_max(paction, paction->min_distance)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Action %s: min distance is %d but max distance is %d.", action_id_rule_name(act), paction->min_distance, paction->max_distance); @@ -1152,7 +1173,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Can't find an individual unit target to evaluate the blocking * action against. (A tile may have more than one individual * unit) */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "The action %s can't block %s.", action_id_rule_name(blocker), action_id_rule_name(act)); @@ -1161,11 +1182,11 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } action_iterate_end; action_enabler_list_iterate(action_enablers_for_action(act), enabler) { - if (!sanity_check_req_vec(&(enabler->actor_reqs), TRUE, -1, + if (!sanity_check_req_vec(logger, &(enabler->actor_reqs), TRUE, -1, "Action Enabler Actor Reqs") - || !sanity_check_req_vec(&(enabler->target_reqs), TRUE, -1, + || !sanity_check_req_vec(logger, &(enabler->target_reqs), TRUE, -1, "Action Enabler Target Reqs")) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Action enabler for %s has conflicting or invalid " "requirements!", action_id_rule_name(act)); ok = FALSE; @@ -1177,7 +1198,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (requirement_vector_size(&(enabler->target_reqs)) > 0) { /* Shouldn't have target requirements since the action doesn't * have a target. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "An action enabler for %s has a target " "requirement vector. %s doesn't have a target.", action_id_rule_name(act), @@ -1192,7 +1213,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* A Local DiplRel requirement can be expressed as a requirement * in actor_reqs. Demand that it is there. This avoids breaking * code that reasons about actions. */ - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Action enabler for %s has a local DiplRel " "requirement %s in target_reqs! Please read the " "section \"Requirement vector rules\" in " @@ -1212,7 +1233,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) = action_enabler_suggest_repair(enabler); if (problem != NULL) { - ruleset_error(LOG_ERROR, "%s", problem->description); + ruleset_error(logger, LOG_ERROR, "%s", problem->description); req_vec_problem_free(problem); ok = FALSE; } @@ -1230,7 +1251,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* There must be basic city style for each nation style to start with */ styles_iterate(pstyle) { if (basic_city_style_for_style(pstyle) < 0) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "There's no basic city style for nation style %s", style_rule_name(pstyle)); ok = FALSE; @@ -1239,8 +1260,8 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) /* Music styles */ music_styles_iterate(pmus) { - if (!sanity_check_req_vec(&pmus->reqs, TRUE, -1, "Music Style")) { - ruleset_error(LOG_ERROR, + if (!sanity_check_req_vec(logger, &pmus->reqs, TRUE, -1, "Music Style")) { + ruleset_error(logger, LOG_ERROR, "Music Styles have conflicting or invalid requirements!"); ok = FALSE; } @@ -1251,7 +1272,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) if (pterr->animal != NULL) { if (!is_native_to_class(utype_class(pterr->animal), pterr, NULL)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s has %s as animal to appear, but it's not native to the terrain.", terrain_rule_name(pterr), utype_rule_name(pterr->animal)); ok = FALSE; @@ -1260,7 +1281,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) for (pres = pterr->resources; *pres != NULL; pres++) { if (!is_extra_caused_by((*pres), EC_RESOURCE)) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "%s has %s as a resource, but it's not a resource extra.", terrain_rule_name(pterr), extra_rule_name(*pres)); ok = FALSE; @@ -1291,7 +1312,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } if (!can_exist) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Unit class %s cannot exist anywhere.", uclass_rule_name(pclass)); ok = FALSE; @@ -1301,7 +1322,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) achievements_iterate(pach) { if (!pach->unique && pach->cons_msg == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "Achievement %s has no message for consecutive gainers though " "it's possible to be gained by multiple players", achievement_rule_name(pach)); @@ -1317,7 +1338,7 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) = nation_by_rule_name(game.server.ruledit.embedded_nations[nati]); if (pnat == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(logger, LOG_ERROR, "There's nation %s listed in embedded nations, but there's " "no such nation.", game.server.ruledit.embedded_nations[nati]); @@ -1327,13 +1348,13 @@ bool sanity_check_ruleset_data(struct rscompat_info *compat) } if (ok) { - ok = rs_common_units(); + ok = rs_common_units(logger); } if (ok) { - ok = rs_barbarian_units(); + ok = rs_barbarian_units(logger); } if (ok) { - ok = rs_buildings(); + ok = rs_buildings(logger); } return ok; diff --git a/server/ruleset.c b/server/ruleset.c index 2a8e2f2336..5cbe0bd1f1 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -200,15 +200,25 @@ char *script_buffer = NULL; Notifications about ruleset errors to clients. Especially important in case of internal server crashing. **************************************************************************/ -void ruleset_error_real(const char *file, const char *function, +void ruleset_error_real(rs_conversion_logger logger, + const char *file, const char *function, int line, enum log_level level, const char *format, ...) { va_list args; char buf[MAX_LEN_LOG_LINE]; + if (logger == NULL && !log_do_output_for_level(level)) { + return; + } + va_start(args, format); - vdo_log(file, function, line, FALSE, level, buf, sizeof(buf), format, args); + if (logger != NULL) { + fc_vsnprintf(buf, sizeof(buf), format, args); + logger(buf); + } else { + vdo_log(file, function, line, FALSE, level, buf, sizeof(buf), format, args); + } va_end(args); if (LOG_FATAL >= level) { @@ -252,7 +262,7 @@ static const char *valid_ruleset_filename(const char *subdir, if (dfilename) { return dfilename; } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, /* TRANS: message about an installation error. */ _("Could not find a readable \"%s.%s\" ruleset file."), name, extension); @@ -291,7 +301,7 @@ static struct section_file *openload_ruleset_file(const char *whichset, secfile = secfile_load(sfilename, FALSE); if (secfile == NULL) { - ruleset_error(LOG_ERROR, "Could not load ruleset '%s':\n%s", + ruleset_error(NULL, LOG_ERROR, "Could not load ruleset '%s':\n%s", sfilename, secfile_error()); } @@ -313,7 +323,7 @@ static bool openload_script_file(const char *whichset, const char *rsdir, if (buffer == NULL) { if (!script_server_do_file(NULL, dfilename)) { - ruleset_error(LOG_ERROR, "\"%s\": could not load ruleset script.", + ruleset_error(NULL, LOG_ERROR, "\"%s\": could not load ruleset script.", dfilename); return FALSE; @@ -353,7 +363,7 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, if (!(pentry = secfile_entry_lookup(file, "%s.%s%d.name", sec, sub, j))) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); return NULL; } @@ -384,7 +394,7 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, break; case ENTRY_FLOAT: fc_assert(entry_type_get(pentry) != ENTRY_FLOAT); - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": trying to have an floating point entry as a requirement name in '%s.%s%d'.", filename, sec, sub, j); break; @@ -396,14 +406,14 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, break; } if (NULL == name) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": error in handling requirement name for '%s.%s%d'.", filename, sec, sub, j); return NULL; } if (!(range = secfile_lookup_str(file, "%s.%s%d.range", sec, sub, j))) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); return NULL; } @@ -412,7 +422,7 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, if ((pentry = secfile_entry_lookup(file, "%s.%s%d.survives", sec, sub, j)) && !entry_bool_get(pentry, &survives)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": invalid boolean value for survives for " "'%s.%s%d'.", filename, sec, sub, j); } @@ -421,7 +431,7 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, if ((pentry = secfile_entry_lookup(file, "%s.%s%d.present", sec, sub, j)) && !entry_bool_get(pentry, &present)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": invalid boolean value for present for " "'%s.%s%d'.", filename, sec, sub, j); } @@ -429,7 +439,7 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, if ((pentry = secfile_entry_lookup(file, "%s.%s%d.quiet", sec, sub, j)) && !entry_bool_get(pentry, &quiet)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": invalid boolean value for quiet for " "'%s.%s%d'.", filename, sec, sub, j); } @@ -445,8 +455,9 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, req = req_from_str(type, range, survives, present, quiet, name); if (req.source.kind == universals_n_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] has invalid or unknown req: " - "\"%s\" \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] has invalid or unknown req: " + "\"%s\" \"%s\".", filename, sec, type, name); return NULL; @@ -456,7 +467,8 @@ static struct requirement_vector *lookup_req_list(struct section_file *file, } if (j > MAX_NUM_REQS) { - ruleset_error(LOG_ERROR, "Too many (%d) requirements for %s. Max is %d", + ruleset_error(NULL, LOG_ERROR, + "Too many (%d) requirements for %s. Max is %d", j, rfor, MAX_NUM_REQS); return NULL; @@ -544,7 +556,7 @@ static bool lookup_tech(struct section_file *file, *result = advance_by_rule_name(sval); if (A_NEVER == *result) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s %s: couldn't match \"%s\".", filename, (description ? description : prefix), entry, sval); return FALSE; @@ -577,7 +589,7 @@ static bool lookup_building(struct section_file *file, *result = improvement_by_rule_name(sval); if (B_NEVER == *result) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s %s: couldn't match \"%s\".", filename, (description ? description : prefix), entry, sval); ok = FALSE; @@ -617,7 +629,7 @@ static bool lookup_unit_list(struct section_file *file, const char *prefix, return TRUE; } if (nval > MAX_NUM_UNIT_LIST) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": string vector %s.%s too long (%d, max %d)", filename, prefix, entry, (int) nval, MAX_NUM_UNIT_LIST); ok = FALSE; @@ -631,7 +643,7 @@ static bool lookup_unit_list(struct section_file *file, const char *prefix, struct unit_type *punittype = unit_type_by_rule_name(sval); if (!punittype) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename, prefix, entry, i, sval); ok = FALSE; @@ -671,7 +683,7 @@ static bool lookup_tech_list(struct section_file *file, const char *prefix, if (slist == NULL || nval == 0) { return TRUE; } else if (nval > MAX_NUM_TECH_LIST) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": string vector %s.%s too long (%d, max %d)", filename, prefix, entry, (int) nval, MAX_NUM_TECH_LIST); ok = FALSE; @@ -687,13 +699,14 @@ static bool lookup_tech_list(struct section_file *file, const char *prefix, struct advance *padvance = advance_by_rule_name(sval); if (NULL == padvance) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename, prefix, entry, i, sval); ok = FALSE; } if (!valid_advance(padvance)) { - ruleset_error(LOG_ERROR, "\"%s\" %s.%s (%d): \"%s\" is removed.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" %s.%s (%d): \"%s\" is removed.", filename, prefix, entry, i, sval); ok = FALSE; } @@ -732,7 +745,7 @@ static bool lookup_building_list(struct section_file *file, } slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry); if (nval > MAX_NUM_BUILDING_LIST) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": string vector %s.%s too long (%d, max %d)", filename, prefix, entry, (int) nval, MAX_NUM_BUILDING_LIST); ok = FALSE; @@ -748,7 +761,7 @@ static bool lookup_building_list(struct section_file *file, struct impr_type *pimprove = improvement_by_rule_name(sval); if (NULL == pimprove) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s.%s (%d): couldn't match \"%s\".", filename, prefix, entry, i, sval); ok = FALSE; @@ -785,7 +798,7 @@ static bool lookup_unit_type(struct section_file *file, } else { *result = unit_type_by_rule_name(sval); if (*result == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s %s: couldn't match \"%s\".", filename, (description ? description : prefix), entry, sval); @@ -815,7 +828,7 @@ static struct government *lookup_government(struct section_file *file, gov = government_by_rule_name(sval); } if (!gov) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" %s: couldn't match \"%s\".", filename, entry, sval); } @@ -874,11 +887,9 @@ static struct extra_type *lookup_resource(const char *filename, pres = extra_type_by_rule_name(name); if (pres == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] has unknown \"%s\".", - filename, - jsection, - name); + filename, jsection, name); } return pres; @@ -917,7 +928,8 @@ static bool lookup_terrain(struct section_file *file, *result = pterr; if (pterr == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] has unknown \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] has unknown \"%s\".", secfile_name(file), jsection, name); return FALSE; } @@ -945,7 +957,7 @@ static bool lookup_time(const struct section_file *secfile, int *turns, } if (*turns > max_turns) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": \"%s\": \"%s\" value %d too large (max %d)", filename, item_name ? item_name : sec_name, property_name, *turns, max_turns); @@ -967,7 +979,7 @@ static bool ruleset_load_names(struct name_translation *pname, const char *rule_name = secfile_lookup_str(file, "%s.rule_name", sec_name); if (!name) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s]: no \"name\" specified.", secfile_name(file), sec_name); return FALSE; @@ -1040,7 +1052,8 @@ static bool load_game_names(struct section_file *file, if (nval > MAX_ACHIEVEMENT_TYPES) { int num = nval; /* No "size_t" to printf */ - ruleset_error(LOG_ERROR, "\"%s\": Too many achievement types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many achievement types (%d, max %d)", filename, num, MAX_ACHIEVEMENT_TYPES); ok = FALSE; } else { @@ -1052,7 +1065,8 @@ static bool load_game_names(struct section_file *file, const char *sec_name = section_name(section_list_get(sec, achievement_index(pach))); if (!ruleset_load_names(&pach->name, NULL, file, sec_name)) { - ruleset_error(LOG_ERROR, "\"%s\": Cannot load achievement names", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Cannot load achievement names", filename); ok = FALSE; break; @@ -1070,13 +1084,14 @@ static bool load_game_names(struct section_file *file, if (nval > MAX_GOODS_TYPES) { int num = nval; /* No "size_t" to printf */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": Too many goods types (%d, max %d)", filename, num, MAX_GOODS_TYPES); section_list_destroy(sec); ok = FALSE; } else if (nval < 1) { - ruleset_error(LOG_ERROR, "\"%s\": At least one goods type needed", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": At least one goods type needed", filename); section_list_destroy(sec); ok = FALSE; @@ -1090,7 +1105,8 @@ static bool load_game_names(struct section_file *file, = section_name(section_list_get(sec, goods_index(pgood))); if (!ruleset_load_names(&pgood->name, NULL, file, sec_name)) { - ruleset_error(LOG_ERROR, "\"%s\": Cannot load goods names", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Cannot load goods names", filename); ok = FALSE; break; @@ -1134,13 +1150,15 @@ static bool load_tech_names(struct section_file *file, const char *helptxt = secfile_lookup_str_default(file, NULL, "control.flags%d.helptxt", i); if (tech_flag_id_by_name(flag, fc_strcasecmp) != tech_flag_id_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\": Duplicate tech flag name '%s'", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Duplicate tech flag name '%s'", filename, flag); ok = FALSE; break; } if (i > MAX_NUM_USER_TECH_FLAGS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many user tech flags!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many user tech flags!", filename); ok = FALSE; break; @@ -1163,7 +1181,7 @@ static bool load_tech_names(struct section_file *file, if (nval > MAX_NUM_TECH_CLASSES) { int num = nval; /* No "size_t" to printf */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": Too many tech classes (%d, max %d)", filename, num, MAX_NUM_TECH_CLASSES); section_list_destroy(sec); @@ -1178,7 +1196,7 @@ static bool load_tech_names(struct section_file *file, = section_name(section_list_get(sec, tech_class_index(ptclass))); if (!ruleset_load_names(&ptclass->name, NULL, file, sec_name)) { - ruleset_error(LOG_ERROR, "\"%s\": Cannot load tech class names", + ruleset_error(NULL, LOG_ERROR, "\"%s\": Cannot load tech class names", filename); ok = FALSE; break; @@ -1191,12 +1209,14 @@ static bool load_tech_names(struct section_file *file, /* The techs: */ sec = secfile_sections_by_name_prefix(file, ADVANCE_SECTION_PREFIX); if (NULL == sec || 0 == (num_techs = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": No Advances?!?", filename); + ruleset_error(NULL, LOG_ERROR, + "\"%s\": No Advances?!?", filename); ok = FALSE; } else { log_verbose("%d advances (including possibly unused)", num_techs); if (num_techs + A_FIRST > A_LAST) { - ruleset_error(LOG_ERROR, "\"%s\": Too many advances (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many advances (%d, max %d)", filename, num_techs, A_LAST - A_FIRST); ok = FALSE; } @@ -1267,13 +1287,15 @@ static bool load_ruleset_techs(struct section_file *file, if ((A_NEVER == a->require[AR_ONE] && A_NEVER != a->require[AR_TWO]) || (A_NEVER != a->require[AR_ONE] && A_NEVER == a->require[AR_TWO])) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] \"%s\": \"Never\" with non-\"Never\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] \"%s\": \"Never\" with non-\"Never\".", filename, sec_name, rule_name_get(&a->name)); ok = FALSE; break; } if (a_none == a->require[AR_ONE] && a_none != a->require[AR_TWO]) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] \"%s\": should have \"None\" second.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] \"%s\": should have \"None\" second.", filename, sec_name, rule_name_get(&a->name)); ok = FALSE; break; @@ -1289,7 +1311,8 @@ static bool load_ruleset_techs(struct section_file *file, classname = Q_(classname); a->tclass = tech_class_by_rule_name(classname); if (a->tclass == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] \"%s\": Uknown tech class \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] \"%s\": Uknown tech class \"%s\".", filename, sec_name, rule_name_get(&a->name), classname); ok = FALSE; break; @@ -1318,7 +1341,8 @@ static bool load_ruleset_techs(struct section_file *file, } ival = tech_flag_id_by_name(sval, fc_strcasecmp); if (!tech_flag_id_is_valid(ival)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] \"%s\": bad flag name \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] \"%s\": bad flag name \"%s\".", filename, sec_name, rule_name_get(&a->name), sval); ok = FALSE; break; @@ -1401,18 +1425,16 @@ restart: /* We check for recursive tech loops later, * in build_required_techs_helper. */ if (!valid_advance(a->require[AR_ONE])) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" tech \"%s\": req1 leads to removed tech.", - filename, - advance_rule_name(a)); + filename, advance_rule_name(a)); ok = FALSE; break; } if (!valid_advance(a->require[AR_TWO])) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" tech \"%s\": req2 leads to removed tech.", - filename, - advance_rule_name(a)); + filename, advance_rule_name(a)); ok = FALSE; break; } @@ -1459,13 +1481,15 @@ static bool load_unit_names(struct section_file *file, if (unit_type_flag_id_by_name(rscompat_utype_flag_name_3_0(compat, flag), fc_strcasecmp) != unit_type_flag_id_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\": Duplicate unit flag name '%s'", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Duplicate unit flag name '%s'", filename, flag); ok = FALSE; break; } if (i > MAX_NUM_USER_UNIT_FLAGS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many user unit type flags!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many user unit type flags!", filename); ok = FALSE; break; @@ -1493,14 +1517,15 @@ static bool load_unit_names(struct section_file *file, if (unit_class_flag_id_by_name(flag, fc_strcasecmp) != unit_class_flag_id_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\": Duplicate unit class flag name " - "'%s'", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Duplicate unit class flag name '%s'", filename, flag); ok = FALSE; break; } if (i > MAX_NUM_USER_UCLASS_FLAGS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many user unit class flags!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many user unit class flags!", filename); ok = FALSE; break; @@ -1521,13 +1546,15 @@ static bool load_unit_names(struct section_file *file, /* Unit classes */ sec = secfile_sections_by_name_prefix(file, UNIT_CLASS_SECTION_PREFIX); if (NULL == sec || 0 == (nval = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": No unit classes?!?", filename); + ruleset_error(NULL, LOG_ERROR, + "\"%s\": No unit classes?!?", filename); ok = FALSE; } else { log_verbose("%d unit classes", nval); if (nval > UCL_LAST) { - ruleset_error(LOG_ERROR, "\"%s\": Too many unit classes (%d, max %d)", - filename, nval, UCL_LAST); + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many unit classes (%d, max %d)", + filename, nval, UCL_LAST); ok = FALSE; } } @@ -1553,12 +1580,14 @@ static bool load_unit_names(struct section_file *file, if (ok) { sec = secfile_sections_by_name_prefix(file, UNIT_SECTION_PREFIX); if (NULL == sec || 0 == (nval = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": No unit types?!?", filename); + ruleset_error(NULL, LOG_ERROR, + "\"%s\": No unit types?!?", filename); ok = FALSE; } else { log_verbose("%d unit types (including possibly unused)", nval); if (nval > U_LAST) { - ruleset_error(LOG_ERROR, "\"%s\": Too many unit types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many unit types (%d, max %d)", filename, nval, U_LAST); ok = FALSE; } @@ -1719,7 +1748,8 @@ static bool load_ruleset_units(struct section_file *file, if (!load_ruleset_veteran(file, "veteran_system", &game.veteran, msg, sizeof(msg)) || game.veteran == NULL) { - ruleset_error(LOG_ERROR, "Error loading the default veteran system: %s", + ruleset_error(NULL, LOG_ERROR, + "Error loading the default veteran system: %s", msg); ok = FALSE; } @@ -1739,13 +1769,13 @@ static bool load_ruleset_units(struct section_file *file, if (secfile_lookup_int(file, &uc->min_speed, "%s.min_speed", sec_name)) { uc->min_speed *= SINGLE_MOVE; } else { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } if (!secfile_lookup_int(file, &uc->hp_loss_pct, "%s.hp_loss_pct", sec_name)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -1762,12 +1792,10 @@ static bool load_ruleset_units(struct section_file *file, } else if (fc_strcasecmp(hut_str, "Frighten") == 0) { uc->hut_behavior = HUT_FRIGHTEN; } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_class \"%s\":" " Illegal hut behavior \"%s\".", - filename, - uclass_rule_name(uc), - hut_str); + filename, uclass_rule_name(uc), hut_str); ok = FALSE; break; } @@ -1785,11 +1813,11 @@ static bool load_ruleset_units(struct section_file *file, ival = unit_type_flag_id_by_name(rscompat_utype_flag_name_3_0(compat, sval), fc_strcasecmp); if (unit_type_flag_id_is_valid(ival)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_class \"%s\": unit_type flag \"%s\"!", filename, uclass_rule_name(uc), sval); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_class \"%s\": bad flag name \"%s\".", filename, uclass_rule_name(uc), sval); } @@ -1822,7 +1850,8 @@ static bool load_ruleset_units(struct section_file *file, break; } if (u->require_advance == A_NEVER) { - ruleset_error(LOG_ERROR, "%s lacks valid tech_req.", + ruleset_error(NULL, LOG_ERROR, + "%s lacks valid tech_req.", rule_name_get(&u->name)); ok = FALSE; break; @@ -1842,7 +1871,8 @@ static bool load_ruleset_units(struct section_file *file, if (!load_ruleset_veteran(file, sec_name, &u->veteran, msg, sizeof(msg))) { - ruleset_error(LOG_ERROR, "Error loading the veteran system: %s", + ruleset_error(NULL, LOG_ERROR, + "Error loading the veteran system: %s", msg); ok = FALSE; break; @@ -1881,12 +1911,9 @@ static bool load_ruleset_units(struct section_file *file, sval = secfile_lookup_str(file, "%s.class", sec_name); pclass = unit_class_by_rule_name(sval); if (!pclass) { - ruleset_error(LOG_ERROR, - "\"%s\" unit_type \"%s\":" - " bad class \"%s\".", - filename, - utype_rule_name(u), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" unit_type \"%s\": bad class \"%s\".", + filename, utype_rule_name(u), sval); ok = FALSE; break; } @@ -1908,7 +1935,7 @@ static bool load_ruleset_units(struct section_file *file, if ((string = secfile_lookup_str(file, "%s.graphic", sec_name))) { sz_strlcpy(u->graphic_str, string); } else { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -1938,22 +1965,20 @@ static bool load_ruleset_units(struct section_file *file, "%s.fuel", sec_name) || !secfile_lookup_int(file, &u->happy_cost, "%s.uk_happy", sec_name)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } u->move_rate *= SINGLE_MOVE; if (u->firepower <= 0) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\":" " firepower is %d," " but must be at least 1. " " If you want no attack ability," " set the unit's attack strength to 0.", - filename, - utype_rule_name(u), - u->firepower); + filename, utype_rule_name(u), u->firepower); ok = FALSE; break; } @@ -1969,7 +1994,7 @@ static bool load_ruleset_units(struct section_file *file, slist = secfile_lookup_str_vec(file, &nval, "%s.cargo", sec_name); if (u->transport_capacity > 0) { if (nval == 0) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit type \"%s\" " "has transport_cap %d, but no cargo unit classes.", filename, utype_rule_name(u), u->transport_capacity); @@ -1978,7 +2003,7 @@ static bool load_ruleset_units(struct section_file *file, } } else { if (nval > 0) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit type \"%s\" " "has cargo defined, but transport_cap is 0.", filename, utype_rule_name(u)); @@ -1992,12 +2017,10 @@ static bool load_ruleset_units(struct section_file *file, struct unit_class *uclass = unit_class_by_rule_name(slist[j]); if (!uclass) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\":" "has unknown unit class %s as cargo.", - filename, - utype_rule_name(u), - slist[j]); + filename, utype_rule_name(u), slist[j]); ok = FALSE; break; } @@ -2016,12 +2039,10 @@ static bool load_ruleset_units(struct section_file *file, struct unit_class *uclass = unit_class_by_rule_name(slist[j]); if (!uclass) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\":" "has unknown unit class %s as target.", - filename, - utype_rule_name(u), - slist[j]); + filename, utype_rule_name(u), slist[j]); ok = FALSE; break; } @@ -2040,12 +2061,10 @@ static bool load_ruleset_units(struct section_file *file, struct unit_class *uclass = unit_class_by_rule_name(slist[j]); if (!uclass) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\":" "has unknown unit class %s as embarkable.", - filename, - utype_rule_name(u), - slist[j]); + filename, utype_rule_name(u), slist[j]); ok = FALSE; break; } @@ -2064,12 +2083,10 @@ static bool load_ruleset_units(struct section_file *file, struct unit_class *uclass = unit_class_by_rule_name(slist[j]); if (!uclass) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\":" "has unknown unit class %s as disembarkable.", - filename, - utype_rule_name(u), - slist[j]); + filename, utype_rule_name(u), slist[j]); ok = FALSE; break; } @@ -2130,10 +2147,11 @@ static bool load_ruleset_units(struct section_file *file, ok = FALSE; ival = unit_class_flag_id_by_name(sval, fc_strcasecmp); if (unit_class_flag_id_is_valid(ival)) { - ruleset_error(LOG_ERROR, "\"%s\" unit_type \"%s\": unit_class flag!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" unit_type \"%s\": unit_class flag!", filename, utype_rule_name(u)); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unit_type \"%s\": bad flag name \"%s\".", filename, utype_rule_name(u), sval); } @@ -2167,7 +2185,8 @@ static bool load_ruleset_units(struct section_file *file, } ival = unit_role_id_by_name(sval, fc_strcasecmp); if (!unit_role_id_is_valid(ival)) { - ruleset_error(LOG_ERROR, "\"%s\" unit_type \"%s\": bad role name \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" unit_type \"%s\": bad role name \"%s\".", filename, utype_rule_name(u), sval); ok = FALSE; break; @@ -2184,9 +2203,10 @@ static bool load_ruleset_units(struct section_file *file, /* Some more consistency checking: */ unit_type_iterate(u) { if (!valid_advance(u->require_advance)) { - ruleset_error(LOG_ERROR, "\"%s\" unit_type \"%s\": depends on removed tech \"%s\".", - filename, utype_rule_name(u), - advance_rule_name(u->require_advance)); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" unit_type \"%s\": depends on removed tech \"%s\".", + filename, utype_rule_name(u), + advance_rule_name(u->require_advance)); u->require_advance = A_NEVER; ok = FALSE; break; @@ -2228,12 +2248,14 @@ static bool load_building_names(struct section_file *file, /* The names: */ sec = secfile_sections_by_name_prefix(file, BUILDING_SECTION_PREFIX); if (NULL == sec || 0 == (nval = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": No improvements?!?", filename); + ruleset_error(NULL, LOG_ERROR, + "\"%s\": No improvements?!?", filename); ok = FALSE; } else { log_verbose("%d improvement types (including possibly unused)", nval); if (nval > B_LAST) { - ruleset_error(LOG_ERROR, "\"%s\": Too many improvements (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many improvements (%d, max %d)", filename, nval, B_LAST); ok = FALSE; } @@ -2290,7 +2312,8 @@ static bool load_ruleset_buildings(struct section_file *file, item = secfile_lookup_str(file, "%s.genus", sec_name); b->genus = impr_genus_id_by_name(item, fc_strcasecmp); if (!impr_genus_id_is_valid(b->genus)) { - ruleset_error(LOG_ERROR, "\"%s\" improvement \"%s\": couldn't match " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" improvement \"%s\": couldn't match " "genus \"%s\".", filename, improvement_rule_name(b), item); ok = FALSE; @@ -2307,7 +2330,7 @@ static bool load_ruleset_buildings(struct section_file *file, } ival = impr_flag_id_by_name(sval, fc_strcasecmp); if (!impr_flag_id_is_valid(ival)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" improvement \"%s\": bad flag name \"%s\".", filename, improvement_rule_name(b), sval); ok = FALSE; @@ -2343,7 +2366,7 @@ static bool load_ruleset_buildings(struct section_file *file, "%s.upkeep", sec_name) || !secfile_lookup_int(file, &b->sabotage, "%s.sabotage", sec_name)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2404,13 +2427,15 @@ static bool load_terrain_names(struct section_file *file, if (terrain_flag_id_by_name(flag, fc_strcasecmp) != terrain_flag_id_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\": Duplicate terrain flag name '%s'", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Duplicate terrain flag name '%s'", filename, flag); ok = FALSE; break; } if (i > MAX_NUM_USER_TER_FLAGS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many user terrain flags!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many user terrain flags!", filename); ok = FALSE; break; @@ -2437,13 +2462,15 @@ static bool load_terrain_names(struct section_file *file, if (extra_flag_id_by_name(flag, fc_strcasecmp) != extra_flag_id_invalid()) { - ruleset_error(LOG_ERROR, "\"%s\": Duplicate extra flag name '%s'", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Duplicate extra flag name '%s'", filename, flag); ok = FALSE; break; } if (i > MAX_NUM_USER_EXTRA_FLAGS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many user extra flags!", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many user extra flags!", filename); ok = FALSE; break; @@ -2462,12 +2489,14 @@ static bool load_terrain_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, TERRAIN_SECTION_PREFIX); if (NULL == sec || 0 == (nval = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": ruleset doesn't have any terrains.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": ruleset doesn't have any terrains.", filename); ok = FALSE; } else { if (nval > MAX_NUM_TERRAINS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many terrains (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many terrains (%d, max %d)", filename, nval, MAX_NUM_TERRAINS); ok = FALSE; } @@ -2505,7 +2534,8 @@ static bool load_terrain_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, EXTRA_SECTION_PREFIX); nval = (NULL != sec ? section_list_size(sec) : 0); if (nval > MAX_EXTRA_TYPES) { - ruleset_error(LOG_ERROR, "\"%s\": Too many extra types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many extra types (%d, max %d)", filename, nval, MAX_EXTRA_TYPES); ok = FALSE; } @@ -2550,7 +2580,8 @@ static bool load_terrain_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, BASE_SECTION_PREFIX); nval = (NULL != sec ? section_list_size(sec) : 0); if (nval > MAX_BASE_TYPES) { - ruleset_error(LOG_ERROR, "\"%s\": Too many base types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many base types (%d, max %d)", filename, nval, MAX_BASE_TYPES); ok = FALSE; } @@ -2579,13 +2610,13 @@ static bool load_terrain_names(struct section_file *file, base_type_init(pextra, idx); section_strlcpy(&base_sections[idx * MAX_SECTION_LABEL], sec_name); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "No extra definition matching base definition \"%s\"", base_name); ok = FALSE; } } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Base section \"%s\" does not associate base with any extra", sec_name); ok = FALSE; @@ -2602,7 +2633,8 @@ static bool load_terrain_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, ROAD_SECTION_PREFIX); nval = (NULL != sec ? section_list_size(sec) : 0); if (nval > MAX_ROAD_TYPES) { - ruleset_error(LOG_ERROR, "\"%s\": Too many road types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many road types (%d, max %d)", filename, nval, MAX_ROAD_TYPES); ok = FALSE; } @@ -2631,13 +2663,13 @@ static bool load_terrain_names(struct section_file *file, road_type_init(pextra, idx); section_strlcpy(&road_sections[idx * MAX_SECTION_LABEL], sec_name); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "No extra definition matching road definition \"%s\"", road_name); ok = FALSE; } } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Road section \"%s\" does not associate road with any extra", sec_name); ok = FALSE; @@ -2654,7 +2686,8 @@ static bool load_terrain_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, RESOURCE_SECTION_PREFIX); nval = (NULL != sec ? section_list_size(sec) : 0); if (nval > MAX_RESOURCE_TYPES) { - ruleset_error(LOG_ERROR, "\"%s\": Too many resource types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many resource types (%d, max %d)", filename, nval, MAX_RESOURCE_TYPES); ok = FALSE; } @@ -2696,13 +2729,13 @@ static bool load_terrain_names(struct section_file *file, resource_type_init(pextra); section_strlcpy(&resource_sections[idx * MAX_SECTION_LABEL], sec_name); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "No extra definition matching resource definition \"%s\"", resource_name); ok = FALSE; } } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Resource section %s does not list extra this resource belongs to.", sec_name); ok = FALSE; @@ -2755,7 +2788,8 @@ static bool load_ruleset_terrain(struct section_file *file, = secfile_lookup_int_default(file, 3, "parameters.move_fragments"); if (terrain_control.move_fragments < 1) { - ruleset_error(LOG_ERROR, "\"%s\": move_fragments must be at least 1", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": move_fragments must be at least 1", filename); ok = FALSE; } @@ -2764,7 +2798,8 @@ static bool load_ruleset_terrain(struct section_file *file, = secfile_lookup_int_default(file, 1, "parameters.igter_cost"); if (terrain_control.igter_cost < 1) { - ruleset_error(LOG_ERROR, "\"%s\": igter_cost must be at least 1", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": igter_cost must be at least 1", filename); ok = FALSE; } @@ -2803,13 +2838,14 @@ static bool load_ruleset_terrain(struct section_file *file, pterrain->identifier = secfile_lookup_str(file, "%s.identifier", tsection)[0]; if ('\0' == pterrain->identifier) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] identifier missing value.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] identifier missing value.", filename, tsection); ok = FALSE; break; } if (TERRAIN_UNKNOWN_IDENTIFIER == pterrain->identifier) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] cannot use '%c' as an identifier;" " it is reserved for unknown terrain.", filename, tsection, pterrain->identifier); @@ -2818,10 +2854,9 @@ static bool load_ruleset_terrain(struct section_file *file, } for (j = T_FIRST; j < i; j++) { if (pterrain->identifier == terrain_by_number(j)->identifier) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] has the same identifier as [%s].", - filename, - tsection, + filename, tsection, &terrain_sections[j * MAX_SECTION_LABEL]); ok = FALSE; break; @@ -2835,7 +2870,8 @@ static bool load_ruleset_terrain(struct section_file *file, cstr = secfile_lookup_str(file, "%s.class", tsection); pterrain->tclass = terrain_class_by_name(cstr, fc_strcasecmp); if (!terrain_class_is_valid(pterrain->tclass)) { - ruleset_error(LOG_ERROR, "\"%s\": [%s] unknown class \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": [%s] unknown class \"%s\"", filename, tsection, cstr); ok = FALSE; break; @@ -2845,7 +2881,7 @@ static bool load_ruleset_terrain(struct section_file *file, "%s.movement_cost", tsection) || !secfile_lookup_int(file, &pterrain->defense_bonus, "%s.defense_bonus", tsection)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2883,7 +2919,7 @@ static bool load_ruleset_terrain(struct section_file *file, filename, NULL, &ok) || !lookup_time(file, &pterrain->road_time, tsection, "road_time", filename, NULL, &ok)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2897,7 +2933,7 @@ static bool load_ruleset_terrain(struct section_file *file, "%s.irrigation_food_incr", tsection) || !lookup_time(file, &pterrain->irrigation_time, tsection, "irrigation_time", filename, NULL, &ok)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2911,7 +2947,7 @@ static bool load_ruleset_terrain(struct section_file *file, "%s.mining_shield_incr", tsection) || !lookup_time(file, &pterrain->mining_time, tsection, "mining_time", filename, NULL, &ok)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2930,7 +2966,7 @@ static bool load_ruleset_terrain(struct section_file *file, } if (!lookup_time(file, &pterrain->transform_time, tsection, "transform_time", filename, NULL, &ok)) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -2974,7 +3010,8 @@ static bool load_ruleset_terrain(struct section_file *file, = terrain_flag_id_by_name(sval, fc_strcasecmp); if (!terrain_flag_id_is_valid(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] has unknown flag \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] has unknown flag \"%s\".", filename, tsection, sval); ok = FALSE; break; @@ -3005,7 +3042,7 @@ static bool load_ruleset_terrain(struct section_file *file, struct unit_class *class = unit_class_by_rule_name(slist[j]); if (!class) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] is native to unknown unit class \"%s\".", filename, tsection, slist[j]); ok = FALSE; @@ -3024,7 +3061,8 @@ static bool load_ruleset_terrain(struct section_file *file, { fc_assert_ret_val(pterrain->rgb == NULL, FALSE); if (!rgbcolor_load(file, &pterrain->rgb, "%s.color", tsection)) { - ruleset_error(LOG_ERROR, "Missing terrain color definition: %s", + ruleset_error(NULL, LOG_ERROR, + "Missing terrain color definition: %s", secfile_error()); ok = FALSE; break; @@ -3056,15 +3094,15 @@ static bool load_ruleset_terrain(struct section_file *file, catname = secfile_lookup_str(file, "%s.category", section); if (catname == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\" has no category.", - filename, - extra_rule_name(pextra)); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\" has no category.", + filename, extra_rule_name(pextra)); ok = FALSE; break; } pextra->category = extra_category_by_name(catname, fc_strcasecmp); if (!extra_category_is_valid(pextra->category)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" has invalid category \"%s\".", filename, extra_rule_name(pextra), catname); ok = FALSE; @@ -3078,10 +3116,9 @@ static bool load_ruleset_terrain(struct section_file *file, cause = extra_cause_by_name(sval, fc_strcasecmp); if (!extra_cause_is_valid(cause)) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\": unknown cause \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\": unknown cause \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3112,10 +3149,9 @@ static bool load_ruleset_terrain(struct section_file *file, rmcause = extra_rmcause_by_name(sval, fc_strcasecmp); if (!extra_rmcause_is_valid(rmcause)) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\": unknown rmcause \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\": unknown rmcause \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3206,7 +3242,7 @@ static bool load_ruleset_terrain(struct section_file *file, eus_name = secfile_lookup_str_default(file, "Normal", "%s.unit_seen", section); pextra->eus = extra_unit_seen_type_by_name(eus_name, fc_strcasecmp); if (!extra_unit_seen_type_is_valid(pextra->eus)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" has illegal unit_seen value \"%s\".", filename, extra_rule_name(pextra), eus_name); @@ -3231,11 +3267,9 @@ static bool load_ruleset_terrain(struct section_file *file, struct unit_class *uclass = unit_class_by_rule_name(slist[j]); if (uclass == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" is native to unknown unit class \"%s\".", - filename, - extra_rule_name(pextra), - slist[j]); + filename, extra_rule_name(pextra), slist[j]); ok = FALSE; break; } else { @@ -3255,10 +3289,9 @@ static bool load_ruleset_terrain(struct section_file *file, enum extra_flag_id flag = extra_flag_id_by_name(sval, fc_strcasecmp); if (!extra_flag_id_is_valid(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\": unknown flag \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\": unknown flag \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3277,10 +3310,9 @@ static bool load_ruleset_terrain(struct section_file *file, struct extra_type *pextra2 = extra_type_by_rule_name(sval); if (pextra2 == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\": unknown conflict extra \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\": unknown conflict extra \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3302,10 +3334,9 @@ static bool load_ruleset_terrain(struct section_file *file, const struct extra_type *top = extra_type_by_rule_name(sval); if (top == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" extra \"%s\" hidden by unknown extra \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" extra \"%s\" hidden by unknown extra \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3323,7 +3354,8 @@ static bool load_ruleset_terrain(struct section_file *file, vis_req = advance_by_rule_name(vis_req_name); if (vis_req == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" %s: unknown visibility_req %s.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" %s: unknown visibility_req %s.", filename, section, vis_req_name); ok = FALSE; break; @@ -3345,7 +3377,7 @@ static bool load_ruleset_terrain(struct section_file *file, const char *rsection = &resource_sections[i * MAX_SECTION_LABEL]; if (!presource->data.resource) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" has \"Resource\" cause but no " "corresponding [resource_*] section", filename, extra_rule_name(presource)); @@ -3363,13 +3395,14 @@ static bool load_ruleset_terrain(struct section_file *file, secfile_lookup_str(file,"%s.identifier", rsection)); presource->data.resource->id_old_save = identifier[0]; if (RESOURCE_NULL_IDENTIFIER == presource->data.resource->id_old_save) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] identifier missing value.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] identifier missing value.", filename, rsection); ok = FALSE; break; } if (RESOURCE_NONE_IDENTIFIER == presource->data.resource->id_old_save) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] cannot use '%c' as an identifier;" " it is reserved.", filename, rsection, presource->data.resource->id_old_save); @@ -3391,7 +3424,7 @@ static bool load_ruleset_terrain(struct section_file *file, if (pextra != NULL) { if (!is_extra_caused_by(pextra, EC_RESOURCE)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" resource section [%s]: extra \"%s\" does not " "have \"Resource\" in its causes", filename, section, extra_name); @@ -3411,7 +3444,7 @@ static bool load_ruleset_terrain(struct section_file *file, extra_type_by_cause_iterate(EC_RESOURCE, pres2) { if (pres->data.resource->id_old_save == pres2->data.resource->id_old_save && pres != pres2) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" [%s] has the same identifier as [%s].", filename, extra_rule_name(pres), @@ -3437,7 +3470,7 @@ static bool load_ruleset_terrain(struct section_file *file, const char *gui_str; if (!pbase) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" has \"Base\" cause but no " "corresponding [base_*] section", filename, extra_rule_name(pextra)); @@ -3449,10 +3482,9 @@ static bool load_ruleset_terrain(struct section_file *file, gui_str = secfile_lookup_str(file,"%s.gui_type", section); pbase->gui_type = base_gui_type_by_name(gui_str, fc_strcasecmp); if (!base_gui_type_is_valid(pbase->gui_type)) { - ruleset_error(LOG_ERROR, "\"%s\" base \"%s\": unknown gui_type \"%s\".", - filename, - extra_rule_name(pextra), - gui_str); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" base \"%s\": unknown gui_type \"%s\".", + filename, extra_rule_name(pextra), gui_str); ok = FALSE; break; } @@ -3473,19 +3505,17 @@ static bool load_ruleset_terrain(struct section_file *file, enum base_flag_id flag = base_flag_id_by_name(sval, fc_strcasecmp); if (!base_flag_id_is_valid(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" base \"%s\": unknown flag \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" base \"%s\": unknown flag \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else if ((!compat->compat_mode || compat->ver_terrain >= 10) && base_flag_is_retired(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" base \"%s\": retired flag " - "\"%s\". Please update the ruleset.", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" base \"%s\": retired flag " + "\"%s\". Please update the ruleset.", + filename, extra_rule_name(pextra), sval); ok = FALSE; } else { BV_SET(pbase->flags, flag); @@ -3522,7 +3552,7 @@ static bool load_ruleset_terrain(struct section_file *file, struct extra_type *pextra = extra_type_by_rule_name(extra_name); if (!is_extra_caused_by(pextra, EC_BASE)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" base section [%s]: extra \"%s\" does not have " "\"Base\" in its causes", filename, section, extra_name); @@ -3541,7 +3571,7 @@ static bool load_ruleset_terrain(struct section_file *file, struct requirement_vector *reqs; if (!proad) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" extra \"%s\" has \"Road\" cause but no " "corresponding [road_*] section", filename, extra_rule_name(pextra)); @@ -3559,7 +3589,7 @@ static bool load_ruleset_terrain(struct section_file *file, if (!secfile_lookup_int(file, &proad->move_cost, "%s.move_cost", section)) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } @@ -3568,7 +3598,8 @@ static bool load_ruleset_terrain(struct section_file *file, section); proad->move_mode = road_move_mode_by_name(modestr, fc_strcasecmp); if (!road_move_mode_is_valid(proad->move_mode)) { - ruleset_error(LOG_ERROR, "Illegal move_mode \"%s\" for road \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Illegal move_mode \"%s\" for road \"%s\"", modestr, extra_rule_name(pextra)); ok = FALSE; break; @@ -3589,21 +3620,24 @@ static bool load_ruleset_terrain(struct section_file *file, special = secfile_lookup_str_default(file, "None", "%s.compat_special", section); if (!fc_strcasecmp(special, "Road")) { if (compat_road) { - ruleset_error(LOG_ERROR, "Multiple roads marked as compatibility \"Road\""); + ruleset_error(NULL, LOG_ERROR, + "Multiple roads marked as compatibility \"Road\""); ok = FALSE; } compat_road = TRUE; proad->compat = ROCO_ROAD; } else if (!fc_strcasecmp(special, "Railroad")) { if (compat_rail) { - ruleset_error(LOG_ERROR, "Multiple roads marked as compatibility \"Railroad\""); + ruleset_error(NULL, LOG_ERROR, + "Multiple roads marked as compatibility \"Railroad\""); ok = FALSE; } compat_rail = TRUE; proad->compat = ROCO_RAILROAD; } else if (!fc_strcasecmp(special, "River")) { if (compat_river) { - ruleset_error(LOG_ERROR, "Multiple roads marked as compatibility \"River\""); + ruleset_error(NULL, LOG_ERROR, + "Multiple roads marked as compatibility \"River\""); ok = FALSE; } compat_river = TRUE; @@ -3611,7 +3645,8 @@ static bool load_ruleset_terrain(struct section_file *file, } else if (!fc_strcasecmp(special, "None")) { proad->compat = ROCO_NONE; } else { - ruleset_error(LOG_ERROR, "Illegal compatibility special \"%s\" for road %s", + ruleset_error(NULL, LOG_ERROR, + "Illegal compatibility special \"%s\" for road %s", special, extra_rule_name(pextra)); ok = FALSE; } @@ -3632,10 +3667,9 @@ static bool load_ruleset_terrain(struct section_file *file, } if (top == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" road \"%s\" integrates with unknown road \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" road \"%s\" integrates with unknown road \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3655,10 +3689,9 @@ static bool load_ruleset_terrain(struct section_file *file, enum road_flag_id flag = road_flag_id_by_name(sval, fc_strcasecmp); if (!road_flag_id_is_valid(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" road \"%s\": unknown flag \"%s\".", - filename, - extra_rule_name(pextra), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" road \"%s\": unknown flag \"%s\".", + filename, extra_rule_name(pextra), sval); ok = FALSE; break; } else { @@ -3678,7 +3711,7 @@ static bool load_ruleset_terrain(struct section_file *file, struct extra_type *pextra = extra_type_by_rule_name(extra_name); if (!is_extra_caused_by(pextra, EC_ROAD)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" road section [%s]: extra \"%s\" does not have " "\"Road\" in its causes", filename, section, extra_name); @@ -3717,10 +3750,11 @@ static bool load_government_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, GOVERNMENT_SECTION_PREFIX); if (NULL == sec || 0 == (nval = section_list_size(sec))) { - ruleset_error(LOG_ERROR, "\"%s\": No governments?!?", filename); + ruleset_error(NULL, LOG_ERROR, "\"%s\": No governments?!?", filename); ok = FALSE; } else if (nval > G_LAST) { - ruleset_error(LOG_ERROR, "\"%s\": Too many governments (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many governments (%d, max %d)", filename, nval, G_LAST); ok = FALSE; } @@ -3748,7 +3782,8 @@ static bool load_government_names(struct section_file *file, nval = (NULL != sec ? section_list_size(sec) : 0); if (nval > MAX_NUM_MULTIPLIERS) { - ruleset_error(LOG_ERROR, "\"%s\": Too many multipliers (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many multipliers (%d, max %d)", filename, nval, MAX_NUM_MULTIPLIERS); ok = FALSE; @@ -3762,7 +3797,8 @@ static bool load_government_names(struct section_file *file, section_name(section_list_get(sec, multiplier_index(pmul))); if (!ruleset_load_names(&pmul->name, NULL, file, sec_name)) { - ruleset_error(LOG_ERROR, "\"%s\": Cannot load multiplier names", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Cannot load multiplier names", filename); ok = FALSE; break; @@ -3844,14 +3880,16 @@ static bool load_ruleset_governments(struct section_file *file, if (!(male = secfile_lookup_str(file, "%s.ruler_male_title", sec_name)) || !(female = secfile_lookup_str(file, "%s.ruler_female_title", sec_name))) { - ruleset_error(LOG_ERROR, "Lack of default ruler titles for " + ruleset_error(NULL, LOG_ERROR, + "Lack of default ruler titles for " "government \"%s\" (nb %d): %s", government_rule_name(g), government_number(g), secfile_error()); ok = FALSE; break; } else if (NULL == government_ruler_title_new(g, NULL, male, female)) { - ruleset_error(LOG_ERROR, "Lack of default ruler titles for " + ruleset_error(NULL, LOG_ERROR, + "Lack of default ruler titles for " "government \"%s\" (nb %d).", government_rule_name(g), government_number(g)); ok = FALSE; @@ -3869,29 +3907,31 @@ static bool load_ruleset_governments(struct section_file *file, const char *sec_name = section_name(section_list_get(sec, id)); if (!secfile_lookup_int(file, &pmul->start, "%s.start", sec_name)) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } if (!secfile_lookup_int(file, &pmul->stop, "%s.stop", sec_name)) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } if (pmul->stop <= pmul->start) { - ruleset_error(LOG_ERROR, "Multiplier \"%s\" stop (%d) must be greater " + ruleset_error(NULL, LOG_ERROR, + "Multiplier \"%s\" stop (%d) must be greater " "than start (%d)", multiplier_rule_name(pmul), pmul->stop, pmul->start); ok = FALSE; break; } if (!secfile_lookup_int(file, &pmul->step, "%s.step", sec_name)) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } if (((pmul->stop - pmul->start) % pmul->step) != 0) { - ruleset_error(LOG_ERROR, "Multiplier \"%s\" step (%d) does not fit " + ruleset_error(NULL, LOG_ERROR, + "Multiplier \"%s\" step (%d) does not fit " "exactly into interval start-stop (%d to %d)", multiplier_rule_name(pmul), pmul->step, pmul->start, pmul->stop); @@ -3899,19 +3939,21 @@ static bool load_ruleset_governments(struct section_file *file, break; } if (!secfile_lookup_int(file, &pmul->def, "%s.default", sec_name)) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } if (pmul->def < pmul->start || pmul->def > pmul->stop) { - ruleset_error(LOG_ERROR, "Multiplier \"%s\" default (%d) not within " + ruleset_error(NULL, LOG_ERROR, + "Multiplier \"%s\" default (%d) not within " "legal range (%d to %d)", multiplier_rule_name(pmul), pmul->def, pmul->start, pmul->stop); ok = FALSE; break; } if (((pmul->def - pmul->start) % pmul->step) != 0) { - ruleset_error(LOG_ERROR, "Multiplier \"%s\" default (%d) not legal " + ruleset_error(NULL, LOG_ERROR, + "Multiplier \"%s\" default (%d) not legal " "with respect to step size %d", multiplier_rule_name(pmul), pmul->def, pmul->step); ok = FALSE; @@ -3922,7 +3964,8 @@ static bool load_ruleset_governments(struct section_file *file, pmul->factor = secfile_lookup_int_default(file, 100, "%s.factor", sec_name); if (pmul->factor == 0) { - ruleset_error(LOG_ERROR, "Multiplier \"%s\" scaling factor must " + ruleset_error(NULL, LOG_ERROR, + "Multiplier \"%s\" scaling factor must " "not be zero", multiplier_rule_name(pmul)); ok = FALSE; break; @@ -4028,10 +4071,12 @@ static bool load_nation_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, NATION_SECTION_PREFIX); if (NULL == sec) { - ruleset_error(LOG_ERROR, "No available nations in this ruleset!"); + ruleset_error(NULL, LOG_ERROR, + "No available nations in this ruleset!"); ok = FALSE; } else if (section_list_size(sec) > MAX_NUM_NATIONS) { - ruleset_error(LOG_ERROR, "Too many nations (max %d, we have %d)!", + ruleset_error(NULL, LOG_ERROR, + "Too many nations (max %d, we have %d)!", MAX_NUM_NATIONS, section_list_size(sec)); ok = FALSE; } else { @@ -4057,7 +4102,8 @@ static bool load_nation_names(struct section_file *file, pl->translation_domain = fc_malloc(strlen(domain) + 1); strcpy(pl->translation_domain, domain); } else { - ruleset_error(LOG_ERROR, "Unsupported translation domain \"%s\" for %s", + ruleset_error(NULL, LOG_ERROR, + "Unsupported translation domain \"%s\" for %s", domain, sec_name); ok = FALSE; break; @@ -4078,7 +4124,7 @@ static bool load_nation_names(struct section_file *file, * (This check only catches English, not localisations, of course.) */ if (0 == strcmp(Qn_(untranslated_name(&n2->adjective)), Qn_(untranslated_name(&pl->adjective)))) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Two nations defined with the same adjective \"%s\": " "in section \'%s\' and section \'%s\'", Qn_(untranslated_name(&pl->adjective)), @@ -4088,7 +4134,7 @@ static bool load_nation_names(struct section_file *file, rule_name_get(&pl->adjective))) { /* We cannot have the same rule name, as the game needs them to be * distinct. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Two nations defined with the same rule_name \"%s\": " "in section \'%s\' and section \'%s\'", rule_name_get(&pl->adjective), @@ -4097,7 +4143,7 @@ static bool load_nation_names(struct section_file *file, } else if (0 == strcmp(Qn_(untranslated_name(&n2->noun_plural)), Qn_(untranslated_name(&pl->noun_plural)))) { /* We don't want identical English plural names either. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Two nations defined with the same plural name \"%s\": " "in section \'%s\' and section \'%s\'", Qn_(untranslated_name(&pl->noun_plural)), @@ -4122,7 +4168,7 @@ static bool load_nation_names(struct section_file *file, name = secfile_lookup_str(file, "%s.name", section_name(psection)); if (NULL == name) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } @@ -4192,14 +4238,16 @@ static bool load_city_name_list(struct section_file *file, *p++ = '\0'; if (!(end = strchr(p, ')'))) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city name \"%s\" " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city name \"%s\" " "unmatched parenthesis.", secfile_name(file), secfile_str1, secfile_str2, cities[j]); ok = FALSE; } else { for (*end++ = '\0'; '\0' != *end; end++) { if (!fc_isspace(*end)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city name \"%s\" " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city name \"%s\" " "contains characters after last parenthesis.", secfile_name(file), secfile_str1, secfile_str2, cities[j]); @@ -4215,8 +4263,9 @@ static bool load_city_name_list(struct section_file *file, if (check_cityname(city_name)) { /* The ruleset contains a name that is too long. This shouldn't * happen - if it does, the author should get immediate feedback. */ - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city name \"%s\" " - "is too long.", secfile_name(file), + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city name \"%s\" is too long.", + secfile_name(file), secfile_str1, secfile_str2, city_name); ok = FALSE; city_name[MAX_LEN_CITYNAME - 1] = '\0'; @@ -4247,7 +4296,8 @@ static bool load_city_name_list(struct section_file *file, if (game.server.ruledit.allowed_terrains != NULL && !is_on_allowed_list(p, game.server.ruledit.allowed_terrains, atcount)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city \"%s\" " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city \"%s\" " "has terrain hint \"%s\" not in allowed_terrains.", secfile_name(file), secfile_str1, secfile_str2, city_name, p); @@ -4283,7 +4333,8 @@ static bool load_city_name_list(struct section_file *file, if (!is_on_allowed_list(p, game.server.ruledit.allowed_terrains, atcount)) { /* Terrain exists, but not intended for these nations */ - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city \"%s\" " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city \"%s\" " "has terrain hint \"%s\" not in allowed_terrains.", secfile_name(file), secfile_str1, secfile_str2, city_name, p); @@ -4295,7 +4346,8 @@ static bool load_city_name_list(struct section_file *file, if (game.server.ruledit.allowed_terrains == NULL || !is_on_allowed_list(p, game.server.ruledit.allowed_terrains, atcount)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] %s: city \"%s\" " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] %s: city \"%s\" " "has unknown terrain hint \"%s\".", secfile_name(file), secfile_str1, secfile_str2, city_name, p); @@ -4375,7 +4427,8 @@ static bool load_ruleset_nations(struct section_file *file, game.server.default_traits[tr].fixed = diff / 2 + game.server.default_traits[tr].min; } if (game.server.default_traits[tr].max < game.server.default_traits[tr].min) { - ruleset_error(LOG_ERROR, "Default values for trait %s not sane.", + ruleset_error(NULL, LOG_ERROR, + "Default values for trait %s not sane.", trait_name(tr)); ok = FALSE; break; @@ -4439,7 +4492,7 @@ static bool load_ruleset_nations(struct section_file *file, if (sval != NULL) { game.default_government = government_by_rule_name(sval); if (game.default_government == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Tried to set unknown government type \"%s\" as default_government!", sval); ok = FALSE; @@ -4462,7 +4515,7 @@ static bool load_ruleset_nations(struct section_file *file, set_description = secfile_lookup_str_default(file, "", "%s.description", section_name(psection)); if (NULL == set_name || NULL == set_rule_name) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } @@ -4474,7 +4527,7 @@ static bool load_ruleset_nations(struct section_file *file, section_list_destroy(sec); sec = NULL; } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "At least one nation set [" NATION_SET_SECTION_PREFIX "_*] " "must be defined."); ok = FALSE; @@ -4490,7 +4543,7 @@ static bool load_ruleset_nations(struct section_file *file, if (pset != NULL) { default_set = nation_set_number(pset); } else { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Unknown default_nationset \"%s\".", sval); ok = FALSE; } @@ -4524,7 +4577,7 @@ static bool load_ruleset_nations(struct section_file *file, nation_group_set_hidden(pgroup, hidden); if (!secfile_lookup_int(file, &j, "%s.match", section_name(psection))) { - ruleset_error(LOG_ERROR, "Error: %s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "Error: %s", secfile_error()); ok = FALSE; break; } @@ -4574,7 +4627,7 @@ static bool load_ruleset_nations(struct section_file *file, free(vec); } if (nation_set_list_size(pnation->sets) < 1) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s is not a member of any nation set", nation_rule_name(pnation)); ok = FALSE; @@ -4587,7 +4640,8 @@ static bool load_ruleset_nations(struct section_file *file, pconflict = nation_by_rule_name(vec[j]); if (pnation == pconflict) { - ruleset_error(LOG_ERROR, "Nation %s conflicts with itself", + ruleset_error(NULL, LOG_ERROR, + "Nation %s conflicts with itself", nation_rule_name(pnation)); ok = FALSE; break; @@ -4624,8 +4678,8 @@ static bool load_ruleset_nations(struct section_file *file, /* The ruleset contains a name that is too long. This shouldn't * happen - if it does, the author should get immediate feedback */ sz_strlcpy(temp_name, name); - ruleset_error(LOG_ERROR, "Nation %s: leader name \"%s\" " - "is too long.", + ruleset_error(NULL, LOG_ERROR, + "Nation %s: leader name \"%s\" is too long.", nation_rule_name(pnation), name); ok = FALSE; break; @@ -4633,14 +4687,15 @@ static bool load_ruleset_nations(struct section_file *file, sex = secfile_lookup_str(file, "%s.leaders%d.sex", sec_name, j); if (NULL == sex) { - ruleset_error(LOG_ERROR, "Nation %s: leader \"%s\": %s.", + ruleset_error(NULL, LOG_ERROR, "Nation %s: leader \"%s\": %s.", nation_rule_name(pnation), name, secfile_error()); ok = FALSE; break; } else if (0 == fc_strcasecmp("Male", sex)) { is_male = TRUE; } else if (0 != fc_strcasecmp("Female", sex)) { - ruleset_error(LOG_ERROR, "Nation %s: leader \"%s\" has unsupported " + ruleset_error(NULL, LOG_ERROR, + "Nation %s: leader \"%s\" has unsupported " "sex variant \"%s\".", nation_rule_name(pnation), name, sex); ok = FALSE; @@ -4659,12 +4714,13 @@ static bool load_ruleset_nations(struct section_file *file, sec_name, j)) { j++; } - ruleset_error(LOG_ERROR, "Nation %s: Too many leaders; max is %d", + ruleset_error(NULL, LOG_ERROR, + "Nation %s: Too many leaders; max is %d", nation_rule_name(pnation), MAX_NUM_LEADERS); ok = FALSE; break; } else if (0 == j) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s: no leaders; at least one is required.", nation_rule_name(pnation)); ok = FALSE; @@ -4673,7 +4729,7 @@ static bool load_ruleset_nations(struct section_file *file, /* Check if leader name is not already defined in this nation. */ if ((bad_leader = check_leader_names(pnation))) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s: leader \"%s\" defined more than once.", nation_rule_name(pnation), bad_leader); ok = FALSE; @@ -4710,7 +4766,8 @@ static bool load_ruleset_nations(struct section_file *file, } } if (pnation->server.traits[tr].max < pnation->server.traits[tr].min) { - ruleset_error(LOG_ERROR, "%s values for trait %s not sane.", + ruleset_error(NULL, LOG_ERROR, + "%s values for trait %s not sane.", nation_rule_name(pnation), trait_name(tr)); ok = FALSE; break; @@ -4729,7 +4786,7 @@ static bool load_ruleset_nations(struct section_file *file, "%s.barbarian_type", sec_name); pnation->barb_type = barbarian_type_by_name(barb_type, fc_strcasecmp); if (!barbarian_type_is_valid(pnation->barb_type)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s, barbarian_type is invalid (\"%s\")", nation_rule_name(pnation), barb_type); ok = FALSE; @@ -4740,7 +4797,7 @@ static bool load_ruleset_nations(struct section_file *file, && pnation->is_playable) { /* We can't allow players to use barbarian nations, barbarians * may run out of nations */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s marked both barbarian and playable.", nation_rule_name(pnation)); ok = FALSE; @@ -4785,7 +4842,7 @@ static bool load_ruleset_nations(struct section_file *file, game.server.ruledit.ag_count)) { /* Gov exists, but not intended for these nations */ gov = NULL; - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s: government \"%s\" not in allowed_govs.", nation_rule_name(pnation), name); ok = FALSE; @@ -4797,7 +4854,8 @@ static bool load_ruleset_nations(struct section_file *file, || !is_on_allowed_list(name, game.server.ruledit.allowed_govs, game.server.ruledit.ag_count)) { - ruleset_error(LOG_ERROR, "Nation %s: government \"%s\" not found.", + ruleset_error(NULL, LOG_ERROR, + "Nation %s: government \"%s\" not found.", nation_rule_name(pnation), name); ok = FALSE; break; @@ -4808,7 +4866,7 @@ static bool load_ruleset_nations(struct section_file *file, (void) government_ruler_title_new(gov, pnation, male, female); } } else { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -4820,7 +4878,7 @@ static bool load_ruleset_nations(struct section_file *file, /* City styles */ name = secfile_lookup_str(file, "%s.style", sec_name); if (!name) { - ruleset_error(LOG_ERROR, "%s", secfile_error()); + ruleset_error(NULL, LOG_ERROR, "%s", secfile_error()); ok = FALSE; break; } @@ -4830,7 +4888,8 @@ static bool load_ruleset_nations(struct section_file *file, || !is_on_allowed_list(name, game.server.ruledit.allowed_styles, game.server.ruledit.as_count)) { - ruleset_error(LOG_ERROR, "Nation %s: Illegal style \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Nation %s: Illegal style \"%s\"", nation_rule_name(pnation), name); ok = FALSE; break; @@ -4852,7 +4911,8 @@ static bool load_ruleset_nations(struct section_file *file, * entry it will just cause that nation to have an increased * probability of being chosen. */ if (pconflict == pnation) { - ruleset_error(LOG_ERROR, "Nation %s is its own civil war nation", + ruleset_error(NULL, LOG_ERROR, + "Nation %s is its own civil war nation", nation_rule_name(pnation)); ok = FALSE; break; @@ -4908,7 +4968,7 @@ static bool load_ruleset_nations(struct section_file *file, && !is_on_allowed_list(government_rule_name(pnation->init_government), game.server.ruledit.allowed_govs, game.server.ruledit.ag_count)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s: init_government \"%s\" not allowed.", nation_rule_name(pnation), government_rule_name(pnation->init_government)); @@ -4928,7 +4988,7 @@ static bool load_ruleset_nations(struct section_file *file, legend = secfile_lookup_str_default(file, "", "%s.legend", sec_name); pnation->legend = fc_strdup(legend); if (check_strlen(pnation->legend, MAX_LEN_MSG, NULL)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation %s: legend \"%s\" is too long.", nation_rule_name(pnation), pnation->legend); @@ -4986,21 +5046,21 @@ static bool load_ruleset_nations(struct section_file *file, } } nations_iterate_end; if (num_playable < 1) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Nation set \"%s\" has no playable nations. " "At least one required!", nation_set_rule_name(pset)); ok = FALSE; break; } if (barb_land_count == 0 && barb_both_count == 0) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "No land barbarian nation defined in set \"%s\". " "At least one required!", nation_set_rule_name(pset)); ok = FALSE; break; } if (barb_sea_count == 0 && barb_both_count == 0) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "No sea barbarian nation defined in set \"%s\". " "At least one required!", nation_set_rule_name(pset)); ok = FALSE; @@ -5033,7 +5093,8 @@ static bool load_style_names(struct section_file *file, sec = secfile_sections_by_name_prefix(file, STYLE_SECTION_PREFIX); if (NULL == sec) { - ruleset_error(LOG_ERROR, "No available nation styles in this ruleset!"); + ruleset_error(NULL, LOG_ERROR, + "No available nation styles in this ruleset!"); ok = FALSE; } else { game.control.num_styles = section_list_size(sec); @@ -5176,7 +5237,7 @@ static bool load_action_auto_uflag_block(struct section_file *file, if (!protecor_flag) { /* Entity exists but couldn't read it. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": %s: bad unit type flag list.", filename, uflags_path); @@ -5217,7 +5278,7 @@ static bool load_action_auto_actions(struct section_file *file, if (!unit_acts) { /* Entity exists but couldn't read it. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": %s: bad action list", filename, actions_path); @@ -5278,7 +5339,8 @@ static bool load_ruleset_cities(struct section_file *file, /* Specialist options */ sec = secfile_sections_by_name_prefix(file, SPECIALIST_SECTION_PREFIX); if (section_list_size(sec) >= SP_MAX) { - ruleset_error(LOG_ERROR, "\"%s\": Too many specialists (%d, max %d).", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many specialists (%d, max %d).", filename, section_list_size(sec), SP_MAX); ok = FALSE; } @@ -5308,7 +5370,7 @@ static bool load_ruleset_cities(struct section_file *file, tag = rscompat_specialist_gfx_tag_3_0(compat, s); } if (tag == NULL) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": No graphic tag for specialist at %s.", filename, sec_name); ok = FALSE; @@ -5336,7 +5398,7 @@ static bool load_ruleset_cities(struct section_file *file, } if (ok && DEFAULT_SPECIALIST == -1) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": must give a min_size of 0 for at least one " "specialist type.", filename); ok = FALSE; @@ -5366,7 +5428,7 @@ static bool load_ruleset_cities(struct section_file *file, secfile_lookup_int_default(file, 0, "parameters.forced_gold"); if (game.info.forced_science + game.info.forced_luxury + game.info.forced_gold != 100) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": Forced taxes do not add up in ruleset!", filename); ok = FALSE; @@ -5505,15 +5567,17 @@ static bool load_ruleset_effects(struct section_file *file, } } if (type == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] missing effect type.", filename, sec_name); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] missing effect type.", filename, sec_name); ok = FALSE; break; } eff = effect_type_by_name(type, fc_strcasecmp); if (!effect_type_is_valid(eff)) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] lists unknown effect type \"%s\".", - filename, sec_name, type); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] lists unknown effect type \"%s\".", + filename, sec_name, type); ok = FALSE; break; } @@ -5527,7 +5591,8 @@ static bool load_ruleset_effects(struct section_file *file, if (multiplier_name) { pmul = multiplier_by_rule_name(multiplier_name); if (!pmul) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] has unknown multiplier \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] has unknown multiplier \"%s\".", filename, sec_name, multiplier_name); ok = FALSE; break; @@ -5594,14 +5659,16 @@ static int secfile_lookup_int_default_min_max(struct section_file *file, } if (ival < min) { - ruleset_error(LOG_ERROR,"\"%s\" should be in the interval [%d, %d] " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" should be in the interval [%d, %d] " "but is %d; using the minimal value.", fullpath, min, max, ival); ival = min; } if (ival > max) { - ruleset_error(LOG_ERROR,"\"%s\" should be in the interval [%d, %d] " + ruleset_error(NULL, LOG_ERROR, + "\"%s\" should be in the interval [%d, %d] " "but is %d; using the maximal value.", fullpath, min, max, ival); ival = max; @@ -5650,7 +5717,7 @@ static bool load_action_range_max(struct section_file *file, action_id act, && !fc_strcasecmp(custom, RS_ACTION_NO_MAX_DISTANCE)) { max_range = ACTION_DISTANCE_UNLIMITED; } else { - ruleset_error(LOG_ERROR, "Bad %s", entry_name); + ruleset_error(NULL, LOG_ERROR, "Bad %s", entry_name); action_by_number(act)->max_distance = default_value; return FALSE; } @@ -5829,7 +5896,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, } style = gameloss_style_by_name(sval, fc_strcasecmp); if (!gameloss_style_is_valid(style)) { - ruleset_error(LOG_ERROR, "\"%s\": bad value \"%s\" for gameloss_style.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": bad value \"%s\" for gameloss_style.", filename, sval); ok = FALSE; break; @@ -5917,7 +5985,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.granary_num_inis = (int) gni_tmp; if (game.info.granary_num_inis > MAX_GRANARY_INIS) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "Too many granary_food_ini entries (%d, max %d)", game.info.granary_num_inis, MAX_GRANARY_INIS); ok = FALSE; @@ -5987,7 +6055,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.gold_upkeep_style = gold_upkeep_style_by_name(tus_text, fc_strcasecmp); if (!gold_upkeep_style_is_valid(game.info.gold_upkeep_style)) { - ruleset_error(LOG_ERROR, "Unknown gold upkeep style \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Unknown gold upkeep style \"%s\"", tus_text); ok = FALSE; } @@ -6180,7 +6249,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, if (!quiet_actions) { /* Entity exists but couldn't read it. */ - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\": actions.quiet_actions: bad action list", filename); @@ -6214,7 +6283,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, action_text = secfile_lookup_str(file, "%s.action", sec_name); if (action_text == NULL) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] missing action to enable.", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] missing action to enable.", filename, sec_name); ok = FALSE; break; @@ -6222,7 +6292,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, paction = action_by_rule_name(action_text); if (!paction) { - ruleset_error(LOG_ERROR, "\"%s\" [%s] lists unknown action type \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "\"%s\" [%s] lists unknown action type \"%s\".", filename, sec_name, action_text); ok = FALSE; break; @@ -6292,7 +6363,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.tech_cost_style = tech_cost_style_by_name(tus_text, fc_strcasecmp); if (!tech_cost_style_is_valid(game.info.tech_cost_style)) { - ruleset_error(LOG_ERROR, "Unknown tech cost style \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Unknown tech cost style \"%s\"", tus_text); ok = FALSE; } @@ -6302,7 +6374,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.tech_leakage = tech_leakage_style_by_name(tus_text, fc_strcasecmp); if (!tech_leakage_style_is_valid(game.info.tech_leakage)) { - ruleset_error(LOG_ERROR, "Unknown tech leakage \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Unknown tech leakage \"%s\"", tus_text); ok = FALSE; } @@ -6329,7 +6402,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.tech_upkeep_style = tech_upkeep_style_by_name(tus_text, fc_strcasecmp); if (!tech_upkeep_style_is_valid(game.info.tech_upkeep_style)) { - ruleset_error(LOG_ERROR, "Unknown tech upkeep style \"%s\"", + ruleset_error(NULL, LOG_ERROR, + "Unknown tech upkeep style \"%s\"", tus_text); ok = FALSE; } @@ -6345,12 +6419,14 @@ static bool load_ruleset_game(struct section_file *file, bool act, sval = secfile_lookup_str_default(file, NULL, "research.free_tech_method"); if (sval == NULL) { - ruleset_error(LOG_ERROR, "No free_tech_method given"); + ruleset_error(NULL, LOG_ERROR, + "No free_tech_method given"); ok = FALSE; } else { game.info.free_tech_method = free_tech_method_by_name(sval, fc_strcasecmp); if (!free_tech_method_is_valid(game.info.free_tech_method)) { - ruleset_error(LOG_ERROR, "Bad value %s for free_tech_method.", sval); + ruleset_error(NULL, LOG_ERROR, + "Bad value %s for free_tech_method.", sval); ok = FALSE; } } @@ -6381,7 +6457,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, = secfile_lookup_int_default(file, 0, "calendar.fragments"); if (game.calendar.calendar_fragments > MAX_CALENDAR_FRAGMENTS) { - ruleset_error(LOG_ERROR, "Too many calendar fragments. Max is %d", + ruleset_error(NULL, LOG_ERROR, + "Too many calendar fragments. Max is %d", MAX_CALENDAR_FRAGMENTS); ok = FALSE; game.calendar.calendar_fragments = 0; @@ -6429,14 +6506,15 @@ static bool load_ruleset_game(struct section_file *file, bool act, } if (playercolor_count() == 0) { - ruleset_error(LOG_ERROR, "No player colors defined!"); + ruleset_error(NULL, LOG_ERROR, "No player colors defined!"); ok = FALSE; } if (ok) { fc_assert(game.plr_bg_color == NULL); if (!rgbcolor_load(file, &game.plr_bg_color, "playercolors.background")) { - ruleset_error(LOG_ERROR, "No background player color defined! (%s)", + ruleset_error(NULL, LOG_ERROR, + "No background player color defined! (%s)", secfile_error()); ok = FALSE; } @@ -6461,7 +6539,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, if (nval > MAX_DISASTER_TYPES) { int num = nval; /* No "size_t" to printf */ - ruleset_error(LOG_ERROR, "\"%s\": Too many disaster types (%d, max %d)", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Too many disaster types (%d, max %d)", filename, num, MAX_DISASTER_TYPES); section_list_destroy(sec); ok = FALSE; @@ -6479,7 +6558,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, const char *sec_name = section_name(section_list_get(sec, id)); if (!ruleset_load_names(&pdis->name, NULL, file, sec_name)) { - ruleset_error(LOG_ERROR, "\"%s\": Cannot load disaster names", + ruleset_error(NULL, LOG_ERROR, + "\"%s\": Cannot load disaster names", filename); ok = FALSE; break; @@ -6505,11 +6585,9 @@ static bool load_ruleset_game(struct section_file *file, bool act, effect = disaster_effect_id_by_name(dsval, fc_strcasecmp); if (!disaster_effect_id_is_valid(effect)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" disaster \"%s\": unknown effect \"%s\".", - filename, - disaster_rule_name(pdis), - dsval); + filename, disaster_rule_name(pdis), dsval); ok = FALSE; break; } else { @@ -6539,7 +6617,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, pach->type = achievement_type_by_name(typename, fc_strcasecmp); if (!achievement_type_is_valid(pach->type)) { - ruleset_error(LOG_ERROR, "Achievement has unknown type \"%s\".", + ruleset_error(NULL, LOG_ERROR, + "Achievement has unknown type \"%s\".", typename != NULL ? typename : "(NULL)"); ok = FALSE; } @@ -6555,7 +6634,8 @@ static bool load_ruleset_game(struct section_file *file, bool act, msg = secfile_lookup_str_default(file, NULL, "%s.first_msg", sec_name); if (msg == NULL) { - ruleset_error(LOG_ERROR, "Achievement %s has no first msg!", sec_name); + ruleset_error(NULL, LOG_ERROR, + "Achievement %s has no first msg!", sec_name); ok = FALSE; } else { pach->first_msg = fc_strdup(msg); @@ -6566,7 +6646,9 @@ static bool load_ruleset_game(struct section_file *file, bool act, msg = secfile_lookup_str_default(file, NULL, "%s.cons_msg", sec_name); if (msg == NULL) { if (!pach->unique) { - ruleset_error(LOG_ERROR, "Achievement %s has no msg for consecutive gainers!", sec_name); + ruleset_error(NULL, LOG_ERROR, + "Achievement %s has no msg for consecutive gainers!", + sec_name); ok = FALSE; } } else { @@ -6588,7 +6670,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, enum trade_route_type type = trade_route_type_by_name(name); if (type == TRT_LAST) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unknown trade route type \"%s\".", filename, name); ok = FALSE; @@ -6603,7 +6685,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, "trade.settings%d.cancelling", i); set->cancelling = traderoute_cancelling_type_by_name(cancelling); if (set->cancelling == TRI_LAST) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unknown traderoute cancelling type \"%s\".", filename, cancelling); ok = FALSE; @@ -6614,7 +6696,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, set->bonus_type = traderoute_bonus_type_by_name(bonus, fc_strcasecmp); if (!traderoute_bonus_type_is_valid(set->bonus_type)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" unknown traderoute bonus type \"%s\".", filename, bonus); ok = FALSE; @@ -6631,7 +6713,7 @@ static bool load_ruleset_game(struct section_file *file, bool act, game.info.goods_selection = goods_selection_method_by_name(str, fc_strcasecmp); if (!goods_selection_method_is_valid(game.info.goods_selection)) { - ruleset_error(LOG_ERROR, + ruleset_error(NULL, LOG_ERROR, "\"%s\" goods selection method \"%s\" unknown.", filename, str); ok = FALSE; @@ -6673,10 +6755,9 @@ static bool load_ruleset_game(struct section_file *file, bool act, sval = slist[j]; flag = goods_flag_id_by_name(sval, fc_strcasecmp); if (!goods_flag_id_is_valid(flag)) { - ruleset_error(LOG_ERROR, "\"%s\" good \"%s\": unknown flag \"%s\".", - filename, - goods_rule_name(pgood), - sval); + ruleset_error(NULL, LOG_ERROR, + "\"%s\" good \"%s\": unknown flag \"%s\".", + filename, goods_rule_name(pgood), sval); ok = FALSE; break; } else { @@ -8139,7 +8220,8 @@ bool reload_rulesets_settings(void) file = openload_ruleset_file("game", game.server.rulesetdir); if (file == NULL) { - ruleset_error(LOG_ERROR, "Could not load game.ruleset:\n%s", + ruleset_error(NULL, LOG_ERROR, + "Could not load game.ruleset:\n%s", secfile_error()); ok = FALSE; } diff --git a/server/ruleset.h b/server/ruleset.h index 06a389c9b4..b02d98eda0 100644 --- a/server/ruleset.h +++ b/server/ruleset.h @@ -46,16 +46,17 @@ void send_rulesets(struct conn_list *dest); void rulesets_deinit(void); -void ruleset_error_real(const char *file, const char *function, +void ruleset_error_real(rs_conversion_logger logger, + const char *file, const char *function, int line, enum log_level level, const char *format, ...) - fc__attribute((__format__ (__printf__, 5, 6))); + fc__attribute((__format__ (__printf__, 6, 7))); -#define ruleset_error(level, format, ...) \ - if (log_do_output_for_level(level)) { \ - ruleset_error_real(__FILE__, __FUNCTION__, __FC_LINE__, \ +#define ruleset_error(logger, level, format, ...) \ + do { \ + ruleset_error_real(logger, __FILE__, __FUNCTION__, __FC_LINE__, \ level, format, ## __VA_ARGS__); \ - } + } while (FALSE); char *get_script_buffer(void); -- 2.35.1