From 07860e67e26af5a7acfd86de6d6431695db9b173 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 19 May 2023 23:22:30 +0200 Subject: [PATCH] Codechange: use fmt::format_to to format the help message --- src/ai/ai.hpp | 4 ++-- src/ai/ai_core.cpp | 8 ++++---- src/base_media_base.h | 2 +- src/base_media_func.h | 22 +++++++++------------- src/blitter/factory.hpp | 10 ++++------ src/console_cmds.cpp | 31 +++++++++++++++---------------- src/debug.cpp | 24 ++++++++++-------------- src/debug.h | 2 +- src/driver.cpp | 14 +++++--------- src/driver.h | 2 +- src/game/game.hpp | 4 ++-- src/game/game_core.cpp | 8 ++++---- src/openttd.cpp | 35 ++++++++++++++++------------------- src/script/script_scanner.cpp | 11 ++++------- src/script/script_scanner.hpp | 4 +++- 15 files changed, 81 insertions(+), 100 deletions(-) diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp index ae19439754..b005f9c990 100644 --- a/src/ai/ai.hpp +++ b/src/ai/ai.hpp @@ -112,9 +112,9 @@ public: static void Save(CompanyID company); /** Wrapper function for AIScanner::GetAIConsoleList */ - static std::string GetConsoleList(bool newest_only = false); + static void GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only); /** Wrapper function for AIScanner::GetAIConsoleLibraryList */ - static std::string GetConsoleLibraryList(); + static void GetConsoleLibraryList(std::back_insert_iterator &output_iterator); /** Wrapper function for AIScanner::GetAIInfoList */ static const ScriptInfoList *GetInfoList(); /** Wrapper function for AIScanner::GetUniqueAIInfoList */ diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index 0660dfe0f5..1251b652af 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -289,14 +289,14 @@ } } -/* static */ std::string AI::GetConsoleList(bool newest_only) +/* static */ void AI::GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only) { - return AI::scanner_info->GetConsoleList(newest_only); + AI::scanner_info->GetConsoleList(output_iterator, newest_only); } -/* static */ std::string AI::GetConsoleLibraryList() +/* static */ void AI::GetConsoleLibraryList(std::back_insert_iterator &output_iterator) { - return AI::scanner_library->GetConsoleList(true); + AI::scanner_library->GetConsoleList(output_iterator, true); } /* static */ const ScriptInfoList *AI::GetInfoList() diff --git a/src/base_media_base.h b/src/base_media_base.h index 9131cbae58..7c36002946 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -192,7 +192,7 @@ public: static Tbase_set *GetAvailableSets(); static bool SetSet(const std::string &name); - static char *GetSetsList(char *p, const char *last); + static void GetSetsList(std::back_insert_iterator &output_iterator); static int GetNumSets(); static int GetIndexOfUsedSet(); static const Tbase_set *GetSet(int index); diff --git a/src/base_media_func.h b/src/base_media_func.h index 102f0a412b..b5ffe7dc8a 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -248,31 +248,27 @@ template /** * Returns a list with the sets. - * @param p where to print to - * @param last the last character to print to - * @return the last printed character + * @param output_iterator The iterator to write the string to. */ template -/* static */ char *BaseMedia::GetSetsList(char *p, const char *last) +/* static */ void BaseMedia::GetSetsList(std::back_insert_iterator &output_iterator) { - p += seprintf(p, last, "List of " SET_TYPE " sets:\n"); + fmt::format_to(output_iterator, "List of " SET_TYPE " sets:\n"); for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { - p += seprintf(p, last, "%18s: %s", s->name.c_str(), s->GetDescription({})); + fmt::format_to(output_iterator, "{:>18}: {}", s->name, s->GetDescription({})); int invalid = s->GetNumInvalid(); if (invalid != 0) { int missing = s->GetNumMissing(); if (missing == 0) { - p += seprintf(p, last, " (%i corrupt file%s)\n", invalid, invalid == 1 ? "" : "s"); + fmt::format_to(output_iterator, " ({} corrupt file{})\n", invalid, invalid == 1 ? "" : "s"); } else { - p += seprintf(p, last, " (unusable: %i missing file%s)\n", missing, missing == 1 ? "" : "s"); + fmt::format_to(output_iterator, " (unusable: {} missing file{})\n", missing, missing == 1 ? "" : "s"); } } else { - p += seprintf(p, last, "\n"); + fmt::format_to(output_iterator, "\n"); } } - p += seprintf(p, last, "\n"); - - return p; + fmt::format_to(output_iterator, "\n"); } #include "network/core/tcp_content_type.h" @@ -378,7 +374,7 @@ template template bool repl_type::AddFile(const std::string &filename, size_t pathlength, const std::string &tar_filename); \ template bool repl_type::HasSet(const struct ContentInfo *ci, bool md5sum); \ template bool repl_type::SetSet(const std::string &name); \ - template char *repl_type::GetSetsList(char *p, const char *last); \ + template void repl_type::GetSetsList(std::back_insert_iterator &output_iterator); \ template int repl_type::GetNumSets(); \ template int repl_type::GetIndexOfUsedSet(); \ template const set_type *repl_type::GetSet(int index); \ diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp index 77911fc31c..3def36d0ad 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.hpp @@ -146,16 +146,14 @@ public: * @param last The last element of the buffer. * @return p The location till where we filled the buffer. */ - static char *GetBlittersInfo(char *p, const char *last) + static void GetBlittersInfo(std::back_insert_iterator &output_iterator) { - p += seprintf(p, last, "List of blitters:\n"); + fmt::format_to(output_iterator, "List of blitters:\n"); for (auto &it : GetBlitters()) { BlitterFactory *b = it.second; - p += seprintf(p, last, "%18s: %s\n", b->name.c_str(), b->GetDescription().c_str()); + fmt::format_to(output_iterator, "{:>18}: {}\n", b->name, b->GetDescription()); } - p += seprintf(p, last, "\n"); - - return p; + fmt::format_to(output_iterator, "\n"); } /** diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 8519c0d217..0980ffcfce 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1180,6 +1180,17 @@ static void PrintLineByLine(const std::string &full_string) } } +template +bool PrintList(F list_function, Args... args) +{ + std::string output_str; + auto inserter = std::back_inserter(output_str); + list_function(inserter, args...); + PrintLineByLine(output_str); + + return true; +} + DEF_CONSOLE_CMD(ConListAILibs) { if (argc == 0) { @@ -1187,10 +1198,7 @@ DEF_CONSOLE_CMD(ConListAILibs) return true; } - const std::string output_str = AI::GetConsoleLibraryList(); - PrintLineByLine(output_str); - - return true; + return PrintList(AI::GetConsoleLibraryList); } DEF_CONSOLE_CMD(ConListAI) @@ -1200,10 +1208,7 @@ DEF_CONSOLE_CMD(ConListAI) return true; } - const std::string output_str = AI::GetConsoleList(); - PrintLineByLine(output_str); - - return true; + return PrintList(AI::GetConsoleList, false); } DEF_CONSOLE_CMD(ConListGameLibs) @@ -1213,10 +1218,7 @@ DEF_CONSOLE_CMD(ConListGameLibs) return true; } - const std::string output_str = Game::GetConsoleLibraryList(); - PrintLineByLine(output_str); - - return true; + return PrintList(Game::GetConsoleLibraryList); } DEF_CONSOLE_CMD(ConListGame) @@ -1226,10 +1228,7 @@ DEF_CONSOLE_CMD(ConListGame) return true; } - const std::string output_str = Game::GetConsoleList(); - PrintLineByLine(output_str); - - return true; + return PrintList(Game::GetConsoleList, false); } DEF_CONSOLE_CMD(ConStartAI) diff --git a/src/debug.cpp b/src/debug.cpp index c82d75236e..b088af9aaa 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -85,27 +85,23 @@ struct DebugLevel { /** * Dump the available debug facility names in the help text. - * @param buf Start address for storing the output. - * @param last Last valid address for storing the output. - * @return Next free position in the output. + * @param output_iterator The iterator to write the string to. */ -char *DumpDebugFacilityNames(char *buf, char *last) +void DumpDebugFacilityNames(std::back_insert_iterator &output_iterator) { - size_t length = 0; + bool written = false; for (const DebugLevel *i = debug_level; i != endof(debug_level); ++i) { - if (length == 0) { - buf = strecpy(buf, "List of debug facility names:\n", last); + if (!written) { + fmt::format_to(output_iterator, "List of debug facility names:\n"); } else { - buf = strecpy(buf, ", ", last); - length += 2; + fmt::format_to(output_iterator, ", "); } - buf = strecpy(buf, i->name, last); - length += strlen(i->name); + fmt::format_to(output_iterator, i->name); + written = true; } - if (length > 0) { - buf = strecpy(buf, "\n\n", last); + if (written) { + fmt::format_to(output_iterator, "\n\n"); } - return buf; } /** diff --git a/src/debug.h b/src/debug.h index 125c5403c5..bb939ccc4c 100644 --- a/src/debug.h +++ b/src/debug.h @@ -56,7 +56,7 @@ extern int _debug_console_level; extern int _debug_random_level; #endif -char *DumpDebugFacilityNames(char *buf, char *last); +void DumpDebugFacilityNames(std::back_insert_iterator &output_iterator); void SetDebugString(const char *s, void (*error_func)(const std::string &)); const char *GetDebugString(); diff --git a/src/driver.cpp b/src/driver.cpp index eefcbbcb12..10a20599b1 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -179,28 +179,24 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t /** * Build a human readable list of available drivers, grouped by type. - * @param p The buffer to write to. - * @param last The last element in the buffer. - * @return The end of the written buffer. + * @param output_iterator The iterator to write the string to. */ -char *DriverFactoryBase::GetDriversInfo(char *p, const char *last) +void DriverFactoryBase::GetDriversInfo(std::back_insert_iterator &output_iterator) { for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) { - p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type)); + fmt::format_to(output_iterator, "List of {} drivers:\n", GetDriverTypeName(type)); for (int priority = 10; priority >= 0; priority--) { for (auto &it : GetDrivers()) { DriverFactoryBase *d = it.second; if (d->type != type) continue; if (d->priority != priority) continue; - p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription()); + fmt::format_to(output_iterator, "{:>18}: {}\n", d->name, d->GetDescription()); } } - p += seprintf(p, last, "\n"); + fmt::format_to(output_iterator, "\n"); } - - return p; } /** diff --git a/src/driver.h b/src/driver.h index 91287fbdb2..80b05b41bd 100644 --- a/src/driver.h +++ b/src/driver.h @@ -127,7 +127,7 @@ public: } static void SelectDriver(const std::string &name, Driver::Type type); - static char *GetDriversInfo(char *p, const char *last); + static void GetDriversInfo(std::back_insert_iterator &output_iterator); /** * Get a nice description of the driver-class. diff --git a/src/game/game.hpp b/src/game/game.hpp index 3c8fcdad92..c3664cd696 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -83,9 +83,9 @@ public: static void Save(); /** Wrapper function for GameScanner::GetConsoleList */ - static std::string GetConsoleList(bool newest_only = false); + static void GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only); /** Wrapper function for GameScanner::GetConsoleLibraryList */ - static std::string GetConsoleLibraryList(); + static void GetConsoleLibraryList(std::back_insert_iterator &output_iterator); /** Wrapper function for GameScanner::GetInfoList */ static const ScriptInfoList *GetInfoList(); /** Wrapper function for GameScanner::GetUniqueInfoList */ diff --git a/src/game/game_core.cpp b/src/game/game_core.cpp index c67446f7cc..865aa2a8fc 100644 --- a/src/game/game_core.cpp +++ b/src/game/game_core.cpp @@ -219,14 +219,14 @@ } } -/* static */ std::string Game::GetConsoleList(bool newest_only) +/* static */ void Game::GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only) { - return Game::scanner_info->GetConsoleList(newest_only); + Game::scanner_info->GetConsoleList(output_iterator, newest_only); } -/* static */ std::string Game::GetConsoleLibraryList() +/* static */ void Game::GetConsoleLibraryList(std::back_insert_iterator &output_iterator) { - return Game::scanner_library->GetConsoleList(true); + Game::scanner_library->GetConsoleList(output_iterator, true); } /* static */ const ScriptInfoList *Game::GetInfoList() diff --git a/src/openttd.cpp b/src/openttd.cpp index 6444d410b9..61c0e1da9d 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -155,11 +155,12 @@ void FatalErrorI(const std::string &str) */ static void ShowHelp() { - char buf[8192]; - char *p = buf; + std::string str; + str.reserve(8192); - p += seprintf(p, lastof(buf), "OpenTTD %s\n", _openttd_revision); - p = strecpy(p, + std::back_insert_iterator output_iterator = std::back_inserter(str); + fmt::format_to(output_iterator, "OpenTTD {}\n", _openttd_revision); + str += "\n" "\n" "Command line options:\n" @@ -191,46 +192,42 @@ static void ShowHelp() " -q savegame = Write some information about the savegame and exit\n" " -Q = Don't scan for/load NewGRF files on startup\n" " -QQ = Disable NewGRF scanning/loading entirely\n" - "\n", - lastof(buf) - ); + "\n"; /* List the graphics packs */ - p = BaseGraphics::GetSetsList(p, lastof(buf)); + BaseGraphics::GetSetsList(output_iterator); /* List the sounds packs */ - p = BaseSounds::GetSetsList(p, lastof(buf)); + BaseSounds::GetSetsList(output_iterator); /* List the music packs */ - p = BaseMusic::GetSetsList(p, lastof(buf)); + BaseMusic::GetSetsList(output_iterator); /* List the drivers */ - p = DriverFactoryBase::GetDriversInfo(p, lastof(buf)); + DriverFactoryBase::GetDriversInfo(output_iterator); /* List the blitters */ - p = BlitterFactory::GetBlittersInfo(p, lastof(buf)); + BlitterFactory::GetBlittersInfo(output_iterator); /* List the debug facilities. */ - p = DumpDebugFacilityNames(p, lastof(buf)); + DumpDebugFacilityNames(output_iterator); /* We need to initialize the AI, so it finds the AIs */ AI::Initialize(); - const std::string ai_list = AI::GetConsoleList(true); - p = strecpy(p, ai_list.c_str(), lastof(buf)); + AI::GetConsoleList(output_iterator, true); AI::Uninitialize(true); /* We need to initialize the GameScript, so it finds the GSs */ Game::Initialize(); - const std::string game_list = Game::GetConsoleList(true); - p = strecpy(p, game_list.c_str(), lastof(buf)); + Game::GetConsoleList(output_iterator, true); Game::Uninitialize(true); /* ShowInfo put output to stderr, but version information should go * to stdout; this is the only exception */ #if !defined(_WIN32) - printf("%s\n", buf); + printf("%s\n", str.c_str()); #else - ShowInfoI(buf); + ShowInfoI(str); #endif } diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 850ae245bf..bb5bd413fc 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -138,18 +138,15 @@ void ScriptScanner::RegisterScript(ScriptInfo *info) } } -std::string ScriptScanner::GetConsoleList(bool newest_only) const +void ScriptScanner::GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only) const { - std::string p; - p += fmt::format("List of {}:\n", this->GetScannerName()); + fmt::format_to(output_iterator, "List of {}:\n", this->GetScannerName()); const ScriptInfoList &list = newest_only ? this->info_single_list : this->info_list; for (const auto &item : list) { ScriptInfo *i = item.second; - p += fmt::format("{:>10} (v{:d}): {}\n", i->GetName(), i->GetVersion(), i->GetDescription()); + fmt::format_to(output_iterator, "{:>10} (v{:d}): {}\n", i->GetName(), i->GetVersion(), i->GetDescription()); } - p += "\n"; - - return p; + fmt::format_to(output_iterator, "\n"); } /** Helper for creating a MD5sum of all files within of a script. */ diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp index 9b0ad6bf31..1f5dca0485 100644 --- a/src/script/script_scanner.hpp +++ b/src/script/script_scanner.hpp @@ -55,8 +55,10 @@ public: /** * Get the list of registered scripts to print on the console. + * @param output_iterator The iterator to write the output to. + * @param newest_only Whether to only show the newest scripts. */ - std::string GetConsoleList(bool newest_only) const; + void GetConsoleList(std::back_insert_iterator &output_iterator, bool newest_only) const; /** * Check whether we have a script with the exact characteristics as ci.