00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include "OSGConfig.h"
00043
00044 #include "OSGPathHandler.h"
00045
00046 #include "OSGFileSystem.h"
00047
00048 #ifndef WIN32
00049 #include <pwd.h>
00050 #endif
00051
00052 OSG_USING_NAMESPACE
00053
00054 const Char8 PathHandler::_dirSepWin32 = '\\';
00055 const Char8 PathHandler::_pathSepWin32 = ';';
00056
00057 const Char8 PathHandler::_dirSepUnix = '/';
00058 const Char8 PathHandler::_pathSepUnix = ':';
00059
00060 #ifdef WIN32
00061 const Char8 PathHandler::_dirSep = _dirSepWin32;
00062 const Char8 PathHandler::_pathSep = _pathSepWin32;
00063 const Char8 PathHandler::_dirSepOther = _dirSepUnix;
00064 const Char8 PathHandler::_pathSepOther = _pathSepUnix;
00065 #else
00066 const Char8 PathHandler::_dirSep = _dirSepUnix;
00067 const Char8 PathHandler::_pathSep = _pathSepUnix;
00068 const Char8 PathHandler::_dirSepOther = _dirSepWin32;
00069 const Char8 PathHandler::_pathSepOther = _pathSepWin32;
00070 #endif
00071
00072
00073
00074 PathHandler::PathHandler(void) :
00075 _pathList (),
00076 _baseFilePath()
00077 {
00078 }
00079
00080 PathHandler::PathHandler(const Char8 *initialPathList)
00081 {
00082 push_backUnixPath(initialPathList);
00083 }
00084
00085
00086
00087 PathHandler::~PathHandler(void)
00088 {
00089 }
00090
00091
00092
00093 std::string PathHandler::findFile(const Char8 *fileName)
00094 {
00095 std::string returnValue;
00096 bool bFound = false;
00097
00098 PathList tmpList;
00099
00100 PathListIter iter = _pathList.begin();
00101 PathListIter listEnd = _pathList.end();
00102
00103 PathType pType = analysePath(fileName);
00104
00105
00106 parsePathList(fileName, tmpList);
00107
00108 if(tmpList.size() != 0)
00109 {
00110 if((pType & TypeMask) == AbsPath)
00111 {
00112 SINFO << "Check abs : " << fileName << std::endl;
00113
00114 if(File::tstAttr(fileName,
00115 AccessFlags::IsReadable))
00116 {
00117 returnValue.assign(fileName);
00118 }
00119 }
00120 else
00121 {
00122 if(_baseFilePath.empty() == false)
00123 {
00124 returnValue.assign(_baseFilePath);
00125
00126 returnValue.append(tmpList.front());
00127
00128 SINFO << "Check base : " << returnValue << std::endl;
00129
00130 if(File::tstAttr(returnValue.c_str(),
00131 AccessFlags::IsReadable) == false)
00132 {
00133 returnValue.erase();
00134 }
00135 else
00136 {
00137 bFound = true;
00138 }
00139 }
00140
00141 if(bFound == false)
00142 {
00143 while(iter != listEnd)
00144 {
00145 returnValue.assign(*iter);
00146 returnValue.append(tmpList.front());
00147
00148 SINFO << "Check from pl : " << returnValue << std::endl;
00149
00150 if(File::tstAttr(returnValue.c_str(),
00151 AccessFlags::IsReadable) == true)
00152 {
00153 break;
00154 }
00155
00156 ++iter;
00157 }
00158
00159 if(iter == listEnd)
00160 {
00161 returnValue.erase();
00162 }
00163 }
00164 }
00165 }
00166
00167 return returnValue;
00168 }
00169
00170 const std::string &PathHandler::getBaseFile (void) const
00171 {
00172 return _baseFilePath;
00173 }
00174
00175
00176
00177 void PathHandler::push_backPath(const Char8 *pathList)
00178 {
00179 PathList tmpList;
00180
00181 parsePathList(pathList, tmpList);
00182
00183 push_backPathList(tmpList);
00184 }
00185
00186 void PathHandler::push_backCurrentDir(void)
00187 {
00188 Char8 *pCurrentDir = Directory::getCurrent();
00189 std::string tmpString = pCurrentDir;
00190
00191 _pathList.push_back(tmpString);
00192
00193 validateList(_pathList);
00194
00195 delete [] pCurrentDir;
00196 }
00197
00198 void PathHandler::push_backUnixPath(const Char8 *pathList)
00199 {
00200 PathList tmpList;
00201
00202 parseUnixPathList(pathList, tmpList);
00203
00204 push_backPathList(tmpList);
00205 }
00206
00207 void PathHandler::push_backWin32Path(const Char8 *pathList)
00208 {
00209 PathList tmpList;
00210
00211 parseWin32PathList(pathList, tmpList);
00212
00213 push_backPathList(tmpList);
00214 }
00215
00216
00217 void PathHandler::push_frontPath(const Char8 *pathList)
00218 {
00219 PathList tmpList;
00220
00221 parsePathList(pathList, tmpList);
00222
00223 push_frontPathList(tmpList);
00224 }
00225
00226 void PathHandler::push_frontCurrentDir(void)
00227 {
00228 Char8 *pCurrentDir = Directory::getCurrent();
00229 std::string tmpString = pCurrentDir;
00230
00231 _pathList.push_front(tmpString);
00232
00233 validateList(_pathList);
00234
00235 delete [] pCurrentDir;
00236 }
00237
00238 void PathHandler::push_frontUnixPath(const Char8 *pathList)
00239 {
00240 PathList tmpList;
00241
00242 parseUnixPathList(pathList, tmpList);
00243
00244 push_frontPathList(tmpList);
00245 }
00246
00247 void PathHandler::push_frontWin32Path(const Char8 *pathList)
00248 {
00249 PathList tmpList;
00250
00251 parseWin32PathList(pathList, tmpList);
00252
00253 push_frontPathList(tmpList);
00254 }
00255
00256 void PathHandler::subPath(const Char8 *pathList)
00257 {
00258 PathList tmpList;
00259
00260 parsePathList(pathList, tmpList);
00261 validateList(tmpList);
00262 subPathList(tmpList);
00263 }
00264
00265 void PathHandler::subUnixPath(const Char8 *pathList)
00266 {
00267 PathList tmpList;
00268
00269 parseUnixPathList(pathList, tmpList);
00270 validateList(tmpList);
00271 subPathList(tmpList);
00272 }
00273
00274 void PathHandler::subWin32Path(const Char8 *pathList)
00275 {
00276 PathList tmpList;
00277
00278 parseWin32PathList(pathList, tmpList);
00279 validateList(tmpList);
00280 subPathList(tmpList);
00281 }
00282
00283 void PathHandler::clearPathList(void)
00284 {
00285 _pathList.clear();
00286 }
00287
00288
00289 void PathHandler::setBaseFile(const Char8 *fileName)
00290 {
00291 if(fileName != NULL)
00292 {
00293 _baseFilePath = extractPath(fileName);
00294 }
00295 }
00296
00297 void PathHandler::clearBaseFile(void)
00298 {
00299 _baseFilePath.erase();
00300 }
00301
00302
00303
00304 void PathHandler::dump(void)
00305 {
00306 PathListIter iter = _pathList.begin();
00307
00308 if(_baseFilePath.size() != 0)
00309 {
00310 SLOG << "Base file path : " << _baseFilePath << std::endl;
00311 }
00312 else
00313 {
00314 SLOG << "Base file path : empty" << std::endl;
00315 }
00316
00317 for( ; iter != _pathList.end(); ++iter )
00318 {
00319 SLOG << "\"" << *iter << "\"" << std::endl;
00320 }
00321 }
00322
00323
00324
00325 void PathHandler::validateList(PathList &pathList)
00326 {
00327 PathListIter iter = pathList.begin();
00328 PathListIter listEnd = pathList.end();
00329
00330 while(iter != listEnd)
00331 {
00332 if(iter->empty() == true)
00333 {
00334 (*iter) += '.';
00335 (*iter) += _dirSep;
00336 }
00337 else
00338 {
00339 if((*iter)[iter->length() - 1] != _dirSep)
00340 {
00341 (*iter) += _dirSep;
00342 }
00343 }
00344
00345 ++iter;
00346 }
00347 }
00348
00349 std::string PathHandler::extractPath(const Char8 *szFilename)
00350 {
00351 std::string returnValue(szFilename);
00352
00353 std::string::size_type pos = returnValue.find_last_of("\\/");
00354
00355 if(pos != std::string::npos)
00356 {
00357 if(pos != returnValue.length() - 1)
00358 {
00359 returnValue.erase(pos + 1);
00360 }
00361 }
00362 else
00363 {
00364 returnValue.assign(".");
00365 }
00366
00367 PathType pType = analysePathList(returnValue.c_str());
00368
00369 if((pType & PlatformMask) == Win32Path)
00370 {
00371 #ifndef WIN32
00372 convertPath(returnValue);
00373 #endif
00374 }
00375 else
00376 {
00377 #ifdef WIN32
00378 convertPath(returnValue);
00379 #endif
00380 }
00381
00382 if(returnValue[returnValue.length() - 1] != _dirSep)
00383 {
00384 returnValue += _dirSep;
00385 }
00386
00387 return returnValue;
00388 }
00389
00390 PathHandler::PathType PathHandler::analysePathList(const Char8 *pathList)
00391 {
00392 PathType returnValue = UnixPath;
00393 const Char8 *pCurr = pathList;
00394
00395 if(pathList == NULL)
00396 return returnValue;
00397
00398 while(*pCurr != '\0')
00399 {
00400 if(*pCurr == '\\')
00401 {
00402 returnValue = Win32Path;
00403 break;
00404 }
00405 else if(*pCurr == ';')
00406 {
00407 returnValue = Win32Path;
00408 break;
00409 }
00410 else if(*pCurr == '%')
00411 {
00412 returnValue = Win32Path;
00413 break;
00414 }
00415 else if(*pCurr == '/')
00416 {
00417 returnValue = UnixPath;
00418 break;
00419 }
00420 else if(*pCurr == '$')
00421 {
00422 returnValue = UnixPath;
00423 break;
00424 }
00425 else if(*pCurr == ':')
00426 {
00427 if(*(pCurr + 1) == '\\')
00428 {
00429 returnValue = Win32Path;
00430 break;
00431 }
00432 }
00433
00434 pCurr++;
00435 }
00436
00437 #ifdef WIN32
00438
00439 if(returnValue == UnixPath)
00440 {
00441
00442 UInt32 uiSize = 0;
00443 pCurr = pathList;
00444 while(*pCurr != '\0')
00445 {
00446 if(*pCurr == ';')
00447 {
00448 returnValue = Win32Path;
00449 break;
00450 }
00451 pCurr++;
00452 uiSize++;
00453 }
00454
00455
00456 if(returnValue == UnixPath)
00457 {
00458 if(uiSize >= 3)
00459 {
00460 if(pathList[1] == ':' &&
00461 (pathList[2] == '/' || pathList[2] == '\\'))
00462 {
00463 returnValue = Win32Path;
00464 }
00465 }
00466 }
00467 }
00468 #endif
00469
00470 return returnValue;
00471 }
00472
00473 PathHandler::PathType PathHandler::analysePath(const Char8 *path)
00474 {
00475 PathType returnValue = UnixPath;
00476 UInt32 uiSize = 0;
00477 const Char8 *pCurr = path;
00478
00479 if(path == NULL)
00480 return returnValue;
00481
00482 while(*pCurr != '\0')
00483 {
00484 if(*pCurr == '\\')
00485 {
00486 returnValue = Win32Path;
00487 break;
00488 }
00489 else if(*pCurr == ';')
00490 {
00491 returnValue = Win32Path;
00492 break;
00493 }
00494 else if(*pCurr == '%')
00495 {
00496 returnValue = Win32Path;
00497 break;
00498 }
00499 else if(*pCurr == '/')
00500 {
00501 returnValue = UnixPath;
00502 break;
00503 }
00504 else if(*pCurr == '$')
00505 {
00506 returnValue = UnixPath;
00507 break;
00508 }
00509 else if(*pCurr == ':')
00510 {
00511 if(*(pCurr + 1) == '\\')
00512 {
00513 returnValue = Win32Path;
00514 uiSize++;
00515 break;
00516 }
00517 }
00518
00519 pCurr++;
00520 uiSize++;
00521 }
00522
00523 #ifdef WIN32
00524 if(returnValue == UnixPath)
00525 {
00526
00527 if(uiSize >= 2)
00528 {
00529 if(path[1] == ':')
00530 returnValue = Win32Path;
00531 }
00532 }
00533 #endif
00534
00535 if(returnValue == Win32Path)
00536 {
00537 if(uiSize >= 2)
00538 {
00539 if(path[1] == ':')
00540 returnValue = (PathType) (returnValue | AbsPath);
00541 }
00542 else
00543 {
00544
00545 if(path[0] == '\\' && path[1] == '\\')
00546 returnValue = (PathType) (returnValue | AbsPath);
00547 }
00548 }
00549 else
00550 {
00551 if(path[0] == '/')
00552 returnValue = (PathType) (returnValue | AbsPath);
00553 }
00554
00555 return returnValue;
00556 }
00557
00558 void PathHandler::expandWin32Path(std::string &path)
00559 {
00560 std::string envVar;
00561
00562 std::string::size_type currPos = 0;
00563 std::string::size_type startPos = 0;
00564
00565 while(currPos < path.size())
00566 {
00567 if(path[currPos] == '%')
00568 {
00569 envVar.erase();
00570 startPos = currPos++;
00571
00572 while(path[currPos] != '%' &&
00573 currPos < path.size())
00574 {
00575 envVar += path[currPos++];
00576 }
00577
00578 if(currPos < path.size())
00579 {
00580 currPos++;
00581 }
00582
00583 Char8 *szEnvVal = getenv(envVar.c_str());
00584
00585 if(szEnvVal == NULL)
00586 {
00587 FWARNING(("Could not find env var %s\n", envVar.c_str()));
00588 }
00589 else
00590 {
00591 path.replace(startPos, currPos - startPos, szEnvVal);
00592 }
00593 }
00594 else
00595 {
00596 currPos++;
00597 }
00598 }
00599 }
00600
00601 void PathHandler::expandUnixPath(std::string &path)
00602 {
00603 std::string envVar;
00604 std::string userName;
00605 std::string userHome;
00606 #ifndef WIN32
00607 bool stop;
00608 passwd *userInfo;
00609 #endif
00610
00611 std::string::size_type currPos = 0;
00612 std::string::size_type startPos = 0;
00613
00614 while(currPos < path.size())
00615 {
00616 if(path[currPos] == '$')
00617 {
00618 envVar.erase();
00619 startPos = currPos++;
00620
00621 while(path[currPos] != ':' &&
00622 path[currPos] != '/' &&
00623 path[currPos] != '$' &&
00624 currPos < path.size())
00625 {
00626 envVar += path[currPos++];
00627 }
00628
00629 Char8 *szEnvVal = getenv(envVar.c_str());
00630
00631 if(szEnvVal == NULL)
00632 {
00633 FWARNING(("Could not find env var %s\n", envVar.c_str()));
00634 }
00635 else
00636 {
00637 path.replace(startPos, currPos - startPos, szEnvVal);
00638 }
00639 }
00640 #ifndef WIN32
00641 else if(path[currPos] == '~')
00642 {
00643 userName.erase();
00644 startPos = currPos++;
00645
00646 while(path[currPos] != ':' &&
00647 path[currPos] != '/' &&
00648 path[currPos] != '$' &&
00649 currPos < path.size())
00650 {
00651 userName += path[currPos++];
00652 }
00653
00654 if(!userName.empty())
00655 {
00656 setpwent();
00657 stop = false;
00658
00659 while(stop == false)
00660 {
00661 if((userInfo=getpwent()) != NULL )
00662 {
00663 if(strcmp(userName.c_str(), userInfo->pw_name) == 0)
00664 {
00665 stop = true;
00666 userHome = userInfo->pw_dir;
00667 }
00668 }
00669 else
00670 {
00671 stop = true;
00672 }
00673 }
00674 endpwent();
00675 }
00676 else
00677 {
00678 if((userInfo=getpwuid(getuid())) != NULL)
00679 {
00680 userHome = userInfo->pw_dir;
00681 }
00682 }
00683
00684 if(userHome.empty() == false)
00685 {
00686 path.replace(startPos, currPos - startPos, userHome);
00687 }
00688 else
00689 {
00690 FWARNING(("Could not find user home %s\n", userHome.c_str()));
00691 }
00692 }
00693 #endif
00694 else
00695 {
00696 currPos++;
00697 }
00698 }
00699 }
00700
00701 void PathHandler::push_backPathList(PathList &pathList)
00702 {
00703 _pathList.splice(_pathList.end(), pathList);
00704
00705 validateList(_pathList);
00706 }
00707
00708 void PathHandler::push_frontPathList(PathList &pathList)
00709 {
00710 _pathList.splice(_pathList.begin(), pathList);
00711
00712 validateList(_pathList);
00713 }
00714
00715 void PathHandler::subPathList(const PathList &pathList)
00716 {
00717 for(PathList::const_iterator i = pathList.begin();i != pathList.end();++i)
00718 {
00719 for(PathList::iterator j = _pathList.begin();j != _pathList.end();++j)
00720 {
00721 if(*j == *i)
00722 {
00723 _pathList.erase(j);
00724 break;
00725 }
00726 }
00727 }
00728 }
00729
00730 void PathHandler::convertPath(std::string &path)
00731 {
00732 std::string::iterator stringIt = path.begin();
00733 std::string::iterator stringEnd = path.end ();
00734
00735 while(stringIt != stringEnd)
00736 {
00737 if(*stringIt == _dirSepOther)
00738 {
00739 *stringIt = _dirSep;
00740 }
00741
00742 stringIt++;
00743 };
00744 }
00745
00746 void PathHandler::convertWin32PathList(PathList &result)
00747 {
00748 PathListIter iter = result.begin();
00749 PathListIter endList = result.end();
00750
00751 while(iter != endList)
00752 {
00753 expandWin32Path(*iter);
00754
00755 #ifndef WIN32
00756 convertPath (*iter);
00757 #endif
00758
00759 iter++;
00760 };
00761 }
00762
00763 void PathHandler::convertUnixPathList(PathList &result)
00764 {
00765 PathListIter iter = result.begin();
00766 PathListIter endList = result.end();
00767
00768 while(iter != endList)
00769 {
00770 expandUnixPath(*iter);
00771
00772 #ifdef WIN32
00773 convertPath (*iter);
00774 #endif
00775
00776 iter++;
00777 };
00778 }
00779
00780 void PathHandler::splitPathList(const Char8 *pathList,
00781 const Char8 pathSep,
00782 PathList &result)
00783 {
00784 std::string::size_type currPos = 0;
00785 std::string::size_type startPos = 0;
00786 std::string workString(pathList);
00787
00788 currPos = workString.find(pathSep);
00789
00790 if(currPos == std::string::npos)
00791 {
00792 result.push_back(workString);
00793 }
00794 else
00795 {
00796 while(currPos != std::string::npos)
00797 {
00798 result.push_back(workString.substr(startPos,
00799 currPos - startPos));
00800
00801 startPos = currPos + 1;
00802
00803 currPos = workString.find(pathSep, startPos);
00804 }
00805
00806 if(startPos != 0)
00807 {
00808 result.push_back(workString.substr(startPos));
00809 }
00810 }
00811 }
00812
00813 void PathHandler::parsePathList(const Char8 *pathList, PathList &result)
00814 {
00815 PathType pType = analysePathList(pathList);
00816
00817 if((pType & PlatformMask) == Win32Path)
00818 {
00819 parseWin32PathList(pathList, result);
00820 }
00821 else
00822 {
00823 parseUnixPathList (pathList, result);
00824 }
00825 }
00826
00827 void PathHandler::parseUnixPathList(const Char8 *pathList, PathList &result)
00828 {
00829 if(pathList == NULL)
00830 return;
00831
00832 splitPathList (pathList, _pathSepUnix, result);
00833
00834 convertUnixPathList(result);
00835 }
00836
00837 void PathHandler::parseWin32PathList(const Char8 *pathList, PathList &result)
00838 {
00839 if(pathList == NULL)
00840 return;
00841
00842 splitPathList (pathList, _pathSepWin32, result);
00843
00844 convertWin32PathList(result);
00845 }
00846
00847
00848
00849
00850
00851 #ifdef __sgi
00852 #pragma set woff 1174
00853 #endif
00854
00855 #ifdef OSG_LINUX_ICC
00856 #pragma warning( disable : 177 )
00857 #endif
00858
00859 namespace
00860 {
00861 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00862 static Char8 cvsid_hpp[] = OSGPATHHANDLER_HEADER_CVSID;
00863 }
00864
00865
00866
00867
00868
00869