libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmFile.c 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmFile.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include <sys/stat.h>
  9. cmFileH_t cmFileNullHandle = { NULL };
  10. typedef struct
  11. {
  12. FILE* fp;
  13. cmErr_t err;
  14. cmChar_t* fnStr;
  15. } cmFile_t;
  16. cmFile_t* _cmFileHandleToPtr( cmFileH_t h )
  17. {
  18. cmFile_t* p = (cmFile_t*)h.h;
  19. assert(p != NULL);
  20. return p;
  21. }
  22. cmFileRC_t _cmFileError( cmFile_t* p, cmFileRC_t rc, int errNumb, const cmChar_t* msg )
  23. {
  24. if(errNumb == 0)
  25. rc = cmErrMsg(&p->err,rc,"%s on file '%s'",msg,p->fnStr);
  26. else
  27. rc = cmErrMsg(&p->err,rc,"%s on file '%s'\nSystem Msg:%s",msg,p->fnStr,strerror(errNumb));
  28. return rc;
  29. }
  30. cmFileRC_t cmFileOpen( cmFileH_t* hp, const cmChar_t* fn, enum cmFileOpenFlags_t flags, cmRpt_t* rpt )
  31. {
  32. char mode[] = "/0/0/0";
  33. cmFile_t* p = NULL;
  34. cmErr_t err;
  35. cmFileRC_t rc;
  36. if((rc = cmFileClose(hp)) != kOkFileRC )
  37. return rc;
  38. cmErrSetup(&err,rpt,"File");
  39. hp->h = NULL;
  40. if( cmIsFlag(flags,kReadFileFl) )
  41. mode[0]='r';
  42. else
  43. if( cmIsFlag(flags,kWriteFileFl) )
  44. mode[0]='w';
  45. else
  46. if( cmIsFlag(flags,kAppendFileFl) )
  47. mode[0]='a';
  48. else
  49. cmErrMsg(&err,kInvalidFlagFileRC,"File open flags must contain 'kReadFileFl','kWriteFileFl', or 'kAppendFileFl'.");
  50. if( cmIsFlag(flags,kUpdateFileFl) )
  51. mode[1]='+';
  52. // handle requests to use stdin,stdout,stderr
  53. FILE* sfp = NULL;
  54. if( cmIsFlag(flags,kStdoutFileFl) )
  55. {
  56. sfp = stdout;
  57. fn = "stdout";
  58. }
  59. else
  60. if( cmIsFlag(flags,kStderrFileFl) )
  61. {
  62. sfp = stderr;
  63. fn = "stderr";
  64. }
  65. else
  66. if( cmIsFlag(flags,kStdinFileFl) )
  67. {
  68. sfp = stdin;
  69. fn = "stdin";
  70. }
  71. if( fn == NULL )
  72. return cmErrMsg(&err,kObjAllocFailFileRC,"File object allocation failed due to empty file name.");
  73. unsigned byteCnt = sizeof(cmFile_t) + strlen(fn) + 1;
  74. if((p = (cmFile_t*)cmMemMallocZ(byteCnt)) == NULL )
  75. return cmErrMsg(&err,kObjAllocFailFileRC,"File object allocation failed for file '%s'.",cmStringNullGuard(fn));
  76. cmErrClone(&p->err,&err);
  77. p->fnStr = (cmChar_t*)(p+1);
  78. strcpy(p->fnStr,fn);
  79. if( sfp != NULL )
  80. p->fp = sfp;
  81. else
  82. {
  83. errno = 0;
  84. if((p->fp = fopen(fn,mode)) == NULL )
  85. {
  86. cmFileRC_t rc = _cmFileError(p,kOpenFailFileRC,errno,"File open failed");
  87. cmMemFree(p);
  88. return rc;
  89. }
  90. }
  91. hp->h = p;
  92. return kOkFileRC;
  93. }
  94. cmFileRC_t cmFileClose( cmFileH_t* hp )
  95. {
  96. if( cmFileIsValid(*hp) == false )
  97. return kOkFileRC;
  98. cmFile_t* p = _cmFileHandleToPtr(*hp);
  99. errno = 0;
  100. if( p->fp != NULL )
  101. if( fclose(p->fp) != 0 )
  102. return _cmFileError(p,kCloseFailFileRC,errno,"File close failed");
  103. cmMemFree(p);
  104. hp->h = NULL;
  105. return kOkFileRC;
  106. }
  107. bool cmFileIsValid( cmFileH_t h )
  108. { return h.h != NULL; }
  109. cmFileRC_t cmFileRead( cmFileH_t h, void* buf, unsigned bufByteCnt )
  110. {
  111. cmFile_t* p = _cmFileHandleToPtr(h);
  112. errno = 0;
  113. if( fread(buf,bufByteCnt,1,p->fp) != 1 )
  114. return _cmFileError(p,kReadFailFileRC,errno,"File read failed");
  115. return kOkFileRC;
  116. }
  117. cmFileRC_t cmFileWrite( cmFileH_t h, const void* buf, unsigned bufByteCnt )
  118. {
  119. cmFile_t* p = _cmFileHandleToPtr(h);
  120. errno = 0;
  121. if( fwrite(buf,bufByteCnt,1,p->fp) != 1 )
  122. return _cmFileError(p,kWriteFailFileRC,errno,"File write failed");
  123. return kOkFileRC;
  124. }
  125. cmFileRC_t cmFileSeek( cmFileH_t h, enum cmFileSeekFlags_t flags, int offsByteCnt )
  126. {
  127. cmFile_t* p = _cmFileHandleToPtr(h);
  128. unsigned fileflags = 0;
  129. if( cmIsFlag(flags,kBeginFileFl) )
  130. fileflags = SEEK_SET;
  131. else
  132. if( cmIsFlag(flags,kCurFileFl) )
  133. fileflags = SEEK_CUR;
  134. else
  135. if( cmIsFlag(flags,kEndFileFl) )
  136. fileflags = SEEK_END;
  137. else
  138. return cmErrMsg(&p->err,kInvalidFlagFileRC,"Invalid file seek flag on '%s'.",p->fnStr);
  139. errno = 0;
  140. if( fseek(p->fp,offsByteCnt,fileflags) != 0 )
  141. return _cmFileError(p,kSeekFailFileRC,errno,"File seek failed");
  142. return kOkFileRC;
  143. }
  144. cmFileRC_t cmFileTell( cmFileH_t h, long* offsPtr )
  145. {
  146. assert( offsPtr != NULL );
  147. *offsPtr = -1;
  148. cmFile_t* p = _cmFileHandleToPtr(h);
  149. errno = 0;
  150. if((*offsPtr = ftell(p->fp)) == -1)
  151. return _cmFileError(p,kTellFailFileRC,errno,"File tell failed");
  152. return kOkFileRC;
  153. }
  154. bool cmFileEof( cmFileH_t h )
  155. { return feof( _cmFileHandleToPtr(h)->fp ) != 0; }
  156. unsigned cmFileByteCount( cmFileH_t h )
  157. {
  158. struct stat sr;
  159. int f;
  160. cmFile_t* p = _cmFileHandleToPtr(h);
  161. const cmChar_t errMsg[] = "File byte count request failed.";
  162. errno = 0;
  163. if((f = fileno(p->fp)) == -1)
  164. {
  165. _cmFileError(p,kHandleInvalidFileRC,errno,errMsg);
  166. return 0;
  167. }
  168. if(fstat(f,&sr) == -1)
  169. {
  170. _cmFileError(p,kStatFailFileRC,errno,errMsg);
  171. return 0;
  172. }
  173. return sr.st_size;
  174. }
  175. cmFileRC_t cmFileByteCountFn( const cmChar_t* fn, cmRpt_t* rpt, unsigned* fileByteCntPtr )
  176. {
  177. assert( fileByteCntPtr != NULL );
  178. cmFileRC_t rc;
  179. cmFileH_t h = cmFileNullHandle;
  180. if((rc = cmFileOpen(&h,fn,kReadFileFl,rpt)) != kOkFileRC )
  181. return rc;
  182. if( fileByteCntPtr != NULL)
  183. *fileByteCntPtr = cmFileByteCount(h);
  184. cmFileClose(&h);
  185. return rc;
  186. }
  187. cmFileRC_t cmFileCompare( const cmChar_t* fn0, const cmChar_t* fn1, cmRpt_t* rpt, bool* isEqualPtr )
  188. {
  189. cmFileRC_t rc = kOkFileRC;
  190. unsigned bufByteCnt = 2048;
  191. cmFileH_t h0 = cmFileNullHandle;
  192. cmFileH_t h1 = cmFileNullHandle;
  193. char b0[ bufByteCnt ];
  194. char b1[ bufByteCnt ];
  195. assert(isEqualPtr != NULL );
  196. *isEqualPtr = true;
  197. if((rc = cmFileOpen(&h0,fn0,kReadFileFl,rpt)) != kOkFileRC )
  198. goto errLabel;
  199. if((rc = cmFileOpen(&h1,fn1,kReadFileFl,rpt)) != kOkFileRC )
  200. goto errLabel;
  201. cmFile_t* p0 = _cmFileHandleToPtr(h0);
  202. cmFile_t* p1 = _cmFileHandleToPtr(h1);
  203. while(1)
  204. {
  205. size_t n0 = fread(b0,1,bufByteCnt,p0->fp);
  206. size_t n1 = fread(b1,1,bufByteCnt,p1->fp);
  207. if( n0 != n1 || memcmp(b0,b1,n0)!=0 )
  208. {
  209. *isEqualPtr = false;
  210. break;
  211. }
  212. if( n0 != bufByteCnt || n1 != bufByteCnt )
  213. break;
  214. }
  215. errLabel:
  216. cmFileClose(&h0);
  217. cmFileClose(&h1);
  218. return rc;
  219. }
  220. const cmChar_t* cmFileName( cmFileH_t h )
  221. {
  222. cmFile_t* p = _cmFileHandleToPtr(h);
  223. return p->fnStr;
  224. }
  225. cmFileRC_t cmFileFnWrite( const cmChar_t* fn, cmRpt_t* rpt, const void* buf, unsigned bufByteCnt )
  226. {
  227. cmFileH_t h = cmFileNullHandle;
  228. cmFileRC_t rc;
  229. if((rc = cmFileOpen(&h,fn,kWriteFileFl,rpt)) != kOkFileRC )
  230. goto errLabel;
  231. rc = cmFileWrite(h,buf,bufByteCnt);
  232. errLabel:
  233. cmFileClose(&h);
  234. return rc;
  235. }
  236. cmChar_t* _cmFileToBuf( cmFileH_t h, unsigned nn, unsigned* bufByteCntPtr )
  237. {
  238. errno = 0;
  239. unsigned n = cmFileByteCount(h);
  240. cmChar_t* buf = NULL;
  241. cmFile_t* p = _cmFileHandleToPtr(h);
  242. // if the file size calculation is ok
  243. if( errno != 0 )
  244. {
  245. _cmFileError(p,kBufAllocFailFileRC,errno,"Invalid file buffer length.");
  246. goto errLabel;
  247. }
  248. // allocate the read target buffer
  249. if((buf = cmMemAlloc(cmChar_t,n+nn)) == NULL)
  250. {
  251. _cmFileError(p,kBufAllocFailFileRC,0,"Read buffer allocation failed.");
  252. goto errLabel;
  253. }
  254. // read the file
  255. if( cmFileRead(h,buf,n) != kOkFileRC )
  256. goto errLabel;
  257. // zero memory after the file data
  258. memset(buf+n,0,nn);
  259. if( bufByteCntPtr != NULL )
  260. *bufByteCntPtr = n;
  261. return buf;
  262. errLabel:
  263. if( bufByteCntPtr != NULL )
  264. *bufByteCntPtr = 0;
  265. cmMemFree(buf);
  266. return NULL;
  267. }
  268. cmChar_t* _cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned nn, unsigned* bufByteCntPtr )
  269. {
  270. cmFileH_t h = cmFileNullHandle;
  271. cmChar_t* buf = NULL;
  272. if( cmFileOpen(&h,fn,kReadFileFl | kBinaryFileFl,rpt) != kOkFileRC )
  273. goto errLabel;
  274. buf = _cmFileToBuf(h,nn,bufByteCntPtr);
  275. errLabel:
  276. cmFileClose(&h);
  277. return buf;
  278. }
  279. cmChar_t* cmFileToBuf( cmFileH_t h, unsigned* bufByteCntPtr )
  280. { return _cmFileToBuf(h,0,bufByteCntPtr); }
  281. cmChar_t* cmFileFnToBuf( const cmChar_t* fn, cmRpt_t* rpt, unsigned* bufByteCntPtr )
  282. { return _cmFileFnToBuf(fn,rpt,0,bufByteCntPtr); }
  283. cmChar_t* cmFileToStr( cmFileH_t h, unsigned* bufByteCntPtr )
  284. { return _cmFileToBuf(h,1,bufByteCntPtr); }
  285. cmChar_t* cmFileFnToStr( const cmChar_t* fn, cmRpt_t* rpt, unsigned* bufByteCntPtr )
  286. { return _cmFileFnToBuf(fn,rpt,1,bufByteCntPtr); }
  287. cmFileRC_t cmFileLineCount( cmFileH_t h, unsigned* lineCntPtr )
  288. {
  289. cmFileRC_t rc = kOkFileRC;
  290. cmFile_t* p = _cmFileHandleToPtr(h);
  291. unsigned lineCnt = 0;
  292. long offs;
  293. int c;
  294. assert( lineCntPtr != NULL );
  295. *lineCntPtr = 0;
  296. if((rc = cmFileTell(h,&offs)) != kOkFileRC )
  297. return rc;
  298. errno = 0;
  299. while(1)
  300. {
  301. c = fgetc(p->fp);
  302. if( c == EOF )
  303. {
  304. if( errno )
  305. rc =_cmFileError(p,kReadFailFileRC,errno,"File read char failed");
  306. else
  307. ++lineCnt; // add one in case the last line isn't terminated with a '\n'.
  308. break;
  309. }
  310. // if an end-of-line was encountered
  311. if( c == '\n' )
  312. ++lineCnt;
  313. }
  314. if((rc = cmFileSeek(h,kBeginFileFl,offs)) != kOkFileRC )
  315. return rc;
  316. *lineCntPtr = lineCnt;
  317. return rc;
  318. }
  319. cmFileRC_t _cmFileGetLine( cmFile_t* p, cmChar_t* buf, unsigned* bufByteCntPtr )
  320. {
  321. // fgets() reads up to n-1 bytes into buf[]
  322. if( fgets(buf,*bufByteCntPtr,p->fp) == NULL )
  323. {
  324. // an read error or EOF condition occurred
  325. *bufByteCntPtr = 0;
  326. if( !feof(p->fp ) )
  327. return _cmFileError(p,kReadFailFileRC,errno,"File read line failed");
  328. return kReadFailFileRC;
  329. }
  330. return kOkFileRC;
  331. }
  332. cmFileRC_t cmFileGetLine( cmFileH_t h, cmChar_t* buf, unsigned* bufByteCntPtr )
  333. {
  334. assert( bufByteCntPtr != NULL );
  335. cmFile_t* p = _cmFileHandleToPtr(h);
  336. unsigned tn = 128;
  337. cmChar_t t[ tn ];
  338. unsigned on = *bufByteCntPtr;
  339. long offs;
  340. cmFileRC_t rc;
  341. // store the current file offset
  342. if((rc = cmFileTell(h,&offs)) != kOkFileRC )
  343. return rc;
  344. // if no buffer was given then use t[]
  345. if( buf == NULL || *bufByteCntPtr == 0 )
  346. {
  347. *bufByteCntPtr = tn;
  348. buf = t;
  349. }
  350. // fill the buffer from the current line
  351. if((rc = _cmFileGetLine(p,buf,bufByteCntPtr)) != kOkFileRC )
  352. return rc;
  353. // get length of the string in the buffer
  354. // (this is one less than the count of bytes written to the buffer)
  355. unsigned n = strlen(buf);
  356. // if the provided buffer was large enough to read the entire string
  357. if( on > n+1 )
  358. {
  359. //*bufByteCntPtr = n+1;
  360. return kOkFileRC;
  361. }
  362. //
  363. // the provided buffer was not large enough
  364. //
  365. // m tracks the length of the string
  366. unsigned m = n;
  367. while( n+1 == *bufByteCntPtr )
  368. {
  369. // fill the buffer from the current line
  370. if((rc = _cmFileGetLine(p,buf,bufByteCntPtr)) != kOkFileRC )
  371. return rc;
  372. n = strlen(buf);
  373. m += n;
  374. }
  375. // restore the original file offset
  376. if((rc = cmFileSeek(h,kBeginFileFl,offs)) != kOkFileRC )
  377. return rc;
  378. // add 1 for /0, 1 for /n and 1 to detect buf-too-short
  379. *bufByteCntPtr = m+3;
  380. return kBufTooSmallFileRC;
  381. }
  382. cmFileRC_t cmFileGetLineAuto( cmFileH_t h, cmChar_t** bufPtrPtr, unsigned* bufByteCntPtr )
  383. {
  384. cmFileRC_t rc = kOkFileRC;
  385. bool fl = true;
  386. cmChar_t* buf = *bufPtrPtr;
  387. *bufPtrPtr = NULL;
  388. while(fl)
  389. {
  390. fl = false;
  391. switch( rc = cmFileGetLine(h,buf,bufByteCntPtr) )
  392. {
  393. case kOkFileRC:
  394. {
  395. *bufPtrPtr = buf;
  396. }
  397. break;
  398. case kBufTooSmallFileRC:
  399. buf = cmMemResizeZ(cmChar_t,buf,*bufByteCntPtr);
  400. fl = true;
  401. break;
  402. default:
  403. cmMemFree(buf);
  404. break;
  405. }
  406. }
  407. return rc;
  408. }
  409. cmFileRC_t cmFileReadChar( cmFileH_t h, char* buf, unsigned cnt )
  410. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  411. cmFileRC_t cmFileReadUChar( cmFileH_t h, unsigned char* buf, unsigned cnt )
  412. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  413. cmFileRC_t cmFileReadShort( cmFileH_t h, short* buf, unsigned cnt )
  414. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  415. cmFileRC_t cmFileReadUShort( cmFileH_t h, unsigned short* buf, unsigned cnt )
  416. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  417. cmFileRC_t cmFileReadLong( cmFileH_t h, long* buf, unsigned cnt )
  418. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  419. cmFileRC_t cmFileReadULong( cmFileH_t h, unsigned long* buf, unsigned cnt )
  420. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  421. cmFileRC_t cmFileReadInt( cmFileH_t h, int* buf, unsigned cnt )
  422. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  423. cmFileRC_t cmFileReadUInt( cmFileH_t h, unsigned int* buf, unsigned cnt )
  424. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  425. cmFileRC_t cmFileReadFloat( cmFileH_t h, float* buf, unsigned cnt )
  426. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  427. cmFileRC_t cmFileReadDouble( cmFileH_t h, double* buf, unsigned cnt )
  428. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  429. cmFileRC_t cmFileReadBool( cmFileH_t h, bool* buf, unsigned cnt )
  430. { return cmFileRead(h,buf,sizeof(buf[0])*cnt); }
  431. cmFileRC_t cmFileWriteChar( cmFileH_t h, const char* buf, unsigned cnt )
  432. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  433. cmFileRC_t cmFileWriteUChar( cmFileH_t h, const unsigned char* buf, unsigned cnt )
  434. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  435. cmFileRC_t cmFileWriteShort( cmFileH_t h, const short* buf, unsigned cnt )
  436. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  437. cmFileRC_t cmFileWriteUShort( cmFileH_t h, const unsigned short* buf, unsigned cnt )
  438. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  439. cmFileRC_t cmFileWriteLong( cmFileH_t h, const long* buf, unsigned cnt )
  440. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  441. cmFileRC_t cmFileWriteULong( cmFileH_t h, const unsigned long* buf, unsigned cnt )
  442. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  443. cmFileRC_t cmFileWriteInt( cmFileH_t h, const int* buf, unsigned cnt )
  444. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  445. cmFileRC_t cmFileWriteUInt( cmFileH_t h, const unsigned int* buf, unsigned cnt )
  446. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  447. cmFileRC_t cmFileWriteFloat( cmFileH_t h, const float* buf, unsigned cnt )
  448. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  449. cmFileRC_t cmFileWriteDouble( cmFileH_t h, const double* buf, unsigned cnt )
  450. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  451. cmFileRC_t cmFileWriteBool( cmFileH_t h, const bool* buf, unsigned cnt )
  452. { return cmFileWrite(h,buf,sizeof(buf[0])*cnt); }
  453. cmFileRC_t cmFilePrint( cmFileH_t h, const cmChar_t* text )
  454. {
  455. cmFile_t* p = _cmFileHandleToPtr(h);
  456. errno = 0;
  457. if( fputs(text,p->fp) < 0 )
  458. return _cmFileError(p,kPrintFailFileRC,errno,"File print failed");
  459. return kOkFileRC;
  460. }
  461. cmFileRC_t cmFileVPrintf( cmFileH_t h, const cmChar_t* fmt, va_list vl )
  462. {
  463. cmFile_t* p = _cmFileHandleToPtr(h);
  464. if( vfprintf(p->fp,fmt,vl) < 0 )
  465. return _cmFileError(p,kPrintFailFileRC,errno,"File print failed");
  466. return kOkFileRC;
  467. }
  468. cmFileRC_t cmFilePrintf( cmFileH_t h, const cmChar_t* fmt, ... )
  469. {
  470. va_list vl;
  471. va_start(vl,fmt);
  472. cmFileRC_t rc = cmFileVPrintf(h,fmt,vl);
  473. va_end(vl);
  474. return rc;
  475. }