OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [Utils/] [win32/] [FileName.cpp] - Blame information for rev 790

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// ####ECOSHOSTGPLCOPYRIGHTBEGIN####                                        
2
// -------------------------------------------                              
3
// This file is part of the eCos host tools.                                
4
// Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.            
5
//
6
// This program is free software; you can redistribute it and/or modify     
7
// it under the terms of the GNU General Public License as published by     
8
// the Free Software Foundation; either version 2 or (at your option) any   
9
// later version.                                                           
10
//
11
// This program is distributed in the hope that it will be useful, but      
12
// WITHOUT ANY WARRANTY; without even the implied warranty of               
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
14
// General Public License for more details.                                 
15
//
16
// You should have received a copy of the GNU General Public License        
17
// along with this program; if not, write to the                            
18
// Free Software Foundation, Inc., 51 Franklin Street,                      
19
// Fifth Floor, Boston, MA  02110-1301, USA.                                
20
// -------------------------------------------                              
21
// ####ECOSHOSTGPLCOPYRIGHTEND####                                          
22
#include "stdafx.h"
23
#include "FileName.h"
24
#include <shlwapi.h>
25
 
26
const TCHAR CFileName::cSep=_TCHAR('\\');
27
 
28
CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2):
29
CString(psz1)
30
{
31
  Normalize();
32
  operator+=(psz2);
33
}
34
 
35
CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3):
36
CString(psz1)
37
{
38
  Normalize();
39
  operator+=(psz2);
40
  operator+=(psz3);
41
}
42
 
43
CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3,LPCTSTR psz4):
44
CString(psz1)
45
{
46
  Normalize();
47
  operator+=(psz2);
48
  operator+=(psz3);
49
  operator+=(psz4);
50
}
51
 
52
CFileName::CFileName(LPCTSTR psz1,LPCTSTR psz2,LPCTSTR psz3,LPCTSTR psz4,LPCTSTR psz5):
53
CString(psz1)
54
{
55
  operator+=(psz2);
56
  operator+=(psz3);
57
  operator+=(psz4);
58
  operator+=(psz5);
59
}
60
 
61
CFileName AFXAPI operator+(const CFileName& string1, const CFileName& string2)
62
{
63
  CFileName s;
64
  s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
65
    string2.GetData()->nDataLength, string2.m_pchData);
66
  return s;
67
}
68
 
69
CFileName AFXAPI operator+(const CFileName& string, LPCTSTR lpsz)
70
{
71
  ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
72
  CFileName s;
73
  s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData,
74
    CFileName::SafeStrlen(lpsz), lpsz);
75
  return s;
76
}
77
 
78
CFileName AFXAPI operator+(LPCTSTR lpsz, const CFileName& string)
79
{
80
  ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
81
  CFileName s;
82
  s.ConcatCopy(CFileName::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength,
83
    string.m_pchData);
84
  return s;
85
}
86
 
87
CFileName AFXAPI operator+(const CFileName& string1, TCHAR ch)
88
{
89
  CFileName s;
90
  s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
91
  return s;
92
}
93
 
94
CFileName AFXAPI operator+(TCHAR ch, const CFileName& string)
95
{
96
  CFileName s;
97
  s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
98
  return s;
99
}
100
 
101
const CFileName& CFileName::operator+=(LPCTSTR lpsz)
102
{
103
  ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
104
  ConcatInPlace(SafeStrlen(lpsz), lpsz);
105
  return *this;
106
}
107
 
108
const CFileName& CFileName::operator+=(TCHAR ch)
109
{
110
  ConcatInPlace(1, &ch);
111
  return *this;
112
}
113
 
114
const CFileName& CFileName::operator+=(const CFileName& string)
115
{
116
  ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
117
  return *this;
118
}
119
 
120
void CFileName::ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData)
121
{
122
  if(nSrcLen>0){
123
    if(GetLength()>0){
124
      // Appending a single separator to a non-null string is a no-op
125
      if(1==nSrcLen && cSep==*lpszSrcData){
126
        return;
127
      }
128
      // Count the intervening separators
129
      int n=(cSep==m_pchData[GetLength()-1])+(cSep==*lpszSrcData);
130
      switch(n){
131
      case 0:
132
        CString::ConcatInPlace(1, &cSep);
133
        break;
134
      case 1:
135
        break;
136
      case 2:
137
        lpszSrcData++;
138
        nSrcLen--;
139
        break;
140
      }
141
    }
142
    CString::ConcatInPlace(nSrcLen, lpszSrcData);
143
  }
144
}
145
 
146
void CFileName::ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data,
147
                           int nSrc2Len, LPCTSTR lpszSrc2Data)
148
{
149
  int n=1;
150
  int nNewLen = nSrc1Len + nSrc2Len;
151
  if(nSrc1Len>0){
152
    if(1==nSrc2Len && cSep==*lpszSrc2Data){
153
      // Appending a single separator to a non-null string is a no-op
154
      lpszSrc2Data++;
155
      nSrc2Len--;
156
      nNewLen--;
157
    } else {
158
      // Count the intervening separators
159
      n=(cSep==lpszSrc1Data[nSrc1Len-1])+(cSep==*lpszSrc2Data);
160
 
161
      switch(n){
162
      case 0:
163
        nNewLen++;
164
        break;
165
      case 1:
166
        break;
167
      case 2:
168
        lpszSrc2Data++;
169
        nSrc2Len--;
170
        nNewLen--;
171
        break;
172
      }
173
    }
174
  }
175
  if (nNewLen != 0)
176
  {
177
    AllocBuffer(nNewLen);
178
    memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(TCHAR));
179
    LPTSTR p=m_pchData+nSrc1Len;
180
    if(0==n){
181
      *p++=cSep;
182
    }
183
    memcpy(p, lpszSrc2Data, nSrc2Len*sizeof(TCHAR));
184
  }
185
}
186
 
187
void CFileName::Normalize()
188
{
189
  // Remove any trailing slash
190
  int &n=GetData()->nDataLength;
191
  if(n>1 && (cSep==m_pchData[n-1])){
192
    n--;
193
    m_pchData[n] = _TCHAR('\0');
194
  }
195
}
196
 
197
 
198
const CFileName CFileName::FullName() const
199
{
200
  PTCHAR pFile;
201
  DWORD dwSize=::GetFullPathName (*this, 0, NULL, &pFile);
202
  if(dwSize>0){
203
    CString strCopy;
204
    ::GetFullPathName (*this, 1+dwSize, strCopy.GetBuffer(1+dwSize), &pFile);
205
    strCopy.ReleaseBuffer();
206
    return strCopy;
207
  } else {
208
    return *this;
209
  }
210
}
211
 
212
const CFileName CFileName::ShortName() const
213
{
214
  DWORD dwSize=::GetShortPathName (*this, NULL, 0);
215
  if(dwSize>0){
216
    CString strCopy;
217
    ::GetShortPathName (*this, strCopy.GetBuffer(1+dwSize), 1+dwSize);
218
    strCopy.ReleaseBuffer();
219
    return strCopy;
220
  } else {
221
    return *this;
222
  }
223
}
224
 
225
const CFileName CFileName::NoSpaceName() const// sans spaces
226
{
227
  CStringArray ar1,ar2;
228
  const CString str2(ShortName());
229
 
230
  LPCTSTR pc,pcStart;
231
 
232
  pcStart=*this;
233
  for(pc=*this;*pc;pc++){
234
    if(_TCHAR('\\')==*pc){
235
      ar1.Add(CString(pcStart,pc-pcStart));
236
      pcStart=pc;
237
    }
238
  }
239
  ar1.Add(CString(pcStart,pc-pcStart));
240
 
241
  pcStart=str2;
242
  for(pc=str2;*pc;pc++){
243
    if(_TCHAR('\\')==*pc){
244
      ar2.Add(CString(pcStart,pc-pcStart));
245
      pcStart=pc;
246
    }
247
  }
248
  ar2.Add(CString(pcStart,pc-pcStart));
249
 
250
  ASSERT(ar1.GetSize()==ar2.GetSize());
251
 
252
  CString rc;
253
  for(int i=0;i<ar1.GetSize();i++){
254
    rc+=(-1==ar1[i].Find(_TCHAR(' ')))?ar1[i]:ar2[i];
255
  }
256
  return rc;
257
}
258
 
259
//
260
const CFileName CFileName::Tail() const
261
{
262
  TCHAR *ch=_tcsrchr(m_pchData,cSep);
263
  return ch?ch+1:m_pchData;
264
}
265
 
266
const CFileName CFileName::Head() const
267
{
268
  TCHAR *ch=_tcsrchr(m_pchData,cSep);
269
  return ch?CFileName(m_pchData,ch-m_pchData):m_pchData;
270
}
271
 
272
// GetFileAttributes is not available in Win95 so we test the water first
273
FILETIME CFileName::LastModificationTime() const
274
{
275
  static HINSTANCE hInst=LoadLibrary(_T("kernel32.dll"));
276
  ASSERT(hInst);
277
 
278
#ifdef _UNICODE
279
#define GETFILEATTRIBUTESNAME "GetFileAttributesExW"
280
#else
281
#define GETFILEATTRIBUTESNAME "GetFileAttributesExA"
282
#endif // !UNICODE
283
 
284
  typedef BOOL (WINAPI *GetFileAttributesP)(LPCTSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
285
 
286
  static GetFileAttributesP p=(GetFileAttributesP)GetProcAddress(hInst,GETFILEATTRIBUTESNAME);
287
  if(p){
288
    WIN32_FILE_ATTRIBUTE_DATA data;
289
 
290
    if((*p)(*this, GetFileExInfoStandard, (LPVOID)&data)){
291
      return data.ftLastWriteTime;
292
    }
293
  } else {
294
    HANDLE h=CreateFile(*this,0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
295
    FILETIME ft;
296
    if(INVALID_HANDLE_VALUE!=h){
297
      BOOL b=::GetFileTime(h,NULL,NULL,&ft);
298
      ::CloseHandle(h);
299
      if(b){
300
        return ft;
301
      }
302
    }
303
  }
304
  static FILETIME ftNull={0,0};
305
  return ftNull;
306
}
307
 
308
bool CFileName::SetFileAttributes(DWORD dwFileAttributes) const
309
{
310
  return ::SetFileAttributes (*this, dwFileAttributes)!=0;
311
}
312
 
313
bool CFileName::SameFile(const CFileName &o) const
314
{
315
  return 0==ShortName().CompareNoCase(o.ShortName());
316
}
317
 
318
CFileName CFileName::ExpandEnvironmentStrings(LPCTSTR psz)
319
{
320
  // First call simply determines the size
321
  CFileName f;
322
  DWORD dwSize=::ExpandEnvironmentStrings(psz, NULL, 0);
323
  if(dwSize>0){
324
    ::ExpandEnvironmentStrings(psz, f.GetBuffer(dwSize), dwSize);
325
    f.ReleaseBuffer();
326
  } else {
327
    f=psz;
328
  }
329
  return f;
330
}
331
 
332
const CFileName& CFileName::ExpandEnvironmentStrings()
333
{
334
  *this=CFileName::ExpandEnvironmentStrings(*this);
335
  return *this;
336
}
337
 
338
// Helper for Relative()  psz is in full format.
339
CFileName CFileName::Drive(LPCTSTR psz)
340
{
341
  if(_istalpha(psz[0])){
342
    return psz[0];
343
  } else if(cSep==psz[0]&&cSep==psz[1]){
344
    TCHAR *c=_tcschr(psz+2,cSep);
345
    if(c){
346
      c=_tcschr(c+1,cSep);
347
      if(c){
348
        return CString(psz,c-psz);
349
      }
350
    }
351
  }
352
  return _T("");
353
}
354
 
355
CFileName CFileName::Relative(LPCTSTR compare,LPCTSTR current)
356
{
357
  CString rc;
358
  bool b=(TRUE==PathRelativePathTo(rc.GetBuffer(1+MAX_PATH),current,FILE_ATTRIBUTE_DIRECTORY,compare,0));
359
  rc.ReleaseBuffer();
360
  //TRACE(_T("compare=%s current=%s result=%s (b=%d)\n"),compare,current,b?rc:compare,b);
361
  return b?rc:compare;
362
}
363
 
364
const CFileName& CFileName::MakeRelative(LPCTSTR pszRelativeTo)
365
{
366
  *this=CFileName::Relative(*this,pszRelativeTo);
367
  return *this;
368
}
369
 
370
 
371
CFileName CFileName::GetCurrentDirectory()
372
{
373
  CFileName f;
374
  ::GetCurrentDirectory(1+_MAX_PATH,f.GetBuffer(1+_MAX_PATH));
375
  f.ReleaseBuffer();
376
  f.Normalize();
377
  return f;
378
}
379
 
380
 
381
const CFileName& CFileName::Append(LPCTSTR lpsz)
382
{
383
  ASSERT(lpsz == NULL || AfxIsValidString(lpsz));
384
  CString::ConcatInPlace(SafeStrlen(lpsz), lpsz);
385
  return *this;
386
 
387
}
388
 
389
const CFileName& CFileName::Append(TCHAR ch)
390
{
391
  ConcatInPlace(1, &ch);
392
  return *this;
393
}
394
 
395
bool CFileName::IsAbsolute() const
396
{
397
  int nLength=GetLength();
398
  LPCTSTR psz=*this;
399
  return
400
    (nLength>0 && (cSep==psz[0]))|| // starts with '\'
401
    (nLength>1 && (
402
    (_istalpha(psz[0]) && _TCHAR(':')==psz[1]) ||  // starts with [e.g.] "c:\"
403
    (cSep==psz[0] && cSep==psz[1])));              // UNC
404
}
405
 
406
// Return an array of filename pieces.  Plugs '\0's into 'this', which
407
// is therefore subsequently only usable as referenced by the returned array.
408
LPCTSTR *CFileName::Chop()
409
{
410
  TCHAR *c;
411
  // Count the separators
412
  int nSeps=0;
413
  for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){
414
    nSeps++;
415
  }
416
  LPCTSTR *ar=new LPCTSTR[2+nSeps]; // +1 for first, +1 for terminating 0
417
  ar[0]=m_pchData;
418
  int i=1;
419
  for(c=_tcschr(m_pchData,cSep);c;c=_tcschr(c+1,cSep)){
420
    ar[i++]=c+1;
421
    *c=_TCHAR('\0');
422
  }
423
  ar[i]=0;
424
  return ar;
425
}
426
 
427
CFileName CFileName::GetTempPath()
428
{
429
  CFileName f;
430
  ::GetTempPath(1+_MAX_PATH,f.GetBuffer(1+_MAX_PATH));
431
  f.ReleaseBuffer();
432
  f.Normalize();
433
  return f;
434
 
435
}
436
 
437
const CFileName CFileName::CygPath () const
438
{
439
  TCHAR buf[2+MAX_PATH];
440
  LPCTSTR rc=buf+1;
441
  if(!GetShortPathName(m_pchData,1+buf,MAX_PATH)){
442
    _tcscpy(1+buf,m_pchData);
443
  }
444
  if(_istalpha(*rc)&&_TCHAR(':')==rc[1]){
445
    // Convert c:\ to //c/ [this is the bit that requires the first char of buf]
446
    buf[0]=_TCHAR('/');
447
    buf[2]=buf[1];
448
    buf[1]=_TCHAR('/');
449
    rc=buf;
450
  }
451
  for(TCHAR *c=buf+1;*c;c++){
452
    if(_TCHAR('\\')==*c){
453
      *c=_TCHAR('/');
454
    }
455
  }
456
 
457
  return rc;
458
}
459
 
460
bool CFileName::CreateDirectory(bool bParentsToo,bool bFailIfAlreadyExists) const
461
{
462
  LPCTSTR pszDir=m_pchData;
463
  if(bParentsToo){
464
    // Create intermediate directories
465
    for(LPCTSTR c=_tcschr(pszDir,_TCHAR('\\'));c;c=_tcschr(c+1,_TCHAR('\\'))){
466
      if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){
467
        continue; // don't attempt to create "C:"
468
      }
469
      const CFileName strDir(pszDir,c-pszDir);
470
      if(!(strDir.IsDir()? (!bFailIfAlreadyExists) : ::CreateDirectory(strDir,NULL))){
471
        return false;
472
      }
473
    }
474
  }
475
  return IsDir()? (!bFailIfAlreadyExists) : (TRUE==::CreateDirectory(pszDir,NULL));
476
}
477
 
478
 
479
const CString CFileName::Extension() const
480
{
481
  LPCTSTR ch=_tcsrchr(m_pchData,_TCHAR('.'));
482
  if(ch && !_tcschr(ch,cSep)){
483
    return CString(ch+1);
484
  } else {
485
    return _T("");
486
  }
487
}
488
 
489
const CString CFileName::Root() const
490
{
491
  LPCTSTR ch=_tcsrchr(m_pchData,_TCHAR('.'));
492
  if(ch && !_tcschr(ch,cSep)){
493
    return CString(m_pchData,ch-m_pchData);
494
  } else {
495
    return m_pchData;
496
  }
497
}
498
 
499
CFileName CFileName::SetCurrentDirectory(LPCTSTR pszDir)
500
{
501
  const CFileName strPwd=GetCurrentDirectory();
502
  return ::SetCurrentDirectory(pszDir)?strPwd:_T("");
503
}
504
 
505
bool CFileName::RecursivelyDelete()
506
{
507
  CFileNameArray ar;
508
  for(int i=FindFiles(*this,ar)-1;i>=0;--i){
509
    ::DeleteFile(ar[i]);
510
  }
511
  for(i=FindFiles(*this,ar,_T("*.*"),true,0)-1;i>=0;--i){
512
    ::RemoveDirectory(ar[i]);
513
  }
514
  return TRUE==::RemoveDirectory(*this);
515
}
516
 
517
int CFileName::FindFiles (LPCTSTR pszDir,CFileNameArray &ar,LPCTSTR pszPattern/*=_T("*.*")*/,bool bRecurse/*=true*/,DWORD dwExclude/*=FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN*/)
518
{
519
  ar.RemoveAll();
520
  CFileFind finder;
521
  BOOL bMore=finder.FindFile(CFileName(pszDir)+pszPattern);
522
  while (bMore)    {
523
    bMore = finder.FindNextFile();
524
    if(!finder.IsDots() && !finder.MatchesMask(dwExclude)){
525
      CFileName strFile(finder.GetFilePath());
526
      ar.Add(strFile);
527
    }
528
  }
529
  if(bRecurse){
530
    CFileFind finder;
531
    BOOL bMore=finder.FindFile(CFileName(pszDir)+_T("*.*"));
532
    while (bMore)    {
533
      bMore = finder.FindNextFile();
534
      if(!finder.IsDots() && finder.IsDirectory()){
535
        CFileNameArray ar2;
536
        FindFiles(finder.GetFilePath(),ar2,pszPattern,bRecurse,dwExclude);
537
        ar.Append(ar2);
538
      }
539
    }
540
  }
541
  return ar.GetSize();
542
}
543
 
544
void CFileName::ReplaceExtension(LPCTSTR pszNewExt)
545
{
546
  ASSERT(pszNewExt);
547
  if(_TCHAR('.')==*pszNewExt){
548
    // Be tolerant of whether '.' is included in what we are passed:
549
    pszNewExt++;
550
  }
551
  LPTSTR pch=GetBuffer(2+GetLength()+_tcslen(pszNewExt));
552
  LPTSTR pcExt=_tcsrchr(pch,_TCHAR('.'));
553
  if(NULL==pcExt || _tcschr(pcExt,cSep)){
554
    // No existing extension
555
    pcExt=pch+GetLength();
556
    *pcExt++=_TCHAR('.');
557
  }
558
  _tcscpy(pcExt+1,pszNewExt);
559
  ReleaseBuffer();
560
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.