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