2006-07-18 23:21:48 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
2003-01-22 00:45:36 +08:00
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2002-06-18 05:50:37 +08:00
|
|
|
|
2002-07-17 03:21:31 +08:00
|
|
|
// currently this impl is for _all_ platforms, execpt as defined.
|
|
|
|
// the mac version will change soon to reflect the path scheme under osx, but
|
|
|
|
// for now, the above include is commented out, and the below code takes precedence.
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2008-04-11 18:30:00 +08:00
|
|
|
#include <io.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <winbase.h>
|
2004-05-13 16:11:31 +08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2004-09-01 22:49:18 +08:00
|
|
|
#include <direct.h> // for _mkdir
|
2004-10-04 03:49:27 +08:00
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
#define mkdir(x,y) _mkdir((x))
|
2004-10-05 15:08:02 +08:00
|
|
|
#define stat64 _stati64
|
2004-09-01 22:49:18 +08:00
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
// set up for windows so acts just like unix access().
|
|
|
|
#define F_OK 4
|
2004-09-01 22:49:18 +08:00
|
|
|
|
|
|
|
|
2002-07-17 03:21:31 +08:00
|
|
|
#else // unix
|
2004-10-09 23:00:34 +08:00
|
|
|
|
2006-08-22 05:09:40 +08:00
|
|
|
#if defined( __APPLE__ )
|
|
|
|
// I'm not sure how we would handle this in raw Darwin
|
|
|
|
// without the AvailablilityMacros.
|
|
|
|
#include <AvailabilityMacros.h>
|
|
|
|
// 10.5 defines stat64 so we can't use this #define
|
|
|
|
// By default, MAC_OS_X_VERSION_MAX_ALLOWED is set to the latest
|
|
|
|
// system the headers know about. So I will use this as the control
|
|
|
|
// variable. (MIN_ALLOWED is set low by default so it is
|
|
|
|
// unhelpful in this case.)
|
|
|
|
// Unfortunately, we can't use the label MAC_OS_X_VERSION_10_4
|
|
|
|
// for older OS's like Jaguar, Panther since they are not defined,
|
|
|
|
// so I am going to hardcode the number.
|
|
|
|
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
|
|
|
|
#define stat64 stat
|
|
|
|
#endif
|
2007-09-27 20:15:39 +08:00
|
|
|
#elif defined(__CYGWIN__) || defined(__FreeBSD__) || (defined(__hpux) && !defined(_LARGEFILE64_SOURCE))
|
2004-10-09 23:00:34 +08:00
|
|
|
#define stat64 stat
|
|
|
|
#endif
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
#include <unistd.h>
|
2004-05-08 14:35:32 +08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2001-09-20 05:08:56 +08:00
|
|
|
#endif
|
2002-06-18 05:50:37 +08:00
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
// set up _S_ISDIR()
|
|
|
|
#if !defined(S_ISDIR)
|
|
|
|
# if defined( _S_IFDIR) && !defined( __S_IFDIR)
|
|
|
|
# define __S_IFDIR _S_IFDIR
|
|
|
|
# endif
|
|
|
|
# define S_ISDIR(mode) (mode&__S_IFDIR)
|
|
|
|
#endif
|
|
|
|
|
2002-06-18 18:18:12 +08:00
|
|
|
#include <osg/Notify>
|
|
|
|
|
|
|
|
#include <osgDB/FileUtils>
|
|
|
|
#include <osgDB/FileNameUtils>
|
|
|
|
#include <osgDB/Registry>
|
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stack>
|
|
|
|
|
2007-05-20 20:29:11 +08:00
|
|
|
|
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
bool osgDB::makeDirectory( const std::string &path )
|
|
|
|
{
|
|
|
|
if (path.empty())
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "osgDB::makeDirectory(): cannot create an empty directory" << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-10-03 16:50:56 +08:00
|
|
|
struct stat64 stbuf;
|
|
|
|
if( stat64( path.c_str(), &stbuf ) == 0 )
|
2004-09-01 22:49:18 +08:00
|
|
|
{
|
|
|
|
if( S_ISDIR(stbuf.st_mode))
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "osgDB::makeDirectory(): " <<
|
|
|
|
path << " already exists and is not a directory!" << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string dir = path;
|
|
|
|
std::stack<std::string> paths;
|
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
if( dir.empty() )
|
|
|
|
break;
|
|
|
|
|
2004-10-03 16:50:56 +08:00
|
|
|
if( stat64( dir.c_str(), &stbuf ) < 0 )
|
2004-09-01 22:49:18 +08:00
|
|
|
{
|
|
|
|
switch( errno )
|
|
|
|
{
|
|
|
|
case ENOENT:
|
|
|
|
case ENOTDIR:
|
|
|
|
paths.push( dir );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-11-18 18:08:29 +08:00
|
|
|
osg::notify(osg::DEBUG_INFO) << "osgDB::makeDirectory(): " << strerror(errno) << std::endl;
|
2004-09-01 22:49:18 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dir = getFilePath(std::string(dir));
|
|
|
|
}
|
|
|
|
|
|
|
|
while( !paths.empty() )
|
|
|
|
{
|
|
|
|
std::string dir = paths.top();
|
|
|
|
|
2006-06-08 19:22:45 +08:00
|
|
|
#if defined(WIN32)
|
|
|
|
//catch drive name
|
|
|
|
if (dir.size() == 2 && dir.c_str()[1] == ':') {
|
|
|
|
paths.pop();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
if( mkdir( dir.c_str(), 0755 )< 0 )
|
|
|
|
{
|
2004-11-18 18:08:29 +08:00
|
|
|
osg::notify(osg::DEBUG_INFO) << "osgDB::makeDirectory(): " << strerror(errno) << std::endl;
|
2004-09-01 22:49:18 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
paths.pop();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool osgDB::makeDirectoryForFile( const std::string &path )
|
|
|
|
{
|
|
|
|
return makeDirectory( getFilePath( path ));
|
|
|
|
}
|
2002-06-18 18:18:12 +08:00
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
void osgDB::convertStringPathIntoFilePathList(const std::string& paths,FilePathList& filepath)
|
|
|
|
{
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
char delimitor = ';';
|
|
|
|
#else
|
|
|
|
char delimitor = ':';
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!paths.empty())
|
|
|
|
{
|
|
|
|
std::string::size_type start = 0;
|
|
|
|
std::string::size_type end;
|
|
|
|
while ((end = paths.find_first_of(delimitor,start))!=std::string::npos)
|
|
|
|
{
|
|
|
|
filepath.push_back(std::string(paths,start,end-start));
|
|
|
|
start = end+1;
|
|
|
|
}
|
|
|
|
|
From Jean-Sebastien Guay,"As discussed yesterday on the osg-users list, I have altered
src/osgDB/FileUtils.cpp to implement the official Windows DLL search
order as described on the page
http://msdn2.microsoft.com/en-us/library/ms682586.aspx . As mentioned,
the search order is now:
1. The directory from which the application loaded.
2. The system directory. (C:\Windows\System32 by default, gotten using the
GetSystemDirectory function)
3. The 16-bit system directory. (C:\Windows\System by default, gotten by
adding "\System" to the path gotten in the next step...)
4. The Windows directory. (C:\Windows by default, gotten using the
GetWindowsDirectory function)
5. The current directory. (".")
6. The directories that are listed in the PATH environment variable. (as
before)
The first four directories are obtained using Win32 API calls, so they
should work correctly even on non-standard Windows installs.
The changes are well commented and should be clear, even to someone
not familiar with the Win32 API.
I have tested in a few scenarios and it works as expected. Serge Lages
has also tested the changes and confirmed they worked as described. I
have not had any other reports though (positive or negative).
I also fixed the issue with a trailing semicolon on the PATH adding an
empty string to the end of the search paths, as this was an
inconsistent side effect rather than a desirable effect. This change
will take effect on other platforms as well, but since it tests for an
empty string in the last item added to the search paths, it should
have no adverse effect.
"
2007-08-23 22:10:31 +08:00
|
|
|
std::string lastPath(paths,start,std::string::npos);
|
|
|
|
if (!lastPath.empty())
|
|
|
|
filepath.push_back(lastPath);
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
bool osgDB::fileExists(const std::string& filename)
|
|
|
|
{
|
|
|
|
return access( filename.c_str(), F_OK ) == 0;
|
|
|
|
}
|
|
|
|
|
2004-05-08 14:35:32 +08:00
|
|
|
osgDB::FileType osgDB::fileType(const std::string& filename)
|
|
|
|
{
|
2004-10-03 16:50:56 +08:00
|
|
|
struct stat64 fileStat;
|
|
|
|
if ( stat64(filename.c_str(), &fileStat) != 0 )
|
2004-05-08 14:35:32 +08:00
|
|
|
{
|
|
|
|
return FILE_NOT_FOUND;
|
2004-05-13 16:11:31 +08:00
|
|
|
} // end if
|
2004-05-13 21:37:55 +08:00
|
|
|
|
|
|
|
if ( fileStat.st_mode & S_IFDIR )
|
2004-05-13 16:11:31 +08:00
|
|
|
return DIRECTORY;
|
2004-05-13 21:37:55 +08:00
|
|
|
else if ( fileStat.st_mode & S_IFREG )
|
2004-05-08 14:35:32 +08:00
|
|
|
return REGULAR_FILE;
|
2004-05-13 21:37:55 +08:00
|
|
|
|
2004-05-13 16:11:31 +08:00
|
|
|
return FILE_NOT_FOUND;
|
2004-05-08 14:35:32 +08:00
|
|
|
}
|
|
|
|
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string osgDB::findFileInPath(const std::string& filename, const FilePathList& filepath,CaseSensitivity caseSensitivity)
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
2003-11-06 12:08:53 +08:00
|
|
|
if (filename.empty())
|
|
|
|
return filename;
|
2002-06-18 05:50:37 +08:00
|
|
|
|
2005-02-11 17:58:30 +08:00
|
|
|
if (!isFileNameNativeStyle(filename))
|
|
|
|
return findFileInPath(convertFileNameToNativeStyle(filename), filepath, caseSensitivity);
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
for(FilePathList::const_iterator itr=filepath.begin();
|
|
|
|
itr!=filepath.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2004-11-23 07:54:45 +08:00
|
|
|
osg::notify(osg::DEBUG_INFO) << "itr='" <<*itr<< "'\n";
|
2007-01-17 23:59:29 +08:00
|
|
|
std::string path = itr->empty() ? filename : concatPaths(*itr, filename);
|
|
|
|
|
|
|
|
path = getRealPath(path);
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
osg::notify(osg::DEBUG_INFO) << "FindFileInPath() : trying " << path << " ...\n";
|
2003-11-06 12:08:53 +08:00
|
|
|
if(fileExists(path))
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "FindFileInPath() : USING " << path << "\n";
|
|
|
|
return path;
|
|
|
|
}
|
2003-11-25 17:04:41 +08:00
|
|
|
#ifndef WIN32
|
|
|
|
// windows already case insensitive so no need to retry..
|
|
|
|
else if (caseSensitivity==CASE_INSENSITIVE)
|
|
|
|
{
|
|
|
|
std::string foundfile = findFileInDirectory(filename,*itr,CASE_INSENSITIVE);
|
|
|
|
if (!foundfile.empty()) return foundfile;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
|
2004-11-23 07:54:45 +08:00
|
|
|
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string osgDB::findDataFile(const std::string& filename,CaseSensitivity caseSensitivity)
|
2004-11-22 22:10:12 +08:00
|
|
|
{
|
|
|
|
return findDataFile(filename,static_cast<ReaderWriter::Options*>(0),caseSensitivity);
|
|
|
|
}
|
|
|
|
|
2004-11-23 07:54:45 +08:00
|
|
|
OSGDB_EXPORT std::string osgDB::findDataFile(const std::string& filename,const ReaderWriter::Options* options, CaseSensitivity caseSensitivity)
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
|
|
|
if (filename.empty()) return filename;
|
2004-11-22 22:10:12 +08:00
|
|
|
|
2004-11-23 07:54:45 +08:00
|
|
|
if(fileExists(filename))
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "FindFileInPath(" << filename << "): returning " << filename << std::endl;
|
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
|
2004-11-22 22:10:12 +08:00
|
|
|
std::string fileFound;
|
|
|
|
|
|
|
|
if (options && !options->getDatabasePathList().empty())
|
|
|
|
{
|
|
|
|
fileFound = findFileInPath(filename, options->getDatabasePathList(), caseSensitivity);
|
|
|
|
if (!fileFound.empty()) return fileFound;
|
|
|
|
}
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
const FilePathList& filepath = Registry::instance()->getDataFilePathList();
|
2004-11-23 07:54:45 +08:00
|
|
|
if (!filepath.empty())
|
|
|
|
{
|
|
|
|
fileFound = findFileInPath(filename, filepath,caseSensitivity);
|
|
|
|
if (!fileFound.empty()) return fileFound;
|
|
|
|
}
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
// if a directory is included in the filename, get just the (simple) filename itself and try that
|
|
|
|
std::string simpleFileName = getSimpleFileName(filename);
|
|
|
|
if (simpleFileName!=filename)
|
|
|
|
{
|
2004-11-23 07:54:45 +08:00
|
|
|
|
|
|
|
if(fileExists(simpleFileName))
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "FindFileInPath(" << filename << "): returning " << filename << std::endl;
|
|
|
|
return simpleFileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options && !options->getDatabasePathList().empty())
|
|
|
|
{
|
|
|
|
fileFound = findFileInPath(simpleFileName, options->getDatabasePathList(), caseSensitivity);
|
|
|
|
if (!fileFound.empty()) return fileFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!filepath.empty())
|
|
|
|
{
|
|
|
|
fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity);
|
|
|
|
if (!fileFound.empty()) return fileFound;
|
|
|
|
}
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// return empty string.
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string osgDB::findLibraryFile(const std::string& filename,CaseSensitivity caseSensitivity)
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
2003-11-06 12:08:53 +08:00
|
|
|
if (filename.empty())
|
|
|
|
return filename;
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
const FilePathList& filepath = Registry::instance()->getLibraryFilePathList();
|
|
|
|
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string fileFound = findFileInPath(filename, filepath,caseSensitivity);
|
2003-11-06 12:08:53 +08:00
|
|
|
if (!fileFound.empty())
|
|
|
|
return fileFound;
|
2002-06-18 05:50:37 +08:00
|
|
|
|
2004-11-23 07:54:45 +08:00
|
|
|
if(fileExists(filename))
|
|
|
|
{
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "FindFileInPath(" << filename << "): returning " << filename << std::endl;
|
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
|
2002-06-18 05:50:37 +08:00
|
|
|
// if a directory is included in the filename, get just the (simple) filename itself and try that
|
|
|
|
std::string simpleFileName = getSimpleFileName(filename);
|
|
|
|
if (simpleFileName!=filename)
|
|
|
|
{
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string fileFound = findFileInPath(simpleFileName, filepath,caseSensitivity);
|
2002-06-18 05:50:37 +08:00
|
|
|
if (!fileFound.empty()) return fileFound;
|
|
|
|
}
|
|
|
|
|
2007-08-12 01:44:06 +08:00
|
|
|
// failed return empty string.
|
|
|
|
return std::string();
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
|
|
|
|
2003-11-25 17:04:41 +08:00
|
|
|
std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,CaseSensitivity caseSensitivity)
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
|
|
|
bool needFollowingBackslash = false;
|
|
|
|
bool needDirectoryName = true;
|
|
|
|
osgDB::DirectoryContents dc;
|
|
|
|
|
|
|
|
if (dirName.empty())
|
|
|
|
{
|
|
|
|
dc = osgDB::getDirectoryContents(".");
|
|
|
|
needFollowingBackslash = false;
|
|
|
|
needDirectoryName = false;
|
|
|
|
}
|
|
|
|
else if (dirName=="." || dirName=="./" || dirName==".\\")
|
|
|
|
{
|
|
|
|
dc = osgDB::getDirectoryContents(".");
|
|
|
|
needFollowingBackslash = false;
|
|
|
|
needDirectoryName = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dc = osgDB::getDirectoryContents(dirName);
|
|
|
|
char lastChar = dirName[dirName.size()-1];
|
|
|
|
if (lastChar=='/') needFollowingBackslash = false;
|
|
|
|
else if (lastChar=='\\') needFollowingBackslash = false;
|
|
|
|
else needFollowingBackslash = true;
|
|
|
|
needDirectoryName = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(osgDB::DirectoryContents::iterator itr=dc.begin();
|
|
|
|
itr!=dc.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2003-11-25 17:04:41 +08:00
|
|
|
if ((caseSensitivity==CASE_INSENSITIVE && osgDB::equalCaseInsensitive(fileName,*itr)) ||
|
2002-06-18 05:50:37 +08:00
|
|
|
(fileName==*itr))
|
|
|
|
{
|
|
|
|
if (!needDirectoryName) return *itr;
|
|
|
|
else if (needFollowingBackslash) return dirName+'/'+*itr;
|
|
|
|
else return dirName+*itr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
|
|
|
|
{
|
|
|
|
#ifdef OSG_DEFAULT_LIBRARY_PATH
|
|
|
|
// Append the install prefix path to the library search path if configured
|
|
|
|
filepath.push_back(OSG_DEFAULT_LIBRARY_PATH);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2002-06-26 04:47:42 +08:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2002-06-18 05:50:37 +08:00
|
|
|
#include <io.h>
|
|
|
|
#include <direct.h>
|
|
|
|
|
|
|
|
osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
|
|
|
|
{
|
|
|
|
osgDB::DirectoryContents contents;
|
|
|
|
|
|
|
|
WIN32_FIND_DATA data;
|
|
|
|
HANDLE handle = FindFirstFile((dirName + "\\*").c_str(), &data);
|
|
|
|
if (handle != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
contents.push_back(data.cFileName);
|
|
|
|
}
|
|
|
|
while (FindNextFile(handle, &data) != 0);
|
|
|
|
|
|
|
|
FindClose(handle);
|
|
|
|
}
|
|
|
|
return contents;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
|
|
|
|
{
|
|
|
|
osgDB::DirectoryContents contents;
|
|
|
|
|
|
|
|
DIR *handle = opendir(dirName.c_str());
|
|
|
|
if (handle)
|
|
|
|
{
|
|
|
|
dirent *rc;
|
|
|
|
while((rc = readdir(handle))!=NULL)
|
|
|
|
{
|
|
|
|
contents.push_back(rc->d_name);
|
|
|
|
}
|
|
|
|
closedir(handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return contents;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // unix getDirectoryContexts
|
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Implementation of appendPlatformSpecificLibraryFilePaths(..)
|
|
|
|
//
|
|
|
|
#ifdef __sgi
|
|
|
|
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList("/usr/lib32/:/usr/local/lib32/",filepath);
|
|
|
|
|
|
|
|
// bloody mess see rld(1) man page
|
|
|
|
char* ptr;
|
2004-08-29 07:04:47 +08:00
|
|
|
|
|
|
|
#if (_MIPS_SIM == _MIPS_SIM_ABI32)
|
2004-08-28 00:14:21 +08:00
|
|
|
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr,filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif (_MIPS_SIM == _MIPS_SIM_NABI32)
|
|
|
|
|
|
|
|
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
|
|
|
|
ptr = getenv( "LD_LIBRARY_PATH" );
|
|
|
|
|
|
|
|
if( ptr )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr,filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif (_MIPS_SIM == _MIPS_SIM_ABI64)
|
|
|
|
|
|
|
|
if( !(ptr = getenv( "LD_LIBRARY64_PATH" )))
|
|
|
|
ptr = getenv( "LD_LIBRARY_PATH" );
|
|
|
|
|
|
|
|
if( ptr )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr,filepath);
|
|
|
|
}
|
|
|
|
#endif
|
2008-09-19 20:49:22 +08:00
|
|
|
|
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(__CYGWIN__)
|
|
|
|
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
char* ptr;
|
|
|
|
if ((ptr = getenv( "PATH" )))
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr,filepath);
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
2004-08-28 00:14:21 +08:00
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
convertStringPathIntoFilePathList("/usr/bin/:/usr/local/bin/",filepath);
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(WIN32)
|
|
|
|
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
From Jean-Sebastien Guay,"As discussed yesterday on the osg-users list, I have altered
src/osgDB/FileUtils.cpp to implement the official Windows DLL search
order as described on the page
http://msdn2.microsoft.com/en-us/library/ms682586.aspx . As mentioned,
the search order is now:
1. The directory from which the application loaded.
2. The system directory. (C:\Windows\System32 by default, gotten using the
GetSystemDirectory function)
3. The 16-bit system directory. (C:\Windows\System by default, gotten by
adding "\System" to the path gotten in the next step...)
4. The Windows directory. (C:\Windows by default, gotten using the
GetWindowsDirectory function)
5. The current directory. (".")
6. The directories that are listed in the PATH environment variable. (as
before)
The first four directories are obtained using Win32 API calls, so they
should work correctly even on non-standard Windows installs.
The changes are well commented and should be clear, even to someone
not familiar with the Win32 API.
I have tested in a few scenarios and it works as expected. Serge Lages
has also tested the changes and confirmed they worked as described. I
have not had any other reports though (positive or negative).
I also fixed the issue with a trailing semicolon on the PATH adding an
empty string to the end of the search paths, as this was an
inconsistent side effect rather than a desirable effect. This change
will take effect on other platforms as well, but since it tests for an
empty string in the last item added to the search paths, it should
have no adverse effect.
"
2007-08-23 22:10:31 +08:00
|
|
|
// See http://msdn2.microsoft.com/en-us/library/ms682586.aspx
|
|
|
|
|
|
|
|
// Safe DLL search mode changes the DLL search order to search for
|
2007-08-26 18:24:18 +08:00
|
|
|
// DLLs in the current directory after the system directories, instead
|
|
|
|
// of right after the application's directory. According to the article
|
|
|
|
// linked above, on Windows XP and Windows 2000, Safe DLL search mode
|
|
|
|
// is disabled by default. However, it is a good idea to enable it. We
|
|
|
|
// will search as if it was enabled.
|
From Jean-Sebastien Guay,"As discussed yesterday on the osg-users list, I have altered
src/osgDB/FileUtils.cpp to implement the official Windows DLL search
order as described on the page
http://msdn2.microsoft.com/en-us/library/ms682586.aspx . As mentioned,
the search order is now:
1. The directory from which the application loaded.
2. The system directory. (C:\Windows\System32 by default, gotten using the
GetSystemDirectory function)
3. The 16-bit system directory. (C:\Windows\System by default, gotten by
adding "\System" to the path gotten in the next step...)
4. The Windows directory. (C:\Windows by default, gotten using the
GetWindowsDirectory function)
5. The current directory. (".")
6. The directories that are listed in the PATH environment variable. (as
before)
The first four directories are obtained using Win32 API calls, so they
should work correctly even on non-standard Windows installs.
The changes are well commented and should be clear, even to someone
not familiar with the Win32 API.
I have tested in a few scenarios and it works as expected. Serge Lages
has also tested the changes and confirmed they worked as described. I
have not had any other reports though (positive or negative).
I also fixed the issue with a trailing semicolon on the PATH adding an
empty string to the end of the search paths, as this was an
inconsistent side effect rather than a desirable effect. This change
will take effect on other platforms as well, but since it tests for an
empty string in the last item added to the search paths, it should
have no adverse effect.
"
2007-08-23 22:10:31 +08:00
|
|
|
|
|
|
|
// So if SafeDllSearchMode is enabled, the search order is as follows:
|
|
|
|
|
|
|
|
// 1. The directory from which the application loaded.
|
|
|
|
DWORD retval = 0;
|
|
|
|
const DWORD size = MAX_PATH;
|
|
|
|
char path[size];
|
|
|
|
retval = GetModuleFileName(NULL, path, size);
|
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
|
|
|
std::string pathstr(path);
|
|
|
|
std::string executableDir(pathstr, 0,
|
|
|
|
pathstr.find_last_of("\\/"));
|
|
|
|
convertStringPathIntoFilePathList(executableDir, filepath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::notify(osg::WARN) << "Could not get application directory "
|
|
|
|
"using Win32 API. It will not be searched." << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 2. The system directory. Use the GetSystemDirectory function to
|
|
|
|
// get the path of this directory.
|
|
|
|
char systemDir[(UINT)size];
|
|
|
|
retval = GetSystemDirectory(systemDir, (UINT)size);
|
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(std::string(systemDir),
|
|
|
|
filepath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::notify(osg::WARN) << "Could not get system directory using "
|
|
|
|
"Win32 API, using default directory." << std::endl;
|
|
|
|
convertStringPathIntoFilePathList("C:\\Windows\\System32",
|
|
|
|
filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. The 16-bit system directory. There is no function that obtains
|
|
|
|
// the path of this directory, but it is searched.
|
|
|
|
// 4. The Windows directory. Use the GetWindowsDirectory function to
|
|
|
|
// get the path of this directory.
|
|
|
|
char windowsDir[(UINT)size];
|
|
|
|
retval = GetWindowsDirectory(windowsDir, (UINT)size);
|
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(std::string(windowsDir) +
|
|
|
|
"\\System", filepath);
|
|
|
|
convertStringPathIntoFilePathList(std::string(windowsDir),
|
|
|
|
filepath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::notify(osg::WARN) << "Could not get Windows directory using "
|
|
|
|
"Win32 API, using default directory." << std::endl;
|
|
|
|
convertStringPathIntoFilePathList("C:\\Windows", filepath);
|
|
|
|
convertStringPathIntoFilePathList("C:\\Windows\\System", filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 5. The current directory.
|
|
|
|
convertStringPathIntoFilePathList(".", filepath);
|
|
|
|
|
|
|
|
// 6. The directories that are listed in the PATH environment
|
|
|
|
// variable. Note that this does not include the per-application
|
|
|
|
// path specified by the App Paths registry key.
|
2004-08-28 00:14:21 +08:00
|
|
|
char* ptr;
|
|
|
|
if ((ptr = getenv( "PATH" )))
|
|
|
|
{
|
From Jean-Sebastien Guay,"As discussed yesterday on the osg-users list, I have altered
src/osgDB/FileUtils.cpp to implement the official Windows DLL search
order as described on the page
http://msdn2.microsoft.com/en-us/library/ms682586.aspx . As mentioned,
the search order is now:
1. The directory from which the application loaded.
2. The system directory. (C:\Windows\System32 by default, gotten using the
GetSystemDirectory function)
3. The 16-bit system directory. (C:\Windows\System by default, gotten by
adding "\System" to the path gotten in the next step...)
4. The Windows directory. (C:\Windows by default, gotten using the
GetWindowsDirectory function)
5. The current directory. (".")
6. The directories that are listed in the PATH environment variable. (as
before)
The first four directories are obtained using Win32 API calls, so they
should work correctly even on non-standard Windows installs.
The changes are well commented and should be clear, even to someone
not familiar with the Win32 API.
I have tested in a few scenarios and it works as expected. Serge Lages
has also tested the changes and confirmed they worked as described. I
have not had any other reports though (positive or negative).
I also fixed the issue with a trailing semicolon on the PATH adding an
empty string to the end of the search paths, as this was an
inconsistent side effect rather than a desirable effect. This change
will take effect on other platforms as well, but since it tests for an
empty string in the last item added to the search paths, it should
have no adverse effect.
"
2007-08-23 22:10:31 +08:00
|
|
|
// Note that on any sane Windows system, some of the paths above
|
|
|
|
// will also be on the PATH (the values gotten in systemDir and
|
|
|
|
// windowsDir), but the DLL search goes sequentially and stops
|
|
|
|
// when a DLL is found, so I see no point in removing duplicates.
|
|
|
|
convertStringPathIntoFilePathList(ptr, filepath);
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
2008-09-19 20:49:22 +08:00
|
|
|
|
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
|
2004-08-28 00:52:23 +08:00
|
|
|
// #define COMPILE_COCOA_VERSION
|
2004-09-02 18:01:24 +08:00
|
|
|
#define COMPILE_CARBON_VERSION
|
2005-07-27 05:07:31 +08:00
|
|
|
// WARNING: Cocoa version is currently untested.
|
|
|
|
#ifdef COMPILE_COCOA_VERSION
|
|
|
|
#include <Foundation/Foundation.h>
|
|
|
|
#endif
|
|
|
|
#ifdef COMPILE_CARBON_VERSION
|
|
|
|
#include <CoreServices/CoreServices.h>
|
|
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
#include <Carbon/Carbon.h>
|
|
|
|
#endif
|
|
|
|
#include <iostream>
|
2004-08-28 00:52:23 +08:00
|
|
|
|
2005-07-27 05:07:31 +08:00
|
|
|
// These functions are local to FileUtils.cpp and not exposed to the API
|
|
|
|
// returns the path string except for numToShorten directories stripped off the end
|
|
|
|
std::string GetShortenedPath(std::string path, int numToShorten)
|
|
|
|
{
|
|
|
|
unsigned int i = path.length() - 1;
|
|
|
|
if(path[i] == '/') i--;
|
|
|
|
while(i > 1 && numToShorten)
|
|
|
|
{
|
|
|
|
if(path[i] == '/')
|
|
|
|
numToShorten--;
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
return path.substr(0,i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns an absolute (POSIX on MacOS X) path from a CFURLRef
|
|
|
|
std::string GetPathFromCFURLRef(CFURLRef urlRef)
|
|
|
|
{
|
|
|
|
char buffer[1024];
|
|
|
|
std::string path;
|
|
|
|
if(CFURLGetFileSystemRepresentation(urlRef, true, (UInt8*)buffer, 1024))
|
|
|
|
path = std::string(buffer);
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns the absolute path to the main bundle
|
|
|
|
std::string GetApplicationBundlePath(CFBundleRef mainBundle)
|
|
|
|
{
|
|
|
|
std::string path;
|
|
|
|
CFURLRef urlRef = CFBundleCopyBundleURL(mainBundle);
|
|
|
|
if(urlRef)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
path = GetPathFromCFURLRef(urlRef);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease(urlRef); // docs say we are responsible for releasing CFURLRef
|
|
|
|
}
|
2005-07-27 05:07:31 +08:00
|
|
|
return path;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string GetApplicationParentPath(CFBundleRef mainBundle)
|
|
|
|
{
|
|
|
|
return GetShortenedPath(GetApplicationBundlePath(mainBundle), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string GetApplicationPluginsPath(CFBundleRef mainBundle)
|
|
|
|
{
|
|
|
|
std::string path;
|
|
|
|
CFURLRef urlRef = CFBundleCopyBuiltInPlugInsURL(mainBundle);
|
|
|
|
if(urlRef)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
path = GetPathFromCFURLRef(urlRef);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease(urlRef);
|
|
|
|
}
|
2005-07-27 05:07:31 +08:00
|
|
|
return path;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string GetApplicationResourcesPath(CFBundleRef mainBundle)
|
|
|
|
{
|
|
|
|
std::string path;
|
|
|
|
CFURLRef urlRef = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
|
|
|
if(urlRef)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
path = GetPathFromCFURLRef(urlRef);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease(urlRef);
|
|
|
|
}
|
2005-07-27 05:07:31 +08:00
|
|
|
return path;
|
|
|
|
}
|
2004-08-28 00:52:23 +08:00
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
// The Cocoa version is about 10 lines of code.
|
|
|
|
// The Carbon version is noticably longer.
|
|
|
|
// Unfortunately, the Cocoa version requires -lobjc to be
|
|
|
|
// linked in when creating an executable.
|
|
|
|
// Rumor is that this will be done autmatically in gcc 3.5/Tiger,
|
|
|
|
// but for now, this will cause a lot of headaches for people
|
|
|
|
// who aren't familiar with this concept, so the Carbon version
|
|
|
|
// is preferable.
|
|
|
|
// But for the curious, both implementations are here.
|
|
|
|
// Note that if the Cocoa version is used, the file should be
|
|
|
|
// renamed to use the .mm extension to denote Objective-C++.
|
|
|
|
// And of course, you will need to link against Cocoa
|
2006-08-22 05:09:40 +08:00
|
|
|
// Update: There is a bug in the Cocoa version. Advanced users can remap
|
|
|
|
// their systems so these paths go somewhere else. The Carbon calls
|
|
|
|
// will catch this, but the hardcoded Cocoa code below will not.
|
2004-08-28 00:14:21 +08:00
|
|
|
|
2004-08-28 00:52:23 +08:00
|
|
|
#ifdef COMPILE_COCOA_VERSION
|
2004-08-28 00:14:21 +08:00
|
|
|
// OS X has preferred locations for where PlugIns should be located.
|
|
|
|
// This function will set this as the order to search:
|
|
|
|
// YourProgram.app/Contents/PlugIns
|
|
|
|
// ~/Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
// /Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
// /Network/Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
//
|
|
|
|
// As a side effect of this function, if the application is not a
|
|
|
|
// bundle, the first place searched becomes
|
|
|
|
// YourProgram/PlugIns
|
|
|
|
//
|
|
|
|
// In principle, these other directories should be searched:
|
|
|
|
// ~/Library/Application Support/YourProgram/PlugIns
|
|
|
|
// /Library/Application Support/YourProgram/PlugIns
|
|
|
|
// /Network/Library/Application Support/TheProgram/PlugIns
|
|
|
|
// But I'm not going to worry about it for now because the
|
|
|
|
// bundle's PlugIns directory is supposed to be the preferred
|
|
|
|
// place for this anyway.
|
|
|
|
//
|
|
|
|
// Another directory that might be worth considering is
|
|
|
|
// the directory the program resides in,
|
|
|
|
// but I'm worried about multiplatform distribution.
|
|
|
|
// Because .so is used by other platforms like Linux, we
|
|
|
|
// could end up loading the wrong binary.
|
|
|
|
// I'm not sure how robust the current code is for this case.
|
|
|
|
// Assuming the program doesn't crash, will OSG move on to the
|
|
|
|
// next search directory, or just give up?
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
char* ptr;
|
|
|
|
if ((ptr = getenv( "DYLD_LIBRARY_PATH" )) )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr, filepath);
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
// Since this is currently the only Objective-C code in the
|
|
|
|
// library, we need an autoreleasepool for obj-c memory management.
|
|
|
|
// If more Obj-C is added, we might move this pool to another
|
|
|
|
// location so it can be shared. Pools seem to be stackable,
|
|
|
|
// so I don't think there will be a problem if multiple pools
|
|
|
|
// exist at a time.
|
|
|
|
NSAutoreleasePool* mypool = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
NSString* myBundlePlugInPath;
|
|
|
|
NSString* userSupportDir;
|
|
|
|
|
|
|
|
// This will grab the "official" bundle plug in path.
|
|
|
|
// It will be YourProgram.app/Contents/PlugIns (for App bundles)
|
|
|
|
// or YourProgram/PlugIns (for Unix executables)
|
|
|
|
myBundlePlugInPath = [[NSBundle mainBundle] builtInPlugInsPath];
|
|
|
|
|
|
|
|
// Now setup the other search paths
|
|
|
|
// Cocoa has a nice method for tilde expansion.
|
|
|
|
// There's probably a better way of getting this directory, but I
|
|
|
|
// can't find the call.
|
|
|
|
userSupportDir = [@"~/Library/Application Support/OpenSceneGraph/PlugIns" stringByExpandingTildeInPath];
|
|
|
|
|
|
|
|
// Can setup the remaining directories directly in C++
|
|
|
|
|
|
|
|
// Since Obj-C and C++ objects don't understand each other,
|
|
|
|
// the Obj-C strings must be converted down to C strings so
|
|
|
|
// C++ can make them into C++ strings.
|
|
|
|
filepath.push_back( [myBundlePlugInPath UTF8String] );
|
|
|
|
filepath.push_back( [userSupportDir UTF8String] );
|
|
|
|
|
|
|
|
filepath.push_back( "/Library/Application Support/OpenSceneGraph/PlugIns" );
|
|
|
|
filepath.push_back( "/Network/Library/Application Support/OpenSceneGraph/PlugIns" );
|
|
|
|
|
|
|
|
// Clean up the autorelease pool
|
|
|
|
[mypool release];
|
|
|
|
}
|
|
|
|
|
2004-08-28 00:52:23 +08:00
|
|
|
#elif defined(COMPILE_CARBON_VERSION)
|
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
// OS X has preferred locations for where PlugIns should be located.
|
|
|
|
// This function will set this as the order to search:
|
|
|
|
// YourProgram.app/Contents/PlugIns
|
|
|
|
// ~/Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
// /Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
// /Network/Library/Application Support/OpenSceneGraph/PlugIns
|
|
|
|
//
|
|
|
|
// In principle, these other directories should be searched:
|
|
|
|
// ~/Library/Application Support/YourProgram/PlugIns
|
|
|
|
// /Library/Application Support/YourProgram/PlugIns
|
|
|
|
// /Network/Library/Application Support/TheProgram/PlugIns
|
|
|
|
// But I'm not going to worry about it for now because the
|
|
|
|
// bundle's PlugIns directory is supposed to be the preferred
|
|
|
|
// place for this anyway.
|
|
|
|
//
|
|
|
|
// Another directory that might be worth considering is
|
|
|
|
// the directory the program resides in,
|
|
|
|
// but I'm worried about multiplatform distribution.
|
|
|
|
// Because .so is used by other platforms like Linux, we
|
|
|
|
// could end up loading the wrong binary.
|
|
|
|
// I'm not sure how robust the current code is for this case.
|
|
|
|
// Assuming the program doesn't crash, will OSG move on to the
|
|
|
|
// next search directory, or just give up?
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
char* ptr;
|
|
|
|
if ((ptr = getenv( "DYLD_LIBRARY_PATH" )) )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr, filepath);
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
const std::string OSG_PLUGIN_PATH("/OpenSceneGraph/PlugIns");
|
|
|
|
CFURLRef url;
|
|
|
|
CFBundleRef myBundle;
|
|
|
|
FSRef f;
|
2005-06-13 19:14:42 +08:00
|
|
|
OSErr errCode;
|
2004-08-28 00:14:21 +08:00
|
|
|
|
|
|
|
// Start with the the Bundle PlugIns directory.
|
|
|
|
|
2005-07-27 05:07:31 +08:00
|
|
|
// Get the main bundle first. No need to retain or release it since
|
|
|
|
// we are not keeping a reference
|
2004-08-28 00:14:21 +08:00
|
|
|
myBundle = CFBundleGetMainBundle();
|
2005-07-27 05:07:31 +08:00
|
|
|
|
2004-08-28 00:14:21 +08:00
|
|
|
if(myBundle != NULL)
|
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
// CFBundleGetMainBundle will return a bundle ref even if
|
|
|
|
// the application isn't part of a bundle, so we need to check
|
|
|
|
// if the path to the bundle ends in ".app" to see if it is a
|
|
|
|
// proper application bundle. If it is, the plugins path is added
|
|
|
|
std::string bundlePath = GetApplicationBundlePath(myBundle);
|
|
|
|
if( bundlePath.substr(bundlePath.length() - 4, 4) == std::string(".app") )
|
|
|
|
filepath.push_back(GetApplicationPluginsPath(myBundle));
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-28 00:19:05 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't find the Application Bundle" << std::endl;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next, check the User's Application Support folder
|
|
|
|
errCode = FSFindFolder( kUserDomain, kApplicationSupportFolderType, kDontCreateFolder, &f );
|
|
|
|
if(noErr == errCode)
|
|
|
|
{
|
|
|
|
// Get the URL
|
|
|
|
url = CFURLCreateFromFSRef( 0, &f );
|
2005-07-27 05:07:31 +08:00
|
|
|
if(url)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease( url );
|
|
|
|
}
|
2005-07-27 04:31:43 +08:00
|
|
|
else
|
2005-07-27 05:07:31 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for User's application support Path" << std::endl;
|
|
|
|
|
2005-07-27 04:31:43 +08:00
|
|
|
url = NULL;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-28 00:19:05 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't find the User's Application Support Path" << std::endl;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Next, check the Local System's Application Support Folder
|
|
|
|
errCode = FSFindFolder( kLocalDomain, kApplicationSupportFolderType, kDontCreateFolder, &f );
|
|
|
|
if(noErr == errCode)
|
|
|
|
{
|
|
|
|
// Get the URL
|
|
|
|
url = CFURLCreateFromFSRef( 0, &f );
|
2005-07-27 05:07:31 +08:00
|
|
|
|
|
|
|
if(url)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease( url );
|
|
|
|
}
|
2005-07-27 04:31:43 +08:00
|
|
|
else
|
2005-07-27 05:07:31 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for local System's ApplicationSupport Path" << std::endl;
|
|
|
|
|
2005-07-27 04:31:43 +08:00
|
|
|
url = NULL;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-28 00:19:05 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't find the Local System's Application Support Path" << std::endl;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, check the Network Application Support Folder
|
|
|
|
// This one has a likely chance of not existing so an error
|
|
|
|
// may be returned. Don't panic.
|
|
|
|
errCode = FSFindFolder( kNetworkDomain, kApplicationSupportFolderType, kDontCreateFolder, &f );
|
|
|
|
if(noErr == errCode)
|
|
|
|
{
|
|
|
|
// Get the URL
|
|
|
|
url = CFURLCreateFromFSRef( 0, &f );
|
2005-07-27 05:07:31 +08:00
|
|
|
|
|
|
|
if(url)
|
2006-02-21 00:20:50 +08:00
|
|
|
{
|
2005-07-27 05:07:31 +08:00
|
|
|
filepath.push_back(GetPathFromCFURLRef(url) + OSG_PLUGIN_PATH);
|
2006-02-21 00:20:50 +08:00
|
|
|
CFRelease( url );
|
|
|
|
}
|
2005-07-27 04:31:43 +08:00
|
|
|
else
|
2005-07-27 05:07:31 +08:00
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't create CFURLRef for network Application Support Path" << std::endl;
|
|
|
|
|
|
|
|
url = NULL;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-06-13 19:14:42 +08:00
|
|
|
// had to comment out as it segfauls the OSX app otherwise
|
2004-09-14 23:05:16 +08:00
|
|
|
// osg::notify( osg::DEBUG_INFO ) << "Couldn't find the Network Application Support Path" << std::endl;
|
2004-08-28 00:14:21 +08:00
|
|
|
}
|
|
|
|
}
|
2004-08-28 00:52:23 +08:00
|
|
|
#else
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
char* ptr;
|
|
|
|
if ((ptr = getenv( "DYLD_LIBRARY_PATH" )) )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr, filepath);
|
|
|
|
}
|
2008-09-19 20:49:22 +08:00
|
|
|
|
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
2004-08-28 00:52:23 +08:00
|
|
|
}
|
2004-08-28 00:14:21 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
|
|
|
|
char* ptr;
|
|
|
|
if( (ptr = getenv( "LD_LIBRARY_PATH" )) )
|
|
|
|
{
|
|
|
|
convertStringPathIntoFilePathList(ptr,filepath);
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
appendInstallationLibraryFilePaths(filepath);
|
2005-06-13 19:14:42 +08:00
|
|
|
|
|
|
|
#if defined(__ia64__) || defined(__x86_64__)
|
|
|
|
convertStringPathIntoFilePathList("/usr/lib/:/usr/lib64/:/usr/local/lib/:/usr/local/lib64/",filepath);
|
|
|
|
#else
|
2004-08-28 00:14:21 +08:00
|
|
|
convertStringPathIntoFilePathList("/usr/lib/:/usr/local/lib/",filepath);
|
2005-06-13 19:14:42 +08:00
|
|
|
#endif
|
2004-08-28 00:14:21 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2005-07-27 05:07:31 +08:00
|
|
|
#ifdef __APPLE__
|
|
|
|
void osgDB::appendPlatformSpecificResourceFilePaths(FilePathList& filepath)
|
|
|
|
{
|
|
|
|
// Get the main application bundle
|
|
|
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
|
|
|
|
|
|
|
if (mainBundle != NULL) {
|
|
|
|
// Get the parent directory and the resources directory
|
|
|
|
std::string bundlePath = GetApplicationBundlePath(mainBundle);
|
|
|
|
std::string resourcesPath = GetApplicationResourcesPath(mainBundle);
|
|
|
|
|
|
|
|
// check if application is really part of a .app bundle
|
|
|
|
if(bundlePath.substr(bundlePath.length() - 4, 4) == std::string(".app"))
|
|
|
|
{
|
|
|
|
if(resourcesPath != std::string(""))
|
|
|
|
filepath.push_back( resourcesPath );
|
|
|
|
|
|
|
|
std::string parentPath = GetShortenedPath(bundlePath, 1);
|
|
|
|
if(parentPath != std::string(""))
|
|
|
|
filepath.push_back( parentPath );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::notify( osg::DEBUG_INFO ) << "Couldn't find the Application Bundle." << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2005-10-24 21:46:31 +08:00
|
|
|
void osgDB::appendPlatformSpecificResourceFilePaths(FilePathList& /*filepath*/)
|
2005-07-27 05:07:31 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-28 00:14:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|