diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/mdlcheck | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/mdlcheck')
| -rw-r--r-- | utils/mdlcheck/mdlcheck.cpp | 515 | ||||
| -rw-r--r-- | utils/mdlcheck/mdlcheck.vpc | 66 | ||||
| -rw-r--r-- | utils/mdlcheck/mdlcheck_util.cpp | 424 | ||||
| -rw-r--r-- | utils/mdlcheck/mdlcheck_util.h | 31 | ||||
| -rw-r--r-- | utils/mdlcheck/stdafx.cpp | 15 | ||||
| -rw-r--r-- | utils/mdlcheck/stdafx.h | 26 |
6 files changed, 1077 insertions, 0 deletions
diff --git a/utils/mdlcheck/mdlcheck.cpp b/utils/mdlcheck/mdlcheck.cpp new file mode 100644 index 0000000..9808680 --- /dev/null +++ b/utils/mdlcheck/mdlcheck.cpp @@ -0,0 +1,515 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "stdafx.h" +#include <stdio.h> +#include <windows.h> +#include "mdlcheck_util.h" +#include "tier0/dbg.h" +#include "utldict.h" +#include "tier1/utlstring.h" + +bool uselogfile = false; +bool verbose = false; +bool checkani = false; + +struct QCFile +{ + char outputmodel[ MAX_PATH ]; +}; + +struct ModelFile +{ + char qcfile[ MAX_PATH ]; + int version; + bool needsrecompile; + int toobig; +}; + +struct AnalysisData +{ + CUtlDict< QCFile, int > files; // .qc to modelname lookup + CUtlDict< ModelFile, int > models; // .mdl to .qc/version lookup + + CUtlSymbolTable symbols; +}; + +static AnalysisData g_Analysis; + + +SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg ) +{ + printf( "%s", pMsg ); + OutputDebugString( pMsg ); + + if ( type == SPEW_ERROR ) + { + printf( "\n" ); + OutputDebugString( "\n" ); + } + + return SPEW_CONTINUE; +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void printusage( void ) +{ + vprint( 0, "usage: mdlcheck <model source directory> <.mdl file directory>\n\ + \t-v = verbose output\n\ + \t-l = log to file log.txt\n\ + \t-a = check for large animation data\n\ + \ne.g.: mdlcheck -l u:/hl2/hl2/hl2models u:/hl2/hl2/models\n" ); + + // Exit app + exit( 1 ); +} + +void BuildFileList_R( CUtlVector< CUtlSymbol >& files, char const *dir, char const *extension ) +{ + WIN32_FIND_DATA wfd; + + char directory[ 256 ]; + char filename[ 256 ]; + HANDLE ff; + + sprintf( directory, "%s\\*.*", dir ); + + if ( ( ff = FindFirstFile( directory, &wfd ) ) == INVALID_HANDLE_VALUE ) + return; + + int extlen = strlen( extension ); + + do + { + if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + + if ( wfd.cFileName[ 0 ] == '.' ) + continue; + + // Recurse down directory + sprintf( filename, "%s\\%s", dir, wfd.cFileName ); + BuildFileList_R( files, filename, extension ); + } + else + { + int len = strlen( wfd.cFileName ); + if ( len > extlen ) + { + if ( strstr( wfd.cFileName, ".360." ) ) + { + } + else if ( !stricmp( &wfd.cFileName[ len - extlen ], extension ) ) + { + char filename[ MAX_PATH ]; + Q_snprintf( filename, sizeof( filename ), "%s\\%s", dir, wfd.cFileName ); + _strlwr( filename ); + + Q_FixSlashes( filename ); + + CUtlSymbol sym = g_Analysis.symbols.AddString( filename ); + files.AddToTail( sym ); + } + } + } + } while ( FindNextFile( ff, &wfd ) ); +} + +void BuildFileList( CUtlVector< CUtlSymbol >& files, char const *rootdir, char const *extension ) +{ + files.RemoveAll(); + BuildFileList_R( files, rootdir, extension ); +} + +//----------------------------------------------------------------------------- +// This is here because scriplib.cpp is included in this project but cmdlib.cpp +// is not, but scriplib.cpp uses some stuff from cmdlib.cpp, same with +// LoadFile and ExpandPath above. The only thing that currently uses this +// is $include in scriptlib, if this function returns 0, $include will +// behave the way it did before this change +//----------------------------------------------------------------------------- +int CmdLib_ExpandWithBasePaths( CUtlVector< CUtlString > &expandedPathList, const char *pszPath ) +{ + return 0; +} + + +bool GetModelNameFromSourceFile( char const *filename, char *modelname, int maxlen ) +{ + modelname[0]=0; + + int filelength; + char *buffer = (char *)COM_LoadFile( filename, &filelength ); + if ( !buffer ) + { + vprint( 0, "Couldn't load %s\n", filename ); + return false; + } + + bool valid = false; + + // Parse tokens + char *current = buffer; + while ( current ) + { + current = CC_ParseToken( current ); + if ( strlen( com_token ) <= 0 ) + break; + + if ( stricmp( com_token, "$modelname" ) ) + continue; + + current = CC_ParseToken( current ); + + strcpy( modelname, com_token ); + _strlwr( modelname ); + + Q_FixSlashes( modelname ); + + Q_DefaultExtension( modelname, ".mdl", maxlen ); + + valid = true; + break; + } + + COM_FreeFile( (unsigned char *)buffer ); + + if ( !valid ) + { + vprint_queued( 0, ".qc file %s missing $modelname directive!!!\n", filename ); + } + return valid; +} + +bool AddModelNameFromSource( CUtlDict< ModelFile, int >& models, char const *filename, char const *modelname, int offset ) +{ + int idx = models.Find( modelname ); + if ( idx != models.InvalidIndex() ) + { + char shortname[ MAX_PATH ]; + char shortname2[ MAX_PATH ]; + strcpy( shortname, &filename[ offset ] ); + strcpy( shortname2, &models[ idx ].qcfile[ offset ] ); + + vprint_queued( 0, "multiple .qc's build %s\n %s\n %s\n", + modelname, + shortname, + shortname2 ); + return false; + } + + ModelFile mf; + strcpy( mf.qcfile, filename ); + _strlwr( mf.qcfile ); + mf.version = 0; + + models.Insert( modelname, mf ); + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *sourcetreebase - +// *subdir - +// *baseentityclass - +//----------------------------------------------------------------------------- +void ProcessSourceDirectory( char const *basedir ) +{ + // vprint( 0, "building .qc list\n" ); + + CUtlVector< CUtlSymbol > files; + + BuildFileList( files, basedir, ".qc" ); + + // vprint( 0, "found %i .qc files\n\n", files.Count() ); + + int offset = strlen( basedir ) + 1; + + // Add files to QC Files dictionary + int c = files.Count(); + for ( int i = 0; i < c; i++ ) + { + QCFile qcf; + memset( &qcf, 0, sizeof( qcf ) ); + CUtlSymbol& sym = files[ i ]; + g_Analysis.files.Insert( g_Analysis.symbols.String( sym ), qcf ); + } + + vprint_queued( 0, "%s", "\n\n" ); + + // Now iterate .qc files, looking into each to find the output model name + c = g_Analysis.files.Count(); + int valid = 0; + for ( int i = 0; i < c; i++ ) + { + char modelname[ 256 ]; + char const *filename = g_Analysis.files.GetElementName( i ); + if ( verbose ) + { + vprint( 0, "checking %i: %s\n", i, filename ); + } + if ( GetModelNameFromSourceFile( filename, modelname, sizeof( modelname ) ) ) + { + if ( AddModelNameFromSource( g_Analysis.models, filename, modelname, offset ) ) + { + valid++; + } + } + } + + int ecount = c - valid; + if (ecount != 0) + { + // vprint( 0, "\n summary: found %i/%i (%.2f percent) .qc errors\n\n", ecount, c, 100.0 * ecount / max( c, 1 ) ); + vprint( 0, "\n summary: found %i .qc errors\n\n", ecount ); + } +} + +#include "studio.h" + +#define IDSTUDIOHEADER (('T'<<24)+('S'<<16)+('D'<<8)+'I') + // little-endian "IDST" +#define IDSTUDIOANIMGROUPHEADER (('G'<<24)+('A'<<16)+('D'<<8)+'I') + // little-endian "IDAG" + + +byte buffer[1024*1024*4]; +bool ValidateModelFile( char const *modelname, int offset ) +{ + studiohdr_t *pHdr; + FILE *fp; + + pHdr = (studiohdr_t *)buffer; + + fp = fopen( modelname, "rb" ); + if ( !fp ) + { + vprint_queued( 0, "Unable to open .mdl file %s\n", modelname ); + return false; + } + + // See if there's a .qc which builds this model + char shortname[ MAX_PATH ]; + strcpy( shortname, &modelname[ offset ] ); + + Q_FixSlashes( shortname ); + + fread( buffer, sizeof( buffer ), 1, fp ); + fclose( fp ); + + if ( pHdr->id != IDSTUDIOHEADER ) + { + vprint_queued( 0, "Bogus studiomdl header for %s, expecting 'IDST' four cc code\n", shortname ); + return false; + } + + bool valid = true; + bool needsrecompile = false; + int toobig = 0; + + // previous version is compatible + if ( pHdr->version < 44 || pHdr->version > STUDIO_VERSION ) + { + vprint_queued( 0, "Outdated model %s (ver %i != %i)\n", shortname, pHdr->version, STUDIO_VERSION ); + valid = false; + } + + if (!Studio_ConvertStudioHdrToNewVersion( pHdr )) + { + // vprint( 0, "%s needs to be recompiled\n", pHdr->pszName() ); + needsrecompile = true; + } + + if (checkani) + { + // HACK: since the sequence data is written after the animation data, this is rough way to determine how much anim data there really is + int totalanimsize = pHdr->localseqindex - pHdr->localanimindex - pHdr->numlocalanim * sizeof( mstudioanimdesc_t ); + if (pHdr->pLocalAnimdesc( 0 )->animblock == 0 && totalanimsize > 1024 * 64) + { + toobig = totalanimsize; + } + } + + int idx = g_Analysis.models.Find( shortname ); + if ( idx == g_Analysis.models.InvalidIndex() ) + { + vprint_queued( 0, "Couldn't find a .qc which builds %s\n", shortname ); + valid = false; + } + else + { + g_Analysis.models[idx].version = pHdr->version; + g_Analysis.models[idx].needsrecompile = needsrecompile; + g_Analysis.models[idx].toobig = toobig; + } + + + return valid; +} + +void ProcessModelsDirectory( char const *basedir ) +{ + // vprint( 0, "building .mdl list\n" ); + + CUtlVector< CUtlSymbol > models; + + BuildFileList( models, basedir, ".mdl" ); + + // vprint( 0, "found %i .mdl files\n\n", models.Count() ); + + int offset = strlen( basedir ) + 1; + + // Now iterate model files and check version tag and whether a .qc exists which builds the .mdl + + vprint_queued( 0, "%s", "\n\n" ); + + // Add files to QC Files dictionary + int c = models.Count(); + int valid = 0; + for ( int i = 0; i < c; i++ ) + { + QCFile qcf; + memset( &qcf, 0, sizeof( qcf ) ); + CUtlSymbol& sym = models[ i ]; + + char const *modelname = g_Analysis.symbols.String( sym ); + + if ( verbose ) + { + vprint( 0, "checking %i .mdl %s\n", i, modelname ); + } + + if ( ValidateModelFile( modelname, offset ) ) + { + valid++; + } + } + + int ecount = c - valid; + if (ecount != 0) + { + // vprint( 0, "\n summary: found %i/%i (%.2f percent) .mdl errors\n", ecount, c, 100.0 * ecount / max( c, 1 ) ); + vprint( 0, "\n summary: found %i .mdl errors\n", ecount ); + } +} + + + +void CheckForUnbuiltModels( ) +{ + vprint_queued( 0, "%s", "\n\n" ); + + int c = g_Analysis.models.Count(); + int valid = 0; + for ( int i = 0; i < c; i++ ) + { + if (g_Analysis.models[i].version == 0) + { + vprint_queued( 0, "Can't find %s,\n\tbuilt by %s\n", g_Analysis.models.GetElementName( i ), g_Analysis.models[i].qcfile ); + } + else if (g_Analysis.models[i].needsrecompile) + { + vprint_queued( 0, "%s out of date,\n\tbuilt by %s\n", g_Analysis.models.GetElementName( i ), g_Analysis.models[i].qcfile ); + } + else if (g_Analysis.models[i].toobig) + { + vprint_queued( 0, "%s needs $animblocksize command (%d of animdata),\n\tbuilt by %s\n", g_Analysis.models.GetElementName( i ), g_Analysis.models[i].toobig, g_Analysis.models[i].qcfile ); + } + else + { + valid++; + } + } + + int ecount = c - valid; + if (ecount != 0) + { + // vprint( 0, "\n summary: found %i/%i (%.2f percent) missing .mdl's\n", ecount, c, 100.0 * ecount / max( c, 1 ) ); + vprint( 0, "\n summary: found %i missing .mdl's\n", ecount ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CheckLogFile( void ) +{ + if ( uselogfile ) + { + _unlink( "log.txt" ); + vprint( 0, " Outputting to log.txt\n" ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : argc - +// argv[] - +// Output : int +//----------------------------------------------------------------------------- +int main( int argc, char* argv[] ) +{ + SpewOutputFunc( SpewFunc ); + + int i = 1; + for (i ; i<argc ; i++) + { + if ( argv[ i ][ 0 ] == '-' ) + { + switch( argv[ i ][ 1 ] ) + { + case 'l': + uselogfile = true; + break; + case 'v': + verbose = true; + break; + case 'a': + checkani = true; + break; + default: + printusage(); + break; + } + } + } + + vprint( 0, "Valve Software - mdlcheck.exe (%s)\n", __DATE__ ); + vprint( 0, "--- Source Model Consistency Checker ---\n" ); + + if ( argc < 3 || ( i != argc ) ) + { + printusage(); + } + + CheckLogFile(); + + char modelsources[ 256 ]; + strcpy( modelsources, argv[ i - 2 ] ); + char modelsdir[ 256 ]; + strcpy( modelsdir, argv[ i - 1 ] ); + + if ( !strstr( modelsdir, "models" ) ) + { + vprint( 0, "Models dir %s looks invalid (format: u:/tf2/hl2/models)\n", modelsdir ); + return 0; + } + + Q_StripTrailingSlash( modelsources ); + Q_StripTrailingSlash( modelsdir ); + + ProcessSourceDirectory( modelsources ); + ProcessModelsDirectory( modelsdir ); + CheckForUnbuiltModels( ); + + dump_print_queue( ); + + return 0; +} diff --git a/utils/mdlcheck/mdlcheck.vpc b/utils/mdlcheck/mdlcheck.vpc new file mode 100644 index 0000000..ad8dd1a --- /dev/null +++ b/utils/mdlcheck/mdlcheck.vpc @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// MDLCHECK.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\common" + $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)" + $PrecompiledHeaderFile "Debug/mdlcheck.pch" + } +} + +$Project "Mdlcheck" +{ + $Folder "Source Files" + { + -$File "$SRCDIR\public\tier0\memoverride.cpp" + $File "mdlcheck.cpp" + $File "mdlcheck_util.cpp" + $File "StdAfx.cpp" + { + $Configuration + { + $Compiler + { + $Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)" + } + } + } + } + + $Folder "Header Files" + { + $File "$SRCDIR\public\tier0\basetypes.h" + $File "$SRCDIR\public\tier0\commonmacros.h" + $File "$SRCDIR\public\tier0\dbg.h" + $File "$SRCDIR\public\tier0\fasttimer.h" + $File "$SRCDIR\public\mathlib\mathlib.h" + $File "mdlcheck_util.h" + $File "$SRCDIR\public\tier0\memdbgon.h" + $File "$SRCDIR\public\tier0\platform.h" + $File "$SRCDIR\public\tier0\protected_things.h" + $File "StdAfx.h" + $File "$SRCDIR\public\string_t.h" + $File "$SRCDIR\public\tier1\strtools.h" + $File "$SRCDIR\public\studio.h" + $File "$SRCDIR\public\tier1\utldict.h" + $File "$SRCDIR\public\tier1\utlmemory.h" + $File "$SRCDIR\public\tier1\utlrbtree.h" + $File "$SRCDIR\public\tier1\utlsymbol.h" + $File "$SRCDIR\public\tier1\utlvector.h" + $File "$SRCDIR\public\mathlib\vector.h" + $File "$SRCDIR\public\mathlib\vector2d.h" + $File "$SRCDIR\public\mathlib\vector4d.h" + $File "$SRCDIR\public\vstdlib\vstdlib.h" + } +} diff --git a/utils/mdlcheck/mdlcheck_util.cpp b/utils/mdlcheck/mdlcheck_util.cpp new file mode 100644 index 0000000..660c4ea --- /dev/null +++ b/utils/mdlcheck/mdlcheck_util.cpp @@ -0,0 +1,424 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#include "stdafx.h" +#include <io.h> +#include <stdio.h> +#include <windows.h> +#include "mdlcheck_util.h" +#include "tier0/dbg.h" +#include "utlvector.h" + +extern bool uselogfile; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : depth - +// *fmt - +// ... - +//----------------------------------------------------------------------------- +void vprint( int depth, const char *fmt, ... ) +{ + char string[ 8192 ]; + va_list va; + va_start( va, fmt ); + vsprintf( string, fmt, va ); + va_end( va ); + + FILE *fp = NULL; + + if ( uselogfile ) + { + fp = fopen( "log.txt", "ab" ); + } + + while ( depth-- > 0 ) + { + printf( " " ); + OutputDebugString( " " ); + if ( fp ) + { + fprintf( fp, " " ); + } + } + + ::printf( "%s", string ); + OutputDebugString( string ); + + if ( fp ) + { + char *p = string; + while ( *p ) + { + if ( *p == '\n' ) + { + fputc( '\r', fp ); + } + fputc( *p, fp ); + p++; + } + fclose( fp ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : depth - +// *fmt - +// ... - +//----------------------------------------------------------------------------- +CUtlVector< char * > printQueue; + +void vprint_queued( int depth, const char *fmt, ... ) +{ + char string[ 8192 ]; + strnset( string, ' ', depth * 2 ); + + va_list va; + va_start( va, fmt ); + vsprintf( &string[depth * 2], fmt, va ); + va_end( va ); + + printQueue.AddToTail( strdup( string ) ); +} + +void dump_print_queue( ) +{ + FILE *fp = NULL; + + if ( uselogfile ) + { + fp = fopen( "log.txt", "ab" ); + } + + for (int i = 0; i < printQueue.Count(); i++) + { + ::printf( "%s", printQueue[i] ); + OutputDebugString( printQueue[i] ); + + if ( fp ) + { + char *p = printQueue[i]; + while ( *p ) + { + if ( *p == '\n' ) + { + fputc( '\r', fp ); + } + fputc( *p, fp ); + p++; + } + } + } + if (fp) + { + fclose( fp ); + } + printQueue.RemoveAll(); +} + + + +bool com_ignorecolons = false; // YWB: Ignore colons as token separators in COM_Parse +bool com_ignoreinlinecomment = false; +static bool s_com_token_unget = false; +char com_token[1024]; +int linesprocessed = 0; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CC_UngetToken( void ) +{ + s_com_token_unget = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : ch - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CC_IsBreakChar( char ch ) +{ + bool brk = false; + switch ( ch ) + { + case '{': + case '}': + case ')': + case '(': + case '[': + case ']': +// case '\'': +// case '/': + case ',': + case ';': + case '<': + case '>': + brk = true; + break; + + case ':': + if ( !com_ignorecolons ) + brk = true; + break; + default: + break; + } + return brk; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *data - +// Output : char +//----------------------------------------------------------------------------- +char *CC_ParseToken(char *data) +{ + int c; + int len; + + if ( s_com_token_unget ) + { + s_com_token_unget = false; + return data; + } + + len = 0; + com_token[0] = 0; + + if (!data) + return NULL; + +// skip whitespace +skipwhite: + while ( (c = *data) <= ' ') + { + if (c == 0) + return NULL; // end of file; + if ( c== '\n' ) + { + linesprocessed++; + } + data++; + } + +// skip // comments + if ( !com_ignoreinlinecomment ) + { + if (c=='/' && data[1] == '/') + { + while (*data && *data != '\n') + data++; + goto skipwhite; + } + } + + if ( c == '/' && data[1] == '*' ) + { + while (data[0] && data[1] && !( data[0] == '*' && data[1] == '/' ) ) + { + if ( *data == '\n' ) + { + linesprocessed++; + } + data++; + } + + if ( data[0] == '*' && data[1] == '/' ) + { + data+=2; + } + goto skipwhite; + } + +// handle quoted strings specially + bool isLstring = data[0] == 'L' && (data[1] == '\"' ); + if ( isLstring ) + { + com_token[len++] = (char)c; + return data+1; + } + + if ( c == '\"' ) + { + data++; + bool bEscapeSequence = false; + while (1) + { + Assert( len < 1024 ); + c = *data++; + if ( (c=='\"' && !bEscapeSequence) || !c && len < sizeof( com_token ) - 1 ) + { + com_token[len] = 0; + return data; + } + bEscapeSequence = ( c == '\\' ); + com_token[len] = (char)c; + len++; + } + } + +// parse single characters + if ( CC_IsBreakChar( (char)c ) ) + { + Assert( len < 1024 ); + + com_token[len] = (char)c; + len++; + com_token[len] = 0; + return data+1; + } + +// parse a regular word + do + { + Assert( len < 1024 ); + + com_token[len] = (char)c; + data++; + len++; + c = *data; + + if ( CC_IsBreakChar( (char)c ) ) + break; + } while (c>32 && len < sizeof( com_token ) - 1); + + com_token[len] = 0; + return data; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// *len - +// Output : unsigned char +//----------------------------------------------------------------------------- +unsigned char *COM_LoadFile( const char *name, int *len) +{ + FILE *fp; + fp = fopen( name, "rb" ); + if ( !fp ) + { + *len = 0; + return NULL; + } + + fseek( fp, 0, SEEK_END ); + *len = ftell( fp ); + fseek( fp, 0, SEEK_SET ); + + unsigned char *buffer = new unsigned char[ *len + 1 ]; + fread( buffer, *len, 1, fp ); + fclose( fp ); + buffer[ *len ] = 0; + + return buffer; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *buffer - +//----------------------------------------------------------------------------- +void COM_FreeFile( unsigned char *buffer ) +{ + delete[] buffer; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *dir - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool COM_DirectoryExists( const char *dir ) +{ + if ( !_access( dir, 0 ) ) + return true; + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *input - +// Output : char +//----------------------------------------------------------------------------- +char *CC_ParseUntilEndOfLine( char *input ) +{ + while (*input && *input != '\n') + input++; + + return input; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *input - +// *ch - +// *breakchar - +// Output : char +//----------------------------------------------------------------------------- +char *CC_RawParseChar( char *input, const char *ch, char *breakchar ) +{ + bool done = false; + int listlen = strlen( ch ); + + do + { + input = CC_ParseToken( input ); + if ( strlen( com_token ) <= 0 ) + break; + + if ( strlen( com_token ) == 1 ) + { + for ( int i = 0; i < listlen; i++ ) + { + if ( com_token[ 0 ] == ch[ i ] ) + { + *breakchar = ch [ i ]; + done = true; + break; + } + } + } + } while ( !done ); + + return input; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *input - +// *pairing - +// Output : char +//----------------------------------------------------------------------------- +char *CC_DiscardUntilMatchingCharIncludingNesting( char *input, const char *pairing ) +{ + int nestcount = 1; + + do + { + input = CC_ParseToken( input ); + if ( strlen( com_token ) <= 0 ) + break; + + if ( strlen( com_token ) == 1 ) + { + if ( com_token[ 0 ] == pairing[ 0 ] ) + { + nestcount++; + } + else if ( com_token[ 0 ] == pairing[ 1 ] ) + { + nestcount--; + } + } + } while ( nestcount != 0 ); + + return input; +}
\ No newline at end of file diff --git a/utils/mdlcheck/mdlcheck_util.h b/utils/mdlcheck/mdlcheck_util.h new file mode 100644 index 0000000..da2f0d8 --- /dev/null +++ b/utils/mdlcheck/mdlcheck_util.h @@ -0,0 +1,31 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef CLASSCHECK_UTIL_H +#define CLASSCHECK_UTIL_H +#ifdef _WIN32 +#pragma once +#endif + + +void vprint( int depth, const char *fmt, ... ); +void vprint_queued( int depth, const char *fmt, ... ); +void dump_print_queue( void ); +void CC_UngetToken( void ); +char *CC_ParseToken(char *data); +char *CC_DiscardUntilMatchingCharIncludingNesting( char *input, const char *pairing ); +char *CC_RawParseChar( char *input, const char *ch, char *breakchar ); +char *CC_ParseUntilEndOfLine( char *input ); + +extern char com_token[1024]; +extern bool com_ignoreinlinecomment; +extern int linesprocessed; + +unsigned char *COM_LoadFile( const char *name, int *len); +void COM_FreeFile( unsigned char *buffer ); +bool COM_DirectoryExists( const char *dir ); + +#endif // CLASSCHECK_UTIL_H diff --git a/utils/mdlcheck/stdafx.cpp b/utils/mdlcheck/stdafx.cpp new file mode 100644 index 0000000..1fdf9da --- /dev/null +++ b/utils/mdlcheck/stdafx.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.cpp : source file that includes just the standard includes +// classcheck.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/utils/mdlcheck/stdafx.h b/utils/mdlcheck/stdafx.h new file mode 100644 index 0000000..e0ae61a --- /dev/null +++ b/utils/mdlcheck/stdafx.h @@ -0,0 +1,26 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_) +#define AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__50E4147E_A508_4D85_BF0A_BA26676063F0__INCLUDED_) |