1 /* 2 * File: SearchPath.cpp 3 * 4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 * See included license file for license details. 6 */ 7 8 #include "SearchPath.h" 9 #include <stdio.h> 10 11 #if defined(WIN32) 12 #define PATH_SEP_CHAR '\\' 13 #define PATH_SEP_STRING "\\" 14 #else 15 #define PATH_SEP_CHAR '/' 16 #define PATH_SEP_STRING "/" 17 #endif 18 19 PathSearcher * PathSearcher::s_searcher = NULL; 20 21 //! This function will create the global path search object if it has 22 //! not already been created. 23 PathSearcher & PathSearcher::getGlobalSearcher() 24 { 25 if (!s_searcher) 26 { 27 s_searcher = new PathSearcher; 28 } 29 30 return *s_searcher; 31 } 32 33 void PathSearcher::addSearchPath(std::string & path) 34 { 35 m_paths.push_back(path); 36 } 37 38 //! The \a base path argument can be either a relative or absolute path. If the path 39 //! is relative, then it is joined with search paths one after another until a matching 40 //! file is located or all search paths are exhausted. If the \a base is absolute, 41 //! only that path is tested and if invalid false is returned. 42 //! 43 //! \param base A path to the file that is to be found. 44 //! \param targetType Currently ignored. In the future it will let you select whether to 45 //! find a file or directory. 46 //! \param searchCwd If set to true, the current working directory is searched before using 47 //! any of the search paths. Otherwise only the search paths are considered. 48 //! \param[out] result When true is returned this string is set to the first path at which 49 //! a valid file was found. 50 //! 51 //! \retval true A matching file was found among the search paths. The contents of \a result 52 //! are a valid path. 53 //! \retval false No match could be made. \a result has been left unmodified. 54 bool PathSearcher::search(const std::string & base, target_type_t targetType, bool searchCwd, std::string & result) 55 { 56 FILE * tempFile; 57 bool absolute = isAbsolute(base); 58 59 // Try cwd first if requested. Same process applies to absolute paths. 60 if (absolute || searchCwd) 61 { 62 tempFile = fopen(base.c_str(), "r"); 63 if (tempFile) 64 { 65 fclose(tempFile); 66 result = base; 67 return true; 68 } 69 } 70 71 // If the base path is absolute and the previous test failed, then we don't go any further. 72 if (absolute) 73 { 74 return false; 75 } 76 77 // Iterate over all search paths. 78 string_list_t::const_iterator it = m_paths.begin(); 79 for (; it != m_paths.end(); ++it) 80 { 81 std::string searchPath = joinPaths(*it, base); 82 83 tempFile = fopen(searchPath.c_str(), "r"); 84 if (tempFile) 85 { 86 fclose(tempFile); 87 result = searchPath; 88 return true; 89 } 90 } 91 92 // Couldn't find anything matching the base path. 93 return false; 94 } 95 96 bool PathSearcher::isAbsolute(const std::string & path) 97 { 98 #if __WIN32__ 99 return path.size() >= 3 && path[1] == ':' && path[2] == '\\'; 100 #else 101 return path.size() >= 1 && path[0] == '/'; 102 #endif 103 } 104 105 std::string PathSearcher::joinPaths(const std::string & first, const std::string & second) 106 { 107 // Start with first string. 108 std::string result = first; 109 110 // Add path separator if needed 111 if ((first[first.size() - 1] != PATH_SEP_CHAR) && (second[0] != PATH_SEP_CHAR)) 112 { 113 result += PATH_SEP_STRING; 114 } 115 116 // Append the second string. 117 result += second; 118 119 // And return the whole mess. 120 return result; 121 } 122