diff --git a/src/actions/unit_creator.cpp b/src/actions/unit_creator.cpp index d4dcc87a0d28..87694cd04b35 100644 --- a/src/actions/unit_creator.cpp +++ b/src/actions/unit_creator.cpp @@ -130,7 +130,7 @@ map_location unit_creator::find_location(const config &cfg, const unit* pass_che loc = start_pos_; } if(place == "leader_passable") { - deprecated_message("placement=leader_passable", 2, {1, 15, 0}, "Please use placement=leader and passable=yes instead"); + deprecated_message("placement=leader_passable", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Please use placement=leader and passable=yes instead"); pass = true; } } @@ -144,10 +144,10 @@ map_location unit_creator::find_location(const config &cfg, const unit* pass_che loc = map_location(cfg, resources::gamedata); } if(place == "map_passable") { - deprecated_message("placement=map_passable", 2, {1, 15, 0}, "Please use placement=map and passable=yes instead"); + deprecated_message("placement=map_passable", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Please use placement=map and passable=yes instead"); pass = true; } else if(place == "map_overwrite") { - deprecated_message("placement=map_overwrite", 2, {1, 15, 0}, "Please use placement=map and overwrite=yes instead"); + deprecated_message("placement=map_overwrite", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Please use placement=map and overwrite=yes instead"); vacant = false; } } diff --git a/src/ai/lua/core.cpp b/src/ai/lua/core.cpp index 363d9b682a6a..6d3d7a745741 100644 --- a/src/ai/lua/core.cpp +++ b/src/ai/lua/core.cpp @@ -390,7 +390,7 @@ static int cfun_ai_get_targets(lua_State *L) // (and the things so deprecated) OR add a version parameter to the macro. // Also note that the name MUST be a string literal. #define DEPRECATED_ASPECT_MESSAGE(name) \ - deprecated_message("ai.get_" name, 2, {1, 15, 0}, "Use ai.aspects." name " instead") + deprecated_message("ai.get_" name, DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use ai.aspects." name " instead") // Aspect section static int cfun_ai_get_aggression(lua_State *L) diff --git a/src/config.cpp b/src/config.cpp index c2f0d6cf9b4d..43cdf050cb1c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -725,7 +725,7 @@ const config::attribute_value& config::get_old_attribute( if(!in_tag.empty()) { const std::string what = "[" + in_tag + "]" + old_key + "="; const std::string msg = "Use " + key + "= instead."; - deprecated_message(what, 1, "", msg); + deprecated_message(what, DEP_LEVEL::INDEFINITE, "", msg); lg::wml_error() << msg; } diff --git a/src/deprecation.cpp b/src/deprecation.cpp index a30f106b0ee4..1ae70f53a3b8 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -28,14 +28,16 @@ // and so on and so on. static lg::log_domain log_deprecate("deprecation", -1); -std::string deprecated_message(const std::string& elem_name, int level, const version_info& version, const std::string& detail) { +std::string deprecated_message(const std::string& elem_name, DEP_LEVEL level, const version_info& version, const std::string& detail) { utils::string_map msg_params = {{"elem", elem_name}}; lg::logger* log_ptr = nullptr; std::string message; - if(level == 1) { + switch(level) { + case DEP_LEVEL::INDEFINITE: log_ptr = &lg::info(); message = VGETTEXT("$elem has been deprecated indefinitely.", msg_params); - } else if(level == 2) { + break; + case DEP_LEVEL::PREEMPTIVE: log_ptr = &lg::warn(); if(game_config::wesnoth_version < version) { msg_params["version"] = version.str(); @@ -43,15 +45,18 @@ std::string deprecated_message(const std::string& elem_name, int level, const ve } else { message = VGETTEXT("$elem has been deprecated and may be removed at any time.", msg_params); } - } else if(level == 3) { + break; + case DEP_LEVEL::FOR_REMOVAL: log_ptr = &lg::err(); msg_params["version"] = version.str(); message = VGETTEXT("$elem has been deprecated and will be removed in the next version ($version).", msg_params); - } else if(level == 4) { + break; + case DEP_LEVEL::REMOVED: log_ptr = &lg::err(); message = VGETTEXT("$elem has been deprecated and removed.", msg_params); - } else { - utils::string_map err_params = {{"level", std::to_string(level)}}; + break; + default: // Not impossible, in case level was given an invalid value from a cast. + utils::string_map err_params = {{"level", std::to_string(int(level))}}; // Note: This message is duplicated in data/lua/core.lua // Any changes should be mirrorred there. std::string msg = VGETTEXT("Invalid deprecation level $level (should be 1-4)", err_params); diff --git a/src/deprecation.hpp b/src/deprecation.hpp index a52a7c82cb97..afed12f267bc 100644 --- a/src/deprecation.hpp +++ b/src/deprecation.hpp @@ -11,10 +11,14 @@ See the COPYING file for more details. */ +#pragma once + #include +enum class DEP_LEVEL {INDEFINITE = 1, PREEMPTIVE, FOR_REMOVAL, REMOVED}; + // Note: When using version (for level 2 or 3 deprecation), specify the first version // in which the feature could be removed... NOT the version at which it was deprecated. // For level 1 or 4 deprecation, it's fine to just pass an empty string, as the parameter will not be used. // It returns the final translated deprecation message, in case you want to output it elsewhere as well. -std::string deprecated_message(const std::string& elem_name, int level, const class version_info& version, const std::string& detail = ""); +std::string deprecated_message(const std::string& elem_name, DEP_LEVEL level, const class version_info& version, const std::string& detail = ""); diff --git a/src/game_events/menu_item.cpp b/src/game_events/menu_item.cpp index 16747cc1e1b0..00d66c2b7471 100644 --- a/src/game_events/menu_item.cpp +++ b/src/game_events/menu_item.cpp @@ -82,7 +82,7 @@ wml_menu_item::wml_menu_item(const std::string& id, const config& cfg) , is_synced_(cfg["synced"].to_bool(true)) { if(cfg.has_attribute("needs_select")) { - deprecated_message("needs_select", 1, {1, 15, 0}); + deprecated_message("needs_select", DEP_LEVEL::INDEFINITE, {1, 15, 0}); } gui2::legacy_menu_item parsed(cfg["description"].str(), "Multiple columns in [set_menu_item] are no longer supported; the image is specified by image=."); if(parsed.contained_markup()) { @@ -287,7 +287,7 @@ void wml_menu_item::update(const vconfig& vcfg) } if(vcfg.has_attribute("needs_select")) { - deprecated_message("needs_select", 1, {1, 15, 0}); + deprecated_message("needs_select", DEP_LEVEL::INDEFINITE, {1, 15, 0}); needs_select_ = vcfg["needs_select"].to_bool(); } diff --git a/src/gui/auxiliary/old_markup.cpp b/src/gui/auxiliary/old_markup.cpp index 35ccb64ffbe4..b870456edbc3 100644 --- a/src/gui/auxiliary/old_markup.cpp +++ b/src/gui/auxiliary/old_markup.cpp @@ -68,7 +68,7 @@ legacy_menu_item::legacy_menu_item(const std::string& str, const std::string dep } if(contained_markup_) { - deprecated_message("Legacy DescriptionWML markup (&img=col1=col2)", 3, {1, 15, 0}, deprecation_msg); + deprecated_message("Legacy DescriptionWML markup (&img=col1=col2)", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, deprecation_msg); } } } diff --git a/src/gui/dialogs/campaign_difficulty.cpp b/src/gui/dialogs/campaign_difficulty.cpp index 511916e36613..b4104a7f1636 100644 --- a/src/gui/dialogs/campaign_difficulty.cpp +++ b/src/gui/dialogs/campaign_difficulty.cpp @@ -82,9 +82,9 @@ config generate_difficulty_config(const config& source) // Convert legacy format to new-style config if latter not present if(result.empty() && source.has_attribute("difficulties")) { - deprecated_message("[campaign]difficulties", 3, {1, 15, 0}, "Use [difficulty] instead."); + deprecated_message("[campaign]difficulties", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use [difficulty] instead."); if(source.has_attribute("difficulty_descriptions")) { - deprecated_message("[campaign]difficulty_descriptions", 3, {1, 15, 0}, "Use [difficulty] instead."); + deprecated_message("[campaign]difficulty_descriptions", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use [difficulty] instead."); } std::vector difficulty_list = utils::split(source["difficulties"]); diff --git a/src/gui/dialogs/multiplayer/mp_options_helper.cpp b/src/gui/dialogs/multiplayer/mp_options_helper.cpp index f443fee38891..24e1c631e40f 100644 --- a/src/gui/dialogs/multiplayer/mp_options_helper.cpp +++ b/src/gui/dialogs/multiplayer/mp_options_helper.cpp @@ -260,7 +260,7 @@ void mp_options_helper::display_custom_options(const std::string& type, int node } else if(opt.key == "choice" || opt.key == "combo") { if(opt.key == "combo") { - deprecated_message("combo", 3, {1, 15, 0}, "Use [choice] instead."); + deprecated_message("combo", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use [choice] instead."); } if(!option_cfg.has_child("item")) { diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 56674692190b..8a6b88f5c051 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -850,7 +850,7 @@ int game_lua_kernel::intf_set_end_campaign_text(lua_State *L) int game_lua_kernel::intf_set_next_scenario(lua_State *L) { - deprecated_message("wesnoth.set_next_scenario", 1, ""); + deprecated_message("wesnoth.set_next_scenario", DEP_LEVEL::INDEFINITE, ""); gamedata().set_next_scenario(luaL_checkstring(L, 1)); return 0; } @@ -2091,7 +2091,7 @@ int game_lua_kernel::intf_put_unit(lua_State *L) if (!map().on_board(loc)) return luaL_argerror(L, 1, "invalid location"); } else if (unit_arg != 1) { - deprecated_message("wesnoth.put_unit(x, y, unit)", 3, {1, 15, 0}, "Use wesnoth.put_unit(unit, x, y) or unit:to_map(x, y) instead."); + deprecated_message("wesnoth.put_unit(x, y, unit)", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use wesnoth.put_unit(unit, x, y) or unit:to_map(x, y) instead."); } put_unit_helper(loc); u.put_map(loc); @@ -2105,14 +2105,14 @@ int game_lua_kernel::intf_put_unit(lua_State *L) if (!map().on_board(loc)) return luaL_argerror(L, 2, "invalid location"); } else if (unit_arg != 1) { - deprecated_message("wesnoth.put_unit(x, y, unit)", 3, {1, 15, 0}, "Use wesnoth.put_unit(unit, x, y) or unit:to_map(x, y) instead."); + deprecated_message("wesnoth.put_unit(x, y, unit)", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use wesnoth.put_unit(unit, x, y) or unit:to_map(x, y) instead."); } unit_ptr u(new unit(cfg, true, vcfg)); put_unit_helper(loc); u->set_location(loc); units().insert(u); } else { - deprecated_message("wesnoth.put_unit(x, y)", 3, {1, 15, 0}, "Use wesnoth.erase_unit(x, y) or unit:erase() instead."); + deprecated_message("wesnoth.put_unit(x, y)", DEP_LEVEL::FOR_REMOVAL, {1, 15, 0}, "Use wesnoth.erase_unit(x, y) or unit:erase() instead."); put_unit_helper(loc); return 0; // Don't fire event when unit is only erase } @@ -2556,7 +2556,7 @@ int game_lua_kernel::intf_simulate_combat(lua_State *L) */ static int intf_set_music(lua_State *L) { - deprecated_message("wesnoth.set_music", 1, "", "Use the wesnoth.playlist table instead!"); + deprecated_message("wesnoth.set_music", DEP_LEVEL::INDEFINITE, "", "Use the wesnoth.playlist table instead!"); if (lua_isnoneornil(L, 1)) { sound::commit_music_changes(); return 0; @@ -2629,7 +2629,7 @@ int game_lua_kernel::intf_scroll_to_tile(lua_State *L) int game_lua_kernel::intf_select_hex(lua_State *L) { events::command_disabler command_disabler; - deprecated_message("wesnoth.select_hex", 2, {1, 15, 0}, "Use wesnoth.select_unit and/or wesnoth.highlight_hex instead."); + deprecated_message("wesnoth.select_hex", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use wesnoth.select_unit and/or wesnoth.highlight_hex instead."); // Need this because check_location may change the stack // By doing this now, we ensure that it won't do so when @@ -3124,7 +3124,7 @@ static int intf_add_modification(lua_State *L) std::string sm = m; if (sm == "advance") { // Maintain backwards compatibility sm = "advancement"; - deprecated_message("\"advance\" modification type", 2, {1, 15, 0}, "Use \"advancement\" instead."); + deprecated_message("\"advance\" modification type", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use \"advancement\" instead."); } if (sm != "advancement" && sm != "object" && sm != "trait") { return luaL_argerror(L, 2, "unknown modification type"); @@ -3380,7 +3380,7 @@ static int intf_modify_ai_old(lua_State *L) config cfg; luaW_toconfig(L, 1, cfg); int side = cfg["side"]; - deprecated_message("wesnoth.modify_ai", 2, {1, 15, 0}, "Use wesnoth.add_ai_component, wesnoth.delete_ai_component, or wesnoth.change_ai_component."); + deprecated_message("wesnoth.modify_ai", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use wesnoth.add_ai_component, wesnoth.delete_ai_component, or wesnoth.change_ai_component."); ai::manager::get_singleton().modify_active_ai_for_side(side, cfg); return 0; } diff --git a/src/scripting/lua_kernel_base.cpp b/src/scripting/lua_kernel_base.cpp index e095389546c6..7898f81a88d9 100644 --- a/src/scripting/lua_kernel_base.cpp +++ b/src/scripting/lua_kernel_base.cpp @@ -284,12 +284,13 @@ static int intf_log(lua_State *L) { */ static int intf_deprecated_message(lua_State* L) { const std::string elem = luaL_checkstring(L, 1); - const int level = luaL_checkinteger(L, 2); + // This could produce an invalid deprecation level, but that possibility is handled in deprecated_message() + const DEP_LEVEL level = DEP_LEVEL(luaL_checkinteger(L, 2)); const std::string ver_str = lua_isnoneornil(L, 3) ? "" : luaL_checkstring(L, 3); const std::string detail = luaW_checktstring(L, 4); const version_info ver = ver_str.empty() ? game_config::version : ver_str; const std::string msg = deprecated_message(elem, level, ver, detail); - if(level < 1 || level >= 4) { + if(level < DEP_LEVEL::INDEFINITE || level >= DEP_LEVEL::REMOVED) { // Invalid deprecation level or level 4 deprecation should raise an interpreter error lua_push(L, msg); return lua_error(L); diff --git a/src/serialization/preprocessor.cpp b/src/serialization/preprocessor.cpp index 344d73649ae2..8c282bc184aa 100644 --- a/src/serialization/preprocessor.cpp +++ b/src/serialization/preprocessor.cpp @@ -1154,7 +1154,7 @@ bool preprocessor_data::get_chunk() std::string symbol = items.front(); items.erase(items.begin()); int found_arg = 0, found_enddef = 0, found_deprecate = 0; - int deprecation_level = -1; + boost::optional deprecation_level; std::string buffer, deprecation_detail; version_info deprecation_version = game_config::wesnoth_version; for(;;) { @@ -1217,12 +1217,18 @@ bool preprocessor_data::get_chunk() buffer.erase(buffer.end() - 11, buffer.end()); skip_spaces(); try { - deprecation_level = std::max(deprecation_level, std::stoi(read_word())); + DEP_LEVEL level = DEP_LEVEL(std::stoi(read_word())); + if(deprecation_level) { + deprecation_level = std::max(*deprecation_level, level); + } else { + deprecation_level = level; + } } catch(std::invalid_argument&) { - deprecation_level = 0; + // Meh, fall back to default of PREEMPTIVE... + deprecation_level = DEP_LEVEL::PREEMPTIVE; } deprecation_version = game_config::wesnoth_version; - if(deprecation_level == 2 || deprecation_level == 3) { + if(deprecation_level == DEP_LEVEL::PREEMPTIVE || deprecation_level == DEP_LEVEL::FOR_REMOVAL) { skip_spaces(); deprecation_version = std::max(deprecation_version, version_info(read_word())); } @@ -1272,7 +1278,7 @@ bool preprocessor_data::get_chunk() buffer.erase(buffer.end() - 7, buffer.end()); (*parent_.defines_)[symbol] = preproc_define(buffer, items, optargs, parent_.textdomain_, linenum, parent_.location_, - deprecation_detail, deprecation_level, deprecation_version); + deprecation_detail, *deprecation_level, deprecation_version); LOG_PREPROC << "defining macro " << symbol << " (location " << get_location(parent_.location_) << ")\n"; } @@ -1397,12 +1403,14 @@ bool preprocessor_data::get_chunk() } else if(command == "deprecated") { // The current file is deprecated, so print a message skip_spaces(); - int level = 0; + DEP_LEVEL level = DEP_LEVEL::PREEMPTIVE; try { - level = std::stoi(read_word()); - } catch(std::invalid_argument&) {} + level = DEP_LEVEL(std::stoi(read_word())); + } catch(std::invalid_argument&) { + // Meh, just fall back to the default of PREEMPTIVE... + } version_info version = game_config::wesnoth_version; - if(level == 2 || level == 3) { + if(level == DEP_LEVEL::PREEMPTIVE || level == DEP_LEVEL::FOR_REMOVAL) { skip_spaces(); version = version_info(read_word()); } @@ -1488,7 +1496,7 @@ bool preprocessor_data::get_chunk() const std::string& dir = filesystem::directory_name(val.location.substr(0, val.location.find(' '))); if(val.is_deprecated()) { - deprecated_message(symbol, val.deprecation_level, val.deprecation_version, val.deprecation_message); + deprecated_message(symbol, *val.deprecation_level, val.deprecation_version, val.deprecation_message); } for(size_t i = 0; i < nb_arg; ++i) { diff --git a/src/serialization/preprocessor.hpp b/src/serialization/preprocessor.hpp index 9ae8c96780d0..35baee8234af 100644 --- a/src/serialization/preprocessor.hpp +++ b/src/serialization/preprocessor.hpp @@ -21,9 +21,11 @@ #include #include #include +#include #include "exceptions.hpp" #include "version.hpp" +#include "deprecation.hpp" class config_writer; class config; @@ -59,7 +61,7 @@ struct preproc_define int line, const std::string& loc, const std::string& dep_msg, - int dep_lvl, const version_info& dep_ver) + DEP_LEVEL dep_lvl, const version_info& dep_ver) : value(val) , arguments(args) , optional_arguments(optargs) @@ -86,12 +88,12 @@ struct preproc_define std::string deprecation_message; - int deprecation_level = -1; + boost::optional deprecation_level; version_info deprecation_version; bool is_deprecated() const { - return deprecation_level > 0; + return deprecation_level != boost::none; } void write(config_writer&, const std::string&) const; diff --git a/src/storyscreen/parser.cpp b/src/storyscreen/parser.cpp index c0e7936f1c33..f7937496de93 100644 --- a/src/storyscreen/parser.cpp +++ b/src/storyscreen/parser.cpp @@ -105,7 +105,8 @@ void story_parser::resolve_wml(const vconfig& cfg) // [deprecated_message] else if(key == "deprecated_message") { // Won't appear until the scenario start event finishes. - deprecated_message(node["what"], node["level"], node["version"].str(), node["message"]); + DEP_LEVEL level = DEP_LEVEL(node["level"].to_int(2)); + deprecated_message(node["what"], level, node["version"].str(), node["message"]); } // [wml_message] else if(key == "wml_message") { diff --git a/src/units/abilities.cpp b/src/units/abilities.cpp index 05f47638dfba..886b4881b26a 100644 --- a/src/units/abilities.cpp +++ b/src/units/abilities.cpp @@ -1055,7 +1055,7 @@ effect::effect(const unit_ability_list& list, int def, bool backstab) : const std::string& effect_id = cfg[cfg["id"].empty() ? "name" : "id"]; if (!cfg["backstab"].blank()) { - deprecated_message("backstab= in weapon specials", 2, {1, 15, 0}, "Use [filter_adjacent] instead."); + deprecated_message("backstab= in weapon specials", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use [filter_adjacent] instead."); } if (!backstab && cfg["backstab"].to_bool()) diff --git a/src/units/unit.cpp b/src/units/unit.cpp index 74a8ed80d12d..74e297b3202d 100644 --- a/src/units/unit.cpp +++ b/src/units/unit.cpp @@ -2344,7 +2344,7 @@ void unit::apply_modifications() for(const auto& mod : ModificationTypes) { if(mod == "advance" && modifications_.has_child(mod)) { - deprecated_message("[advance]", 2, {1, 15, 0}, "Use [advancement] instead."); + deprecated_message("[advance]", DEP_LEVEL::PREEMPTIVE, {1, 15, 0}, "Use [advancement] instead."); } for(const config& m : modifications_.child_range(mod)) {