]> git.donarmstrong.com Git - lilypond.git/blob - flower/file-path.cc
* lily/font-config.cc (init_fontconfig): add
[lilypond.git] / flower / file-path.cc
1 /*
2   file-path.cc - implement File_path
3    
4   source file of the Flower Library
5   
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7                  Jan Nieuwenhuizen <janneke@gnu.org>
8 */
9
10 #include "file-path.hh"
11
12 #include <cstdio>
13 #include <cerrno>
14
15 #include "config.hh"
16 #if HAVE_SYS_STAT_H 
17 #include <sys/stat.h>
18 #endif
19
20 #ifdef __CYGWIN__
21 #include <sys/cygwin.h>
22 #endif
23
24 #include "file-name.hh"
25
26 #ifndef PATHSEP
27 #define PATHSEP ':'
28 #endif
29
30 Array<String>
31 File_path::paths () const
32 {
33   return *this;
34 }
35
36 void
37 File_path::parse_path (String p)
38 {
39   int len;
40   while ((len = p.length ()) )
41     {
42       int i = p.index (PATHSEP);
43       if (i <0) 
44         i = len;
45       append (p.left_string (i));
46       p = p.right_string (len - i - 1);
47     }
48 }
49
50 /** Find a file.
51     
52   Check absolute file name, search in the current dir (DUH! FIXME!),
53   in the construction-arg (what's that?), and in any other appended
54   directory, in this order.
55
56   @return
57   The file name if found, or empty string if not found. */
58
59 String
60 File_path::find (String name) const
61 {
62   if (!name.length () || (name == "-") )
63     return name;
64
65   /* Handle absolute file name.  */
66   if (name[0] == DIRSEP)
67     {
68       if (FILE *f = fopen (name.to_str0 (), "r"))
69         {
70           fclose (f);
71           return name;
72         }
73     }
74        
75   for (int i = 0; i < size (); i++)
76     {
77       String file_name = elem (i);
78       String sep = ::to_string (DIRSEP);
79       String right (file_name.right_string (1));
80       if (file_name.length () && right != sep)
81         file_name += ::to_string (DIRSEP);
82
83       file_name += name;
84
85 #if 0 /* Check if directory. TODO: encapsulate for autoconf */
86       struct stat sbuf;
87       if (stat (file_name.to_str0 (), &sbuf) != 0)
88         continue;
89       
90       if (! (sbuf.st_mode & __S_IFREG))
91         continue;
92 #endif
93 #if !STAT_MACROS_BROKEN
94       
95       struct stat sbuf;
96       if (stat (file_name.to_str0 (), &sbuf) != 0)
97         continue;
98
99       if (S_ISDIR (sbuf.st_mode))
100         continue;
101 #endif
102
103       /* ugh */
104       FILE *f = fopen (file_name.to_str0 (), "r");
105       if (f)
106         {
107           fclose (f);
108           return file_name;
109         }
110     }
111   return "";
112 }
113
114 /** Find a file.
115     
116   Seach in the current dir (DUH! FIXME?), in the construction-arg
117   (what's that?, and in any other appended directory, in this order.
118
119   Search for NAME, or name without extension, or name with any of
120   EXTENSIONS, in that order.
121
122   @return
123   The file name if found, or empty string if not found. */
124 String
125 File_path::find (String name, char const *extensions[])
126 {
127   File_name file_name (name);
128   if (name.is_empty () || name == "-")
129     file_name.base_ = "-";
130   else
131     {
132       String orig_ext = file_name.ext_;
133       for (int i = 0; extensions[i]; i++)
134         {
135           file_name.ext_ = orig_ext;
136           if (*extensions[i] && !file_name.ext_.is_empty ())
137             file_name.ext_ += ".";
138           file_name.ext_ += extensions[i];
139           if (!find (file_name.to_string ()).is_empty ())
140             break;
141         }
142       /* Reshuffle extension */
143       file_name = File_name (file_name.to_string ());
144     }
145   return file_name.to_string ();
146 }
147
148 /** Append a directory, return false if failed.  */
149 bool
150 File_path::try_append (String s)
151 {
152   if (s == "")
153     s =  ".";
154   if (FILE *f = fopen (s.to_str0 (), "r"))
155     {
156       fclose (f);
157       append (s);
158       return true;
159     }
160   return false;
161 }
162
163 String
164 File_path::to_string () const
165 {
166   String s;
167   int n = size ();
168   for (int i = 0; i < n; i++)
169     {
170       s = s + elem (i);
171       if (i < n - 1)
172         s += ":";
173     }
174   return s;
175 }