2 file-name.cc - implement File_name
4 source file of the Flower Library
6 (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "file-name.hh"
26 #include <sys/cygwin.h>
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);
54 #endif /* __CYGWIN__ */
56 /** Use slash as directory separator. On Windows, they can pretty
59 static /* avoid warning */
62 slashify (string file_name)
64 replace_all (&file_name, '\\', '/');
65 replace_all (&file_name, string ("//"), "/");
70 dir_name (string const file_name)
74 ssize n = s.length ();
75 if (n && s[n - 1] == '/')
77 if (s.rfind ('/') != NPOS)
78 s = s.substr (0, s.rfind ('/'));
86 get_working_directory ()
89 getcwd (cwd, PATH_MAX);
94 /* Join components to full file_name. */
96 File_name::dir_part () const
100 s = root_ + ::to_string (ROOTSEP);
112 File_name::file_part () const
117 s += ::to_string (EXTSEP) + ext_;
122 File_name::to_string () const
124 string d = dir_part ();
125 string f = file_part ();
130 d += ::to_string (DIRSEP);
136 File_name::File_name (string file_name)
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
142 file_name = dos_to_posix (file_name);
145 file_name = slashify (file_name);
148 ssize i = file_name.find (ROOTSEP);
151 root_ = file_name.substr (0, i);
152 file_name = file_name.substr (i + 1);
155 i = file_name.rfind (DIRSEP);
158 dir_ = file_name.substr (0, i);
159 file_name = file_name.substr (i + 1);
162 i = file_name.rfind ('.');
165 base_ = file_name.substr (0, i);
166 ext_ = file_name.substr (i + 1);
173 File_name::is_absolute () const
176 Hmm. Is c:foo absolute?
178 return (dir_.length () && dir_[0] == DIRSEP) || root_.length ();
184 File_name::canonicalized () const
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 ();
198 new_components.push_back (components[i]);
201 c.dir_ = string_join (new_components, "/");