]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
*** empty log message ***
[lilypond.git] / flower / file-path.cc
1 /*
2   file-path.cc - implement File_path
3
4   source file of the Flower Library
5
6   (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7   Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9
10 #include "file-path.hh"
11
12 #include "std-string.hh"
13
14 #include <cstdio>
15 #include <cerrno>
16
17 #include "config.hh"
18 #if HAVE_SYS_STAT_H
19 #include <sys/stat.h>
20 #endif
21
22 #ifdef __CYGWIN__
23 #include <sys/cygwin.h>
24 #endif
25
26 #include "file-name.hh"
27 #include "warn.hh"
28
29 #ifndef PATHSEP
30 #define PATHSEP ':'
31 #endif
32
33 vector<string>
34 File_path::directories () const
35 {
36   return dirs_;
37 }
38
39 #include <algorithm>
40 void
41 File_path::parse_path (string p)
42 {
43   concat (dirs_, string_split (p, PATHSEP));
44 }
45
46 bool
47 is_file (string file_name)
48 {
49 #if !STAT_MACROS_BROKEN
50   struct stat sbuf;
51   if (stat (file_name.c_str (), &sbuf) != 0)
52     return false;
53
54   return !S_ISDIR (sbuf.st_mode);
55 #endif
56
57   if (FILE *f = fopen (file_name.c_str (), "r"))
58     {
59       fclose (f);
60       return true;
61     }
62
63   return false;
64 }
65
66 bool
67 is_dir (string file_name)
68 {
69 #if !STAT_MACROS_BROKEN
70   struct stat sbuf;
71   if (stat (file_name.c_str (), &sbuf) != 0)
72     return false;
73
74   return S_ISDIR (sbuf.st_mode);
75 #endif
76
77   if (FILE *f = fopen (file_name.c_str (), "r"))
78     {
79       fclose (f);
80       return true;
81     }
82   return false;
83 }
84
85 /** Find a file.
86
87 Check absolute file name, search in the current dir (DUH! FIXME!),
88 in the construction-arg (what's that?), and in any other appended
89 directory, in this order.
90
91 @return
92 The file name if found, or empty string if not found. */
93
94 string
95 File_path::find (string name) const
96 {
97   if (!name.length () || (name == "-"))
98     return name;
99
100 #ifdef __MINGW32__
101   if (name.find ('\\') != NPOS)
102     programming_error ("file name not normalized: " + name);
103 #endif /* __MINGW32__ */
104
105   /* Handle absolute file name.  */
106   File_name file_name (name);
107   if (file_name.dir_[0] == DIRSEP && is_file (file_name.to_string ()))
108     return file_name.to_string ();
109
110   for (vsize i = 0; i < dirs_.size (); i++)
111     {
112       File_name file_name (name);
113       File_name dir = (string) dirs_[i];
114       file_name.root_ = dir.root_;
115       dir.root_ = "";
116       if (file_name.dir_.empty ())
117         file_name.dir_ = dir.to_string ();
118       else if (!dir.to_string ().empty ())
119         file_name.dir_ = dir.to_string ()
120           + ::to_string (DIRSEP) + file_name.dir_;
121       if (is_file (file_name.to_string ()))
122         return file_name.to_string ();
123     }
124   return "";
125 }
126
127 /*
128   Try to find
129
130   file.EXT,
131
132   where EXT is from EXTENSIONS.
133 */
134 string
135 File_path::find (string name, char const *extensions[])
136 {
137   if (name.empty () || name == "-")
138     return name;
139   
140   File_name file_name (name);
141   string orig_ext = file_name.ext_;
142   for (int i = 0; extensions[i]; i++)
143     {
144       file_name.ext_ = orig_ext;
145       if (*extensions[i] && !file_name.ext_.empty ())
146         file_name.ext_ += ".";
147       file_name.ext_ += extensions[i];
148       string found = find (file_name.to_string ());
149       if (!found.empty ())
150         return found;
151     }
152   
153   return "";
154 }
155
156 /** Append a directory, return false if failed.  */
157 bool
158 File_path::try_append (string s)
159 {
160   if (s == "")
161     s = ".";
162   if (is_dir (s))
163     {
164       append (s);
165       return true;
166     }
167   return false;
168 }
169
170 string
171 File_path::to_string () const
172 {
173   string s;
174   for (vsize i = 0; i < dirs_.size (); i++)
175     {
176       s = s + dirs_[i];
177       if (i < dirs_.size () - 1)
178         s += ::to_string (PATHSEP);
179     }
180   return s;
181 }
182
183 void
184 File_path::append (string str)
185 {
186   dirs_.push_back (str);
187 }
188
189 void
190 File_path::prepend (string str)
191 {
192   dirs_.insert (dirs_.begin (), str);
193 }