X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=flower%2Ffile-name.cc;h=1746c2c28d84adc5cbe8cd19f5e8d431dec10383;hb=ebd6d78b9320d286fd7c661e14f6013bbba0e0be;hp=7c93ee65ce6441313e65a336b3cb324e064a2e37;hpb=91e7cbaa6e54e004365d28e0f10c9362a7f13320;p=lilypond.git diff --git a/flower/file-name.cc b/flower/file-name.cc index 7c93ee65ce..1746c2c28d 100644 --- a/flower/file-name.cc +++ b/flower/file-name.cc @@ -1,20 +1,35 @@ /* - file-name.cc - implement File_name - - source file of the Flower Library - - (c) 1997--2005 Han-Wen Nienhuys - Jan Nieuwenhuizen + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 1997--2012 Han-Wen Nienhuys + Jan Nieuwenhuizen + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . */ #include "file-name.hh" #include #include +#include +#include + +using namespace std; #include "config.hh" -#if HAVE_SYS_STAT_H +#if HAVE_SYS_STAT_H #include #endif @@ -22,7 +37,6 @@ #include #endif -/* We don't have multiple roots, set this to '\0'? */ #ifndef ROOTSEP #define ROOTSEP ':' #endif @@ -36,68 +50,161 @@ #endif #ifdef __CYGWIN__ -static String -dos_to_posix (String file_name) +static string +dos_to_posix (const string &file_name) { - char buf[PATH_MAX]; - char *s = file_name.get_copy_str0 (); - /* urg, wtf? char const* argument gets modified! */ - cygwin_conv_to_posix_path (s, buf); - delete s; - return buf; + char buf[PATH_MAX] = ""; + char s[PATH_MAX] = {0}; + file_name.copy (s, PATH_MAX - 1); + /* ugh: char const* argument gets modified. */ + int fail = cygwin_conv_to_posix_path (s, buf); + if (!fail) + return buf; + return file_name; } #endif /* __CYGWIN__ */ +/** Use slash as directory separator. On Windows, they can pretty + much be exchanged. */ +#if 0 +static /* avoid warning */ +#endif +string +slashify (string file_name) +{ + replace_all (&file_name, '\\', '/'); + replace_all (&file_name, string ("//"), "/"); + return file_name; +} + +string +dir_name (const string &file_name) +{ + string s = file_name; + s = slashify (s); + ssize n = s.length (); + if (n && s[n - 1] == '/') + s[n - 1] = 0; + if (s.rfind ('/') != NPOS) + s = s.substr (0, s.rfind ('/')); + else + s = ""; + + return s; +} + +string +get_working_directory () +{ + char cwd[PATH_MAX]; + // getcwd returns NULL upon a failure, contents of cwd would be undefined! + return string (getcwd (cwd, PATH_MAX)); +} + /* Join components to full file_name. */ -String -File_name::to_string () const +string +File_name::dir_part () const { - String s; - if (!root_.is_empty ()) + string s; + if (!root_.empty ()) s = root_ + ::to_string (ROOTSEP); - if (!dir_.is_empty ()) - s += dir_ + ::to_string (DIRSEP); - s += base_; - if (!ext_.is_empty ()) + + if (!dir_.empty ()) + { + s += dir_; + } + + return s; +} + +string +File_name::file_part () const +{ + string s; + s = base_; + if (!ext_.empty ()) s += ::to_string (EXTSEP) + ext_; return s; } -char const* -File_name::to_str0 () const +string +File_name::to_string () const { - return to_string ().to_str0 (); + string d = dir_part (); + string f = file_part (); + + if (!f.empty () + && !dir_.empty ()) + { + d += ::to_string (DIRSEP); + } + + return d + f; } -File_name::File_name (String file_name) +File_name::File_name (string file_name) { #ifdef __CYGWIN__ - /* All system functions would work, even if we don't convert to - posix file_name, but we'd think that \foe\bar\baz.ly is in the cwd. - On by default. */ + /* All system functions would work, even if we do not convert to + posix file_name, but we would think that \foe\bar\baz.ly is in + the cwd. */ file_name = dos_to_posix (file_name); #endif +#ifdef __MINGW32__ + file_name = slashify (file_name); +#endif - int i = file_name.index (ROOTSEP); - if (i >= 0) + ssize i = file_name.find (ROOTSEP); + if (i != NPOS) { - root_ = file_name.left_string (i); - file_name = file_name.right_string (file_name.length () - i - 1); + root_ = file_name.substr (0, i); + file_name = file_name.substr (i + 1); } - i = file_name.index_last (DIRSEP); - if (i >= 0) + i = file_name.rfind (DIRSEP); + if (i != NPOS) { - dir_ = file_name.left_string (i); - file_name = file_name.right_string (file_name.length () - i - 1); + dir_ = file_name.substr (0, i); + file_name = file_name.substr (i + 1); } - i = file_name.index_last ('.'); - if (i >= 0) + i = file_name.rfind ('.'); + if (i != NPOS) { - base_ = file_name.left_string (i); - ext_ = file_name.right_string (file_name.length () - i - 1); + base_ = file_name.substr (0, i); + ext_ = file_name.substr (i + 1); } else base_ = file_name; } + +bool +File_name::is_absolute () const +{ + /* + Hmm. Is c:foo absolute? + */ + return (dir_.length () && dir_[0] == DIRSEP) || root_.length (); +} + +File_name +File_name::canonicalized () const +{ + File_name c = *this; + + replace_all (&c.dir_, string ("//"), string ("/")); + + vector components = string_split (c.dir_, '/'); + vector new_components; + + for (vsize i = 0; i < components.size (); i++) + { + if (components[i] == "..") + new_components.pop_back (); + else + new_components.push_back (components[i]); + } + + c.dir_ = string_join (new_components, "/"); + return c; +}