diff options
Diffstat (limited to 'Build/source/utils/asymptote/locate.cc')
-rw-r--r-- | Build/source/utils/asymptote/locate.cc | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/locate.cc b/Build/source/utils/asymptote/locate.cc new file mode 100644 index 00000000000..d1c11a1f270 --- /dev/null +++ b/Build/source/utils/asymptote/locate.cc @@ -0,0 +1,101 @@ +/***** + * locate.cc + * Tom Prince 2005/03/24 + * + * Locate files in search path. + *****/ + +#include <unistd.h> + +#include "settings.h" +#include "util.h" +#include "locate.h" + + + +namespace settings { + +namespace fs { + +string extension(string name) +{ + size_t n = name.rfind("."); + if (n != string::npos) + return name.substr(n); + else + return string(); +} + +bool exists(string filename) +{ + return ::access(filename.c_str(), R_OK) == 0; +} + +} // namespace fs + + +file_list_t searchPath; + +// Returns list of possible filenames, accounting for extensions. +file_list_t mungeFileName(string id, string suffix) +{ + string ext = fs::extension(id); + file_list_t files; + if (ext == "."+suffix) { + files.push_back(id); + files.push_back(id+"."+suffix); + } else { + files.push_back(id+"."+suffix); + files.push_back(id); + } + return files; +} + +// Join a directory with the given filename, to give the path to the file, +// avoiding unsightly joins such as 'dir//file.asy' in favour of 'dir/file.asy' +string join(string dir, string file, bool full) +{ + return dir == "." ? (full ? string(getPath())+"/"+file : file) : + *dir.rbegin() == '/' ? dir + file : + dir + "/" + file; +} + +// Find the appropriate file, first looking in the local directory, then the +// directory given in settings, and finally the global system directory. +string locateFile(string id, bool full, string suffix) +{ + if(id.empty()) return ""; + file_list_t filenames = mungeFileName(id,suffix); + for (file_list_t::iterator leaf = filenames.begin(); + leaf != filenames.end(); + ++leaf) { +#ifdef __MSDOS__ + size_t p; + while ((p=leaf->find('\\')) < string::npos) + (*leaf)[p]='/'; + if ((p=leaf->find(':')) < string::npos && p > 0) { + (*leaf)[p]='/'; + leaf->insert(0,"/cygdrive/"); + } +#endif + + if ((*leaf)[0] == '/') { + string file = *leaf; + if (fs::exists(file)) + return file; + } else { + for (file_list_t::iterator dir = searchPath.begin(); + dir != searchPath.end(); + ++dir) { + string file = join(*dir,*leaf,full); + if (fs::exists(file)) + return file; + } + } + } + return string(); +} + +} // namespace settings + + |