]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
patch::: 1.3.130.jcn5
[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
9 #if HAVE_SYS_STAT_H 
10 #include <sys/stat.h>
11 #endif
12
13 #include "file-path.hh"
14 #include "flower-debug.hh"
15
16 #ifndef PATHSEP
17 #define PATHSEP ':'
18 #endif
19
20 #ifndef ROOTSEP
21 #define ROOTSEP '/'
22 #endif
23
24 #ifndef DIRSEP
25 #define DIRSEP '/'
26 #endif
27
28 #ifndef EXTSEP
29 #define EXTSEP '.'
30 #endif
31
32 /* Join components to full path. */
33 String
34 Path::str () const
35 {
36   String s;
37   if (!root.empty_b ())
38     s = root + to_str (ROOTSEP);
39   if (!dir.empty_b ())
40     s += dir + to_str (DIRSEP);
41   s += base;
42   if (!ext.empty_b ())
43     s += to_str (EXTSEP) + ext;
44   return s;
45 }
46
47 /**
48    @param path the original full filename
49    @return 4 components of the path. They can be empty
50 */
51 Path
52 split_path (String path)
53 {
54   Path p;
55   int i = path.index_i (ROOTSEP);
56   if (i >= 0)
57     {
58       p.root = path.left_str (i);
59       path = path.right_str (path.length_i () - i); // - 1);
60     }
61
62   i = path.index_last_i (DIRSEP);
63   if (i >= 0)
64     {
65       p.dir = path.left_str (i);
66       path = path.right_str (path.length_i () - i - 1);
67     }
68
69   i = path.index_last_i ('.');
70   if (i >= 0)
71     {
72       p.base = path.left_str (i);
73       p.ext = path.right_str (path.length_i () - i - 1);
74     }
75   else
76     p.base = path;
77   return p;
78 }
79
80 void
81 File_path::parse_path (String p)
82 {
83   int l;
84   
85   while ( (l = p.length_i ()) )
86     {
87       int i = p.index_i(PATHSEP);
88       if (i <0) 
89         i = l;
90       add (p.left_str(i));
91       p = p.right_str (l- i - 1);
92     }
93 }
94
95
96
97
98 /** Find a file.
99   It will search in the current dir, in the construction-arg, and
100   in any other added path, in this order.
101
102   @return
103   The full path if found, or empty string if not found
104   */
105 String
106 File_path::find (String nm) const
107 {
108   DEBUG_OUT << "looking for" << nm << ": ";
109   if (!nm.length_i() || (nm == "-") )
110     return nm;
111   for (int i=0; i < size(); i++)
112     {
113       String path  = elem(i);
114       String sep = to_str (DIRSEP);
115       String right(path.right_str (1));
116       if (path.length_i () && right != sep)
117         path += to_str (DIRSEP);
118
119       path += nm;
120
121       DEBUG_OUT << path << "? ";
122
123 #if 0
124       /*
125         Check if directory. TODO: encapsulate for autoconf
126        */
127       struct stat sbuf;
128       if (stat (path.ch_C(), &sbuf) == ENOENT)
129         continue;
130       
131       if (!(sbuf.st_mode & __S_IFREG))
132         continue;
133 #endif
134 #if !STAT_MACROS_BROKEN
135       struct stat sbuf;
136       if (stat (path.ch_C (), &sbuf) == ENOENT)
137         continue;
138       
139       if (S_ISDIR (sbuf.st_mode))
140         continue;
141 #endif
142
143       FILE *f = fopen (path.ch_C(), "r"); // ugh!
144       if (f)
145         {
146           DEBUG_OUT << "found\n";
147           fclose (f);
148           return path;
149         }
150     }
151   DEBUG_OUT << '\n';
152   return "";
153 }
154
155 /**
156    Add a directory, return false if failed
157  */
158 bool
159 File_path::try_add (String s)
160 {
161   if (s == "")
162     s =  ".";
163   FILE  * f = fopen (s.ch_C(), "r");
164   if (!f)
165     return false;
166   fclose (f);
167     
168   push (s);
169   return true;
170 }
171
172 void
173 File_path::add (String s)
174 {
175   push (s);
176 }
177
178 String
179 File_path::str () const
180 {
181   String s;
182   for (int i=0; i< size (); i++)
183     {
184       s = s + elem (i);
185       if (i < size () -1 )
186         s += ":";
187     }
188   return s;
189 }