diff --git a/run_wml_tests b/run_wml_tests index 3ce314f658e..8c2777697ae 100755 --- a/run_wml_tests +++ b/run_wml_tests @@ -24,10 +24,13 @@ class UnitTestResult(enum.Enum): TIMEOUT = 2 FAIL_LOADING_REPLAY = 3 FAIL_PLAYING_REPLAY = 4 - FAIL_BROKE_STRICT = 5 FAIL_WML_EXCEPTION = 6 FAIL_BY_DEFEAT = 7 PASS_BY_VICTORY = 8 + BROKE_STRICT_TEST_PASS = 9 + BROKE_STRICT_TEST_FAIL = 10 + BROKE_STRICT_TEST_FAIL_BY_DEFEAT = 11 + BROKE_STRICT_TEST_PASS_BY_VICTORY = 12 def __str__(self): return str(self.value) + ' ' + self.name @@ -188,7 +191,12 @@ class WesnothRunner: if self.verbose >= Verbosity.NAMES_OF_TESTS_RUN: print('Skipping test', test_list[0].name, 'because timeout is disabled') return - if expected_result == UnitTestResult.FAIL_BROKE_STRICT and not options.strict_mode: + if ( + expected_result == UnitTestResult.BROKE_STRICT_TEST_PASS or + expected_result == UnitTestResult.BROKE_STRICT_TEST_FAIL or + expected_result == UnitTestResult.BROKE_STRICT_TEST_FAIL_BY_DEFEAT or + expected_result == UnitTestResult.BROKE_STRICT_TEST_PASS_BY_VICTORY + ) and not options.strict_mode: test_summary.skip_test(test_list) if self.verbose >= Verbosity.NAMES_OF_TESTS_RUN: print('Skipping test', test_list[0].name, 'because strict mode is disabled') diff --git a/src/ai/configuration.cpp b/src/ai/configuration.cpp index 1830edf2ef1..f29fd4fedcd 100644 --- a/src/ai/configuration.cpp +++ b/src/ai/configuration.cpp @@ -37,6 +37,9 @@ static lg::log_domain log_ai_configuration("ai/config"); #define WRN_AI_CONFIGURATION LOG_STREAM(warn, log_ai_configuration) #define ERR_AI_CONFIGURATION LOG_STREAM(err, log_ai_configuration) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + void configuration::init(const game_config_view &game_config) { ai_configurations_.clear(); @@ -292,7 +295,8 @@ void configuration::expand_simplified_aspects(side_number side, config &cfg) { algorithm = aiparam["ai_algorithm"].str(); base_config = get_ai_config_for(algorithm); } else if(algorithm != aiparam["ai_algorithm"]) { - lg::wml_error() << "side " << side << " has two [ai] tags with contradictory ai_algorithm - the first one will take precedence.\n"; + lg::log_to_chat() << "side " << side << " has two [ai] tags with contradictory ai_algorithm - the first one will take precedence.\n"; + ERR_WML << "side " << side << " has two [ai] tags with contradictory ai_algorithm - the first one will take precedence."; } } std::deque> facet_configs; diff --git a/src/ai/default/recruitment.cpp b/src/ai/default/recruitment.cpp index 194c52cd526..2ee78dbb012 100644 --- a/src/ai/default/recruitment.cpp +++ b/src/ai/default/recruitment.cpp @@ -49,6 +49,9 @@ static lg::log_domain log_ai_recruitment("ai/recruitment"); #define LOG_AI_RECRUITMENT LOG_STREAM(info, log_ai_recruitment) #define ERR_AI_RECRUITMENT LOG_STREAM(err, log_ai_recruitment) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace ai { namespace default_recruitment { @@ -246,7 +249,8 @@ void recruitment::execute() { // Add team recruits. for (const std::string& recruit : current_team().recruits()) { if (!unit_types.find(recruit)) { - lg::wml_error() << "Unit-type \"" << recruit << "\" doesn't exist.\n"; + lg::log_to_chat() << "Unit-type \"" << recruit << "\" doesn't exist.\n"; + ERR_WML << "Unit-type \"" << recruit << "\" doesn't exist."; } data.recruits.insert(recruit); data.scores[recruit] = 0.0; @@ -256,7 +260,8 @@ void recruitment::execute() { // Add extra recruits. for (const std::string& recruit : leader->recruits()) { if (!unit_types.find(recruit)) { - lg::wml_error() << "Unit-type \"" << recruit << "\" doesn't exist.\n"; + lg::log_to_chat() << "Unit-type \"" << recruit << "\" doesn't exist.\n"; + ERR_WML << "Unit-type \"" << recruit << "\" doesn't exist."; } data.recruits.insert(recruit); data.scores[recruit] = 0.0; diff --git a/src/config.cpp b/src/config.cpp index 145dc83f897..4548f1fea13 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -38,6 +38,9 @@ static lg::log_domain log_config("config"); #define ERR_CF LOG_STREAM(err, log_config) #define DBG_CF LOG_STREAM(debug, log_config) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace { // std::map::operator[] does not support heterogeneous lookup so we need this to work around. @@ -217,7 +220,8 @@ bool config::has_old_attribute(config_key_type key, const std::string& old_key, return true; } else if(values_.find(old_key) != values_.end()) { if(!msg.empty()) { - lg::wml_error() << msg; + lg::log_to_chat() << msg << '\n'; + ERR_WML << msg; } return true; @@ -799,7 +803,8 @@ const config::attribute_value& config::get_old_attribute( const std::string what = formatter() << "[" << in_tag << "]" << old_key << "="; const std::string msg = formatter() << "Use " << key << "= instead."; deprecated_message(what, DEP_LEVEL::INDEFINITE, "", msg); - lg::wml_error() << msg; + lg::log_to_chat() << msg << '\n'; + ERR_WML << msg; } return i->second; diff --git a/src/deprecation.cpp b/src/deprecation.cpp index 8091e2a7456..a5401c11c1d 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -78,10 +78,9 @@ std::string deprecated_message( if(log_ptr && !log_ptr->dont_log(log_deprecate)) { const lg::logger& out_log = *log_ptr; FORCE_LOG_TO(out_log, log_deprecate) << message << '\n'; - - // show deprecation warnings if enabled or if this is a development (odd numbered) release - if(preferences::get("show_deprecation", false) || game_config::wesnoth_version.is_dev_version()) { - lg::wml_error() << message << '\n'; + // whether to show the error in the ingame chat area + if(preferences::get("show_deprecation", game_config::wesnoth_version.is_dev_version())) { + lg::log_to_chat() << message << '\n'; } } diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index 8979d22fb87..053b77b378f 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -613,7 +613,8 @@ WML_HANDLER_FUNCTION(replace_map,, cfg) } } catch(const incorrect_map_format_error&) { const std::string log_map_name = cfg["map"].empty() ? cfg["map_file"] : std::string("from inline data"); - lg::wml_error() << "replace_map: Unable to load map " << log_map_name << std::endl; + lg::log_to_chat() << "replace_map: Unable to load map " << log_map_name << '\n'; + ERR_WML << "replace_map: Unable to load map " << log_map_name; return; } catch(const wml_exception& e) { e.show(); @@ -623,7 +624,8 @@ WML_HANDLER_FUNCTION(replace_map,, cfg) if (map.total_width() > game_map->total_width() || map.total_height() > game_map->total_height()) { if (!cfg["expand"].to_bool()) { - lg::wml_error() << "replace_map: Map dimension(s) increase but expand is not set" << std::endl; + lg::log_to_chat() << "replace_map: Map dimension(s) increase but expand is not set\n"; + ERR_WML << "replace_map: Map dimension(s) increase but expand is not set"; return; } } @@ -631,7 +633,8 @@ WML_HANDLER_FUNCTION(replace_map,, cfg) if (map.total_width() < game_map->total_width() || map.total_height() < game_map->total_height()) { if (!cfg["shrink"].to_bool()) { - lg::wml_error() << "replace_map: Map dimension(s) decrease but shrink is not set" << std::endl; + lg::log_to_chat() << "replace_map: Map dimension(s) decrease but shrink is not set\n"; + ERR_WML << "replace_map: Map dimension(s) decrease but shrink is not set"; return; } } @@ -639,7 +642,8 @@ WML_HANDLER_FUNCTION(replace_map,, cfg) std::optional errmsg = resources::gameboard->replace_map(map); if (errmsg) { - lg::wml_error() << *errmsg << std::endl; + lg::log_to_chat() << *errmsg << '\n'; + ERR_WML << *errmsg; } display::get_singleton()->reload_map(); diff --git a/src/game_events/conditional_wml.cpp b/src/game_events/conditional_wml.cpp index aaea3c03756..5be3db9b6e2 100644 --- a/src/game_events/conditional_wml.cpp +++ b/src/game_events/conditional_wml.cpp @@ -37,6 +37,9 @@ static lg::log_domain log_engine("engine"); #define WRN_NG LOG_STREAM(warn, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + // This file is in the game_events namespace. namespace game_events { @@ -94,16 +97,19 @@ namespace builtin_conditions { bool variable_matches(const vconfig& values) { if(values["name"].blank()) { - lg::wml_error() << "[variable] with missing name=\n"; + lg::log_to_chat() << "[variable] with missing name=\n"; + ERR_WML << "[variable] with missing name="; return true; } const std::string name = values["name"]; config::attribute_value value = resources::gamedata->get_variable_const(name); if(auto n = values.get_config().attribute_count(); n > 2) { - lg::wml_error() << "[variable] name='" << name << "' found with multiple comparison attributes\n"; + lg::log_to_chat() << "[variable] name='" << name << "' found with multiple comparison attributes\n"; + ERR_WML << "[variable] name='" << name << "' found with multiple comparison attributes"; } else if(n < 2) { - lg::wml_error() << "[variable] name='" << name << "' found with no comparison attribute\n"; + lg::log_to_chat() << "[variable] name='" << name << "' found with no comparison attribute\n"; + ERR_WML << "[variable] name='" << name << "' found with no comparison attribute"; } #define TEST_STR_ATTR(name, test) \ diff --git a/src/game_events/manager_impl.cpp b/src/game_events/manager_impl.cpp index 9e115d0f86a..eaafe55c6f2 100644 --- a/src/game_events/manager_impl.cpp +++ b/src/game_events/manager_impl.cpp @@ -31,6 +31,9 @@ static lg::log_domain log_engine("engine"); static lg::log_domain log_event_handler("event_handler"); #define DBG_EH LOG_STREAM(debug, log_event_handler) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace game_events { void event_handlers::log_handlers() @@ -110,7 +113,8 @@ void event_handlers::add_event_handler(const config& cfg, bool is_menu_item) } if(name.empty() && id.empty()) { - lg::wml_error() << "[event] is missing name or id field\n"; + lg::log_to_chat() << "[event] is missing name or id field\n"; + ERR_WML << "[event] is missing name or id field"; return; } diff --git a/src/game_events/pump.cpp b/src/game_events/pump.cpp index bd410517279..c5f5cebbfeb 100644 --- a/src/game_events/pump.cpp +++ b/src/game_events/pump.cpp @@ -343,9 +343,11 @@ void wml_event_pump::fill_wml_messages_map(std::map& msg_map, * the number of times that message was encountered. * The order in which the messages are shown does not need * to be the order in which these messages are encountered. - * Messages are also written to std::cerr if to_cerr is true. + * + * @param source The source to be parsed before being displayed. + * @param caption The text to display before each message parsed from @a source. */ -void wml_event_pump::show_wml_messages(std::stringstream& source, const std::string& caption, bool to_cerr) +void wml_event_pump::show_wml_messages(std::stringstream& source, const std::string& caption) { // Get all unique messages in messages, // with the number of encounters for these messages @@ -362,10 +364,6 @@ void wml_event_pump::show_wml_messages(std::stringstream& source, const std::str game_display::get_singleton()->get_chat_manager().add_chat_message( std::time(nullptr), caption, 0, msg.str(), events::chat_handler::MESSAGE_PUBLIC, false); - - if(to_cerr) { - std::cerr << caption << ": " << msg.str() << '\n'; - } } } @@ -380,9 +378,7 @@ void wml_event_pump::show_wml_messages(std::stringstream& source, const std::str */ void wml_event_pump::show_wml_errors() { - static const std::string caption("Invalid WML found"); - - show_wml_messages(lg::wml_error(), caption, true); + show_wml_messages(lg::log_to_chat(), ""); } /** @@ -394,9 +390,7 @@ void wml_event_pump::show_wml_errors() */ void wml_event_pump::show_wml_messages() { - static const std::string caption("WML"); - - show_wml_messages(impl_->wml_messages_stream, caption, false); + show_wml_messages(impl_->wml_messages_stream, "WML: "); } void wml_event_pump::put_wml_message( diff --git a/src/game_events/pump.hpp b/src/game_events/pump.hpp index b640fb3840d..ecccee31f6c 100644 --- a/src/game_events/pump.hpp +++ b/src/game_events/pump.hpp @@ -148,7 +148,7 @@ private: void fill_wml_messages_map(std::map& msg_map, std::stringstream& source); - void show_wml_messages(std::stringstream& source, const std::string& caption, bool to_cerr); + void show_wml_messages(std::stringstream& source, const std::string& caption); void show_wml_errors(); diff --git a/src/game_launcher.cpp b/src/game_launcher.cpp index c3d63440e98..e08445300b9 100644 --- a/src/game_launcher.cpp +++ b/src/game_launcher.cpp @@ -513,9 +513,6 @@ game_launcher::unit_test_result game_launcher::unit_test() case unit_test_result::TEST_FAIL_PLAYING_REPLAY: describe_result = "FAIL TEST (ERRORED REPLAY)"; break; - case unit_test_result::TEST_FAIL_BROKE_STRICT: - describe_result = "FAIL TEST (BROKE STRICT)"; - break; case unit_test_result::TEST_FAIL_WML_EXCEPTION: describe_result = "FAIL TEST (WML EXCEPTION)"; break; @@ -525,8 +522,20 @@ game_launcher::unit_test_result game_launcher::unit_test() case unit_test_result::TEST_PASS_BY_VICTORY: describe_result = "PASS TEST (VICTORY)"; break; + case unit_test_result::BROKE_STRICT_TEST_PASS: + describe_result = "BROKE STRICT (PASS)"; + break; + case unit_test_result::BROKE_STRICT_TEST_FAIL: + describe_result = "BROKE STRICT (FAIL)"; + break; + case unit_test_result::BROKE_STRICT_TEST_FAIL_BY_DEFEAT: + describe_result = "BROKE STRICT (DEFEAT)"; + break; + case unit_test_result::BROKE_STRICT_TEST_PASS_BY_VICTORY: + describe_result = "BROKE STRICT (VICTORY)"; + break; default: - describe_result = "FAIL TEST"; + describe_result = "FAIL TEST (UNKNOWN)"; break; } @@ -547,13 +556,12 @@ game_launcher::unit_test_result game_launcher::single_unit_test() try { campaign_controller ccontroller(state_, true); game_res = ccontroller.play_game(); - // TODO: How to handle the case where a unit test scenario ends without an explicit {SUCCEED} or {FAIL}? - // ex: check_victory_never_ai_fail results in victory by killing one side's leaders if(game_res == LEVEL_RESULT::TEST_FAIL) { - return unit_test_result::TEST_FAIL; - } - if(lg::broke_strict()) { - return unit_test_result::TEST_FAIL_BROKE_STRICT; + if(lg::broke_strict()) { + return unit_test_result::BROKE_STRICT_TEST_FAIL; + } else { + return unit_test_result::TEST_FAIL; + } } } catch(const wml_exception& e) { std::cerr << "Caught WML Exception:" << e.dev_message << std::endl; @@ -578,9 +586,10 @@ game_launcher::unit_test_result game_launcher::single_unit_test() } try { + const bool was_strict_broken = lg::broke_strict(); campaign_controller ccontroller(state_, true); ccontroller.play_replay(); - if(lg::broke_strict()) { + if(!was_strict_broken && lg::broke_strict()) { std::cerr << "Observed failure on replay" << std::endl; return unit_test_result::TEST_FAIL_PLAYING_REPLAY; } @@ -595,12 +604,24 @@ game_launcher::unit_test_result game_launcher::single_unit_test() game_launcher::unit_test_result game_launcher::pass_victory_or_defeat(LEVEL_RESULT res) { if(res == LEVEL_RESULT::DEFEAT) { - return unit_test_result::TEST_FAIL_BY_DEFEAT; + if(lg::broke_strict()) { + return unit_test_result::BROKE_STRICT_TEST_FAIL_BY_DEFEAT; + } else { + return unit_test_result::TEST_FAIL_BY_DEFEAT; + } } else if(res == LEVEL_RESULT::VICTORY) { - return unit_test_result::TEST_PASS_BY_VICTORY; + if(lg::broke_strict()) { + return unit_test_result::BROKE_STRICT_TEST_PASS_BY_VICTORY; + } else { + return unit_test_result::TEST_PASS_BY_VICTORY; + } } - return unit_test_result::TEST_PASS; + if(lg::broke_strict()) { + return unit_test_result::BROKE_STRICT_TEST_PASS; + } else { + return unit_test_result::TEST_PASS; + } } bool game_launcher::play_screenshot_mode() diff --git a/src/game_launcher.hpp b/src/game_launcher.hpp index 43553c25552..3e47484a6a7 100644 --- a/src/game_launcher.hpp +++ b/src/game_launcher.hpp @@ -70,10 +70,14 @@ public: // 2 is reserved for timeouts TEST_FAIL_LOADING_REPLAY = 3, TEST_FAIL_PLAYING_REPLAY = 4, - TEST_FAIL_BROKE_STRICT = 5, + //TEST_FAIL_BROKE_STRICT = 5, TEST_FAIL_WML_EXCEPTION = 6, TEST_FAIL_BY_DEFEAT = 7, TEST_PASS_BY_VICTORY = 8, + BROKE_STRICT_TEST_PASS = 9, + BROKE_STRICT_TEST_FAIL = 10, + BROKE_STRICT_TEST_FAIL_BY_DEFEAT = 11, + BROKE_STRICT_TEST_PASS_BY_VICTORY = 12, }; bool init_video(); diff --git a/src/generators/cave_map_generator.cpp b/src/generators/cave_map_generator.cpp index 8cf6baf6c55..d0a42af4efb 100644 --- a/src/generators/cave_map_generator.cpp +++ b/src/generators/cave_map_generator.cpp @@ -27,6 +27,9 @@ static lg::log_domain log_engine("engine"); #define LOG_NG LOG_STREAM(info, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + cave_map_generator::cave_map_generator(const config &cfg) : wall_(t_translation::CAVE_WALL), clear_(t_translation::CAVE), @@ -160,7 +163,8 @@ void cave_map_generator::cave_map_generator_job::generate_chambers() min_xpos = std::stoi(items.front()) - 1; max_xpos = std::stoi(items.back()); } catch(const std::invalid_argument&) { - lg::wml_error() << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back() << "\n"; + lg::log_to_chat() << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back() << "\n"; + ERR_WML << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back(); continue; } } @@ -173,7 +177,8 @@ void cave_map_generator::cave_map_generator_job::generate_chambers() min_ypos = std::stoi(items.front()) - 1; max_ypos = std::stoi(items.back()); } catch(const std::invalid_argument&) { - lg::wml_error() << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back() << "\n"; + lg::log_to_chat() << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back() << "\n"; + ERR_WML << "Invalid min/max coordinates in cave_map_generator: " << items.front() << ", " << items.back(); } } } diff --git a/src/gui/widgets/stacked_widget.cpp b/src/gui/widgets/stacked_widget.cpp index 652b482246c..03932a38e20 100644 --- a/src/gui/widgets/stacked_widget.cpp +++ b/src/gui/widgets/stacked_widget.cpp @@ -26,6 +26,9 @@ #include +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace gui2 { @@ -231,7 +234,8 @@ builder_stacked_widget::builder_stacked_widget(const config& real_cfg) { const config& cfg = real_cfg.has_child("stack") ? real_cfg.child("stack") : real_cfg; if(&cfg != &real_cfg) { - lg::wml_error() << "Stacked widgets no longer require a [stack] tag. Instead, place [layer] tags directly in the widget definition.\n"; + lg::log_to_chat() << "Stacked widgets no longer require a [stack] tag. Instead, place [layer] tags directly in the widget definition.\n"; + ERR_WML << "Stacked widgets no longer require a [stack] tag. Instead, place [layer] tags directly in the widget definition."; } VALIDATE(cfg.has_child("layer"), _("No stack layers defined.")); for(const auto & layer : cfg.child_range("layer")) diff --git a/src/log.cpp b/src/log.cpp index 4d915cee578..45a6e35654f 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -285,7 +285,7 @@ void scope_logger::do_log_exit() noexcept output | formatter() << "} END: " << str_ << " (took " << ticks << "ms)\n"; } -std::stringstream& wml_error() +std::stringstream& log_to_chat() { static std::stringstream lg; return lg; diff --git a/src/log.hpp b/src/log.hpp index 72f2b28977c..4640555e327 100644 --- a/src/log.hpp +++ b/src/log.hpp @@ -60,6 +60,14 @@ namespace lg { +enum severity +{ + LG_ERROR=0, + LG_WARN=1, + LG_INFO=2, + LG_DEBUG=3 +}; + /** * Helper class to redirect the output of the logger in a certain scope. * @@ -142,6 +150,14 @@ public: return severity_ > domain.domain_->second; } + /** + * Returns following values depending on the logger: + * error: 0 + * warn: 1 + * info: 2 + * debug: 3 + * See also the lg::severity enum. + */ int get_severity() const { return severity_; @@ -191,15 +207,10 @@ private: }; /** - * Use this logger to send errors due to deprecated WML. - * The preferred format is: - * xxx is deprecated; support will be removed in version X. or - * xxx is deprecated; support has been removed in version X. - * - * After every wml-event the errors are shown to the user, - * so they can inform the campaign maintainer. + * Use this to show WML errors in the ingame chat. + * After every WML event the errors are shown to the user so they can inform the campaign maintainer. */ -std::stringstream& wml_error(); +std::stringstream& log_to_chat(); } // namespace lg diff --git a/src/mouse_events.cpp b/src/mouse_events.cpp index 3d8cadd9c4b..b9153853507 100644 --- a/src/mouse_events.cpp +++ b/src/mouse_events.cpp @@ -53,6 +53,9 @@ static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) #define LOG_NG LOG_STREAM(info, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace events { mouse_handler::mouse_handler(game_display* gui, play_controller& pc) @@ -1296,7 +1299,8 @@ void mouse_handler::attack_enemy(const map_location& attacker_loc, const map_loc try { attack_enemy_(attacker_loc, defender_loc, choice); } catch(const std::bad_alloc&) { - lg::wml_error() << "Memory exhausted a unit has either a lot hitpoints or a negative amount.\n"; + lg::log_to_chat() << "Memory exhausted a unit has either a lot hitpoints or a negative amount.\n"; + ERR_WML << "Memory exhausted a unit has either a lot hitpoints or a negative amount."; } } diff --git a/src/pathfind/teleport.cpp b/src/pathfind/teleport.cpp index da7255915f0..47c28791d0e 100644 --- a/src/pathfind/teleport.cpp +++ b/src/pathfind/teleport.cpp @@ -28,6 +28,9 @@ static lg::log_domain log_engine("engine"); #define ERR_PF LOG_STREAM(err, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace pathfind { @@ -287,7 +290,8 @@ manager::manager(const config &cfg) : tunnels_(), id_(cfg["next_teleport_group_i for(int i = 0; i < tunnel_count; ++i) { const config& t = cfg.child("tunnel", i); if(!t["saved"].to_bool()) { - lg::wml_error() << "Do not use [tunnel] directly in a [scenario]. Use it in an [event] or [abilities] tag.\n"; + lg::log_to_chat() << "Do not use [tunnel] directly in a [scenario]. Use it in an [event] or [abilities] tag.\n"; + ERR_WML << "Do not use [tunnel] directly in a [scenario]. Use it in an [event] or [abilities] tag."; continue; } const teleport_group tunnel(t); diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 1608646afd5..8e5b1271c31 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -136,6 +136,9 @@ static lg::log_domain log_scripting_lua("scripting/lua"); #define WRN_LUA LOG_STREAM(warn, log_scripting_lua) #define ERR_LUA LOG_STREAM(err, log_scripting_lua) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + std::vector game_lua_kernel::preload_scripts; config game_lua_kernel::preload_config; @@ -4164,7 +4167,8 @@ int game_lua_kernel::intf_log(lua_State *L) const std::string& msg = lua_isstring(L, 2) ? luaL_checkstring(L, 2) : luaL_checkstring(L, 1); if(logger == "wml" || logger == "WML") { - lg::wml_error() << msg << '\n'; + lg::log_to_chat() << msg << '\n'; + ERR_WML << msg; } else { bool in_chat = luaW_toboolean(L, -1); game_state_.events_manager_->pump().put_wml_message(logger,msg,in_chat); @@ -5035,7 +5039,8 @@ bool game_lua_kernel::run_wml_conditional(const std::string& cmd, const vconfig& // If an invalid coniditional tag is used, consider it a pass. if(!luaW_getglobal(L, "wesnoth", "wml_conditionals", cmd)) { - lg::wml_error() << "unknown conditional wml: [" << cmd << "]\n"; + lg::log_to_chat() << "unknown conditional wml: [" << cmd << "]\n"; + ERR_WML << "unknown conditional wml: [" << cmd << "]"; return true; } diff --git a/src/scripting/lua_common.cpp b/src/scripting/lua_common.cpp index ff998b385f9..77fd4f5dc9f 100644 --- a/src/scripting/lua_common.cpp +++ b/src/scripting/lua_common.cpp @@ -53,6 +53,9 @@ static lg::log_domain log_scripting_lua("scripting/lua"); #define WRN_LUA LOG_STREAM(warn, log_scripting_lua) #define ERR_LUA LOG_STREAM(err, log_scripting_lua) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace lua_common { /** @@ -1124,7 +1127,8 @@ bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error) if (allow_wml_error && strncmp(m, "~wml:", 5) == 0) { m += 5; char const *e = strstr(m, "stack traceback"); - lg::wml_error() << std::string(m, e ? e - m : strlen(m)); + lg::log_to_chat() << std::string(m, e ? e - m : strlen(m)) << '\n'; + ERR_WML << std::string(m, e ? e - m : strlen(m)); } else if (allow_wml_error && strncmp(m, "~lua:", 5) == 0) { m += 5; char const *e = nullptr, *em = m; diff --git a/src/side_filter.cpp b/src/side_filter.cpp index 037cbcd32b2..06b6f486ec9 100644 --- a/src/side_filter.cpp +++ b/src/side_filter.cpp @@ -39,6 +39,9 @@ static lg::log_domain log_engine_sf("engine/side_filter"); #define ERR_NG LOG_STREAM(err, log_engine_sf) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + side_filter::~side_filter() {} side_filter::side_filter(const vconfig& cfg, const filter_context * fc, bool flat_tod) @@ -239,7 +242,8 @@ bool side_filter::match_internal(const team &t) const } return true; } catch(const wfl::formula_error& e) { - lg::wml_error() << "Formula error in side filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + lg::log_to_chat() << "Formula error in side filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + ERR_WML << "Formula error in side filter: " << e.type << " at " << e.filename << ':' << e.line << ")"; // Formulae with syntax errors match nothing return false; } diff --git a/src/terrain/filter.cpp b/src/terrain/filter.cpp index 3520a88420c..292ede81c79 100644 --- a/src/terrain/filter.cpp +++ b/src/terrain/filter.cpp @@ -40,6 +40,9 @@ static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) #define WRN_NG LOG_STREAM(warn, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + terrain_filter::~terrain_filter() { } @@ -346,7 +349,8 @@ bool terrain_filter::match_internal(const map_location& loc, const unit* ref_uni } return true; } catch(const wfl::formula_error& e) { - lg::wml_error() << "Formula error in location filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + lg::log_to_chat() << "Formula error in location filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + ERR_WML << "Formula error in location filter: " << e.type << " at " << e.filename << ':' << e.line << ")"; // Formulae with syntax errors match nothing return false; } diff --git a/src/units/abilities.cpp b/src/units/abilities.cpp index 7a1aefbd196..26546921d3a 100644 --- a/src/units/abilities.cpp +++ b/src/units/abilities.cpp @@ -45,6 +45,9 @@ static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + namespace { class temporary_facing { @@ -536,7 +539,8 @@ T get_single_ability_value(const config::attribute_value& v, T def, const unit_a } return formula_handler(wfl::formula(s, new wfl::gamestate_function_symbol_table), callable); } catch(const wfl::formula_error& e) { - lg::wml_error() << "Formula error in ability or weapon special: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + lg::log_to_chat() << "Formula error in ability or weapon special: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + ERR_WML << "Formula error in ability or weapon special: " << e.type << " at " << e.filename << ':' << e.line << ")"; return def; } })); diff --git a/src/units/attack_type.cpp b/src/units/attack_type.cpp index 8cdf8e347e6..8a18475d541 100644 --- a/src/units/attack_type.cpp +++ b/src/units/attack_type.cpp @@ -43,6 +43,9 @@ static lg::log_domain log_unit("unit"); #define DBG_UT LOG_STREAM(debug, log_unit) #define ERR_UT LOG_STREAM(err, log_unit) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + attack_type::attack_type(const config& cfg) : self_loc_(), other_loc_(), @@ -222,7 +225,8 @@ static bool matches_simple_filter(const attack_type & attack, const config & fil return false; } } catch(const wfl::formula_error& e) { - lg::wml_error() << "Formula error in weapon filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + lg::log_to_chat() << "Formula error in weapon filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + ERR_WML << "Formula error in weapon filter: " << e.type << " at " << e.filename << ':' << e.line << ")"; // Formulae with syntax errors match nothing return false; } diff --git a/src/units/filter.cpp b/src/units/filter.cpp index 3c7ad8908ed..cd88b3bd3ab 100644 --- a/src/units/filter.cpp +++ b/src/units/filter.cpp @@ -42,6 +42,9 @@ static lg::log_domain log_config("config"); #define WRN_CF LOG_STREAM(warn, log_config) #define DBG_CF LOG_STREAM(debug, log_config) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + using namespace unit_filter_impl; unit_filter::unit_filter(vconfig cfg) @@ -712,7 +715,8 @@ void unit_filter_compound::fill(vconfig cfg) } return true; } catch(const wfl::formula_error& e) { - lg::wml_error() << "Formula error in unit filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + lg::log_to_chat() << "Formula error in unit filter: " << e.type << " at " << e.filename << ':' << e.line << ")\n"; + ERR_WML << "Formula error in unit filter: " << e.type << " at " << e.filename << ':' << e.line << ")"; // Formulae with syntax errors match nothing return false; } diff --git a/src/units/race.cpp b/src/units/race.cpp index f6630af6d17..51bd8792c00 100644 --- a/src/units/race.cpp +++ b/src/units/race.cpp @@ -26,6 +26,9 @@ #include "utils/name_generator.hpp" #include "utils/name_generator_factory.hpp" +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + /** Dummy race used when a race is not yet known. */ const unit_race unit_race::null_race; /** Standard string id (not translatable) for FEMALE */ @@ -77,10 +80,12 @@ unit_race::unit_race(const config& cfg) : { if (id_.empty()) { - lg::wml_error() << "[race] '" << cfg["name"] << "' is missing an id field."; + lg::log_to_chat() << "[race] '" << cfg["name"] << "' is missing an id field.\n"; + ERR_WML << "[race] '" << cfg["name"] << "' is missing an id field."; } if (plural_name_.empty()) { - lg::wml_error() << "[race] '" << cfg["name"] << "' is missing a plural_name field."; + lg::log_to_chat() << "[race] '" << cfg["name"] << "' is missing a plural_name field.\n"; + ERR_WML << "[race] '" << cfg["name"] << "' is missing a plural_name field."; plural_name_ = (cfg["name"]); } diff --git a/src/utils/context_free_grammar_generator.cpp b/src/utils/context_free_grammar_generator.cpp index 9c74818e89a..f549d299f3f 100644 --- a/src/utils/context_free_grammar_generator.cpp +++ b/src/utils/context_free_grammar_generator.cpp @@ -28,6 +28,9 @@ #include +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + context_free_grammar_generator::~context_free_grammar_generator() { } @@ -143,7 +146,8 @@ std::string context_free_grammar_generator::print_nonterminal(const std::string& std::map::const_iterator found = nonterminals_.find(name); if (found == nonterminals_.end()) { - lg::wml_error() << "[context_free_grammar_generator] Warning: needed nonterminal" << name << " not defined"; + lg::log_to_chat() << "[context_free_grammar_generator] Warning: needed nonterminal " << name << " not defined\n"; + ERR_WML << "[context_free_grammar_generator] Warning: needed nonterminal " << name << " not defined"; return "!" + name; } const context_free_grammar_generator::nonterminal& got = found->second; diff --git a/src/utils/name_generator_factory.cpp b/src/utils/name_generator_factory.cpp index f57a22e1588..f71b17cf05b 100644 --- a/src/utils/name_generator_factory.cpp +++ b/src/utils/name_generator_factory.cpp @@ -19,6 +19,9 @@ #include "utils/markov_generator.hpp" #include "formula/string_utils.hpp" +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + std::string name_generator::generate(const std::map& variables) const { return utils::interpolate_variables_into_string(generate(), &variables); } @@ -42,7 +45,8 @@ void name_generator_factory::add_name_generator_from_config(const config& config return; } catch (const name_generator_invalid_exception& ex) { - lg::wml_error() << ex.what() << '\n'; + lg::log_to_chat() << ex.what() << '\n'; + ERR_WML << ex.what(); } } diff --git a/src/wml_exception.cpp b/src/wml_exception.cpp index 4b02e6e6459..8f65e7675ae 100644 --- a/src/wml_exception.cpp +++ b/src/wml_exception.cpp @@ -29,6 +29,9 @@ static lg::log_domain log_engine("engine"); #define WRN_NG LOG_STREAM(warn, log_engine) +static lg::log_domain log_wml("wml"); +#define ERR_WML LOG_STREAM(err, log_wml) + void throw_wml_exception( const char* cond , const char* file @@ -149,12 +152,9 @@ const config::attribute_value& get_renamed_config_attribute( result = cfg.get(deprecated_key); if(result) { - lg::wml_error() - << deprecated_renamed_wml_key_warning( - deprecated_key - , key - , removal_version) - << '\n'; + std::string msg = deprecated_renamed_wml_key_warning(deprecated_key, key, removal_version); + lg::log_to_chat() << msg << '\n'; + ERR_WML << msg; return *result; } diff --git a/wml_test_schedule b/wml_test_schedule index ad24598420b..8b6bc7b85ef 100644 --- a/wml_test_schedule +++ b/wml_test_schedule @@ -44,7 +44,7 @@ # Security test # 0 cve_2018_1999023 -5 cve_2018_1999023_2 +9 cve_2018_1999023_2 # # Test Check Victory (If this isn't working other tests may have dubious value) # @@ -76,7 +76,7 @@ # WML API tests # 0 two_plus_two -1 two_plus_two_fail +10 two_plus_two_fail 0 order_of_nested_events 0 test_clear_one 0 test_clear_two @@ -85,12 +85,12 @@ 0 units_offmap_goto_recall 0 recall_by_unit_tag 0 test_move -5 test_move_fail_1 -5 test_move_fail_2 -5 test_move_fail_3 -5 test_move_fail_4 -5 test_move_fail_5 -5 test_move_fail_6 +9 test_move_fail_1 +9 test_move_fail_2 +9 test_move_fail_3 +9 test_move_fail_4 +9 test_move_fail_5 +9 test_move_fail_6 0 test_move_unit 0 test_move_unit_in_circle 0 sighted_on_move @@ -151,7 +151,7 @@ 0 events-test_defeat 0 events-test_die 0 test_store_unit_defense_on -5 test_store_unit_defense_deprecated +9 test_store_unit_defense_deprecated # Terrain mask tests 0 test_terrain_mask_simple_nop 0 test_terrain_mask_simple_set @@ -266,7 +266,7 @@ # Interface tests # 0 test_wml_menu_items_1 -1 test_wml_menu_items_2 +10 test_wml_menu_items_2 0 test_wml_menu_items_3 # # Conditional tests @@ -278,19 +278,19 @@ 0 filter_this_unit_tl 0 filter_this_unit_formula 0 filter_formula_unit -5 filter_formula_unit_error +9 filter_formula_unit_error # Interrupt tag tests 0 check_interrupts_break 0 check_interrupts_return 0 check_interrupts_continue 0 check_interrupts_break_global 0 check_interrupts_return_nested -0 check_interrupts_continue_global +9 check_interrupts_continue_global 0 check_interrupts_elseif 0 check_interrupts_case # For-loop tests -0 forloop_all_zero -0 forloop_step_zero +9 forloop_all_zero +9 forloop_step_zero 0 forloop_once_positive 0 forloop_once_negative 0 forloop_twice_matched @@ -336,4 +336,4 @@ # Warnings about WML 0 unknown_scenario_false_positives 0 unknown_scenario_interpolated -5 unknown_scenario_1_0 +9 unknown_scenario_1_0