From 9059215b3b06a07eb75b6d68e207c6d1de7cf445 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Mon, 10 Oct 2022 12:19:58 +0100 Subject: [PATCH] Fix #10073: Stop truncating output of list_ai and friends commands --- src/ai/ai.hpp | 4 ++-- src/ai/ai_core.cpp | 8 +++---- src/console_cmds.cpp | 39 ++++++++++++++--------------------- src/game/game.hpp | 4 ++-- src/game/game_core.cpp | 8 +++---- src/openttd.cpp | 6 ++++-- src/script/script_scanner.cpp | 9 ++++---- src/script/script_scanner.hpp | 2 +- 8 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp index 59886486fe..f9112fc177 100644 --- a/src/ai/ai.hpp +++ b/src/ai/ai.hpp @@ -139,9 +139,9 @@ public: static int GetStartNextTime(); /** Wrapper function for AIScanner::GetAIConsoleList */ - static char *GetConsoleList(char *p, const char *last, bool newest_only = false); + static std::string GetConsoleList(bool newest_only = false); /** Wrapper function for AIScanner::GetAIConsoleLibraryList */ - static char *GetConsoleLibraryList(char *p, const char *last); + static std::string GetConsoleLibraryList(); /** 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 e45738776d..add76e0685 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -315,14 +315,14 @@ return DAYS_IN_YEAR; } -/* static */ char *AI::GetConsoleList(char *p, const char *last, bool newest_only) +/* static */ std::string AI::GetConsoleList(bool newest_only) { - return AI::scanner_info->GetConsoleList(p, last, newest_only); + return AI::scanner_info->GetConsoleList(newest_only); } -/* static */ char *AI::GetConsoleLibraryList(char *p, const char *last) +/* static */ std::string AI::GetConsoleLibraryList() { - return AI::scanner_library->GetConsoleList(p, last, true); + return AI::scanner_library->GetConsoleList(true); } /* static */ const ScriptInfoList *AI::GetInfoList() diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 61c0c331d9..2936a8a147 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -45,6 +45,8 @@ #include "company_cmd.h" #include "misc_cmd.h" +#include + #include "safeguards.h" /* scriptfile handling */ @@ -1160,19 +1162,14 @@ DEF_CONSOLE_CMD(ConReload) /** * Print a text buffer line by line to the console. Lines are separated by '\n'. - * @param buf The buffer to print. - * @note All newlines are replace by '\0' characters. + * @param full_string The multi-line string to print. */ -static void PrintLineByLine(char *buf) +static void PrintLineByLine(const std::string &full_string) { - char *p = buf; - /* Print output line by line */ - for (char *p2 = buf; *p2 != '\0'; p2++) { - if (*p2 == '\n') { - *p2 = '\0'; - IConsolePrint(CC_DEFAULT, p); - p = p2 + 1; - } + std::istringstream in(full_string); + std::string line; + while (std::getline(in, line)) { + IConsolePrint(CC_DEFAULT, line.c_str()); } } @@ -1182,10 +1179,9 @@ DEF_CONSOLE_CMD(ConListAILibs) IConsolePrint(CC_HELP, "List installed AI libraries. Usage: 'list_ai_libs'."); return true; } - char buf[4096]; - AI::GetConsoleLibraryList(buf, lastof(buf)); - PrintLineByLine(buf); + const std::string output_str = AI::GetConsoleLibraryList(); + PrintLineByLine(output_str); return true; } @@ -1196,10 +1192,9 @@ DEF_CONSOLE_CMD(ConListAI) IConsolePrint(CC_HELP, "List installed AIs. Usage: 'list_ai'."); return true; } - char buf[4096]; - AI::GetConsoleList(buf, lastof(buf)); - PrintLineByLine(buf); + const std::string output_str = AI::GetConsoleList(); + PrintLineByLine(output_str); return true; } @@ -1210,10 +1205,9 @@ DEF_CONSOLE_CMD(ConListGameLibs) IConsolePrint(CC_HELP, "List installed Game Script libraries. Usage: 'list_game_libs'."); return true; } - char buf[4096]; - Game::GetConsoleLibraryList(buf, lastof(buf)); - PrintLineByLine(buf); + const std::string output_str = Game::GetConsoleLibraryList(); + PrintLineByLine(output_str); return true; } @@ -1224,10 +1218,9 @@ DEF_CONSOLE_CMD(ConListGame) IConsolePrint(CC_HELP, "List installed Game Scripts. Usage: 'list_game'."); return true; } - char buf[4096]; - Game::GetConsoleList(buf, lastof(buf)); - PrintLineByLine(buf); + const std::string output_str = Game::GetConsoleList(); + PrintLineByLine(output_str); return true; } diff --git a/src/game/game.hpp b/src/game/game.hpp index 8381a6c148..c72b081be6 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -93,9 +93,9 @@ public: static void Load(int version); /** Wrapper function for GameScanner::GetConsoleList */ - static char *GetConsoleList(char *p, const char *last, bool newest_only = false); + static std::string GetConsoleList(bool newest_only = false); /** Wrapper function for GameScanner::GetConsoleLibraryList */ - static char *GetConsoleLibraryList(char *p, const char *last); + static std::string GetConsoleLibraryList(); /** 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 19d8bbf54e..32ca99e6a4 100644 --- a/src/game/game_core.cpp +++ b/src/game/game_core.cpp @@ -225,14 +225,14 @@ } } -/* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only) +/* static */ std::string Game::GetConsoleList(bool newest_only) { - return Game::scanner_info->GetConsoleList(p, last, newest_only); + return Game::scanner_info->GetConsoleList(newest_only); } -/* static */ char *Game::GetConsoleLibraryList(char *p, const char *last) +/* static */ std::string Game::GetConsoleLibraryList() { - return Game::scanner_library->GetConsoleList(p, last, true); + return Game::scanner_library->GetConsoleList(true); } /* static */ const ScriptInfoList *Game::GetInfoList() diff --git a/src/openttd.cpp b/src/openttd.cpp index 1b5e7be0ce..4ba83620f9 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -227,12 +227,14 @@ static void ShowHelp() /* We need to initialize the AI, so it finds the AIs */ AI::Initialize(); - p = AI::GetConsoleList(p, lastof(buf), true); + const std::string ai_list = AI::GetConsoleList(true); + p = strecpy(p, ai_list.c_str(), lastof(buf)); AI::Uninitialize(true); /* We need to initialize the GameScript, so it finds the GSs */ Game::Initialize(); - p = Game::GetConsoleList(p, lastof(buf), true); + const std::string game_list = Game::GetConsoleList(true); + p = strecpy(p, game_list.c_str(), lastof(buf)); Game::Uninitialize(true); /* ShowInfo put output to stderr, but version information should go diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 319a1c7fc0..3b76b7b651 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -145,15 +145,16 @@ void ScriptScanner::RegisterScript(ScriptInfo *info) } } -char *ScriptScanner::GetConsoleList(char *p, const char *last, bool newest_only) const +std::string ScriptScanner::GetConsoleList(bool newest_only) const { - p += seprintf(p, last, "List of %s:\n", this->GetScannerName()); + std::string p; + p += fmt::format("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 += seprintf(p, last, "%10s (v%d): %s\n", i->GetName(), i->GetVersion(), i->GetDescription()); + p += fmt::format("{:>10} (v{:d}): {}\n", i->GetName(), i->GetVersion(), i->GetDescription()); } - p += seprintf(p, last, "\n"); + p += "\n"; return p; } diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp index ca9068ca10..9781e07b69 100644 --- a/src/script/script_scanner.hpp +++ b/src/script/script_scanner.hpp @@ -57,7 +57,7 @@ public: /** * Get the list of registered scripts to print on the console. */ - char *GetConsoleList(char *p, const char *last, bool newest_only) const; + std::string GetConsoleList(bool newest_only) const; /** * Check whether we have a script with the exact characteristics as ci.