+ m_name = filepath.GetName();
+ m_ext = filepath.GetExt();
+ m_relative = filepath.m_relative;
+ m_hasExt = filepath.m_hasExt;
+}
+
+void wxFileName::Assign(const wxString& volume,
+ const wxString& path,
+ const wxString& name,
+ const wxString& ext,
+ bool hasExt,
+ wxPathFormat format)
+{
+ // we should ignore paths which look like UNC shares because we already
+ // have the volume here and the UNC notation (\\server\path) is only valid
+ // for paths which don't start with a volume, so prevent SetPath() from
+ // recognizing "\\foo\bar" in "c:\\foo\bar" as an UNC path
+ //
+ // note also that this is a rather ugly way to do what we want (passing
+ // some kind of flag telling to ignore UNC paths to SetPath() would be
+ // better) but this is the safest thing to do to avoid breaking backwards
+ // compatibility in 2.8
+ if ( IsUNCPath(path, format) )
+ {
+ // remove one of the 2 leading backslashes to ensure that it's not
+ // recognized as an UNC path by SetPath()
+ wxString pathNonUNC(path, 1, wxString::npos);
+ SetPath(pathNonUNC, format);
+ }
+ else // no UNC complications
+ {
+ SetPath(path, format);
+ }
+
+ m_volume = volume;
+ m_ext = ext;
+ m_name = name;
+
+ m_hasExt = hasExt;
+}
+
+void wxFileName::SetPath( const wxString& pathOrig, wxPathFormat format )
+{
+ m_dirs.Clear();
+
+ if ( pathOrig.empty() )
+ {
+ // no path at all
+ m_relative = true;
+
+ return;
+ }
+
+ format = GetFormat( format );
+
+ // 0) deal with possible volume part first
+ wxString volume,
+ path;
+ SplitVolume(pathOrig, &volume, &path, format);
+ if ( !volume.empty() )
+ {
+ m_relative = false;
+
+ SetVolume(volume);
+ }
+
+ // 1) Determine if the path is relative or absolute.
+ wxChar leadingChar = path[0u];
+
+ switch (format)
+ {
+ case wxPATH_MAC:
+ m_relative = leadingChar == wxT(':');
+
+ // We then remove a leading ":". The reason is in our
+ // storage form for relative paths:
+ // ":dir:file.txt" actually means "./dir/file.txt" in
+ // DOS notation and should get stored as
+ // (relative) (dir) (file.txt)
+ // "::dir:file.txt" actually means "../dir/file.txt"
+ // stored as (relative) (..) (dir) (file.txt)
+ // This is important only for the Mac as an empty dir
+ // actually means <UP>, whereas under DOS, double
+ // slashes can be ignored: "\\\\" is the same as "\\".
+ if (m_relative)
+ path.erase( 0, 1 );
+ break;
+
+ case wxPATH_VMS:
+ // TODO: what is the relative path format here?
+ m_relative = false;
+ break;
+
+ default:
+ wxFAIL_MSG( _T("Unknown path format") );
+ // !! Fall through !!
+
+ case wxPATH_UNIX:
+ // the paths of the form "~" or "~username" are absolute
+ m_relative = leadingChar != wxT('/') && leadingChar != _T('~');
+ break;
+
+ case wxPATH_DOS:
+ m_relative = !IsPathSeparator(leadingChar, format);
+ break;
+
+ }
+
+ // 2) Break up the path into its members. If the original path
+ // was just "/" or "\\", m_dirs will be empty. We know from
+ // the m_relative field, if this means "nothing" or "root dir".
+
+ wxStringTokenizer tn( path, GetPathSeparators(format) );
+
+ while ( tn.HasMoreTokens() )
+ {
+ wxString token = tn.GetNextToken();
+
+ // Remove empty token under DOS and Unix, interpret them
+ // as .. under Mac.
+ if (token.empty())
+ {
+ if (format == wxPATH_MAC)
+ m_dirs.Add( wxT("..") );
+ // else ignore
+ }
+ else
+ {
+ m_dirs.Add( token );
+ }
+ }
+}
+
+void wxFileName::Assign(const wxString& fullpath,
+ wxPathFormat format)
+{
+ wxString volume, path, name, ext;
+ bool hasExt;
+ SplitPath(fullpath, &volume, &path, &name, &ext, &hasExt, format);
+
+ Assign(volume, path, name, ext, hasExt, format);
+}
+
+void wxFileName::Assign(const wxString& fullpathOrig,
+ const wxString& fullname,
+ wxPathFormat format)
+{
+ // always recognize fullpath as directory, even if it doesn't end with a
+ // slash
+ wxString fullpath = fullpathOrig;
+ if ( !fullpath.empty() && !wxEndsWithPathSeparator(fullpath) )
+ {
+ fullpath += GetPathSeparator(format);
+ }
+
+ wxString volume, path, name, ext;
+ bool hasExt;
+
+ // do some consistency checks in debug mode: the name should be really just
+ // the filename and the path should be really just a path
+#ifdef __WXDEBUG__
+ wxString volDummy, pathDummy, nameDummy, extDummy;
+
+ SplitPath(fullname, &volDummy, &pathDummy, &name, &ext, &hasExt, format);
+
+ wxASSERT_MSG( volDummy.empty() && pathDummy.empty(),
+ _T("the file name shouldn't contain the path") );
+
+ SplitPath(fullpath, &volume, &path, &nameDummy, &extDummy, format);
+
+ wxASSERT_MSG( nameDummy.empty() && extDummy.empty(),
+ _T("the path shouldn't contain file name nor extension") );
+
+#else // !__WXDEBUG__
+ SplitPath(fullname, NULL /* no volume */, NULL /* no path */,
+ &name, &ext, &hasExt, format);
+ SplitPath(fullpath, &volume, &path, NULL, NULL, format);
+#endif // __WXDEBUG__/!__WXDEBUG__
+
+ Assign(volume, path, name, ext, hasExt, format);
+}
+
+void wxFileName::Assign(const wxString& pathOrig,
+ const wxString& name,
+ const wxString& ext,
+ wxPathFormat format)
+{
+ wxString volume,
+ path;
+ SplitVolume(pathOrig, &volume, &path, format);
+
+ Assign(volume, path, name, ext, format);
+}
+
+void wxFileName::AssignDir(const wxString& dir, wxPathFormat format)
+{
+ Assign(dir, wxEmptyString, format);
+}
+
+void wxFileName::Clear()
+{
+ m_dirs.Clear();
+
+ m_volume =
+ m_name =
+ m_ext = wxEmptyString;
+
+ // we don't have any absolute path for now
+ m_relative = true;
+
+ // nor any extension
+ m_hasExt = false;
+}
+
+/* static */
+wxFileName wxFileName::FileName(const wxString& file, wxPathFormat format)
+{
+ return wxFileName(file, format);
+}
+
+/* static */
+wxFileName wxFileName::DirName(const wxString& dir, wxPathFormat format)
+{
+ wxFileName fn;
+ fn.AssignDir(dir, format);
+ return fn;
+}
+
+// ----------------------------------------------------------------------------
+// existence tests
+// ----------------------------------------------------------------------------
+
+bool wxFileName::FileExists() const
+{
+ return wxFileName::FileExists( GetFullPath() );
+}
+
+bool wxFileName::FileExists( const wxString &file )
+{
+ return ::wxFileExists( file );
+}
+
+bool wxFileName::DirExists() const
+{
+ return wxFileName::DirExists( GetPath() );
+}
+
+bool wxFileName::DirExists( const wxString &dir )
+{
+ return ::wxDirExists( dir );
+}
+
+// ----------------------------------------------------------------------------
+// CWD and HOME stuff
+// ----------------------------------------------------------------------------
+
+void wxFileName::AssignCwd(const wxString& volume)
+{
+ AssignDir(wxFileName::GetCwd(volume));
+}
+
+/* static */
+wxString wxFileName::GetCwd(const wxString& volume)
+{
+ // if we have the volume, we must get the current directory on this drive
+ // and to do this we have to chdir to this volume - at least under Windows,
+ // I don't know how to get the current drive on another volume elsewhere
+ // (TODO)
+ wxString cwdOld;
+ if ( !volume.empty() )
+ {
+ cwdOld = wxGetCwd();
+ SetCwd(volume + GetVolumeSeparator());
+ }
+
+ wxString cwd = ::wxGetCwd();
+
+ if ( !volume.empty() )
+ {
+ SetCwd(cwdOld);
+ }
+
+ return cwd;
+}
+
+bool wxFileName::SetCwd()
+{
+ return wxFileName::SetCwd( GetPath() );
+}
+
+bool wxFileName::SetCwd( const wxString &cwd )
+{
+ return ::wxSetWorkingDirectory( cwd );
+}
+
+void wxFileName::AssignHomeDir()
+{
+ AssignDir(wxFileName::GetHomeDir());
+}
+
+wxString wxFileName::GetHomeDir()
+{
+ return ::wxGetHomeDir();
+}
+
+
+// ----------------------------------------------------------------------------
+// CreateTempFileName
+// ----------------------------------------------------------------------------
+
+#if wxUSE_FILE || wxUSE_FFILE
+
+
+#if !defined wx_fdopen && defined HAVE_FDOPEN
+ #define wx_fdopen fdopen
+#endif
+
+// NB: GetTempFileName() under Windows creates the file, so using
+// O_EXCL there would fail
+#ifdef __WINDOWS__
+ #define wxOPEN_EXCL 0
+#else
+ #define wxOPEN_EXCL O_EXCL
+#endif
+
+
+#ifdef wxOpenOSFHandle
+#define WX_HAVE_DELETE_ON_CLOSE
+// On Windows create a file with the FILE_FLAGS_DELETE_ON_CLOSE flags.
+//
+static int wxOpenWithDeleteOnClose(const wxString& filename)
+{
+ DWORD access = GENERIC_READ | GENERIC_WRITE;
+
+ DWORD disposition = OPEN_ALWAYS;
+
+ DWORD attributes = FILE_ATTRIBUTE_TEMPORARY |
+ FILE_FLAG_DELETE_ON_CLOSE;
+
+ HANDLE h = ::CreateFile(filename, access, 0, NULL,
+ disposition, attributes, NULL);
+
+ return wxOpenOSFHandle(h, wxO_BINARY);
+}
+#endif // wxOpenOSFHandle
+
+
+// Helper to open the file
+//
+static int wxTempOpen(const wxString& path, bool *deleteOnClose)
+{
+#ifdef WX_HAVE_DELETE_ON_CLOSE
+ if (*deleteOnClose)
+ return wxOpenWithDeleteOnClose(path);
+#endif
+
+ *deleteOnClose = false;
+
+ return wxOpen(path, wxO_BINARY | O_RDWR | O_CREAT | wxOPEN_EXCL, 0600);
+}
+
+
+#if wxUSE_FFILE
+// Helper to open the file and attach it to the wxFFile
+//
+static bool wxTempOpen(wxFFile *file, const wxString& path, bool *deleteOnClose)
+{
+#ifndef wx_fdopen
+ *deleteOnClose = false;
+ return file->Open(path, _T("w+b"));
+#else // wx_fdopen
+ int fd = wxTempOpen(path, deleteOnClose);
+ if (fd == -1)
+ return false;
+ file->Attach(wx_fdopen(fd, "w+b"));
+ return file->IsOpened();
+#endif // wx_fdopen