summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/locate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/locate.cc')
-rw-r--r--Build/source/utils/asymptote/locate.cc101
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
+
+