support filenames with empty extension (foo.) (bug 1078200)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32436 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-02-28 00:18:37 +00:00
parent 21b9b5e292
commit dfecbee579
4 changed files with 78 additions and 21 deletions

View File

@@ -197,6 +197,8 @@ assert failure in debug build).
\func{void}{Assign}{\param{const wxString\& }{fullpath}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{void}{Assign}{\param{const wxString\& }{volume}, \param{const wxString\& }{path}, \param{const wxString\& }{name}, \param{const wxString\& }{ext}, \param{bool }{hasExt}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{void}{Assign}{\param{const wxString\& }{volume}, \param{const wxString\& }{path}, \param{const wxString\& }{name}, \param{const wxString\& }{ext}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{void}{Assign}{\param{const wxString\& }{path}, \param{const wxString\& }{name}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
@@ -785,6 +787,8 @@ Sets the volume specifier.
\membersection{wxFileName::SplitPath}\label{wxfilenamesplitpath}
\func{static void}{SplitPath}{\param{const wxString\& }{fullpath}, \param{wxString* }{volume}, \param{wxString* }{path}, \param{wxString* }{name}, \param{wxString* }{ext}, \param{bool }{*hasExt = \texttt{NULL}}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{static void}{SplitPath}{\param{const wxString\& }{fullpath}, \param{wxString* }{volume}, \param{wxString* }{path}, \param{wxString* }{name}, \param{wxString* }{ext}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{static void}{SplitPath}{\param{const wxString\& }{fullpath}, \param{wxString* }{path}, \param{wxString* }{name}, \param{wxString* }{ext}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
@@ -801,6 +805,10 @@ without leading dot. All three of them may be empty if the corresponding
component is. The old contents of the strings pointed to by these parameters
will be overwritten in any case (if the pointers are not {\tt NULL}).
Note that for a filename ``foo.'' the extension is present, as indicated by the
trailing dot, but empty. If you need to cope with such cases, you should use
\arg{hasExt} instead of relying on testing whether \arg{ext} is empty or not.
\membersection{wxFileName::SplitVolume}\label{wxfilenamesplitvolume}

View File

@@ -142,8 +142,16 @@ public:
const wxString& path,
const wxString& name,
const wxString& ext,
bool hasExt,
wxPathFormat format = wxPATH_NATIVE);
void Assign(const wxString& volume,
const wxString& path,
const wxString& name,
const wxString& ext,
wxPathFormat format = wxPATH_NATIVE)
{ Assign(volume, path, name, ext, !ext.empty(), format); }
void Assign(const wxString& path,
const wxString& name,
wxPathFormat format = wxPATH_NATIVE);
@@ -178,7 +186,8 @@ public:
bool IsOk() const
{
// we're fine if we have the path or the name or if we're a root dir
return m_dirs.size() != 0 || !m_name.IsEmpty() || !m_relative;
return m_dirs.size() != 0 || !m_name.IsEmpty() || !m_relative ||
!m_ext.empty() || m_hasExt;
}
// does the file with this name exists?
@@ -407,9 +416,20 @@ public:
wxString *path,
wxString *name,
wxString *ext,
bool *hasExt = NULL,
wxPathFormat format = wxPATH_NATIVE);
// compatibility version
static void SplitPath(const wxString& fullpath,
wxString *volume,
wxString *path,
wxString *name,
wxString *ext,
wxPathFormat format = wxPATH_NATIVE)
{
SplitPath(fullpath, volume, path, name, ext, NULL, format);
}
// compatibility version: volume is part of path
static void SplitPath(const wxString& fullpath,
wxString *path,
wxString *name,
@@ -455,6 +475,13 @@ private:
// NB: the path is not absolute just because m_relative is false, it still
// needs the drive (i.e. volume) in some formats (Windows)
bool m_relative;
// when m_ext is empty, it may be because we don't have any extension or
// because we have an empty extension
//
// the difference is important as file with name "foo" and without
// extension has full name "foo" while with empty extension it is "foo."
bool m_hasExt;
};
#endif // _WX_FILENAME_H_

View File

@@ -300,12 +300,14 @@ void wxFileName::Assign( const wxFileName &filepath )
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 )
{
SetPath( path, format );
@@ -313,6 +315,8 @@ void wxFileName::Assign(const wxString& volume,
m_volume = volume;
m_ext = ext;
m_name = name;
m_hasExt = hasExt;
}
void wxFileName::SetPath( const wxString& pathOrig, wxPathFormat format )
@@ -411,9 +415,10 @@ void wxFileName::Assign(const wxString& fullpath,
wxPathFormat format)
{
wxString volume, path, name, ext;
SplitPath(fullpath, &volume, &path, &name, &ext, format);
bool hasExt;
SplitPath(fullpath, &volume, &path, &name, &ext, &hasExt, format);
Assign(volume, path, name, ext, format);
Assign(volume, path, name, ext, hasExt, format);
}
void wxFileName::Assign(const wxString& fullpathOrig,
@@ -429,15 +434,16 @@ void wxFileName::Assign(const wxString& fullpathOrig,
}
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 pathDummy, nameDummy, extDummy;
wxString volDummy, pathDummy, nameDummy, extDummy;
SplitPath(fullname, &pathDummy, &name, &ext, format);
SplitPath(fullname, &volDummy, &pathDummy, &name, &ext, &hasExt, format);
wxASSERT_MSG( pathDummy.empty(),
wxASSERT_MSG( volDummy.empty() && pathDummy.empty(),
_T("the file name shouldn't contain the path") );
SplitPath(fullpath, &volume, &path, &nameDummy, &extDummy, format);
@@ -446,11 +452,11 @@ void wxFileName::Assign(const wxString& fullpathOrig,
_T("the path shouldn't contain file name nor extension") );
#else // !__WXDEBUG__
SplitPath(fullname, NULL /* no path */, &name, &ext, format);
SplitPath(fullname, NULL /* no path */, &name, &ext, &hasExt, format);
SplitPath(fullpath, &volume, &path, NULL, NULL, format);
#endif // __WXDEBUG__/!__WXDEBUG__
Assign(volume, path, name, ext, format);
Assign(volume, path, name, ext, hasExt, format);
}
void wxFileName::Assign(const wxString& pathOrig,
@@ -480,6 +486,9 @@ void wxFileName::Clear()
// we don't have any absolute path for now
m_relative = true;
// nor any extension
m_hasExt = false;
}
/* static */
@@ -1352,13 +1361,14 @@ void wxFileName::RemoveDir(size_t pos)
void wxFileName::SetFullName(const wxString& fullname)
{
SplitPath(fullname, NULL /* no path */, &m_name, &m_ext);
SplitPath(fullname, NULL /* no volume */, NULL /* no path */,
&m_name, &m_ext, &m_hasExt);
}
wxString wxFileName::GetFullName() const
{
wxString fullname = m_name;
if ( !m_ext.empty() )
if ( m_hasExt )
{
fullname << wxFILE_SEP_EXT << m_ext;
}
@@ -1720,6 +1730,7 @@ void wxFileName::SplitPath(const wxString& fullpathWithVolume,
wxString *pstrPath,
wxString *pstrName,
wxString *pstrExt,
bool *hasExt,
wxPathFormat format)
{
format = GetFormat(format);
@@ -1806,18 +1817,25 @@ void wxFileName::SplitPath(const wxString& fullpathWithVolume,
*pstrName = fullpath.Mid(nStart, count);
}
if ( pstrExt )
// finally deal with the extension here: we have an added complication that
// extension may be empty (but present) as in "foo." where trailing dot
// indicates the empty extension at the end -- and hence we must remember
// that we have it independently of pstrExt
if ( posLastDot == wxString::npos )
{
if ( posLastDot == wxString::npos )
{
// no extension
pstrExt->Empty();
}
else
{
// take everything after the dot
// no extension
if ( pstrExt )
pstrExt->clear();
if ( hasExt )
*hasExt = false;
}
else
{
// take everything after the dot
if ( pstrExt )
*pstrExt = fullpath.Mid(posLastDot + 1);
}
if ( hasExt )
*hasExt = true;
}
}

View File

@@ -148,6 +148,10 @@ void FileNameTestCase::TestSplit()
CPPUNIT_ASSERT( name == fni.name );
CPPUNIT_ASSERT( ext == fni.ext );
}
// special case of empty extension
wxFileName fn(_T("foo."));
CPPUNIT_ASSERT( fn.GetFullPath() == _T("foo.") );
}
void FileNameTestCase::TestSetPath()