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