diff --git a/src/libs/portability/portability.h b/src/libs/portability/portability.h index 9cdb53e2a..238e8df1a 100644 --- a/src/libs/portability/portability.h +++ b/src/libs/portability/portability.h @@ -69,7 +69,7 @@ static char *strndup(const char *str, int len) // Windows platform ------------------------------------------------- // Posix functions special names with MS compilers. -// Notes on MSVC compilers detection : +// Notes about MSVC compilers detection : // * _MSC_VER define should be prefered to WIN32/_WIN32 // * MSVC 6 : 1200 <= _MSC_VER < 1300 // * MSVC 2003 : 1300 <= _MSC_VER < 1400 @@ -81,6 +81,31 @@ static char *strndup(const char *str, int len) #define snprintf _snprintf +#define access _access + +// Workaround for sucking MSVC "access" function in C lib : +// * define F_OK, R_OK, W_OK and X_OK. +// * X_OK : no "executable" bit under Windows => use "R_OK" +#ifdef F_OK +#undef F_OK +#endif +#define F_OK 0x0 + +#ifdef W_OK +#undef W_OK +#endif +#define W_OK 0x2 + +#ifdef R_OK +#undef R_OK +#endif +#define R_OK 0x4 + +#ifdef X_OK +#undef X_OK +#endif +#define X_OK R_OK + // For MSVC 2005 and older (2008 already defines these) #if _MSC_VER < 1500 diff --git a/src/libs/tgf/tgf.cpp b/src/libs/tgf/tgf.cpp index f82d5fc2e..5784ff407 100644 --- a/src/libs/tgf/tgf.cpp +++ b/src/libs/tgf/tgf.cpp @@ -20,8 +20,9 @@ #include #include #include +#include #else -#include // getcwd +#include // getcwd, access #endif #include @@ -785,6 +786,14 @@ const char* GfGetInstallDir(void) return gfInstallDir; } +#ifdef WIN32 +static const char* pszPathSeparator = "\\"; +static const char* pszPATHSeparator = ";"; +#else +static const char* pszPathSeparator = "/"; +static const char* pszPATHSeparator = ":"; +#endif + void GfInitInstallDir(const char *pszExecutablePath) { if (gfInstallDir) @@ -798,9 +807,51 @@ void GfInitInstallDir(const char *pszExecutablePath) if (!pLastPathSep) pLastPathSep = strrchr(pszPath, '\\'); #endif - if (!pLastPathSep) - pLastPathSep = pszPath; - *pLastPathSep = 0; + + // If found, we've got the path of the folder where the executable is stored. + if (pLastPathSep) + { + *pLastPathSep = 0; + } + + // Otherwise, let's try the PATH + else if (getenv("PATH")) + { + char* pszPATH = strdup(getenv("PATH")); + for (char* pszCandPath = strtok(pszPATH, pszPATHSeparator); + pszCandPath != NULL; pszCandPath = strtok(NULL, pszPATHSeparator)) + { + // Workaround quoted pathes. + if (strlen(pszCandPath) > 0 + && (pszCandPath[0] == '"' || pszCandPath[0] == '\'')) + { + pszCandPath[strlen(pszCandPath)-1] = 0; + pszCandPath++; + } + + // Are we in the right folder ? + strcpy(pszPath, pszCandPath); + strcat(pszPath, pszPathSeparator); + strcat(pszPath, pszExecutablePath); +#ifdef WIN32 + if (strstr(pszPath, ".exe") != pszPath + strlen(pszPath) - 4) + strcat(pszPath, ".exe"); +#endif + if (access(pszPath, X_OK) == 0) { + // Bingo ! + strcpy(pszPath, pszCandPath); + break; + } + } + free(pszPATH); + } + + // If no PATH, cannot work if we are not in the executable folder. + else + { + getcwd(pszPath, 512); + } + gfInstallDir = makeRunTimeDirPath(pszPath); // If the path to the folder where the executable is stored ends with SD_BINDIR,