Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
- SCAN: Interpret M3U files during scanning
- SCAN: Merge manual and automatic scan into a more flexible setup
- SCAN: Improve GDI content recognition
- SCAN: --scan runs every path and exits with what the scans did; Manual Scan options, --scan-refresh and --scan-refresh-all on the command line; Refresh All Playlists in Manage Playlists
- SHADER: Display on-screen error when preset load fails
- SHADER: Add gyroscope / accelerometer uniforms for shaders
- SHADER: Add aggressive shader caching to slang shader backend
Expand Down
2 changes: 1 addition & 1 deletion core_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ static bool core_info_path_is_standalone_exempt(
return false;
}

static size_t core_info_get_file_id(const char *core_filename,
size_t core_info_get_file_id(const char *core_filename,
char *s, size_t len)
{
size_t _len;
Expand Down
5 changes: 5 additions & 0 deletions core_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info);
bool core_info_find(const char *core_path,
core_info_t **core_info);

/* Writes the file id of 'core_filename' (no extension or
* platform suffix) to 's'; returns its length */
size_t core_info_get_file_id(const char *core_filename,
char *s, size_t len);

bool core_info_load(const char *core_path);

/* The extensions of every core that claims the database at
Expand Down
62 changes: 62 additions & 0 deletions docs/retroarch.6
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,68 @@ Prints available features compiled into RetroArch, then exits.
\fB--cloudsync\fR
Runs a cloud sync with the configured cloud sync driver, then exits.

.TP
\fB--scan PATH\fR
Scans the folder or file PATH for content and adds it to playlists, as Manual Scan does.
Can be given more than once.

.TP
\fB--scan-refresh NAME|PATH\fR
Rescans one playlist with the scan settings it saved, as Refresh Playlist does.
NAME matches a playlist's name exactly first, then ignoring case. PATH must be in the playlist folder.
Like Refresh Playlist, it drops entries whose files are gone or whose extension the saved settings no longer include.
A playlist whose saved content folder is missing is skipped instead, so an unplugged drive does not empty it.

.TP
\fB--scan-refresh-all\fR
Does --scan-refresh for every playlist that has saved scan settings, as Refresh All Playlists does.

.IP
These run in the order given, and one that fails does not stop the rest.
Each prints a totals line on stdout, or its error on stderr.
Without --menu, RetroArch exits when they are done and does not load content given on the command line.
The exit status is then 1 if any failed, 0 if any added an entry, and 2 if none added anything; a skipped playlist does not count.
With --menu, they run while the menu does.
They cannot be combined with --cloudsync or --command.

.IP
The options below set the Manual Scan settings of the --scan, --scan-refresh or --scan-refresh-all before them.
On a refresh they override the saved settings, and the refresh saves them.
A --scan without any is Fully Automatic.

.TP
\fB--scan-playlist NAME\fR
Sets Target Playlist: a database's name, or a custom playlist name. Not allowed on a refresh.

.TP
\fB--scan-database NAME|first\fR
Sets Database To Match: the database NAME, or the first database that matches.

.TP
\fB--scan-match strict|loose|none\fR
Sets Database Check.

.TP
\fB--scan-dat FILE\fR
Sets Arcade DAT File. Matching is strict unless --scan-match loose is given.

.TP
\fB--scan-core CORE\fR
Sets Default Core: a core's path, its file name (with or without _libretro and the extension) or its display name.

.TP
\fB--scan-exts EXTS\fR
Sets File Extensions, separated by commas or spaces.

.TP
\fB--scan-no-recursive, --scan-no-archives\fR
Turn off Scan Recursively and Scan Inside Archives.

.TP
\fB--scan-overwrite, --scan-validate, --scan-omit-db-ref\fR
Turn on Overwrite Existing Playlist, Validate Existing Entries and Skip Database References From Playlist.
They act only when the scan has one playlist, and --scan-overwrite only on a folder; otherwise they print a warning and are ignored.

.TP
\fB-L PATH, --libretro PATH\fR
Path to a libretro implementation which is to be used.
Expand Down
4 changes: 4 additions & 0 deletions intl/msg_hash_lbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,10 @@ MSG_HASH(
MENU_ENUM_LABEL_PLAYLIST_MANAGER_REFRESH_PLAYLIST,
"playlist_manager_refresh_playlist"
)
MSG_HASH(
MENU_ENUM_LABEL_PLAYLIST_MANAGER_REFRESH_ALL_PLAYLISTS,
"playlist_manager_refresh_all_playlists"
)
MSG_HASH(
MENU_ENUM_LABEL_PLAYLIST_SETTINGS_BEGIN,
"playlist_settings_begin"
Expand Down
16 changes: 16 additions & 0 deletions intl/msg_hash_us.h
Original file line number Diff line number Diff line change
Expand Up @@ -23216,6 +23216,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_REFRESH_PLAYLIST,
"Add new content and remove invalid entries by repeating the content scan operation last used to create or edit the playlist."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_REFRESH_ALL_PLAYLISTS,
"Refresh All Playlists"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_PLAYLIST_MANAGER_REFRESH_ALL_PLAYLISTS,
"Rescan every playlist that has saved scan settings, with those settings."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_DELETE_PLAYLIST,
"Delete Playlist"
Expand Down Expand Up @@ -32548,6 +32556,10 @@ MSG_HASH(
MSG_PLAYLIST_MANAGER_REFRESH_DAT_FILE_TOO_LARGE,
"Refresh failed - arcade DAT file too large (insufficient memory): "
)
MSG_HASH(
MSG_PLAYLIST_MANAGER_REFRESH_ALL_DONE,
"Playlists refreshed: %u, skipped: %u, failed: %u"
)
MSG_HASH(
MSG_ADDED_TO_FAVORITES,
"Added to favorites"
Expand Down Expand Up @@ -34344,6 +34356,10 @@ MSG_HASH(
MSG_MANUAL_CONTENT_SCAN_END,
"Scan complete: "
)
MSG_HASH(
MSG_MANUAL_CONTENT_SCAN_ALREADY_RUNNING,
"A content scan is already running."
)
MSG_HASH(
MSG_CORE_BACKUP_SCANNING_CORE,
"Scanning core: "
Expand Down
4 changes: 3 additions & 1 deletion libretro-common/file/file_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,9 @@ size_t fill_pathname_expand_special(char *s, const char *in_path, size_t len)
len -= _len;
}

in_path += 2;
in_path++;
if (PATH_CHAR_IS_SLASH(*in_path))
in_path++;
}
}
#endif
Expand Down
58 changes: 57 additions & 1 deletion libretro-common/samples/file/file_path/fill_pathname_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,16 @@ static void test_join_truncation(void)
free(region);
}

/* mingw-w64 has no setenv(). */
static void set_home(const char *home)
{
#ifdef _WIN32
_putenv_s("HOME", home);
#else
setenv("HOME", home, 1);
#endif
}

/* fill_pathname_abbreviated_or_relative() resolves a relative @in_path
* against @in_refpath's directory before choosing between the
* relative and abbreviated forms. That join still carries its '..'
Expand All @@ -273,7 +283,7 @@ static void test_abbreviated_or_relative_long_join(void)
size_t _len = 0;
size_t i;

setenv("HOME", "/nonexistent-home", 1);
set_home("/nonexistent-home");

_len = strlcpy(refpath, "/r/s/t/u/v/w/", sizeof(refpath));
for (i = 0; i < 230; i++)
Expand Down Expand Up @@ -315,6 +325,51 @@ static void test_abbreviated_or_relative_long_join(void)
printf("[SUCCESS] absolute reference preferred over deeper relative\n");
}

/* Equal but for which slash separates. */
static int path_same(const char *a, const char *b)
{
for (; *a && *b; a++, b++)
if (*a != *b && !(PATH_CHAR_IS_SLASH(*a) && PATH_CHAR_IS_SLASH(*b)))
return 0;
return *a == *b;
}

/* fill_pathname_expand_special() replaces '~' and the slash after it.
* The input is a heap copy, so ASan sees a read past its NUL. */
static void test_expand_special_home(void)
{
static const char *const in[] =
{ "~", "~/", "~/x", "~x", "", "a/~" };
static const char *const want[] =
{ "/h/", "/h/", "/h/x", "/h/x", "", "a/~" };
char out[64];
size_t i;

set_home("/h");
for (i = 0; i < sizeof(in) / sizeof(in[0]); i++)
{
size_t n = strlen(in[i]) + 1;
char *path = (char*)malloc(n);
if (!path)
{
printf("[FAILED] expand \"%s\": out of memory\n", in[i]);
failures++;
continue;
}
memcpy(path, in[i], n);
fill_pathname_expand_special(out, path, sizeof(out));
free(path);
if (!path_same(out, want[i]))
{
printf("[FAILED] expand \"%s\" gave \"%s\" (expected \"%s\")\n",
in[i], out, want[i]);
failures++;
}
else
printf("[SUCCESS] expand \"%s\"\n", in[i]);
}
}

int main(void)
{
/* Documented semantics. */
Expand All @@ -335,6 +390,7 @@ int main(void)
test_overlong_input_no_dot();
test_join_truncation();
test_abbreviated_or_relative_long_join();
test_expand_special_home();

if (failures)
{
Expand Down
Loading
Loading