Nitpick: ly:spanner-bound grob name slur -> spanner.
[lilypond.git] / flower / file-name.cc
blob2d9f1454fbe6dfc0952e31287ecd4b39fd1e1268
1 /*
2 file-name.cc - implement File_name
4 source file of the Flower Library
6 (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
8 */
10 #include "file-name.hh"
12 #include <cstdio>
13 #include <cerrno>
14 #include <unistd.h>
15 #include <limits.h>
17 using namespace std;
19 #include "config.hh"
21 #if HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #endif
25 #ifdef __CYGWIN__
26 #include <sys/cygwin.h>
27 #endif
29 #ifndef ROOTSEP
30 #define ROOTSEP ':'
31 #endif
33 #ifndef DIRSEP
34 #define DIRSEP '/'
35 #endif
37 #ifndef EXTSEP
38 #define EXTSEP '.'
39 #endif
41 #ifdef __CYGWIN__
42 static string
43 dos_to_posix (string file_name)
45 char buf[PATH_MAX] = "";
46 char s[PATH_MAX] = {0};
47 file_name.copy (s, PATH_MAX - 1);
48 /* ugh: char const* argument gets modified. */
49 int fail = cygwin_conv_to_posix_path (s, buf);
50 if (!fail)
51 return buf;
52 return file_name;
54 #endif /* __CYGWIN__ */
56 /** Use slash as directory separator. On Windows, they can pretty
57 much be exchanged. */
58 #if 0
59 static /* avoid warning */
60 #endif
61 string
62 slashify (string file_name)
64 replace_all (&file_name, '\\', '/');
65 replace_all (&file_name, string ("//"), "/");
66 return file_name;
69 string
70 dir_name (string const file_name)
72 string s = file_name;
73 s = slashify (s);
74 ssize n = s.length ();
75 if (n && s[n - 1] == '/')
76 s[n - 1] = 0;
77 if (s.rfind ('/') != NPOS)
78 s = s.substr (0, s.rfind ('/'));
79 else
80 s = "";
82 return s;
85 string
86 get_working_directory ()
88 char cwd[PATH_MAX];
89 getcwd (cwd, PATH_MAX);
91 return string (cwd);
94 /* Join components to full file_name. */
95 string
96 File_name::dir_part () const
98 string s;
99 if (!root_.empty ())
100 s = root_ + ::to_string (ROOTSEP);
102 if (!dir_.empty ())
104 s += dir_;
107 return s;
111 string
112 File_name::file_part () const
114 string s;
115 s = base_;
116 if (!ext_.empty ())
117 s += ::to_string (EXTSEP) + ext_;
118 return s;
121 string
122 File_name::to_string () const
124 string d = dir_part ();
125 string f = file_part ();
127 if (!f.empty ()
128 && !dir_.empty())
130 d += ::to_string (DIRSEP);
133 return d + f;
136 File_name::File_name (string file_name)
138 #ifdef __CYGWIN__
139 /* All system functions would work, even if we do not convert to
140 posix file_name, but we would think that \foe\bar\baz.ly is in
141 the cwd. */
142 file_name = dos_to_posix (file_name);
143 #endif
144 #ifdef __MINGW32__
145 file_name = slashify (file_name);
146 #endif
148 ssize i = file_name.find (ROOTSEP);
149 if (i != NPOS)
151 root_ = file_name.substr (0, i);
152 file_name = file_name.substr (i + 1);
155 i = file_name.rfind (DIRSEP);
156 if (i != NPOS)
158 dir_ = file_name.substr (0, i);
159 file_name = file_name.substr (i + 1);
162 i = file_name.rfind ('.');
163 if (i != NPOS)
165 base_ = file_name.substr (0, i);
166 ext_ = file_name.substr (i + 1);
168 else
169 base_ = file_name;
172 bool
173 File_name::is_absolute () const
176 Hmm. Is c:foo absolute?
178 return (dir_.length () && dir_[0] == DIRSEP) || root_.length ();
183 File_name
184 File_name::canonicalized () const
186 File_name c = *this;
188 replace_all (&c.dir_, string ("//"), string ("/"));
190 vector<string> components = string_split (c.dir_, '/');
191 vector<string> new_components;
193 for (vsize i = 0; i < components.size (); i++)
195 if (components[i] == "..")
196 new_components.pop_back ();
197 else
198 new_components.push_back (components[i]);
201 c.dir_ = string_join (new_components, "/");
202 return c;