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"
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-
597594struct 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