1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2024-12-22 17:47:38 +08:00

Add debug functions for keyvalues

This commit is contained in:
A1mDev 2024-10-24 06:38:26 +07:00
parent cdf711a3e0
commit 44fd37a559
4 changed files with 220 additions and 34 deletions

Binary file not shown.

Binary file not shown.

View File

@ -449,45 +449,44 @@ inline void KeyValues::SetExpressionHandler( GetSymbolProc_t pExpSymbolProc )
// KeyValuesDumpContext and generic implementations
//
// class IKeyValuesDumpContext
// {
// public:
// virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel ) = 0;
// virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel ) = 0;
// virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel ) = 0;
// };
class IKeyValuesDumpContext
{
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel ) = 0;
virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel ) = 0;
virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel ) = 0;
};
// class IKeyValuesDumpContextAsText : public IKeyValuesDumpContext
// {
// public:
// virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
// virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel );
// virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel );
class IKeyValuesDumpContextAsText : public IKeyValuesDumpContext
{
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel );
virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel );
// public:
// virtual bool KvWriteIndent( int nIndentLevel );
// virtual bool KvWriteText( char const *szText ) = 0;
// };
public:
virtual bool KvWriteIndent( int nIndentLevel );
virtual bool KvWriteText( char const *szText ) = 0;
};
// class CKeyValuesDumpContextAsDevMsg : public IKeyValuesDumpContextAsText
// {
// public:
// // Overrides developer level to dump in DevMsg, zero to dump as Msg
// CKeyValuesDumpContextAsDevMsg( int nDeveloperLevel = 1 ) : m_nDeveloperLevel( nDeveloperLevel ) {}
class CKeyValuesDumpContextAsDevMsg : public IKeyValuesDumpContextAsText
{
public:
// Overrides developer level to dump in DevMsg, zero to dump as Msg
CKeyValuesDumpContextAsDevMsg( int nDeveloperLevel = 1 ) : m_nDeveloperLevel( nDeveloperLevel ) {}
// public:
// virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
// virtual bool KvWriteText( char const *szText );
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
virtual bool KvWriteText( char const *szText );
// protected:
// int m_nDeveloperLevel;
// };
// inline bool KeyValuesDumpAsDevMsg( KeyValues *pKeyValues, int nIndentLevel = 0, int nDeveloperLevel = 1 )
// {
// CKeyValuesDumpContextAsDevMsg ctx( nDeveloperLevel );
// return pKeyValues->Dump( &ctx, nIndentLevel );
// }
protected:
int m_nDeveloperLevel;
};
inline bool KeyValuesDumpAsDevMsg( KeyValues *pKeyValues, int nIndentLevel = 0, int nDeveloperLevel = 1 )
{
CKeyValuesDumpContextAsDevMsg ctx( nDeveloperLevel );
return pKeyValues->Dump( &ctx, nIndentLevel );
}
#endif // KEYVALUES_H

View File

@ -19,6 +19,7 @@
#include <Color.h>
#include <stdlib.h>
#include "tier1/convar.h"
#include "tier0/dbg.h"
#include "tier0/mem.h"
#include "utlvector.h"
@ -2572,3 +2573,189 @@ bool KeyValues::ProcessResolutionKeys( const char *pResString )
return true;
}
//
// KeyValues dumping implementation
//
bool KeyValues::Dump( IKeyValuesDumpContext *pDump, int nIndentLevel /* = 0 */ )
{
if ( !pDump->KvBeginKey( this, nIndentLevel ) )
return false;
// Dump values
for ( KeyValues *val = this ? GetFirstValue() : NULL; val; val = val->GetNextValue() )
{
if ( !pDump->KvWriteValue( val, nIndentLevel + 1 ) )
return false;
}
// Dump subkeys
for ( KeyValues *sub = this ? GetFirstTrueSubKey() : NULL; sub; sub = sub->GetNextTrueSubKey() )
{
if ( !sub->Dump( pDump, nIndentLevel + 1 ) )
return false;
}
return pDump->KvEndKey( this, nIndentLevel );
}
bool IKeyValuesDumpContextAsText::KvBeginKey( KeyValues *pKey, int nIndentLevel )
{
if ( pKey )
{
return
KvWriteIndent( nIndentLevel ) &&
KvWriteText( pKey->GetName() ) &&
KvWriteText( " {\n" );
}
else
{
return
KvWriteIndent( nIndentLevel ) &&
KvWriteText( "<< NULL >>\n" );
}
}
bool IKeyValuesDumpContextAsText::KvWriteValue( KeyValues *val, int nIndentLevel )
{
if ( !val )
{
return
KvWriteIndent( nIndentLevel ) &&
KvWriteText( "<< NULL >>\n" );
}
if ( !KvWriteIndent( nIndentLevel ) )
return false;
if ( !KvWriteText( val->GetName() ) )
return false;
if ( !KvWriteText( " " ) )
return false;
switch ( val->GetDataType() )
{
case KeyValues::TYPE_STRING:
{
if ( !KvWriteText( val->GetString() ) )
return false;
}
break;
case KeyValues::TYPE_INT:
{
int n = val->GetInt();
char *chBuffer = ( char * ) stackalloc( 128 );
V_snprintf( chBuffer, 128, "int( %d = 0x%X )", n, n );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
case KeyValues::TYPE_FLOAT:
{
float fl = val->GetFloat();
char *chBuffer = ( char * ) stackalloc( 128 );
V_snprintf( chBuffer, 128, "float( %f )", fl );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
case KeyValues::TYPE_PTR:
{
void *ptr = val->GetPtr();
char *chBuffer = ( char * ) stackalloc( 128 );
V_snprintf( chBuffer, 128, "ptr( 0x%p )", ptr );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
case KeyValues::TYPE_WSTRING:
{
wchar_t const *wsz = val->GetWString();
int nLen = V_wcslen( wsz );
int numBytes = nLen*2 + 64;
char *chBuffer = ( char * ) stackalloc( numBytes );
V_snprintf( chBuffer, numBytes, "%ls [wstring, len = %d]", wsz, nLen );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
case KeyValues::TYPE_UINT64:
{
uint64 n = val->GetUint64();
char *chBuffer = ( char * ) stackalloc( 128 );
V_snprintf( chBuffer, 128, "u64( %lld = 0x%llX )", n, n );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
default:
break;
#if 0 // this code was accidentally stubbed out by a mis-integration in CL722860; it hasn't been tested
{
int n = val->GetDataType();
char *chBuffer = ( char * ) stackalloc( 128 );
V_snprintf( chBuffer, 128, "??kvtype[%d]", n );
if ( !KvWriteText( chBuffer ) )
return false;
}
break;
#endif
}
return KvWriteText( "\n" );
}
bool IKeyValuesDumpContextAsText::KvEndKey( KeyValues *pKey, int nIndentLevel )
{
if ( pKey )
{
return
KvWriteIndent( nIndentLevel ) &&
KvWriteText( "}\n" );
}
else
{
return true;
}
}
bool IKeyValuesDumpContextAsText::KvWriteIndent( int nIndentLevel )
{
int numIndentBytes = ( nIndentLevel * 2 + 1 );
char *pchIndent = ( char * ) stackalloc( numIndentBytes );
memset( pchIndent, ' ', numIndentBytes - 1 );
pchIndent[ numIndentBytes - 1 ] = 0;
return KvWriteText( pchIndent );
}
bool CKeyValuesDumpContextAsDevMsg::KvBeginKey( KeyValues *pKey, int nIndentLevel )
{
static ConVarRef r_developer( "developer" );
if ( r_developer.IsValid() && r_developer.GetInt() < m_nDeveloperLevel )
// If "developer" is not the correct level, then avoid evaluating KeyValues tree early
return false;
else
return IKeyValuesDumpContextAsText::KvBeginKey( pKey, nIndentLevel );
}
bool CKeyValuesDumpContextAsDevMsg::KvWriteText( char const *szText )
{
if ( m_nDeveloperLevel > 0 )
{
DevMsg( "%s", szText );
}
else
{
Msg( "%s", szText );
}
return true;
}