]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
* scripts/lilypond-invoke-editor.scm (dissect-uri): Handle URIs
[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     programming_error ("file name not normalized: " + name);
117 #endif /* __MINGW32__ */
118
119   /* Handle absolute file name.  */
120   File_name file_name (name);
121   if (file_name.dir_[0] == DIRSEP && is_file (file_name.to_string ()))
122     return file_name.to_string ();
123
124   for (int i = 0, n = size (); i < n; i++)
125     {
126       File_name dir = elem (i);
127       file_name.root_ = dir.root_;
128       dir.root_ = "";
129       file_name.dir_ = dir.to_string ();
130       if (is_file (file_name.to_string ()))
131         return file_name.to_string ();
132     }
133   return "";
134 }
135
136 /** Find a file.
137
138 Seach in the current dir (DUH! FIXME?), in the construction-arg
139 (what's that?, and in any other appended directory, in this order.
140
141 Search for NAME, or name without extension, or name with any of
142 EXTENSIONS, in that order.
143
144 @return
145 The file name if found, or empty string if not found. */
146 String
147 File_path::find (String name, char const *extensions[])
148 {
149   File_name file_name (name);
150   if (name.is_empty () || name == "-")
151     file_name.base_ = "-";
152   else
153     {
154       String orig_ext = file_name.ext_;
155       for (int i = 0; extensions[i]; i++)
156         {
157           file_name.ext_ = orig_ext;
158           if (*extensions[i] && !file_name.ext_.is_empty ())
159             file_name.ext_ += ".";
160           file_name.ext_ += extensions[i];
161           if (!find (file_name.to_string ()).is_empty ())
162             break;
163         }
164       /* Reshuffle extension */
165       file_name = File_name (file_name.to_string ());
166     }
167   return file_name.to_string ();
168 }
169
170 /** Append a directory, return false if failed.  */
171 bool
172 File_path::try_append (String s)
173 {
174   if (s == "")
175     s = ".";
176   if (is_dir (s))
177     {
178       append (s);
179       return true;
180     }
181   return false;
182 }
183
184 String
185 File_path::to_string () const
186 {
187   String s;
188   for (int i = 0, n = size (); i < n; i++)
189     {
190       s = s + elem (i);
191       if (i < n - 1)
192         s += ::to_string (PATHSEP);
193     }
194   return s;
195 }