Skip to content

Commit c74fc74

Browse files
committed
(libretro-common) Optimize files
1 parent 07d4c55 commit c74fc74

5 files changed

Lines changed: 335 additions & 205 deletions

File tree

libretro-common/file/config_file_userdata.c

Lines changed: 80 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,134 +25,162 @@
2525

2626
#include <file/config_file_userdata.h>
2727

28+
#define CFG_KEY_SIZE 256
29+
2830
int config_userdata_get_float(void *userdata, const char *key_str,
2931
float *value, float default_value)
3032
{
31-
char key[256];
32-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
33+
char key[CFG_KEY_SIZE];
34+
const struct config_file_userdata *usr =
35+
(const struct config_file_userdata *)userdata;
36+
3337
fill_pathname_join_delim(key, usr->prefix[0], key_str, '_', sizeof(key));
3438
if (config_get_float(usr->conf, key, value))
35-
return true;
36-
*value = default_value;
39+
return 1;
40+
3741
fill_pathname_join_delim(key, usr->prefix[1], key_str, '_', sizeof(key));
3842
if (config_get_float(usr->conf, key, value))
39-
return true;
40-
return false;
43+
return 1;
44+
45+
*value = default_value;
46+
return 0;
4147
}
4248

4349
int config_userdata_get_int(void *userdata, const char *key_str,
4450
int *value, int default_value)
4551
{
46-
char key[256];
47-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
52+
char key[CFG_KEY_SIZE];
53+
const struct config_file_userdata *usr =
54+
(const struct config_file_userdata *)userdata;
55+
4856
fill_pathname_join_delim(key, usr->prefix[0], key_str, '_', sizeof(key));
4957
if (config_get_int(usr->conf, key, value))
50-
return true;
51-
*value = default_value;
58+
return 1;
59+
5260
fill_pathname_join_delim(key, usr->prefix[1], key_str, '_', sizeof(key));
5361
if (config_get_int(usr->conf, key, value))
54-
return true;
55-
return false;
62+
return 1;
63+
64+
*value = default_value;
65+
return 0;
5666
}
5767

5868
int config_userdata_get_hex(void *userdata, const char *key_str,
5969
unsigned *value, unsigned default_value)
6070
{
61-
char key[256];
62-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
71+
char key[CFG_KEY_SIZE];
72+
const struct config_file_userdata *usr =
73+
(const struct config_file_userdata *)userdata;
74+
6375
fill_pathname_join_delim(key, usr->prefix[0], key_str, '_', sizeof(key));
6476
if (config_get_hex(usr->conf, key, value))
65-
return true;
66-
*value = default_value;
77+
return 1;
78+
6779
fill_pathname_join_delim(key, usr->prefix[1], key_str, '_', sizeof(key));
6880
if (config_get_hex(usr->conf, key, value))
69-
return true;
70-
return false;
81+
return 1;
82+
83+
*value = default_value;
84+
return 0;
7185
}
7286

7387
int config_userdata_get_float_array(void *userdata, const char *key_str,
7488
float **values, unsigned *out_num_values,
7589
const float *default_values, unsigned num_default_values)
7690
{
77-
char key[2][256];
91+
char key0[CFG_KEY_SIZE];
92+
char key1[CFG_KEY_SIZE];
7893
char *str = NULL;
79-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
94+
const struct config_file_userdata *usr =
95+
(const struct config_file_userdata *)userdata;
8096

81-
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
82-
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
97+
fill_pathname_join_delim(key0, usr->prefix[0], key_str, '_', sizeof(key0));
98+
fill_pathname_join_delim(key1, usr->prefix[1], key_str, '_', sizeof(key1));
8399

84-
if ( config_get_string(usr->conf, key[0], &str)
85-
|| config_get_string(usr->conf, key[1], &str))
100+
if ( config_get_string(usr->conf, key0, &str)
101+
|| config_get_string(usr->conf, key1, &str))
86102
{
87103
unsigned i;
88-
struct string_list list = {0};
104+
struct string_list list;
89105
string_list_initialize(&list);
90106
string_split_noalloc(&list, str, " ");
91-
*values = (float*)calloc(list.size, sizeof(float));
92-
for (i = 0; i < list.size; i++)
93-
(*values)[i] = (float)strtod(list.elems[i].data, NULL);
107+
108+
*values = (float *)calloc(list.size, sizeof(float));
94109
*out_num_values = (unsigned)list.size;
110+
111+
for (i = 0; i < list.size; i++)
112+
(*values)[i] = (float)strtof(list.elems[i].data, NULL);
113+
95114
string_list_deinitialize(&list);
96115
free(str);
97-
return true;
116+
return 1;
98117
}
99118

100-
*values = (float*)calloc(num_default_values, sizeof(float));
119+
*values = (float *)calloc(num_default_values, sizeof(float));
101120
memcpy(*values, default_values, sizeof(float) * num_default_values);
102121
*out_num_values = num_default_values;
103-
return false;
122+
return 0;
104123
}
105124

106125
int config_userdata_get_int_array(void *userdata, const char *key_str,
107126
int **values, unsigned *out_num_values,
108127
const int *default_values, unsigned num_default_values)
109128
{
110-
char key[2][256];
129+
char key0[CFG_KEY_SIZE];
130+
char key1[CFG_KEY_SIZE];
111131
char *str = NULL;
112-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
113-
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
114-
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
132+
const struct config_file_userdata *usr =
133+
(const struct config_file_userdata *)userdata;
115134

116-
if ( config_get_string(usr->conf, key[0], &str)
117-
|| config_get_string(usr->conf, key[1], &str))
135+
fill_pathname_join_delim(key0, usr->prefix[0], key_str, '_', sizeof(key0));
136+
fill_pathname_join_delim(key1, usr->prefix[1], key_str, '_', sizeof(key1));
137+
138+
if ( config_get_string(usr->conf, key0, &str)
139+
|| config_get_string(usr->conf, key1, &str))
118140
{
119141
unsigned i;
120-
struct string_list list = {0};
142+
struct string_list list;
121143
string_list_initialize(&list);
122144
string_split_noalloc(&list, str, " ");
123-
*values = (int*)calloc(list.size, sizeof(int));
124-
for (i = 0; i < list.size; i++)
125-
(*values)[i] = (int)strtod(list.elems[i].data, NULL);
145+
146+
*values = (int *)calloc(list.size, sizeof(int));
126147
*out_num_values = (unsigned)list.size;
148+
149+
for (i = 0; i < list.size; i++)
150+
(*values)[i] = (int)strtol(list.elems[i].data, NULL, 10);
151+
127152
string_list_deinitialize(&list);
128153
free(str);
129-
return true;
154+
return 1;
130155
}
131156

132-
*values = (int*)calloc(num_default_values, sizeof(int));
157+
*values = (int *)calloc(num_default_values, sizeof(int));
133158
memcpy(*values, default_values, sizeof(int) * num_default_values);
134159
*out_num_values = num_default_values;
135-
return false;
160+
return 0;
136161
}
137162

138163
int config_userdata_get_string(void *userdata, const char *key_str,
139164
char **output, const char *default_output)
140165
{
141-
char key[2][256];
166+
char key0[CFG_KEY_SIZE];
167+
char key1[CFG_KEY_SIZE];
142168
char *str = NULL;
143-
struct config_file_userdata *usr = (struct config_file_userdata*)userdata;
144-
fill_pathname_join_delim(key[0], usr->prefix[0], key_str, '_', sizeof(key[0]));
145-
fill_pathname_join_delim(key[1], usr->prefix[1], key_str, '_', sizeof(key[1]));
169+
const struct config_file_userdata *usr =
170+
(const struct config_file_userdata *)userdata;
171+
172+
fill_pathname_join_delim(key0, usr->prefix[0], key_str, '_', sizeof(key0));
173+
fill_pathname_join_delim(key1, usr->prefix[1], key_str, '_', sizeof(key1));
146174

147-
if ( config_get_string(usr->conf, key[0], &str)
148-
|| config_get_string(usr->conf, key[1], &str))
175+
if ( config_get_string(usr->conf, key0, &str)
176+
|| config_get_string(usr->conf, key1, &str))
149177
{
150178
*output = str;
151-
return true;
179+
return 1;
152180
}
153181

154182
*output = strdup(default_output);
155-
return false;
183+
return 0;
156184
}
157185

158186
void config_userdata_free(void *ptr)

libretro-common/file/file_path_io.c

Lines changed: 87 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,28 @@
4343
#endif
4444

4545
/* TODO/FIXME - globals */
46-
static retro_vfs_stat_t path_stat_cb = retro_vfs_stat_impl;
46+
static retro_vfs_stat_t path_stat_cb = retro_vfs_stat_impl;
4747
static retro_vfs_mkdir_t path_mkdir_cb = retro_vfs_mkdir_impl;
4848

4949
void path_vfs_init(const struct retro_vfs_interface_info* vfs_info)
5050
{
51-
const struct retro_vfs_interface*
52-
vfs_iface = vfs_info->iface;
51+
const struct retro_vfs_interface *vfs_iface;
5352

54-
path_stat_cb = retro_vfs_stat_impl;
55-
path_mkdir_cb = retro_vfs_mkdir_impl;
53+
/* Reset to defaults unconditionally first */
54+
path_stat_cb = retro_vfs_stat_impl;
55+
path_mkdir_cb = retro_vfs_mkdir_impl;
56+
57+
/* Single combined guard: reject unsupported version or null interface */
58+
if (!vfs_info)
59+
return;
60+
61+
vfs_iface = vfs_info->iface;
5662

5763
if (vfs_info->required_interface_version < PATH_REQUIRED_VFS_VERSION || !vfs_iface)
5864
return;
5965

60-
path_stat_cb = vfs_iface->stat;
61-
path_mkdir_cb = vfs_iface->mkdir;
66+
path_stat_cb = vfs_iface->stat;
67+
path_mkdir_cb = vfs_iface->mkdir;
6268
}
6369

6470
int path_stat(const char *path)
@@ -94,56 +100,100 @@ int32_t path_get_size(const char *path)
94100
int32_t filesize = 0;
95101
if (path_stat_cb(path, &filesize) != 0)
96102
return filesize;
97-
98103
return -1;
99104
}
100105

101106
/**
102107
* path_mkdir:
103108
* @dir : directory
104109
*
105-
* Create directory on filesystem.
106-
*
107-
* Recursive function.
110+
* Create directory on filesystem, creating intermediate parent
111+
* directories as needed (iterative, not recursive).
112+
*
113+
* Converts the original tail-recursive design into an explicit
114+
* iterative loop to avoid stack growth on deep paths, while
115+
* keeping a single heap allocation for the working buffer.
108116
*
109-
* @return true if directory could be created, otherwise false.
117+
* @return true if directory exists or was created, otherwise false.
110118
**/
111119
bool path_mkdir(const char *dir)
112120
{
113-
bool norecurse = false;
114-
char *basedir = NULL;
121+
size_t len;
122+
char *buf;
123+
char *cur;
124+
int ret;
115125

116-
if (!(dir && *dir))
126+
if (!dir || !*dir)
117127
return false;
118128

119-
/* Use heap. Real chance of stack
120-
* overflow if we recurse too hard. */
121-
if (!(basedir = strdup(dir)))
129+
len = strlen(dir);
130+
buf = (char *)malloc(len + 1);
131+
if (!buf)
122132
return false;
123133

124-
path_parent_dir(basedir, strlen(basedir));
134+
memcpy(buf, dir, len + 1);
125135

126-
if (!*basedir || !strcmp(basedir, dir))
136+
/* Walk up to find the highest missing ancestor, then
137+
* create directories on the way back down — all without
138+
* extra heap allocations or recursion. */
139+
cur = buf + len;
140+
for (;;)
127141
{
128-
free(basedir);
129-
return false;
142+
/* Trim trailing separators to get the true parent */
143+
path_parent_dir(buf, (size_t)(cur - buf));
144+
145+
/* parent_dir wrote a NUL; find it */
146+
cur = buf + strlen(buf);
147+
148+
/* Reached filesystem root or an empty string */
149+
if (cur == buf || !strcmp(buf, dir))
150+
{
151+
free(buf);
152+
return false;
153+
}
154+
155+
/* Stop as soon as we hit an existing directory */
156+
if (path_is_directory(buf))
157+
break;
130158
}
131159

132-
if ( path_is_directory(basedir)
133-
|| path_mkdir(basedir))
134-
norecurse = true;
135-
136-
free(basedir);
137-
138-
if (norecurse)
160+
/* Restore each component from the bottom up and mkdir it.
161+
* We reconstruct the path by re-appending the segments we
162+
* stripped during the upward walk. */
163+
while ((size_t)(cur - buf) < len)
139164
{
140-
int ret = path_mkdir_cb(dir);
141-
142-
/* Don't treat this as an error. */
143-
if (ret == -2 && path_is_directory(dir))
144-
return true;
145-
else if (ret == 0)
146-
return true;
165+
/* Re-extend to next separator / end-of-original-path */
166+
*cur = dir[(size_t)(cur - buf)]; /* restore separator */
167+
while ( (size_t)(cur - buf) < len
168+
&& dir[(size_t)(cur - buf)] != '\0'
169+
&& dir[(size_t)(cur - buf)] != '/'
170+
#ifdef _WIN32
171+
&& dir[(size_t)(cur - buf)] != '\\'
172+
#endif
173+
)
174+
{
175+
cur++;
176+
*cur = dir[(size_t)(cur - buf)];
177+
}
178+
*cur = '\0';
179+
180+
ret = path_mkdir_cb(buf);
181+
/* -2 means "already exists"; verify it really is a dir */
182+
if (ret == -2)
183+
{
184+
if (!path_is_directory(buf))
185+
{
186+
free(buf);
187+
return false;
188+
}
189+
}
190+
else if (ret != 0)
191+
{
192+
free(buf);
193+
return false;
194+
}
147195
}
148-
return false;
196+
197+
free(buf);
198+
return true;
149199
}

0 commit comments

Comments
 (0)