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.

1090 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // SYS_UTILS.C
  4. //
  5. //=====================================================================================//
  6. #include "vxconsole.h"
  7. CHAR g_szRegistryPrefix[256];
  8. //-----------------------------------------------------------------------------
  9. // Sys_SetRegistryPrefix
  10. //
  11. //-----------------------------------------------------------------------------
  12. void Sys_SetRegistryPrefix( const CHAR *pPrefix )
  13. {
  14. _snprintf_s( g_szRegistryPrefix, sizeof( g_szRegistryPrefix ), _TRUNCATE, pPrefix );
  15. }
  16. //-----------------------------------------------------------------------------
  17. // Sys_SplitRegistryKey
  18. //
  19. //-----------------------------------------------------------------------------
  20. static BOOL Sys_SplitRegistryKey( const CHAR *key, CHAR *key0, int key0Len, CHAR *key1, int key1Len )
  21. {
  22. if ( !key )
  23. {
  24. return false;
  25. }
  26. int len = (int)strlen( key );
  27. if ( !len )
  28. {
  29. return false;
  30. }
  31. int Start = -1;
  32. for ( int i=len-1; i>=0; i-- )
  33. {
  34. if ( key[i] == '\\' )
  35. break;
  36. else
  37. Start=i;
  38. }
  39. if ( Start == -1 )
  40. return false;
  41. _snprintf_s( key0, Start, _TRUNCATE, key );
  42. _snprintf_s( key1, ( len-Start )+1, _TRUNCATE, key+Start );
  43. return true;
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Sys_SetRegistryString
  47. //
  48. //-----------------------------------------------------------------------------
  49. BOOL Sys_SetRegistryString( const CHAR *keyName, const CHAR *value )
  50. {
  51. HKEY hKey;
  52. CHAR key0[256];
  53. CHAR key1[256];
  54. CHAR keyBuff[256];
  55. CHAR *key;
  56. strcpy_s( keyBuff, sizeof( keyBuff ), g_szRegistryPrefix );
  57. strcat_s( keyBuff, sizeof( keyBuff ), keyName );
  58. key = keyBuff;
  59. HKEY hSlot = HKEY_CURRENT_USER;
  60. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  61. {
  62. hSlot = HKEY_LOCAL_MACHINE;
  63. key += 19;
  64. }
  65. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  66. {
  67. hSlot = HKEY_CURRENT_USER;
  68. key += 18;
  69. }
  70. if ( !Sys_SplitRegistryKey( key, key0, sizeof( key0 ), key1, sizeof( key1 ) ) )
  71. return false;
  72. if ( RegCreateKeyEx( hSlot,key0,NULL,NULL,REG_OPTION_NON_VOLATILE, value ? KEY_WRITE : KEY_ALL_ACCESS,NULL,&hKey,NULL )!=ERROR_SUCCESS )
  73. return false;
  74. if ( RegSetValueEx( hKey, key1, NULL, REG_SZ, ( UCHAR* )value, (int)strlen( value ) + 1 ) != ERROR_SUCCESS )
  75. {
  76. RegCloseKey( hKey );
  77. return false;
  78. }
  79. // success
  80. RegCloseKey( hKey );
  81. return true;
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Sys_GetRegistryString
  85. //
  86. //-----------------------------------------------------------------------------
  87. BOOL Sys_GetRegistryString( const CHAR *keyName, CHAR *value, const CHAR* defValue, int valueLen )
  88. {
  89. HKEY hKey;
  90. CHAR key0[256];
  91. CHAR key1[256];
  92. CHAR keyBuff[256];
  93. CHAR *key;
  94. strcpy_s( keyBuff, sizeof( keyBuff ), g_szRegistryPrefix );
  95. strcat_s( keyBuff, sizeof( keyBuff ), keyName );
  96. key = keyBuff;
  97. if ( defValue )
  98. {
  99. _snprintf_s( value, valueLen, _TRUNCATE, defValue );
  100. }
  101. HKEY hSlot = HKEY_CURRENT_USER;
  102. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  103. {
  104. hSlot = HKEY_LOCAL_MACHINE;
  105. key += 19;
  106. }
  107. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  108. {
  109. hSlot = HKEY_CURRENT_USER;
  110. key += 18;
  111. }
  112. if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
  113. return false;
  114. if ( RegOpenKeyEx( hSlot,key0,NULL,KEY_READ,&hKey )!=ERROR_SUCCESS )
  115. return false;
  116. unsigned long len=valueLen;
  117. if ( RegQueryValueEx( hKey,key1,NULL,NULL,( UCHAR* )value,&len )!=ERROR_SUCCESS )
  118. {
  119. RegCloseKey( hKey );
  120. return false;
  121. }
  122. // success
  123. RegCloseKey( hKey );
  124. return true;
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Sys_SetRegistryInteger
  128. //
  129. //-----------------------------------------------------------------------------
  130. BOOL Sys_SetRegistryInteger( const CHAR *keyName, int value )
  131. {
  132. HKEY hKey;
  133. CHAR key0[256];
  134. CHAR key1[256];
  135. CHAR keyBuff[256];
  136. CHAR *key;
  137. strcpy_s( keyBuff, sizeof( keyBuff ), g_szRegistryPrefix );
  138. strcat_s( keyBuff, sizeof( keyBuff ), keyName );
  139. key = keyBuff;
  140. HKEY hSlot = HKEY_CURRENT_USER;
  141. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  142. {
  143. hSlot = HKEY_LOCAL_MACHINE;
  144. key += 19;
  145. }
  146. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  147. {
  148. hSlot = HKEY_CURRENT_USER;
  149. key += 18;
  150. }
  151. if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
  152. return false;
  153. if ( RegCreateKeyEx( hSlot, key0, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL )!=ERROR_SUCCESS )
  154. return false;
  155. if ( RegSetValueEx( hKey, key1, NULL, REG_DWORD, ( UCHAR* )&value, 4 )!=ERROR_SUCCESS )
  156. {
  157. RegCloseKey( hKey );
  158. return false;
  159. }
  160. // success
  161. RegCloseKey( hKey );
  162. return true;
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Sys_GetRegistryInteger
  166. //
  167. //-----------------------------------------------------------------------------
  168. BOOL Sys_GetRegistryInteger( const CHAR *keyName, int defValue, int &value )
  169. {
  170. HKEY hKey;
  171. CHAR key0[256];
  172. CHAR key1[256];
  173. CHAR keyBuff[256];
  174. CHAR *key;
  175. strcpy_s( keyBuff, sizeof( keyBuff ), g_szRegistryPrefix );
  176. strcat_s( keyBuff, sizeof( keyBuff ), keyName );
  177. key = keyBuff;
  178. value = defValue;
  179. HKEY hSlot = HKEY_CURRENT_USER;
  180. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  181. {
  182. hSlot = HKEY_LOCAL_MACHINE;
  183. key += 19;
  184. }
  185. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  186. {
  187. hSlot = HKEY_CURRENT_USER;
  188. key += 18;
  189. }
  190. if ( !Sys_SplitRegistryKey( key, key0, 256, key1, 256 ) )
  191. return false;
  192. if ( RegOpenKeyEx( hSlot, key0, NULL, KEY_READ, &hKey ) != ERROR_SUCCESS )
  193. return false;
  194. unsigned long len=4;
  195. if ( RegQueryValueEx( hKey, key1, NULL, NULL, ( UCHAR* )&value, &len ) != ERROR_SUCCESS )
  196. {
  197. RegCloseKey( hKey );
  198. return false;
  199. }
  200. // success
  201. RegCloseKey( hKey );
  202. return true;
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Sys_MessageBox
  206. //
  207. //-----------------------------------------------------------------------------
  208. void Sys_MessageBox( const CHAR* title, const CHAR* format, ... )
  209. {
  210. CHAR msg[2048];
  211. va_list argptr;
  212. va_start( argptr, format );
  213. vsprintf_s( msg, sizeof( msg ), format, argptr );
  214. va_end( argptr );
  215. MessageBox( NULL, msg, title, MB_OK|MB_TASKMODAL|MB_TOPMOST );
  216. }
  217. //-----------------------------------------------------------------------------
  218. // Sys_CopyString
  219. //
  220. //-----------------------------------------------------------------------------
  221. CHAR* Sys_CopyString( const CHAR* str )
  222. {
  223. int len = (int)strlen( str );
  224. CHAR *ptr = ( CHAR* )Sys_Alloc( len+1 );
  225. memcpy( ptr,str,len+1 );
  226. return ( ptr );
  227. }
  228. //-----------------------------------------------------------------------------
  229. // Sys_Alloc
  230. //
  231. //-----------------------------------------------------------------------------
  232. void* Sys_Alloc( int size )
  233. {
  234. int* ptr;
  235. if ( !size )
  236. {
  237. Sys_Error( "Sys_Alloc(): zero size" );
  238. }
  239. size = AlignValue( size, 4 );
  240. // allocate fixed zero init block
  241. ptr = ( int* )malloc( size );
  242. if ( !ptr )
  243. {
  244. Sys_Error( "Sys_Alloc(): %d bytes not available",size );
  245. }
  246. V_memset( ptr, 0, size );
  247. return ptr;
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Sys_Free
  251. //
  252. //-----------------------------------------------------------------------------
  253. void Sys_Free( void* ptr )
  254. {
  255. if ( !ptr )
  256. {
  257. // already freed - easier for me, not really an error
  258. return;
  259. }
  260. free( ptr );
  261. }
  262. //-----------------------------------------------------------------------------
  263. // Sys_Error
  264. //
  265. //-----------------------------------------------------------------------------
  266. void Sys_Error( const CHAR* format, ... )
  267. {
  268. va_list argptr;
  269. CHAR msg[MAX_SYSPRINTMSG];
  270. va_start( argptr, format );
  271. vsprintf_s( msg, sizeof( msg ), format, argptr );
  272. va_end( argptr );
  273. MessageBox( NULL, msg, "FATAL ERROR", MB_OK|MB_ICONHAND );
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Sys_LoadFile
  277. //
  278. //-----------------------------------------------------------------------------
  279. int Sys_LoadFile( const CHAR* filename, void** bufferptr, bool bText )
  280. {
  281. int handle;
  282. long length;
  283. CHAR* buffer;
  284. *bufferptr = NULL;
  285. if ( !Sys_Exists( filename ) )
  286. {
  287. return ( -1 );
  288. }
  289. int openFlags = bText ? _O_TEXT : _O_BINARY;
  290. _sopen_s( &handle, filename, _O_RDONLY|openFlags, _SH_DENYWR, _S_IREAD );
  291. if ( handle == -1 )
  292. {
  293. char szError[MAX_PATH];
  294. strerror_s( szError, sizeof( szError ), errno );
  295. Sys_Error( "Sys_LoadFile(): Error opening %s: %s", filename, szError );
  296. }
  297. // allocate a buffer with an auto null terminator
  298. length = Sys_FileLength( handle );
  299. buffer = ( CHAR* )Sys_Alloc( length+1 );
  300. int numBytesRead = _read( handle, buffer, length );
  301. _close( handle );
  302. if ( bText )
  303. {
  304. length = numBytesRead;
  305. }
  306. else if ( length != numBytesRead )
  307. {
  308. Sys_Error( "Sys_LoadFile(): read failure" );
  309. }
  310. // for parsing
  311. buffer[length] = '\0';
  312. *bufferptr = ( void* )buffer;
  313. return ( length );
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Sys_SaveFile
  317. //
  318. //-----------------------------------------------------------------------------
  319. bool Sys_SaveFile( const CHAR* filename, void* buffer, long count, bool bText )
  320. {
  321. int handle;
  322. int status;
  323. int openFlags = bText ? _O_TEXT : _O_BINARY;
  324. _sopen_s( &handle, filename, _O_RDWR|_O_CREAT|_O_TRUNC|openFlags, _SH_DENYNO, _S_IREAD|_S_IWRITE );
  325. if ( handle == -1 )
  326. {
  327. char szError[MAX_PATH];
  328. strerror_s( szError, sizeof( szError ), errno );
  329. Sys_Error( "Sys_SaveFile(): Error opening %s: %s", filename, szError );
  330. return false;
  331. }
  332. status = _write( handle, buffer, count );
  333. if ( status != count )
  334. {
  335. Sys_Error( "Sys_SaveFile(): write failure %d, errno=%d", status, errno );
  336. return false;
  337. }
  338. _close( handle );
  339. return true;
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Sys_FileLength
  343. //
  344. //-----------------------------------------------------------------------------
  345. long Sys_FileLength( const CHAR* filename, bool bText )
  346. {
  347. long length;
  348. if ( filename )
  349. {
  350. int handle;
  351. int openFlags = bText ? _O_TEXT : _O_BINARY;
  352. _sopen_s( &handle, filename, _O_RDONLY|openFlags, _SH_DENYWR, _S_IREAD );
  353. if ( handle == -1 )
  354. {
  355. // file does not exist
  356. return -1;
  357. }
  358. length = _lseek( handle, 0, SEEK_END );
  359. _close( handle );
  360. }
  361. else
  362. {
  363. return -1;
  364. }
  365. return length;
  366. }
  367. //-----------------------------------------------------------------------------
  368. // Sys_FileLength
  369. //
  370. //-----------------------------------------------------------------------------
  371. long Sys_FileLength( int handle )
  372. {
  373. long pos;
  374. long length;
  375. if ( handle != -1 )
  376. {
  377. pos = _lseek( handle, 0, SEEK_CUR );
  378. length = _lseek( handle, 0, SEEK_END );
  379. _lseek( handle, pos, SEEK_SET );
  380. }
  381. else
  382. {
  383. return -1;
  384. }
  385. return length;
  386. }
  387. //-----------------------------------------------------------------------------
  388. // Sys_NormalizePath
  389. //
  390. //-----------------------------------------------------------------------------
  391. void Sys_NormalizePath( CHAR* path, bool forceToLower )
  392. {
  393. int i;
  394. int srclen;
  395. srclen = (int)strlen( path );
  396. for ( i=0; i<srclen; i++ )
  397. {
  398. if ( path[i] == '/' )
  399. path[i] = '\\';
  400. else if ( forceToLower && ( path[i] >= 'A' && path[i] <= 'Z' ) )
  401. path[i] = path[i] - 'A' + 'a';
  402. }
  403. }
  404. //-----------------------------------------------------------------------------
  405. // Sys_AddFileSeperator
  406. //
  407. //-----------------------------------------------------------------------------
  408. void Sys_AddFileSeperator( CHAR* path, int pathLen )
  409. {
  410. int srclen;
  411. if ( !path[0] )
  412. {
  413. strcpy_s( path, pathLen, ".\\" );
  414. return;
  415. }
  416. srclen = (int)strlen( path );
  417. if ( path[srclen-1] == '\\' )
  418. {
  419. return;
  420. }
  421. strcat_s( path, pathLen, "\\" );
  422. }
  423. //-----------------------------------------------------------------------------
  424. // Sys_StripFilename
  425. //
  426. // Removes filename from path.
  427. //-----------------------------------------------------------------------------
  428. void Sys_StripFilename( const CHAR* inpath, CHAR* outpath, int outPathLen )
  429. {
  430. int length;
  431. strcpy_s( outpath, outPathLen, inpath );
  432. length = (int)strlen( outpath )-1;
  433. while ( ( length > 0 ) && ( outpath[length] != '\\' ) && ( outpath[length] != '/' ) && ( outpath[length] != ':' ) )
  434. length--;
  435. // leave possible seperator
  436. if ( !length )
  437. outpath[0] = '\0';
  438. else
  439. outpath[length+1] = '\0';
  440. }
  441. //-----------------------------------------------------------------------------
  442. // Sys_StripExtension
  443. //
  444. // Removes extension from path.
  445. //-----------------------------------------------------------------------------
  446. void Sys_StripExtension( const CHAR* inpath, CHAR* outpath, int outPathLen )
  447. {
  448. int length;
  449. strcpy_s( outpath, outPathLen, inpath );
  450. length = (int)strlen( outpath )-1;
  451. while ( length > 0 && outpath[length] != '.' )
  452. {
  453. length--;
  454. }
  455. if ( length && outpath[length] == '.' )
  456. {
  457. outpath[length] = '\0';
  458. }
  459. }
  460. //-----------------------------------------------------------------------------
  461. // Sys_StripPath
  462. //
  463. // Removes path from full path.
  464. //-----------------------------------------------------------------------------
  465. void Sys_StripPath( const CHAR* inpath, CHAR* outpath, int outPathLen )
  466. {
  467. const CHAR* src;
  468. src = inpath + strlen( inpath );
  469. while ( ( src != inpath ) && ( *( src-1 ) != '\\' ) && ( *( src-1 ) != '/' ) && ( *( src-1 ) != ':' ) )
  470. {
  471. src--;
  472. }
  473. strcpy_s( outpath, outPathLen, src );
  474. }
  475. //-----------------------------------------------------------------------------
  476. // Sys_GetExtension
  477. //
  478. // Gets any extension from the full path.
  479. //-----------------------------------------------------------------------------
  480. void Sys_GetExtension( const CHAR* inpath, CHAR* outpath, int outPathLen )
  481. {
  482. const CHAR* src;
  483. src = inpath + strlen( inpath ) - 1;
  484. // back up until a . or the start
  485. while ( src != inpath && *( src-1 ) != '.' )
  486. {
  487. src--;
  488. }
  489. if ( src == inpath )
  490. {
  491. *outpath = '\0'; // no extension
  492. return;
  493. }
  494. strcpy_s( outpath, outPathLen, src );
  495. }
  496. //-----------------------------------------------------------------------------
  497. // Sys_AddExtension
  498. //
  499. // Adds extension to end of path.
  500. //-----------------------------------------------------------------------------
  501. void Sys_AddExtension( const CHAR* extension, CHAR* outpath, int outPathLen )
  502. {
  503. CHAR* src;
  504. if ( outpath[0] )
  505. {
  506. src = outpath + strlen( outpath ) - 1;
  507. while ( ( src != outpath ) && ( *src != '\\' ) && ( *src != '/' ) )
  508. {
  509. if ( *src == '.' )
  510. return;
  511. src--;
  512. }
  513. }
  514. strcat_s( outpath, outPathLen, extension );
  515. }
  516. //-----------------------------------------------------------------------------
  517. // Sys_TempFilename
  518. //
  519. // Make a temporary filename at specified path.
  520. //-----------------------------------------------------------------------------
  521. void Sys_TempFilename( CHAR* temppath, int tempPathLen )
  522. {
  523. CHAR* ptr;
  524. ptr = _tempnam( "c:\\", "tmp" );
  525. strcpy_s( temppath, tempPathLen, ptr );
  526. free( ptr );
  527. }
  528. //-----------------------------------------------------------------------------
  529. // Sys_Exists
  530. //
  531. // Returns TRUE if file exists.
  532. //-----------------------------------------------------------------------------
  533. BOOL Sys_Exists( const CHAR* filename )
  534. {
  535. FILE* test;
  536. fopen_s( &test, filename, "rb" );
  537. if ( test == NULL )
  538. {
  539. return false;
  540. }
  541. fclose( test );
  542. return true;
  543. }
  544. //-----------------------------------------------------------------------------
  545. // Sys_SkipWhitespace
  546. //
  547. //-----------------------------------------------------------------------------
  548. CHAR* Sys_SkipWhitespace( CHAR *data, BOOL *hasNewLines, int* numlines )
  549. {
  550. int c;
  551. while( ( c = *data ) <= ' ' )
  552. {
  553. if ( c == '\n' )
  554. {
  555. if ( numlines )
  556. ( *numlines )++;
  557. if ( hasNewLines )
  558. *hasNewLines = true;
  559. }
  560. else if ( !c )
  561. return ( NULL );
  562. data++;
  563. }
  564. return ( data );
  565. }
  566. //-----------------------------------------------------------------------------
  567. // Sys_GetToken
  568. //
  569. //-----------------------------------------------------------------------------
  570. CHAR* Sys_GetToken( CHAR** dataptr, BOOL allowLineBreaks, int* numlines )
  571. {
  572. CHAR c;
  573. int len;
  574. BOOL hasNewLines;
  575. CHAR* data;
  576. static CHAR token[MAX_SYSTOKENCHARS];
  577. if ( numlines )
  578. *numlines = 0;
  579. c = 0;
  580. data = *dataptr;
  581. len = 0;
  582. token[0] = 0;
  583. hasNewLines = false;
  584. // make sure incoming data is valid
  585. if ( !data )
  586. {
  587. *dataptr = NULL;
  588. return ( token );
  589. }
  590. for ( ;; )
  591. {
  592. // skip whitespace
  593. data = Sys_SkipWhitespace( data,&hasNewLines,numlines );
  594. if ( !data )
  595. {
  596. *dataptr = NULL;
  597. return ( token );
  598. }
  599. if ( hasNewLines && !allowLineBreaks )
  600. {
  601. *dataptr = data;
  602. return ( token );
  603. }
  604. c = *data;
  605. // skip double slash comments
  606. if ( c == '/' && data[1] == '/' )
  607. {
  608. data += 2;
  609. while ( *data && *data != '\n' )
  610. data++;
  611. }
  612. // skip /* */ comments
  613. else if ( c =='/' && data[1] == '*' )
  614. {
  615. data += 2;
  616. while ( *data && ( *data != '*' || data[1] != '/' ) )
  617. data++;
  618. if ( *data )
  619. data += 2;
  620. }
  621. else
  622. break;
  623. }
  624. // handle quoted strings
  625. if ( c == '\"' )
  626. {
  627. data++;
  628. for ( ;; )
  629. {
  630. c = *data++;
  631. if ( c == '\"' || !c )
  632. {
  633. token[len] = 0;
  634. *dataptr = ( CHAR* )data;
  635. return ( token );
  636. }
  637. if ( len < MAX_SYSTOKENCHARS )
  638. token[len++] = c;
  639. }
  640. }
  641. // parse a regular word
  642. do
  643. {
  644. if ( len < MAX_SYSTOKENCHARS )
  645. token[len++] = c;
  646. data++;
  647. c = *data;
  648. if ( c == '\n' && numlines )
  649. ( *numlines )++;
  650. } while ( c > ' ' );
  651. if ( len >= MAX_SYSTOKENCHARS )
  652. len = 0;
  653. token[len] = '\0';
  654. *dataptr = ( CHAR* ) data;
  655. return ( token );
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Sys_SkipBracedSection
  659. //
  660. // The next token should be an open brace.
  661. // Skips until a matching close brace is found.
  662. // Internal brace depths are properly skipped.
  663. //-----------------------------------------------------------------------------
  664. void Sys_SkipBracedSection( CHAR** dataptr, int* numlines )
  665. {
  666. CHAR* token;
  667. int depth;
  668. depth = 0;
  669. do
  670. {
  671. token = Sys_GetToken( dataptr, true, numlines );
  672. if ( token[1] == '\0' )
  673. {
  674. if ( token[0] == '{' )
  675. depth++;
  676. else if ( token[0] == '}' )
  677. depth--;
  678. }
  679. }
  680. while( depth && *dataptr );
  681. }
  682. //-----------------------------------------------------------------------------
  683. // Sys_SkipRestOfLine
  684. //
  685. //-----------------------------------------------------------------------------
  686. void Sys_SkipRestOfLine( CHAR** dataptr, int* numlines )
  687. {
  688. CHAR* p;
  689. int c;
  690. p = *dataptr;
  691. while ( ( c = *p++ ) != '\0' )
  692. {
  693. if ( c == '\n' )
  694. {
  695. if ( numlines )
  696. ( *numlines )++;
  697. break;
  698. }
  699. }
  700. *dataptr = p;
  701. }
  702. //-----------------------------------------------------------------------------
  703. // Sys_FileTime
  704. //
  705. // Returns a file's last write time
  706. //-----------------------------------------------------------------------------
  707. BOOL Sys_FileTime( CHAR* filename, FILETIME* time )
  708. {
  709. HANDLE hFile;
  710. hFile = CreateFile(
  711. filename,
  712. GENERIC_READ,
  713. FILE_SHARE_READ,
  714. NULL,
  715. OPEN_EXISTING,
  716. FILE_ATTRIBUTE_NORMAL,
  717. NULL );
  718. if ( hFile == INVALID_HANDLE_VALUE )
  719. return ( false );
  720. // Retrieve the file times for the file.
  721. if ( !GetFileTime( hFile, NULL, NULL, time ) )
  722. {
  723. CloseHandle( hFile );
  724. return ( false );
  725. }
  726. CloseHandle( hFile );
  727. return ( true );
  728. }
  729. //-----------------------------------------------------------------------------
  730. // Sys_GetSystemTime
  731. //
  732. // Current time marker in milliseconds
  733. //-----------------------------------------------------------------------------
  734. DWORD Sys_GetSystemTime( void )
  735. {
  736. LARGE_INTEGER qwTime;
  737. LARGE_INTEGER qwTicksPerSec;
  738. float msecsPerTick;
  739. // Get the frequency of the timer
  740. QueryPerformanceFrequency( &qwTicksPerSec );
  741. msecsPerTick = 1000.0f/( FLOAT )qwTicksPerSec.QuadPart;
  742. QueryPerformanceCounter( &qwTime );
  743. return ( ( DWORD )( msecsPerTick * ( FLOAT )qwTime.QuadPart ) );
  744. }
  745. //-----------------------------------------------------------------------------
  746. // Sys_ColorScale
  747. //
  748. //-----------------------------------------------------------------------------
  749. COLORREF Sys_ColorScale( COLORREF color, float scale )
  750. {
  751. int r;
  752. int g;
  753. int b;
  754. r = color & 0xFF;
  755. g = ( color >> 8 ) & 0xFF;
  756. b = ( color >> 16 ) & 0xFF;
  757. r = ( int )( ( float )r * scale );
  758. g = ( int )( ( float )g * scale );
  759. b = ( int )( ( float )b * scale );
  760. if ( r > 255 )
  761. r = 255;
  762. if ( g > 255 )
  763. g = 255;
  764. if ( b > 255 )
  765. b = 255;
  766. color = RGB( r, g, b );
  767. return ( color );
  768. }
  769. //-----------------------------------------------------------------------------
  770. // Sys_IsWildcardMatch
  771. //
  772. // See if a string matches a wildcard specification that uses * or ?
  773. //-----------------------------------------------------------------------------
  774. bool Sys_IsWildcardMatch( const CHAR *wildcardString, const CHAR *stringToCheck, bool caseSensitive )
  775. {
  776. CHAR wcChar;
  777. CHAR strChar;
  778. if ( !_stricmp( wildcardString, "*.*" ) || !_stricmp( wildcardString, "*" ) )
  779. {
  780. // matches everything
  781. return true;
  782. }
  783. // use the starMatchesZero variable to determine whether an asterisk
  784. // matches zero or more characters ( TRUE ) or one or more characters
  785. // ( FALSE )
  786. bool starMatchesZero = true;
  787. for ( ;; )
  788. {
  789. strChar = *stringToCheck;
  790. if ( !strChar )
  791. {
  792. break;
  793. }
  794. wcChar = *wildcardString;
  795. if ( !wcChar )
  796. {
  797. break;
  798. }
  799. // we only want to advance the pointers if we successfully assigned
  800. // both of our char variables, so we'll do it here rather than in the
  801. // loop condition itself
  802. *stringToCheck++;
  803. *wildcardString++;
  804. // if this isn't a case-sensitive match, make both chars uppercase
  805. // ( thanks to David John Fielder ( Konan ) at http://innuendo.ev.ca
  806. // for pointing out an error here in the original code )
  807. if ( !caseSensitive )
  808. {
  809. wcChar = (CHAR)toupper( wcChar );
  810. strChar = (CHAR)toupper( strChar );
  811. }
  812. // check the wcChar against our wildcard list
  813. switch ( wcChar )
  814. {
  815. // an asterisk matches zero or more characters
  816. case '*' :
  817. // do a recursive call against the rest of the string,
  818. // until we've either found a match or the string has
  819. // ended
  820. if ( starMatchesZero )
  821. *stringToCheck--;
  822. while ( *stringToCheck )
  823. {
  824. if ( Sys_IsWildcardMatch( wildcardString, stringToCheck++, caseSensitive ) )
  825. return true;
  826. }
  827. break;
  828. // a question mark matches any single character
  829. case '?' :
  830. break;
  831. // if we fell through, we want an exact match
  832. default :
  833. if ( wcChar != strChar )
  834. return false;
  835. break;
  836. }
  837. }
  838. // if we have any asterisks left at the end of the wildcard string, we can
  839. // advance past them if starMatchesZero is TRUE ( so "blah*" will match "blah" )
  840. while ( ( *wildcardString ) && ( starMatchesZero ) )
  841. {
  842. if ( *wildcardString == '*' )
  843. wildcardString++;
  844. else
  845. break;
  846. }
  847. // if we got to the end but there's still stuff left in either of our strings,
  848. // return false; otherwise, we have a match
  849. if ( ( *stringToCheck ) || ( *wildcardString ) )
  850. return false;
  851. else
  852. return true;
  853. }
  854. //-----------------------------------------------------------------------------
  855. // Sys_NumberToCommaString
  856. //
  857. // Add commas to number
  858. //-----------------------------------------------------------------------------
  859. char *Sys_NumberToCommaString( __int64 number, char *buffer, int bufferSize )
  860. {
  861. char temp[256];
  862. char temp2[256];
  863. int inLen;
  864. char *inPtr;
  865. char *outPtr;
  866. int i;
  867. sprintf_s( temp, sizeof( temp ), "%I64d", number );
  868. // build string backwards
  869. inLen = (int)strlen( temp );
  870. inPtr = temp+inLen-1;
  871. outPtr = temp2;
  872. while ( inLen > 0 )
  873. {
  874. for ( i=0; i<3 && inLen > 0; i++, inLen-- )
  875. {
  876. *outPtr++ = *inPtr--;
  877. }
  878. if ( inLen > 0 )
  879. *outPtr++ = ',';
  880. }
  881. *outPtr++ = '\0';
  882. // reverse string
  883. inLen = (int)strlen( temp2 );
  884. inPtr = temp2;
  885. outPtr = temp;
  886. for ( i=inLen-1; i>=0; i-- )
  887. {
  888. *outPtr++ = inPtr[i];
  889. }
  890. *outPtr++ = '\0';
  891. _snprintf_s( buffer, bufferSize, _TRUNCATE, temp );
  892. return buffer;
  893. }
  894. //-----------------------------------------------------------------------------
  895. // Sys_CreatePath
  896. //
  897. //-----------------------------------------------------------------------------
  898. void Sys_CreatePath( const char* pInPath )
  899. {
  900. char* ptr;
  901. char dirPath[MAX_PATH];
  902. // prime and skip to first seperator
  903. strcpy_s( dirPath, sizeof( dirPath ), pInPath );
  904. if ( dirPath[0] == '\\' && dirPath[1] == '\\' )
  905. {
  906. ptr = strchr( dirPath+1, '\\' );
  907. }
  908. else
  909. {
  910. ptr = strchr( dirPath, '\\' );
  911. }
  912. while ( ptr )
  913. {
  914. ptr = strchr( ptr+1, '\\' );
  915. if ( ptr )
  916. {
  917. *ptr = '\0';
  918. CreateDirectory( dirPath, NULL );
  919. *ptr = '\\';
  920. }
  921. }
  922. }