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