lilypond-1.5.8
[lilypond.git] / flower / file-path.cc
blob1ff0762a883d39fdc3041185edde8a4740354bf1
1 /*
2 path.cc - manipulation of paths and filenames.
3 */
5 #include "config.h"
6 #include <stdio.h>
7 #include <errno.h>
8 #include <limits.h>
10 #if HAVE_SYS_STAT_H
11 #include <sys/stat.h>
12 #endif
14 #ifdef __CYGWIN__
15 #include <sys/cygwin.h>
17 // URGURG
18 #include "../lily/include/scm-option.hh"
19 #endif
21 #include "file-path.hh"
24 #ifndef PATHSEP
25 #define PATHSEP ':'
26 #endif
28 /* We don't have multiple roots, set this to '\0'? */
29 #ifndef ROOTSEP
30 #define ROOTSEP ':'
31 #endif
33 #ifndef DIRSEP
34 #define DIRSEP '/'
35 #endif
37 #ifndef EXTSEP
38 #define EXTSEP '.'
39 #endif
43 #ifdef __CYGWIN__
44 static String
45 dos_to_posix (String path)
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;
55 static String
56 dos_to_posix_list (String path)
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;
67 String ret = buf;
68 delete buf;
69 return ret;
71 #endif /* __CYGWIN__ */
73 /* Join components to full path. */
74 String
75 Path::str () const
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;
88 /**
89 @param path the original full filename
90 @return 4 components of the path. They can be empty
92 Path
93 split_path (String path)
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
103 Path p;
104 int i = path.index_i (ROOTSEP);
105 if (i >= 0)
107 p.root = path.left_str (i);
108 path = path.right_str (path.length_i () - i - 1);
111 i = path.index_last_i (DIRSEP);
112 if (i >= 0)
114 p.dir = path.left_str (i);
115 path = path.right_str (path.length_i () - i - 1);
118 i = path.index_last_i ('.');
119 if (i >= 0)
121 p.base = path.left_str (i);
122 p.ext = path.right_str (path.length_i () - i - 1);
124 else
125 p.base = path;
126 return p;
129 void
130 File_path::parse_path (String p)
132 #ifdef __CYGWIN__
133 if (testing_level_global & 4)
134 p = dos_to_posix_list (p);
135 #endif
137 int l;
139 while ((l = p.length_i ()) )
141 int i = p.index_i (PATHSEP);
142 if (i <0)
143 i = l;
144 add (p.left_str (i));
145 p = p.right_str (l- i - 1);
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.
156 @return
157 The full path if found, or empty string if not found
159 String
160 File_path::find (String nm) const
162 if (!nm.length_i () || (nm == "-") )
163 return nm;
164 for (int i=0; i < size (); i++)
166 String path = elem (i);
167 String sep = to_str (DIRSEP);
168 String right (path.right_str (1));
169 if (path.length_i () && right != sep)
170 path += to_str (DIRSEP);
172 path += nm;
175 #if 0
177 Check if directory. TODO: encapsulate for autoconf
179 struct stat sbuf;
180 if (stat (path.ch_C (), &sbuf) == ENOENT)
181 continue;
183 if (! (sbuf.st_mode & __S_IFREG))
184 continue;
185 #endif
186 #if !STAT_MACROS_BROKEN
187 struct stat sbuf;
188 if (stat (path.ch_C (), &sbuf) == ENOENT)
189 continue;
191 if (S_ISDIR (sbuf.st_mode))
192 continue;
193 #endif
195 FILE *f = fopen (path.ch_C (), "r"); // ugh!
196 if (f)
198 fclose (f);
199 return path;
202 return "";
206 Add a directory, return false if failed
208 bool
209 File_path::try_add (String s)
211 if (s == "")
212 s = ".";
213 FILE * f = fopen (s.ch_C (), "r");
214 if (!f)
215 return false;
216 fclose (f);
218 add (s);
219 return true;
222 void
223 File_path::add (String s)
225 #ifdef __CYGWIN__
226 if (testing_level_global & 2)
227 s = dos_to_posix (s);
228 #endif
230 push (s);
233 String
234 File_path::str () const
236 String s;
237 for (int i=0; i< size (); i++)
239 s = s + elem (i);
240 if (i < size () -1 )
241 s += ":";
243 return s;