Skip to content

Commit 4290a29

Browse files
committed
vulkan_sdl3: use IS_KEY_PREFIX
The parsing made more C-string based (because IS_KEY_PREFIX expects that). It can be made more string_view using again later but it seems to be more short now). this also fixes gpu=integrated|discrete
1 parent d7191a7 commit 4290a29

File tree

1 file changed

+44
-67
lines changed

1 file changed

+44
-67
lines changed

src/video_display/vulkan/vulkan_sdl3.cpp

Lines changed: 44 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@
4444
* * audio (would be perhaps better as an audio playback device)
4545
*/
4646

47-
#include <cmath> // for sqrt
4847
#include <cctype> // for toupper
48+
#include <cmath> // for sqrt
4949
#include <cstdio> // for sscanf
5050
#include <cstdlib> // for calloc
51+
#include <cstring> // for strchr, strcmp
5152

5253
#include "debug.h"
5354
#include "host.h"
@@ -56,6 +57,7 @@
5657
#include "messaging.h"
5758
#include "module.h"
5859
#include "utils/color_out.h"
60+
#include "utils/macros.h" // for IS_KEY_PREFIX
5961
#include "video_display.h"
6062
#include "video_display/splashscreen.h"
6163
#include "video.h"
@@ -589,11 +591,6 @@ void draw_splashscreen(state_vulkan_sdl3& s) {
589591
catch (std::exception& e) { log_and_exit_uv(e); }
590592
}
591593

592-
// todo C++20: replace with member function
593-
constexpr bool starts_with(std::string_view str, std::string_view match){
594-
return str.rfind(match, /*check only 0-th pos*/ 0) == 0;
595-
};
596-
597594
struct command_line_arguments {
598595
bool cursor = true;
599596
bool help = false;
@@ -610,94 +607,73 @@ struct command_line_arguments {
610607
std::string driver{};
611608
};
612609

613-
bool parse_command_line_arguments(command_line_arguments& args, state_vulkan_sdl3& s, std::string_view arguments_sv) {
614-
constexpr auto npos = std::string_view::npos;
610+
bool parse_command_line_arguments(command_line_arguments& args, state_vulkan_sdl3& s, char *fmt) {
615611
constexpr std::string_view wrong_option_msg = MOD_NAME "Wrong option: ";
616612

617-
// todo C++20: replace with std::views::split(options, ":")
618-
auto next_token = [](std::string_view & options) -> std::string_view {
619-
auto colon_pos = options.find(':');
620-
auto token = options.substr(0, colon_pos);
621-
options.remove_prefix(colon_pos == npos ? options.size() : colon_pos + 1);
622-
return token;
623-
};
624-
625-
while (!arguments_sv.empty()) try {
626-
const std::string_view token = next_token(arguments_sv);
627-
if (token.empty()) {
628-
continue;
629-
}
630-
631-
//svtoi = string_view to int
632-
auto svtoi = [token](std::string_view str) -> int {
613+
char *token = nullptr;
614+
char *saveptr = nullptr;
615+
while ((token = strtok_r(fmt, ":", &saveptr))) try {
616+
fmt = nullptr;
617+
//cstoi = cstring to int (checked)
618+
auto cstoi = [token](char *cstr) -> int {
633619
std::size_t endpos = 0;
634-
int result = std::stoi(std::string(str), &endpos, 0);
620+
std::string str = cstr;
621+
int result = std::stoi(str, &endpos, 0);
635622
if (endpos != str.size()) {
636623
throw std::runtime_error{ std::string(token) };
637624
}
638625
return result;
639626
};
640-
641-
if (token == "d") {
627+
if (strcmp(token, "help") == 0) {
628+
show_help();
629+
args.help = true;
630+
} else if (strcmp(token, "d") == 0) {
642631
s.deinterlace = true;
643-
} else if (token == "fs") {
632+
} else if (strcmp(token, "fs") == 0) {
644633
s.fullscreen = true;
645-
} else if (token == "keep-aspect") {
634+
} else if (strcmp(token, "keep-aspect") == 0) {
646635
s.keep_aspect = true;
647-
} else if (token == "nocursor") {
636+
} else if (strcmp(token, "nocursor") == 0) {
648637
args.cursor = false;
649-
} else if (token == "nodecorate") {
638+
} else if (strcmp(token, "nodecorate") == 0) {
650639
args.window_flags |= SDL_WINDOW_BORDERLESS;
651-
} else if (token == "novsync") {
640+
} else if (strcmp(token, "novsync") == 0) {
652641
args.vsync = false;
653-
} else if (token == "tearing") {
642+
} else if (strcmp(token, "tearing") == 0) {
654643
args.tearing_permitted = true;
655-
} else if (token == "validation") {
644+
} else if (strcmp(token, "validation") == 0) {
656645
args.validation = true;
657-
} else if (starts_with(token, "display=")) {
658-
constexpr auto pos = "display="sv.size();
659-
args.display_idx = svtoi(token.substr(pos));
660-
} else if (starts_with(token, "driver=")) {
661-
constexpr auto pos = "driver="sv.size();
662-
args.driver = std::string{ token.substr(pos) };
663-
} else if (starts_with(token, "gpu=")) {
664-
if (token == "integrated"sv) {
646+
} else if (IS_KEY_PREFIX(token, "display")) {
647+
args.display_idx = cstoi(strchr(token, '=') + 1);
648+
} else if (IS_KEY_PREFIX(token, "driver")) {
649+
args.driver = std::string{ strchr(token, '=') + 1};
650+
} else if (IS_KEY_PREFIX(token, "gpu")) {
651+
char *val = strchr(token, '=') + 1;
652+
if (strcmp(val, "integrated") == 0) {
665653
args.gpu_idx = vulkan_display::gpu_integrated;
666-
} else if (token == "discrete"sv) {
654+
} else if (strcmp(val, "discrete") == 0) {
667655
args.gpu_idx = vulkan_display::gpu_discrete;
668656
} else {
669-
constexpr auto pos = "gpu="sv.size();
670-
args.gpu_idx = svtoi(token.substr(pos));
657+
args.gpu_idx = cstoi(val);
671658
}
672-
} else if (starts_with(token, "pos=")) {
673-
auto tok = token;
674-
tok.remove_prefix("pos="sv.size());
675-
auto comma = tok.find(',');
676-
if (comma == npos) {
659+
} else if (IS_KEY_PREFIX(token, "pos")) {
660+
if (strchr(token, ',') == nullptr) {
677661
LOG(LOG_LEVEL_ERROR) << MOD_NAME "Missing colon in option:"
678662
<< token << '\n';
679663
return false;
680664
}
681-
args.x = svtoi(tok.substr(0, comma));
682-
args.y = svtoi(tok.substr(comma + 1));
683-
} else if (starts_with(token, "size=")) {
684-
auto tok = token;
685-
tok.remove_prefix("size="sv.size());
686-
auto x = tok.find('x');
687-
if (x == npos) {
665+
args.x = cstoi(strchr(token, '=') + 1);
666+
args.y = cstoi(strchr(token, ',') + 1);
667+
} else if (IS_KEY_PREFIX(token, "size")) {
668+
if (strchr(token, 'x') == nullptr) {
688669
LOG(LOG_LEVEL_ERROR) << MOD_NAME "Missing deliminer 'x' in option:"
689670
<< token << '\n';
690671
return false;
691672
}
692-
s.width = svtoi(tok.substr(0, x));
693-
s.height = svtoi(tok.substr(x + 1));
694-
} else if (starts_with(token, "window_flags=")) {
695-
constexpr auto pos = "window_flags="sv.size();
696-
int flags = svtoi(token.substr(pos));
697-
args.window_flags |= flags;
698-
} else if (token == "help") {
699-
show_help();
700-
args.help = true;
673+
s.width = cstoi(strchr(token, '=') + 1);
674+
s.height = cstoi(strchr(token, 'x') + 1);
675+
} else if (IS_KEY_PREFIX(token, "window_flags")) {
676+
args.window_flags |= cstoi(strchr(token, '=') + 1);
701677
} else {
702678
LOG(LOG_LEVEL_ERROR) << wrong_option_msg << token << '\n';
703679
return false;
@@ -775,7 +751,8 @@ void* display_vulkan_init(module* parent, const char* fmt, unsigned int flags) {
775751

776752
command_line_arguments args{};
777753
if (fmt) {
778-
if (!parse_command_line_arguments(args, *s, fmt)) {
754+
std::string cpy = fmt;
755+
if (!parse_command_line_arguments(args, *s, cpy.data())) {
779756
return nullptr;
780757
}
781758
if (args.help) {

0 commit comments

Comments
 (0)