From dba1302360823481dad9afe36af8b164b9ecf226 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Fri, 12 Jul 2019 16:35:49 -1000 Subject: [PATCH] Playlist (iOS): support abbreviating and expanding application and home directory paths so that playlist entries are valid across installs iOS: add call to realpath() when setting directory to ensure expanding special chars in paths work; fixed braces style --- frontend/drivers/platform_darwin.m | 7 ++++ libretro-common/file/file_path.c | 15 +++++++- menu/cbs/menu_cbs_ok.c | 58 +++++++++++++++++++++++++++--- playlist.c | 20 +++++++++++ 4 files changed, 95 insertions(+), 5 deletions(-) diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m index 03eb8354a0..8325ae87b8 100644 --- a/frontend/drivers/platform_darwin.m +++ b/frontend/drivers/platform_darwin.m @@ -358,6 +358,13 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[], resolved_home_dir_buf, sizeof(home_dir_buf)) < sizeof(home_dir_buf)); } + char resolved_bundle_dir_buf[PATH_MAX_LENGTH] = {0}; + if (realpath(bundle_path_buf, resolved_bundle_dir_buf)) + { + retro_assert(strlcpy(bundle_path_buf, + resolved_bundle_dir_buf, + sizeof(bundle_path_buf)) < sizeof(bundle_path_buf)); + } #endif strlcat(home_dir_buf, "/RetroArch", sizeof(home_dir_buf)); diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 9b85d76855..d478f2842e 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -1197,10 +1197,23 @@ void fill_pathname_application_path(char *s, size_t len) CFURLRef bundle_url = CFBundleCopyBundleURL(bundle); CFStringRef bundle_path = CFURLCopyPath(bundle_url); CFStringGetCString(bundle_path, s, len, kCFStringEncodingUTF8); +#ifdef HAVE_COCOATOUCH + // This needs to be done so that the path becomes /private/var/... and this + // is used consistently throughout for the iOS bundle path + char resolved_bundle_dir_buf[PATH_MAX_LENGTH] = {0}; + if (realpath(s, resolved_bundle_dir_buf)) + { + strlcpy(s,resolved_bundle_dir_buf, len); + strlcat(s,"/",len); + } +#endif + CFRelease(bundle_path); CFRelease(bundle_url); - +#ifndef HAVE_COCOATOUCH + // Not sure what this does but it breaks stuff for iOS so skipping retro_assert(strlcat(s, "nobin", len) < len); +#endif return; } #elif defined(__HAIKU__) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 42fa203018..4952237c03 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1020,11 +1020,20 @@ static bool menu_content_playlist_load(playlist_t *playlist, size_t idx) { const char *path = NULL; 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 + if (!string_is_empty(path)) { unsigned i; @@ -1586,6 +1595,15 @@ static int generic_action_ok(const char *path, break; case ACTION_OK_SET_DIRECTORY: flush_char = msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DIRECTORY_SETTINGS_LIST); +#ifdef HAVE_COCOATOUCH + // For iOS, set the path using realpath because the path name + // can start with /private and this ensures the path starts with it. + // This will allow the path to be properly substituted when fill_pathname_expand_special + // is called. + char real_action_path[PATH_MAX_LENGTH] = {0}; + realpath(action_path, real_action_path); + strlcpy(action_path, real_action_path, sizeof(action_path)); +#endif ret = set_path_generic(menu->filebrowser_label, action_path); break; case ACTION_OK_SET_PATH_VIDEO_FILTER: @@ -1780,12 +1798,22 @@ 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_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( @@ -1878,7 +1906,13 @@ 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 + } if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) { @@ -1893,8 +1927,14 @@ static int action_ok_playlist_entry_collection(const char *path, playlist_get_index(playlist, selection_ptr, &entry); - return default_action_ok_load_content_from_playlist_from_menu( - new_core_path, entry->path, entry->label); +#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 } static int action_ok_playlist_entry(const char *path, @@ -1909,6 +1949,11 @@ static int action_ok_playlist_entry(const char *path, new_core_path[0] = '\0'; +#ifdef HAVE_COCOATOUCH + char expanded_core_path[PATH_MAX_LENGTH]; + expanded_core_path[0] = '\0'; +#endif + if (!playlist || !menu_driver_ctl(RARCH_MENU_CTL_DRIVER_DATA_GET, &menu)) return menu_cbs_exit(); @@ -1957,8 +2002,13 @@ static int action_ok_playlist_entry(const char *path, } } - else if (!string_is_empty(entry->core_path)) - strlcpy(new_core_path, entry->core_path, sizeof(new_core_path)); + else if (!string_is_empty(entry->core_path)) { + 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 + } if (!playlist || !menu_content_playlist_load(playlist, selection_ptr)) { diff --git a/playlist.c b/playlist.c index 5931ae18c6..166c6591d4 100644 --- a/playlist.c +++ b/playlist.c @@ -639,9 +639,19 @@ 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; @@ -656,6 +666,11 @@ bool playlist_push(playlist_t *playlist, { 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 } /* Get 'real' core path */ @@ -668,6 +683,11 @@ bool playlist_push(playlist_t *playlist, 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)) {