diff --git a/cmFileSys.c b/cmFileSys.c index 9cd8147..9a96583 100644 --- a/cmFileSys.c +++ b/cmFileSys.c @@ -7,6 +7,7 @@ #include "cmMallocDebug.h" #include "cmLinkedHeap.h" #include "cmFileSys.h" +#include "cmText.h" #include #include @@ -467,6 +468,45 @@ void cmFileSysFreeFn( cmFileSysH_t h, const cmChar_t* fn ) cmLHeapFree(p->heapH, (void*)fn); } +cmFsRC_t cmFileSysGenFn( cmFileSysH_t h, const cmChar_t* dir, const cmChar_t* prefixStr, const cmChar_t* extStr, const cmChar_t** fnPtr ) +{ + cmFsRC_t rc = kOkFsRC; + cmFs_t* p = _cmFileSysHandleToPtr(h); + unsigned maxAttemptCnt = 0xffff; + + *fnPtr = NULL; + + assert(dir != NULL); + + if( prefixStr == NULL ) + prefixStr = ""; + + if( extStr == NULL ) + extStr = ""; + + if( !cmFileSysIsDir(h,dir) ) + return cmErrMsg(&p->err,kOpenDirFailFsRC,"File name generation failed because the directory '%s' does not exist.",cmStringNullGuard(dir)); + + unsigned i; + for(i=0; *fnPtr==NULL; ++i) + { + cmChar_t* fn = cmTsPrintfP(NULL,"%s%i",prefixStr,i); + + const cmChar_t* path = cmFileSysMakeFn(h,dir,fn,extStr,NULL ); + + if( !cmFileSysIsFile(h,path) ) + *fnPtr = cmMemAllocStr(path); + + cmFileSysFreeFn(h,path); + cmMemFree(fn); + + if( i == maxAttemptCnt ) + return cmErrMsg(&p->err,kGenFileFailFsRC,"File name generation failed because a suitable file name could not be found after %i attempts.",maxAttemptCnt); + }; + + return rc; +} + cmFsRC_t cmFileSysMkDir( cmFileSysH_t h, const cmChar_t* dir ) { cmFs_t* p = _cmFileSysHandleToPtr(h); @@ -1113,6 +1153,9 @@ const cmChar_t* cmFsMakeFn( const cmChar_t* dirPrefix, const cmChar_t* fn, void cmFsFreeFn( const cmChar_t* fn ) { cmFileSysFreeFn(_cmFsH, fn); } +cmFsRC_t cmFsGenFn( const cmChar_t* dir, const cmChar_t* prefixStr, const cmChar_t* extStr, const cmChar_t** fnPtr ) +{ return cmFileSysGenFn(_cmFsH,dir,prefixStr,extStr,fnPtr); } + cmFsRC_t cmFsMkDir( const cmChar_t* dir ) { return cmFileSysMkDir(_cmFsH,dir); } diff --git a/cmFileSys.h b/cmFileSys.h index 71488c7..e67dca9 100644 --- a/cmFileSys.h +++ b/cmFileSys.h @@ -34,7 +34,8 @@ extern "C" { kSysErrFsRC, kOsxFailFsRC, kLinuxFailFsRC, - kInvalidDirFsRC + kInvalidDirFsRC, + kGenFileFailFsRC }; @@ -89,6 +90,12 @@ extern "C" { // Release the file name created through an earlier call to cmFileSysMakeFn(). void cmFileSysFreeFn( cmFileSysH_t h, const cmChar_t* fn ); + // Generate an unused filename in the directory 'dir' beginning with the prefix 'prefixStr'. + // The returned file name will have the format: /nnnn. where + // nnn represents 1 or more digits. The returned string must be released with a + // call to cmMemFree(). + cmFsRC_t cmFileSysGenFn( cmFileSysH_t h, const cmChar_t* dir, const cmChar_t* prefixStr, const cmChar_t* extStr, const cmChar_t** fnPtr ); + // Create a directory - where the entire path already exists except for the // final directory. cmFsRC_t cmFileSysMkDir( cmFileSysH_t h, const cmChar_t* dir ); @@ -178,6 +185,7 @@ extern "C" { // Release the memory assoicated with a cmFileSysDirEntry_t array returned from an earlier call to cmFileSysDirEntries(). void cmFileSysDirFreeEntries( cmFileSysH_t h, cmFileSysDirEntry_t* p ); + // Return the last error code generated by the file system. cmFsRC_t cmFileSysErrorCode( cmFileSysH_t h ); @@ -202,6 +210,8 @@ extern "C" { const cmChar_t* cmFsVMakeFn( const cmChar_t* dirPrefix, const cmChar_t* fn, const cmChar_t* ext, va_list vl ); const cmChar_t* cmFsMakeFn( const cmChar_t* dirPrefix, const cmChar_t* fn, const cmChar_t* ext, ... ); void cmFsFreeFn( const cmChar_t* fn ); + cmFsRC_t cmFsGenFn( const cmChar_t* dir, const cmChar_t* prefixStr, const cmChar_t* extStr, const cmChar_t** fnPtr ); + cmFsRC_t cmFsMkDir( const cmChar_t* dir ); cmFsRC_t cmFsMkDirAll( const cmChar_t* dir );