]> git.donarmstrong.com Git - lilypond.git/blobdiff - flower/file-path.cc
Imported sources
[lilypond.git] / flower / file-path.cc
index 3b76d4b1dd927aa5fa2aba58a87664249fad2b7e..c59d218cd1f2dce2f4f071cb647005bea0527d7d 100644 (file)
 /*
    path.cc - manipulation of paths and filenames.
 */
+
+#include "config.h"
 #include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+
+#if HAVE_SYS_STAT_H 
+#include <sys/stat.h>
+#endif
+
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+
+// URGURG
+#include "../lily/include/scm-option.hh"
+#endif
+
 #include "file-path.hh"
-#include "flower-debug.hh"
+
+
+#ifndef PATHSEP
+#define PATHSEP ':'
+#endif
+
+/* We don't have multiple roots, set this to '\0'? */
+#ifndef ROOTSEP
+#define ROOTSEP ':'
+#endif
 
 #ifndef DIRSEP
 #define DIRSEP '/'
 #endif
 
-#ifndef PATHSEP
-#define PATHSEP ':'
+#ifndef EXTSEP
+#define EXTSEP '.'
 #endif
 
+
+
+#ifdef __CYGWIN__
+static String
+dos_to_posix (String path)
+{
+  char buf[PATH_MAX];
+  char *filename = path.get_copy_str0 ();
+  /* urg, wtf? char const* argument gets modified! */
+  cygwin_conv_to_posix_path (filename, buf);
+  delete filename;
+  return buf;
+}
+
+static String
+dos_to_posix_list (String path)
+{
+  char *filename = path.get_copy_str0 ();
+  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;
+}
+#endif /* __CYGWIN__ */
+
+/* Join components to full path. */
+String
+Path::to_string () const
+{
+  String s;
+  if (!root.is_empty ())
+    s = root + ::to_string (ROOTSEP);
+  if (!dir.is_empty ())
+    s += dir + ::to_string (DIRSEP);
+  s += base;
+  if (!ext.is_empty ())
+    s += ::to_string (EXTSEP) + ext;
+  return s;
+}
+
 /**
    @param path the original full filename
    @return 4 components of the path. They can be empty
 */
-void
-split_path (String path,
-           String &drive, String &dirs, String &filebase, String &extension)
+Path
+split_path (String path)
 {
-  // peel off components, one by one.
-  int di = path.index_i (':');
-  if (di >= 0)
+#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);
+#endif
+
+  Path p;
+  int i = path.index (ROOTSEP);
+  if (i >= 0)
     {
-      drive = path.left_str (di + 1);
-      path = path.right_str (path.length_i () - di -1);
+      p.root = path.left_string (i);
+      path = path.right_string (path.length () - i - 1);
     }
-  else
-    drive = "";
 
-  di = path.index_last_i (DIRSEP);
-  if (di >=0)
+  i = path.index_last (DIRSEP);
+  if (i >= 0)
     {
-      dirs = path.left_str (di + 1);
-      path = path.right_str (path.length_i ()-di -1);
+      p.dir = path.left_string (i);
+      path = path.right_string (path.length () - i - 1);
     }
-  else
-    dirs = "";
 
-  di = path.index_last_i ('.');
-  if (di >= 0)
+  i = path.index_last ('.');
+  if (i >= 0)
     {
-      filebase = path.left_str (di);
-      extension =path.right_str (path.length_i ()-di);
+      p.base = path.left_string (i);
+      p.ext = path.right_string (path.length () - i - 1);
     }
   else
-    {
-      extension = "";
-      filebase = path;
-    }
+    p.base = path;
+  return p;
 }
 
 void
 File_path::parse_path (String p)
 {
+#ifdef __CYGWIN__
+  if (testing_level_global & 4)
+    p = dos_to_posix_list (p);
+#endif
+
   int l;
   
-  while ( (l = p.length_i ()) )
+  while ((l = p.length ()) )
     {
-      int i = p.index_i(PATHSEP);
+      int i = p.index (PATHSEP);
       if (i <0) 
        i = l;
-      add (p.left_str(i));
-      p = p.right_str (l- i - 1);
+      add (p.left_string (i));
+      p = p.right_string (l- i - 1);
     }
 }
 
 
 
 
-/** find a file.
+/** Find a file.
   It will search in the current dir, in the construction-arg, and
   in any other added path, in this order.
 
@@ -81,34 +159,87 @@ File_path::parse_path (String p)
 String
 File_path::find (String nm) const
 {
-  fdebug << "looking for" << nm << ": ";
-  if (!nm.length_i() || (nm == "-") )
+  if (!nm.length () || (nm == "-") )
     return nm;
-  for (int i=0; i < size(); i++)
+  for (int i=0; i < 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);
+      String path  = elem (i);
+      String sep = ::to_string (DIRSEP);
+      String right (path.right_string (1));
+      if (path.length () && right != sep)
+       path += ::to_string (DIRSEP);
 
       path += nm;
 
-      fdebug << path << "? ";
-      FILE *f = fopen (path.ch_C(), "r"); // ugh!
+
+#if 0
+      /*
+       Check if directory. TODO: encapsulate for autoconf
+       */
+      struct stat sbuf;
+      if (stat (path.to_str0 (), &sbuf) != 0)
+       continue;
+      
+      if (! (sbuf.st_mode & __S_IFREG))
+       continue;
+#endif
+#if !STAT_MACROS_BROKEN
+      
+      struct stat sbuf;
+      if (stat (path.to_str0 (), &sbuf) != 0)
+       continue;
+
+      if (S_ISDIR (sbuf.st_mode))
+       continue;
+#endif
+
+      FILE *f = fopen (path.to_str0 (), "r"); // ugh!
       if (f)
        {
-         fdebug << "found\n";
          fclose (f);
          return path;
        }
     }
-  fdebug << '\n';
   return "";
 }
 
+/**
+   Add a directory, return false if failed
+ */
+bool
+File_path::try_add (String s)
+{
+  if (s == "")
+    s =  ".";
+  FILE  * f = fopen (s.to_str0 (), "r");
+  if (!f)
+    return false;
+  fclose (f);
+    
+  add (s);
+  return true;
+}
+
 void
 File_path::add (String s)
 {
-   push (s); 
+#ifdef __CYGWIN__
+  if (testing_level_global & 2)
+    s = dos_to_posix (s);
+#endif
+
+  push (s);
+}
+
+String
+File_path::to_string () const
+{
+  String s;
+  for (int i=0; i< size (); i++)
+    {
+      s = s + elem (i);
+      if (i < size () -1 )
+       s += ":";
+    }
+  return s;
 }