added volume support and support for UNC paths under Windows, improved Mac and VMS support
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12769 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -105,19 +105,30 @@ public:
|
|||||||
|
|
||||||
// the same for delayed initialization
|
// the same for delayed initialization
|
||||||
|
|
||||||
// VZ: wouldn't it be better to call this Create() for consistency with
|
|
||||||
// all GUI classes? Personally, I like Set() more than Assign() too
|
|
||||||
|
|
||||||
void Assign(const wxFileName& filepath);
|
void Assign(const wxFileName& filepath);
|
||||||
|
|
||||||
void Assign(const wxString& fullpath,
|
void Assign(const wxString& fullpath,
|
||||||
wxPathFormat format = wxPATH_NATIVE);
|
wxPathFormat format = wxPATH_NATIVE);
|
||||||
void Assign(const wxString& path,
|
|
||||||
const wxString& name,
|
void Assign(const wxString& volume,
|
||||||
wxPathFormat format = wxPATH_NATIVE);
|
const wxString& path,
|
||||||
void Assign(const wxString& path,
|
|
||||||
const wxString& name,
|
const wxString& name,
|
||||||
const wxString& ext,
|
const wxString& ext,
|
||||||
wxPathFormat format = wxPATH_NATIVE);
|
wxPathFormat format = wxPATH_NATIVE);
|
||||||
|
|
||||||
|
void Assign(const wxString& path,
|
||||||
|
const wxString& name,
|
||||||
|
wxPathFormat format = wxPATH_NATIVE);
|
||||||
|
|
||||||
|
void Assign(const wxString& path,
|
||||||
|
const wxString& name,
|
||||||
|
const wxString& ext,
|
||||||
|
wxPathFormat format = wxPATH_NATIVE)
|
||||||
|
{
|
||||||
|
// empty volume
|
||||||
|
Assign(_T(""), path, name, ext, format);
|
||||||
|
}
|
||||||
|
|
||||||
void AssignDir(const wxString& dir, wxPathFormat format = wxPATH_NATIVE)
|
void AssignDir(const wxString& dir, wxPathFormat format = wxPATH_NATIVE)
|
||||||
{ Assign(dir, _T(""), format); }
|
{ Assign(dir, _T(""), format); }
|
||||||
|
|
||||||
@@ -224,10 +235,22 @@ public:
|
|||||||
{ return *this == wxFileName(filename); }
|
{ return *this == wxFileName(filename); }
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
|
|
||||||
|
// are the file names of this type cases sensitive?
|
||||||
static bool IsCaseSensitive( wxPathFormat format = wxPATH_NATIVE );
|
static bool IsCaseSensitive( wxPathFormat format = wxPATH_NATIVE );
|
||||||
bool IsRelative( wxPathFormat format = wxPATH_NATIVE );
|
|
||||||
|
// is this filename absolute?
|
||||||
bool IsAbsolute( wxPathFormat format = wxPATH_NATIVE );
|
bool IsAbsolute( wxPathFormat format = wxPATH_NATIVE );
|
||||||
|
|
||||||
|
// is this filename relative?
|
||||||
|
bool IsRelative( wxPathFormat format = wxPATH_NATIVE )
|
||||||
|
{ return !IsAbsolute(format); }
|
||||||
|
|
||||||
|
// Information about path format
|
||||||
|
|
||||||
|
// get the string separating the volume from the path for this format
|
||||||
|
static wxString GetVolumeSeparator(wxPathFormat format = wxPATH_NATIVE);
|
||||||
|
|
||||||
// get the string of path separators for this format
|
// get the string of path separators for this format
|
||||||
static wxString GetPathSeparators(wxPathFormat format = wxPATH_NATIVE);
|
static wxString GetPathSeparators(wxPathFormat format = wxPATH_NATIVE);
|
||||||
|
|
||||||
@@ -247,17 +270,21 @@ public:
|
|||||||
// Other accessors
|
// Other accessors
|
||||||
void SetExt( const wxString &ext ) { m_ext = ext; }
|
void SetExt( const wxString &ext ) { m_ext = ext; }
|
||||||
wxString GetExt() const { return m_ext; }
|
wxString GetExt() const { return m_ext; }
|
||||||
bool HasExt() const { return !m_ext.IsEmpty(); }
|
bool HasExt() const { return !m_ext.empty(); }
|
||||||
|
|
||||||
void SetName( const wxString &name ) { m_name = name; }
|
void SetName( const wxString &name ) { m_name = name; }
|
||||||
wxString GetName() const { return m_name; }
|
wxString GetName() const { return m_name; }
|
||||||
bool HasName() const { return !m_name.IsEmpty(); }
|
bool HasName() const { return !m_name.empty(); }
|
||||||
|
|
||||||
|
void SetVolume( const wxString &volume ) { m_volume = volume; }
|
||||||
|
wxString GetVolume() const { return m_volume; }
|
||||||
|
bool HasVolume() const { return !m_volume.empty(); }
|
||||||
|
|
||||||
// full name is the file name + extension (but without the path)
|
// full name is the file name + extension (but without the path)
|
||||||
void SetFullName(const wxString& fullname);
|
void SetFullName(const wxString& fullname);
|
||||||
wxString GetFullName() const;
|
wxString GetFullName() const;
|
||||||
|
|
||||||
const wxArrayString &GetDirs() const { return m_dirs; }
|
const wxArrayString& GetDirs() const { return m_dirs; }
|
||||||
|
|
||||||
// Construct path only - possibly with the trailing separator
|
// Construct path only - possibly with the trailing separator
|
||||||
wxString GetPath( bool add_separator = FALSE,
|
wxString GetPath( bool add_separator = FALSE,
|
||||||
@@ -281,15 +308,29 @@ public:
|
|||||||
// get the canonical path format for this platform
|
// get the canonical path format for this platform
|
||||||
static wxPathFormat GetFormat( wxPathFormat format = wxPATH_NATIVE );
|
static wxPathFormat GetFormat( wxPathFormat format = wxPATH_NATIVE );
|
||||||
|
|
||||||
// split a fullpath into path, (base) name and ext (all of the pointers
|
// split a fullpath into the volume, path, (base) name and extension
|
||||||
// can be NULL)
|
// (all of the pointers can be NULL)
|
||||||
static void SplitPath(const wxString& fullpath,
|
static void SplitPath(const wxString& fullpath,
|
||||||
|
wxString *volume,
|
||||||
wxString *path,
|
wxString *path,
|
||||||
wxString *name,
|
wxString *name,
|
||||||
wxString *ext,
|
wxString *ext,
|
||||||
wxPathFormat format = wxPATH_NATIVE);
|
wxPathFormat format = wxPATH_NATIVE);
|
||||||
|
|
||||||
|
// compatibility version
|
||||||
|
static void SplitPath(const wxString& fullpath,
|
||||||
|
wxString *path,
|
||||||
|
wxString *name,
|
||||||
|
wxString *ext,
|
||||||
|
wxPathFormat format = wxPATH_NATIVE)
|
||||||
|
{
|
||||||
|
SplitPath(fullpath, NULL, path, name, ext, format);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// the drive/volume/device specification (always empty for Unix)
|
||||||
|
wxString m_volume;
|
||||||
|
|
||||||
// the path components of the file
|
// the path components of the file
|
||||||
wxArrayString m_dirs;
|
wxArrayString m_dirs;
|
||||||
|
|
||||||
|
@@ -9,6 +9,44 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Here are brief descriptions of the filename formats supported by this class:
|
||||||
|
|
||||||
|
wxPATH_UNIX: standard Unix format, absolute file names have the form
|
||||||
|
/dir1/dir2/.../dirN/filename, "." and ".." stand for the
|
||||||
|
current and parent directory respectively, "~" is parsed as the
|
||||||
|
user HOME and "~username" as the HOME of that user
|
||||||
|
|
||||||
|
wxPATH_DOS: DOS/Windows format, absolute file names have the form
|
||||||
|
drive:\dir1\dir2\...\dirN\filename.ext where drive is a single
|
||||||
|
letter. "." and ".." as for Unix but no "~".
|
||||||
|
|
||||||
|
There are also UNC names of the form \\share\fullpath
|
||||||
|
|
||||||
|
wxPATH_MAC: Mac OS 8/9 format, absolute file names have the form
|
||||||
|
volume:dir1:...:dirN:filename
|
||||||
|
and the relative file names are either
|
||||||
|
:dir1:...:dirN:filename
|
||||||
|
or just
|
||||||
|
filename
|
||||||
|
(although :filename works as well).
|
||||||
|
|
||||||
|
wxPATH_VMS: VMS native format, absolute file names have the form
|
||||||
|
<device>:[dir1.dir2.dir3]file.txt
|
||||||
|
or
|
||||||
|
<device>:[000000.dir1.dir2.dir3]file.txt
|
||||||
|
|
||||||
|
the <device> is the physical device (i.e. disk). 000000 is the
|
||||||
|
root directory on the device which can be omitted.
|
||||||
|
|
||||||
|
Note that VMS uses different separators unlike Unix:
|
||||||
|
: always after the device. If the path does not contain : than
|
||||||
|
the default (the device of the current directory) is assumed.
|
||||||
|
[ start of directory specyfication
|
||||||
|
. separator between directory and subdirectory
|
||||||
|
] between directory and file
|
||||||
|
*/
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// declarations
|
// declarations
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -166,32 +204,33 @@ static void ConvertWxToFileTime(FILETIME *ft, const wxDateTime& dt)
|
|||||||
|
|
||||||
void wxFileName::Assign( const wxFileName &filepath )
|
void wxFileName::Assign( const wxFileName &filepath )
|
||||||
{
|
{
|
||||||
m_ext = filepath.GetExt();
|
m_volume = filepath.GetVolume();
|
||||||
m_name = filepath.GetName();
|
|
||||||
m_dirs = filepath.GetDirs();
|
m_dirs = filepath.GetDirs();
|
||||||
|
m_name = filepath.GetName();
|
||||||
|
m_ext = filepath.GetExt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFileName::Assign( const wxString& path,
|
void wxFileName::Assign(const wxString& volume,
|
||||||
|
const wxString& path,
|
||||||
const wxString& name,
|
const wxString& name,
|
||||||
const wxString& ext,
|
const wxString& ext,
|
||||||
wxPathFormat format )
|
wxPathFormat format )
|
||||||
{
|
{
|
||||||
wxStringTokenizer tn(path, GetPathSeparators(format),
|
wxStringTokenizer tn(path, GetPathSeparators(format));
|
||||||
wxTOKEN_RET_EMPTY_ALL);
|
|
||||||
int i = 0;
|
|
||||||
m_dirs.Clear();
|
m_dirs.Clear();
|
||||||
while ( tn.HasMoreTokens() )
|
while ( tn.HasMoreTokens() )
|
||||||
{
|
{
|
||||||
wxString token = tn.GetNextToken();
|
wxString token = tn.GetNextToken();
|
||||||
|
|
||||||
// If the path starts with a slash (or two for a network path),
|
// if the path starts with a slash, we do need the first empty dir
|
||||||
// we need the first dir entry to be an empty for later reassembly.
|
// entry to be able to tell later that it was an absolute path, but
|
||||||
if ((i < 2) || !token.IsEmpty())
|
// otherwise ignore the double slashes
|
||||||
|
if ( m_dirs.IsEmpty() || !token.IsEmpty() )
|
||||||
m_dirs.Add( token );
|
m_dirs.Add( token );
|
||||||
|
|
||||||
i ++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_volume = volume;
|
||||||
m_ext = ext;
|
m_ext = ext;
|
||||||
m_name = name;
|
m_name = name;
|
||||||
}
|
}
|
||||||
@@ -199,10 +238,10 @@ void wxFileName::Assign( const wxString& path,
|
|||||||
void wxFileName::Assign(const wxString& fullpath,
|
void wxFileName::Assign(const wxString& fullpath,
|
||||||
wxPathFormat format)
|
wxPathFormat format)
|
||||||
{
|
{
|
||||||
wxString path, name, ext;
|
wxString volume, path, name, ext;
|
||||||
SplitPath(fullpath, &path, &name, &ext, format);
|
SplitPath(fullpath, &volume, &path, &name, &ext, format);
|
||||||
|
|
||||||
Assign(path, name, ext, format);
|
Assign(volume, path, name, ext, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFileName::Assign(const wxString& path,
|
void wxFileName::Assign(const wxString& path,
|
||||||
@@ -218,6 +257,8 @@ void wxFileName::Assign(const wxString& path,
|
|||||||
void wxFileName::Clear()
|
void wxFileName::Clear()
|
||||||
{
|
{
|
||||||
m_dirs.Clear();
|
m_dirs.Clear();
|
||||||
|
|
||||||
|
m_volume =
|
||||||
m_name =
|
m_name =
|
||||||
m_ext = wxEmptyString;
|
m_ext = wxEmptyString;
|
||||||
}
|
}
|
||||||
@@ -503,29 +544,59 @@ bool wxFileName::SameAs( const wxFileName &filepath, wxPathFormat format)
|
|||||||
/* static */
|
/* static */
|
||||||
bool wxFileName::IsCaseSensitive( wxPathFormat format )
|
bool wxFileName::IsCaseSensitive( wxPathFormat format )
|
||||||
{
|
{
|
||||||
// only DOS and OpenVMS filenames are case-sensitive
|
// only Unix filenames are truely case-sensitive
|
||||||
return GetFormat(format) != wxPATH_DOS && GetFormat(format) != wxPATH_VMS;
|
return GetFormat(format) == wxPATH_UNIX;
|
||||||
}
|
|
||||||
|
|
||||||
bool wxFileName::IsRelative( wxPathFormat format )
|
|
||||||
{
|
|
||||||
return !IsAbsolute(format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFileName::IsAbsolute( wxPathFormat format )
|
bool wxFileName::IsAbsolute( wxPathFormat format )
|
||||||
{
|
{
|
||||||
wxChar ch = m_dirs.IsEmpty() ? _T('\0') : m_dirs[0u][0u];
|
// if we have no path, we can't be an abs filename
|
||||||
|
if ( m_dirs.IsEmpty() )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// Hack to cope with e.g. c:\thing - need something better
|
switch ( GetFormat(format) )
|
||||||
wxChar driveSep = _T('\0');
|
{
|
||||||
if (!m_dirs.IsEmpty() && m_dirs[0].Length() > 1)
|
case wxPATH_DOS:
|
||||||
driveSep = m_dirs[0u][1u];
|
case wxPATH_VMS:
|
||||||
|
case wxPATH_MAC:
|
||||||
|
// must have the drive
|
||||||
|
return !m_volume.empty();
|
||||||
|
|
||||||
// the path is absolute if it starts with a path separator or, only for
|
default:
|
||||||
// Unix filenames, with "~" or "~user"
|
wxFAIL_MSG( _T("unknown wxPATH_XXX style") );
|
||||||
return IsPathSeparator(ch, format) ||
|
// fall through
|
||||||
driveSep == _T(':') ||
|
|
||||||
(GetFormat(format) == wxPATH_UNIX && ch == _T('~') );
|
case wxPATH_UNIX:
|
||||||
|
const wxString& str = m_dirs[0u];
|
||||||
|
if ( str.empty() )
|
||||||
|
{
|
||||||
|
// the path started with '/', it's an absolute one
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the path is absolute if it starts with a path separator or
|
||||||
|
// with "~" or "~user"
|
||||||
|
wxChar ch = str[0u];
|
||||||
|
|
||||||
|
return IsPathSeparator(ch, format) || ch == _T('~');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
wxString wxFileName::GetVolumeSeparator(wxPathFormat format)
|
||||||
|
{
|
||||||
|
wxString sepVol;
|
||||||
|
|
||||||
|
if ( GetFormat(format) != wxPATH_UNIX )
|
||||||
|
{
|
||||||
|
// so far it is the same for all systems which have it
|
||||||
|
sepVol = wxFILE_SEP_DSK;
|
||||||
|
}
|
||||||
|
//else: leave empty, no volume separators under Unix
|
||||||
|
|
||||||
|
return sepVol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -535,8 +606,9 @@ wxString wxFileName::GetPathSeparators(wxPathFormat format)
|
|||||||
switch ( GetFormat(format) )
|
switch ( GetFormat(format) )
|
||||||
{
|
{
|
||||||
case wxPATH_DOS:
|
case wxPATH_DOS:
|
||||||
// accept both as native APIs do
|
// accept both as native APIs do but put the native one first as
|
||||||
seps << wxFILE_SEP_PATH_UNIX << wxFILE_SEP_PATH_DOS;
|
// this is the one we use in GetFullPath()
|
||||||
|
seps << wxFILE_SEP_PATH_DOS << wxFILE_SEP_PATH_UNIX;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -562,6 +634,10 @@ wxString wxFileName::GetPathSeparators(wxPathFormat format)
|
|||||||
/* static */
|
/* static */
|
||||||
bool wxFileName::IsPathSeparator(wxChar ch, wxPathFormat format)
|
bool wxFileName::IsPathSeparator(wxChar ch, wxPathFormat format)
|
||||||
{
|
{
|
||||||
|
// wxString::Find() doesn't work as expected with NUL - it will always find
|
||||||
|
// it, so it is almost surely a bug if this function is called with NUL arg
|
||||||
|
wxASSERT_MSG( ch != _T('\0'), _T("shouldn't be called with NUL") );
|
||||||
|
|
||||||
return GetPathSeparators(format).Find(ch) != wxNOT_FOUND;
|
return GetPathSeparators(format).Find(ch) != wxNOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,55 +711,71 @@ wxString wxFileName::GetPath( bool add_separator, wxPathFormat format ) const
|
|||||||
|
|
||||||
wxString wxFileName::GetFullPath( wxPathFormat format ) const
|
wxString wxFileName::GetFullPath( wxPathFormat format ) const
|
||||||
{
|
{
|
||||||
format = GetFormat( format );
|
format = GetFormat(format);
|
||||||
|
|
||||||
wxString ret;
|
wxString fullpath;
|
||||||
if (format == wxPATH_DOS)
|
|
||||||
|
// first put the volume
|
||||||
|
if ( !m_volume.empty() )
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_dirs.GetCount(); i++)
|
// special Windows UNC paths hack, part 2: undo what we did in
|
||||||
|
// SplitPath() and make an UNC path if we have a drive which is not a
|
||||||
|
// single letter (hopefully the network shares can't be one letter only
|
||||||
|
// although I didn't find any authoritative docs on this)
|
||||||
|
if ( format == wxPATH_DOS && m_volume.length() > 1 )
|
||||||
{
|
{
|
||||||
ret += m_dirs[i];
|
fullpath << wxFILE_SEP_PATH_DOS << wxFILE_SEP_PATH_DOS << m_volume;
|
||||||
ret += '\\';
|
|
||||||
}
|
}
|
||||||
}
|
else // !UNC
|
||||||
else
|
|
||||||
if (format == wxPATH_UNIX)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_dirs.GetCount(); i++)
|
fullpath << m_volume << GetVolumeSeparator(format);
|
||||||
{
|
|
||||||
ret += m_dirs[i];
|
|
||||||
ret += '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (format == wxPATH_VMS)
|
|
||||||
{
|
|
||||||
ret += '[';
|
|
||||||
for (size_t i = 0; i < m_dirs.GetCount(); i++)
|
|
||||||
{
|
|
||||||
ret += '.';
|
|
||||||
ret += m_dirs[i];
|
|
||||||
}
|
|
||||||
ret += ']';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < m_dirs.GetCount(); i++)
|
|
||||||
{
|
|
||||||
ret += m_dirs[i];
|
|
||||||
ret += ':';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += m_name;
|
// then concatenate all the path components using the path separator
|
||||||
|
size_t dirCount = m_dirs.GetCount();
|
||||||
if (!m_ext.IsEmpty())
|
if ( dirCount )
|
||||||
{
|
{
|
||||||
ret += '.';
|
// under Mac, we must have a path separator in the beginning of the
|
||||||
ret += m_ext;
|
// relative path - otherwise it would be parsed as an absolute one
|
||||||
|
if ( format == wxPATH_MAC && m_volume.empty() && !m_dirs[0].empty() )
|
||||||
|
{
|
||||||
|
fullpath += wxFILE_SEP_PATH_MAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
wxChar chPathSep = GetPathSeparators(format)[0u];
|
||||||
|
if ( format == wxPATH_VMS )
|
||||||
|
{
|
||||||
|
fullpath += _T('[');
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < dirCount; i++ )
|
||||||
|
{
|
||||||
|
// under VMS, we shouldn't have a leading dot
|
||||||
|
if ( i && (format != wxPATH_VMS || !m_dirs[i - 1].empty()) )
|
||||||
|
fullpath += chPathSep;
|
||||||
|
|
||||||
|
fullpath += m_dirs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( format == wxPATH_VMS )
|
||||||
|
{
|
||||||
|
fullpath += _T(']');
|
||||||
|
}
|
||||||
|
else // !VMS
|
||||||
|
{
|
||||||
|
// separate the file name from the last directory, notice that we
|
||||||
|
// intentionally do it even if the name and extension are empty as
|
||||||
|
// this allows us to distinguish the directories from the file
|
||||||
|
// names (the directories have the trailing slash)
|
||||||
|
fullpath += chPathSep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally add the file name and extension
|
||||||
|
fullpath += GetFullName();
|
||||||
|
|
||||||
|
return fullpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the short form of the path (returns identity on non-Windows platforms)
|
// Return the short form of the path (returns identity on non-Windows platforms)
|
||||||
@@ -847,7 +939,8 @@ wxPathFormat wxFileName::GetFormat( wxPathFormat format )
|
|||||||
// path splitting function
|
// path splitting function
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxFileName::SplitPath(const wxString& fullpath,
|
void wxFileName::SplitPath(const wxString& fullpathWithVolume,
|
||||||
|
wxString *pstrVolume,
|
||||||
wxString *pstrPath,
|
wxString *pstrPath,
|
||||||
wxString *pstrName,
|
wxString *pstrName,
|
||||||
wxString *pstrExt,
|
wxString *pstrExt,
|
||||||
@@ -855,30 +948,63 @@ void wxFileName::SplitPath(const wxString& fullpath,
|
|||||||
{
|
{
|
||||||
format = GetFormat(format);
|
format = GetFormat(format);
|
||||||
|
|
||||||
|
wxString fullpath = fullpathWithVolume;
|
||||||
|
|
||||||
|
// under VMS the end of the path is ']', not the path separator used to
|
||||||
|
// separate the components
|
||||||
|
wxString sepPath = format == wxPATH_VMS ? _T(']')
|
||||||
|
: GetPathSeparators(format);
|
||||||
|
|
||||||
|
// special Windows UNC paths hack: transform \\share\path into share:path
|
||||||
|
if ( format == wxPATH_DOS )
|
||||||
|
{
|
||||||
|
if ( fullpath.length() >= 4 &&
|
||||||
|
fullpath[0u] == wxFILE_SEP_PATH_DOS &&
|
||||||
|
fullpath[1u] == wxFILE_SEP_PATH_DOS )
|
||||||
|
{
|
||||||
|
fullpath.erase(0, 2);
|
||||||
|
|
||||||
|
size_t posFirstSlash = fullpath.find_first_of(sepPath);
|
||||||
|
if ( posFirstSlash != wxString::npos )
|
||||||
|
{
|
||||||
|
fullpath[posFirstSlash] = wxFILE_SEP_DSK;
|
||||||
|
|
||||||
|
// UNC paths are always absolute, right? (FIXME)
|
||||||
|
fullpath.insert(posFirstSlash + 1, wxFILE_SEP_PATH_DOS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have the volume name in the beginning?
|
||||||
|
wxString sepVol = GetVolumeSeparator(format);
|
||||||
|
if ( !sepVol.empty() )
|
||||||
|
{
|
||||||
|
size_t posFirstColon = fullpath.find_first_of(sepVol);
|
||||||
|
if ( posFirstColon != wxString::npos )
|
||||||
|
{
|
||||||
|
if ( pstrVolume )
|
||||||
|
{
|
||||||
|
*pstrVolume = fullpath.Left(posFirstColon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the volume name and the separator from the full path
|
||||||
|
fullpath.erase(0, posFirstColon + sepVol.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// find the positions of the last dot and last path separator in the path
|
// find the positions of the last dot and last path separator in the path
|
||||||
size_t posLastDot = fullpath.find_last_of(wxFILE_SEP_EXT);
|
size_t posLastDot = fullpath.find_last_of(wxFILE_SEP_EXT);
|
||||||
size_t posLastSlash = fullpath.find_last_of(GetPathSeparators(format));
|
size_t posLastSlash = fullpath.find_last_of(sepPath);
|
||||||
|
|
||||||
if ( (posLastDot != wxString::npos) && (format == wxPATH_UNIX) )
|
if ( (posLastDot != wxString::npos) &&
|
||||||
|
((format == wxPATH_UNIX) || (format == wxPATH_VMS)) )
|
||||||
{
|
{
|
||||||
if ( (posLastDot == 0) ||
|
if ( (posLastDot == 0) ||
|
||||||
(fullpath[posLastDot - 1] == wxFILE_SEP_PATH_UNIX) )
|
(fullpath[posLastDot - 1] == sepPath[0u] ) )
|
||||||
{
|
{
|
||||||
// under Unix, dot may be (and commonly is) the first character of
|
// under Unix and VMS, dot may be (and commonly is) the first
|
||||||
// the filename, don't treat the entire filename as extension in
|
// character of the filename, don't treat the entire filename as
|
||||||
// this case
|
// extension in this case
|
||||||
posLastDot = wxString::npos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ( (posLastDot != wxString::npos) && (format == wxPATH_VMS) )
|
|
||||||
{
|
|
||||||
if ( (posLastDot == 0) ||
|
|
||||||
(fullpath[posLastDot - 1] == ']' ) )
|
|
||||||
{
|
|
||||||
// under OpenVMS, dot may be (and commonly is) the first character of
|
|
||||||
// the filename, don't treat the entire filename as extension in
|
|
||||||
// this case
|
|
||||||
posLastDot = wxString::npos;
|
posLastDot = wxString::npos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -902,8 +1028,21 @@ void wxFileName::SplitPath(const wxString& fullpath,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// take all until the separator
|
// take everything up to the path separator but take care to make
|
||||||
*pstrPath = fullpath.Left(posLastSlash);
|
// tha path equal to something like '/', not empty, for the files
|
||||||
|
// immediately under root directory
|
||||||
|
size_t len = posLastSlash;
|
||||||
|
if ( !len )
|
||||||
|
len++;
|
||||||
|
|
||||||
|
*pstrPath = fullpath.Left(len);
|
||||||
|
|
||||||
|
// special VMS hack: remove the initial bracket
|
||||||
|
if ( format == wxPATH_VMS )
|
||||||
|
{
|
||||||
|
if ( (*pstrPath)[0u] == _T('[') )
|
||||||
|
pstrPath->erase(0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user