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