Mercurial > ecos
diff host/tools/configtool/standalone/wxwin/filename.cpp @ 160:0d0f03f76f6a
Merge from eCos master repository on 2001-06-01-18:52:13-BST
| author | jlarmour |
|---|---|
| date | Fri, 01 Jun 2001 22:16:29 +0000 |
| parents | |
| children | 42f843b391aa |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/host/tools/configtool/standalone/wxwin/filename.cpp @@ -0,0 +1,715 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### + +#ifdef __GNUG__ +#pragma implementation "filename.h" +#endif + +// Includes other headers for precompiled compilation +#include "ecpch.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "wx/filefn.h" +#include "wx/confbase.h" // For wxExpandEnvVars + +#include "filename.h" + +#ifdef __WXMSW__ +#include <direct.h> +#include <dos.h> + +#include <windows.h> +#include <shlwapi.h> + +#include "wx/msw/winundef.h" +#ifdef CreateDirectory +#undef CreateDirectory +#endif +#ifdef ExpandEnvironmentStrings +#undef ExpandEnvironmentStrings +#endif +#ifdef GetCurrentDirectory +#undef GetCurrentDirectory +#endif +#ifdef SetCurrentDirectory +#undef SetCurrentDirectory +#endif +#ifdef GetTempPath +#undef GetTempPath +#endif + +#else + +// #include <dir.h> +#endif + +#include <sys/stat.h> + +#define wxTChar wxT + +const wxChar ecFileName::cSep=wxFILE_SEP_PATH; + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); + operator+=(psz3); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3,const wxChar* psz4): +wxString(psz1) +{ + Normalize(); + operator+=(psz2); + operator+=(psz3); + operator+=(psz4); +} + +ecFileName::ecFileName(const wxChar* psz1,const wxChar* psz2,const wxChar* psz3,const wxChar* psz4,const wxChar* psz5): +wxString(psz1) +{ + operator+=(psz2); + operator+=(psz3); + operator+=(psz4); + operator+=(psz5); +} + +/* +ecFileName::~ecFileName() +{ + // Unfortunately we can't do this since GetStringData is private in wxString. + // So for now, we may memory leaks since ~wxString is not virtual. + //GetStringData()->Unlock(); +} +*/ + +ecFileName operator+(const ecFileName& string1, const ecFileName& string2) +{ + ecFileName s; + s.ConcatCopy(string1, string2); + return s; +} + +ecFileName operator+(const ecFileName& string, const wxChar* lpsz) +{ + if (lpsz == NULL) + return string; + + ecFileName s; + s.ConcatCopy(string, wxString(lpsz)); + return s; +} + +ecFileName operator+(const wxChar* lpsz, const ecFileName& string) +{ + if (lpsz == NULL) + return string; + + ecFileName s; + s.ConcatCopy(wxString(lpsz), string); + return s; +} + +ecFileName operator+(const ecFileName& string1, wxChar ch) +{ + ecFileName s; + s.ConcatCopy(string1, wxString(ch)); + return s; +} + +ecFileName operator+(wxChar ch, const ecFileName& string) +{ + ecFileName s; + s.ConcatCopy(wxString(ch), string); + return s; +} + +const ecFileName& ecFileName::operator+=(const wxChar* lpsz) +{ + if (lpsz == NULL) + return *this; + + ConcatInPlace(wxString(lpsz)); + return *this; +} + +const ecFileName& ecFileName::operator+=(wxChar ch) +{ + ConcatInPlace(wxString(ch)); + return *this; +} + +const ecFileName& ecFileName::operator+=(const ecFileName& string) +{ + ConcatInPlace(string); + return *this; +} + +void ecFileName::ConcatInPlace(const wxString& src) +{ + ConcatCopy(* this, src); +} + +void ecFileName::ConcatCopy(const wxString& src1, + const wxString& src2) +{ + int nSrc1Len = src1.Len(); + int nSrc2Len = src2.Len(); + int n=1; + int nNewLen = nSrc1Len + nSrc2Len; + if(nSrc1Len>0) + { + if(1==nSrc2Len && cSep==src2[0]) + { + // Appending a single separator to a non-null string is a no-op + return; + } else { + // Count the intervening separators + n=(cSep==src1[nSrc1Len-1])+(cSep==src2[0]); + + switch(n){ + case 0: + (*this) = src1 + wxString(cSep) + src2; + break; + case 1: + (*this) = src1 + src2; + break; + case 2: + (*this) = src1 + src2.Mid(1); + break; + } + return; + } + } +} + +void ecFileName::Normalize() +{ + // Remove any trailing seperator + int len = Len(); + if (len > 0 && (*this)[(size_t)(len - 1)] == cSep) + (*this) = Mid(0, len - 1); +} + + +const ecFileName ecFileName::FullName() const +{ +#ifdef __WXMSW__ + TCHAR* pFile; + long dwSize=::GetFullPathName (*this, 0, NULL, &pFile); + if(dwSize>0){ + wxString strCopy; + ::GetFullPathName (*this, 1+dwSize, strCopy.GetWriteBuf(1+dwSize), &pFile); + strCopy.UngetWriteBuf(); + return strCopy; + } else { + return *this; + } +#else + return wxGetCwd() + wxString(cSep) + *this; +#endif +} + +const ecFileName ecFileName::ShortName() const +{ +#ifdef __WXMSW__ + long dwSize=::GetShortPathName (*this, NULL, 0); + if(dwSize>0){ + wxString strCopy; + ::GetShortPathName (*this, strCopy.GetWriteBuf(1+dwSize), 1+dwSize); + strCopy.UngetWriteBuf(); + return strCopy; + } else { + return *this; + } +#else + return *this; +#endif +} + +const ecFileName ecFileName::NoSpaceName() const// sans spaces +{ +#ifndef __WXMSW__ + return *this; +#else + // Only replace components with spaces with FAT names. + wxArrayString ar1,ar2; + const wxString str2(ShortName()); + + size_t i,pcStart; + + unsigned int len = Len(); + pcStart = 0; + for (i = 0; i < len; i++) + { + if(wxTChar('\\')==(*this)[i]) + { + ar1.Add(this->Mid(pcStart, i - pcStart + 1)); + pcStart = i + 1; + } + } + ar1.Add(this->Mid(pcStart, i - pcStart + 1)); + + len = str2.Len(); + pcStart = 0; + for (i = 0; i < len; i++) + { + if(wxTChar('\\')==str2[i]) + { + ar2.Add(str2.Mid(pcStart, i - pcStart + 1)); + pcStart = i + 1; + } + } + ar2.Add(str2.Mid(pcStart, i - pcStart + 1)); + + wxASSERT(ar1.Count()==ar2.Count()); + + wxString rc; + for(i=0;i<ar1.Count();i++){ + rc+=(-1==ar1[i].Find(wxTChar(' ')))?ar1[i]:ar2[i]; + } + return rc; +#endif +} + +// +const ecFileName ecFileName::Tail() const +{ + return AfterLast(cSep); +} + +const ecFileName ecFileName::Head() const +{ + return BeforeLast(cSep); +} + +time_t ecFileName::LastModificationTime() const +{ + return wxFileModificationTime(* this); + +#if 0 + // GetFileAttributes is not available in Win95 so we test the water first + static HINSTANCE hInst=LoadLibrary(_T("kernel32.dll")); + wxASSERT(hInst); + +#ifdef _UNICODE +#define GETFILEATTRIBUTESNAME "GetFileAttributesExW" +#else +#define GETFILEATTRIBUTESNAME "GetFileAttributesExA" +#endif // !UNICODE + + typedef BOOL (WINAPI *GetFileAttributesP)(const wxChar*,GET_FILEEX_INFO_LEVELS,LPVOID); + + static GetFileAttributesP p=(GetFileAttributesP)GetProcAddress(hInst,GETFILEATTRIBUTESNAME); + if(p){ + WIN32_FILE_ATTRIBUTE_DATA data; + + if((*p)(*this, GetFileExInfoStandard, (LPVOID)&data)){ + return data.ftLastWriteTime; + } + } else { + HANDLE h=CreateFile(*this,0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + FILETIME ft; + if(INVALID_HANDLE_VALUE!=h){ + BOOL b=::GetFileTime(h,NULL,NULL,&ft); + ::CloseHandle(h); + if(b){ + return ft; + } + } + } + static FILETIME ftNull={0,0}; + return ftNull; +#endif +} + +/* TODO +bool ecFileName::SetFileAttributes(long dwFileAttributes) const +{ +return ::SetFileAttributes (*this, dwFileAttributes)!=0; +} +*/ + +bool ecFileName::Exists () const +{ + return IsFile() || IsDir() ; +} + +bool ecFileName::IsDir () const +{ + return wxPathExists(* this); +} + +bool ecFileName::IsFile () const +{ +#if defined(__WXMAC__) + struct stat stbuf; + if (filename && stat (wxUnix2MacFilename(filename), &stbuf) == 0 ) + return TRUE; + return FALSE ; +#else + wxStructStat st; + if ((*this) != wxT("") && wxStat (wxFNSTRINGCAST fn_str(), &st) == 0 && (st.st_mode & S_IFREG)) + return TRUE; + + return FALSE; +#endif +} + +bool ecFileName::IsReadOnly () const +{ +#ifdef __WXMSW__ + long a=GetFileAttributes(* this); return 0xFFFFFFFF!=a && (0!=(a&FILE_ATTRIBUTE_READONLY )); +#else + wxFAIL_MSG("ecFileName::IsReadOnly not supported on this platform."); + return FALSE; +#endif +} + +bool ecFileName::SameFile(const ecFileName &o) const +{ +#ifdef __WXMSW__ + return 0==ShortName().CmpNoCase(o.ShortName()); +#else + // On most other platforms, case is important. + return o == (*this); +#endif +} + +ecFileName ecFileName::ExpandEnvironmentStrings(const wxChar* psz) +{ + // wxExpandEnvVars is from confbase.h + + ecFileName f = wxExpandEnvVars(psz); + return f; +} + +const ecFileName& ecFileName::ExpandEnvironmentStrings() +{ + *this=ecFileName::ExpandEnvironmentStrings(*this); + return *this; +} + +#if 0 +// Helper for Relative() psz is in full format. +ecFileName ecFileName::Drive(const wxChar* psz) +{ + if(wxIsalpha(psz[0])){ + return psz[0]; + } else if(cSep==psz[0]&&cSep==psz[1]){ + wxChar *c=_tcschr(psz+2,cSep); + if(c){ + c=_tcschr(c+1,cSep); + if(c){ + return wxString(psz,c-psz); + } + } + } + return _T(""); +} +#endif + +ecFileName ecFileName::Relative(const wxChar* compare,const wxChar* current) +{ +#ifdef __WXMSW__ + wxString rc; + bool b=(TRUE==PathRelativePathTo(rc.GetWriteBuf(1+MAX_PATH),current,FILE_ATTRIBUTE_DIRECTORY,compare,0)); + rc.UngetWriteBuf(); + return b?rc:compare; +#else + wxFAIL_MSG("ecFileName::Relative not implemented on this platform."); + return ecFileName(); +#endif +} + +const ecFileName& ecFileName::MakeRelative(const wxChar* pszRelativeTo) +{ + *this=ecFileName::Relative(*this,pszRelativeTo); + return *this; +} + + +ecFileName ecFileName::GetCurrentDirectory() +{ + ecFileName f; + f = wxGetCwd(); + f.Normalize(); + + return f; +} + + +const ecFileName& ecFileName::Append(const wxChar* lpsz) +{ + if (lpsz) + return *this; + + //wxString::ConcatInPlace(lpsz); + wxString::Append(lpsz); + return *this; + +} + +const ecFileName& ecFileName::Append(wxChar ch) +{ + ConcatInPlace(wxString(ch)); + return *this; +} + +bool ecFileName::IsAbsolute() const +{ + int nLength=Len(); + const wxString& psz=*this; + return + (nLength>0 && (cSep==psz[0]))|| // starts with '\' + (nLength>1 && ( + (wxIsalpha(psz[0]) && wxTChar(':')==psz[1]) || // starts with [e.g.] "c:\" + (cSep==psz[0] && cSep==psz[1]))); // UNC +} + +// TODO (?) +#if 0 +// Return an array of filename pieces. Plugs '\0's into 'this', which +// is therefore subsequently only usable as referenced by the returned array. +const wxChar* *ecFileName::Chop() +{ + wxChar *c; + // Count the separators + int nSeps=0; + for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ + nSeps++; + } + const wxChar* *ar=new const wxChar*[2+nSeps]; // +1 for first, +1 for terminating 0 + ar[0]=m_pchData; + int i=1; + for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){ + ar[i++]=c+1; + *c=wxTChar('\0'); + } + ar[i]=0; + return ar; +} +#endif + +ecFileName ecFileName::GetTempPath() +{ + ecFileName f; +#ifdef __WXMSW__ +#ifdef _UNICODE + ::GetTempPathW(1+_MAX_PATH,f.GetWriteBuf(1+_MAX_PATH)); +#else + ::GetTempPathA(1+_MAX_PATH,f.GetWriteBuf(1+_MAX_PATH)); +#endif + f.UngetWriteBuf(); +#elif defined(__WXGTK__) +#else + wxFAIL("ecFileName::GetTempPath() not implemented on this platform."); +#endif + f.Normalize(); + return f; +} + +const ecFileName ecFileName::CygPath () const +{ +#ifdef __WXMSW__ + ecFileName rc = ShortName(); + if(wxIsalpha(rc[(size_t)0]) && wxTChar(':')==rc[(size_t)1]) + { + // Convert c:\ to //c/ + wxString s = wxString(wxT("//")) + wxString(rc[(size_t)0]) + rc.Mid(2); + rc = s; + } + size_t i; + for (i = 0; i < rc.Len(); i++) + { + if (rc[i] == wxTChar('\\')) + rc[i] = wxTChar('/'); + } +#else + const ecFileName& rc = * this; +#endif + + return rc; +} + +bool ecFileName::CreateDirectory(bool bParentsToo,bool bFailIfAlreadyExists) const +{ + if(bParentsToo) + { + // Create intermediate directories + + // 'rest' will progressively have its separators replaced by underscores in order + // to find the next separator + wxString rest = * this; + size_t lastPos = 0; + int len = rest.Len(); + while (lastPos != -1) + { + lastPos = rest.Find(cSep); + if (lastPos != -1 && lastPos >= 0) + { + rest[lastPos] = wxT('_'); // So we find the NEXT separator + + // don't attempt to create "C: or /" + if (lastPos > 0 && (*this)[lastPos-1] == wxT(':')) + continue; + else if (lastPos == 0) + continue; + } + + // Fail if any of the dirs exist already + wxString str(this->Mid(0, lastPos)); + bool alreadyExists = wxDirExists(str); + if (alreadyExists && bFailIfAlreadyExists) + return FALSE; + + if (!alreadyExists) + if (!wxMkdir(str)) + return FALSE; + } + } + + + return IsDir()? (!bFailIfAlreadyExists) : (TRUE==wxMkdir(*this)); +} + + +const wxString ecFileName::Extension() const +{ + wxString path, name, ext; + + wxSplitPath(*this, & path, & name, & ext); + return ext; +} + +const wxString ecFileName::Root() const +{ + return wxPathOnly(*this); +} + +ecFileName ecFileName::SetCurrentDirectory(const wxChar* pszDir) +{ + const ecFileName strPwd=wxGetCwd(); + if (::wxSetWorkingDirectory(pszDir)) + return strPwd; + else + return wxT(""); +} + +bool ecFileName::RecursivelyDelete() +{ + wxArrayString ar; + int i; + for(i=FindFiles(*this,ar)-1;i>=0;--i){ + wxRemoveFile(ar[i]); + } + for(i=FindFiles(*this,ar,wxT("*.*"),TRUE,0)-1;i>=0;--i){ + wxRmdir(ar[i]); + } + return TRUE==wxRmdir(*this); +} + +// TODO: take account of dwExclude +int ecFileName::FindFiles (const wxString& pszDir,wxArrayString &ar,const wxString& pszPattern/*=wxT("*.*")*/,bool bRecurse/*=TRUE*/,long dwExclude/*=wxDIR_DIRS|wxDIR_HIDDEN*/) +{ + ar.Clear(); + + // Scoping for wxDir + { + wxDir dir(pszDir); + + wxString fileName; + bool bMore = dir.GetFirst(& fileName, pszPattern, wxDIR_FILES); + while (bMore) + { + if (fileName != wxT(".") && fileName != wxT("..")) + { + // Add full path + ecFileName path(pszDir); + path += (const wxChar*) fileName; + ar.Add(path); + } + bMore = dir.GetNext(& fileName); + } + } + + if (bRecurse) + { + // Since wxDir isn't rentrant, we need to gather all the directories + // first + wxArrayString ar2; + + // Scoping + { + wxDir dir(pszDir); + + wxString fileName; + + bool bMore = dir.GetFirst(& fileName, wxT("*"), wxDIR_DIRS); + while (bMore) + { + if (fileName != wxT(".") && fileName != wxT("..")) + { + // Add full path + ecFileName path(pszDir); + path += (const wxChar*) fileName; + ar2.Add(path); + } + bMore = dir.GetNext(& fileName); + } + } + + unsigned int i; + for (i = 0; i < ar2.Count(); i++) + { + wxString f(ar2[i]); + FindFiles(f, ar, pszPattern, bRecurse, dwExclude); + } + } + + return ar.Count(); +} + +void ecFileName::ReplaceExtension(const wxString& newExt) +{ + wxString ext = newExt; + if (ext[0] == wxT('.')) + ext = ext.Mid(1); + + wxStripExtension(* this); + this->wxString::Append(wxT(".")); + this->wxString::Append(ext); +}
