mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-05 22:09:59 +03:00
1
This commit is contained in:
1581
utils/classcheck/class.cpp
Normal file
1581
utils/classcheck/class.cpp
Normal file
File diff suppressed because it is too large
Load Diff
196
utils/classcheck/class.h
Normal file
196
utils/classcheck/class.h
Normal file
@@ -0,0 +1,196 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( CLASS_H )
|
||||
#define CLASS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class CTypeDescriptionField
|
||||
{
|
||||
public:
|
||||
CTypeDescriptionField()
|
||||
{
|
||||
m_szVariableName[ 0 ] = 0;
|
||||
m_szType[ 0 ] = 0;
|
||||
m_szDefineType[ 0 ] = 0;
|
||||
m_bCommentedOut = false;
|
||||
m_bRepresentedInRecvTable = false;
|
||||
}
|
||||
|
||||
char m_szVariableName[ 128 ];
|
||||
char m_szType[ 128 ];
|
||||
char m_szDefineType[ 128 ];
|
||||
bool m_bCommentedOut;
|
||||
bool m_bRepresentedInRecvTable;
|
||||
};
|
||||
|
||||
class CClassVariable
|
||||
{
|
||||
public:
|
||||
CClassVariable()
|
||||
{
|
||||
m_szName[ 0 ] = 0;
|
||||
m_szType[ 0 ] = 0;
|
||||
|
||||
m_Type = TPUBLIC;
|
||||
|
||||
m_bKnownType = false;
|
||||
m_nTypeSize = 0;
|
||||
|
||||
m_bIsArray = false;
|
||||
m_szArraySize[ 0 ] = 0;
|
||||
|
||||
m_bInRecvTable = false;
|
||||
|
||||
m_TypeSize = 0;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TPUBLIC = 0,
|
||||
TPROTECTED,
|
||||
TPRIVATE
|
||||
} VARTYPE;
|
||||
|
||||
char m_szName[ 128 ];
|
||||
char m_szType[ 128 ];
|
||||
|
||||
VARTYPE m_Type;
|
||||
|
||||
bool m_bKnownType;
|
||||
int m_nTypeSize;
|
||||
|
||||
bool m_bIsArray;
|
||||
char m_szArraySize[ 128 ];
|
||||
|
||||
bool m_bInRecvTable;
|
||||
|
||||
int m_TypeSize;
|
||||
};
|
||||
|
||||
class CClassMemberFunction
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
TPUBLIC = 0,
|
||||
TPROTECTED,
|
||||
TPRIVATE
|
||||
} MEMBERTYPE;
|
||||
|
||||
char m_szName[ 128 ];
|
||||
// Return type
|
||||
char m_szType[ 128 ];
|
||||
|
||||
MEMBERTYPE m_Type;
|
||||
|
||||
};
|
||||
|
||||
class CClassTypedef
|
||||
{
|
||||
public:
|
||||
char m_szTypeName[ 128 ];
|
||||
char m_szAlias[ 128 ];
|
||||
|
||||
// bool m_bIsTypedefForBaseClass;
|
||||
};
|
||||
|
||||
class CClass
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_VARIABLES = 1024,
|
||||
MAX_MEMBERS = 1024,
|
||||
MAX_TDFIELDS = 1024,
|
||||
};
|
||||
|
||||
CClass( const char *name );
|
||||
~CClass( void );
|
||||
|
||||
char *ParseClassDeclaration( char *input );
|
||||
|
||||
|
||||
void SetBaseClass( const char *name );
|
||||
void CheckChildOfBaseEntity( const char *baseentityclass );
|
||||
bool CheckForMissingTypeDescriptionFields( int& missingcount, bool createtds = false );
|
||||
bool CheckForMissingPredictionFields( int& missingcount, bool createtds = false );
|
||||
bool CheckForPredictionFieldsInRecvTableNotMarkedAsSuchCorrectly( int& missingcount );
|
||||
void AddVariable( int protection, char *type, char *name, bool array, char *arraysize = 0 );
|
||||
|
||||
// Parsing helper methods
|
||||
bool ParseProtection( char *&input, int &protection );
|
||||
bool ParseNestedClass( char *&input );
|
||||
bool ParseBaseClass( char *&input );
|
||||
bool ParseClassMember( char *&input, int protection );
|
||||
bool ParseNetworkVar( char *&input, int protection );
|
||||
void ReportTypeMismatches( CClassVariable *var, CTypeDescriptionField *td );
|
||||
|
||||
void CheckForHungarianErrors( int& warnings );
|
||||
|
||||
char m_szName[ 128 ];
|
||||
char m_szBaseClass[ 128 ];
|
||||
char m_szTypedefBaseClass[ 128 ];
|
||||
|
||||
CClassVariable *FindVar( const char *name, bool checkbaseclasses = false );
|
||||
CClassVariable *AddVar( const char *name );
|
||||
int m_nVarCount;
|
||||
CClassVariable *m_Variables[ MAX_VARIABLES ];
|
||||
|
||||
CClassMemberFunction *FindMember( const char *name );
|
||||
CClassMemberFunction *AddMember( const char *name );
|
||||
int m_nMemberCount;
|
||||
CClassMemberFunction *m_Members[ MAX_MEMBERS ];
|
||||
|
||||
CTypeDescriptionField *FindTD( const char *name );
|
||||
CTypeDescriptionField *AddTD( const char *name, const char *type, const char *definetype, bool incomments );
|
||||
int m_nTDCount;
|
||||
CTypeDescriptionField *m_TDFields[ MAX_TDFIELDS ];
|
||||
|
||||
CTypeDescriptionField *FindPredTD( const char *name );
|
||||
CTypeDescriptionField *AddPredTD( const char *name, const char *type, const char *definetype, bool incomments, bool inrecvtable );
|
||||
int m_nPredTDCount;
|
||||
CTypeDescriptionField *m_PredTDFields[ MAX_TDFIELDS ];
|
||||
|
||||
|
||||
CClass *m_pBaseClass;
|
||||
|
||||
CClass *m_pNext;
|
||||
|
||||
bool m_bDerivedFromCBaseEntity;
|
||||
bool m_bHasSaveRestoreData;
|
||||
bool m_bHasPredictionData;
|
||||
bool m_bHasRecvTableData;
|
||||
bool m_bConstructPredictableCalled;
|
||||
|
||||
int m_nClassDataSize;
|
||||
|
||||
private:
|
||||
struct MemberVarParse_t
|
||||
{
|
||||
char m_pType[256];
|
||||
char m_pTypeModifier[256];
|
||||
char m_pName[256];
|
||||
char m_pArraySize[ 128 ];
|
||||
bool m_bArray;
|
||||
|
||||
MemberVarParse_t() { Reset(); }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_pType[0] = 0;
|
||||
m_pTypeModifier[0] = 0;
|
||||
m_pName[0] = 0;
|
||||
m_pArraySize[0] = 0;
|
||||
m_bArray = false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // CLASS_H
|
||||
216
utils/classcheck/classcheck.cpp
Normal file
216
utils/classcheck/classcheck.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "stdafx.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "classcheck_util.h"
|
||||
#include "icodeprocessor.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
|
||||
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: classcheck -q -h -m -t <root source directory> <game: hl2 | tf2>\n\
|
||||
\t-q = quiet\n\
|
||||
\t-h = print class hierarchy\n\
|
||||
\t-m = don't print member functions/variables of class\n\
|
||||
\t-t = don't print type description errors\n\
|
||||
\t-p = don't print prediction description errors\n\
|
||||
\t-c = create missing save descriptions\n\
|
||||
\t-x = create missing prediction descriptions\n\
|
||||
\t-i = specify specific input file to parse\n\
|
||||
\t-b = similar to -i, allows specifying files outside client\\server directories\n\
|
||||
\t-j = check for Crazy Jay Stelly's mismatched Hungarian notation errors\n\
|
||||
\t-l = log to file log.txt\n" );
|
||||
|
||||
// Exit app
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *sourcetreebase -
|
||||
// *subdir -
|
||||
// *baseentityclass -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ProcessDirectory( const char *game, const char *sourcetreebase, const char *subdir, const char *baseentityclass )
|
||||
{
|
||||
char rootdirectory[ 256 ];
|
||||
sprintf( rootdirectory, "%s\\%s", sourcetreebase, subdir );
|
||||
|
||||
// check for existence
|
||||
if ( COM_DirectoryExists( rootdirectory ) )
|
||||
{
|
||||
processor->Process( baseentityclass, game, sourcetreebase, subdir );
|
||||
}
|
||||
else
|
||||
{
|
||||
vprint( 0, "Couldn't find directory %s, check path %s\n", rootdirectory, sourcetreebase );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *sourcetreebase -
|
||||
// *subdir -
|
||||
// *baseentityclass -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ProcessFile( const char *game, const char *sourcetreebase, const char *subdir, const char *baseentityclass, const char *pFileName )
|
||||
{
|
||||
char rootdirectory[ 256 ];
|
||||
sprintf( rootdirectory, "%s\\%s", sourcetreebase, subdir );
|
||||
|
||||
// check for existence
|
||||
if ( COM_DirectoryExists( rootdirectory ) )
|
||||
{
|
||||
processor->Process( baseentityclass, game, sourcetreebase, subdir, pFileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
vprint( 0, "Couldn't find directory %s, check path %s\n", rootdirectory, sourcetreebase );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CheckLogFile( void )
|
||||
{
|
||||
if ( processor->GetLogFile() )
|
||||
{
|
||||
_unlink( "log.txt" );
|
||||
vprint( 0, " Outputting to log.txt\n" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : argc -
|
||||
// argv[] -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
SpewOutputFunc( SpewFunc );
|
||||
|
||||
vprint( 0, "Valve Software - classcheck.exe (%s)\n", __DATE__ );
|
||||
vprint( 0, "--- Game Code Static Analysis ---\n" );
|
||||
char *pSpecificFile = NULL;
|
||||
bool bOutsideGamedir = false;
|
||||
|
||||
int i = 1;
|
||||
for ( i ; i<argc ; i++)
|
||||
{
|
||||
if ( argv[ i ][ 0 ] == '-' )
|
||||
{
|
||||
switch( argv[ i ][ 1 ] )
|
||||
{
|
||||
case 'q':
|
||||
processor->SetQuiet( true );
|
||||
break;
|
||||
case 'h':
|
||||
processor->SetPrintHierarchy( true );
|
||||
break;
|
||||
case 'm':
|
||||
processor->SetPrintMembers( false );
|
||||
break;
|
||||
case 't':
|
||||
processor->SetPrintTDs( false );
|
||||
break;
|
||||
case 'p':
|
||||
processor->SetPrintPredTDs( false );
|
||||
break;
|
||||
case 'c':
|
||||
processor->SetPrintCreateMissingTDs( true );
|
||||
break;
|
||||
case 'x':
|
||||
processor->SetPrintCreateMissingPredTDs( true );
|
||||
break;
|
||||
case 'i':
|
||||
if (i < argc-1)
|
||||
{
|
||||
pSpecificFile = argv[i+1];
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
if (i < argc-1)
|
||||
{
|
||||
pSpecificFile = argv[i+1];
|
||||
bOutsideGamedir = true;
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
processor->SetLogFile( true );
|
||||
break;
|
||||
case 'j':
|
||||
processor->SetCheckHungarian( true );
|
||||
break;
|
||||
default:
|
||||
printusage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc < 3 || ( i != argc ) )
|
||||
{
|
||||
printusage();
|
||||
}
|
||||
|
||||
CheckLogFile();
|
||||
|
||||
vprint( 0, " Looking for obvious screwups and boneheaded mistakes...\n" );
|
||||
|
||||
char sourcetreebase[ 256 ];
|
||||
strcpy( sourcetreebase, argv[i-2] );
|
||||
|
||||
Q_StripTrailingSlash( sourcetreebase );
|
||||
|
||||
if ( !pSpecificFile )
|
||||
{
|
||||
ProcessDirectory( argv[ i-1 ], sourcetreebase, "server", "CBaseEntity" );
|
||||
ProcessDirectory( argv[ i-1 ], sourcetreebase, "client", "C_BaseEntity" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bOutsideGamedir )
|
||||
{
|
||||
ProcessFile( argv[ i-1 ], sourcetreebase, "", "", pSpecificFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessFile( argv[ i-1 ], sourcetreebase, "server", "CBaseEntity", pSpecificFile );
|
||||
ProcessFile( argv[ i-1 ], sourcetreebase, "client", "C_BaseEntity", pSpecificFile );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
utils/classcheck/classcheck.vpc
Normal file
39
utils/classcheck/classcheck.vpc
Normal file
@@ -0,0 +1,39 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// CLASSCHECK.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE,..\common"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Classcheck"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "class.cpp"
|
||||
$File "classcheck.cpp"
|
||||
$File "classcheck_util.cpp"
|
||||
$File "processmodule.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "$SRCDIR\public\tier0\basetypes.h"
|
||||
$File "class.h"
|
||||
$File "classcheck_util.h"
|
||||
$File "codeprocessor.h"
|
||||
$File "icodeprocessor.h"
|
||||
$File "$SRCDIR\public\tier1\utldict.h"
|
||||
}
|
||||
}
|
||||
369
utils/classcheck/classcheck_util.cpp
Normal file
369
utils/classcheck/classcheck_util.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "stdafx.h"
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "classcheck_util.h"
|
||||
#include "icodeprocessor.h"
|
||||
#include "tier0/dbg.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 ( processor->GetLogFile() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
if ( len >= 1024 )
|
||||
{
|
||||
com_token[ len -1 ] = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
29
utils/classcheck/classcheck_util.h
Normal file
29
utils/classcheck/classcheck_util.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//========= 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 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
|
||||
129
utils/classcheck/codeprocessor.h
Normal file
129
utils/classcheck/codeprocessor.h
Normal file
@@ -0,0 +1,129 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( CODEPROCESSOR_H )
|
||||
#define CODEPROCESSOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "class.h"
|
||||
#include "icodeprocessor.h"
|
||||
|
||||
#include "utldict.h"
|
||||
|
||||
class CCodeProcessor : public ICodeProcessor
|
||||
{
|
||||
public:
|
||||
CCodeProcessor( void );
|
||||
~CCodeProcessor( void );
|
||||
|
||||
void Process( const char *baseentityclass, const char *gamespecific, const char *sourcetreebase, const char *subdir );
|
||||
void Process( const char *baseentityclass, const char *gamespecific, const char *sourcetreebase, const char *subdir, const char *pFileName );
|
||||
CClass *AddClass( const char *classname );
|
||||
|
||||
void SetQuiet( bool quiet );
|
||||
bool GetQuiet( void ) const;
|
||||
|
||||
void SetPrintHierarchy( bool print );
|
||||
bool GetPrintHierarchy( void ) const;
|
||||
|
||||
void SetPrintMembers( bool print );
|
||||
bool GetPrintMembers( void ) const;
|
||||
|
||||
void SetPrintTDs( bool print );
|
||||
bool GetPrintTDs( void ) const;
|
||||
|
||||
void SetPrintPredTDs( bool print );
|
||||
bool GetPrintPredTDs( void ) const;
|
||||
|
||||
void SetPrintCreateMissingTDs( bool print );
|
||||
bool GetPrintCreateMissingTDs( void ) const;
|
||||
|
||||
void SetPrintCreateMissingPredTDs( bool print );
|
||||
bool GetPrintCreateMissingPredTDs( void ) const;
|
||||
|
||||
void SetLogFile( bool log );
|
||||
bool GetLogFile( void ) const;
|
||||
|
||||
void SetCheckHungarian( bool check );
|
||||
bool GetCheckHungarian() const;
|
||||
|
||||
CClass *FindClass( const char *name ) const;
|
||||
|
||||
void ResolveBaseClasses( const char *baseentityclass );
|
||||
void Clear( void );
|
||||
void PrintClassList( void ) const;
|
||||
void PrintMissingTDFields( void ) const;
|
||||
void ReportHungarianNotationErrors();
|
||||
|
||||
int Count( void ) const;
|
||||
|
||||
void SortClassList( void );
|
||||
|
||||
private:
|
||||
char *ParseTypeDescription( char *current, bool fIsMacroized );
|
||||
char *ParsePredictionTypeDescription( char *current );
|
||||
char *ParseReceiveTable( char *current );
|
||||
|
||||
void ProcessModule( bool forcequiet, int depth, int& maxdepth, int& numheaders, int& skippedfiles,
|
||||
const char *srcroot, const char *baseroot, const char *root, const char *module );
|
||||
void ProcessModules( const char *srcroot, const char *root, const char *rootmodule );
|
||||
void PrintResults( const char *baseentityclass );
|
||||
void ConstructModuleList_R( int level, const char *baseentityclass, const char *gamespecific, const char *root, char const *srcroot );
|
||||
|
||||
void AddHeader( int depth, const char *filename, const char *rootmodule );
|
||||
|
||||
bool CheckShouldSkip( bool forcequiet, int depth, char const *filename, int& numheaders, int& skippedfiles);
|
||||
bool LoadFile( char **buffer, char *filename, char const *module, bool forcequiet,
|
||||
int depth, int& filelength, int& numheaders, int& skippedfiles,
|
||||
char const *srcroot, char const *root, char const *baseroot );
|
||||
|
||||
// include file path
|
||||
void CleanupIncludePath();
|
||||
void AddIncludePath( const char *pPath );
|
||||
void SetupIncludePath( const char *sourcetreebase, const char *subdir, const char *gamespecific );
|
||||
|
||||
CClass *m_pClassList;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool skipped;
|
||||
} CODE_MODULE;
|
||||
|
||||
CUtlDict< CODE_MODULE, int > m_Modules;
|
||||
CUtlDict< CODE_MODULE, int > m_Headers;
|
||||
|
||||
CUtlVector< char * > m_IncludePath;
|
||||
|
||||
bool m_bQuiet;
|
||||
bool m_bPrintHierarchy;
|
||||
bool m_bPrintMembers;
|
||||
bool m_bPrintTypedescriptionErrors;
|
||||
bool m_bPrintPredictionDescErrors;
|
||||
bool m_bCreateMissingTDs;
|
||||
bool m_bCreateMissingPredTDs;
|
||||
bool m_bLogToFile;
|
||||
bool m_bCheckHungarian;
|
||||
|
||||
int m_nFilesProcessed;
|
||||
int m_nHeadersProcessed;
|
||||
int m_nClassesParsed;
|
||||
int m_nOffset;
|
||||
int m_nBytesProcessed;
|
||||
int m_nLinesOfCode;
|
||||
|
||||
double m_flStart;
|
||||
double m_flEnd;
|
||||
|
||||
char m_szCurrentCPP[ 128 ];
|
||||
char m_szBaseEntityClass[ 256 ];
|
||||
|
||||
};
|
||||
|
||||
extern ICodeProcessor *processor;
|
||||
|
||||
#endif // CODEPROCESSOR_H
|
||||
59
utils/classcheck/icodeprocessor.h
Normal file
59
utils/classcheck/icodeprocessor.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( ICODEPROCESSOR_H )
|
||||
#define ICODEPROCESSOR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#pragma warning( disable : 4127 )
|
||||
|
||||
class CClass;
|
||||
|
||||
class ICodeProcessor
|
||||
{
|
||||
public:
|
||||
// Process all files in a directory
|
||||
virtual void Process( const char *baseentityclass, const char *gamespecific, const char *sourcetreebase, const char *subdir ) = 0;
|
||||
|
||||
// Process a single file
|
||||
virtual void Process( const char *baseentityclass, const char *gamespecific, const char *sourcetreebase, const char *subdir, const char *pFileName ) = 0;
|
||||
|
||||
virtual CClass *AddClass( const char *classname ) = 0;
|
||||
virtual CClass *FindClass( const char *name ) const = 0;
|
||||
|
||||
virtual void SetQuiet( bool quiet ) = 0;
|
||||
virtual bool GetQuiet( void ) const = 0;
|
||||
|
||||
virtual void SetPrintHierarchy( bool print ) = 0;
|
||||
virtual bool GetPrintHierarchy( void ) const = 0;
|
||||
|
||||
virtual void SetPrintMembers( bool print ) = 0;
|
||||
virtual bool GetPrintMembers( void ) const = 0;
|
||||
|
||||
virtual void SetPrintTDs( bool print ) = 0;
|
||||
virtual bool GetPrintTDs( void ) const = 0;
|
||||
|
||||
virtual void SetPrintPredTDs( bool print ) = 0;
|
||||
virtual bool GetPrintPredTDs( void ) const = 0;
|
||||
|
||||
virtual void SetPrintCreateMissingTDs( bool print ) = 0;
|
||||
virtual bool GetPrintCreateMissingTDs( void ) const = 0;
|
||||
|
||||
virtual void SetPrintCreateMissingPredTDs( bool print ) = 0;
|
||||
virtual bool GetPrintCreateMissingPredTDs( void ) const = 0;
|
||||
|
||||
virtual void SetLogFile( bool log ) = 0;
|
||||
virtual bool GetLogFile( void ) const = 0;
|
||||
|
||||
virtual void SetCheckHungarian( bool check ) = 0;
|
||||
virtual bool GetCheckHungarian() const = 0;
|
||||
};
|
||||
|
||||
extern ICodeProcessor *processor;
|
||||
|
||||
#endif // ICODEPROCESSOR_H
|
||||
1866
utils/classcheck/processmodule.cpp
Normal file
1866
utils/classcheck/processmodule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
15
utils/classcheck/stdafx.cpp
Normal file
15
utils/classcheck/stdafx.cpp
Normal file
@@ -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
|
||||
26
utils/classcheck/stdafx.h
Normal file
26
utils/classcheck/stdafx.h
Normal file
@@ -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_)
|
||||
Reference in New Issue
Block a user