X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=flower%2Ffile-path.cc;h=65cd517e5a07247fc798277631be1857601679e0;hb=97a0169312a260933246ab224e4f8b0969871dd5;hp=1ff0762a883d39fdc3041185edde8a4740354bf1;hpb=3c4bcc40606d67a5870e688cf88073f50513a7bb;p=lilypond.git diff --git a/flower/file-path.cc b/flower/file-path.cc index 1ff0762a88..65cd517e5a 100644 --- a/flower/file-path.cc +++ b/flower/file-path.cc @@ -1,244 +1,208 @@ /* - path.cc - manipulation of paths and filenames. -*/ + This file is part of LilyPond, the GNU music typesetter. -#include "config.h" -#include -#include -#include + Copyright (C) 1997--2015 Han-Wen Nienhuys + Jan Nieuwenhuizen -#if HAVE_SYS_STAT_H -#include -#endif + 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. -#ifdef __CYGWIN__ -#include + 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. -// URGURG -#include "../lily/include/scm-option.hh" -#endif + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see . +*/ #include "file-path.hh" +#include +#include -#ifndef PATHSEP -#define PATHSEP ':' +#include "config.hh" +#if HAVE_SYS_STAT_H +#include #endif -/* We don't have multiple roots, set this to '\0'? */ -#ifndef ROOTSEP -#define ROOTSEP ':' +#ifdef __CYGWIN__ +#include #endif -#ifndef DIRSEP -#define DIRSEP '/' -#endif +#include "file-name.hh" +#include "warn.hh" -#ifndef EXTSEP -#define EXTSEP '.' +#ifndef PATHSEP +#define PATHSEP ':' #endif +#include - -#ifdef __CYGWIN__ -static String -dos_to_posix (String path) +vector +File_path::directories () const { - char buf[PATH_MAX]; - char *filename = path.copy_ch_p (); - /* urg, wtf? char const* argument gets modified! */ - cygwin_conv_to_posix_path (filename, buf); - delete filename; - return buf; + return dirs_; } -static String -dos_to_posix_list (String path) +void +File_path::parse_path (const string &p) { - char *filename = path.copy_ch_p (); - int len = cygwin_win32_to_posix_path_list_buf_size (filename); - if (len < PATH_MAX) - len = PATH_MAX; - char *buf = new char[len]; - /* urg, wtf? char const* argument gets modified! */ - cygwin_win32_to_posix_path_list (filename, buf); - delete filename; - - String ret = buf; - delete buf; - return ret; + concat (dirs_, string_split (p, PATHSEP)); } -#endif /* __CYGWIN__ */ -/* Join components to full path. */ -String -Path::str () const +bool +is_file (const string &file_name) { - String s; - if (!root.empty_b ()) - s = root + to_str (ROOTSEP); - if (!dir.empty_b ()) - s += dir + to_str (DIRSEP); - s += base; - if (!ext.empty_b ()) - s += to_str (EXTSEP) + ext; - return s; -} +#if !STAT_MACROS_BROKEN + struct stat sbuf; + if (stat (file_name.c_str (), &sbuf) != 0) + return false; -/** - @param path the original full filename - @return 4 components of the path. They can be empty -*/ -Path -split_path (String path) -{ -#ifdef __CYGWIN__ - /* All system functions would work, even if we don't convert to - posix path, but we'd think that \foe\bar\baz.ly is in the cwd. - On by default. */ - if (!(testing_level_global & 1)) - path = dos_to_posix (path); + return !S_ISDIR (sbuf.st_mode); #endif - Path p; - int i = path.index_i (ROOTSEP); - if (i >= 0) - { - p.root = path.left_str (i); - path = path.right_str (path.length_i () - i - 1); - } - - i = path.index_last_i (DIRSEP); - if (i >= 0) + if (FILE *f = fopen (file_name.c_str (), "r")) { - p.dir = path.left_str (i); - path = path.right_str (path.length_i () - i - 1); + fclose (f); + return true; } - i = path.index_last_i ('.'); - if (i >= 0) - { - p.base = path.left_str (i); - p.ext = path.right_str (path.length_i () - i - 1); - } - else - p.base = path; - return p; + return false; } -void -File_path::parse_path (String p) +bool +is_dir (string file_name) { -#ifdef __CYGWIN__ - if (testing_level_global & 4) - p = dos_to_posix_list (p); + /* + canonicalize; in particular, trailing slashes should disappear. + */ + file_name = File_name (file_name).to_string (); + +#if !STAT_MACROS_BROKEN + struct stat sbuf; + if (stat (file_name.c_str (), &sbuf) != 0) + return false; + + return S_ISDIR (sbuf.st_mode); #endif - int l; - - while ((l = p.length_i ()) ) + if (FILE *f = fopen (file_name.c_str (), "r")) { - int i = p.index_i (PATHSEP); - if (i <0) - i = l; - add (p.left_str (i)); - p = p.right_str (l- i - 1); + fclose (f); + return true; } + return false; } +/** Find a file. +Check absolute file name, search in the current dir (DUH! FIXME!), +in the construction-arg (what's that?), and in any other appended +directory, in this order. +@return +The file name if found, or empty string if not found. */ -/** Find a file. - It will search in the current dir, in the construction-arg, and - in any other added path, in this order. - - @return - The full path if found, or empty string if not found - */ -String -File_path::find (String nm) const +string +File_path::find (const string &name) const { - if (!nm.length_i () || (nm == "-") ) - return nm; - for (int i=0; i < size (); i++) + if (!name.length () || (name == "-")) + return name; + +#ifdef __MINGW32__ + if (name.find ('\\') != NPOS) + programming_error ("file name not normalized: " + name); +#endif /* __MINGW32__ */ + + /* Handle absolute file name. */ + File_name file_name (name); + if (file_name.dir_[0] == DIRSEP && is_file (file_name.to_string ())) + return file_name.to_string (); + + for (vsize i = 0; i < dirs_.size (); i++) { - String path = elem (i); - String sep = to_str (DIRSEP); - String right (path.right_str (1)); - if (path.length_i () && right != sep) - path += to_str (DIRSEP); - - path += nm; - - -#if 0 - /* - Check if directory. TODO: encapsulate for autoconf - */ - struct stat sbuf; - if (stat (path.ch_C (), &sbuf) == ENOENT) - continue; - - if (! (sbuf.st_mode & __S_IFREG)) - continue; -#endif -#if !STAT_MACROS_BROKEN - struct stat sbuf; - if (stat (path.ch_C (), &sbuf) == ENOENT) - continue; - - if (S_ISDIR (sbuf.st_mode)) - continue; -#endif + File_name file_name (name); + File_name dir = (string) dirs_[i]; + file_name.root_ = dir.root_; + dir.root_ = ""; + if (file_name.dir_.empty ()) + file_name.dir_ = dir.to_string (); + else if (!dir.to_string ().empty ()) + file_name.dir_ = dir.to_string () + + ::to_string (DIRSEP) + file_name.dir_; + if (is_file (file_name.to_string ())) + return file_name.to_string (); + } + return ""; +} + +/* + Try to find + + file.EXT, + + where EXT is from EXTENSIONS. +*/ +string +File_path::find (const string &name, char const *extensions[]) +{ + if (name.empty () || name == "-") + return name; - FILE *f = fopen (path.ch_C (), "r"); // ugh! - if (f) - { - fclose (f); - return path; - } + File_name file_name (name); + string orig_ext = file_name.ext_; + for (int i = 0; extensions[i]; i++) + { + file_name.ext_ = orig_ext; + if (*extensions[i] && !file_name.ext_.empty ()) + file_name.ext_ += "."; + file_name.ext_ += extensions[i]; + string found = find (file_name.to_string ()); + if (!found.empty ()) + return found; } + return ""; } -/** - Add a directory, return false if failed - */ +/** Append a directory, return false if failed. */ bool -File_path::try_add (String s) +File_path::try_append (string s) { if (s == "") - s = "."; - FILE * f = fopen (s.ch_C (), "r"); - if (!f) - return false; - fclose (f); - - add (s); - return true; + s = "."; + if (is_dir (s)) + { + append (s); + return true; + } + return false; } -void -File_path::add (String s) +string +File_path::to_string () const { -#ifdef __CYGWIN__ - if (testing_level_global & 2) - s = dos_to_posix (s); -#endif + string s; + for (vsize i = 0; i < dirs_.size (); i++) + { + s = s + dirs_[i]; + if (i < dirs_.size () - 1) + s += ::to_string (PATHSEP); + } + return s; +} - push (s); +void +File_path::append (const string &str) +{ + dirs_.push_back (str); } -String -File_path::str () const +void +File_path::prepend (const string &str) { - String s; - for (int i=0; i< size (); i++) - { - s = s + elem (i); - if (i < size () -1 ) - s += ":"; - } - return s; + dirs_.insert (dirs_.begin (), str); }