demangle.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,208 行 · 第 1/5 页
C
2,208 行
return( assignment_function( data, state ) );
break;
case REL_FUN_PREFIX:
advanceChar( data );
return( relational_function( data, state ) );
break;
case OP_FUN_PREFIX:
advanceChar( data );
return( operator_function( data, state ) );
break;
case SPEC_TYPE_PREFIX:
advanceChar( data );
return( special_type_names( data, state ) );
break;
case WAT_FUN_PREFIX:
advanceChar( data );
return( watcom_object( data, state ) );
break;
}
return( FALSE );
}
static int name( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data );
if( isdigit( c ) ) {
size_t len;
char const *id;
c = c - '0';
// in case C++ compiler and demangler don't match; don't crash
if( c >= next_replicate ) {
id = "@";
len = 1;
} else {
id = replicate[c].ptr;
len = replicate[c].len;
}
if( data->ctdt_pending ) {
_output2( DM_RESET_INDEX, data->pending_loc );
_output1( DM_CTOR_DTOR_NAME );
_output3( DM_IDENTIFIER, len, id );
data->ctdt_pending = FALSE;
}
if( data->scope_name && data->scope_index == 0 ) {
data->scope_name = FALSE;
data->scope_ptr = id;
data->scope_len = len;
}
_output2( DM_SET_INDEX, state->prefix );
_output3( DM_IDENTIFIER, len, id );
_output1( DM_EMIT_SPACE );
advanceChar( data );
return( TRUE );
} else {
char const *ptr = data->input;
size_t len = 0;
while( is_identifier( c ) ) {
len++;
advanceChar( data );
c = nextChar( data );
}
if( data->scope_name && data->scope_index == 0 ) {
data->scope_name = FALSE;
data->scope_ptr = ptr;
data->scope_len = len;
}
if( c == SYMBOL_SUFFIX ) {
advanceChar( data );
if( data->ctdt_pending ) {
_output2( DM_RESET_INDEX, data->pending_loc );
_output1( DM_CTOR_DTOR_NAME );
_output3( DM_IDENTIFIER, len, ptr );
data->ctdt_pending = FALSE;
}
_output2( DM_SET_INDEX, state->prefix );
_output3( DM_IDENTIFIER, len, ptr );
_output1( DM_EMIT_SPACE );
if( next_replicate < MAX_REPLICATE ) {
replicate[next_replicate].ptr = ptr;
replicate[next_replicate].len = len;
next_replicate++;
}
return( TRUE );
}
}
return( FALSE );
}
static int sym_name( output_desc *data, state_desc *state )
{
_output1( DM_NAME );
if( nextChar( data ) == OPNAME_PREFIX ) {
advanceChar( data );
return( op_name( data, state ) );
} else {
return( name( data, state ) ) ;
}
}
static int scope( output_desc *data, state_desc *state, size_t *symbol_length )
{
char c;
_output1( DM_SCOPE );
if( data->scope_name && data->scope_index > 0 ) {
data->scope_index--;
}
c = nextChar( data );
if( c == PREFIX_EMBEDDED ) {
advanceChar( data );
if( check_recurse() ) {
return( recursive_mangled_name( data, state ) );
}
} else if( c == TEMPLATE_PREFIX ) {
auto state_desc new_state;
advanceChar( data );
new_state = *state;
new_state.suffix = data->count - state->prefix - *symbol_length;
return( template_name( data, &new_state ) );
} else {
int rc = sym_name( data, state );
*symbol_length = data->index - state->prefix - 1;
return( rc );
}
return( FALSE );
}
static int scoped_name( output_desc *data, state_desc *state )
{
size_t symbol_length;
_output1( DM_SCOPED_NAME );
if( sym_name( data, state ) ) {
symbol_length = data->index - state->prefix - 1;
while( nextChar( data ) == SCOPE_PREFIX ) {
_output2( DM_SET_INDEX, state->prefix );
if( *(data->input + 1) != TEMPLATE_PREFIX ) {
_output1( DM_SCOPE_SEPARATOR );
}
advanceChar( data );
if( !scope( data, state, &symbol_length ) ) {
return( FALSE );
}
_output1( DM_ZAP_SPACE );
}
return( TRUE );
}
return( FALSE );
}
static int mangled_name( output_desc *data )
{
auto state_desc new_state;
_output1( DM_MANGLED_NAME );
new_state.prefix = 0;
new_state.suffix = 0;
new_state.right = FALSE;
if( scoped_name( data, &new_state ) ) {
_output2( DM_RESET_INDEX, 0 );
_output1( DM_ZAP_SPACE );
return( type_encoding( data, &new_state ) );
}
return( FALSE );
}
#ifndef __LIB__
static int full_mangled_name( output_desc *data )
{
unsigned advances;
advances = 1;
if( strRecog( data, IMPORT_PREFIX_STR, IMPORT_PREFIX_LEN ) ) {
data->dllimport = 1;
}
switch( nextChar( data ) ) {
case TRUNCATED_PREFIX1:
advances += TRUNCATED_HASH_LEN;
_output1( DM_TRUNCATED_NAME );
/* fall through */
case MANGLE_PREFIX1:
advanceChar( data );
if( nextChar( data ) == MANGLE_PREFIX2 ) {
for( ; advances != 0; --advances ) {
advanceChar( data );
if( nextChar( data ) == NULL_CHAR ) {
return( FALSE );
}
}
return( mangled_name( data ) );
}
break;
}
return( FALSE );
}
static void do_demangle( output_desc *data )
{
#if 0 || defined(TEST)
char const *input = data->input;
#endif
if( !full_mangled_name( data ) ) {
#if 0 || defined(TEST)
if( ! no_errors ) {
size_t terminateOutput( output_desc * );
++errors;
printf( "ERROR: full_mangled_name failed\n" );
printf( "in:-->%s<--\n", input );
printf( "remaining:-->%s<--\n", data->input );
terminateOutput( data );
printf( "output:-->%s<--\n", data->output );
}
#endif
} else {
#if 0 || defined(TEST)
if( nextChar( data ) != NULL_CHAR ) {
++errors;
printf( "ERROR: full_mangled_name failed to consume all\n" );
printf( "-->%s<--\n", input );
}
#endif
}
}
static void do_copy( output_desc *data )
{
char const *ptr;
int len;
char c;
ptr = data->input;
len = 0;
c = nextChar( data );
advanceChar( data );
while( c ) {
len++;
c = nextChar( data );
advanceChar( data );
}
_output3( DM_COPY_STRING, len, ptr );
}
#endif
static void init_globals( realloc_fn_t reallocator )
{
next_replicate = 0;
user_realloc = reallocator;
}
static void init_descriptor( output_desc *data,
outfunPtr ofn, void *cookie,
char const *input, size_t len,
char *output, size_t size )
{
data->outfun = ofn;
data->cookie = cookie;
data->end = NULL;
if( len != 0 ) {
/* length of mangled name is known */
data->end = input + len;
}
data->input = input;
data->output = output;
data->scope_ptr = NULL;
data->size = size;
data->count = 0;
data->index = 0;
data->pending_loc = 0;
data->scope_len = 0;
data->suppress_output = 1;
data->scope_index = 0;
data->ctdt_pending = 0;
data->cv_pending = 0;
data->scope_name = 0;
data->base_name = 0;
data->dllimport = 0;
}
static size_t terminateOutput( output_desc *data )
{
size_t outlen;
outlen = data->count;
if( data->output != NULL ) {
/* name may have been truncated */
if( outlen >= data->size ) {
outlen = data->size-1;
}
if( outlen > 0 ) {
if( data->output[outlen-1] == ' ' ) {
--outlen;
}
}
data->output[outlen] = '\0';
}
/* size does not include '\0' */
return( outlen );
}
static size_t demangle_recursive( char const *input, char *output, size_t size )
{
realloc_fn_t save_reallocator;
auto output_desc data;
save_reallocator = user_realloc;
user_realloc = NULL;
init_descriptor( &data, &demangleEmit, &data, input, 0, output, size );
if( !mangled_name( &data ) ) {
#if 0 || defined(TEST)
++errors;
printf( "ERROR: mangled_name failed\n" );
printf( "-->%s<--\n", input );
#endif
}
terminateOutput( &data );
user_realloc = save_reallocator;
return( data.input - input );
}
static int recursive_mangled_name( output_desc *data, state_desc *state )
{
auto char buff[AUTO_BUFFER_SIZE];
_output1( DM_RECURSE_BEGIN );
data->input += demangle_recursive( data->input, buff, sizeof( buff ) );
_output1( DM_RECURSE_END );
_output2( DM_SET_INDEX, state->prefix );
_output3( DM_COPY_STRING, 0, buff );
return( TRUE );
}
#ifdef __LIB__
_WCRTLINK
#endif
size_t __demangle_t( // DEMANGLE A C++ TYPE
char const *input, // - mangled C++ type
size_t len, // - length of mangled type
char *output, // - for demangled C++ type
size_t size ) // - size of output buffer
{
size_t outlen;
auto output_desc data;
auto state_desc new_state;
init_globals( NULL );
init_descriptor( &data, &demangleEmit, &data, input, len, output, size );
data.suppress_output = 0;
new_state.prefix = 0;
new_state.suffix = 0;
new_state.right = FALSE;
type_encoding( &data, &new_state );
outlen = terminateOutput( &data );
/* size does not include '\0' */
return( outlen );
}
#ifndef __LIB__
size_t __demangle_l( // DEMANGLE A C++ NAME
char const *input, // - mangled C++ name
size_t len, // - length of mangled name
char *output, // - for demangled C++ name
size_t size ) // - size of output buffer
{
int mangled;
size_t outlen;
auto output_desc data;
init_globals( NULL );
mangled = __is_mangled( input, len );
init_descriptor( &data, &demangleEmit, &data, input, len, output, size );
if( mangled ) {
do_demangle( &data );
} else {
do_copy( &data );
}
outlen = terminateOutput( &data );
/* size does not include '\0' */
return( outlen );
}
size_t __demangle_r( // DEMANGLE A C++ NAME
char const *input, // - mangled C++ name
size_t len, // - length of mangled name
char **output, // - for demangled C++ name
size_t size, // - size of output buffer
char * (*realloc)( char *, size_t ) ) // - size adjuster for output
{
char *output_buff;
int mangled;
size_t outlen;
auto output_desc data;
init_globals( realloc );
mangled = __is_mangled( input, len );
output_buff = NULL;
if( output != NULL ) {
output_buff = *output;
}
init_descriptor( &data, &demangleEmit, &data, input, len, output_buff, size );
data.suppress_output = 0;
if( mangled ) {
do_demangle( &data );
} else {
do_copy( &data );
}
outlen = terminateOutput( &data );
if( output != NULL ) {
*output = data.output;
}
/* size does not include '\0' */
return( outlen );
}
int __scope_name( // EXTRACT A C++ SCOPE
char const *input, // - mangled C++ name
size_t len, // - length of mangled name
unsigned index, // - scope wanted
char const **scope, // - location of name
size_t *size ) // - size of output buffer
{ // returns TRUE on success
int mangled;
auto output_desc data;
init_globals( NULL );
*scope = NULL;
*size = 0;
mangled = __is_mangled( input, len );
if( !mangled ) {
return( FALSE );
}
init_descriptor( &data, &demangleEmit, &data, input, len, NULL, 0 );
data.scope_name = TRUE;
data.scope_index = index;
do_demangle( &data );
if( data.scope_len != 0 ) {
*scope = data.scope_ptr;
*size = data.scope_len;
return( TRUE );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?