]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filefn.cpp
fixing pattern phase bugs
[wxWidgets.git] / src / common / filefn.cpp
index 3707d0a32713681741d26356e45f77263b1413dc..8a8b921abf5ad0d2461b3a9fe855cb22474c9dff 100644 (file)
     #pragma hdrstop
 #endif
 
+#include "wx/filefn.h"
+
 #ifndef WX_PRECOMP
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/utils.h"
 #endif
 
-#include "wx/file.h" // This does include filefn.h
+#include "wx/file.h"
 #include "wx/filename.h"
 #include "wx/dir.h"
 
@@ -115,13 +117,17 @@ const int wxInvalidOffset = -1;
 // macros
 // ----------------------------------------------------------------------------
 
-// we need to translate Mac filenames before passing them to OS functions
+// translate the filenames before passing them to OS functions
 #define OS_FILENAME(s) (s.fn_str())
 
 // ============================================================================
 // implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// wrappers around standard POSIX functions
+// ----------------------------------------------------------------------------
+
 #ifdef wxNEED_WX_UNISTD_H
 
 WXDLLEXPORT int wxStat( const wxChar *file_name, wxStructStat *buf )
@@ -129,6 +135,11 @@ WXDLLEXPORT int wxStat( const wxChar *file_name, wxStructStat *buf )
     return stat( wxConvFile.cWX2MB( file_name ), buf );
 }
 
+WXDLLEXPORT int wxLstat( const wxChar *file_name, wxStructStat *buf )
+{
+    return lstat( wxConvFile.cWX2MB( file_name ), buf );
+}
+
 WXDLLEXPORT int wxAccess( const wxChar *pathname, int mode )
 {
     return access( wxConvFile.cWX2MB( pathname ), mode );
@@ -139,22 +150,31 @@ WXDLLEXPORT int wxOpen( const wxChar *pathname, int flags, mode_t mode )
     return open( wxConvFile.cWX2MB( pathname ), flags, mode );
 }
 
-#endif
-   // wxNEED_WX_UNISTD_H
+#endif // wxNEED_WX_UNISTD_H
 
 // ----------------------------------------------------------------------------
 // wxPathList
 // ----------------------------------------------------------------------------
 
-void wxPathList::Add (const wxString& path)
+bool wxPathList::Add(const wxString& path)
 {
-    // add only the path part of the given string (not the filename, in case it's present)
+    // add a path separator to force wxFileName to interpret it always as a directory
+    // (i.e. if we are called with '/home/user' we want to consider it a folder and
+    // not, as wxFileName would consider, a filename).
     wxFileName fn(path + wxFileName::GetPathSeparator());
-    fn.Normalize();     // add only normalized paths
+
+    // add only normalized relative/absolute paths
+    // NB: we won't do wxPATH_NORM_DOTS in order to avoid problems when trying to
+    //     normalize paths which starts with ".." (which can be normalized only if
+    //     we use also wxPATH_NORM_ABSOLUTE - which we don't want to use).
+    if (!fn.Normalize(wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS))
+        return false;
 
     wxString toadd = fn.GetPath();
     if (Index(toadd) == wxNOT_FOUND)
         wxArrayString::Add(toadd);      // do not add duplicates
+
+    return true;
 }
 
 void wxPathList::Add(const wxArrayString &arr)
@@ -193,30 +213,36 @@ void wxPathList::AddEnvList (const wxString& WXUNUSED_IN_WINCE(envVariable))
 // Given a full filename (with path), ensure that that file can
 // be accessed again USING FILENAME ONLY by adding the path
 // to the list if not already there.
-void wxPathList::EnsureFileAccessible (const wxString& path)
+bool wxPathList::EnsureFileAccessible (const wxString& path)
 {
-    wxString path_only(wxPathOnly(path));
-    if ( !path_only.empty() )
-    {
-        if ( Index(path_only) == wxNOT_FOUND )
-            Add(path_only);
-    }
+    return Add(wxPathOnly(path));
 }
 
-// deprecated !
+#if WXWIN_COMPATIBILITY_2_6
 bool wxPathList::Member (const wxString& path) const
 {
     return Index(path) != wxNOT_FOUND;
 }
+#endif
 
 wxString wxPathList::FindValidPath (const wxString& file) const
 {
+    // normalize the given string as it could be a path + a filename
+    // and not only a filename
     wxFileName fn(file);
     wxString strend;
 
-    fn.Normalize();
+    // NB: normalize without making absolute otherwise calling this function with
+    //     e.g. "b/c.txt" would result in removing the directory 'b' and the for loop
+    //     below would only add to the paths of this list the 'c.txt' part when doing
+    //     the existence checks...
+    // NB: we don't use wxPATH_NORM_DOTS here, too (see wxPathList::Add for more info)
+    if (!fn.Normalize(wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS))
+        return wxEmptyString;
+
+    wxASSERT_MSG(!fn.IsDir(), wxT("Cannot search for directories; only for files"));
     if (fn.IsAbsolute())
-        strend = fn.GetFullName();
+        strend = fn.GetFullName();      // search for the file name and ignore the path part
     else
         strend = fn.GetFullPath();
 
@@ -898,6 +924,8 @@ wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname )
     return wxMacCFStringHolder(cfMutableString).AsString() ;
 }
 
+#ifndef __LP64__
+
 wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
 {
     FSRef fsRef ;
@@ -915,6 +943,7 @@ void wxMacFilename2FSSpec( const wxString& path , FSSpec *spec )
     wxMacPathToFSRef( path , &fsRef ) ;
     err = FSRefMakeFSSpec( &fsRef , spec ) ;
 }
+#endif
 
 #endif // __WXMAC__
 
@@ -1220,7 +1249,7 @@ bool wxDirExists(const wxChar *pszPathName)
 #if defined(__WINDOWS__) || defined(__OS2__)
     // Windows fails to find directory named "c:\dir\" even if "c:\dir" exists,
     // so remove all trailing backslashes from the path - but don't do this for
-    // the pathes "d:\" (which are different from "d:") nor for just "\"
+    // the paths "d:\" (which are different from "d:") nor for just "\"
     while ( wxEndsWithPathSeparator(strPath) )
     {
         size_t len = strPath.length();
@@ -1268,9 +1297,8 @@ bool wxDirExists(const wxChar *pszPathName)
 // Get a temporary filename, opening and closing the file.
 wxChar *wxGetTempFileName(const wxString& prefix, wxChar *buf)
 {
-#if wxUSE_FILE
-    wxString filename = wxFileName::CreateTempFileName(prefix);
-    if ( filename.empty() )
+    wxString filename;
+    if ( !wxGetTempFileName(prefix, filename) )
         return NULL;
 
     if ( buf )
@@ -1279,19 +1307,20 @@ wxChar *wxGetTempFileName(const wxString& prefix, wxChar *buf)
         buf = MYcopystring(filename);
 
     return buf;
-#else
-    wxUnusedVar(prefix);
-    wxUnusedVar(buf);
-    // wxFileName::CreateTempFileName needs wxFile class enabled
-    return NULL;
-#endif
 }
 
 bool wxGetTempFileName(const wxString& prefix, wxString& buf)
 {
-    buf = wxGetTempFileName(prefix);
+#if wxUSE_FILE
+    buf = wxFileName::CreateTempFileName(prefix);
 
     return !buf.empty();
+#else // !wxUSE_FILE
+    wxUnusedVar(prefix);
+    wxUnusedVar(buf);
+
+    return false;
+#endif // wxUSE_FILE/!wxUSE_FILE
 }
 
 // Get first file name matching given wild card.
@@ -1391,7 +1420,7 @@ wxChar *wxDoGetCwd(wxChar *buf, int sz)
 
     #ifdef HAVE_WGETCWD
         #if wxUSE_UNICODE_MSLU
-            if ( wxGetOsVersion() != wxWIN95 )
+            if ( wxGetOsVersion() != wxOS_WINDOWS_9X )
         #else
             char *cbuf = NULL; // never really used because needsANSI will always be false
         #endif
@@ -1750,6 +1779,152 @@ int WXDLLEXPORT wxParseCommonDialogsFilter(const wxString& filterStr,
     return filters.GetCount();
 }
 
+#if defined(__WINDOWS__) && !(defined(__UNIX__) || defined(__OS2__))
+static bool wxCheckWin32Permission(const wxString& path, DWORD access)
+{
+    // quoting the MSDN: "To obtain a handle to a directory, call the
+    // CreateFile function with the FILE_FLAG_BACKUP_SEMANTICS flag", but this
+    // doesn't work under Win9x/ME but then it's not needed there anyhow
+    bool isdir = wxDirExists(path);
+    if ( isdir && wxGetOsVersion() == wxOS_WINDOWS_9X )
+    {
+        // FAT directories always allow all access, even if they have the
+        // readonly flag set
+        return true;
+    }
+
+    HANDLE h = ::CreateFile
+                 (
+                    path.c_str(),
+                    access,
+                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                    NULL,
+                    OPEN_EXISTING,
+                    isdir ? FILE_FLAG_BACKUP_SEMANTICS : 0,
+                    NULL
+                 );
+    if ( h != INVALID_HANDLE_VALUE )
+        CloseHandle(h);
+
+    return h != INVALID_HANDLE_VALUE;
+}
+#endif // __WINDOWS__
+
+bool wxIsWritable(const wxString &path)
+{
+#if defined( __UNIX__ ) || defined(__OS2__)
+    // access() will take in count also symbolic links
+    return access(wxConvFile.cWX2MB(path), W_OK) == 0;
+#elif defined( __WINDOWS__ )
+    return wxCheckWin32Permission(path, GENERIC_WRITE);
+#else
+    wxUnusedVar(path);
+    // TODO
+    return false;
+#endif
+}
+
+bool wxIsReadable(const wxString &path)
+{
+#if defined( __UNIX__ ) || defined(__OS2__)
+    // access() will take in count also symbolic links
+    return access(wxConvFile.cWX2MB(path), R_OK) == 0;
+#elif defined( __WINDOWS__ )
+    return wxCheckWin32Permission(path, GENERIC_READ);
+#else
+    wxUnusedVar(path);
+    // TODO
+    return false;
+#endif
+}
+
+bool wxIsExecutable(const wxString &path)
+{
+#if defined( __UNIX__ ) || defined(__OS2__)
+    // access() will take in count also symbolic links
+    return access(wxConvFile.cWX2MB(path), X_OK) == 0;
+#elif defined( __WINDOWS__ )
+   return wxCheckWin32Permission(path, GENERIC_EXECUTE);
+#else
+    wxUnusedVar(path);
+    // TODO
+    return false;
+#endif
+}
+
+// Return the type of an open file
+//
+// Some file types on some platforms seem seekable but in fact are not.
+// The main use of this function is to allow such cases to be detected
+// (IsSeekable() is implemented as wxGetFileKind() == wxFILE_KIND_DISK).
+//
+// This is important for the archive streams, which benefit greatly from
+// being able to seek on a stream, but which will produce corrupt archives
+// if they unknowingly seek on a non-seekable stream.
+//
+// wxFILE_KIND_DISK is a good catch all return value, since other values
+// disable features of the archive streams. Some other value must be returned
+// for a file type that appears seekable but isn't.
+//
+// Known examples:
+//   *  Pipes on Windows
+//   *  Files on VMS with a record format other than StreamLF
+//
+wxFileKind wxGetFileKind(int fd)
+{
+#if defined __WXMSW__ && !defined __WXWINCE__ && defined wxGetOSFHandle
+    switch (::GetFileType(wxGetOSFHandle(fd)) & ~FILE_TYPE_REMOTE)
+    {
+        case FILE_TYPE_CHAR:
+            return wxFILE_KIND_TERMINAL;
+        case FILE_TYPE_DISK:
+            return wxFILE_KIND_DISK;
+        case FILE_TYPE_PIPE:
+            return wxFILE_KIND_PIPE;
+    }
+
+    return wxFILE_KIND_UNKNOWN;
+
+#elif defined(__UNIX__)
+    if (isatty(fd))
+        return wxFILE_KIND_TERMINAL;
+
+    struct stat st;
+    fstat(fd, &st);
+
+    if (S_ISFIFO(st.st_mode))
+        return wxFILE_KIND_PIPE;
+    if (!S_ISREG(st.st_mode))
+        return wxFILE_KIND_UNKNOWN;
+
+    #if defined(__VMS__)
+        if (st.st_fab_rfm != FAB$C_STMLF)
+            return wxFILE_KIND_UNKNOWN;
+    #endif
+
+    return wxFILE_KIND_DISK;
+
+#else
+    #define wxFILEKIND_STUB
+    (void)fd;
+    return wxFILE_KIND_DISK;
+#endif
+}
+
+wxFileKind wxGetFileKind(FILE *fp)
+{
+    // Note: The watcom rtl dll doesn't have fileno (the static lib does).
+    //       Should be fixed in version 1.4.
+#if defined(wxFILEKIND_STUB) || wxONLY_WATCOM_EARLIER_THAN(1,4)
+    (void)fp;
+    return wxFILE_KIND_DISK;
+#elif defined(__WINDOWS__) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
+    return fp ? wxGetFileKind(_fileno(fp)) : wxFILE_KIND_UNKNOWN;
+#else
+    return fp ? wxGetFileKind(fileno(fp)) : wxFILE_KIND_UNKNOWN;
+#endif
+}
+
 
 //------------------------------------------------------------------------
 // wild character routines
@@ -1882,77 +2057,6 @@ bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
     }
 }
 
-// Return the type of an open file
-//
-// Some file types on some platforms seem seekable but in fact are not.
-// The main use of this function is to allow such cases to be detected
-// (IsSeekable() is implemented as wxGetFileKind() == wxFILE_KIND_DISK).
-//
-// This is important for the archive streams, which benefit greatly from
-// being able to seek on a stream, but which will produce corrupt archives
-// if they unknowingly seek on a non-seekable stream.
-//
-// wxFILE_KIND_DISK is a good catch all return value, since other values
-// disable features of the archive streams. Some other value must be returned
-// for a file type that appears seekable but isn't.
-//
-// Known examples:
-//   *  Pipes on Windows
-//   *  Files on VMS with a record format other than StreamLF
-//
-wxFileKind wxGetFileKind(int fd)
-{
-#if defined __WXMSW__ && !defined __WXWINCE__ && defined wxGetOSFHandle
-    switch (::GetFileType(wxGetOSFHandle(fd)) & ~FILE_TYPE_REMOTE)
-    {
-        case FILE_TYPE_CHAR:
-            return wxFILE_KIND_TERMINAL;
-        case FILE_TYPE_DISK:
-            return wxFILE_KIND_DISK;
-        case FILE_TYPE_PIPE:
-            return wxFILE_KIND_PIPE;
-    }
-
-    return wxFILE_KIND_UNKNOWN;
-
-#elif defined(__UNIX__)
-    if (isatty(fd))
-        return wxFILE_KIND_TERMINAL;
-
-    struct stat st;
-    fstat(fd, &st);
-
-    if (S_ISFIFO(st.st_mode))
-        return wxFILE_KIND_PIPE;
-    if (!S_ISREG(st.st_mode))
-        return wxFILE_KIND_UNKNOWN;
-
-    #if defined(__VMS__)
-        if (st.st_fab_rfm != FAB$C_STMLF)
-            return wxFILE_KIND_UNKNOWN;
-    #endif
-
-    return wxFILE_KIND_DISK;
-
-#else
-    #define wxFILEKIND_STUB
-    (void)fd;
-    return wxFILE_KIND_DISK;
-#endif
-}
-
-wxFileKind wxGetFileKind(FILE *fp)
-{
-    // Note: The watcom rtl dll doesn't have fileno (the static lib does).
-    //       Should be fixed in version 1.4.
-#if defined(wxFILEKIND_STUB) || wxONLY_WATCOM_EARLIER_THAN(1,4)
-    (void)fp;
-    return wxFILE_KIND_DISK;
-#else
-    return fp ? wxGetFileKind(fileno(fp)) : wxFILE_KIND_UNKNOWN;
-#endif
-}
-
 #ifdef __VISUALC__
     #pragma warning(default:4706)   // assignment within conditional expression
 #endif // VC++