dbgptree.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 644 行 · 第 1/2 页
C
644 行
char *text; // - text pointer (returned)
static char buffer[256]; // - buffer (valid until next call)
boolean type_add; // - TRUE ==> add type
PTREE pnode; // - parse-tree node
pnode = node->pnode;
switch( pnode->op ) {
case PT_ERROR :
text = PTREE_ERROR_NODE;
type_add = FALSE;
break;
case PT_UNARY :
case PT_BINARY :
stpcpy( buffer, DbgOperator( pnode->cgop ) );
text = buffer;
type_add = printTypes;
break;
case PT_INT_CONSTANT :
switch( TypedefModifierRemoveOnly( pnode->type )->id ) {
case TYP_SCHAR :
case TYP_SSHORT :
case TYP_SINT :
case TYP_SLONG :
sticpy( buffer, pnode->u.int_constant );
break;
case TYP_SLONG64 :
case TYP_ULONG64 :
{ char *buf;
buffer[0] = '<';
buf = stxcpy( &buffer[1], pnode->u.int64_constant.u._32[0] );
*buf='~';
buf = stxcpy( buf+1, pnode->u.int64_constant.u._32[1] );
buf[0] = '>';
buf[1] = '\0';
} break;
default :
stdcpy( buffer, pnode->u.uint_constant );
break;
}
text = buffer;
type_add = printTypes;
break;
case PT_FLOATING_CONSTANT :
BFCnvFS( pnode->u.floating_constant, buffer, 256 );
text = buffer;
type_add = printTypes;
break;
case PT_STRING_CONSTANT :
stvcpy( buffer, pnode->u.string->string, pnode->u.string->len );
text = buffer;
type_add = printTypes;
break;
case PT_TYPE :
textType( buffer, pnode->type, "<> " );
text = buffer;
type_add = FALSE;
break;
case PT_ID :
text = pnode->u.id.name;
type_add = FALSE;
break;
case PT_SYMBOL :
if( pnode->cgop == CO_NAME_THIS ) {
stpcpy( buffer, "this" );
text = buffer;
} else if( pnode->cgop == CO_NAME_CDTOR_EXTRA ) {
stpcpy( buffer, "cdtor_extra" );
text = buffer;
} else {
SYMBOL sym;
if( pnode->cgop == CO_NAME_PARM_REF ) {
text = stpcpy( buffer, "parm-ref:" );
} else {
text = buffer;
}
sym = pnode->u.symcg.symbol;
if( sym == NULL ) {
stpcpy( text, "this" );
} else if( sym->name == NULL ) {
stpcpy( text, "**NULL**" );
} else if( sym->name->name == NULL ) {
stpcpy( text, "**NULL**" );
} else {
stpcpy( text, sym->name->name );
}
text = buffer;
}
type_add = printTypes;
break;
case PT_DUP_EXPR :
text = stpcpy( buffer, "dup[" );
text = stxcpy( text, (unsigned)pnode->u.subtree[0] );
stpcpy( text, "]" );
text = buffer;
type_add = printTypes;
break;
case PT_IC :
text = stpcpy( buffer, DbgIcOpcode( pnode->u.ic.opcode ) );
text = stpcpy( text, " " );
text = stxcpy( text, pnode->u.ic.value.uvalue );
text = buffer;
type_add = printTypes;
break;
}
if( type_add && ( pnode->type != NULL ) ) {
textType( strend( text )
, pnode->type
, (pnode->flags & PTF_LVALUE ) ? "<LV> " : "<RV> " );
}
if( 0 != node->numb ) {
char* p;
p = stpcpy( strend( text ), " {" );
p = stdcpy( p, node->numb );
p = stpcpy( p, "}" );
}
return text;
}
static void buildSubtree( // BUILD A SUBTREE
PTREE root ) // - root of subtree
{
SUBTREE *subtree; // - info for subtree
RingIterBeg( subtrees, subtree ) {
if( subtree->root == root ) return;
} RingIterEnd( subtree )
subtree = RingCarveAlloc( carveSubtree, &subtrees );
subtree->lines = NULL;
subtree->root = root;
subtree->centre = buildNode( root, subtree, NULL );
}
static COL buildNode( // BUILD A NODE
PTREE expr, // - parse-tree expression
SUBTREE *subtree, // - subtree under construction
LINE *pred ) // - preceding line (or NULL)
{
NODE *node; // - node for expression
LINE *line; // - line entry for node
COL width; // - node width
COL centre; // - trial centre
COL offset; // - centre between operands
COL bound; // - bound for next centre on next line
if( expr == NULL ) return 0;
node = CarveAlloc( carveNode );
node->pnode = expr;
node->centre = 0;
node->left = 0;
node->right = 0;
if( NULL == expr->decor ) {
node->numb = 0;
} else {
node->numb = addDecorated( node );
}
if( ( pred == NULL ) || ( pred == subtree->lines ) ) {
line = addLine( subtree );
} else {
line = pred->next;
}
RingAppend( &line->nodes, node );
width = strlen( textPTREE( node ) );
switch( expr->op ) {
case PT_UNARY :
node->left = buildNode( expr->u.subtree[0], subtree, line );
break;
case PT_BINARY :
node->left = buildNode( expr->u.subtree[0], subtree, line );
node->right = buildNode( expr->u.subtree[1], subtree, line );
break;
case PT_DUP_EXPR :
buildSubtree( expr->u.subtree[0] );
break;
}
if( node->left == 0 ) {
centre = node->right;
bound = centre;
} else if( node->right == 0 ) {
centre = node->left;
bound = centre;
} else {
centre = ( node->left + node->right ) / 2;
bound = node->right;
}
offset = line->width + width / 2 + 1;
if( centre < offset ) {
centre = offset;
}
if( centre < line->bound ) {
centre = line->bound;
}
node->centre = centre;
line->width = centre - ( width / 2 ) + width;
line->bound = line->width;
if( bound != 0 ) {
if( bound < centre ) {
bound = centre;
}
++ bound;
line = line->next;
if( line->bound < bound ) {
line->bound = bound;
}
}
return centre;
}
static void printNode( // PRINT A NODE
NODE *node ) // - node to be printed
{
char *text; // - text to be printed
text = textPTREE( node );
centreText( text, node->centre );
if( node->left != 0 ) {
connectLeft( node->centre, node->left );
}
if( node->right != 0 ) {
connectRight( node->centre, node->right );
if( node->left != 0 ) {
connectBoth( node->centre, node->left, node->right );
}
}
}
static void printSubtree( // PRINT A SUBTREE
void *_subtree ) // - subtree to be printed
{
char buffer[ 256 ]; // - buffer
char *bptr; // - buffer ptr
LINE *line; // - current line
NODE *node; // - current node
TOKEN_LOCN locn; // - subtree location
boolean print_locn; // - TRUE ==> print location
SUBTREE *subtree = _subtree;
begLine();
if( subtree->next == subtrees ) {
print_locn = TRUE;
bptr = stpcpy( buffer, "tree[" );
} else {
endLine();
begLine();
print_locn = FALSE;
bptr = stpcpy( buffer, "dup[" );
}
bptr = stxcpy( bptr, (unsigned)subtree->root );
if( print_locn ) {
PTreeExtractLocn( subtree->root, &locn );
if( NULL != locn.src_file ) {
bptr = stpcpy( bptr, " " );
bptr = stpcpy( bptr, SrcFileName( locn.src_file ) );
bptr = stpcpy( bptr, " line[" );
bptr = stdcpy( bptr, locn.line );
bptr = stpcpy( bptr, "] column[" );
bptr = stdcpy( bptr, locn.column );
bptr = stpcpy( bptr, "]" );
}
}
centreText( buffer, subtree->centre );
connectLeft( subtree->centre, subtree->centre );
endLine();
RingIterBeg( subtree->lines, line ) {
begLine();
RingIterBeg( line->nodes, node ) {
printNode( node );
} RingIterEnd( node );
endLine();
} RingIterEnd( line )
}
static void printDecoration( // PRINT DECORATION FOR A NODE
void )
{
DECORATED* dec; // - decoration entry
if( NULL != decoration ) {
printf( "\n Decorated Nodes:\n\n" );
RingIterBeg( decoration, dec ) {
PtdPrint( dec->node->numb, dec->node->pnode );
} RingIterEnd( dec );
}
}
void DbgPrintPTREE( // PRINT A PARSE-TREE BEAUTIFULLY
PTREE root ) // - root of tree to be printed
{
decor_numb = 0;
carveNode = CarveCreate( sizeof( NODE ), 16 );
carveLine = CarveCreate( sizeof( LINE ), 16 );
carveSubtree = CarveCreate( sizeof( SUBTREE ), 16 );
carveDecoration = CarveCreate( sizeof( DECORATED ), 16 );
subtrees = NULL;
decoration = NULL;
buildSubtree( root );
RingWalk( subtrees, &printSubtree );
printDecoration();
CarveDestroy( carveNode );
CarveDestroy( carveLine );
CarveDestroy( carveSubtree );
CarveDestroy( carveDecoration );
prlineFree( &node_line );
prlineFree( &conn_line );
}
void DbgPrintPTREEtyped( // PRINT BEAUTIFUL PTREE, WITH TYPES
PTREE root ) // - root of tree
{
printTypes = TRUE;
DbgPrintPTREE( root );
printTypes = FALSE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?