]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
* lily/melisma-engraver.cc (try_music): use melisma_busy()
[lilypond.git] / flower / file-path.cc
1 /*
2    path.cc - manipulation of paths and filenames.
3 */
4
5 #include "config.h"
6 #include <stdio.h>
7 #include <errno.h>
8 #include <limits.h>
9
10 #if HAVE_SYS_STAT_H 
11 #include <sys/stat.h>
12 #endif
13
14 #ifdef __CYGWIN__
15 #include <sys/cygwin.h>
16
17 // URGURG
18 #include "../lily/include/scm-option.hh"
19 #endif
20
21 #include "file-path.hh"
22
23
24 #ifndef PATHSEP
25 #define PATHSEP ':'
26 #endif
27
28 /* We don't have multiple roots, set this to '\0'? */
29 #ifndef ROOTSEP
30 #define ROOTSEP ':'
31 #endif
32
33 #ifndef DIRSEP
34 #define DIRSEP '/'
35 #endif
36
37 #ifndef EXTSEP
38 #define EXTSEP '.'
39 #endif
40
41
42
43 #ifdef __CYGWIN__
44 static String
45 dos_to_posix (String path)
46 {
47   char buf[PATH_MAX];
48   char *filename = path.get_copy_str0 ();
49   /* urg, wtf? char const* argument gets modified! */
50   cygwin_conv_to_posix_path (filename, buf);
51   delete filename;
52   return buf;
53 }
54
55 static String
56 dos_to_posix_list (String path)
57 {
58   char *filename = path.get_copy_str0 ();
59   int len = cygwin_win32_to_posix_path_list_buf_size (filename);
60   if (len < PATH_MAX)
61     len = PATH_MAX;
62   char *buf = new char[len];
63   /* urg, wtf? char const* argument gets modified! */
64   cygwin_win32_to_posix_path_list (filename, buf);
65   delete filename;
66   
67   String ret = buf;
68   delete buf;
69   return ret;
70 }
71 #endif /* __CYGWIN__ */
72
73 /* Join components to full path. */
74 String
75 Path::to_string () const
76 {
77   String s;
78   if (!root.is_empty ())
79     s = root + ::to_string (ROOTSEP);
80   if (!dir.is_empty ())
81     s += dir + ::to_string (DIRSEP);
82   s += base;
83   if (!ext.is_empty ())
84     s += ::to_string (EXTSEP) + ext;
85   return s;
86 }
87
88 /**
89    @param path the original full filename
90    @return 4 components of the path. They can be empty
91 */
92 Path
93 split_path (String path)
94 {
95 #ifdef __CYGWIN__
96   /* All system functions would work, even if we don't convert to
97      posix path, but we'd think that \foe\bar\baz.ly is in the cwd.
98      On by default.  */
99   if (!(testing_level_global & 1))
100     path = dos_to_posix (path);
101 #endif
102
103   Path p;
104   int i = path.index (ROOTSEP);
105   if (i >= 0)
106     {
107       p.root = path.left_string (i);
108       path = path.right_string (path.length () - i - 1);
109     }
110
111   i = path.index_last (DIRSEP);
112   if (i >= 0)
113     {
114       p.dir = path.left_string (i);
115       path = path.right_string (path.length () - i - 1);
116     }
117
118   i = path.index_last ('.');
119   if (i >= 0)
120     {
121       p.base = path.left_string (i);
122       p.ext = path.right_string (path.length () - i - 1);
123     }
124   else
125     p.base = path;
126   return p;
127 }
128
129 void
130 File_path::parse_path (String p)
131 {
132 #ifdef __CYGWIN__
133   if (testing_level_global & 4)
134     p = dos_to_posix_list (p);
135 #endif
136
137   int l;
138   
139   while ((l = p.length ()) )
140     {
141       int i = p.index (PATHSEP);
142       if (i <0) 
143         i = l;
144       add (p.left_string (i));
145       p = p.right_string (l- i - 1);
146     }
147 }
148
149
150
151
152 /** Find a file.
153   It will search in the current dir, in the construction-arg, and
154   in any other added path, in this order.
155
156   @return
157   The full path if found, or empty string if not found
158   */
159 String
160 File_path::find (String nm) const
161 {
162   if (!nm.length () || (nm == "-") )
163     return nm;
164   for (int i=0; i < size (); i++)
165     {
166       String path  = elem (i);
167       String sep = ::to_string (DIRSEP);
168       String right (path.right_string (1));
169       if (path.length () && right != sep)
170         path += ::to_string (DIRSEP);
171
172       path += nm;
173
174
175 #if 0
176       /*
177         Check if directory. TODO: encapsulate for autoconf
178        */
179       struct stat sbuf;
180       if (stat (path.to_str0 (), &sbuf) != 0)
181         continue;
182       
183       if (! (sbuf.st_mode & __S_IFREG))
184         continue;
185 #endif
186 #if !STAT_MACROS_BROKEN
187       
188       struct stat sbuf;
189       if (stat (path.to_str0 (), &sbuf) != 0)
190         continue;
191
192       if (S_ISDIR (sbuf.st_mode))
193         continue;
194 #endif
195
196       FILE *f = fopen (path.to_str0 (), "r"); // ugh!
197       if (f)
198         {
199           fclose (f);
200           return path;
201         }
202     }
203   return "";
204 }
205
206 /**
207    Add a directory, return false if failed
208  */
209 bool
210 File_path::try_add (String s)
211 {
212   if (s == "")
213     s =  ".";
214   FILE  * f = fopen (s.to_str0 (), "r");
215   if (!f)
216     return false;
217   fclose (f);
218     
219   add (s);
220   return true;
221 }
222
223 void
224 File_path::add (String s)
225 {
226 #ifdef __CYGWIN__
227   if (testing_level_global & 2)
228     s = dos_to_posix (s);
229 #endif
230
231   push (s);
232 }
233
234 String
235 File_path::to_string () const
236 {
237   String s;
238   for (int i=0; i< size (); i++)
239     {
240       s = s + elem (i);
241       if (i < size () -1 )
242         s += ":";
243     }
244   return s;
245 }