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.

507 lines
9.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: vcd_sound_check.cpp : Defines the entry point for the console application.
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include <stdio.h>
  8. #include <windows.h>
  9. #include <direct.h>
  10. #include "tier0/dbg.h"
  11. #include "utldict.h"
  12. #include "KeyValues.h"
  13. #include "cmdlib.h"
  14. #include "scriplib.h"
  15. #include "vstdlib/random.h"
  16. bool uselogfile = true;
  17. struct AnalysisData
  18. {
  19. CUtlSymbolTable symbols;
  20. };
  21. static AnalysisData g_Analysis;
  22. static CUniformRandomStream g_Random;
  23. IUniformRandomStream *random = &g_Random;
  24. static bool spewed = false;
  25. static bool preview = false;
  26. static bool parallel = false;
  27. static char g_szDesignation[ 256 ];
  28. static char outdir[ 256 ];
  29. static char rootdir[ 256 ];
  30. static int rootoffset = 0;
  31. int START_PAGE = 0;
  32. #define LINE_WIDTH 80
  33. #define LINES_PER_PAGE 45
  34. char *va( const char *fmt, ... )
  35. {
  36. static char string[ 8192 ];
  37. va_list va;
  38. va_start( va, fmt );
  39. vsprintf( string, fmt, va );
  40. va_end( va );
  41. return string;
  42. }
  43. SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg )
  44. {
  45. spewed = true;
  46. printf( "%s", pMsg );
  47. OutputDebugString( pMsg );
  48. if ( type == SPEW_ERROR )
  49. {
  50. printf( "\n" );
  51. OutputDebugString( "\n" );
  52. }
  53. return SPEW_CONTINUE;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Purpose:
  57. // Input : depth -
  58. // *fmt -
  59. // ... -
  60. //-----------------------------------------------------------------------------
  61. void vprint( int depth, const char *fmt, ... )
  62. {
  63. char string[ 8192 ];
  64. va_list va;
  65. va_start( va, fmt );
  66. vsprintf( string, fmt, va );
  67. va_end( va );
  68. FILE *fp = NULL;
  69. if ( uselogfile )
  70. {
  71. fp = fopen( "log.txt", "ab" );
  72. }
  73. while ( depth-- > 0 )
  74. {
  75. printf( " " );
  76. OutputDebugString( " " );
  77. if ( fp )
  78. {
  79. fprintf( fp, " " );
  80. }
  81. }
  82. ::printf( "%s", string );
  83. OutputDebugString( string );
  84. if ( fp )
  85. {
  86. char *p = string;
  87. while ( *p )
  88. {
  89. if ( *p == '\n' )
  90. {
  91. fputc( '\r', fp );
  92. }
  93. fputc( *p, fp );
  94. p++;
  95. }
  96. fclose( fp );
  97. }
  98. }
  99. void Con_Printf( const char *fmt, ... )
  100. {
  101. va_list args;
  102. static char output[1024];
  103. va_start( args, fmt );
  104. vprintf( fmt, args );
  105. vsprintf( output, fmt, args );
  106. vprint( 0, output );
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. //-----------------------------------------------------------------------------
  111. void printusage( void )
  112. {
  113. vprint( 0, "usage: paginate startpage \"designation\" <root directory> [<outdir>]\n\
  114. \t-p = preview only\n\
  115. \ne.g.: paginate -p 700000 \"Confidential\" u:/production u:/production_numbered" );
  116. // Exit app
  117. exit( 1 );
  118. }
  119. void BuildFileList_R( CUtlVector< CUtlSymbol >& files, char const *dir, char const *extension )
  120. {
  121. WIN32_FIND_DATA wfd;
  122. char directory[ 256 ];
  123. char filename[ 256 ];
  124. HANDLE ff;
  125. sprintf( directory, "%s\\*.*", dir );
  126. if ( ( ff = FindFirstFile( directory, &wfd ) ) == INVALID_HANDLE_VALUE )
  127. return;
  128. int extlen = extension ? strlen( extension ) : 0 ;
  129. do
  130. {
  131. if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  132. {
  133. if ( wfd.cFileName[ 0 ] == '.' )
  134. continue;
  135. // Recurse down directory
  136. sprintf( filename, "%s\\%s", dir, wfd.cFileName );
  137. BuildFileList_R( files, filename, extension );
  138. }
  139. else
  140. {
  141. int len = strlen( wfd.cFileName );
  142. if ( len > extlen )
  143. {
  144. if ( !extension || !stricmp( &wfd.cFileName[ len - extlen ], extension ) )
  145. {
  146. char filename[ MAX_PATH ];
  147. Q_snprintf( filename, sizeof( filename ), "%s\\%s", dir, wfd.cFileName );
  148. _strlwr( filename );
  149. Q_FixSlashes( filename );
  150. CUtlSymbol sym = g_Analysis.symbols.AddString( filename );
  151. files.AddToTail( sym );
  152. if ( !( files.Count() % 3000 ) )
  153. {
  154. if( extension )
  155. {
  156. vprint( 0, "...found %i .%s files\n", files.Count(), extension );
  157. }
  158. else
  159. {
  160. vprint( 0, "...found %i files\n", files.Count() );
  161. }
  162. }
  163. }
  164. }
  165. }
  166. } while ( FindNextFile( ff, &wfd ) );
  167. }
  168. void BuildFileList( CUtlVector< CUtlSymbol >& files, char const *rootdir, char const *extension )
  169. {
  170. files.RemoveAll();
  171. BuildFileList_R( files, rootdir, extension );
  172. }
  173. struct PageStats_t
  174. {
  175. int linecount;
  176. int pagecount;
  177. int totalbytes;
  178. };
  179. void Paginate_CreatePath(const char *path)
  180. {
  181. char temppath[512];
  182. Q_strncpy( temppath, path, sizeof(temppath) );
  183. for (char *ofs = temppath+1 ; *ofs ; ofs++)
  184. {
  185. if (*ofs == '/' || *ofs == '\\')
  186. { // create the directory
  187. char old = *ofs;
  188. *ofs = 0;
  189. _mkdir (temppath);
  190. *ofs = old;
  191. }
  192. }
  193. }
  194. void PaginateFile( int startpage, PageStats_t *stats, char const *filename )
  195. {
  196. FILE *fp = fopen( filename, "rb" );
  197. if ( !fp )
  198. return;
  199. char outfn[ 256 ];
  200. Q_StripExtension( filename, outfn, sizeof( outfn ) );
  201. if ( parallel )
  202. {
  203. Q_snprintf( outfn, sizeof( outfn ), "%s/%s", outdir, &filename[ rootoffset ] );
  204. Q_FixSlashes( outfn );
  205. if ( !preview )
  206. {
  207. Paginate_CreatePath( outfn );
  208. }
  209. }
  210. else
  211. {
  212. Q_strncat( outfn, "_numbered.out", sizeof( outfn ), COPY_ALL_CHARACTERS );
  213. }
  214. FILE *outfile = NULL;
  215. if ( !preview )
  216. {
  217. outfile = fopen( outfn, "wb" );
  218. if ( !outfile )
  219. {
  220. vprint( 0, "Unable to open %s for writing\n", outfn );
  221. return;
  222. }
  223. }
  224. fseek( fp, 0, SEEK_END );
  225. int size = ftell( fp );
  226. fseek( fp, 0, SEEK_SET );
  227. char *buf = new char[ size + 1 ];
  228. if ( !buf )
  229. exit( -2 );
  230. fread( buf, size, 1, fp );
  231. fclose( fp );
  232. buf[ size ] = 0;
  233. stats->totalbytes += size;
  234. char *in = buf;
  235. int numlines = stats->linecount;
  236. int chars_on_line = 0;
  237. while ( 1 )
  238. {
  239. if ( !*in )
  240. break;
  241. if ( *in == '\n' )
  242. {
  243. ++stats->linecount;
  244. chars_on_line = 0;
  245. }
  246. if ( *in == '\t' )
  247. {
  248. if ( !preview )
  249. {
  250. fprintf( outfile, " " );
  251. }
  252. chars_on_line += 4;
  253. ++in;
  254. }
  255. if ( ( chars_on_line ) >= LINE_WIDTH )
  256. {
  257. chars_on_line = 0;
  258. ++stats->linecount;
  259. }
  260. if ( stats->linecount - numlines >= LINES_PER_PAGE )
  261. {
  262. ++stats->pagecount;
  263. numlines = stats->linecount;
  264. if ( !preview )
  265. {
  266. fprintf( outfile, "\r\n%s VLV%i\r\nPAGEBREAK\r\n",
  267. g_szDesignation,
  268. startpage + START_PAGE + stats->pagecount );
  269. }
  270. }
  271. if ( !preview )
  272. {
  273. fwrite( (void *)in, 1, 1, outfile );
  274. }
  275. ++chars_on_line;
  276. ++in;
  277. }
  278. // Final page number
  279. {
  280. ++stats->pagecount;
  281. numlines = stats->linecount;
  282. if ( !preview )
  283. {
  284. fprintf( outfile, "\r\n%s VLV%i\r\nPAGEBREAK\r\n",
  285. g_szDesignation,
  286. startpage + START_PAGE + stats->pagecount );
  287. }
  288. }
  289. if ( !preview )
  290. {
  291. fclose( outfile );
  292. }
  293. delete[] buf;
  294. }
  295. void PaginateFilesInDirectory( char const *rootdir )
  296. {
  297. CUtlVector< CUtlSymbol > files;
  298. BuildFileList( files, rootdir, NULL );
  299. vprint( 0, "Found %i files\n", files.Count() );
  300. PageStats_t stats;
  301. memset( &stats, 0, sizeof( stats ) );
  302. // Process files...
  303. int c = files.Count();
  304. vprint( 1, "%-160s\t%8s\t%10s\t%12s\t%35s\n",
  305. "filename",
  306. "pages",
  307. "lines",
  308. "size",
  309. "Bates#" );
  310. for ( int i = 0 ; i < c; ++i )
  311. {
  312. PageStats_t pagestats;
  313. memset( &pagestats, 0, sizeof( pagestats ) );
  314. char const *fn = g_Analysis.symbols.String( files[ i ] );
  315. PaginateFile( stats.pagecount, &pagestats, fn );
  316. char p1[ 32 ];
  317. char p2[ 32 ];
  318. Q_snprintf( p1, sizeof( p1 ), "VLV%i", START_PAGE + stats.pagecount + 1 );
  319. Q_snprintf( p2, sizeof( p2 ), "VLV%i", START_PAGE + stats.pagecount + pagestats.pagecount );
  320. vprint( 1, "%-160s\t%8i\t%10i\t%12s\t%35s\n",
  321. fn,
  322. pagestats.pagecount,
  323. pagestats.linecount,
  324. Q_pretifymem( pagestats.totalbytes, 2 ),
  325. va( "%s -> %s", p1, p2 ) );
  326. stats.linecount += pagestats.linecount;
  327. stats.pagecount += pagestats.pagecount;
  328. stats.totalbytes += pagestats.totalbytes;
  329. }
  330. vprint( 0, "Processed %s\n", Q_pretifymem( stats.totalbytes, 2 ));
  331. vprint( 0, "Line count %i\n", stats.linecount );
  332. vprint( 0, "Page count %i\n", stats.pagecount );
  333. vprint( 0, "Final Bates # %d\n", START_PAGE + stats.pagecount );
  334. }
  335. //-----------------------------------------------------------------------------
  336. // Purpose:
  337. //-----------------------------------------------------------------------------
  338. void CheckLogFile( void )
  339. {
  340. if ( uselogfile )
  341. {
  342. _unlink( "log.txt" );
  343. vprint( 0, " Outputting to log.txt\n" );
  344. }
  345. }
  346. void PrintHeader()
  347. {
  348. vprint( 0, "Valve Software - paginate.exe (%s)\n", __DATE__ );
  349. vprint( 0, "--- Insert Bates #'s for the lawyers ---\n" );
  350. }
  351. //-----------------------------------------------------------------------------
  352. // Purpose:
  353. // Input : argc -
  354. // argv[] -
  355. // Output : int
  356. //-----------------------------------------------------------------------------
  357. int main( int argc, char* argv[] )
  358. {
  359. SpewOutputFunc( SpewFunc );
  360. SpewActivate( "paginate", 2 );
  361. Q_strncpy( g_szDesignation, "Confidential - Attorney's Eyes Only", sizeof( g_szDesignation ) );
  362. int i=1;
  363. for ( i ; i<argc ; i++)
  364. {
  365. if ( argv[ i ][ 0 ] == '-' )
  366. {
  367. switch( argv[ i ][ 1 ] )
  368. {
  369. case 'p':
  370. preview = true;
  371. break;
  372. default:
  373. printusage();
  374. break;
  375. }
  376. }
  377. }
  378. if ( argc < 4 || ( i != argc ) )
  379. {
  380. PrintHeader();
  381. printusage();
  382. }
  383. outdir[ 0 ] = 0;
  384. if ( argc == 6 || ( argc == 5 && !preview ) )
  385. {
  386. --i;
  387. Q_strncpy( outdir, argv[ argc - 1 ], sizeof( outdir ) );
  388. parallel = true;
  389. --argc;
  390. }
  391. START_PAGE = atoi( argv[ argc - 3 ] );
  392. if ( START_PAGE == 0 )
  393. {
  394. PrintHeader();
  395. printusage();
  396. }
  397. Q_strncpy( g_szDesignation, argv[ argc - 2 ], sizeof( g_szDesignation ) );
  398. CheckLogFile();
  399. PrintHeader();
  400. vprint( 0, " Paginating and Bates numbering documents...\n" );
  401. strcpy( rootdir, argv[ argc - 1 ] );
  402. Q_FixSlashes( rootdir );
  403. Q_strlower( rootdir );
  404. Q_StripTrailingSlash( rootdir );
  405. rootoffset = Q_strlen( rootdir ) + 1;
  406. vprint( 0, "dir %s\n\n", rootdir );
  407. PaginateFilesInDirectory( rootdir );
  408. return 0;
  409. }