1
0
Fork 0

Codechange: replace char* in GetOptData with std::string_view

pull/14178/head
Rubidium 2025-04-30 22:19:11 +02:00 committed by rubidium42
parent c1a287ad17
commit fbe80f31fe
9 changed files with 58 additions and 57 deletions

View File

@ -21,30 +21,30 @@
*/
int GetOptData::GetOpt()
{
const char *s = this->cont;
if (s == nullptr) {
std::string_view s = this->cont;
if (s.empty()) {
if (this->arguments.empty()) return -1; // No arguments left -> finished.
s = this->arguments[0];
if (*s != '-') return -1; // No leading '-' -> not an option -> finished.
if (s[0] != '-') return -1; // No leading '-' -> not an option -> finished.
this->arguments = this->arguments.subspan(1);
/* Is it a long option? */
for (auto &option : this->options) {
if (option.longname != nullptr && !strcmp(option.longname, s)) { // Long options always use the entire argument.
this->cont = nullptr;
if (option.longname == s) { // Long options always use the entire argument.
this->cont = {};
return this->GetOpt(option);
}
}
s++; // Skip leading '-'.
s.remove_prefix(1); // Skip leading '-'.
}
/* Is it a short option? */
for (auto &option : this->options) {
if (option.shortname != '\0' && *s == option.shortname) {
this->cont = (s[1] != '\0') ? s + 1 : nullptr;
if (option.shortname != '\0' && s[0] == option.shortname) {
this->cont = s.substr(1);
return this->GetOpt(option);
}
}
@ -54,16 +54,16 @@ int GetOptData::GetOpt()
int GetOptData::GetOpt(const OptionData &option)
{
this->opt = nullptr;
this->opt = {};
switch (option.type) {
case ODF_NO_VALUE:
return option.id;
case ODF_HAS_VALUE:
case ODF_OPTIONAL_VALUE:
if (this->cont != nullptr) { // Remainder of the argument is the option value.
if (!this->cont.empty()) { // Remainder of the argument is the option value.
this->opt = this->cont;
this->cont = nullptr;
this->cont = {};
return option.id;
}
/* No more arguments, either return an error or a value-less option. */

View File

@ -22,18 +22,18 @@ struct OptionData {
OptionDataType type; ///< The type of option.
char id; ///< Unique identification of this option data, often the same as #shortname.
char shortname = '\0'; ///< Short option letter if available, else use \c '\0'.
const char *longname = nullptr; ///< Long option name including '-'/'--' prefix, use \c nullptr if not available.
std::string_view longname{}; ///< Long option name including '-'/'--' prefix, leave empty if not available.
};
/** Data storage for parsing command line options. */
struct GetOptData {
using OptionSpan = std::span<const OptionData>;
using ArgumentSpan = std::span<char * const>;
using ArgumentSpan = std::span<std::string_view>;
ArgumentSpan arguments; ///< Remaining command line arguments.
const OptionSpan options; ///< Command line option descriptions.
const char *opt = nullptr; ///< Option value, if available (else \c nullptr).
const char *cont = nullptr; ///< Next call to #GetOpt should start here (in the middle of an argument).
std::string_view opt; ///< Option value, if available (else empty).
std::string_view cont; ///< Next call to #GetOpt should start here (in the middle of an argument).
/**
* Constructor of the data store.

View File

@ -497,7 +497,7 @@ static std::vector<OptionData> CreateOptions()
* @param arguments The command line arguments passed to the application.
* @return 0 when there is no error.
*/
int openttd_main(std::span<char * const> arguments)
int openttd_main(std::span<std::string_view> arguments)
{
_game_session_stats.start_time = std::chrono::steady_clock::now();
_game_session_stats.savegame_size = std::nullopt;
@ -541,7 +541,7 @@ int openttd_main(std::span<char * const> arguments)
blitter = "null";
dedicated = true;
SetDebugString("net=4", ShowInfoI);
if (mgo.opt != nullptr) {
if (!mgo.opt.empty()) {
scanner->dedicated_host = ParseFullConnectionString(mgo.opt, scanner->dedicated_port);
}
break;
@ -564,7 +564,7 @@ int openttd_main(std::span<char * const> arguments)
#if defined(_WIN32)
CreateConsole();
#endif
if (mgo.opt != nullptr) SetDebugString(mgo.opt, ShowInfoI);
if (!mgo.opt.empty()) SetDebugString(mgo.opt, ShowInfoI);
break;
}
case 'e':
@ -577,7 +577,7 @@ int openttd_main(std::span<char * const> arguments)
}
break;
case 'g':
if (mgo.opt != nullptr) {
if (!mgo.opt.empty()) {
_file_to_saveload.name = mgo.opt;
std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(_file_to_saveload.name)).extension().native());
@ -609,7 +609,7 @@ int openttd_main(std::span<char * const> arguments)
break;
case 'q': {
DeterminePaths(arguments[0], only_local_path);
if (StrEmpty(mgo.opt)) {
if (mgo.opt.empty()) {
ret = 1;
return ret;
}

View File

@ -83,7 +83,7 @@ extern PauseModes _pause_mode;
void AskExitGame();
void AskExitToGameMenu();
int openttd_main(std::span<char * const> arguments);
int openttd_main(std::span<std::string_view> arguments);
void StateGameLoop();
void HandleExitGameRequest();

View File

@ -26,13 +26,16 @@ void CocoaReleaseAutoreleasePool();
int CDECL main(int argc, char *argv[])
{
/* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
std::vector<std::string_view> params;
for (int i = 0; i < argc; ++i) {
StrMakeValidInPlace(argv[i]);
params.emplace_back(argv[i]);
}
CocoaSetupAutoreleasePool();
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
argv[1] = nullptr;
argc = 1;
if (params.size() >= 2 && params[1].starts_with("-psn")) {
params.resize(1);
}
CrashLog::InitialiseCrashLog();
@ -41,7 +44,7 @@ int CDECL main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
int ret = openttd_main(std::span(argv, argc));
int ret = openttd_main(params);
CocoaReleaseAutoreleasePool();

View File

@ -21,7 +21,11 @@
int CDECL main(int argc, char *argv[])
{
/* Make sure our arguments contain only valid UTF-8 characters. */
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
std::vector<std::string_view> params;
for (int i = 0; i < argc; ++i) {
StrMakeValidInPlace(argv[i]);
params.emplace_back(argv[i]);
}
CrashLog::InitialiseCrashLog();
@ -29,5 +33,5 @@ int CDECL main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
return openttd_main(std::span(argv, argc));
return openttd_main(params);
}

View File

@ -12,37 +12,31 @@
#include <mmsystem.h>
#include "../../openttd.h"
#include "../../core/random_func.hpp"
#include "../../core/string_consumer.hpp"
#include "../../string_func.h"
#include "../../crashlog.h"
#include "../../debug.h"
#include "../../safeguards.h"
static auto ParseCommandLine(char *line)
static auto ParseCommandLine(std::string_view line)
{
std::vector<char *> arguments;
for (;;) {
/* skip whitespace */
while (*line == ' ' || *line == '\t') line++;
std::vector<std::string_view> arguments;
/* end? */
if (*line == '\0') break;
StringConsumer consumer{line};
while (consumer.AnyBytesLeft()) {
consumer.SkipUntilCharNotIn(StringConsumer::WHITESPACE_NO_NEWLINE);
if (!consumer.AnyBytesLeft()) break;
/* special handling when quoted */
if (*line == '"') {
arguments.push_back(++line);
while (*line != '"') {
if (*line == '\0') return arguments;
line++;
}
std::string_view argument;
if (consumer.ReadIf("\"")) {
/* special handling when quoted */
argument = consumer.ReadUntil("\"", StringConsumer::SKIP_ONE_SEPARATOR);
} else {
arguments.push_back(line);
while (*line != ' ' && *line != '\t') {
if (*line == '\0') return arguments;
line++;
}
argument = consumer.ReadUntilCharIn(StringConsumer::WHITESPACE_NO_NEWLINE);
}
*line++ = '\0';
arguments.push_back(argument);
};
return arguments;
@ -57,8 +51,8 @@ int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
CrashLog::InitialiseCrashLog();
/* Convert the command line to UTF-8. */
std::string cmdline = FS2OTTD(GetCommandLine());
/* Convert the command line to valid UTF-8. */
std::string cmdline = StrMakeValid(FS2OTTD(GetCommandLine()));
/* Set the console codepage to UTF-8. */
SetConsoleOutputCP(CP_UTF8);
@ -72,11 +66,7 @@ int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
/* setup random seed to something quite random */
SetRandomSeed(GetTickCount());
auto arguments = ParseCommandLine(cmdline.data());
/* Make sure our arguments contain only valid UTF-8 characters. */
for (auto argument : arguments) StrMakeValidInPlace(argument);
auto arguments = ParseCommandLine(cmdline);
int ret = openttd_main(arguments);
/* Restore system timer resolution. */

View File

@ -403,7 +403,9 @@ int CDECL main(int argc, char *argv[])
std::optional<std::string_view> before_file;
std::optional<std::string_view> after_file;
GetOptData mgo(std::span(argv + 1, argc - 1), _opts);
std::vector<std::string_view> params;
for (int i = 1; i < argc; ++i) params.emplace_back(argv[i]);
GetOptData mgo(params, _opts);
for (;;) {
int i = mgo.GetOpt();
if (i == -1) break;

View File

@ -322,7 +322,9 @@ int CDECL main(int argc, char *argv[])
std::filesystem::path src_dir(".");
std::filesystem::path dest_dir;
GetOptData mgo(std::span(argv + 1, argc - 1), _opts);
std::vector<std::string_view> params;
for (int i = 1; i < argc; ++i) params.emplace_back(argv[i]);
GetOptData mgo(params, _opts);
for (;;) {
int i = mgo.GetOpt();
if (i == -1) break;