From f1e7793361bb0106611e5d1373b4e1e6ed30f14f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Jul 2004 13:59:47 +0000 Subject: [PATCH] added and documented SplitVolume() and GetPathTerminators(); corrected SetPath() to treat the volume part properly (patch 970580) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28468 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/filename.tex | 21 ++++ include/wx/filename.h | 9 ++ src/common/filename.cpp | 193 ++++++++++++++++++++++--------------- 3 files changed, 143 insertions(+), 80 deletions(-) diff --git a/docs/latex/wx/filename.tex b/docs/latex/wx/filename.tex index 6a79a412d5..4c79011c30 100644 --- a/docs/latex/wx/filename.tex +++ b/docs/latex/wx/filename.tex @@ -460,6 +460,15 @@ separators. \helpref{GetPathSeparator}{wxfilenamegetpathseparator} +\membersection{wxFileName::GetPathTerminators}\label{wxfilenamegetpathterminators} + +\func{static wxString}{GetPathTerminators}{\param{wxPathFormat }{format = wxPATH\_NATIVE}} + +Returns the string of characters which may terminate the path part. This is the +same as \helpref{GetPathSeparators}{wxfilenamegetpathseparators} except for VMS +path format where $]$ is used at the end of the path part. + + \membersection{wxFileName::GetShortPath}\label{wxfilenamegetshortpath} \constfunc{wxString}{GetShortPath}{\void} @@ -763,6 +772,18 @@ 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}). +\membersection{wxFileName::SplitVolume}\label{wxfilenamesplitvolume} + +\func{static void}{SplitVolume}{\param{const wxString\& }{fullpath}, \param{wxString* }{volume}, \param{wxString* }{path}, \param{wxPathFormat }{format = wxPATH\_NATIVE}} + +Splits the given \arg{fullpath} into the volume part (which may be empty) and +the pure path part, not containing any volume. + +\wxheading{See also} + +\helpref{SplitPath}{wxfilenamesplitpath} + + \membersection{wxFileName::Touch}\label{wxfilenametouch} \func{bool}{Touch}{\void} diff --git a/include/wx/filename.h b/include/wx/filename.h index cbd601e663..ef9a23dd97 100644 --- a/include/wx/filename.h +++ b/include/wx/filename.h @@ -338,6 +338,10 @@ public: // get the string of path separators for this format static wxString GetPathSeparators(wxPathFormat format = wxPATH_NATIVE); + // get the string of path terminators, i.e. characters which terminate the + // path + static wxString GetPathTerminators(wxPathFormat format = wxPATH_NATIVE); + // get the canonical path separator for this format static wxChar GetPathSeparator(wxPathFormat format = wxPATH_NATIVE) { return GetPathSeparators(format)[0u]; } @@ -411,6 +415,11 @@ public: wxString *ext, wxPathFormat format = wxPATH_NATIVE); + // split a path into volume and pure path part + static void SplitVolume(const wxString& fullpathWithVolume, + wxString *volume, + wxString *path, + wxPathFormat format = wxPATH_NATIVE); // deprecated methods, don't use any more // -------------------------------------- diff --git a/src/common/filename.cpp b/src/common/filename.cpp index a74aa0fa4b..17218d98d3 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -312,84 +312,95 @@ void wxFileName::Assign(const wxString& volume, m_name = name; } -void wxFileName::SetPath( const wxString &path, wxPathFormat format ) +void wxFileName::SetPath( const wxString& pathOrig, wxPathFormat format ) { m_dirs.Clear(); - if ( !path.empty() ) + if ( pathOrig.empty() ) { - wxPathFormat my_format = GetFormat( format ); - wxString my_path = path; + // no path at all + m_relative = true; - // 1) Determine if the path is relative or absolute. - wxChar leadingChar = my_path[0u]; + return; + } - switch (my_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 , whereas under DOS, double - // slashes can be ignored: "\\\\" is the same as "\\". - if (m_relative) - my_path.erase( 0, 1 ); - break; + format = GetFormat( format ); - case wxPATH_VMS: - // TODO: what is the relative path format here? - m_relative = false; - break; + // 0) deal with possible volume part first + wxString volume, + path; + SplitVolume(pathOrig, &volume, &path, format); + if ( !volume.empty() ) + { + m_relative = false; - default: - wxFAIL_MSG( _T("Unknown path format") ); - // !! Fall through !! + SetVolume(volume); + } - case wxPATH_UNIX: - // the paths of the form "~" or "~username" are absolute - m_relative = leadingChar != wxT('/') && leadingChar != _T('~'); - break; + // 1) Determine if the path is relative or absolute. + wxChar leadingChar = path[0u]; - case wxPATH_DOS: - m_relative = !IsPathSeparator(leadingChar, my_format); - break; + 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 , 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; - // 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". + default: + wxFAIL_MSG( _T("Unknown path format") ); + // !! Fall through !! - wxStringTokenizer tn( my_path, GetPathSeparators(my_format) ); + case wxPATH_UNIX: + // the paths of the form "~" or "~username" are absolute + m_relative = leadingChar != wxT('/') && leadingChar != _T('~'); + break; - while ( tn.HasMoreTokens() ) - { - wxString token = tn.GetNextToken(); + case wxPATH_DOS: + m_relative = !IsPathSeparator(leadingChar, format); + break; - // Remove empty token under DOS and Unix, interpret them - // as .. under Mac. - if (token.empty()) - { - if (my_format == wxPATH_MAC) - m_dirs.Add( wxT("..") ); - // else ignore - } - else - { - m_dirs.Add( token ); - } - } } - else // no path at all + + // 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() ) { - m_relative = true; + 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 ); + } } } @@ -1244,6 +1255,16 @@ wxString wxFileName::GetPathSeparators(wxPathFormat format) return seps; } +/* static */ +wxString wxFileName::GetPathTerminators(wxPathFormat format) +{ + format = GetFormat(format); + + // under VMS the end of the path is ']', not the path separator used to + // separate the components + return format == wxPATH_VMS ? wxString(_T(']')) : GetPathSeparators(format); +} + /* static */ bool wxFileName::IsPathSeparator(wxChar ch, wxPathFormat format) { @@ -1618,22 +1639,16 @@ wxPathFormat wxFileName::GetFormat( wxPathFormat format ) // ---------------------------------------------------------------------------- /* static */ -void wxFileName::SplitPath(const wxString& fullpathWithVolume, - wxString *pstrVolume, - wxString *pstrPath, - wxString *pstrName, - wxString *pstrExt, - wxPathFormat format) +void +wxFileName::SplitVolume(const wxString& fullpathWithVolume, + wxString *pstrVolume, + wxString *pstrPath, + wxPathFormat 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 ? wxString(_T(']')) - : GetPathSeparators(format); - // special Windows UNC paths hack: transform \\share\path into share:path if ( format == wxPATH_DOS ) { @@ -1643,7 +1658,8 @@ void wxFileName::SplitPath(const wxString& fullpathWithVolume, { fullpath.erase(0, 2); - size_t posFirstSlash = fullpath.find_first_of(sepPath); + size_t posFirstSlash = + fullpath.find_first_of(GetPathTerminators(format)); if ( posFirstSlash != wxString::npos ) { fullpath[posFirstSlash] = wxFILE_SEP_DSK; @@ -1672,21 +1688,38 @@ void wxFileName::SplitPath(const wxString& fullpathWithVolume, } } + if ( pstrPath ) + *pstrPath = fullpath; +} + +/* static */ +void wxFileName::SplitPath(const wxString& fullpathWithVolume, + wxString *pstrVolume, + wxString *pstrPath, + wxString *pstrName, + wxString *pstrExt, + wxPathFormat format) +{ + format = GetFormat(format); + + wxString fullpath; + SplitVolume(fullpathWithVolume, pstrVolume, &fullpath, format); + // 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 posLastSlash = fullpath.find_last_of(sepPath); + size_t posLastSlash = fullpath.find_last_of(GetPathTerminators(format)); // check whether this dot occurs at the very beginning of a path component if ( (posLastDot != wxString::npos) && (posLastDot == 0 || IsPathSeparator(fullpath[posLastDot - 1]) || (format == wxPATH_VMS && fullpath[posLastDot - 1] == _T(']'))) ) - { - // dot may be (and commonly -- at least under Unix -- is) the first - // character of the filename, don't treat the entire filename as - // extension in this case - posLastDot = wxString::npos; - } + { + // dot may be (and commonly -- at least under Unix -- is) the first + // character of the filename, don't treat the entire filename as + // extension in this case + posLastDot = wxString::npos; + } // if we do have a dot and a slash, check that the dot is in the name part if ( (posLastDot != wxString::npos) && -- 2.45.2