1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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 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,
// 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)
{
if(id.empty()) return "";
file_list_t filenames = mungeFileName(id);
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
|