diff --git a/GG/src/Font.cpp b/GG/src/Font.cpp index 83f78c7dd6a..8cbbb2f1cee 100644 --- a/GG/src/Font.cpp +++ b/GG/src/Font.cpp @@ -2744,31 +2744,15 @@ Font::ExpensiveParseFromTextToTextElements(const std::string& text, const Flags< // Fetch and use the regular expression from the TagHandler which parses all the known XML tags. const sregex& regex = tag_handler.Regex(text, ignore_tags); sregex_iterator it(text.begin(), text.end(), regex); - const sregex_iterator end_it; - while (it != end_it) - { - // Consolidate adjacent blocks of text. - // If adjacent found substrings are all text, merge them into a single Substring. - bool need_increment = true; - Substring combined_text; - sub_match const* text_match; - while (it != end_it && - (text_match = &(*it)[text_tag_idx]) && - text_match->matched) - { - need_increment = false; - if (combined_text.empty()) - combined_text = Substring(text, *text_match); - else - combined_text += *text_match; - ++it; - } + for (; it != end_it; ++it) { const auto& it_elem = *it; - if (!combined_text.empty()) { - text_elements.emplace_back(combined_text); // Basic text element. + if (it_elem[text_tag_idx].matched) { + auto matched_text = Substring(text, it_elem[text_tag_idx]); + if (!matched_text.empty()) + text_elements.emplace_back(matched_text); // Basic text element. } else if (it_elem[open_bracket_tag_idx].matched) { // Open XML tag. @@ -2808,9 +2792,6 @@ Font::ExpensiveParseFromTextToTextElements(const std::string& text, const Flags< if (last_char == '\n' || last_char == '\f' || last_char == '\r') text_elements.emplace_back(NEWLINE); } - - if (need_increment) - ++it; } // fill in the widths of code points in each TextElement diff --git a/UI/Sound.cpp b/UI/Sound.cpp index d8c6ff69ade..02822be4034 100644 --- a/UI/Sound.cpp +++ b/UI/Sound.cpp @@ -287,7 +287,6 @@ void Sound::Impl::Disable() { m_temporary_disable_count = 0; m_initialized = false; - DebugLogger() << "Audio " << (m_initialized ? "enabled." : "disabled."); } void Sound::Impl::InitOpenAL() { diff --git a/parse/BuildingsParser.cpp b/parse/BuildingsParser.cpp index d760d9898ee..63a9aaa3c0f 100644 --- a/parse/BuildingsParser.cpp +++ b/parse/BuildingsParser.cpp @@ -251,7 +251,7 @@ namespace parse { ScopedTimer timer("Buildings Parsing"); for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, building_types); + detail::parse_file(GetLexer(), file, building_types); py_grammar p = py_grammar(parser, building_types); for (const auto& file : ListDir(path, IsFOCPyScript)) diff --git a/parse/DoubleValueRefParser.cpp b/parse/DoubleValueRefParser.cpp index 94e4bfe7d96..8e25870d1b4 100644 --- a/parse/DoubleValueRefParser.cpp +++ b/parse/DoubleValueRefParser.cpp @@ -188,15 +188,17 @@ parse::double_parser_rules::double_parser_rules( namespace parse { bool double_free_variable(std::string& text) { + const auto& tok = GetLexer(); + boost::spirit::qi::in_state_type in_state; - parse::detail::simple_double_parser_rules simple_double_rules(lexer::tok); + parse::detail::simple_double_parser_rules simple_double_rules(tok); text_iterator first = text.begin(); text_iterator last = text.end(); - token_iterator it = lexer::tok.begin(first, last); + token_iterator it = tok.begin(first, last); bool success = boost::spirit::qi::phrase_parse( - it, lexer::tok.end(), simple_double_rules.free_variable_name, in_state("WS")[lexer::tok.self]); + it, tok.end(), simple_double_rules.free_variable_name, in_state("WS")[tok.self]); return success; } diff --git a/parse/EmpireStatsParser.cpp b/parse/EmpireStatsParser.cpp index 974fa5dcbab..652e780e20c 100644 --- a/parse/EmpireStatsParser.cpp +++ b/parse/EmpireStatsParser.cpp @@ -98,7 +98,7 @@ namespace parse { for (const auto& file : ListDir(path, IsFOCScript)) { start_rule_payload stats_; - if (detail::parse_file(lexer::tok, file, stats_)) { + if (detail::parse_file(GetLexer(), file, stats_)) { for (auto& stat : stats_) { auto maybe_inserted = all_stats.emplace(stat.first, std::move(stat.second)); if (!maybe_inserted.second) { diff --git a/parse/EncyclopediaParser.cpp b/parse/EncyclopediaParser.cpp index 06fd2dd50ee..3fed0882a48 100644 --- a/parse/EncyclopediaParser.cpp +++ b/parse/EncyclopediaParser.cpp @@ -90,7 +90,7 @@ namespace parse { ScopedTimer timer("Encyclopedia Parsing"); for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, articles); + detail::parse_file(GetLexer(), file, articles); return articles; } diff --git a/parse/FieldsParser.cpp b/parse/FieldsParser.cpp index 3c933a6a8d1..a0ec27ac13d 100644 --- a/parse/FieldsParser.cpp +++ b/parse/FieldsParser.cpp @@ -117,7 +117,7 @@ namespace parse { ScopedTimer timer("Fields Parsing"); for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, field_types); + detail::parse_file(GetLexer(), file, field_types); return field_types; } diff --git a/parse/FleetPlansParser.cpp b/parse/FleetPlansParser.cpp index 7235091220c..ef39bb5e800 100644 --- a/parse/FleetPlansParser.cpp +++ b/parse/FleetPlansParser.cpp @@ -84,7 +84,7 @@ namespace parse { start_rule_payload fleet_plans(const boost::filesystem::path& path) { start_rule_payload fleet_plans_; fleet_plans_.reserve(32); // guesstimate of enough space - detail::parse_file(lexer::tok, path, fleet_plans_); + detail::parse_file(GetLexer(), path, fleet_plans_); return fleet_plans_; } } diff --git a/parse/IntValueRefParser.cpp b/parse/IntValueRefParser.cpp index 5c420578c66..4ba5e4bf1ea 100644 --- a/parse/IntValueRefParser.cpp +++ b/parse/IntValueRefParser.cpp @@ -200,15 +200,17 @@ parse::int_arithmetic_rules::int_arithmetic_rules( namespace parse { bool int_free_variable(std::string& text) { + const auto& tok = GetLexer(); + boost::spirit::qi::in_state_type in_state; - parse::detail::simple_int_parser_rules simple_int_rules(lexer::tok); + parse::detail::simple_int_parser_rules simple_int_rules(tok); text_iterator first = text.begin(); text_iterator last = text.end(); - token_iterator it = lexer::tok.begin(first, last); + token_iterator it = tok.begin(first, last); bool success = boost::spirit::qi::phrase_parse( - it, lexer::tok.end(), simple_int_rules.free_variable_name, in_state("WS")[lexer::tok.self]); + it, tok.end(), simple_int_rules.free_variable_name, in_state("WS")[tok.self]); return success; } diff --git a/parse/ItemsParser.cpp b/parse/ItemsParser.cpp index a3bc86704da..b856ac00202 100644 --- a/parse/ItemsParser.cpp +++ b/parse/ItemsParser.cpp @@ -58,14 +58,14 @@ namespace parse { start_rule_payload items(const boost::filesystem::path& path) { start_rule_payload items_; items_.reserve(128); // should be more than enough as of this writing - detail::parse_file(lexer::tok, path, items_); + detail::parse_file(GetLexer(), path, items_); return items_; } start_rule_payload starting_buildings(const boost::filesystem::path& path) { start_rule_payload starting_buildings_; starting_buildings_.reserve(32); // should be more than enough as of this writing... - detail::parse_file(lexer::tok, path, starting_buildings_); + detail::parse_file(GetLexer(), path, starting_buildings_); return starting_buildings_; } } diff --git a/parse/Lexer.cpp b/parse/Lexer.cpp index 00e10448614..0bee7995f33 100644 --- a/parse/Lexer.cpp +++ b/parse/Lexer.cpp @@ -119,5 +119,3 @@ lexer::lexer() : | end_of_line_comment ; } - -const lexer lexer::tok{}; diff --git a/parse/Lexer.h b/parse/Lexer.h index 5f7a65b8749..42fa4b1c06b 100644 --- a/parse/Lexer.h +++ b/parse/Lexer.h @@ -80,9 +80,13 @@ struct lexer : boost::spirit::lex::lexer { static inline const std::string int_regex{"\\d+"}; static inline const std::string double_regex{"\\d+\\.\\d*|\\d*\\.\\d+"}; static inline const std::string string_regex{"\\\"[^\\\"]*\\\""}; - static const lexer tok; }; +inline const lexer& GetLexer() { + static const lexer tok; + return tok; +} + /** The type of iterator passed to the script file parser by the script file lexer. */ typedef lexer::iterator_type token_iterator; diff --git a/parse/MonsterFleetPlansParser.cpp b/parse/MonsterFleetPlansParser.cpp index 9362f619f6e..197e935c7c5 100644 --- a/parse/MonsterFleetPlansParser.cpp +++ b/parse/MonsterFleetPlansParser.cpp @@ -125,7 +125,7 @@ namespace { namespace parse { start_rule_payload monster_fleet_plans(const boost::filesystem::path& path) { start_rule_payload monster_fleet_plans_; - detail::parse_file(lexer::tok, path, monster_fleet_plans_); + detail::parse_file(GetLexer(), path, monster_fleet_plans_); return monster_fleet_plans_; } } diff --git a/parse/NamedValueRefParser.cpp b/parse/NamedValueRefParser.cpp index 0d9b23e3c5b..7dd404eb205 100644 --- a/parse/NamedValueRefParser.cpp +++ b/parse/NamedValueRefParser.cpp @@ -133,7 +133,7 @@ namespace parse { ScopedTimer timer("Named ValueRef Parsing"); for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, named_value_refs); + detail::parse_file(GetLexer(), file, named_value_refs); for (auto& k_v : named_value_refs) ErrorLogger() << "Should have not returned anything: named_value_refs : " << k_v.first; diff --git a/parse/PoliciesParser.cpp b/parse/PoliciesParser.cpp index 4d60599bcf8..0a12444ddf5 100644 --- a/parse/PoliciesParser.cpp +++ b/parse/PoliciesParser.cpp @@ -227,7 +227,7 @@ namespace parse { ScopedTimer timer("Policies Parsing"); for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, policies_); + detail::parse_file(GetLexer(), file, policies_); return policies_; } diff --git a/parse/ShipDesignsParser.cpp b/parse/ShipDesignsParser.cpp index 0dc6fd4ad07..66f707560ee 100644 --- a/parse/ShipDesignsParser.cpp +++ b/parse/ShipDesignsParser.cpp @@ -227,6 +227,8 @@ namespace parse { ScopedTimer timer("Ship Designs Parsing"); + const auto& tok = GetLexer(); + for (auto& file : ListDir(path, IsFOCScript)) { TraceLogger() << "Parse ship design file " << file.filename(); if (file.filename() == "ShipDesignOrdering.focs.txt" ) { @@ -237,7 +239,7 @@ namespace parse { try { boost::optional> maybe_design; auto partial_result = detail::parse_file>>( - lexer::tok, file, maybe_design); + tok, file, maybe_design); if (!partial_result || !maybe_design) continue; @@ -252,7 +254,7 @@ namespace parse { if (!manifest_file.empty()) { try { detail::parse_file>( - lexer::tok, manifest_file, ordering); + tok, manifest_file, ordering); } catch (const std::runtime_error& e) { ErrorLogger() << "Failed to parse ship design manifest in " << manifest_file << " from " << path diff --git a/parse/ShipHullsParser.cpp b/parse/ShipHullsParser.cpp index 96c603eaea9..68f6694d67d 100644 --- a/parse/ShipHullsParser.cpp +++ b/parse/ShipHullsParser.cpp @@ -211,7 +211,7 @@ namespace parse { start_rule_payload hulls; for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, hulls); + detail::parse_file(GetLexer(), file, hulls); return hulls; } diff --git a/parse/ShipPartsParser.cpp b/parse/ShipPartsParser.cpp index aca961da0c1..338b9e08f27 100644 --- a/parse/ShipPartsParser.cpp +++ b/parse/ShipPartsParser.cpp @@ -183,7 +183,7 @@ namespace parse { start_rule_payload parts; for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, parts); + detail::parse_file(GetLexer(), file, parts); return parts; } diff --git a/parse/SpecialsParser.cpp b/parse/SpecialsParser.cpp index e0f52d644eb..8955b7caf5d 100644 --- a/parse/SpecialsParser.cpp +++ b/parse/SpecialsParser.cpp @@ -145,7 +145,7 @@ namespace parse { start_rule_payload specials_; for (const auto& file : ListDir(path, IsFOCScript)) - detail::parse_file(lexer::tok, file, specials_); + detail::parse_file(GetLexer(), file, specials_); return specials_; } diff --git a/parse/StringValueRefParser.cpp b/parse/StringValueRefParser.cpp index 65858735aae..7c169ae507a 100644 --- a/parse/StringValueRefParser.cpp +++ b/parse/StringValueRefParser.cpp @@ -203,12 +203,14 @@ namespace parse { bool string_free_variable(std::string& text) { boost::spirit::qi::in_state_type in_state; + const auto& tok = GetLexer(); + text_iterator first = text.begin(); text_iterator last = text.end(); - token_iterator it = lexer::tok.begin(first, last); + token_iterator it = tok.begin(first, last); bool success = boost::spirit::qi::phrase_parse( - it, lexer::tok.end(), lexer::tok.GalaxySeed_, in_state("WS")[lexer::tok.self]); + it, tok.end(), tok.GalaxySeed_, in_state("WS")[tok.self]); return success; } diff --git a/universe/Meter.cpp b/universe/Meter.cpp index 080d250c207..9642a402f7a 100644 --- a/universe/Meter.cpp +++ b/universe/Meter.cpp @@ -136,8 +136,9 @@ int Meter::SetFromChars(std::string_view chars) noexcept(have_noexcept_to_chars) static_assert(noexcept(result.ptr - chars.data())); #else + const std::string null_terminated_chars{chars}; int chars_consumed = 0; - std::sscanf(chars.data(), "%d %d%n", &cur, &init, &chars_consumed); + std::sscanf(null_terminated_chars.data(), "%d %d%n", &cur, &init, &chars_consumed); return chars_consumed; #endif diff --git a/util/SerializeEmpire.cpp b/util/SerializeEmpire.cpp index 4546ab438ef..b2e92633294 100644 --- a/util/SerializeEmpire.cpp +++ b/util/SerializeEmpire.cpp @@ -273,7 +273,6 @@ void Empire::serialize(Archive& ar, const unsigned int version) } else { ar & BOOST_SERIALIZATION_NVP(m_last_turn_received); } - } BOOST_CLASS_VERSION(Empire, 13) @@ -363,8 +362,9 @@ void serialize(Archive& ar, EmpireManager& em, unsigned int const version) for (const auto e1_id : em.m_empire_map | range_keys) { const auto e1_id_lower = [e1_id](auto e2_id) { return e1_id < e2_id; }; for (const auto e2_id : em.m_empire_map | range_keys | range_filter(e1_id_lower)) { + auto dk = DiploKey(e1_id, e2_id); const auto inserted_missing_status = em.m_empire_diplomatic_statuses.try_emplace( - DiploKey(e1_id, e2_id), DiplomaticStatus::DIPLO_WAR).second; + dk, DiplomaticStatus::DIPLO_WAR).second; if (inserted_missing_status) ErrorLogger() << "Added missing diplomatic status (default WAR) between empires " << e1_id << " and " << e2_id;