Преглед на файлове

cmFile.h/c : Added cmFileCopy() and cmFileBackup().

master
kevin преди 10 години
родител
ревизия
92a9b18f44
променени са 2 файла, в които са добавени 175 реда и са изтрити 24 реда
  1. 150
    23
      cmFile.c
  2. 25
    1
      cmFile.h

+ 150
- 23
cmFile.c Целия файл

2
 #include "cmGlobal.h"
2
 #include "cmGlobal.h"
3
 #include "cmRpt.h"
3
 #include "cmRpt.h"
4
 #include "cmErr.h"
4
 #include "cmErr.h"
5
+#include "cmCtx.h"
5
 #include "cmFile.h"
6
 #include "cmFile.h"
7
+#include "cmFileSys.h"
6
 #include "cmMem.h"
8
 #include "cmMem.h"
7
 #include "cmMallocDebug.h"
9
 #include "cmMallocDebug.h"
10
+#include "cmLinkedHeap.h"
11
+#include "cmText.h"
8
 #include <sys/stat.h>
12
 #include <sys/stat.h>
9
 cmFileH_t cmFileNullHandle = { NULL };
13
 cmFileH_t cmFileNullHandle = { NULL };
10
 
14
 
34
 
38
 
35
 cmFileRC_t cmFileOpen(    cmFileH_t* hp, const cmChar_t* fn, enum cmFileOpenFlags_t flags, cmRpt_t* rpt )
39
 cmFileRC_t cmFileOpen(    cmFileH_t* hp, const cmChar_t* fn, enum cmFileOpenFlags_t flags, cmRpt_t* rpt )
36
 {
40
 {
37
-  char mode[] = "/0/0/0";
38
-  cmFile_t* p = NULL;
39
-  cmErr_t err;
41
+  char mode[]  = "/0/0/0";
42
+  cmFile_t*  p = NULL;
43
+  cmErr_t    err;
40
   cmFileRC_t rc;
44
   cmFileRC_t rc;
41
 
45
 
42
   if((rc = cmFileClose(hp)) != kOkFileRC )
46
   if((rc = cmFileClose(hp)) != kOkFileRC )
47
   hp->h = NULL;
51
   hp->h = NULL;
48
 
52
 
49
   if( cmIsFlag(flags,kReadFileFl) )
53
   if( cmIsFlag(flags,kReadFileFl) )
50
-    mode[0]='r';
54
+    mode[0] = 'r';
51
   else
55
   else
52
     if( cmIsFlag(flags,kWriteFileFl) )
56
     if( cmIsFlag(flags,kWriteFileFl) )
53
-      mode[0]='w';
57
+      mode[0] = 'w';
54
     else
58
     else
55
       if( cmIsFlag(flags,kAppendFileFl) )
59
       if( cmIsFlag(flags,kAppendFileFl) )
56
-        mode[0]='a';
60
+        mode[0] = 'a';
57
       else
61
       else
58
         cmErrMsg(&err,kInvalidFlagFileRC,"File open flags must contain 'kReadFileFl','kWriteFileFl', or 'kAppendFileFl'.");
62
         cmErrMsg(&err,kInvalidFlagFileRC,"File open flags must contain 'kReadFileFl','kWriteFileFl', or 'kAppendFileFl'.");
59
   
63
   
60
   if( cmIsFlag(flags,kUpdateFileFl) )
64
   if( cmIsFlag(flags,kUpdateFileFl) )
61
-    mode[1]='+';
65
+    mode[1] = '+';
62
 
66
 
63
   // handle requests to use stdin,stdout,stderr
67
   // handle requests to use stdin,stdout,stderr
64
-  FILE*           sfp = NULL;
68
+  FILE* sfp = NULL;
65
   if( cmIsFlag(flags,kStdoutFileFl) )
69
   if( cmIsFlag(flags,kStdoutFileFl) )
66
   {
70
   {
67
     sfp = stdout;
71
     sfp = stdout;
107
     }
111
     }
108
   }
112
   }
109
  
113
  
110
-  hp->h    = p;
114
+  hp->h = p;
111
 
115
 
112
   return kOkFileRC;
116
   return kOkFileRC;
113
 }
117
 }
158
 cmFileRC_t cmFileSeek(    cmFileH_t h, enum cmFileSeekFlags_t flags, int offsByteCnt )
162
 cmFileRC_t cmFileSeek(    cmFileH_t h, enum cmFileSeekFlags_t flags, int offsByteCnt )
159
 {
163
 {
160
   cmFile_t* p = _cmFileHandleToPtr(h);
164
   cmFile_t* p = _cmFileHandleToPtr(h);
161
-  unsigned fileflags = 0;
165
+  unsigned  fileflags = 0;
162
 
166
 
163
   if( cmIsFlag(flags,kBeginFileFl) )
167
   if( cmIsFlag(flags,kBeginFileFl) )
164
     fileflags = SEEK_SET;
168
     fileflags = SEEK_SET;
171
       else
175
       else
172
         return cmErrMsg(&p->err,kInvalidFlagFileRC,"Invalid file seek flag on '%s'.",p->fnStr);
176
         return cmErrMsg(&p->err,kInvalidFlagFileRC,"Invalid file seek flag on '%s'.",p->fnStr);
173
   
177
   
174
-  errno = 0;
178
+  errno  = 0;
175
   if( fseek(p->fp,offsByteCnt,fileflags) != 0 )
179
   if( fseek(p->fp,offsByteCnt,fileflags) != 0 )
176
     return _cmFileError(p,kSeekFailFileRC,errno,"File seek failed");
180
     return _cmFileError(p,kSeekFailFileRC,errno,"File seek failed");
177
 
181
 
181
 cmFileRC_t cmFileTell( cmFileH_t h, long* offsPtr )
185
 cmFileRC_t cmFileTell( cmFileH_t h, long* offsPtr )
182
 {
186
 {
183
   assert( offsPtr != NULL );
187
   assert( offsPtr != NULL );
184
-  *offsPtr     = -1;
185
-  cmFile_t* p  = _cmFileHandleToPtr(h);
186
-  errno        = 0;
188
+  *offsPtr    = -1;
189
+  cmFile_t* p = _cmFileHandleToPtr(h);
190
+  errno       = 0;
191
+
187
   if((*offsPtr = ftell(p->fp)) == -1)
192
   if((*offsPtr = ftell(p->fp)) == -1)
188
     return _cmFileError(p,kTellFailFileRC,errno,"File tell failed");
193
     return _cmFileError(p,kTellFailFileRC,errno,"File tell failed");
189
   return kOkFileRC;
194
   return kOkFileRC;
222
 {
227
 {
223
   assert( fileByteCntPtr != NULL );
228
   assert( fileByteCntPtr != NULL );
224
   cmFileRC_t rc;
229
   cmFileRC_t rc;
225
-  cmFileH_t h = cmFileNullHandle;
230
+  cmFileH_t  h                                 = cmFileNullHandle;
226
   if((rc = cmFileOpen(&h,fn,kReadFileFl,rpt)) != kOkFileRC )
231
   if((rc = cmFileOpen(&h,fn,kReadFileFl,rpt)) != kOkFileRC )
227
     return rc;
232
     return rc;
228
 
233
 
241
   cmFileH_t  h0         = cmFileNullHandle;
246
   cmFileH_t  h0         = cmFileNullHandle;
242
   cmFileH_t  h1         = cmFileNullHandle;
247
   cmFileH_t  h1         = cmFileNullHandle;
243
 
248
 
244
-  char       b0[ bufByteCnt ];
245
-  char       b1[ bufByteCnt ];
249
+  char b0[ bufByteCnt ];
250
+  char b1[ bufByteCnt ];
246
 
251
 
247
   assert(isEqualPtr != NULL );
252
   assert(isEqualPtr != NULL );
248
   *isEqualPtr = true;
253
   *isEqualPtr = true;
253
   if((rc = cmFileOpen(&h1,fn1,kReadFileFl,rpt)) != kOkFileRC )
258
   if((rc = cmFileOpen(&h1,fn1,kReadFileFl,rpt)) != kOkFileRC )
254
     goto errLabel;
259
     goto errLabel;
255
 
260
 
256
-  cmFile_t*   p0 = _cmFileHandleToPtr(h0);
257
-  cmFile_t*   p1 = _cmFileHandleToPtr(h1);
261
+  cmFile_t* p0 = _cmFileHandleToPtr(h0);
262
+  cmFile_t* p1 = _cmFileHandleToPtr(h1);
258
 
263
 
259
   while(1)
264
   while(1)
260
   {
265
   {
261
     size_t n0 = fread(b0,1,bufByteCnt,p0->fp);
266
     size_t n0 = fread(b0,1,bufByteCnt,p0->fp);
262
     size_t n1 = fread(b1,1,bufByteCnt,p1->fp);
267
     size_t n1 = fread(b1,1,bufByteCnt,p1->fp);
263
-    if( n0 != n1 || memcmp(b0,b1,n0)!=0 )
268
+    if( n0 != n1 || memcmp(b0,b1,n0) != 0 )
264
     {
269
     {
265
       *isEqualPtr = false;
270
       *isEqualPtr = false;
266
       break;
271
       break;
285
 
290
 
286
 cmFileRC_t cmFileFnWrite( const cmChar_t* fn, cmRpt_t* rpt, const void* buf, unsigned bufByteCnt )
291
 cmFileRC_t cmFileFnWrite( const cmChar_t* fn, cmRpt_t* rpt, const void* buf, unsigned bufByteCnt )
287
 {
292
 {
288
-  cmFileH_t h = cmFileNullHandle;
293
+  cmFileH_t  h = cmFileNullHandle;
289
   cmFileRC_t rc;
294
   cmFileRC_t rc;
290
 
295
 
291
   if((rc = cmFileOpen(&h,fn,kWriteFileFl,rpt)) != kOkFileRC )
296
   if((rc = cmFileOpen(&h,fn,kWriteFileFl,rpt)) != kOkFileRC )
305
 
310
 
306
   unsigned  n   = cmFileByteCount(h);
311
   unsigned  n   = cmFileByteCount(h);
307
   cmChar_t* buf = NULL;
312
   cmChar_t* buf = NULL;
308
-  cmFile_t*   p = _cmFileHandleToPtr(h);
313
+  cmFile_t* p   = _cmFileHandleToPtr(h);
309
  
314
  
310
 
315
 
311
   // if the file size calculation is ok
316
   // if the file size calculation is ok
346
 
351
 
347
 cmChar_t* _cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned nn, unsigned* bufByteCntPtr  )
352
 cmChar_t* _cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned nn, unsigned* bufByteCntPtr  )
348
 {
353
 {
349
-  cmFileH_t h = cmFileNullHandle;
354
+  cmFileH_t h   = cmFileNullHandle;
350
   cmChar_t* buf = NULL;
355
   cmChar_t* buf = NULL;
351
 
356
 
352
   if( cmFileOpen(&h,fn,kReadFileFl | kBinaryFileFl,rpt) != kOkFileRC )
357
   if( cmFileOpen(&h,fn,kReadFileFl | kBinaryFileFl,rpt) != kOkFileRC )
360
   return buf;
365
   return buf;
361
 }
366
 }
362
 
367
 
368
+cmFileRC_t    cmFileCopy( 
369
+    const cmChar_t* srcDir, 
370
+    const cmChar_t* srcFn, 
371
+    const cmChar_t* srcExt, 
372
+    const cmChar_t* dstDir, 
373
+    const cmChar_t* dstFn, 
374
+    const cmChar_t* dstExt,
375
+    cmErr_t*        err)
376
+{
377
+  cmFileRC_t      rc        = kOkFileRC;
378
+  unsigned        byteCnt   = 0;
379
+  cmChar_t*       buf       = NULL;
380
+  const cmChar_t* srcPathFn = NULL;
381
+  const cmChar_t* dstPathFn = NULL;
382
+
383
+  // form the source path fn
384
+  if((srcPathFn = cmFsMakeFn(srcDir,srcFn,srcExt,NULL)) == NULL )
385
+  {
386
+    rc = cmErrMsg(err,kFileSysFailFileRC,"The soure file name for dir:%s name:%s ext:%s could not be formed.",cmStringNullGuard(srcDir),cmStringNullGuard(srcFn),cmStringNullGuard(srcExt));
387
+    goto errLabel;
388
+  }
389
+
390
+  // form the dest path fn
391
+  if((dstPathFn = cmFsMakeFn(dstDir,dstFn,dstExt,NULL)) == NULL )
392
+  {
393
+    rc = cmErrMsg(err,kFileSysFailFileRC,"The destination file name for dir:%s name:%s ext:%s could not be formed.",cmStringNullGuard(dstDir),cmStringNullGuard(dstFn),cmStringNullGuard(dstExt));
394
+    goto errLabel;
395
+  }
396
+
397
+  // verify that the source exists
398
+  if( cmFsIsFile(srcPathFn) == false )
399
+  {
400
+    rc = cmErrMsg(err,kOpenFailFileRC,"The source file '%s' does not exist.",cmStringNullGuard(srcPathFn));
401
+    goto errLabel;
402
+  }
403
+
404
+  // read the source file into a buffer
405
+  if((buf = cmFileFnToBuf(srcPathFn,err->rpt,&byteCnt)) == NULL )
406
+    rc = cmErrMsg(err,kReadFailFileRC,"Attempt to fill a buffer from '%s' failed.",cmStringNullGuard(srcPathFn));
407
+  else
408
+  {
409
+    // write the file to the output file
410
+    if( cmFileFnWrite(dstPathFn,err->rpt,buf,byteCnt) != kOkFileRC )
411
+      rc = cmErrMsg(err,kWriteFailFileRC,"An attempt to write a buffer to '%s' failed.",cmStringNullGuard(dstPathFn));    
412
+  }
413
+
414
+ errLabel:
415
+  // free the buffer
416
+  cmMemFree(buf);
417
+  cmFsFreeFn(srcPathFn);
418
+  cmFsFreeFn(dstPathFn);
419
+  return rc;
420
+
421
+}
422
+
423
+cmFileRC_t cmFileBackup( const cmChar_t* dir, const cmChar_t* name, const cmChar_t* ext, cmErr_t* err )
424
+{
425
+  cmFileRC_t      rc      = kOkFileRC;
426
+  cmChar_t*       newName = NULL;
427
+  const cmChar_t* newFn   = NULL;
428
+  unsigned        n       = 0;
429
+  const cmChar_t* srcFn   = NULL;
430
+
431
+  // form the name of the backup file
432
+  if((srcFn = cmFsMakeFn(dir,name,ext,NULL)) == NULL )
433
+  {
434
+    rc = cmErrMsg(err,kFileSysFailFileRC,"Backup source file name formation failed.");
435
+    goto errLabel;
436
+  }
437
+
438
+  // if the src file does not exist then there is nothing to do
439
+  if( cmFsIsFile(srcFn) == false )
440
+    return rc;
441
+
442
+  // break the source file name up into dir/fn/ext.
443
+  cmFileSysPathPart_t* pp = NULL;
444
+  if((pp = cmFsPathParts(srcFn)) == NULL || pp->fnStr==NULL)
445
+  {
446
+    rc = cmErrMsg(err,kFileSysFailFileRC,"The file name '%s' could not be parsed into its parts.",cmStringNullGuard(srcFn));
447
+    goto errLabel;
448
+  }
449
+
450
+  // iterate until a unique file name is found
451
+  for(n=0; 1; ++n)
452
+  {
453
+    cmFsFreeFn(newFn);
454
+
455
+    // generate a new file name
456
+    newName = cmTsPrintfP(newName,"%s_%i",pp->fnStr,n);
457
+    
458
+    // form the new file name into a complete path
459
+    if((newFn = cmFsMakeFn(pp->dirStr,newName,pp->extStr,NULL)) == NULL )
460
+    {
461
+      rc = cmErrMsg(err,kFileSysFailFileRC,"A backup file name could not be formed for the file '%s'.",cmStringNullGuard(newName));
462
+      goto errLabel;
463
+    }
464
+
465
+    // if the new file name is not already in use ...
466
+    if( cmFsIsFile(newFn) == false )
467
+    {
468
+      // .. then duplicate the file
469
+      if((rc = cmFileCopy(srcFn,NULL,NULL,newFn,NULL,NULL,err)) != kOkFileRC )
470
+        rc = cmErrMsg(err,rc,"The file '%s' could not be duplicated as '%s'.",cmStringNullGuard(srcFn),cmStringNullGuard(newFn));
471
+
472
+      break;
473
+    }
474
+
475
+
476
+  }
477
+
478
+ errLabel:
479
+
480
+  cmFsFreeFn(srcFn);
481
+  cmFsFreeFn(newFn);
482
+  cmMemFree(newName);
483
+  cmFsFreePathParts(pp);
484
+
485
+  return rc;
486
+
487
+}
488
+
489
+
363
 cmChar_t*  cmFileToBuf( cmFileH_t h, unsigned* bufByteCntPtr )
490
 cmChar_t*  cmFileToBuf( cmFileH_t h, unsigned* bufByteCntPtr )
364
 { return _cmFileToBuf(h,0,bufByteCntPtr); }
491
 { return _cmFileToBuf(h,0,bufByteCntPtr); }
365
 
492
 

+ 25
- 1
cmFile.h Целия файл

27
     kHandleInvalidFileRC,
27
     kHandleInvalidFileRC,
28
     kStatFailFileRC,
28
     kStatFailFileRC,
29
     kBufAllocFailFileRC,
29
     kBufAllocFailFileRC,
30
-    kBufTooSmallFileRC
30
+    kBufTooSmallFileRC,
31
+    kFileSysFailFileRC,
32
+
31
   };
33
   };
32
 
34
 
33
   typedef unsigned   cmFileRC_t;
35
   typedef unsigned   cmFileRC_t;
116
   // Same as cmFileToBuf() but accepts a file name argument.
118
   // Same as cmFileToBuf() but accepts a file name argument.
117
   // 'rpt' is the report object to use for error reporting.
119
   // 'rpt' is the report object to use for error reporting.
118
   cmChar_t*  cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned* bufByteCntPtr );
120
   cmChar_t*  cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned* bufByteCntPtr );
121
+
122
+
123
+  // Copy the file named in srcDir/srcFn/srcExt to a file named dstDir/dstFn/dstExt.
124
+  // Note that srcExt/dstExt may be set to NULL if the file extension is included
125
+  // in srcFn/dstFn.  Likewise srcFn/dstFn may be set to NULL if the file name
126
+  // is included in srcDir/dstDir.
127
+  cmFileRC_t    cmFileCopy( 
128
+    const cmChar_t* srcDir, 
129
+    const cmChar_t* srcFn, 
130
+    const cmChar_t* srcExt, 
131
+    const cmChar_t* dstDir, 
132
+    const cmChar_t* dstFn, 
133
+    const cmChar_t* dstExt,
134
+    cmErr_t*        err);
135
+
136
+
137
+  // This function creates a backup copy of the file 'fn' by duplicating it into
138
+  // a file named fn_#.ext where # is an integer which makes the file name unique.
139
+  // The integers chosen with zero and are incremented until an
140
+  // unused file name is found in the same directory as 'fn'.
141
+  // If the file identified by 'fn' is not found then the function returns quietly.
142
+  cmFileRC_t cmFileBackup( const cmChar_t* dir, const cmChar_t* name, const cmChar_t* ext, cmErr_t* err );
119
   
143
   
120
   // Allocate and fill a zero terminated string from a file.
144
   // Allocate and fill a zero terminated string from a file.
121
   // Set *bufByteCntPtr to count of bytes read into the buffer.=
145
   // Set *bufByteCntPtr to count of bytes read into the buffer.=

Loading…
Отказ
Запис