mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-06-07 19:32:09 +03:00
Merge pull request #411 from samisalreadytaken/vscript-debugger
vscript debugger cleanup
This commit is contained in:
commit
77a9ec6c34
@ -29,7 +29,7 @@ extern IScriptManager *scriptmanager;
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
extern int vscript_debugger_port;
|
||||
ConVar script_connect_debugger_on_mapspawn_client( "script_connect_debugger_on_mapspawn_client", "0" );
|
||||
#endif
|
||||
|
||||
// #define VMPROFILE 1
|
||||
@ -687,10 +687,13 @@ bool VScriptClientInit()
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( vscript_debugger_port )
|
||||
if ( script_connect_debugger_on_mapspawn_client.GetInt() == 2 )
|
||||
{
|
||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port, 10.0f );
|
||||
}
|
||||
else if ( script_connect_debugger_on_mapspawn_client.GetInt() != 0 )
|
||||
{
|
||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||
vscript_debugger_port = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
extern int vscript_debugger_port;
|
||||
ConVar script_connect_debugger_on_mapspawn( "script_connect_debugger_on_mapspawn", "0" );
|
||||
#endif
|
||||
|
||||
// #define VMPROFILE 1
|
||||
@ -668,10 +668,13 @@ bool VScriptServerInit()
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if ( vscript_debugger_port )
|
||||
if ( script_connect_debugger_on_mapspawn.GetInt() == 2 )
|
||||
{
|
||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port, 10.0f );
|
||||
}
|
||||
else if ( script_connect_debugger_on_mapspawn.GetInt() != 0 )
|
||||
{
|
||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||
vscript_debugger_port = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -37,7 +37,6 @@ extern ScriptClassDesc_t * GetScriptDesc( CBaseEntity * );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
// This is to ensure a dependency exists between the vscript library and the game DLLs
|
||||
extern int vscript_token;
|
||||
extern int vscript_debugger_port;
|
||||
int vscript_token_hack = vscript_token;
|
||||
#endif
|
||||
|
||||
@ -391,27 +390,14 @@ CON_COMMAND_F( script_debug, "Connect the vscript VM to the script debugger", FC
|
||||
if ( !IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#ifdef GAME_DLL
|
||||
int port = 1212;
|
||||
#else
|
||||
int port = 1213;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( !g_pScriptVM )
|
||||
{
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
vscript_debugger_port = port;
|
||||
CGMsg( 0, CON_GROUP_VSCRIPT, "VScript VM is not running, waiting for it to attach the debugger to port %d...\n", port );
|
||||
#else
|
||||
CGWarning( 0, CON_GROUP_VSCRIPT, "Scripting disabled or no server running\n" );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_pScriptVM->ConnectDebugger( port );
|
||||
g_pScriptVM->ConnectDebugger( vscript_debugger_port );
|
||||
#else
|
||||
g_pScriptVM->ConnectDebugger();
|
||||
#endif
|
||||
|
@ -47,6 +47,12 @@ class CBaseEntityScriptInstanceHelper : public IScriptInstanceHelper
|
||||
extern CBaseEntityScriptInstanceHelper g_BaseEntityScriptInstanceHelper;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#ifdef GAME_DLL
|
||||
const int vscript_debugger_port = 1212;
|
||||
#else
|
||||
const int vscript_debugger_port = 1213;
|
||||
#endif
|
||||
|
||||
void RegisterSharedScriptConstants();
|
||||
void RegisterSharedScriptFunctions();
|
||||
|
||||
|
@ -882,7 +882,7 @@ public:
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual bool ConnectDebugger( int port = 0 ) = 0;
|
||||
virtual bool ConnectDebugger( int port = 0, float timeout = 0.0f ) = 0;
|
||||
#else
|
||||
virtual bool ConnectDebugger() = 0;
|
||||
#endif
|
||||
|
19
sp/src/vscript/sqdbg/LICENSE
Normal file
19
sp/src/vscript/sqdbg/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) samisalreadytaken
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -60,9 +60,14 @@ SQDBG_API int sqdbg_listen_socket( HSQDEBUGSERVER dbg, unsigned short port );
|
||||
SQDBG_API void sqdbg_frame( HSQDEBUGSERVER dbg );
|
||||
|
||||
// Copies the script to be able to source it to debugger clients
|
||||
SQDBG_API void sqdbg_on_script_compile( HSQDEBUGSERVER dbg, const SQChar *script, SQInteger size,
|
||||
SQDBG_API void sqdbg_on_script_compile( HSQDEBUGSERVER dbg,
|
||||
const SQChar *script, SQInteger scriptlen,
|
||||
const SQChar *sourcename, SQInteger sourcenamelen );
|
||||
|
||||
// Check if a client is connected to the debugger
|
||||
// Returns 0 if there is no client connected
|
||||
SQDBG_API int sqdbg_is_client_connected( HSQDEBUGSERVER dbg );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -62,12 +62,12 @@ class json_array_t
|
||||
{
|
||||
public:
|
||||
const char *m_pBase;
|
||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
int *m_Elements;
|
||||
unsigned short m_nElementCount;
|
||||
unsigned short m_nElementsSize;
|
||||
|
||||
void Init( const char *base, CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||
void Init( const char *base, CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||
{
|
||||
m_pBase = base;
|
||||
m_Allocator = allocator;
|
||||
@ -96,7 +96,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int size() const
|
||||
int Size() const
|
||||
{
|
||||
return m_nElementCount;
|
||||
}
|
||||
@ -138,12 +138,12 @@ class json_table_t
|
||||
{
|
||||
public:
|
||||
const char *m_pBase;
|
||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
int *m_Elements;
|
||||
unsigned short m_nElementCount;
|
||||
unsigned short m_nElementsSize;
|
||||
|
||||
void Init( const char *base, CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||
void Init( const char *base, CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator )
|
||||
{
|
||||
m_pBase = base;
|
||||
m_Allocator = allocator;
|
||||
@ -266,11 +266,20 @@ public:
|
||||
bool Get( const string_t &key, json_array_t **out ) const { return GetArray( key, out ); }
|
||||
};
|
||||
|
||||
static inline void PutStrL( CBuffer *buffer, const string_t &str )
|
||||
static inline void PutStr( CBuffer *buffer, const string_t &str )
|
||||
{
|
||||
buffer->_base.Ensure( buffer->size() + str.len );
|
||||
memcpy( buffer->base() + buffer->size(), str.ptr, str.len );
|
||||
buffer->_size += str.len;
|
||||
buffer->base.Ensure( buffer->Size() + str.len );
|
||||
memcpy( buffer->Base() + buffer->Size(), str.ptr, str.len );
|
||||
buffer->size += str.len;
|
||||
|
||||
#ifdef SQDBG_VALIDATE_SENT_MSG
|
||||
for ( unsigned int i = 0; i < str.len; i++ )
|
||||
{
|
||||
AssertMsg( IN_RANGE_CHAR( str.ptr[i], 0x20, 0x7E ) &&
|
||||
( ( str.ptr[i] != '\\' && str.ptr[i] != '\"' ) || ( i && str.ptr[i-1] == '\\' ) ),
|
||||
"control char in json string" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
@ -278,7 +287,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
const char *c = str.ptr;
|
||||
unsigned int i = str.len;
|
||||
|
||||
unsigned int len = 2 + i;
|
||||
unsigned int len = i;
|
||||
|
||||
if ( quote )
|
||||
len += 4;
|
||||
@ -287,18 +296,19 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
{
|
||||
switch ( *c )
|
||||
{
|
||||
case '\"': case '\\': case '\b':
|
||||
case '\f': case '\n': case '\r': case '\t':
|
||||
case '\\': case '\"':
|
||||
case '\a': case '\b': case '\f':
|
||||
case '\n': case '\r': case '\t': case '\v':
|
||||
len++;
|
||||
if ( quote )
|
||||
{
|
||||
len++;
|
||||
if ( *c == '\"' || *c == '\\' )
|
||||
if ( *c == '\\' || *c == '\"' )
|
||||
len++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ( !IN_RANGE_CHAR( *(unsigned char*)c, 0x20, 0x7E ) )
|
||||
if ( !IN_RANGE_CHAR( *c, 0x20, 0x7E ) )
|
||||
{
|
||||
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
||||
if ( ret != 0 )
|
||||
@ -321,16 +331,14 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
}
|
||||
}
|
||||
|
||||
buffer->_base.Ensure( buffer->size() + len );
|
||||
buffer->base.Ensure( buffer->Size() + len );
|
||||
|
||||
char *mem = buffer->base();
|
||||
unsigned int idx = buffer->size();
|
||||
char *mem = buffer->Base();
|
||||
unsigned int idx = buffer->Size();
|
||||
|
||||
c = str.ptr;
|
||||
i = str.len;
|
||||
|
||||
mem[idx++] = '\"';
|
||||
|
||||
if ( quote )
|
||||
{
|
||||
mem[idx++] = '\\';
|
||||
@ -343,6 +351,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
|
||||
switch ( *c )
|
||||
{
|
||||
case '\\':
|
||||
case '\"':
|
||||
mem[idx-1] = '\\';
|
||||
if ( quote )
|
||||
@ -350,15 +359,13 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
mem[idx++] = '\\';
|
||||
mem[idx++] = '\\';
|
||||
}
|
||||
mem[idx++] = '\"';
|
||||
mem[idx++] = *c;
|
||||
break;
|
||||
case '\\':
|
||||
case '\a':
|
||||
mem[idx-1] = '\\';
|
||||
if ( quote )
|
||||
{
|
||||
mem[idx++] = '\\';
|
||||
mem[idx++] = '\\';
|
||||
}
|
||||
mem[idx++] = '\\';
|
||||
mem[idx++] = 'a';
|
||||
break;
|
||||
case '\b':
|
||||
mem[idx-1] = '\\';
|
||||
@ -390,8 +397,14 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
mem[idx++] = '\\';
|
||||
mem[idx++] = 't';
|
||||
break;
|
||||
case '\v':
|
||||
mem[idx-1] = '\\';
|
||||
if ( quote )
|
||||
mem[idx++] = '\\';
|
||||
mem[idx++] = 'v';
|
||||
break;
|
||||
default:
|
||||
if ( !IN_RANGE_CHAR( *(unsigned char*)c, 0x20, 0x7E ) )
|
||||
if ( !IN_RANGE_CHAR( *c, 0x20, 0x7E ) )
|
||||
{
|
||||
int ret = IsValidUTF8( (unsigned char*)c, i + 1 );
|
||||
if ( ret != 0 )
|
||||
@ -410,7 +423,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
mem[idx++] = 'u';
|
||||
idx += printhex< true, false >(
|
||||
mem + idx,
|
||||
buffer->capacity() - idx,
|
||||
buffer->Capacity() - idx,
|
||||
(uint16_t)*(unsigned char*)c );
|
||||
}
|
||||
else
|
||||
@ -419,7 +432,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
mem[idx++] = 'x';
|
||||
idx += printhex< true, false >(
|
||||
mem + idx,
|
||||
buffer->capacity() - idx,
|
||||
buffer->Capacity() - idx,
|
||||
(SQChar)*(unsigned char*)c );
|
||||
}
|
||||
}
|
||||
@ -433,9 +446,7 @@ static inline void PutStr( CBuffer *buffer, const string_t &str, bool quote )
|
||||
mem[idx++] = '\"';
|
||||
}
|
||||
|
||||
mem[idx++] = '\"';
|
||||
|
||||
buffer->_size = idx;
|
||||
buffer->size = idx;
|
||||
}
|
||||
|
||||
#ifdef SQUNICODE
|
||||
@ -445,64 +456,126 @@ static inline void PutStr( CBuffer *buffer, const sqstring_t &str, bool quote )
|
||||
|
||||
if ( !quote )
|
||||
{
|
||||
len = 2 + UTF8Length< kUTFEscapeJSON >( str.ptr, str.len );
|
||||
len = UTF8Length< kUTFEscapeJSON >( str.ptr, str.len );
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 2 + UTF8Length< kUTFEscapeQuoted >( str.ptr, str.len );
|
||||
len = UTF8Length< kUTFEscapeQuoted >( str.ptr, str.len );
|
||||
}
|
||||
|
||||
buffer->_base.Ensure( buffer->size() + len );
|
||||
buffer->base()[buffer->_size++] = '\"';
|
||||
buffer->base.Ensure( buffer->Size() + len );
|
||||
|
||||
if ( !quote )
|
||||
{
|
||||
len = SQUnicodeToUTF8< kUTFEscapeJSON >(
|
||||
buffer->base() + buffer->size(),
|
||||
buffer->capacity() - buffer->size(),
|
||||
buffer->Base() + buffer->Size(),
|
||||
buffer->Capacity() - buffer->Size(),
|
||||
str.ptr,
|
||||
str.len );
|
||||
}
|
||||
else
|
||||
{
|
||||
len = SQUnicodeToUTF8< kUTFEscapeQuoted >(
|
||||
buffer->base() + buffer->size(),
|
||||
buffer->capacity() - buffer->size(),
|
||||
buffer->Base() + buffer->Size(),
|
||||
buffer->Capacity() - buffer->Size(),
|
||||
str.ptr,
|
||||
str.len );
|
||||
}
|
||||
|
||||
buffer->_size += len;
|
||||
buffer->base()[buffer->_size++] = '\"';
|
||||
buffer->size += len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void PutChar( CBuffer *buffer, char c )
|
||||
{
|
||||
buffer->_base.Ensure( buffer->size() + 1 );
|
||||
buffer->base()[buffer->_size++] = c;
|
||||
buffer->base.Ensure( buffer->Size() + 1 );
|
||||
buffer->Base()[buffer->size++] = c;
|
||||
}
|
||||
|
||||
template < typename I >
|
||||
static inline void PutInt( CBuffer *buffer, I val, bool hex = false )
|
||||
static inline void PutInt( CBuffer *buffer, I val )
|
||||
{
|
||||
int len;
|
||||
buffer->_base.Ensure( buffer->size() + countdigits( val ) + 1 );
|
||||
|
||||
if ( !hex )
|
||||
{
|
||||
len = printint( buffer->base() + buffer->size(), buffer->capacity() - buffer->size(), val );
|
||||
}
|
||||
else
|
||||
{
|
||||
len = printhex< false >( buffer->base() + buffer->size(), buffer->capacity() - buffer->size(), val );
|
||||
}
|
||||
|
||||
buffer->_size += len;
|
||||
buffer->base.Ensure( buffer->Size() + countdigits( val ) + 1 );
|
||||
int len = printint( buffer->Base() + buffer->Size(), buffer->Capacity() - buffer->Size(), val );
|
||||
buffer->size += len;
|
||||
}
|
||||
|
||||
class wjson_table_t;
|
||||
class wjson_array_t;
|
||||
template < bool padding, typename I >
|
||||
static inline void PutHex( CBuffer *buffer, I val )
|
||||
{
|
||||
buffer->base.Ensure( buffer->Size() + countdigits<16>( val ) + 1 );
|
||||
int len = printhex< padding >( buffer->Base() + buffer->Size(), buffer->Capacity() - buffer->Size(), val );
|
||||
buffer->size += len;
|
||||
}
|
||||
|
||||
struct jstringbuf_t
|
||||
{
|
||||
CBuffer *m_pBuffer;
|
||||
|
||||
jstringbuf_t( CBuffer *b ) : m_pBuffer(b)
|
||||
{
|
||||
::PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
|
||||
~jstringbuf_t()
|
||||
{
|
||||
::PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
|
||||
jstringbuf_t( const jstringbuf_t &src );
|
||||
|
||||
void Seek( int i )
|
||||
{
|
||||
m_pBuffer->size += i;
|
||||
}
|
||||
|
||||
template < int SIZE >
|
||||
void Puts( const char (&str)[SIZE] )
|
||||
{
|
||||
::PutStr( m_pBuffer, str );
|
||||
}
|
||||
|
||||
void Puts( const conststring_t &str )
|
||||
{
|
||||
::PutStr( m_pBuffer, str );
|
||||
}
|
||||
|
||||
void Puts( const string_t &str, bool quote = false )
|
||||
{
|
||||
::PutStr( m_pBuffer, str, quote );
|
||||
}
|
||||
|
||||
#ifdef SQUNICODE
|
||||
void Puts( const sqstring_t &str, bool quote = false )
|
||||
{
|
||||
::PutStr( m_pBuffer, str, quote );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Put( char c )
|
||||
{
|
||||
::PutChar( m_pBuffer, c );
|
||||
}
|
||||
|
||||
template < typename I >
|
||||
void PutInt( I val )
|
||||
{
|
||||
::PutInt( m_pBuffer, val );
|
||||
}
|
||||
|
||||
template < typename I >
|
||||
void PutHex( I val, bool padding = true )
|
||||
{
|
||||
if ( padding )
|
||||
{
|
||||
::PutHex< true >( m_pBuffer, val );
|
||||
}
|
||||
else
|
||||
{
|
||||
::PutHex< false >( m_pBuffer, val );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class wjson_t
|
||||
{
|
||||
@ -542,7 +615,7 @@ public:
|
||||
PutChar( m_pBuffer, ',' );
|
||||
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStrL( m_pBuffer, key );
|
||||
PutStr( m_pBuffer, key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutChar( m_pBuffer, ':' );
|
||||
}
|
||||
@ -556,26 +629,53 @@ public:
|
||||
void SetNull( const string_t &key )
|
||||
{
|
||||
PutKey( key );
|
||||
PutStrL( m_pBuffer, "null" );
|
||||
PutStr( m_pBuffer, "null" );
|
||||
}
|
||||
|
||||
void SetBool( const string_t &key, bool val )
|
||||
{
|
||||
PutKey( key );
|
||||
PutStrL( m_pBuffer, val ? string_t("true") : string_t("false") );
|
||||
PutStr( m_pBuffer, val ? string_t("true") : string_t("false") );
|
||||
}
|
||||
|
||||
jstringbuf_t SetStringAsBuf( const string_t &key )
|
||||
{
|
||||
PutKey( key );
|
||||
return { m_pBuffer };
|
||||
}
|
||||
|
||||
template < int SIZE >
|
||||
void SetString( const string_t &key, const char (&val)[SIZE] )
|
||||
{
|
||||
PutKey( key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStr( m_pBuffer, val );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
|
||||
void SetString( const string_t &key, const conststring_t &val )
|
||||
{
|
||||
PutKey( key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStr( m_pBuffer, val );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
|
||||
void SetString( const string_t &key, const string_t &val, bool quote = false )
|
||||
{
|
||||
PutKey( key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStr( m_pBuffer, val, quote );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
|
||||
#ifdef SQUNICODE
|
||||
void SetString( const string_t &key, const sqstring_t &val, bool quote = false )
|
||||
{
|
||||
PutKey( key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStr( m_pBuffer, val, quote );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -593,7 +693,14 @@ public:
|
||||
PutKey( key );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutChar( m_pBuffer, '[' );
|
||||
PutInt( m_pBuffer, val, hex );
|
||||
if ( !hex )
|
||||
{
|
||||
PutInt( m_pBuffer, val );
|
||||
}
|
||||
else
|
||||
{
|
||||
PutHex< false >( m_pBuffer, val );
|
||||
}
|
||||
PutChar( m_pBuffer, ']' );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
@ -637,7 +744,7 @@ public:
|
||||
|
||||
wjson_array_t( const wjson_array_t &src );
|
||||
|
||||
int size()
|
||||
int Size()
|
||||
{
|
||||
return m_nElementCount;
|
||||
}
|
||||
@ -665,7 +772,7 @@ public:
|
||||
PutChar( m_pBuffer, ',' );
|
||||
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
PutStrL( m_pBuffer, val );
|
||||
PutStr( m_pBuffer, val );
|
||||
PutChar( m_pBuffer, '\"' );
|
||||
}
|
||||
};
|
||||
@ -676,7 +783,7 @@ private:
|
||||
char *m_cur;
|
||||
char *m_end;
|
||||
char *m_start;
|
||||
CScratch< JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *m_Allocator;
|
||||
char *m_error;
|
||||
|
||||
enum
|
||||
@ -693,7 +800,7 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
JSONParser( CScratch< JSON_SCRATCH_CHUNK_SIZE > *allocator, char *ptr, int len, json_table_t *pTable ) :
|
||||
JSONParser( CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *allocator, char *ptr, int len, json_table_t *pTable ) :
|
||||
m_cur( ptr ),
|
||||
m_end( ptr + len + 1 ),
|
||||
m_start( ptr ),
|
||||
@ -710,7 +817,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError( "expected '%c', got '0x%02x' @ %i", '{', Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", '{', Char(type), Index() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -725,12 +832,30 @@ private:
|
||||
return m_cur - m_start;
|
||||
}
|
||||
|
||||
unsigned char Char( char token )
|
||||
char *Char( char token )
|
||||
{
|
||||
if ( token != Token_Error )
|
||||
return (unsigned char)token;
|
||||
char *buf;
|
||||
|
||||
return *(unsigned char*)m_cur;
|
||||
if ( token == Token_Error )
|
||||
token = *m_cur;
|
||||
|
||||
if ( IN_RANGE_CHAR( token, 0x20, 0x7E ) )
|
||||
{
|
||||
buf = m_Allocator->Alloc(4);
|
||||
buf[0] = '\'';
|
||||
buf[1] = token;
|
||||
buf[2] = '\'';
|
||||
buf[3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = m_Allocator->Alloc(5);
|
||||
int i = printhex< true, true, false >( buf, 5, token );
|
||||
Assert( i == 4 );
|
||||
buf[i] = 0;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void SetError( const char *fmt, ... )
|
||||
@ -776,37 +901,37 @@ private:
|
||||
return *m_cur++;
|
||||
|
||||
case 't':
|
||||
if ( m_cur + 4 >= m_end ||
|
||||
m_cur[1] != 'r' || m_cur[2] != 'u' || m_cur[3] != 'e' )
|
||||
if ( m_cur + 4 < m_end &&
|
||||
m_cur[1] == 'r' && m_cur[2] == 'u' && m_cur[3] == 'e' )
|
||||
{
|
||||
SetError( "expected %s @ %i", "\"true\"", Index() );
|
||||
return Token_Error;
|
||||
m_cur += 4;
|
||||
return Token_True;
|
||||
}
|
||||
|
||||
m_cur += 4;
|
||||
return Token_True;
|
||||
SetError( "expected %s @ %i", "\"true\"", Index() );
|
||||
return Token_Error;
|
||||
|
||||
case 'f':
|
||||
if ( m_cur + 5 >= m_end ||
|
||||
m_cur[1] != 'a' || m_cur[2] != 'l' || m_cur[3] != 's' || m_cur[4] != 'e' )
|
||||
if ( m_cur + 5 < m_end &&
|
||||
m_cur[1] == 'a' && m_cur[2] == 'l' && m_cur[3] == 's' && m_cur[4] == 'e' )
|
||||
{
|
||||
SetError( "expected %s @ %i", "\"false\"", Index() );
|
||||
return Token_Error;
|
||||
m_cur += 5;
|
||||
return Token_False;
|
||||
}
|
||||
|
||||
m_cur += 5;
|
||||
return Token_False;
|
||||
SetError( "expected %s @ %i", "\"false\"", Index() );
|
||||
return Token_Error;
|
||||
|
||||
case 'n':
|
||||
if ( m_cur + 4 >= m_end ||
|
||||
m_cur[1] != 'u' || m_cur[2] != 'l' || m_cur[3] != 'l' )
|
||||
if ( m_cur + 4 < m_end &&
|
||||
m_cur[1] == 'u' && m_cur[2] == 'l' && m_cur[3] == 'l' )
|
||||
{
|
||||
SetError( "expected %s @ %i", "\"null\"", Index() );
|
||||
return Token_Error;
|
||||
m_cur += 4;
|
||||
return Token_Null;
|
||||
}
|
||||
|
||||
m_cur += 4;
|
||||
return Token_Null;
|
||||
SetError( "expected %s @ %i", "\"null\"", Index() );
|
||||
return Token_Error;
|
||||
|
||||
default:
|
||||
return Token_Error;
|
||||
@ -829,12 +954,10 @@ private:
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
// end
|
||||
if ( *m_cur == '\"' )
|
||||
{
|
||||
*m_cur = 0;
|
||||
token.Assign( pStart, m_cur - pStart );
|
||||
m_cur++;
|
||||
*m_cur++ = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -857,7 +980,7 @@ private:
|
||||
// Defer unescape until the end of the string is found
|
||||
switch ( *m_cur )
|
||||
{
|
||||
case '\"': case '\\': case '/':
|
||||
case '\\': case '\"': case '/':
|
||||
case 'b': case 'f':
|
||||
case 'n': case 'r': case 't':
|
||||
m_cur++;
|
||||
@ -876,7 +999,7 @@ private:
|
||||
break;
|
||||
|
||||
default:
|
||||
SetError( "invalid escape char '0x%02x' @ %i", *(unsigned char*)m_cur, Index() );
|
||||
SetError( "invalid escape char 0x%02x @ %i", *(unsigned char*)m_cur, Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
}
|
||||
@ -895,6 +1018,7 @@ private:
|
||||
}
|
||||
|
||||
#define _shift( bytesWritten, bytesRead ) \
|
||||
Assert( (bytesWritten) < (bytesRead) ); \
|
||||
memmove( cur + (bytesWritten), cur + (bytesRead), end - ( cur + (bytesRead) ) ); \
|
||||
cur += (bytesWritten); \
|
||||
end -= (bytesRead) - (bytesWritten);
|
||||
@ -903,22 +1027,21 @@ private:
|
||||
{
|
||||
case '\\':
|
||||
shift_one:
|
||||
_shift( 0, 1 );
|
||||
cur++;
|
||||
_shift( 1, 2 );
|
||||
break;
|
||||
case '\"': goto shift_one;
|
||||
case '/': goto shift_one;
|
||||
case 'b': cur[1] = '\b'; goto shift_one;
|
||||
case 'f': cur[1] = '\f'; goto shift_one;
|
||||
case 'n': cur[1] = '\n'; goto shift_one;
|
||||
case 'r': cur[1] = '\r'; goto shift_one;
|
||||
case 't': cur[1] = '\t'; goto shift_one;
|
||||
case '\"': cur[0] = '\"'; goto shift_one;
|
||||
case '/': cur[0] = '/'; goto shift_one;
|
||||
case 'b': cur[0] = '\b'; goto shift_one;
|
||||
case 'f': cur[0] = '\f'; goto shift_one;
|
||||
case 'n': cur[0] = '\n'; goto shift_one;
|
||||
case 'r': cur[0] = '\r'; goto shift_one;
|
||||
case 't': cur[0] = '\t'; goto shift_one;
|
||||
case 'u':
|
||||
{
|
||||
unsigned int val;
|
||||
Verify( atox( { cur + 2, 4 }, &val ) );
|
||||
|
||||
if ( val <= 0xFF )
|
||||
if ( val <= 0x7F )
|
||||
{
|
||||
cur[0] = (char)val;
|
||||
|
||||
@ -993,7 +1116,7 @@ shift_one:
|
||||
if ( m_cur >= m_end )
|
||||
goto err_eof;
|
||||
}
|
||||
else if ( IN_RANGE_CHAR( *(unsigned char*)m_cur, '1', '9' ) )
|
||||
else if ( IN_RANGE_CHAR( *m_cur, '1', '9' ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -1001,11 +1124,11 @@ shift_one:
|
||||
if ( m_cur >= m_end )
|
||||
goto err_eof;
|
||||
}
|
||||
while ( IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) );
|
||||
while ( IN_RANGE_CHAR( *m_cur, '0', '9' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError( "unexpected char '0x%02x' in number @ %i", *(unsigned char*)m_cur, Index() );
|
||||
SetError( "unexpected char 0x%02x in number @ %i", *(unsigned char*)m_cur, Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1016,7 +1139,7 @@ shift_one:
|
||||
type = Token_Float;
|
||||
m_cur++;
|
||||
|
||||
while ( m_cur < m_end && IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) )
|
||||
while ( m_cur < m_end && IN_RANGE_CHAR( *m_cur, '0', '9' ) )
|
||||
m_cur++;
|
||||
|
||||
if ( m_cur >= m_end )
|
||||
@ -1039,7 +1162,7 @@ shift_one:
|
||||
goto err_eof;
|
||||
}
|
||||
|
||||
while ( m_cur < m_end && IN_RANGE_CHAR( *(unsigned char*)m_cur, '0', '9' ) )
|
||||
while ( m_cur < m_end && IN_RANGE_CHAR( *m_cur, '0', '9' ) )
|
||||
m_cur++;
|
||||
}
|
||||
|
||||
@ -1062,7 +1185,7 @@ err_eof:
|
||||
{
|
||||
if ( type != Token_String )
|
||||
{
|
||||
SetError( "expected %s, got '0x%02x' @ %i", "string", Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", '\"', Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1070,7 +1193,7 @@ err_eof:
|
||||
|
||||
if ( type != ':' )
|
||||
{
|
||||
SetError( "expected '%c', got '0x%02x' @ %i", ':', Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", ':', Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1085,7 +1208,7 @@ err_eof:
|
||||
|
||||
if ( type == Token_Error )
|
||||
{
|
||||
SetError( "invalid token '0x%02x' @ %i", Char(type), Index() );
|
||||
SetError( "invalid token %s @ %i", Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1101,7 +1224,7 @@ err_eof:
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError( "expected '%c', got '0x%02x' @ %i", '}', Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", '}', Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
}
|
||||
@ -1118,7 +1241,7 @@ err_eof:
|
||||
{
|
||||
if ( type == Token_Error )
|
||||
{
|
||||
SetError( "expected '%c', got '0x%02x' @ %i", ']', Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", ']', Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1127,7 +1250,7 @@ err_eof:
|
||||
|
||||
if ( type == Token_Error )
|
||||
{
|
||||
SetError( "invalid token '0x%02x' @ %i", Char(type), Index() );
|
||||
SetError( "invalid token %s @ %i", Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
|
||||
@ -1143,7 +1266,7 @@ err_eof:
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError( "expected '%c', got '0x%02x' @ %i", ']', Char(type), Index() );
|
||||
SetError( "expected '%c', got %s @ %i", ']', Char(type), Index() );
|
||||
return Token_Error;
|
||||
}
|
||||
}
|
||||
@ -1154,7 +1277,7 @@ err_eof:
|
||||
switch ( type )
|
||||
{
|
||||
case Token_Integer:
|
||||
if ( token.len > FMT_INT_LEN )
|
||||
if ( token.len > FMT_UINT32_LEN + 1 )
|
||||
{
|
||||
SetError( "invalid integer literal @ %i", Index() );
|
||||
return Token_Error;
|
||||
|
@ -602,6 +602,9 @@ public:
|
||||
|
||||
bool Listen()
|
||||
{
|
||||
if ( m_ServerSocket == INVALID_SOCKET )
|
||||
return false;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
@ -12,10 +12,10 @@
|
||||
|
||||
inline void DAP_Serialise( CBuffer *buffer )
|
||||
{
|
||||
Assert( buffer->size() > 0 && buffer->size() < INT_MAX );
|
||||
Assert( buffer->Size() > 0 && buffer->Size() < INT_MAX );
|
||||
|
||||
char *mem = buffer->base();
|
||||
int contentSize = buffer->size() - DAP_HEADER_MAXSIZE;
|
||||
char *mem = buffer->Base();
|
||||
int contentSize = buffer->Size() - DAP_HEADER_MAXSIZE;
|
||||
int digits = countdigits( contentSize );
|
||||
int padding = FMT_UINT32_LEN - digits;
|
||||
|
||||
@ -31,8 +31,8 @@ inline void DAP_Serialise( CBuffer *buffer )
|
||||
// add padding in the end to match
|
||||
padding--;
|
||||
digits++;
|
||||
buffer->_base.Ensure( buffer->size() + 1 );
|
||||
mem[buffer->_size++] = ' ';
|
||||
buffer->base.Ensure( buffer->Size() + 1 );
|
||||
mem[buffer->size++] = ' ';
|
||||
}
|
||||
|
||||
memcpy( mem, DAP_HEADER_CONTENTLENGTH ": ", STRLEN(DAP_HEADER_CONTENTLENGTH ": ") );
|
||||
@ -53,10 +53,10 @@ inline void DAP_Serialise( CBuffer *buffer )
|
||||
|
||||
inline void DAP_Free( CBuffer *buffer )
|
||||
{
|
||||
buffer->_size = 0;
|
||||
buffer->size = 0;
|
||||
}
|
||||
|
||||
static inline void ParseFieldName( const char *pMemEnd, char *pStart, int *len )
|
||||
static inline int ParseFieldName( const char *pMemEnd, char *pStart )
|
||||
{
|
||||
char *c = pStart;
|
||||
|
||||
@ -65,56 +65,39 @@ static inline void ParseFieldName( const char *pMemEnd, char *pStart, int *len )
|
||||
if ( IN_RANGE_CHAR( ((unsigned char*)c)[0], 0x20, 0x7E ) )
|
||||
{
|
||||
if ( c + 1 >= pMemEnd )
|
||||
{
|
||||
*len = -1;
|
||||
return;
|
||||
}
|
||||
return -1;
|
||||
|
||||
if ( c[0] == ':' )
|
||||
{
|
||||
if ( c[1] == ' ' )
|
||||
{
|
||||
*len = c - pStart;
|
||||
return;
|
||||
}
|
||||
return c - pStart;
|
||||
|
||||
*len = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ParseFieldValue( const char *pMemEnd, char *pStart, int *len )
|
||||
static inline int ParseFieldValue( const char *pMemEnd, char *pStart )
|
||||
{
|
||||
char *c = pStart;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( c + 1 >= pMemEnd )
|
||||
{
|
||||
*len = -1;
|
||||
return;
|
||||
}
|
||||
return -1;
|
||||
|
||||
if ( c[0] == '\n' )
|
||||
{
|
||||
*len = 0;
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if ( c[0] == '\r' && c[1] == '\n' )
|
||||
{
|
||||
*len = c - pStart;
|
||||
return;
|
||||
}
|
||||
return c - pStart;
|
||||
|
||||
c++;
|
||||
}
|
||||
@ -128,8 +111,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int len;
|
||||
ParseFieldName( pMemEnd, pMsg, &len );
|
||||
int len = ParseFieldName( pMemEnd, pMsg );
|
||||
|
||||
if ( len == 0 )
|
||||
goto invalid;
|
||||
@ -151,7 +133,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
||||
if ( pMsg >= pMemEnd )
|
||||
return false;
|
||||
|
||||
if ( IN_RANGE_CHAR( *(unsigned char*)pMsg, '0', '9' ) )
|
||||
if ( IN_RANGE_CHAR( *pMsg, '0', '9' ) )
|
||||
{
|
||||
nContentLength = nContentLength * 10 + *pMsg - '0';
|
||||
pMsg++;
|
||||
@ -187,7 +169,7 @@ inline bool DAP_ReadHeader( char **ppMsg, int *pLength )
|
||||
ignore:
|
||||
pMsg += len + 2;
|
||||
|
||||
ParseFieldValue( pMemEnd, pMsg, &len );
|
||||
len = ParseFieldValue( pMemEnd, pMsg );
|
||||
|
||||
if ( len == 0 )
|
||||
goto invalid;
|
||||
@ -216,13 +198,13 @@ invalid:
|
||||
}
|
||||
|
||||
#ifdef SQDBG_VALIDATE_SENT_MSG
|
||||
inline void DAP_Test( CScratch< JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buffer )
|
||||
inline void DAP_Test( CScratch< true, JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buffer )
|
||||
{
|
||||
char *pMsg = buffer->base();
|
||||
int nLength = buffer->size();
|
||||
char *pMsg = buffer->Base();
|
||||
int nLength = buffer->Size();
|
||||
|
||||
bool res = DAP_ReadHeader( &pMsg, &nLength );
|
||||
Assert( res && nLength < buffer->size() );
|
||||
Assert( res && nLength < buffer->Size() );
|
||||
|
||||
if ( res )
|
||||
{
|
||||
@ -238,7 +220,7 @@ inline void DAP_Test( CScratch< JSON_SCRATCH_CHUNK_SIZE > *scratch, CBuffer *buf
|
||||
|
||||
#define _DAP_INIT_BUF( _buf ) \
|
||||
CBufTmpCache _bufcache( (_buf) ); \
|
||||
(_buf)->_size = DAP_HEADER_MAXSIZE; \
|
||||
(_buf)->size = DAP_HEADER_MAXSIZE; \
|
||||
(void)0
|
||||
|
||||
#define DAP_START_REQUEST( _seq, _cmd ) \
|
||||
@ -262,10 +244,10 @@ if ( IsClientConnected() ) \
|
||||
packet.SetBool( "success", _suc );
|
||||
|
||||
#define DAP_START_RESPONSE( _seq, _cmd ) \
|
||||
_DAP_START_RESPONSE( _seq, _cmd, true );
|
||||
_DAP_START_RESPONSE( _seq, _cmd, true )
|
||||
|
||||
#define DAP_ERROR_RESPONSE( _seq, _cmd ) \
|
||||
_DAP_START_RESPONSE( _seq, _cmd, false );
|
||||
_DAP_START_RESPONSE( _seq, _cmd, false )
|
||||
|
||||
#define DAP_ERROR_BODY( _id, _fmt ) \
|
||||
wjson_table_t body = packet.SetTable( "body" ); \
|
||||
@ -292,7 +274,7 @@ if ( IsClientConnected() ) \
|
||||
} \
|
||||
\
|
||||
DAP_Serialise( &m_SendBuf ); \
|
||||
Send( m_SendBuf.base(), m_SendBuf.size() ); \
|
||||
Send( m_SendBuf.Base(), m_SendBuf.Size() ); \
|
||||
DAP_Test( &m_ReadBuf, &m_SendBuf ); \
|
||||
DAP_Free( &m_SendBuf ); \
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -76,12 +76,19 @@ template < typename I >
|
||||
bool atoo( string_t str, I *out );
|
||||
|
||||
|
||||
#ifdef SQUNICODE
|
||||
void CopyString( const string_t &src, sqstring_t *dst );
|
||||
void CopyString( const sqstring_t &src, string_t *dst );
|
||||
#endif
|
||||
template < typename T > void CopyString( const T &src, T *dst );
|
||||
template < typename T > void FreeString( T *dst );
|
||||
#define _isdigit( c ) \
|
||||
IN_RANGE_CHAR( c, '0', '9' )
|
||||
|
||||
#define _isxdigit( c ) \
|
||||
( IN_RANGE_CHAR( c, '0', '9' ) || \
|
||||
IN_RANGE_CHAR( c, 'A', 'F' ) || \
|
||||
IN_RANGE_CHAR( c, 'a', 'f' ) )
|
||||
|
||||
#define _isalpha( c ) \
|
||||
( IN_RANGE_CHAR( c, 'A', 'Z' ) || IN_RANGE_CHAR( c, 'a', 'z' ) )
|
||||
|
||||
#define _isalnum( c ) \
|
||||
( _isalpha(c) || _isdigit(c) )
|
||||
|
||||
#define IN_RANGE(c, min, max) \
|
||||
((uint32_t)((uint32_t)(c) - (uint32_t)(min)) <= (uint32_t)((max)-(min)))
|
||||
@ -249,51 +256,21 @@ struct string_t
|
||||
}
|
||||
#endif
|
||||
|
||||
template < int size >
|
||||
string_t( const char (&src)[size] ) :
|
||||
template < int SIZE >
|
||||
string_t( const char (&src)[SIZE] ) :
|
||||
ptr((char*)src),
|
||||
len(size-1)
|
||||
len(SIZE-1)
|
||||
{
|
||||
// input wasn't a string literal,
|
||||
// call ( src, size ) constructor instead
|
||||
Assert( strlen(src) == len );
|
||||
}
|
||||
|
||||
void Strip()
|
||||
template < int SIZE >
|
||||
bool StartsWith( const char (&other)[SIZE] ) const
|
||||
{
|
||||
char *end = ptr + len;
|
||||
|
||||
for ( char *c = ptr; c < end; c++ )
|
||||
{
|
||||
if ( *c == ' ' || *c == '\t' || *c == '\n' )
|
||||
{
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ( char *c = end - 1; c >= ptr; c-- )
|
||||
{
|
||||
if ( *c == ' ' || *c == '\t' || *c == '\n' )
|
||||
{
|
||||
len--;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < int size >
|
||||
bool StartsWith( const char (&other)[size] ) const
|
||||
{
|
||||
if ( size-1 <= len && *ptr == *other )
|
||||
return !memcmp( ptr, other, size-1 );
|
||||
if ( SIZE-1 <= len && *ptr == *other )
|
||||
return !memcmp( ptr, other, SIZE-1 );
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -306,11 +283,11 @@ struct string_t
|
||||
return false;
|
||||
}
|
||||
|
||||
template < int size >
|
||||
bool IsEqualTo( const char (&other)[size] ) const
|
||||
template < int SIZE >
|
||||
bool IsEqualTo( const char (&other)[SIZE] ) const
|
||||
{
|
||||
if ( size-1 == len && *ptr == *other )
|
||||
return !memcmp( ptr, other, size-1 );
|
||||
if ( SIZE-1 == len && *ptr == *other )
|
||||
return !memcmp( ptr, other, SIZE-1 );
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -333,6 +310,14 @@ struct string_t
|
||||
|
||||
#ifdef SQUNICODE
|
||||
bool IsEqualTo( const sqstring_t &other ) const;
|
||||
#else
|
||||
bool IsEqualTo( const SQString *other ) const
|
||||
{
|
||||
if ( (SQUnsignedInteger)len == (SQUnsignedInteger)other->_len && *ptr == *other->_val )
|
||||
return !memcmp( ptr, other->_val, sq_rsl(len) );
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsEmpty() const
|
||||
@ -345,11 +330,11 @@ struct string_t
|
||||
return ( memchr( ptr, ch, len ) != NULL );
|
||||
}
|
||||
|
||||
template < int size >
|
||||
void Assign( const char (&src)[size] )
|
||||
template < int SIZE >
|
||||
void Assign( const char (&src)[SIZE] )
|
||||
{
|
||||
ptr = (char*)src;
|
||||
len = size - 1;
|
||||
len = SIZE - 1;
|
||||
Assert( strlen(src) == len );
|
||||
}
|
||||
|
||||
@ -373,6 +358,14 @@ private:
|
||||
string_t &operator=( const char *src );
|
||||
};
|
||||
|
||||
struct conststring_t : string_t
|
||||
{
|
||||
template < int SIZE >
|
||||
conststring_t( const char (&src)[SIZE] ) : string_t(src) {}
|
||||
|
||||
conststring_t() {}
|
||||
};
|
||||
|
||||
#ifdef SQUNICODE
|
||||
struct sqstring_t
|
||||
{
|
||||
@ -393,10 +386,10 @@ struct sqstring_t
|
||||
{
|
||||
}
|
||||
|
||||
template < int size >
|
||||
sqstring_t( const SQChar (&src)[size] ) :
|
||||
template < int SIZE >
|
||||
sqstring_t( const SQChar (&src)[SIZE] ) :
|
||||
ptr((SQChar*)src),
|
||||
len(size-1)
|
||||
len(SIZE-1)
|
||||
{
|
||||
Assert( scstrlen(src) == len );
|
||||
}
|
||||
@ -434,7 +427,7 @@ struct sqstring_t
|
||||
|
||||
bool IsEqualTo( const SQString *other ) const
|
||||
{
|
||||
if ( len == other->_len && *ptr == *other->_val )
|
||||
if ( (SQUnsignedInteger)len == (SQUnsignedInteger)other->_len && *ptr == *other->_val )
|
||||
return !memcmp( ptr, other->_val, sq_rsl(len) );
|
||||
|
||||
return false;
|
||||
@ -445,11 +438,11 @@ struct sqstring_t
|
||||
return !len;
|
||||
}
|
||||
|
||||
template < int size >
|
||||
void Assign( const SQChar (&src)[size] )
|
||||
template < int SIZE >
|
||||
void Assign( const SQChar (&src)[SIZE] )
|
||||
{
|
||||
ptr = (SQChar*)src;
|
||||
len = size - 1;
|
||||
len = SIZE - 1;
|
||||
Assert( scstrlen(src) == len );
|
||||
}
|
||||
|
||||
@ -471,12 +464,12 @@ struct stringbufbase_t
|
||||
{
|
||||
char *ptr;
|
||||
unsigned int len;
|
||||
const int size;
|
||||
const unsigned int size;
|
||||
|
||||
stringbufbase_t( char *src, unsigned int size ) :
|
||||
stringbufbase_t( char *src, unsigned int nSize ) :
|
||||
ptr(src),
|
||||
len(0),
|
||||
size(size)
|
||||
size(nSize)
|
||||
{
|
||||
}
|
||||
|
||||
@ -622,20 +615,6 @@ struct stringbuf_t : stringbufbase_t
|
||||
}
|
||||
};
|
||||
|
||||
#define _isdigit( c ) \
|
||||
IN_RANGE_CHAR(c, '0', '9')
|
||||
|
||||
#define _isxdigit( c ) \
|
||||
( IN_RANGE_CHAR(c, '0', '9') || \
|
||||
IN_RANGE_CHAR(c, 'A', 'F') || \
|
||||
IN_RANGE_CHAR(c, 'a', 'f') )
|
||||
|
||||
#define _isalpha( c ) \
|
||||
( IN_RANGE_CHAR(c, 'A', 'Z') || IN_RANGE_CHAR(c, 'a', 'z') )
|
||||
|
||||
#define _isalnum( c ) \
|
||||
( _isalpha(c) || _isdigit(c) )
|
||||
|
||||
template < int BASE = 10, typename I >
|
||||
inline int countdigits( I input )
|
||||
{
|
||||
@ -789,7 +768,7 @@ inline bool atoi( string_t str, I *out )
|
||||
{
|
||||
unsigned char ch = *str.ptr;
|
||||
|
||||
if ( IN_RANGE_CHAR(ch, '0', '9') )
|
||||
if ( IN_RANGE_CHAR( ch, '0', '9' ) )
|
||||
{
|
||||
val *= 10;
|
||||
val += ch - '0';
|
||||
@ -820,17 +799,17 @@ inline bool atox( string_t str, I *out )
|
||||
{
|
||||
unsigned char ch = *str.ptr;
|
||||
|
||||
if ( IN_RANGE_CHAR(ch, '0', '9') )
|
||||
if ( IN_RANGE_CHAR( ch, '0', '9' ) )
|
||||
{
|
||||
val <<= 4;
|
||||
val += ch - '0';
|
||||
}
|
||||
else if ( IN_RANGE_CHAR(ch, 'A', 'F') )
|
||||
else if ( IN_RANGE_CHAR( ch, 'A', 'F' ) )
|
||||
{
|
||||
val <<= 4;
|
||||
val += ch - 'A' + 10;
|
||||
}
|
||||
else if ( IN_RANGE_CHAR(ch, 'a', 'f') )
|
||||
else if ( IN_RANGE_CHAR( ch, 'a', 'f' ) )
|
||||
{
|
||||
val <<= 4;
|
||||
val += ch - 'a' + 10;
|
||||
@ -855,7 +834,7 @@ inline bool atoo( string_t str, I *out )
|
||||
{
|
||||
unsigned char ch = *str.ptr;
|
||||
|
||||
if ( IN_RANGE_CHAR(ch, '0', '7') )
|
||||
if ( IN_RANGE_CHAR( ch, '0', '7' ) )
|
||||
{
|
||||
val <<= 3;
|
||||
val += ch - '0';
|
||||
@ -898,7 +877,7 @@ inline int IsValidUTF8( unsigned char *src, unsigned int srclen )
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if ( IN_RANGE_CHAR(cp, 0xC2, 0xF4) )
|
||||
else if ( IN_RANGE_CHAR( cp, 0xC2, 0xF4 ) )
|
||||
{
|
||||
if ( UTF8_2_LEAD(cp) )
|
||||
{
|
||||
@ -938,7 +917,7 @@ inline int IsValidUTF8( unsigned char *src, unsigned int srclen )
|
||||
|
||||
if ( !UTF8_TRAIL(cp) )
|
||||
{
|
||||
if ( IN_RANGE_CHAR(cp, 0xC2, 0xF4) )
|
||||
if ( IN_RANGE_CHAR( cp, 0xC2, 0xF4 ) )
|
||||
goto check;
|
||||
|
||||
return 0;
|
||||
@ -967,34 +946,8 @@ inline int IsValidUnicode( const SQChar *src, unsigned int srclen )
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if ( cp <= 0xFF )
|
||||
else if ( cp < 0xA0 )
|
||||
{
|
||||
if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
||||
{
|
||||
if ( UTF8_2_LEAD(cp) )
|
||||
{
|
||||
if ( UTF8_2( srclen, cp, src ) )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ( UTF8_3_LEAD(cp) )
|
||||
{
|
||||
if ( UTF8_3( srclen, cp, src ) )
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else if ( UTF8_4_LEAD(cp) )
|
||||
{
|
||||
if ( UTF8_4( srclen, cp, src ) )
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
// else [0x7F, 0xC2) & (0xF4, 0xFF]
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1041,18 +994,21 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
||||
{
|
||||
switch ( ((unsigned char*)src)[1] )
|
||||
{
|
||||
case '\"': cp = '\"'; src++; break;
|
||||
case '\\': src++; break;
|
||||
case '\"': cp = '\"'; src++; break;
|
||||
case '\'': cp = '\''; src++; break;
|
||||
case 'a': cp = '\a'; src++; break;
|
||||
case 'b': cp = '\b'; src++; break;
|
||||
case 'f': cp = '\f'; src++; break;
|
||||
case 'n': cp = '\n'; src++; break;
|
||||
case 'r': cp = '\r'; src++; break;
|
||||
case 't': cp = '\t'; src++; break;
|
||||
case 'v': cp = '\v'; src++; break;
|
||||
case 'x':
|
||||
{
|
||||
if ( src + sizeof(SQChar) * 2 + 1 < end )
|
||||
{
|
||||
Verify( atox( { src + 2, sizeof(SQChar) * 2 }, &cp ) );
|
||||
atox( { src + 2, sizeof(SQChar) * 2 }, &cp );
|
||||
src += sizeof(SQChar) * 2 + 1;
|
||||
}
|
||||
|
||||
@ -1062,7 +1018,7 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
||||
{
|
||||
if ( src + sizeof(uint16_t) * 2 + 1 < end )
|
||||
{
|
||||
Verify( atox( { src + 2, sizeof(uint16_t) * 2 }, &cp ) );
|
||||
atox( { src + 2, sizeof(uint16_t) * 2 }, &cp );
|
||||
src += sizeof(uint16_t) * 2 + 1;
|
||||
}
|
||||
|
||||
@ -1074,7 +1030,7 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
||||
|
||||
goto xffff;
|
||||
}
|
||||
else if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
||||
else if ( IN_RANGE( cp, 0xC2, 0xF4 ) )
|
||||
{
|
||||
if ( UTF8_2_LEAD(cp) )
|
||||
{
|
||||
@ -1111,34 +1067,13 @@ inline unsigned int UTF8ToSQUnicode( SQChar *dst, unsigned int destSize, const c
|
||||
goto xffff;
|
||||
}
|
||||
|
||||
xffff:
|
||||
#if WCHAR_SIZE == 4
|
||||
xffff:
|
||||
supplementary:
|
||||
#endif
|
||||
if ( dst )
|
||||
{
|
||||
if ( destSize >= sizeof(SQChar) )
|
||||
{
|
||||
*dst++ = cp;
|
||||
destSize -= sizeof(SQChar);
|
||||
count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// out of space
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
#else // WCHAR_SIZE == 2
|
||||
xffff:
|
||||
if ( dst )
|
||||
{
|
||||
if ( destSize >= sizeof(SQChar) )
|
||||
if ( sizeof(SQChar) <= destSize )
|
||||
{
|
||||
*dst++ = (SQChar)cp;
|
||||
destSize -= sizeof(SQChar);
|
||||
@ -1157,14 +1092,15 @@ xffff:
|
||||
|
||||
continue;
|
||||
|
||||
#if WCHAR_SIZE == 2
|
||||
supplementary:
|
||||
if ( dst )
|
||||
{
|
||||
if ( destSize > sizeof(SQChar) )
|
||||
if ( sizeof(SQChar) * 2 <= destSize )
|
||||
{
|
||||
UTF16_SURROGATE_FROM_UTF32( dst, cp );
|
||||
dst += 2;
|
||||
destSize -= 2 * sizeof(SQChar);
|
||||
destSize -= sizeof(SQChar) * 2;
|
||||
count += 2;
|
||||
}
|
||||
else
|
||||
@ -1241,6 +1177,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
||||
|
||||
switch ( cp )
|
||||
{
|
||||
case '\\':
|
||||
case '\"':
|
||||
if ( escape == kUTFEscapeQuoted )
|
||||
{
|
||||
@ -1248,16 +1185,15 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
||||
mbc[bytes++] = '\\';
|
||||
}
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = '\"';
|
||||
mbc[bytes++] = (unsigned char)cp;
|
||||
goto write;
|
||||
case '\\':
|
||||
case '\a':
|
||||
if ( escape == kUTFEscapeJSON )
|
||||
goto doescape;
|
||||
if ( escape == kUTFEscapeQuoted )
|
||||
{
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = '\\';
|
||||
}
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = 'a';
|
||||
goto write;
|
||||
case '\b':
|
||||
if ( escape == kUTFEscapeQuoted )
|
||||
@ -1289,15 +1225,25 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = 't';
|
||||
goto write;
|
||||
case '\v':
|
||||
if ( escape == kUTFEscapeJSON )
|
||||
goto doescape;
|
||||
if ( escape == kUTFEscapeQuoted )
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = '\\';
|
||||
mbc[bytes++] = 'v';
|
||||
goto write;
|
||||
|
||||
default:
|
||||
|
||||
if ( !IN_RANGE_CHAR(cp, 0x20, 0x7E) )
|
||||
if ( !IN_RANGE_CHAR( cp, 0x20, 0x7E ) )
|
||||
{
|
||||
// While UTF8 bytes are valid UTF16, converting them will
|
||||
// make distinct SQ strings indistinguishable to the client
|
||||
#ifndef SQDBG_ESCAPE_UTF8_BYTES_IN_UTF16
|
||||
if ( IN_RANGE(cp, 0xC2, 0xF4) )
|
||||
// Convert UTF8 bytes in UTF16 by default with the assumption of
|
||||
// most editors using UTF8 without BOM,
|
||||
// and files being likely read plain (no conversion/ISO 8859-1)
|
||||
// However, this will make certain distinct SQ strings (e.g. "\xC3\xBC", "\xFC")
|
||||
// indistinguishable to the client
|
||||
#ifndef SQDBG_DONT_CONVERT_UTF8_BYTES_IN_UTF16
|
||||
if ( IN_RANGE( cp, 0xC2, 0xF4 ) )
|
||||
{
|
||||
if ( UTF8_2_LEAD(cp) )
|
||||
{
|
||||
@ -1337,7 +1283,12 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// [0x7F, 0xC2) & (0xF4, 0xFF]
|
||||
|
||||
if ( cp >= 0xA0 ) // [0xA0, 0xFF]
|
||||
goto x7ff;
|
||||
|
||||
doescape:
|
||||
// [0x00, 0x20) & (0x7E, 0xA0)
|
||||
if ( escape == kUTFEscapeQuoted )
|
||||
mbc[bytes++] = '\\';
|
||||
|
||||
@ -1364,6 +1315,7 @@ inline unsigned int SQUnicodeToUTF8( char *dst, unsigned int destSize, const SQC
|
||||
}
|
||||
else if ( cp <= 0x7FF )
|
||||
{
|
||||
x7ff:
|
||||
UTF8_2_FROM_UTF32( mbc, cp );
|
||||
bytes = 2;
|
||||
}
|
||||
@ -1478,4 +1430,33 @@ write:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SQUNICODE) && !defined(_WIN32)
|
||||
// Do case insensitive comparison for ASCII characters, ignore the rest
|
||||
inline int sqdbg_wcsicmp( const SQChar *s1, const SQChar *s2 )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
SQChar c1 = *s1++;
|
||||
SQChar c2 = *s2++;
|
||||
|
||||
if ( !c1 || !c2 )
|
||||
return c1 - c2;
|
||||
|
||||
if ( c1 == c2 )
|
||||
continue;
|
||||
|
||||
if ( c1 >= 'A' && c1 <= 'Z' )
|
||||
c1 |= 0x20;
|
||||
|
||||
if ( c2 >= 'A' && c2 <= 'Z' )
|
||||
c2 |= 0x20;
|
||||
|
||||
if ( c1 == c2 )
|
||||
continue;
|
||||
|
||||
return c1 - c2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SQDBG_STRING_H
|
||||
|
@ -111,7 +111,44 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template< int MEM_CACHE_CHUNKS_ALIGN = 2048 >
|
||||
// GCC requires this to be outside of the class
|
||||
template < bool S >
|
||||
struct _CScratch_members;
|
||||
|
||||
template <>
|
||||
struct _CScratch_members< true >
|
||||
{
|
||||
int m_LastFreeChunk;
|
||||
int m_LastFreeIndex;
|
||||
int m_PrevChunk;
|
||||
int m_PrevIndex;
|
||||
|
||||
int LastFreeChunk() { return m_LastFreeChunk; }
|
||||
int LastFreeIndex() { return m_LastFreeIndex; }
|
||||
int PrevChunk() { return m_PrevChunk; }
|
||||
int PrevIndex() { return m_PrevIndex; }
|
||||
|
||||
void SetLastFreeChunk( int i ) { m_LastFreeChunk = i; }
|
||||
void SetLastFreeIndex( int i ) { m_LastFreeIndex = i; }
|
||||
void SetPrevChunk( int i ) { m_PrevChunk = i; }
|
||||
void SetPrevIndex( int i ) { m_PrevIndex = i; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _CScratch_members< false >
|
||||
{
|
||||
int LastFreeChunk() { return 0; }
|
||||
int LastFreeIndex() { return 0; }
|
||||
int PrevChunk() { return 0; }
|
||||
int PrevIndex() { return 0; }
|
||||
|
||||
void SetLastFreeChunk( int ) {}
|
||||
void SetLastFreeIndex( int ) {}
|
||||
void SetPrevChunk( int ) {}
|
||||
void SetPrevIndex( int ) {}
|
||||
};
|
||||
|
||||
template< bool SEQUENTIAL, int MEM_CACHE_CHUNKS_ALIGN = 2048 >
|
||||
class CScratch
|
||||
{
|
||||
public:
|
||||
@ -126,8 +163,7 @@ public:
|
||||
|
||||
chunk_t *m_Memory;
|
||||
int m_MemChunkCount;
|
||||
int m_LastFreeChunk;
|
||||
int m_LastFreeIndex;
|
||||
_CScratch_members< SEQUENTIAL > m;
|
||||
|
||||
char *Get( int index )
|
||||
{
|
||||
@ -145,7 +181,7 @@ public:
|
||||
return &chunk->ptr[ msgIdx * MEM_CACHE_CHUNKSIZE ];
|
||||
}
|
||||
|
||||
char *Alloc( int size, int *index = NULL, bool sequential = true )
|
||||
char *Alloc( int size, int *index = NULL )
|
||||
{
|
||||
if ( !m_Memory )
|
||||
{
|
||||
@ -166,11 +202,11 @@ public:
|
||||
int chunkIdx;
|
||||
int matchedChunks = 0;
|
||||
|
||||
if ( sequential )
|
||||
if ( SEQUENTIAL )
|
||||
{
|
||||
requiredChunks = ( size - 1 ) / MEM_CACHE_CHUNKSIZE + 1;
|
||||
msgIdx = m_LastFreeIndex;
|
||||
chunkIdx = m_LastFreeChunk;
|
||||
msgIdx = m.LastFreeIndex();
|
||||
chunkIdx = m.LastFreeChunk();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,14 +220,17 @@ public:
|
||||
chunk_t *chunk = &m_Memory[ chunkIdx ];
|
||||
Assert( chunk->count && chunk->ptr );
|
||||
|
||||
if ( sequential )
|
||||
if ( SEQUENTIAL )
|
||||
{
|
||||
int remainingChunks = chunk->count - msgIdx;
|
||||
|
||||
if ( remainingChunks >= requiredChunks )
|
||||
{
|
||||
m_LastFreeIndex = msgIdx + requiredChunks;
|
||||
m_LastFreeChunk = chunkIdx;
|
||||
m.SetPrevChunk( m.LastFreeChunk() );
|
||||
m.SetPrevIndex( m.LastFreeIndex() );
|
||||
|
||||
m.SetLastFreeIndex( msgIdx + requiredChunks );
|
||||
m.SetLastFreeChunk( chunkIdx );
|
||||
|
||||
if ( index )
|
||||
{
|
||||
@ -267,6 +306,7 @@ public:
|
||||
|
||||
void Free( void *ptr )
|
||||
{
|
||||
Assert( !SEQUENTIAL );
|
||||
Assert( m_Memory );
|
||||
Assert( ptr );
|
||||
|
||||
@ -290,7 +330,8 @@ public:
|
||||
|
||||
Assert( found );
|
||||
|
||||
(*(unsigned char**)&ptr)[ *(int*)ptr + sizeof(int) - 1 ] = 0xdd;
|
||||
if ( *(int*)ptr )
|
||||
(*(unsigned char**)&ptr)[ *(int*)ptr + sizeof(int) - 1 ] = 0xdd;
|
||||
#endif
|
||||
|
||||
memset( (char*)ptr, 0, *(int*)ptr + sizeof(int) );
|
||||
@ -315,12 +356,16 @@ public:
|
||||
|
||||
m_Memory = NULL;
|
||||
m_MemChunkCount = 4;
|
||||
m_LastFreeChunk = 0;
|
||||
m_LastFreeIndex = 0;
|
||||
m.SetLastFreeChunk( 0 );
|
||||
m.SetLastFreeIndex( 0 );
|
||||
m.SetPrevChunk( 0 );
|
||||
m.SetPrevIndex( 0 );
|
||||
}
|
||||
|
||||
void ReleaseShrink()
|
||||
{
|
||||
Assert( SEQUENTIAL );
|
||||
|
||||
if ( !m_Memory )
|
||||
return;
|
||||
|
||||
@ -359,13 +404,17 @@ public:
|
||||
AssertOOM( m_Memory, m_MemChunkCount * sizeof(chunk_t) );
|
||||
}
|
||||
|
||||
m_LastFreeChunk = 0;
|
||||
m_LastFreeIndex = 0;
|
||||
m.SetLastFreeChunk( 0 );
|
||||
m.SetLastFreeIndex( 0 );
|
||||
m.SetPrevChunk( 0 );
|
||||
m.SetPrevIndex( 0 );
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if ( !m_Memory || ( !m_LastFreeChunk && !m_LastFreeIndex ) )
|
||||
Assert( SEQUENTIAL );
|
||||
|
||||
if ( !m_Memory || ( !m.LastFreeChunk() && !m.LastFreeIndex() ) )
|
||||
return;
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -380,8 +429,18 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
m_LastFreeChunk = 0;
|
||||
m_LastFreeIndex = 0;
|
||||
m.SetLastFreeChunk( 0 );
|
||||
m.SetLastFreeIndex( 0 );
|
||||
m.SetPrevChunk( 0 );
|
||||
m.SetPrevIndex( 0 );
|
||||
}
|
||||
|
||||
void ReleaseTop()
|
||||
{
|
||||
Assert( SEQUENTIAL );
|
||||
|
||||
m.SetLastFreeChunk( m.PrevChunk() );
|
||||
m.SetLastFreeIndex( m.PrevIndex() );
|
||||
}
|
||||
};
|
||||
|
||||
@ -391,212 +450,212 @@ class vector
|
||||
public:
|
||||
typedef unsigned int I;
|
||||
|
||||
CAllocator _base;
|
||||
I _size;
|
||||
CAllocator base;
|
||||
I size;
|
||||
|
||||
vector() : _base(), _size(0)
|
||||
vector() : base(), size(0)
|
||||
{
|
||||
Assert( !bExternalMem );
|
||||
}
|
||||
|
||||
vector( CAllocator &a ) : _base(a), _size(0)
|
||||
vector( CAllocator &a ) : base(a), size(0)
|
||||
{
|
||||
Assert( bExternalMem );
|
||||
}
|
||||
|
||||
vector( I count ) : _base(), _size(0)
|
||||
vector( I count ) : base(), size(0)
|
||||
{
|
||||
Assert( !bExternalMem );
|
||||
_base.Alloc( count * sizeof(T) );
|
||||
base.Alloc( count * sizeof(T) );
|
||||
}
|
||||
|
||||
vector( const vector< T > &src ) : _base()
|
||||
vector( const vector< T > &src ) : base()
|
||||
{
|
||||
Assert( !bExternalMem );
|
||||
_base.Alloc( src._base.Size() );
|
||||
_size = src._size;
|
||||
base.Alloc( src.base.Size() );
|
||||
size = src.size;
|
||||
|
||||
for ( I i = 0; i < _size; i++ )
|
||||
new( &_base[ i * sizeof(T) ] ) T( (T&)src._base[ i * sizeof(T) ] );
|
||||
for ( I i = 0; i < size; i++ )
|
||||
new( &base[ i * sizeof(T) ] ) T( (T&)src.base[ i * sizeof(T) ] );
|
||||
}
|
||||
|
||||
~vector()
|
||||
{
|
||||
Assert( (unsigned int)_size <= _base.Size() );
|
||||
Assert( (unsigned int)size <= base.Size() );
|
||||
|
||||
for ( I i = 0; i < _size; i++ )
|
||||
((T&)(_base[ i * sizeof(T) ])).~T();
|
||||
for ( I i = 0; i < size; i++ )
|
||||
((T&)(base[ i * sizeof(T) ])).~T();
|
||||
|
||||
if ( !bExternalMem )
|
||||
_base.Free();
|
||||
base.Free();
|
||||
}
|
||||
|
||||
T &operator[]( I i ) const
|
||||
{
|
||||
Assert( _size > 0 );
|
||||
Assert( i >= 0 && i < _size );
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
return (T&)_base[ i * sizeof(T) ];
|
||||
Assert( size > 0 );
|
||||
Assert( i >= 0 && i < size );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
return (T&)base[ i * sizeof(T) ];
|
||||
}
|
||||
|
||||
T *base()
|
||||
T *Base()
|
||||
{
|
||||
return _base.Base();
|
||||
return base.Base();
|
||||
}
|
||||
|
||||
I size() const
|
||||
I Size() const
|
||||
{
|
||||
return _size;
|
||||
return size;
|
||||
}
|
||||
|
||||
I capacity() const
|
||||
I Capacity() const
|
||||
{
|
||||
return _base.Size() / sizeof(T);
|
||||
return base.Size() / sizeof(T);
|
||||
}
|
||||
|
||||
T &top() const
|
||||
T &Top() const
|
||||
{
|
||||
Assert( _size > 0 );
|
||||
return (T&)_base[ ( _size - 1 ) * sizeof(T) ];
|
||||
Assert( size > 0 );
|
||||
return (T&)base[ ( size - 1 ) * sizeof(T) ];
|
||||
}
|
||||
|
||||
void pop()
|
||||
void Pop()
|
||||
{
|
||||
Assert( _size > 0 );
|
||||
((T&)_base[ --_size * sizeof(T) ]).~T();
|
||||
Assert( size > 0 );
|
||||
((T&)base[ --size * sizeof(T) ]).~T();
|
||||
}
|
||||
|
||||
T &append()
|
||||
T &Append()
|
||||
{
|
||||
_base.Ensure( ++_size * sizeof(T) );
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
return *( new( &_base[ ( _size - 1 ) * sizeof(T) ] ) T() );
|
||||
base.Ensure( ++size * sizeof(T) );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
return *( new( &base[ ( size - 1 ) * sizeof(T) ] ) T() );
|
||||
}
|
||||
|
||||
void append( const T &src )
|
||||
void Append( const T &src )
|
||||
{
|
||||
_base.Ensure( ++_size * sizeof(T) );
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
new( &_base[ ( _size - 1 ) * sizeof(T) ] ) T( src );
|
||||
base.Ensure( ++size * sizeof(T) );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
new( &base[ ( size - 1 ) * sizeof(T) ] ) T( src );
|
||||
}
|
||||
|
||||
T &insert( I i )
|
||||
T &Insert( I i )
|
||||
{
|
||||
Assert( i >= 0 && i <= _size );
|
||||
Assert( i >= 0 && i <= size );
|
||||
|
||||
_base.Ensure( ++_size * sizeof(T) );
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
base.Ensure( ++size * sizeof(T) );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
|
||||
if ( i != _size - 1 )
|
||||
if ( i != size - 1 )
|
||||
{
|
||||
memmove( &_base[ ( i + 1 ) * sizeof(T) ],
|
||||
&_base[ i * sizeof(T) ],
|
||||
( _size - ( i + 1 ) ) * sizeof(T) );
|
||||
memmove( &base[ ( i + 1 ) * sizeof(T) ],
|
||||
&base[ i * sizeof(T) ],
|
||||
( size - ( i + 1 ) ) * sizeof(T) );
|
||||
}
|
||||
|
||||
return *( new( &_base[ i * sizeof(T) ] ) T() );
|
||||
return *( new( &base[ i * sizeof(T) ] ) T() );
|
||||
}
|
||||
|
||||
void remove( I i )
|
||||
void Remove( I i )
|
||||
{
|
||||
Assert( _size > 0 );
|
||||
Assert( i >= 0 && i < _size );
|
||||
Assert( size > 0 );
|
||||
Assert( i >= 0 && i < size );
|
||||
|
||||
((T&)_base[ i * sizeof(T) ]).~T();
|
||||
((T&)base[ i * sizeof(T) ]).~T();
|
||||
|
||||
if ( i != _size - 1 )
|
||||
if ( i != size - 1 )
|
||||
{
|
||||
memmove( &_base[ i * sizeof(T) ],
|
||||
&_base[ ( i + 1 ) * sizeof(T) ],
|
||||
( _size - ( i + 1 ) ) * sizeof(T) );
|
||||
memmove( &base[ i * sizeof(T) ],
|
||||
&base[ ( i + 1 ) * sizeof(T) ],
|
||||
( size - ( i + 1 ) ) * sizeof(T) );
|
||||
}
|
||||
|
||||
_size--;
|
||||
size--;
|
||||
}
|
||||
|
||||
void clear()
|
||||
void Clear()
|
||||
{
|
||||
for ( I i = 0; i < _size; i++ )
|
||||
((T&)_base[ i * sizeof(T) ]).~T();
|
||||
for ( I i = 0; i < size; i++ )
|
||||
((T&)base[ i * sizeof(T) ]).~T();
|
||||
|
||||
_size = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
void sort( int (*fn)(const T *, const T *) )
|
||||
void Sort( int (*fn)(const T *, const T *) )
|
||||
{
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
|
||||
if ( _size > 1 )
|
||||
if ( size > 1 )
|
||||
{
|
||||
qsort( _base.Base(), _size, sizeof(T), (int (*)(const void *, const void *))fn );
|
||||
qsort( base.Base(), size, sizeof(T), (int (*)(const void *, const void *))fn );
|
||||
}
|
||||
}
|
||||
|
||||
void reserve( I count )
|
||||
void Reserve( I count )
|
||||
{
|
||||
Assert( (unsigned int)_size <= _base.Size() );
|
||||
Assert( (unsigned int)size <= base.Size() );
|
||||
|
||||
if ( count == 0 )
|
||||
count = 4;
|
||||
|
||||
if ( (unsigned int)count == _base.Size() )
|
||||
if ( (unsigned int)count == base.Size() )
|
||||
return;
|
||||
|
||||
for ( I i = count; i < _size; i++ )
|
||||
((T&)_base[ i * sizeof(T) ]).~T();
|
||||
for ( I i = count; i < size; i++ )
|
||||
((T&)base[ i * sizeof(T) ]).~T();
|
||||
|
||||
_base.Alloc( count * sizeof(T) );
|
||||
base.Alloc( count * sizeof(T) );
|
||||
}
|
||||
|
||||
void purge()
|
||||
void Purge()
|
||||
{
|
||||
Assert( _size * sizeof(T) <= _base.Size() );
|
||||
Assert( size * sizeof(T) <= base.Size() );
|
||||
|
||||
for ( I i = 0; i < _size; i++ )
|
||||
((T&)_base[ i * sizeof(T) ]).~T();
|
||||
for ( I i = 0; i < size; i++ )
|
||||
((T&)base[ i * sizeof(T) ]).~T();
|
||||
|
||||
_base.Free();
|
||||
_size = 0;
|
||||
base.Free();
|
||||
size = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CBuffer
|
||||
{
|
||||
public:
|
||||
CMemory _base;
|
||||
int _size;
|
||||
int _offset;
|
||||
CMemory base;
|
||||
int size;
|
||||
int offset;
|
||||
|
||||
char *base()
|
||||
char *Base()
|
||||
{
|
||||
return _base.Base() + _offset;
|
||||
return base.Base() + offset;
|
||||
}
|
||||
|
||||
int size() const
|
||||
int Size() const
|
||||
{
|
||||
return _size;
|
||||
return size;
|
||||
}
|
||||
|
||||
int capacity() const
|
||||
int Capacity() const
|
||||
{
|
||||
return _base.Size();
|
||||
return base.Size();
|
||||
}
|
||||
|
||||
void reserve( int count )
|
||||
void Reserve( int count )
|
||||
{
|
||||
Assert( (unsigned int)_size <= _base.Size() );
|
||||
Assert( (unsigned int)size <= base.Size() );
|
||||
|
||||
if ( (unsigned int)count == _base.Size() )
|
||||
if ( (unsigned int)count == base.Size() )
|
||||
return;
|
||||
|
||||
_base.Alloc( count );
|
||||
base.Alloc( count );
|
||||
}
|
||||
|
||||
void purge()
|
||||
void Purge()
|
||||
{
|
||||
_base.Free();
|
||||
_size = 0;
|
||||
_offset = 0;
|
||||
base.Free();
|
||||
size = 0;
|
||||
offset = 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -608,16 +667,16 @@ public:
|
||||
|
||||
CBufTmpCache( CBuffer *b ) :
|
||||
buffer(b),
|
||||
size(buffer->_size)
|
||||
size(buffer->size)
|
||||
{
|
||||
buffer->_offset += buffer->_size;
|
||||
buffer->_size = 0;
|
||||
buffer->offset += buffer->size;
|
||||
buffer->size = 0;
|
||||
}
|
||||
|
||||
~CBufTmpCache()
|
||||
{
|
||||
buffer->_offset -= size;
|
||||
buffer->_size = size;
|
||||
buffer->offset -= size;
|
||||
buffer->size = size;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
IScriptVM* makeSquirrelVM();
|
||||
|
||||
int vscript_token = 0;
|
||||
int vscript_debugger_port = 0;
|
||||
|
||||
class CScriptManager : public CTier1AppSystem<IScriptManager>
|
||||
{
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
virtual bool Init() override;
|
||||
virtual void Shutdown() override;
|
||||
|
||||
virtual bool ConnectDebugger( int port = 0 ) override;
|
||||
virtual bool ConnectDebugger( int port = 0, float timeout = 0.0f ) override;
|
||||
virtual void DisconnectDebugger() override;
|
||||
|
||||
virtual ScriptLanguage_t GetLanguage() override;
|
||||
@ -2050,17 +2050,26 @@ void SquirrelVM::Shutdown()
|
||||
|
||||
bool VScriptRunScript( const char *pszScriptName, HSCRIPT hScope, bool bWarnMissing );
|
||||
|
||||
bool SquirrelVM::ConnectDebugger( int port )
|
||||
bool SquirrelVM::ConnectDebugger( int port, float timeout )
|
||||
{
|
||||
if ( !debugger_ )
|
||||
{
|
||||
debugger_ = sqdbg_attach_debugger( vm_ );
|
||||
|
||||
if ( sqdbg_listen_socket( debugger_, port ) != 0 )
|
||||
if ( sqdbg_listen_socket( debugger_, port ) == 0 && timeout )
|
||||
{
|
||||
sqdbg_destroy_debugger( vm_ );
|
||||
debugger_ = nullptr;
|
||||
return false;
|
||||
float startTime = Plat_FloatTime();
|
||||
|
||||
while ( !sqdbg_is_client_connected( debugger_ ) )
|
||||
{
|
||||
float time = Plat_FloatTime();
|
||||
if ( time - startTime > timeout )
|
||||
break;
|
||||
|
||||
ThreadSleep( 50 );
|
||||
|
||||
sqdbg_frame( debugger_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user