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