diff options
Diffstat (limited to 'Build/source/utils/asymptote/locate.cc')
-rw-r--r-- | Build/source/utils/asymptote/locate.cc | 102 |
1 files changed, 102 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..98e2ff79ff4 --- /dev/null +++ b/Build/source/utils/asymptote/locate.cc @@ -0,0 +1,102 @@ +/***** + * 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 ext = fs::extension(id); + file_list_t files; + if (ext == "."+settings::suffix) { + files.push_back(id); + files.push_back(id+"."+settings::suffix); + } else { + files.push_back(id+"."+settings::suffix); + files.push_back(id); + } + return files; +} + +// Join a directory with the given filename, to give the path to the file. This +// also avoids unsightly joins such as './file.asy' in favour of 'file.asy' and +// 'dir//file.asy' in favour of 'dir/file.asy' +string join(string dir, string file) +{ + return dir == "." ? 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) +{ + if(id.empty()) return ""; + file_list_t filenames = mungeFileName(id); + for (file_list_t::iterator leaf = filenames.begin(); + leaf != filenames.end(); + ++leaf) { +#ifdef __CYGWIN__ + 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); + if (fs::exists(file)) + return file; + } + } + } + return string(); +} + +} // namespace settings + + |