From 8701e4d98df05cf56416c48903a7fc612e6b63e1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 4 Jan 2003 23:24:50 +0000 Subject: [PATCH] Added hack for OSX bundles, from Eric Wing. --- platform/unix.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/platform/unix.c b/platform/unix.c index 5b8b7b5..b79d0c8 100644 --- a/platform/unix.c +++ b/platform/unix.c @@ -266,6 +266,103 @@ void __PHYSFS_platformTimeslice(void) } /* __PHYSFS_platformTimeslice */ +#if defined(__MACH__) && defined(__APPLE__) +/* + * This function is only for OSX. The problem is that Apple's applications + * can actually be directory structures with the actual executable nested + * several levels down. PhysFS computes the base directory from the Unix + * executable, but this may not be the correct directory. Apple tries to + * hide everything from the user, so from Finder, the user never sees the + * Unix executable, and the directory package (bundle) is considered the + * "executable". This means that the correct base directory is at the + * level where the directory structure starts. + * A typical bundle seems to look like this: + * MyApp.app/ <-- top level...this is what the user sees in Finder + * Contents/ + * MacOS/ + * MyApp <-- the actual executable + * + * Since anything below the app folder is considered hidden, most + * application files need to be at the top level if you intend to + * write portable software. Thus if the application resides in: + * /Applications/MyProgram + * and the executable is the bundle MyApp.app, + * PhysFS computes the following as the base directory: + * /Applications/MyProgram/MyApp.app/Contents/MacOS/ + * We need to strip off the MyApp.app/Contents/MacOS/ + * + * However, there are corner cases. OSX applications can be traditional + * Unix executables without the bundle. Also, it is not entirely clear + * to me what kinds of permutations bundle structures can have. + * + * For now, this is a temporary hack until a better solution + * can be made. This function will try to find a "/Contents/MacOS" + * inside the path. If it succeeds, then the path will be truncated + * to correct the directory. If it is not found, the path will be + * left alone and will presume it is a traditional Unix execuatable. + * Most programs also include the .app extention in the top level + * folder, but it doesn't seem to be a requirement (Acrobat doesn't + * have it). MacOS looks like it can also be MacOSClassic. + * This function will test for MacOS and hope it captures any + * other permutations. + */ +static void stripAppleBundle(char *path) +{ + char *sub_str = "/contents/macos"; + char *found_ptr = NULL; + char *tempbuf = NULL; + int i; + + /* Calloc will place the \0 character in the proper place for us */ + tempbuf = (char*)calloc( (strlen(path)+1), sizeof(char) ); + /* Unlike other Unix filesystems, HFS is case insensitive + * It wouldn be nice to use strcasestr, but it doesn't seem + * to be available in the OSX gcc library right now. + * So we should make a lower case copy of the path to + * compare against + */ + for(i=0; i=0; i--) + { + if('/' == path[i]) + { + break; + } + } + /* Safety check */ + if(i<1) + { + /* This probably shouldn't happen. */ + path[0] = '\0'; + } + else + { + /* Back up one more to remove trailing '/' and set the '\0' */ + path[i] = '\0'; + } + free(tempbuf); + return; +} +#endif /* defined __MACH__ && defined __APPLE__ */ + + char *__PHYSFS_platformRealPath(const char *path) { char resolved_path[MAXPATHLEN]; @@ -276,6 +373,11 @@ char *__PHYSFS_platformRealPath(const char *path) retval = (char *) malloc(strlen(resolved_path) + 1); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); strcpy(retval, resolved_path); + +#if defined(__MACH__) && defined(__APPLE__) + stripAppleBundle(retval); +#endif /* defined __MACH__ && defined __APPLE__ */ + return(retval); } /* __PHYSFS_platformRealPath */