summaryrefslogtreecommitdiff
path: root/utils/vmtcheck
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmtcheck
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/vmtcheck')
-rw-r--r--utils/vmtcheck/stdafx.cpp15
-rw-r--r--utils/vmtcheck/stdafx.h26
-rw-r--r--utils/vmtcheck/vmtcheck.cpp279
-rw-r--r--utils/vmtcheck/vmtcheck.vpc89
-rw-r--r--utils/vmtcheck/vmtcheck_util.cpp115
-rw-r--r--utils/vmtcheck/vmtcheck_util.h20
6 files changed, 544 insertions, 0 deletions
diff --git a/utils/vmtcheck/stdafx.cpp b/utils/vmtcheck/stdafx.cpp
new file mode 100644
index 0000000..1fdf9da
--- /dev/null
+++ b/utils/vmtcheck/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/vmtcheck/stdafx.h b/utils/vmtcheck/stdafx.h
new file mode 100644
index 0000000..e0ae61a
--- /dev/null
+++ b/utils/vmtcheck/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_)
diff --git a/utils/vmtcheck/vmtcheck.cpp b/utils/vmtcheck/vmtcheck.cpp
new file mode 100644
index 0000000..241a1d0
--- /dev/null
+++ b/utils/vmtcheck/vmtcheck.cpp
@@ -0,0 +1,279 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "stdafx.h"
+#include <stdio.h>
+#include <windows.h>
+#include "vmtcheck_util.h"
+#include "tier0/dbg.h"
+#include "utldict.h"
+#include "filesystem.h"
+#include "FileSystem_Tools.h"
+#include "KeyValues.h"
+#include "cmdlib.h"
+
+bool uselogfile = false;
+
+struct AnalysisData
+{
+ CUtlSymbolTable symbols;
+};
+
+static AnalysisData g_Analysis;
+
+
+static bool spewed = false;
+
+SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg )
+{
+ spewed = true;
+
+ printf( "%s", pMsg );
+ OutputDebugString( pMsg );
+
+ if ( type == SPEW_ERROR )
+ {
+ printf( "\n" );
+ OutputDebugString( "\n" );
+ }
+
+ return SPEW_CONTINUE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void printusage( void )
+{
+ vprint( 0, "usage: vmtcheck <materials/.vmt root directory>\n\
+ \t-v = verbose output\n\
+ \t-l = log to file log.txt\n\
+ \ne.g.: vmtcheck -l u:/hl2/hl2/materials\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 ( !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 );
+
+ if ( !( files.Count() % 3000 ) )
+ {
+ vprint( 0, "...found %i .vmt files\n", files.Count() );
+ }
+ }
+ }
+ }
+ } while ( FindNextFile( ff, &wfd ) );
+}
+
+void BuildFileList( CUtlVector< CUtlSymbol >& files, char const *rootdir, char const *extension )
+{
+ files.RemoveAll();
+ BuildFileList_R( files, rootdir, extension );
+}
+
+bool ValidateVMTFile( char const *vmtname, int offset )
+{
+ bool valid = true;
+
+ KeyValues *kv = new KeyValues( "Test" );
+ if ( kv->LoadFromFile( g_pFileSystem, &vmtname[offset] ) )
+ {
+ // Do any custom checking here...
+ }
+ else
+ {
+ valid = false;
+ }
+ kv->deleteThis();
+
+ return valid;
+}
+
+void ProcessMaterialsDirectory( char const *basedir )
+{
+ vprint( 0, "building .vmt list\n" );
+
+ CUtlVector< CUtlSymbol > vmts;
+
+ BuildFileList( vmts, basedir, ".vmt" );
+
+ vprint( 0, "found %i .vmt files\n\n", vmts.Count() );
+
+ int offset = strlen( basedir ) + 1;
+ offset -= strlen( "materials/" );
+ if ( offset < 0 )
+ {
+ Error( "Bogus offset\n" );
+ }
+
+ // Now iterate vmts and load into memory, etc.
+
+ int c = vmts.Count();
+ int valid = 0;
+ for ( int i = 0; i < c; i++ )
+ {
+ CUtlSymbol& sym = vmts[ i ];
+
+ char const *vmtfile = g_Analysis.symbols.String( sym );
+
+ if ( verbose )
+ {
+ vprint( 0, "checking %i .vmt %s\n", i, vmtfile );
+ }
+
+ spewed = false;
+ if ( ValidateVMTFile( vmtfile, offset ) )
+ {
+ if ( !spewed )
+ {
+ valid++;
+ }
+ }
+
+ if ( i > 0 && !( i % 1000 ) )
+ {
+ vprint( 0, "Analyzed %i .vmt files (%.2f %%%%)\n", i, 100.0f * (float)i/(float)c );
+ }
+ }
+
+ int ecount = c - valid;
+ vprint( 0, "\nSummary: found %i/%i (%.2f percent) .vmt errors\n", ecount, c, 100.0 * ecount / max( c, 1 ) );
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CheckLogFile( void )
+{
+ if ( uselogfile )
+ {
+ _unlink( "log.txt" );
+ vprint( 0, " Outputting to log.txt\n" );
+ }
+}
+
+void PrintHeader()
+{
+ vprint( 0, "Valve Software - vmtcheck.exe (%s)\n", __DATE__ );
+ vprint( 0, "--- VMT File Consistency Checker ---\n" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : argc -
+// argv[] -
+// Output : int
+//-----------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ SpewOutputFunc( SpewFunc );
+ SpewActivate( "vmtcheck", 2 );
+
+ 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;
+ default:
+ printusage();
+ break;
+ }
+ }
+ }
+
+ if ( argc < 2 || ( i != argc ) )
+ {
+ PrintHeader();
+ printusage();
+ }
+
+ CheckLogFile();
+
+ PrintHeader();
+
+ vprint( 0, " Looking for messed up .vmt files...\n" );
+
+ char vmtdir[ 256 ];
+ strcpy( vmtdir, argv[ i - 1 ] );
+
+ if ( !strstr( vmtdir, "materials" ) )
+ {
+ vprint( 0, "Materials dir %s looks invalid (format: u:/tf2/hl2/materials)\n", vmtdir );
+
+ return 0;
+ }
+
+ char workingdir[ 256 ];
+ workingdir[0] = 0;
+ Q_getwd( workingdir, sizeof( workingdir ) );
+
+ // If they didn't specify -game on the command line, use VPROJECT.
+ CmdLib_InitFileSystem( workingdir );
+
+ vprint( 0, "game dir %s\nmaterials dir %s\n\n",
+ gamedir,
+ vmtdir );
+
+ Q_StripTrailingSlash( vmtdir );
+ ProcessMaterialsDirectory( vmtdir );
+
+ FileSystem_Term();
+
+ return 0;
+}
diff --git a/utils/vmtcheck/vmtcheck.vpc b/utils/vmtcheck/vmtcheck.vpc
new file mode 100644
index 0000000..8788d86
--- /dev/null
+++ b/utils/vmtcheck/vmtcheck.vpc
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// VMTCHECK.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)"
+ $Create/UsePCHThroughFile "stdafx.h"
+ $PrecompiledHeaderFile "Debug/vmtcheck.pch"
+ }
+}
+
+$Project "Vmtcheck"
+{
+ $Folder "Source Files"
+ {
+ -$File "$SRCDIR\public\tier0\memoverride.cpp"
+
+ $File "vmtcheck.cpp"
+ $File "vmtcheck_util.cpp"
+
+ $File "..\common\cmdlib.cpp" \
+ "$SRCDIR\public\filesystem_helpers.cpp" \
+ "$SRCDIR\public\filesystem_init.cpp" \
+ "..\common\filesystem_tools.cpp"
+ {
+ $Configuration
+ {
+ $Compiler
+ {
+ $Create/UsePrecompiledHeader "Not Using Precompiled Headers"
+ }
+ }
+ }
+
+ $File "StdAfx.cpp"
+ {
+ $Configuration
+ {
+ $Compiler
+ {
+ $Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
+ }
+ }
+ }
+ }
+
+ $Folder "Header Files"
+ {
+ $File "$SRCDIR\public\tier0\basetypes.h"
+ $File "..\common\cmdlib.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 "$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 "vmtcheck_util.h"
+ $File "$SRCDIR\public\vstdlib\vstdlib.h"
+ }
+
+ $Folder "Link Libraries"
+ {
+ $Lib tier2
+ }
+}
diff --git a/utils/vmtcheck/vmtcheck_util.cpp b/utils/vmtcheck/vmtcheck_util.cpp
new file mode 100644
index 0000000..afbffec
--- /dev/null
+++ b/utils/vmtcheck/vmtcheck_util.cpp
@@ -0,0 +1,115 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "stdafx.h"
+#include <io.h>
+#include <stdio.h>
+#include <windows.h>
+#include "vmtcheck_util.h"
+#include "tier0/dbg.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 : *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;
+}
diff --git a/utils/vmtcheck/vmtcheck_util.h b/utils/vmtcheck/vmtcheck_util.h
new file mode 100644
index 0000000..4c3c701
--- /dev/null
+++ b/utils/vmtcheck/vmtcheck_util.h
@@ -0,0 +1,20 @@
+//========= 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, ... );
+
+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