diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index b95bc75d64..5c208bfff6 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -69,6 +69,7 @@ #include "../../tasks/tasks_internal.h" #include "../../input/input_remapping.h" #include "../../paths.h" +#include "../../playlist.h" #include "../../retroarch.h" #include "../../verbosity.h" #include "../../lakka.h" @@ -1018,21 +1019,14 @@ end: **/ static bool menu_content_playlist_load(playlist_t *playlist, size_t idx) { - const char *path = NULL; + char path[PATH_MAX_LENGTH]; const struct playlist_entry *entry = NULL; -#ifdef HAVE_COCOATOUCH - char expanded_path[PATH_MAX_LENGTH]; -#endif playlist_get_index(playlist, idx, &entry); - path = entry->path; - -#ifdef HAVE_COCOATOUCH - expanded_path[0] = '\0'; - fill_pathname_expand_special(expanded_path, entry->path, sizeof(expanded_path)); - path = expanded_path; -#endif + path[0] = '\0'; + strlcpy(path, entry->path, sizeof(path)); + playlist_resolve_path(PLAYLIST_LOAD, path, sizeof(path)); if (!string_is_empty(path)) { @@ -1789,6 +1783,7 @@ static int action_ok_file_load(const char *path, static int action_ok_playlist_entry_collection(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { + char new_path[PATH_MAX_LENGTH]; char new_core_path[PATH_MAX_LENGTH]; size_t selection_ptr = 0; bool playlist_initialized = false; @@ -1798,22 +1793,13 @@ static int action_ok_playlist_entry_collection(const char *path, const struct playlist_entry *entry = NULL; unsigned i = 0; -#ifdef HAVE_COCOATOUCH - char expanded_path[PATH_MAX_LENGTH]; - char expanded_core_path[PATH_MAX_LENGTH] = {0}; -#endif - if (!menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); + new_path[0] = '\0'; new_core_path[0] = '\0'; tmp_playlist = playlist_get_cached(); -#ifdef HAVE_COCOATOUCH - expanded_path[0] = '\0'; - expanded_core_path[0] = '\0'; -#endif - if (!tmp_playlist) { tmp_playlist = playlist_init( @@ -1870,6 +1856,7 @@ static int action_ok_playlist_entry_collection(const char *path, if (!string_is_empty(default_core_path)) { strlcpy(new_core_path, default_core_path, sizeof(new_core_path)); + playlist_resolve_path(PLAYLIST_LOAD, new_core_path, sizeof(new_core_path)); found_associated_core = true; } @@ -1908,10 +1895,7 @@ static int action_ok_playlist_entry_collection(const char *path, else { strlcpy(new_core_path, entry->core_path, sizeof(new_core_path)); -#ifdef HAVE_COCOATOUCH - fill_pathname_expand_special(expanded_core_path, new_core_path, sizeof(expanded_core_path)); - strlcpy(new_core_path, expanded_core_path, sizeof(new_core_path)); -#endif + playlist_resolve_path(PLAYLIST_LOAD, new_core_path, sizeof(new_core_path)); } if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) @@ -1927,14 +1911,10 @@ static int action_ok_playlist_entry_collection(const char *path, playlist_get_index(playlist, selection_ptr, &entry); -#ifdef HAVE_COCOATOUCH - fill_pathname_expand_special(expanded_path, entry->path, sizeof(expanded_path)); - return default_action_ok_load_content_from_playlist_from_menu( - new_core_path, expanded_path, entry->label); -#else - return default_action_ok_load_content_from_playlist_from_menu( - new_core_path, entry->path, entry->label); -#endif + strlcpy(new_path, entry->path, sizeof(new_path)); + playlist_resolve_path(PLAYLIST_LOAD, new_path, sizeof(new_path)); + return default_action_ok_load_content_from_playlist_from_menu( + new_core_path, new_path, entry->label); } static int action_ok_playlist_entry(const char *path, @@ -2919,6 +2899,13 @@ static int action_ok_core_deferred_set(const char *new_core_path, entry.core_path = (char*)new_core_path; entry.core_name = core_display_name; +#ifdef HAVE_COCOATOUCH + // for iOS, change abbreviate the bundle path with ":" because bundle path changes on each install + char abbreviated_core_path[PATH_MAX_LENGTH] = {0}; + fill_pathname_abbreviate_special(abbreviated_core_path, new_core_path, sizeof(abbreviated_core_path)); + entry.core_path = abbreviated_core_path; +#endif + command_playlist_update_write( NULL, menu->scratchpad.unsigned_var, diff --git a/playlist.c b/playlist.c index 166c6591d4..8a98e53826 100644 --- a/playlist.c +++ b/playlist.c @@ -624,6 +624,53 @@ success: return true; } +/** + * playlist_resolve_path: + * @mode : PLAYLIST_LOAD or PLAYLIST_SAVE + * @path : The path to be modified + * + * Resolves the path of an item, such as the content path or path to the core, to a format + * appropriate for saving or loading depending on the @mode parameter + * + * Can be platform specific. File paths for saving can be abbreviated to avoid saving absolute + * paths, as the base directory (home or application dir) may change after each subsequent + * install (iOS) +**/ +void playlist_resolve_path(enum playlist_file_mode mode, char *path, size_t size) +{ + char tmp[PATH_MAX_LENGTH]; + tmp[0] = '\0'; +#ifdef HAVE_COCOATOUCH + char resolved_path[PATH_MAX_LENGTH] = {0}; + strlcpy(tmp, path, sizeof(tmp)); + if ( mode == PLAYLIST_LOAD ) + { + strlcpy(resolved_path, tmp, sizeof(resolved_path)); + fill_pathname_expand_special(tmp, resolved_path, sizeof(tmp)); + } + else + { + // iOS needs to call realpath here since the call above fails due to possibly + // buffer related issues + realpath(tmp, resolved_path); + fill_pathname_abbreviate_special(tmp, resolved_path, sizeof(tmp)); + } + strlcpy(path, tmp, size); + return; +#else + if ( mode == PLAYLIST_LOAD) + { + return; + } + else + { + strlcpy(tmp, path, sizeof(tmp)); + path_resolve_realpath(tmp, sizeof(tmp)); + strlcpy(path, tmp, size); + } +#endif +} + /** * playlist_push: * @playlist : Playlist handle. @@ -639,19 +686,9 @@ bool playlist_push(playlist_t *playlist, const char *core_name = entry->core_name; bool entry_updated = false; -#ifdef HAVE_COCOATOUCH - char abbreviated_path[PATH_MAX_LENGTH]; - char abbreviated_core_path[PATH_MAX_LENGTH]; -#endif - real_path[0] = '\0'; real_core_path[0] = '\0'; -#ifdef HAVE_COCOATOUCH - abbreviated_path[0] = '\0'; - abbreviated_core_path[0] = '\0'; -#endif - if (!playlist || !entry) return false; @@ -665,29 +702,19 @@ bool playlist_push(playlist_t *playlist, if (!string_is_empty(entry->path)) { strlcpy(real_path, entry->path, sizeof(real_path)); - path_resolve_realpath(real_path, sizeof(real_path)); -#ifdef HAVE_COCOATOUCH - strlcpy(abbreviated_path, real_path, sizeof(abbreviated_path)); - fill_pathname_abbreviate_special(abbreviated_path, real_path, sizeof(abbreviated_path)); - strlcpy(real_path, abbreviated_path, sizeof(real_path)); -#endif + playlist_resolve_path(PLAYLIST_SAVE, real_path, sizeof(real_path)); } /* Get 'real' core path */ strlcpy(real_core_path, entry->core_path, sizeof(real_core_path)); if (!string_is_equal(real_core_path, file_path_str(FILE_PATH_DETECT))) - path_resolve_realpath(real_core_path, sizeof(real_core_path)); + playlist_resolve_path(PLAYLIST_SAVE, real_core_path, sizeof(real_core_path)); if (string_is_empty(real_core_path)) { RARCH_ERR("cannot push NULL or empty core path into the playlist.\n"); return false; } -#ifdef HAVE_COCOATOUCH - strlcpy(abbreviated_core_path, real_core_path, sizeof(abbreviated_core_path)); - fill_pathname_abbreviate_special(abbreviated_core_path, real_core_path, sizeof(abbreviated_core_path)); - strlcpy(real_core_path, abbreviated_core_path, sizeof(real_core_path)); -#endif if (string_is_empty(core_name)) { @@ -2330,7 +2357,7 @@ void playlist_set_default_core_path(playlist_t *playlist, const char *core_path) /* Get 'real' core path */ strlcpy(real_core_path, core_path, sizeof(real_core_path)); if (!string_is_equal(real_core_path, file_path_str(FILE_PATH_DETECT))) - path_resolve_realpath(real_core_path, sizeof(real_core_path)); + playlist_resolve_path(PLAYLIST_SAVE, real_core_path, sizeof(real_core_path)); if (string_is_empty(real_core_path)) return; diff --git a/playlist.h b/playlist.h index 7a82fd999b..ce29f849cb 100644 --- a/playlist.h +++ b/playlist.h @@ -35,6 +35,12 @@ enum playlist_runtime_status PLAYLIST_RUNTIME_VALID }; +enum playlist_file_mode +{ + PLAYLIST_LOAD, + PLAYLIST_SAVE +}; + struct playlist_entry { char *path; @@ -118,6 +124,21 @@ void playlist_get_index(playlist_t *playlist, void playlist_delete_index(playlist_t *playlist, size_t idx); +/** + * playlist_resolve_path: + * @mode : PLAYLIST_LOAD or PLAYLIST_SAVE + * @path : The path to be modified + * + * Resolves the path of an item, such as the content path or path to the core, to a format + * appropriate for saving or loading depending on the @mode parameter + * + * Can be platform specific. File paths for saving can be abbreviated to avoid saving absolute + * paths, as the base directory (home or application dir) may change after each subsequent + * install (iOS) + **/ +void playlist_resolve_path(enum playlist_file_mode mode, + char *path, size_t size); + /** * playlist_push: * @playlist : Playlist handle.