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