]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
release: 1.3.145
[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
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   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
122 #if 0
123       /*
124         Check if directory. TODO: encapsulate for autoconf
125        */
126       struct stat sbuf;
127       if (stat (path.ch_C (), &sbuf) == ENOENT)
128         continue;
129       
130       if (! (sbuf.st_mode & __S_IFREG))
131         continue;
132 #endif
133 #if !STAT_MACROS_BROKEN
134       struct stat sbuf;
135       if (stat (path.ch_C (), &sbuf) == ENOENT)
136         continue;
137       
138       if (S_ISDIR (sbuf.st_mode))
139         continue;
140 #endif
141
142       FILE *f = fopen (path.ch_C (), "r"); // ugh!
143       if (f)
144         {
145           fclose (f);
146           return path;
147         }
148     }
149   return "";
150 }
151
152 /**
153    Add a directory, return false if failed
154  */
155 bool
156 File_path::try_add (String s)
157 {
158   if (s == "")
159     s =  ".";
160   FILE  * f = fopen (s.ch_C (), "r");
161   if (!f)
162     return false;
163   fclose (f);
164     
165   push (s);
166   return true;
167 }
168
169 void
170 File_path::add (String s)
171 {
172   push (s);
173 }
174
175 String
176 File_path::str () const
177 {
178   String s;
179   for (int i=0; i< size (); i++)
180     {
181       s = s + elem (i);
182       if (i < size () -1 )
183         s += ":";
184     }
185   return s;
186 }