Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1322 lines
28 KiB

  1. #include "toollib.h"
  2. #ifdef _DEBUG
  3. #define HEAP_CHECK
  4. #endif
  5. int g_tl_argc;
  6. char** g_tl_argv;
  7. int g_tl_byteorder;
  8. int g_tl_dircount;
  9. char** g_tl_dirlist;
  10. int g_tl_start;
  11. int g_tl_abort;
  12. bool g_tl_quiet;
  13. #pragma warning(disable:4311)
  14. #pragma warning(disable:4267)
  15. /*****************************************************************************
  16. TL_Setup
  17. *****************************************************************************/
  18. void TL_Setup(char* appname, int argc, char** argv)
  19. {
  20. const char* buildStr;
  21. g_tl_argc = argc;
  22. g_tl_argv = argv;
  23. g_tl_quiet = (TL_CheckParm("q") > 0) || (TL_CheckParm("quiet") > 0) || (TL_CheckParm("noheader") > 0);
  24. if (appname)
  25. {
  26. TL_printf("\n%s \n",appname);
  27. #ifdef _DEBUG
  28. buildStr = "Debug Build";
  29. #else
  30. buildStr = "Release Build";
  31. #endif
  32. TL_printf("%s - %s %s\n\n", buildStr, __DATE__, __TIME__);
  33. }
  34. g_tl_abort = TL_CheckParm("abort");
  35. g_tl_start = TL_CPUCount();
  36. }
  37. /*****************************************************************************
  38. TL_End
  39. *****************************************************************************/
  40. void TL_End(bool showtime)
  41. {
  42. int end;
  43. if (showtime && !g_tl_quiet)
  44. {
  45. end = TL_CPUCount();
  46. TL_printf("\n%f seconds.\n",TL_CPUTime(g_tl_start,end));
  47. }
  48. }
  49. /*****************************************************************************
  50. TL_Error
  51. *****************************************************************************/
  52. void TL_Error(char* error, ...)
  53. {
  54. va_list argptr;
  55. va_start(argptr,error);
  56. vprintf(error,argptr);
  57. va_end(argptr);
  58. printf("\n");
  59. #if !defined( _X360 )
  60. __asm
  61. {
  62. int 3;
  63. }
  64. #endif
  65. if (g_tl_abort)
  66. abort();
  67. exit(-1);
  68. }
  69. /*****************************************************************************
  70. TL_CheckParm
  71. Returns the argument number (1 to argc-1) or 0 if not present
  72. *****************************************************************************/
  73. int TL_CheckParm(char* check)
  74. {
  75. int i;
  76. char* parm;
  77. for (i=1; i<g_tl_argc; i++)
  78. {
  79. parm = g_tl_argv[i];
  80. if (!isalpha(*parm))
  81. if (!*++parm)
  82. continue;
  83. if (!stricmp(check,parm))
  84. return (i);
  85. }
  86. return (0);
  87. }
  88. /*****************************************************************************
  89. TL_SafeRead
  90. *****************************************************************************/
  91. void TL_SafeRead(int handle, void* buffer, long count)
  92. {
  93. if (_read(handle,buffer,count) != count)
  94. TL_Error("SafeRead(): read failure");
  95. }
  96. /*****************************************************************************
  97. TL_SafeOpenRead
  98. *****************************************************************************/
  99. int TL_SafeOpenRead(const char* filename)
  100. {
  101. int handle;
  102. handle = _open(filename,_O_RDONLY|_O_BINARY);
  103. if (handle == -1)
  104. TL_Error("TL_SafeOpenRead(): Error opening %s: %s",filename,strerror(errno));
  105. return (handle);
  106. }
  107. /*****************************************************************************
  108. TL_SafeOpenWrite
  109. *****************************************************************************/
  110. int TL_SafeOpenWrite(const char* filename)
  111. {
  112. int handle;
  113. handle = _open(filename,_O_RDWR|_O_BINARY|_O_CREAT|_O_TRUNC,0666);
  114. if (handle == -1)
  115. TL_Error("TL_SafeOpenWrite(): Error opening %s: %s",filename,strerror(errno));
  116. return (handle);
  117. }
  118. /*****************************************************************************
  119. TL_SafeWrite
  120. *****************************************************************************/
  121. void TL_SafeWrite(int handle, void* buffer, long count)
  122. {
  123. int status;
  124. status = _write(handle,buffer,count);
  125. if (status != count)
  126. TL_Error("TL_SafeWrite(): write failure %d, errno=%d",status,errno);
  127. }
  128. /*****************************************************************************
  129. TL_SafeClose
  130. *****************************************************************************/
  131. void TL_SafeClose(int handle, int touch)
  132. {
  133. // ensure date and time of modification get set
  134. if (touch)
  135. _futime(handle,NULL);
  136. close(handle);
  137. }
  138. /*****************************************************************************
  139. TL_Malloc
  140. *****************************************************************************/
  141. void* TL_Malloc(int size)
  142. {
  143. void* ptr;
  144. int newsize;
  145. newsize = size + sizeof(tlmem_t);
  146. newsize = (newsize + 3) & ~3;
  147. ptr = malloc(newsize);
  148. if (!ptr)
  149. TL_Error("TL_Malloc(): failure for %lu bytes",size);
  150. memset(ptr,0,newsize);
  151. ((tlmem_t*)ptr)->id = TL_MEMID;
  152. ((tlmem_t*)ptr)->size = size;
  153. return ((byte_t*)ptr + sizeof(tlmem_t));
  154. }
  155. /*****************************************************************************
  156. TL_Free
  157. *****************************************************************************/
  158. void TL_Free(void* ptr)
  159. {
  160. tlmem_t* memptr;
  161. if (!ptr)
  162. TL_Error("TL_Free(): null pointer");
  163. memptr = (tlmem_t*)((byte_t*)ptr - sizeof(tlmem_t));
  164. if (((u32)memptr) & 3)
  165. TL_Error("TL_Free(): bad pointer %8.8x",ptr);
  166. if (memptr->id != TL_MEMID)
  167. TL_Error("TL_Free(): corrupted pointer %8.8x",ptr);
  168. memptr->id = 0;
  169. memptr->size = 0;
  170. free(memptr);
  171. #ifdef HEAP_CHECK
  172. if (_heapchk() != _HEAPOK)
  173. TL_Error("TL_Free(): heap corrupted");
  174. #endif
  175. }
  176. bool TL_Check(void* ptr)
  177. {
  178. tlmem_t* memptr;
  179. if (!ptr)
  180. return false;
  181. memptr = (tlmem_t*)((byte_t*)ptr - sizeof(tlmem_t));
  182. if (((u32)memptr) & 3)
  183. return false;
  184. if (memptr->id != TL_MEMID)
  185. return false;
  186. return true;
  187. }
  188. /*****************************************************************************
  189. TL_Realloc
  190. *****************************************************************************/
  191. void* TL_Realloc(void* ptr, int newsize)
  192. {
  193. int len;
  194. tlmem_t* oldmemptr;
  195. void* newptr;
  196. if (!ptr)
  197. {
  198. newptr = TL_Malloc(newsize);
  199. return (newptr);
  200. }
  201. oldmemptr = (tlmem_t*)((byte_t*)ptr - sizeof(tlmem_t));
  202. if ((u32)oldmemptr & 3)
  203. TL_Error("TL_Realloc(): bad pointer %8.8x",ptr);
  204. if (oldmemptr->id != TL_MEMID)
  205. TL_Error("TL_Realloc(): corrupted pointer %8.8x",ptr);
  206. newptr = TL_Malloc(newsize);
  207. len = TL_min(newsize,oldmemptr->size);
  208. memcpy(newptr,ptr,len);
  209. TL_Free(ptr);
  210. return (newptr);
  211. }
  212. /*****************************************************************************
  213. TL_strncpyz
  214. Copy up to (N) bytes including appending null.
  215. *****************************************************************************/
  216. void TL_strncpyz(char* dst, char* src, int n)
  217. {
  218. if (n <= 0)
  219. return;
  220. if (n > 1)
  221. strncpy(dst,src,n-1);
  222. dst[n-1] = '\0';
  223. }
  224. /*****************************************************************************
  225. TL_strncatz
  226. Concatenate up to dstsize bytes including appending null.
  227. *****************************************************************************/
  228. void TL_strncatz(char* dst, char* src, int dstsize)
  229. {
  230. int len;
  231. if (dstsize <= 0)
  232. return;
  233. len = (int)strlen(dst);
  234. TL_strncpyz(dst+len,src,dstsize-len);
  235. }
  236. /*****************************************************************************
  237. TL_LoadFile
  238. *****************************************************************************/
  239. long TL_LoadFile(const char* filename, void** bufferptr)
  240. {
  241. int handle;
  242. long length;
  243. char* buffer;
  244. handle = TL_SafeOpenRead(filename);
  245. length = TL_FileLength(handle);
  246. buffer = (char*)TL_Malloc(length+1);
  247. TL_SafeRead(handle,buffer,length);
  248. close(handle);
  249. // for parsing
  250. buffer[length] = '\0';
  251. *bufferptr = (void*)buffer;
  252. return (length);
  253. }
  254. /*****************************************************************************
  255. TL_TouchFile
  256. *****************************************************************************/
  257. void TL_TouchFile(char* filename)
  258. {
  259. int h;
  260. h = _open(filename,_O_RDWR|_O_BINARY,0666);
  261. if (h < 0)
  262. return;
  263. _futime(h,NULL);
  264. _close(h);
  265. }
  266. /*****************************************************************************
  267. TL_SaveFile
  268. *****************************************************************************/
  269. void TL_SaveFile(char* filename, void* buffer, long count)
  270. {
  271. int handle;
  272. handle = TL_SafeOpenWrite(filename);
  273. TL_SafeWrite(handle,buffer,count);
  274. TL_SafeClose(handle,true);
  275. }
  276. /*****************************************************************************
  277. TL_FileLength
  278. *****************************************************************************/
  279. long TL_FileLength(int handle)
  280. {
  281. long pos;
  282. long length;
  283. pos = lseek(handle,0,SEEK_CUR);
  284. length = lseek(handle,0,SEEK_END);
  285. lseek(handle,pos,SEEK_SET);
  286. return (length);
  287. }
  288. /*****************************************************************************
  289. TL_StripFilename
  290. Removes filename from path.
  291. *****************************************************************************/
  292. void TL_StripFilename(char* path)
  293. {
  294. int length;
  295. length = (int)strlen(path)-1;
  296. while ((length > 0) && (path[length] != '\\') && (path[length] != '/') && (path[length] != ':'))
  297. length--;
  298. /* leave possible seperator */
  299. if (!length)
  300. path[0] = '\0';
  301. else
  302. path[length+1] = '\0';
  303. }
  304. /*****************************************************************************
  305. TL_StripExtension
  306. Removes extension from path.
  307. *****************************************************************************/
  308. void TL_StripExtension(char* path)
  309. {
  310. int length;
  311. length = (int)strlen(path)-1;
  312. while (length > 0 && path[length] != '.')
  313. length--;
  314. if (length && path[length] == '.')
  315. path[length] = 0;
  316. }
  317. /*****************************************************************************
  318. TL_StripPath
  319. Removes path from full path.
  320. *****************************************************************************/
  321. void TL_StripPath(char* path, char* dest)
  322. {
  323. char* src;
  324. src = path + strlen(path);
  325. while ((src != path) && (*(src-1) != '\\') && (*(src-1) != '/') && (*(src-1) != ':'))
  326. src--;
  327. strcpy(dest,src);
  328. }
  329. /*****************************************************************************
  330. TL_GetExtension
  331. Gets any extension from the full path.
  332. *****************************************************************************/
  333. void TL_GetExtension(char* path, char* dest)
  334. {
  335. char* src;
  336. src = path + strlen(path) - 1;
  337. // back up until a . or the start
  338. while (src != path && *(src-1) != '.')
  339. src--;
  340. if (src == path)
  341. {
  342. *dest = '\0'; // no extension
  343. return;
  344. }
  345. strcpy(dest,src);
  346. }
  347. /*****************************************************************************
  348. TL_DefaultPath
  349. Adds basepath to head of path.
  350. *****************************************************************************/
  351. void TL_DefaultPath(char* path, char* basepath)
  352. {
  353. char temp[TL_MAXPATH];
  354. char* ptr;
  355. char ch;
  356. if (path[0] == '\\')
  357. {
  358. // path is absolute
  359. return;
  360. }
  361. ptr = path;
  362. while (1)
  363. {
  364. ch = *ptr++;
  365. if (!ch)
  366. break;
  367. if (ch == ':')
  368. {
  369. // path has a device - must be absolute
  370. return;
  371. }
  372. }
  373. // place basepath at head of path
  374. // do intermediate copy to preserve any arg wierdness
  375. strcpy(temp,path);
  376. strcpy(path,basepath);
  377. strcat(path,temp);
  378. }
  379. /*****************************************************************************
  380. TL_AddSeperatorToPath
  381. *****************************************************************************/
  382. void TL_AddSeperatorToPath(char* inpath, char* outpath)
  383. {
  384. int len;
  385. strcpy(outpath,inpath);
  386. len = (int)strlen(outpath);
  387. if (outpath[len-1] != '\\')
  388. {
  389. outpath[len] = '\\';
  390. outpath[len+1] = '\0';
  391. }
  392. }
  393. /*****************************************************************************
  394. TL_DefaultExtension
  395. Adds extension a path that has no extension.
  396. *****************************************************************************/
  397. void TL_DefaultExtension(char* path, char* extension, bool bForce)
  398. {
  399. char* src;
  400. if ( !bForce && path[0] )
  401. {
  402. src = path + strlen(path) - 1;
  403. while ((src != path) && (*src != '\\') && (*src != '/'))
  404. {
  405. if (*src == '.')
  406. return;
  407. src--;
  408. }
  409. }
  410. strcat(path,extension);
  411. }
  412. /*****************************************************************************
  413. TL_ReplaceDosExtension
  414. Handles files of the form xxxx.xxxxxxx.xxxxx.zzz
  415. *****************************************************************************/
  416. void TL_ReplaceDosExtension(char* path, char* extension)
  417. {
  418. int len;
  419. len = (int)strlen(path);
  420. if (!len)
  421. return;
  422. if (path[len-1] == '.')
  423. {
  424. path[len-1] = '\0';
  425. strcat(path,extension);
  426. return;
  427. }
  428. if (len-4 > 0 && path[len-4] == '.')
  429. path[len-4] = '\0';
  430. strcat(path,extension);
  431. }
  432. /*****************************************************************************
  433. TL_ReplaceExtension
  434. Replaces any extension found after '.'
  435. *****************************************************************************/
  436. void TL_ReplaceExtension(const char* inPath, const char* extension, char* outPath)
  437. {
  438. int len;
  439. char* src;
  440. if (outPath != inPath)
  441. strcpy(outPath, inPath);
  442. len = (int)strlen(outPath);
  443. if (!len)
  444. return;
  445. if (outPath[len-1] == '.')
  446. {
  447. outPath[len-1] = '\0';
  448. strcat(outPath, extension);
  449. return;
  450. }
  451. src = outPath + len - 1;
  452. while ((src != outPath) && (*src != '\\') && (*src != '/'))
  453. {
  454. if (*src == '.')
  455. {
  456. *src = '\0';
  457. break;
  458. }
  459. src--;
  460. }
  461. strcat(outPath, extension);
  462. }
  463. /*****************************************************************************
  464. TL_TempFilename
  465. Builds a temporary filename at specified path.
  466. *****************************************************************************/
  467. void TL_TempFilename(char* path)
  468. {
  469. int len;
  470. len = (int)strlen(path);
  471. if (len)
  472. {
  473. /* tack on appending seperator */
  474. if (path[len-1] != '\\')
  475. {
  476. path[len] = '\\';
  477. path[len+1] = '\0';
  478. }
  479. }
  480. strcat(path,tmpnam(NULL));
  481. }
  482. /*****************************************************************************
  483. TL_AlignFile
  484. TL_Aligns data in file to any boundary.
  485. *****************************************************************************/
  486. int TL_AlignFile(int handle, int align)
  487. {
  488. int i;
  489. int pos;
  490. int empty;
  491. int count;
  492. empty = 0;
  493. pos = lseek(handle,0,SEEK_CUR);
  494. count = ((pos+align-1)/align)*align - pos;
  495. for (i=0; i<count; i++)
  496. TL_SafeWrite(handle,&empty,1);
  497. return (pos+count);
  498. }
  499. /*****************************************************************************
  500. TL_GetByteOrder
  501. Gets byte ordering, true is bigendian.
  502. *****************************************************************************/
  503. int TL_GetByteOrder(void)
  504. {
  505. return (g_tl_byteorder);
  506. }
  507. /*****************************************************************************
  508. TL_SetByteOrder
  509. Sets byte ordering, true is bigendian.
  510. *****************************************************************************/
  511. void TL_SetByteOrder(int flag)
  512. {
  513. g_tl_byteorder = flag;
  514. }
  515. /*****************************************************************************
  516. TL_LongSwap
  517. Swap according to set state.
  518. *****************************************************************************/
  519. long TL_LongSwap(long l)
  520. {
  521. if (!g_tl_byteorder)
  522. return (l);
  523. return (TL_BigLong(l));
  524. }
  525. /*****************************************************************************
  526. TL_ShortSwap
  527. Swap according to set state.
  528. *****************************************************************************/
  529. short TL_ShortSwap(short s)
  530. {
  531. if (!g_tl_byteorder)
  532. return (s);
  533. return (TL_BigShort(s));
  534. }
  535. /*****************************************************************************
  536. TL_BigShort
  537. Converts native short to big endian
  538. *****************************************************************************/
  539. short TL_BigShort(short l)
  540. {
  541. byte_t b1;
  542. byte_t b2;
  543. b1 = l&255;
  544. b2 = (l>>8)&255;
  545. return (b1<<8) + b2;
  546. }
  547. /*****************************************************************************
  548. TL_LittleShort
  549. Converts native short to little endian
  550. *****************************************************************************/
  551. short TL_LittleShort(short l)
  552. {
  553. return (l);
  554. }
  555. /*****************************************************************************
  556. TL_BigLong
  557. Converts native long to big endian
  558. *****************************************************************************/
  559. long TL_BigLong(long l)
  560. {
  561. byte_t b1;
  562. byte_t b2;
  563. byte_t b3;
  564. byte_t b4;
  565. b1 = (byte_t)(l&255);
  566. b2 = (byte_t)((l>>8)&255);
  567. b3 = (byte_t)((l>>16)&255);
  568. b4 = (byte_t)((l>>24)&255);
  569. return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
  570. }
  571. /*****************************************************************************
  572. TL_LittleLong
  573. Converts native long to little endian
  574. *****************************************************************************/
  575. long TL_LittleLong(long l)
  576. {
  577. return (l);
  578. }
  579. /*****************************************************************************
  580. TL_BigFloat
  581. Converts native float to big endian
  582. *****************************************************************************/
  583. float TL_BigFloat(float f)
  584. {
  585. union
  586. {
  587. float f;
  588. byte_t b[4];
  589. } dat1,dat2;
  590. dat1.f = f;
  591. dat2.b[0] = dat1.b[3];
  592. dat2.b[1] = dat1.b[2];
  593. dat2.b[2] = dat1.b[1];
  594. dat2.b[3] = dat1.b[0];
  595. return (dat2.f);
  596. }
  597. /*****************************************************************************
  598. TL_Exists
  599. Returns TRUE if file exists.
  600. *****************************************************************************/
  601. bool TL_Exists(const char* filename)
  602. {
  603. FILE* test;
  604. if (!filename || !filename[0])
  605. return (false);
  606. if ((test = fopen(filename,"rb")) == NULL)
  607. return (false);
  608. fclose(test);
  609. return (true);
  610. }
  611. /*****************************************************************************
  612. TL_FileTime
  613. Returns a file's time and data word.
  614. *****************************************************************************/
  615. u32 TL_FileTime(char* filename)
  616. {
  617. struct _finddata_t finddata;
  618. intptr_t h;
  619. h = _findfirst(filename, &finddata);
  620. if (h == -1)
  621. return (0);
  622. _findclose(h);
  623. return (finddata.time_write);
  624. }
  625. /*****************************************************************************
  626. TL_SortNames
  627. *****************************************************************************/
  628. int TL_SortNames(const void *a, const void *b)
  629. {
  630. return (strcmp(*((char **)a), *((char **)b)));
  631. }
  632. /*****************************************************************************
  633. TL_FindFiles
  634. *****************************************************************************/
  635. int TL_FindFiles(char* filemask, char*** filenames)
  636. {
  637. struct _finddata_t finddata;
  638. intptr_t h;
  639. char sourcepath[TL_MAXPATH];
  640. int count;
  641. int len;
  642. char** names = NULL;
  643. char* ptr;
  644. h = _findfirst(filemask,&finddata);
  645. if (h == -1)
  646. return (0);
  647. TL_strncpyz(sourcepath,filemask,TL_MAXPATH);
  648. TL_StripFilename(sourcepath);
  649. if (!sourcepath[0])
  650. strcpy(sourcepath,".\\");
  651. else
  652. {
  653. len = (int)strlen(sourcepath);
  654. if (sourcepath[len-1] != '\\')
  655. TL_strncatz(sourcepath,"\\",TL_MAXPATH);
  656. }
  657. count = 0;
  658. do
  659. {
  660. if (finddata.attrib & _A_SUBDIR)
  661. continue;
  662. if (!count)
  663. names = (char**)TL_Malloc(sizeof(char*));
  664. else
  665. names = (char**)TL_Realloc(names,(count+1)*sizeof(char*));
  666. ptr = (char*)TL_Malloc(TL_MAXPATH);
  667. names[count] = ptr;
  668. TL_strncpyz(names[count],sourcepath,TL_MAXPATH);
  669. TL_strncatz(names[count],finddata.name,TL_MAXPATH);
  670. count++;
  671. }
  672. while (!_findnext(h,&finddata));
  673. _findclose(h);
  674. // ascending sort the names
  675. qsort(names,count,sizeof(char*),TL_SortNames);
  676. *filenames = names;
  677. return (count);
  678. }
  679. /*****************************************************************************
  680. TL_GetFileList
  681. *****************************************************************************/
  682. int TL_GetFileList(char* dirpath, char* pattern, tlfile_t*** filelist)
  683. {
  684. struct _finddata_t finddata;
  685. char sourcepath[TL_MAXPATH];
  686. char fullpath[TL_MAXPATH];
  687. char* filename;
  688. intptr_t h;
  689. int filecount;
  690. int finddirs;
  691. int len;
  692. filecount = 0;
  693. strcpy(sourcepath,dirpath);
  694. len = (int)strlen(sourcepath);
  695. if (!len)
  696. strcpy(sourcepath,".\\");
  697. else if (sourcepath[len-1] != '\\')
  698. {
  699. sourcepath[len] = '\\';
  700. sourcepath[len+1] = '\0';
  701. }
  702. strcpy(fullpath,sourcepath);
  703. if (pattern[0] == '\\' && pattern[1] == '\0')
  704. {
  705. // find directories
  706. finddirs = true;
  707. strcat(fullpath,"*");
  708. }
  709. else
  710. {
  711. finddirs = false;
  712. strcat(fullpath,pattern);
  713. }
  714. h = _findfirst(fullpath,&finddata);
  715. if (h == -1)
  716. return (0);
  717. do
  718. {
  719. // dos attribute complexities i.e. _A_NORMAL is 0
  720. if (finddirs)
  721. {
  722. // skip non dirs
  723. if (!(finddata.attrib & _A_SUBDIR))
  724. continue;
  725. }
  726. else
  727. {
  728. // skip dirs
  729. if (finddata.attrib & _A_SUBDIR)
  730. continue;
  731. }
  732. if (!stricmp(finddata.name,"."))
  733. continue;
  734. if (!stricmp(finddata.name,".."))
  735. continue;
  736. if (!filecount)
  737. *filelist = (tlfile_t**)TL_Malloc(sizeof(tlfile_t*));
  738. else
  739. *filelist = (tlfile_t**)TL_Realloc(*filelist,(filecount+1)*sizeof(tlfile_t*));
  740. (*filelist)[filecount] = (tlfile_t*)TL_Malloc(sizeof(tlfile_t));
  741. len = (int)strlen(sourcepath) + (int)strlen(finddata.name) + 1;
  742. filename = (char*)TL_Malloc(len);
  743. strcpy(filename,sourcepath);
  744. strcat(filename,finddata.name);
  745. (*filelist)[filecount]->filename = filename;
  746. (*filelist)[filecount]->time_write = finddata.time_write;
  747. filecount++;
  748. }
  749. while (!_findnext(h,&finddata));
  750. _findclose(h);
  751. return (filecount);
  752. }
  753. /*****************************************************************************
  754. _RecurseFileTree
  755. *****************************************************************************/
  756. void _RecurseFileTree(char* dirpath, int depth)
  757. {
  758. tlfile_t** filelist;
  759. int numfiles;
  760. int i;
  761. int len;
  762. // recurse from source directory
  763. numfiles = TL_GetFileList(dirpath,"\\",&filelist);
  764. if (!numfiles)
  765. {
  766. // add directory name to search tree
  767. if (!g_tl_dircount)
  768. g_tl_dirlist = (char**)TL_Malloc(sizeof(char*));
  769. else
  770. g_tl_dirlist = (char**)TL_Realloc(g_tl_dirlist,(g_tl_dircount+1)*sizeof(char*));
  771. len = (int)strlen(dirpath);
  772. g_tl_dirlist[g_tl_dircount] = (char*)TL_Malloc(len+1);
  773. strcpy(g_tl_dirlist[g_tl_dircount],dirpath);
  774. g_tl_dircount++;
  775. return;
  776. }
  777. for (i=0; i<numfiles; i++)
  778. {
  779. // form new path name
  780. _RecurseFileTree(filelist[i]->filename,depth+1);
  781. }
  782. g_tl_dirlist = (char**)TL_Realloc(g_tl_dirlist,(g_tl_dircount+1)*sizeof(char*));
  783. len = (int)strlen(dirpath);
  784. g_tl_dirlist[g_tl_dircount] = (char*)TL_Malloc(len+1);
  785. strcpy(g_tl_dirlist[g_tl_dircount],dirpath);
  786. g_tl_dircount++;
  787. }
  788. /*****************************************************************************
  789. TL_BuildFileTree
  790. *****************************************************************************/
  791. int TL_BuildFileTree(char* dirpath, char*** dirlist)
  792. {
  793. g_tl_dircount = 0;
  794. g_tl_dirlist = NULL;
  795. _RecurseFileTree(dirpath,0);
  796. *dirlist = g_tl_dirlist;
  797. return (g_tl_dircount);
  798. }
  799. /*****************************************************************************
  800. TL_FindFiles2
  801. *****************************************************************************/
  802. int TL_FindFiles2(char* filemask, bool recurse, tlfile_t*** filelist)
  803. {
  804. char dirpath[TL_MAXPATH];
  805. char pattern[TL_MAXPATH];
  806. char** dirlist;
  807. tlfile_t*** templists;
  808. tlfile_t** list;
  809. int* numfiles;
  810. int numoutfiles;
  811. int count;
  812. int numdirs;
  813. int i;
  814. int j;
  815. int k;
  816. // get path only
  817. strcpy(dirpath,filemask);
  818. TL_StripFilename(dirpath);
  819. // get pattern only
  820. TL_StripPath(filemask,pattern);
  821. numoutfiles = 0;
  822. if (recurse)
  823. {
  824. // get the tree
  825. numdirs = TL_BuildFileTree(dirpath,&dirlist);
  826. if (numdirs)
  827. {
  828. templists = (tlfile_t***)TL_Malloc(numdirs * sizeof(tlfile_t**));
  829. numfiles = (int*)TL_Malloc(numdirs * sizeof(int));
  830. // iterate each directory found
  831. for (i=0; i<numdirs; i++)
  832. numfiles[i] = TL_GetFileList(dirlist[i],pattern,&templists[i]);
  833. // count all the files
  834. numoutfiles = 0;
  835. for (i=0; i<numdirs; i++)
  836. numoutfiles += numfiles[i];
  837. // allocate single list
  838. if (numoutfiles)
  839. {
  840. *filelist = (tlfile_t**)TL_Malloc(numoutfiles*sizeof(tlfile_t*));
  841. k = 0;
  842. for (i=0; i<numdirs; i++)
  843. {
  844. count = numfiles[i];
  845. list = templists[i];
  846. for (j=0; j<count; j++,k++)
  847. {
  848. (*filelist)[k] = list[j];
  849. }
  850. }
  851. }
  852. // free the directory lists
  853. for (i=0; i<numdirs; i++)
  854. {
  855. TL_Free(dirlist[i]);
  856. if (numfiles[i])
  857. TL_Free(templists[i]);
  858. }
  859. TL_Free(dirlist);
  860. TL_Free(templists);
  861. TL_Free(numfiles);
  862. }
  863. }
  864. else
  865. {
  866. numoutfiles = TL_GetFileList(dirpath,pattern,filelist);
  867. }
  868. return (numoutfiles);
  869. }
  870. /*****************************************************************************
  871. TL_FreeFileList
  872. *****************************************************************************/
  873. void TL_FreeFileList(int count, tlfile_t** filelist)
  874. {
  875. int i;
  876. for (i=0; i<count; i++)
  877. {
  878. TL_Free(filelist[i]->filename);
  879. TL_Free(filelist[i]);
  880. }
  881. if (count)
  882. TL_Free(filelist);
  883. }
  884. /*****************************************************************************
  885. TL_CPUCount
  886. *****************************************************************************/
  887. int TL_CPUCount(void)
  888. {
  889. int time;
  890. time = clock();
  891. return (time);
  892. }
  893. /*****************************************************************************
  894. TL_CPUTime
  895. *****************************************************************************/
  896. double TL_CPUTime(int start, int stop)
  897. {
  898. double duration;
  899. duration = (double)(stop - start)/CLOCKS_PER_SEC;
  900. return (duration);
  901. }
  902. /*****************************************************************************
  903. TL_CreatePath
  904. *****************************************************************************/
  905. void TL_CreatePath(const char* inPath)
  906. {
  907. char* ptr;
  908. char dirPath[TL_MAXPATH];
  909. // prime and skip to first seperator
  910. strcpy(dirPath, inPath);
  911. ptr = strchr(dirPath, '\\');
  912. while (ptr)
  913. {
  914. ptr = strchr(ptr+1, '\\');
  915. if (ptr)
  916. {
  917. *ptr = '\0';
  918. mkdir(dirPath);
  919. *ptr = '\\';
  920. }
  921. }
  922. }
  923. /*****************************************************************************
  924. TL_Warning
  925. *****************************************************************************/
  926. void TL_Warning(const char* format, ...)
  927. {
  928. char msg[4096];
  929. va_list argptr;
  930. if (g_tl_quiet)
  931. return;
  932. va_start(argptr, format);
  933. vsprintf(msg, format, argptr);
  934. va_end(argptr);
  935. printf("WARNING: %s", msg);
  936. }
  937. /*****************************************************************************
  938. TL_printf
  939. *****************************************************************************/
  940. void TL_printf(const char* format, ...)
  941. {
  942. char msg[4096];
  943. va_list argptr;
  944. if (g_tl_quiet)
  945. return;
  946. va_start(argptr, format);
  947. vsprintf(msg, format, argptr);
  948. va_end(argptr);
  949. printf(msg);
  950. }
  951. //-----------------------------------------------------------------------------
  952. // TL_IsWildcardMatch
  953. //
  954. // See if a string matches a wildcard specification that uses * or ?
  955. //-----------------------------------------------------------------------------
  956. bool TL_IsWildcardMatch( const char *wildcardString, const char *stringToCheck, bool caseSensitive )
  957. {
  958. char wcChar;
  959. char strChar;
  960. // use the starMatchesZero variable to determine whether an asterisk
  961. // matches zero or more characters ( TRUE ) or one or more characters
  962. // ( FALSE )
  963. bool starMatchesZero = true;
  964. while ( ( strChar = *stringToCheck ) && ( wcChar = *wildcardString ) )
  965. {
  966. // we only want to advance the pointers if we successfully assigned
  967. // both of our char variables, so we'll do it here rather than in the
  968. // loop condition itself
  969. *stringToCheck++;
  970. *wildcardString++;
  971. // if this isn't a case-sensitive match, make both chars uppercase
  972. // ( thanks to David John Fielder ( Konan ) at http://innuendo.ev.ca
  973. // for pointing out an error here in the original code )
  974. if ( !caseSensitive )
  975. {
  976. wcChar = toupper( wcChar );
  977. strChar = toupper( strChar );
  978. }
  979. // check the wcChar against our wildcard list
  980. switch ( wcChar )
  981. {
  982. // an asterisk matches zero or more characters
  983. case '*' :
  984. // do a recursive call against the rest of the string,
  985. // until we've either found a match or the string has
  986. // ended
  987. if ( starMatchesZero )
  988. *stringToCheck--;
  989. while ( *stringToCheck )
  990. {
  991. if ( TL_IsWildcardMatch( wildcardString, stringToCheck++, caseSensitive ) )
  992. return true;
  993. }
  994. break;
  995. // a question mark matches any single character
  996. case '?' :
  997. break;
  998. // if we fell through, we want an exact match
  999. default :
  1000. if ( wcChar != strChar )
  1001. return false;
  1002. break;
  1003. }
  1004. }
  1005. // if we have any asterisks left at the end of the wildcard string, we can
  1006. // advance past them if starMatchesZero is TRUE ( so "blah*" will match "blah" )
  1007. while ( ( *wildcardString ) && ( starMatchesZero ) )
  1008. {
  1009. if ( *wildcardString == '*' )
  1010. wildcardString++;
  1011. else
  1012. break;
  1013. }
  1014. // if we got to the end but there's still stuff left in either of our strings,
  1015. // return false; otherwise, we have a match
  1016. if ( ( *stringToCheck ) || ( *wildcardString ) )
  1017. return false;
  1018. else
  1019. return true;
  1020. }
  1021. //-----------------------------------------------------------------------------
  1022. // TL_CopyString
  1023. //
  1024. //-----------------------------------------------------------------------------
  1025. char *TL_CopyString( const char* pString )
  1026. {
  1027. int size = strlen( pString ) + 1;
  1028. char *pNewString = (char *)TL_Malloc( size );
  1029. memcpy( pNewString, pString, size );
  1030. return pNewString;
  1031. }