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
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
// currently this impl is for _all_ platforms, except as defined.
|
2002-07-17 03:21:31 +08:00
|
|
|
// 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().
|
2008-11-21 20:15:16 +08:00
|
|
|
#ifndef F_OK
|
2002-06-18 05:50:37 +08:00
|
|
|
#define F_OK 4
|
2008-11-21 20:15:16 +08:00
|
|
|
#endif
|
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
|
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
#include <osg/Config>
|
|
|
|
#include <osgDB/ConvertUTF>
|
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>
|
2008-12-13 02:47:30 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
2004-09-01 22:49:18 +08:00
|
|
|
#include <stack>
|
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
namespace osgDB
|
|
|
|
{
|
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
#define OSGDB_STRING_TO_FILENAME(s) osgDB::convertUTF8toUTF16(s)
|
|
|
|
#define OSGDB_FILENAME_TO_STRING(s) osgDB::convertUTF16toUTF8(s)
|
|
|
|
#define OSGDB_FILENAME_TEXT(x) L ## x
|
|
|
|
#define OSGDB_WINDOWS_FUNCT(x) x ## W
|
|
|
|
typedef wchar_t filenamechar;
|
|
|
|
typedef std::wstring filenamestring;
|
|
|
|
#else
|
|
|
|
#define OSGDB_STRING_TO_FILENAME(s) s
|
|
|
|
#define OSGDB_FILENAME_TO_STRING(s) s
|
|
|
|
#define OSGDB_FILENAME_TEXT(x) x
|
|
|
|
#define OSGDB_WINDOWS_FUNCT(x) x ## A
|
|
|
|
typedef char filenamechar;
|
|
|
|
typedef std::string filenamestring;
|
|
|
|
#endif
|
|
|
|
}
|
2007-05-20 20:29:11 +08:00
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
FILE* osgDB::fopen(const char* filename, const char* mode)
|
|
|
|
{
|
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
return ::_wfopen(convertUTF8toUTF16(filename).c_str(), convertUTF8toUTF16(mode).c_str());
|
|
|
|
#else
|
|
|
|
return ::fopen(filename, mode);
|
|
|
|
#endif
|
|
|
|
}
|
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;
|
2008-11-07 23:08:08 +08:00
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
if( _wstat64( OSGDB_STRING_TO_FILENAME(path).c_str(), &stbuf ) == 0 )
|
|
|
|
#else
|
2004-10-03 16:50:56 +08:00
|
|
|
if( stat64( path.c_str(), &stbuf ) == 0 )
|
2008-11-07 23:08:08 +08:00
|
|
|
#endif
|
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;
|
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
if( _wstat64( OSGDB_STRING_TO_FILENAME(dir).c_str(), &stbuf ) < 0 )
|
|
|
|
#else
|
2004-10-03 16:50:56 +08:00
|
|
|
if( stat64( dir.c_str(), &stbuf ) < 0 )
|
2008-11-07 23:08:08 +08:00
|
|
|
#endif
|
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
|
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
if ( _wmkdir(OSGDB_STRING_TO_FILENAME(dir).c_str())< 0 )
|
|
|
|
#else
|
2004-09-01 22:49:18 +08:00
|
|
|
if( mkdir( dir.c_str(), 0755 )< 0 )
|
2008-11-07 23:08:08 +08:00
|
|
|
#endif
|
2004-09-01 22:49:18 +08:00
|
|
|
{
|
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)
|
|
|
|
{
|
2008-11-07 23:08:08 +08:00
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
return _waccess( OSGDB_STRING_TO_FILENAME(filename).c_str(), F_OK ) == 0;
|
|
|
|
#else
|
2002-06-18 05:50:37 +08:00
|
|
|
return access( filename.c_str(), F_OK ) == 0;
|
2008-11-07 23:08:08 +08:00
|
|
|
#endif
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
|
|
|
|
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;
|
2008-11-07 23:08:08 +08:00
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
if ( _wstat64(OSGDB_STRING_TO_FILENAME(filename).c_str(), &fileStat) != 0 )
|
|
|
|
#else
|
|
|
|
if ( stat64(filename.c_str(), &fileStat) != 0 )
|
|
|
|
#endif
|
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;
|
|
|
|
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
std::string realDirName = dirName;
|
|
|
|
std::string realFileName = fileName;
|
|
|
|
|
|
|
|
// Skip case-insensitive recursion if on Windows
|
|
|
|
#ifdef WIN32
|
|
|
|
bool win32 = true;
|
|
|
|
#else
|
|
|
|
bool win32 = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// If the fileName contains extra path information, make that part of the
|
|
|
|
// directory name instead
|
|
|
|
if (fileName != getSimpleFileName(fileName))
|
|
|
|
{
|
|
|
|
// See if we need to add a slash between the directory and file
|
|
|
|
if (realDirName.empty())
|
|
|
|
{
|
|
|
|
realDirName = getFilePath(fileName);
|
|
|
|
}
|
|
|
|
else if (realDirName=="." || realDirName=="./" || realDirName==".\\")
|
|
|
|
{
|
|
|
|
realDirName = "./" + getFilePath(fileName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char lastChar = dirName[dirName.size()-1];
|
|
|
|
if ((lastChar == '/') || (lastChar == '\\'))
|
|
|
|
realDirName = dirName + getFilePath(fileName);
|
|
|
|
else
|
|
|
|
realDirName = dirName + "/" + getFilePath(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Simplify the file name
|
|
|
|
realFileName = getSimpleFileName(fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
osg::notify(osg::DEBUG_INFO) << "findFileInDirectory() : looking for " << realFileName << " in " << realDirName << "...\n";
|
|
|
|
|
|
|
|
if (realDirName.empty())
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
|
|
|
dc = osgDB::getDirectoryContents(".");
|
|
|
|
needFollowingBackslash = false;
|
|
|
|
needDirectoryName = false;
|
|
|
|
}
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
else if (realDirName=="." || realDirName=="./" || realDirName==".\\")
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
|
|
|
dc = osgDB::getDirectoryContents(".");
|
|
|
|
needFollowingBackslash = false;
|
|
|
|
needDirectoryName = false;
|
|
|
|
}
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
else if (realDirName=="/")
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
dc = osgDB::getDirectoryContents("/");
|
|
|
|
needFollowingBackslash = false;
|
2002-06-18 05:50:37 +08:00
|
|
|
needDirectoryName = true;
|
|
|
|
}
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// See if we're working in case insensitive mode, and that we're not
|
|
|
|
// using Windows (the recursive search is not needed in these
|
|
|
|
// cases)
|
|
|
|
if ((caseSensitivity == CASE_INSENSITIVE) && (!win32))
|
|
|
|
{
|
|
|
|
// Split the last path element from the directory name
|
|
|
|
std::string parentPath = getFilePath(realDirName);
|
|
|
|
std::string lastElement = getSimpleFileName(realDirName);
|
|
|
|
|
|
|
|
// See if we're already at the top level of the filesystem
|
|
|
|
if ((parentPath.empty()) && (!lastElement.empty()))
|
|
|
|
{
|
|
|
|
// Search for the first path element (ignoring case) in
|
|
|
|
// the top-level directory
|
|
|
|
realDirName = findFileInDirectory(lastElement, "/",
|
|
|
|
CASE_INSENSITIVE);
|
|
|
|
|
|
|
|
dc = osgDB::getDirectoryContents(realDirName);
|
|
|
|
needFollowingBackslash = true;
|
|
|
|
needDirectoryName = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Recursively search for the last path element (ignoring case)
|
|
|
|
// in the parent path
|
|
|
|
realDirName = findFileInDirectory(lastElement, parentPath,
|
|
|
|
CASE_INSENSITIVE);
|
|
|
|
|
|
|
|
dc = osgDB::getDirectoryContents(realDirName);
|
|
|
|
char lastChar = realDirName[realDirName.size()-1];
|
|
|
|
if (lastChar=='/') needFollowingBackslash = false;
|
|
|
|
else if (lastChar=='\\') needFollowingBackslash = false;
|
|
|
|
else needFollowingBackslash = true;
|
|
|
|
needDirectoryName = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No need for recursive search if we're doing an exact comparison
|
|
|
|
dc = osgDB::getDirectoryContents(realDirName);
|
|
|
|
char lastChar = realDirName[realDirName.size()-1];
|
|
|
|
if (lastChar=='/') needFollowingBackslash = false;
|
|
|
|
else if (lastChar=='\\') needFollowingBackslash = false;
|
|
|
|
else needFollowingBackslash = true;
|
|
|
|
needDirectoryName = true;
|
|
|
|
}
|
|
|
|
}
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
for(osgDB::DirectoryContents::iterator itr=dc.begin();
|
|
|
|
itr!=dc.end();
|
|
|
|
++itr)
|
|
|
|
{
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
if ((caseSensitivity==CASE_INSENSITIVE && osgDB::equalCaseInsensitive(realFileName,*itr)) ||
|
|
|
|
(realFileName==*itr))
|
2002-06-18 05:50:37 +08:00
|
|
|
{
|
|
|
|
if (!needDirectoryName) return *itr;
|
From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:
osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search. This is because the HL2 map and model files are often sloppy with case. For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf. In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case. In case-sensitive mode, the code behaves exactly as it used to. The new code is also mostly skipped on Windows because of the case-insensitive file system. Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH. There are some instructions in the plugins' README files about this.
osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps). This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps. Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations. Currently, it can load the simple objects. It can also load the characters, but it can't load the skeletons or animations.
osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry. There are also
several bugs fixed.
osgPlugins/vtf:
This is the loader for Valve's texture format. Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time. It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate. I also fixed a rather significant bug.
I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit). I'll be testing on Windows soon.
I also attached a simple .mdl file, along with it's associated files and textures. Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:
osgviewer models/props_junk/gascan001a.mdl"
2008-12-20 21:35:49 +08:00
|
|
|
else if (needFollowingBackslash) return realDirName+'/'+*itr;
|
|
|
|
else return realDirName+*itr;
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
static void appendInstallationLibraryFilePaths(osgDB::FilePathList& filepath)
|
|
|
|
{
|
|
|
|
#ifdef OSG_DEFAULT_LIBRARY_PATH
|
2008-09-22 21:16:29 +08:00
|
|
|
|
2008-09-19 20:49:22 +08:00
|
|
|
// Append the install prefix path to the library search path if configured
|
2008-09-22 21:16:29 +08:00
|
|
|
filepath.push_back(ADDQUOTES(OSG_DEFAULT_LIBRARY_PATH));
|
2008-09-19 20:49:22 +08:00
|
|
|
#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;
|
|
|
|
|
2008-11-07 23:08:08 +08:00
|
|
|
OSGDB_WINDOWS_FUNCT(WIN32_FIND_DATA) data;
|
|
|
|
HANDLE handle = OSGDB_WINDOWS_FUNCT(FindFirstFile)((OSGDB_STRING_TO_FILENAME(dirName) + OSGDB_FILENAME_TEXT("\\*")).c_str(), &data);
|
2002-06-18 05:50:37 +08:00
|
|
|
if (handle != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2008-11-07 23:08:08 +08:00
|
|
|
contents.push_back(OSGDB_FILENAME_TO_STRING(data.cFileName));
|
2002-06-18 05:50:37 +08:00
|
|
|
}
|
2008-11-07 23:08:08 +08:00
|
|
|
while (OSGDB_WINDOWS_FUNCT(FindNextFile)(handle, &data) != 0);
|
2002-06-18 05:50:37 +08:00
|
|
|
|
|
|
|
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;
|
2008-11-07 23:08:08 +08:00
|
|
|
filenamechar path[size];
|
|
|
|
retval = OSGDB_WINDOWS_FUNCT(GetModuleFileName)(NULL, path, size);
|
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
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
2008-11-07 23:08:08 +08:00
|
|
|
filenamestring pathstr(path);
|
|
|
|
filenamestring executableDir(pathstr, 0,
|
|
|
|
pathstr.find_last_of(OSGDB_FILENAME_TEXT("\\/")));
|
|
|
|
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(executableDir), 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
|
|
|
}
|
|
|
|
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.
|
2008-11-07 23:08:08 +08:00
|
|
|
filenamechar systemDir[(UINT)size];
|
|
|
|
retval = OSGDB_WINDOWS_FUNCT(GetSystemDirectory)(systemDir, (UINT)size);
|
|
|
|
|
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
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
2008-11-07 23:08:08 +08:00
|
|
|
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(systemDir),
|
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
|
|
|
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.
|
2008-11-07 23:08:08 +08:00
|
|
|
filenamechar windowsDir[(UINT)size];
|
|
|
|
retval = OSGDB_WINDOWS_FUNCT(GetWindowsDirectory)(windowsDir, (UINT)size);
|
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
|
|
|
if (retval != 0 && retval < size)
|
|
|
|
{
|
2008-11-07 23:08:08 +08:00
|
|
|
convertStringPathIntoFilePathList(std::string(OSGDB_FILENAME_TO_STRING(windowsDir)) +
|
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
|
|
|
"\\System", filepath);
|
2008-11-07 23:08:08 +08:00
|
|
|
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(windowsDir),
|
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
|
|
|
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.
|
2008-11-07 23:08:08 +08:00
|
|
|
filenamechar* ptr;
|
|
|
|
#ifdef OSG_USE_UTF8_FILENAME
|
|
|
|
if (ptr = _wgetenv(OSGDB_FILENAME_TEXT("PATH")))
|
|
|
|
#else
|
|
|
|
if (ptr = getenv("PATH"))
|
|
|
|
#endif
|
2004-08-28 00:14:21 +08:00
|
|
|
{
|
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.
|
2008-11-07 23:08:08 +08:00
|
|
|
convertStringPathIntoFilePathList(OSGDB_FILENAME_TO_STRING(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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|