]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
patch::: 1.3.147.jcn1
[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.copy_ch_p ();
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.copy_ch_p ();
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::str () const
76 {
77   String s;
78   if (!root.empty_b ())
79     s = root + to_str (ROOTSEP);
80   if (!dir.empty_b ())
81     s += dir + to_str (DIRSEP);
82   s += base;
83   if (!ext.empty_b ())
84     s += to_str (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   if (testing_level_global & 1)
99     path = dos_to_posix (path);
100 #endif
101
102   Path p;
103   int i = path.index_i (ROOTSEP);
104   if (i >= 0)
105     {
106       p.root = path.left_str (i);
107       path = path.right_str (path.length_i () - i - 1);
108     }
109
110   i = path.index_last_i (DIRSEP);
111   if (i >= 0)
112     {
113       p.dir = path.left_str (i);
114       path = path.right_str (path.length_i () - i - 1);
115     }
116
117   i = path.index_last_i ('.');
118   if (i >= 0)
119     {
120       p.base = path.left_str (i);
121       p.ext = path.right_str (path.length_i () - i - 1);
122     }
123   else
124     p.base = path;
125   return p;
126 }
127
128 void
129 File_path::parse_path (String p)
130 {
131 #ifdef __CYGWIN__
132   if (testing_level_global & 4)
133     p = dos_to_posix_list (p);
134 #endif
135
136   int l;
137   
138   while ((l = p.length_i ()) )
139     {
140       int i = p.index_i (PATHSEP);
141       if (i <0) 
142         i = l;
143       add (p.left_str (i));
144       p = p.right_str (l- i - 1);
145     }
146 }
147
148
149
150
151 /** Find a file.
152   It will search in the current dir, in the construction-arg, and
153   in any other added path, in this order.
154
155   @return
156   The full path if found, or empty string if not found
157   */
158 String
159 File_path::find (String nm) const
160 {
161   if (!nm.length_i () || (nm == "-") )
162     return nm;
163   for (int i=0; i < size (); i++)
164     {
165       String path  = elem (i);
166       String sep = to_str (DIRSEP);
167       String right (path.right_str (1));
168       if (path.length_i () && right != sep)
169         path += to_str (DIRSEP);
170
171       path += nm;
172
173
174 #if 0
175       /*
176         Check if directory. TODO: encapsulate for autoconf
177        */
178       struct stat sbuf;
179       if (stat (path.ch_C (), &sbuf) == ENOENT)
180         continue;
181       
182       if (! (sbuf.st_mode & __S_IFREG))
183         continue;
184 #endif
185 #if !STAT_MACROS_BROKEN
186       struct stat sbuf;
187       if (stat (path.ch_C (), &sbuf) == ENOENT)
188         continue;
189       
190       if (S_ISDIR (sbuf.st_mode))
191         continue;
192 #endif
193
194       FILE *f = fopen (path.ch_C (), "r"); // ugh!
195       if (f)
196         {
197           fclose (f);
198           return path;
199         }
200     }
201   return "";
202 }
203
204 /**
205    Add a directory, return false if failed
206  */
207 bool
208 File_path::try_add (String s)
209 {
210   if (s == "")
211     s =  ".";
212   FILE  * f = fopen (s.ch_C (), "r");
213   if (!f)
214     return false;
215   fclose (f);
216     
217   add (s);
218   return true;
219 }
220
221 void
222 File_path::add (String s)
223 {
224 #ifdef __CYGWIN__
225   if (testing_level_global & 2)
226     s = dos_to_posix (s);
227 #endif
228
229   push (s);
230 }
231
232 String
233 File_path::str () const
234 {
235   String s;
236   for (int i=0; i< size (); i++)
237     {
238       s = s + elem (i);
239       if (i < size () -1 )
240         s += ":";
241     }
242   return s;
243 }