From 4149384ebc8c49453cd7c73b09b6cf7485a93d48 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 22 Apr 2025 21:47:59 +0200 Subject: [PATCH] Codechange: simplify and move GetArgumentInteger --- src/console.cpp | 24 -------------- src/console_cmds.cpp | 72 ++++++++++++++++++++++++++++-------------- src/console_internal.h | 3 -- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 675b8bbcb5..d2eb84ec01 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -117,30 +117,6 @@ void IConsolePrint(TextColour colour_code, const std::string &string) IConsoleGUIPrint(colour_code, str); } -/** - * Change a string into its number representation. Supports - * decimal and hexadecimal numbers as well as 'on'/'off' 'true'/'false' - * @param *value the variable a successful conversion will be put in - * @param *arg the string to be converted - * @return Return true on success or false on failure - */ -bool GetArgumentInteger(uint32_t *value, const char *arg) -{ - char *endptr; - - if (strcmp(arg, "on") == 0 || strcmp(arg, "true") == 0) { - *value = 1; - return true; - } - if (strcmp(arg, "off") == 0 || strcmp(arg, "false") == 0) { - *value = 0; - return true; - } - - *value = std::strtoul(arg, &endptr, 0); - return arg != endptr; -} - /** * Creates a copy of a string with underscores removed from it * @param name String to remove the underscores from. diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 80df076665..a0d34be2ba 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -8,6 +8,7 @@ /** @file console_cmds.cpp Implementation of the console hooks. */ #include "stdafx.h" +#include "core/string_consumer.hpp" #include "console_internal.h" #include "debug.h" #include "engine_func.h" @@ -70,6 +71,17 @@ static IntervalTimer _scheduled_monthly_timer = {{TimerGameCa IConsoleCmdExec(std::string("exec") + " " + filename); }}; + +/** + * Change a string into its number representation. Supports decimal and hexadecimal numbers. + * @param arg The string to be converted. + * @return The number, or std::nullopt when it could not be parsed. + */ +static std::optional ParseInteger(std::string_view arg) +{ + return StringConsumer{arg}.TryReadIntegerBase(0); +} + /** File list storage for the console, for caching the last 'ls' command. */ class ConsoleFileList : public FileList { public: @@ -275,9 +287,9 @@ static bool ConResetTile([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *a } if (argc == 2) { - uint32_t result; - if (GetArgumentInteger(&result, argv[1])) { - DoClearSquare((TileIndex)result); + auto result = ParseInteger(argv[1]); + if (result.has_value() && IsValidTile(*result)) { + DoClearSquare(TileIndex{*result}); return true; } } @@ -312,25 +324,25 @@ static bool ConZoomToLevel([[maybe_unused]] uint8_t argc, [[maybe_unused]] char return true; case 2: { - uint32_t level; - if (GetArgumentInteger(&level, argv[1])) { + auto level = ParseInteger(argv[1]); + if (level.has_value()) { /* In case ZOOM_LVL_MIN is more than 0, the next if statement needs to be amended. * A simple check for less than ZOOM_LVL_MIN does not work here because we are * reading an unsigned integer from the console, so just check for a '-' char. */ static_assert(ZOOM_LVL_MIN == 0); if (argv[1][0] == '-') { IConsolePrint(CC_ERROR, "Zoom-in levels below {} are not supported.", ZOOM_LVL_MIN); - } else if (level < _settings_client.gui.zoom_min) { + } else if (*level < _settings_client.gui.zoom_min) { IConsolePrint(CC_ERROR, "Current client settings do not allow zooming in below level {}.", _settings_client.gui.zoom_min); - } else if (level > ZOOM_LVL_MAX) { + } else if (*level > ZOOM_LVL_MAX) { IConsolePrint(CC_ERROR, "Zoom-in levels above {} are not supported.", ZOOM_LVL_MAX); - } else if (level > _settings_client.gui.zoom_max) { + } else if (*level > _settings_client.gui.zoom_max) { IConsolePrint(CC_ERROR, "Current client settings do not allow zooming out beyond level {}.", _settings_client.gui.zoom_max); } else { Window *w = GetMainWindow(); Viewport &vp = *w->viewport; - while (vp.zoom > level) DoZoomInOutWindow(ZOOM_IN, w); - while (vp.zoom < level) DoZoomInOutWindow(ZOOM_OUT, w); + while (vp.zoom > *level) DoZoomInOutWindow(ZOOM_IN, w); + while (vp.zoom < *level) DoZoomInOutWindow(ZOOM_OUT, w); } return true; } @@ -370,26 +382,27 @@ static bool ConScrollToTile([[maybe_unused]] uint8_t argc, [[maybe_unused]] char switch (argc - arg_index) { case 1: { - uint32_t result; - if (GetArgumentInteger(&result, argv[arg_index])) { - if (result >= Map::Size()) { + auto result = ParseInteger(argv[arg_index]); + if (result.has_value()) { + if (*result >= Map::Size()) { IConsolePrint(CC_ERROR, "Tile does not exist."); return true; } - ScrollMainWindowToTile((TileIndex)result, instant); + ScrollMainWindowToTile(TileIndex{*result}, instant); return true; } break; } case 2: { - uint32_t x, y; - if (GetArgumentInteger(&x, argv[arg_index]) && GetArgumentInteger(&y, argv[arg_index + 1])) { - if (x >= Map::SizeX() || y >= Map::SizeY()) { + auto x = ParseInteger(argv[arg_index]); + auto y = ParseInteger(argv[arg_index + 1]); + if (x.has_value() && y.has_value()) { + if (*x >= Map::SizeX() || *y >= Map::SizeY()) { IConsolePrint(CC_ERROR, "Tile does not exist."); return true; } - ScrollMainWindowToTile(TileXY(x, y), instant); + ScrollMainWindowToTile(TileXY(*x, *y), instant); return true; } break; @@ -1690,8 +1703,19 @@ static bool ConScreenShot([[maybe_unused]] uint8_t argc, [[maybe_unused]] char * IConsolePrint(CC_ERROR, "'size' can only be used in combination with 'normal' or 'big'."); return true; } - GetArgumentInteger(&width, argv[arg_index + 1]); - GetArgumentInteger(&height, argv[arg_index + 2]); + auto t = ParseInteger(argv[arg_index + 1]); + if (!t.has_value()) { + IConsolePrint(CC_ERROR, "Invalid width '{}'", argv[arg_index + 1]); + return true; + } + width = *t; + + t = ParseInteger(argv[arg_index + 2]); + if (!t.has_value()) { + IConsolePrint(CC_ERROR, "Invalid height '{}'", argv[arg_index + 2]); + return true; + } + height = *t; arg_index += 3; } @@ -2247,18 +2271,18 @@ static bool ConFont([[maybe_unused]] uint8_t argc, [[maybe_unused]] char *argv[] FontCacheSubSetting *setting = GetFontCacheSubSetting(argfs); std::string font = setting->font; uint size = setting->size; - uint v; uint8_t arg_index = 2; /* For we want a string. */ - if (!GetArgumentInteger(&v, argv[arg_index])) { + if (!ParseInteger(argv[arg_index]).has_value()) { font = argv[arg_index++]; } if (argc > arg_index) { /* For we want a number. */ - if (GetArgumentInteger(&v, argv[arg_index])) { - size = v; + auto v = ParseInteger(argv[arg_index]); + if (v.has_value()) { + size = *v; arg_index++; } } diff --git a/src/console_internal.h b/src/console_internal.h index cbf4c61bc5..b1481e7d53 100644 --- a/src/console_internal.h +++ b/src/console_internal.h @@ -81,9 +81,6 @@ void IConsoleClearBuffer(); /* console std lib (register ingame commands/aliases) */ void IConsoleStdLibRegister(); -/* Supporting functions */ -bool GetArgumentInteger(uint32_t *value, const char *arg); - void IConsoleGUIInit(); void IConsoleGUIFree(); void IConsoleGUIPrint(TextColour colour_code, const std::string &string);