Skip to content

Commit d6b974c

Browse files
committed
(menu_setting) No longer use sscanf for float/uint/int callback functions -
significantly faster when doing it with strtoull/strtod
1 parent 8f27f13 commit d6b974c

1 file changed

Lines changed: 65 additions & 77 deletions

File tree

menu/menu_setting.c

Lines changed: 65 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -441,20 +441,23 @@ static int setting_set_with_string_representation(rarch_setting_t* setting,
441441
case ST_SIZE:
442442
{
443443
uint32_t flags = setting->flags;
444-
sscanf(value, "%" PRI_SIZET, setting->value.target.sizet);
444+
char *end;
445+
unsigned long long parsed = strtoull(value, &end, 10);
446+
if (end != value && *end == '\0')
447+
*setting->value.target.sizet = (size_t)parsed;
445448
if (flags & SD_FLAG_HAS_RANGE)
446449
{
447-
float min = setting->min;
448-
float max = setting->max;
449-
if (flags & SD_FLAG_ENFORCE_MINRANGE && *setting->value.target.sizet < min)
450-
*setting->value.target.sizet = min;
451-
if (flags & SD_FLAG_ENFORCE_MAXRANGE && *setting->value.target.sizet > max)
450+
float min = setting->min;
451+
float max = setting->max;
452+
if (flags & SD_FLAG_ENFORCE_MINRANGE && *setting->value.target.sizet < (size_t)min)
453+
*setting->value.target.sizet = (size_t)min;
454+
if (flags & SD_FLAG_ENFORCE_MAXRANGE && *setting->value.target.sizet > (size_t)max)
452455
{
453456
settings_t *settings = config_get_ptr();
454457
if (settings && settings->bools.menu_navigation_wraparound_enable)
455-
*setting->value.target.sizet = min;
458+
*setting->value.target.sizet = (size_t)min;
456459
else
457-
*setting->value.target.sizet = max;
460+
*setting->value.target.sizet = (size_t)max;
458461
}
459462
}
460463
}
@@ -506,100 +509,84 @@ static int setting_set_with_string_representation(rarch_setting_t* setting,
506509
return 0;
507510
}
508511

509-
510512
static void menu_input_st_uint_cb(void *userdata, const char *str)
511513
{
512514
if (str && *str)
513515
{
514-
const char *ptr = NULL;
515-
unsigned value = 0;
516-
int chars_read = 0;
517-
int ret = 0;
518-
519-
/* Ensure that input string contains a valid
520-
* unsigned value
521-
* Note: sscanf() will accept negative number
522-
* strings here and overflow, so have to check
523-
* for minus characters first... */
524-
for (ptr = str; *ptr != '\0'; ptr++)
525-
{
526-
if (*ptr == '-')
527-
{
528-
menu_input_dialog_end();
529-
return;
530-
}
531-
}
532-
533-
ret = sscanf(str, "%u %n", &value, &chars_read);
534-
535-
if ((ret == 1) && !str[chars_read])
516+
const char *ptr = str;
517+
/* Reject negative numbers (sscanf %u would silently overflow) */
518+
while (*ptr == ' ')
519+
ptr++;
520+
if (*ptr >= '0' && *ptr <= '9')
536521
{
537-
struct menu_state *menu_st = menu_state_get_ptr();
538-
const char *label = menu_st->input_dialog_kb_label_setting;
539-
540-
if (!string_is_empty(label))
522+
char *end = NULL;
523+
unsigned long value = strtoul(str, &end, 10);
524+
/* Ensure entire string was consumed and value fits in unsigned */
525+
if (end && *end == '\0' && value <= UINT_MAX)
541526
{
542-
rarch_setting_t *setting = NULL;
543-
if ((setting = menu_setting_find(label)))
544-
setting_set_with_string_representation(setting, str);
527+
struct menu_state *menu_st = menu_state_get_ptr();
528+
const char *label = menu_st->input_dialog_kb_label_setting;
529+
if (label && *label)
530+
{
531+
rarch_setting_t *setting = NULL;
532+
if ((setting = menu_setting_find(label)))
533+
setting_set_with_string_representation(setting, str);
534+
}
545535
}
546536
}
547537
}
548-
549538
menu_input_dialog_end();
550539
}
551540

552541
static void menu_input_st_int_cb(void *userdata, const char *str)
553542
{
554543
if (str && *str)
555544
{
556-
int value = 0;
557-
int chars_read = 0;
558-
/* Ensure that input string contains a valid
559-
* unsigned value */
560-
int ret = sscanf(str, "%d %n", &value, &chars_read);
545+
const char *ptr = str;
561546

562-
if ((ret == 1) && !str[chars_read])
547+
if (*ptr >= '0' && *ptr <= '9')
563548
{
564-
struct menu_state *menu_st = menu_state_get_ptr();
565-
const char *label = menu_st->input_dialog_kb_label_setting;
549+
while (*ptr >= '0' && *ptr <= '9')
550+
ptr++;
566551

567-
if (!string_is_empty(label))
552+
/* Skip trailing whitespace */
553+
while (*ptr == ' ' || *ptr == '\t')
554+
ptr++;
555+
556+
if (*ptr == '\0')
568557
{
569-
rarch_setting_t *setting = NULL;
570-
if ((setting = menu_setting_find(label)))
571-
setting_set_with_string_representation(setting, str);
558+
struct menu_state *menu_st = menu_state_get_ptr();
559+
const char *label = menu_st->input_dialog_kb_label_setting;
560+
if (label && *label)
561+
{
562+
rarch_setting_t *setting = NULL;
563+
if ((setting = menu_setting_find(label)))
564+
setting_set_with_string_representation(setting, str);
565+
}
572566
}
573567
}
574568
}
575-
576569
menu_input_dialog_end();
577570
}
578571

579572
static void menu_input_st_float_cb(void *userdata, const char *str)
580573
{
581574
if (str && *str)
582575
{
583-
float value = 0.0f;
584-
int chars_read = 0;
585-
/* Ensure that input string contains a valid
586-
* floating point value */
587-
int ret = sscanf(str, "%f %n", &value, &chars_read);
588-
589-
if ((ret == 1) && !str[chars_read])
576+
char *end = NULL;
577+
(void)strtod(str, &end);
578+
if (end != str && *end == '\0')
590579
{
591580
struct menu_state *menu_st = menu_state_get_ptr();
592581
const char *label = menu_st->input_dialog_kb_label_setting;
593-
594-
if (!string_is_empty(label))
582+
if (label && *label)
595583
{
596584
rarch_setting_t *setting = NULL;
597585
if ((setting = menu_setting_find(label)))
598586
setting_set_with_string_representation(setting, str);
599587
}
600588
}
601589
}
602-
603590
menu_input_dialog_end();
604591
}
605592

@@ -610,7 +597,7 @@ static void menu_input_st_string_cb(void *userdata, const char *str)
610597
struct menu_state *menu_st = menu_state_get_ptr();
611598
const char *label = menu_st->input_dialog_kb_label_setting;
612599

613-
if (!string_is_empty(label))
600+
if (label && *label)
614601
{
615602
rarch_setting_t *setting = NULL;
616603
if ((setting = menu_setting_find(label)))
@@ -2595,7 +2582,8 @@ static int setting_action_ok_bind_all_save_autoconfig(
25952582
map = settings->uints.input_joypad_index[index_offset];
25962583
name = input_config_get_device_name(map);
25972584

2598-
if ( !string_is_empty(name)
2585+
if ( name
2586+
&& *name
25992587
&& config_save_autoconf_profile(name, map))
26002588
{
26012589
int i;
@@ -2859,7 +2847,7 @@ static int setting_action_right_retropad_bind(
28592847
#if defined(HAVE_NETWORKING)
28602848
static void setting_action_ok_color_rgb_cb(void *userdata, const char *line)
28612849
{
2862-
if (!string_is_empty(line))
2850+
if (line && *line)
28632851
{
28642852
struct menu_state *menu_st = menu_state_get_ptr();
28652853
const char *label = menu_st->input_dialog_kb_label_setting;
@@ -6911,7 +6899,7 @@ static size_t setting_get_string_representation_uint_libretro_device(
69116899
break;
69126900
}
69136901
}
6914-
if (!string_is_empty(name))
6902+
if (name && *name)
69156903
return strlcpy(s, name, len);
69166904
return 0;
69176905
}
@@ -6956,7 +6944,7 @@ static size_t setting_get_string_representation_uint_analog_dpad_mode(
69566944
break;
69576945
}
69586946

6959-
if (!string_is_empty(name))
6947+
if (name && *name)
69606948
return strlcpy(s, name, len);
69616949
return 0;
69626950
}
@@ -8303,11 +8291,11 @@ static size_t get_string_representation_input_device_index(
83038291
_len = snprintf(s, len,
83048292
"#%u: %s",
83058293
map + 1,
8306-
!string_is_empty(device_name)
8294+
(device_name && *device_name)
83078295
? device_name
83088296
: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE));
83098297

8310-
if (!string_is_empty(device_name))
8298+
if (device_name && *device_name)
83118299
{
83128300
unsigned idx = input_config_get_device_name_index(map);
83138301

@@ -8317,7 +8305,7 @@ static size_t get_string_representation_input_device_index(
83178305
}
83188306
}
83198307

8320-
if (string_is_empty(s))
8308+
if (s && *s)
83218309
_len = strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED), len);
83228310
return _len;
83238311
}
@@ -8339,8 +8327,7 @@ static size_t get_string_representation_input_device_reservation_type(
83398327
return strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED), len);
83408328
}
83418329

8342-
static size_t setting_get_string_representation_input_device_reserved_device_name(
8343-
rarch_setting_t *setting, char *s, size_t len)
8330+
static size_t setting_get_string_representation_input_device_reserved_device_name(rarch_setting_t *setting, char *s, size_t len)
83448331
{
83458332
unsigned int dev_vendor_id;
83468333
unsigned int dev_product_id;
@@ -8372,14 +8359,14 @@ static size_t get_string_representation_input_mouse_index(
83728359
_len = snprintf(s, len,
83738360
"#%u: %s",
83748361
map + 1,
8375-
!string_is_empty(device_name)
8362+
(device_name && *device_name)
83768363
? device_name
83778364
: (map > 0)
83788365
? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)
83798366
: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE));
83808367
}
83818368

8382-
if (string_is_empty(s))
8369+
if (s && *s)
83838370
_len = strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED), len);
83848371
return _len;
83858372
}
@@ -9234,8 +9221,9 @@ static void general_write_handler(rarch_setting_t *setting)
92349221
* force a cache refresh on the next
92359222
* core info initialisation */
92369223
if (*setting->value.target.boolean)
9237-
if (!core_info_cache_force_refresh(!string_is_empty(path_libretro_info)
9238-
? path_libretro_info : dir_libretro))
9224+
if (!core_info_cache_force_refresh(
9225+
(path_libretro_info && *path_libretro_info)
9226+
? path_libretro_info : dir_libretro))
92399227
{
92409228
const char *_msg = msg_hash_to_str(MSG_CORE_INFO_CACHE_UNSUPPORTED);
92419229
/* core_info_cache_force_refresh() will fail
@@ -10013,7 +10001,7 @@ static bool setting_append_list_input_player_options(
1001310001
const char *input_desc_btn;
1001410002

1001510003
input_desc_btn = sys_info->input_desc_btn[user][i];
10016-
if (!string_is_empty(input_desc_btn))
10004+
if (input_desc_btn && *input_desc_btn)
1001710005
{
1001810006
char input_description[NAME_MAX_LENGTH];
1001910007
/* > Up to RARCH_FIRST_CUSTOM_BIND, inputs

0 commit comments

Comments
 (0)