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