Use out/gen-emmentaler-scripts, not gen-emmentaler-scripts.py.
[lilypond.git] / flower / file-name.cc
blob0f0bb61270beee42468ec305e31fb0b4106e06fa
1 /*
2 file-name.cc - implement File_name
4 source file of the Flower Library
6 (c) 1997--2007 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>
16 using namespace std;
18 #include "config.hh"
20 #if HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
24 #ifdef __CYGWIN__
25 #include <sys/cygwin.h>
26 #endif
28 #ifndef ROOTSEP
29 #define ROOTSEP ':'
30 #endif
32 #ifndef DIRSEP
33 #define DIRSEP '/'
34 #endif
36 #ifndef EXTSEP
37 #define EXTSEP '.'
38 #endif
40 #ifdef __CYGWIN__
41 static string
42 dos_to_posix (string file_name)
44 char buf[PATH_MAX] = "";
45 char s[PATH_MAX] = {0};
46 file_name.copy (s, PATH_MAX - 1);
47 /* ugh: char const* argument gets modified. */
48 int fail = cygwin_conv_to_posix_path (s, buf);
49 if (!fail)
50 return buf;
51 return file_name;
53 #endif /* __CYGWIN__ */
55 /** Use slash as directory separator. On Windows, they can pretty
56 much be exchanged. */
57 #if 0
58 static /* avoid warning */
59 #endif
60 string
61 slashify (string file_name)
63 replace_all (file_name, '\\', '/');
64 replace_all (file_name, string ("//"), "/");
65 return file_name;
68 string
69 dir_name (string const file_name)
71 string s = file_name;
72 s = slashify (s);
73 ssize n = s.length ();
74 if (n && s[n - 1] == '/')
75 s[n - 1] = 0;
76 if (s.rfind ('/') != NPOS)
77 s = s.substr (0, s.rfind ('/'));
78 else
79 s = "";
81 return s;
84 string
85 get_working_directory ()
87 char cwd[PATH_MAX];
88 getcwd (cwd, PATH_MAX);
90 return string (cwd);
93 /* Join components to full file_name. */
94 string
95 File_name::dir_part () const
97 string s;
98 if (!root_.empty ())
99 s = root_ + ::to_string (ROOTSEP);
101 if (!dir_.empty ())
103 s += dir_;
106 return s;
110 string
111 File_name::file_part () const
113 string s;
114 s = base_;
115 if (!ext_.empty ())
116 s += ::to_string (EXTSEP) + ext_;
117 return s;
120 string
121 File_name::to_string () const
123 string d = dir_part ();
124 string f = file_part ();
126 if (!f.empty ()
127 && !dir_.empty())
129 d += ::to_string (DIRSEP);
132 return d + f;
135 File_name::File_name (string file_name)
137 #ifdef __CYGWIN__
138 /* All system functions would work, even if we do not convert to
139 posix file_name, but we would think that \foe\bar\baz.ly is in
140 the cwd. */
141 file_name = dos_to_posix (file_name);
142 #endif
143 #ifdef __MINGW32__
144 file_name = slashify (file_name);
145 #endif
147 ssize i = file_name.find (ROOTSEP);
148 if (i != NPOS)
150 root_ = file_name.substr (0, i);
151 file_name = file_name.substr (i + 1);
154 i = file_name.rfind (DIRSEP);
155 if (i != NPOS)
157 dir_ = file_name.substr (0, i);
158 file_name = file_name.substr (i + 1);
161 i = file_name.rfind ('.');
162 if (i != NPOS)
164 base_ = file_name.substr (0, i);
165 ext_ = file_name.substr (i + 1);
167 else
168 base_ = file_name;
171 bool
172 File_name::is_absolute () const
175 Hmm. Is c:foo absolute?
177 return (dir_.length () && dir_[0] == DIRSEP) || root_.length ();
182 File_name
183 File_name::canonicalized () const
185 File_name c = *this;
187 replace_all (c.dir_, string ("//"), string ("/"));
189 vector<string> components = string_split (c.dir_, '/');
190 vector<string> new_components;
192 for (vsize i = 0; i < components.size (); i++)
194 if (components[i] == "..")
195 new_components.pop_back ();
196 else
197 new_components.push_back (components[i]);
200 c.dir_ = string_join (new_components, "/");
201 return c;