dbgptree.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 644 行 · 第 1/2 页
C
644 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include <stdio.h>
#include "memmgr.h"
#include "cgfront.h"
#include "carve.h"
#include "ring.h"
#include "dbg.h"
#include "vbuf.h"
#include "fmttype.h"
#include "codegen.h"
static carve_t carveNode; // memory: nodes
static carve_t carveLine; // memory: lines
static carve_t carveSubtree; // memory: subtrees
static carve_t carveDecoration; // memory: decoration
static boolean printTypes; // TRUE ==> print types with nodes
typedef struct node NODE;
typedef struct line LINE;
typedef struct subtree SUBTREE;
typedef struct prline PRLINE;
typedef uint_16 COL;
typedef uint_16 DECOR;
struct node // NODE TO BE PRINTED
{ NODE *next; // - next in ring
PTREE pnode; // - parse-tree node
DECOR numb; // - decoration #
COL centre; // - centre of node
COL left; // - left operand
COL right; // - right operand
};
struct line // LINE OF NODES TO BE PRINTED
{ LINE *next; // - next in ring
NODE *nodes; // - nodes on line
COL width; // - line width, so far
COL bound; // - bound for next centre
};
struct subtree // SUBTREE TO BE PRINTED
{ SUBTREE *next; // - next in ring
LINE *lines; // - lines to be printed
PTREE root; // - root of tree
COL centre; // - centre of node
};
struct prline // PRINT LINE BUFFERING
{ char *buffer; // - buffer
COL width; // - buffer size
};
typedef struct _decorated DECORATED;
typedef struct _decorated { // DECORATED NODES
DECORATED * next; // - next in ring
NODE* node; // - decorated node
};
#define PTREE_ERROR_NODE "**error**"
#define LEFT_FROM 217
#define LEFT_TO 218
#define RIGHT_FROM 192
#define RIGHT_TO 191
#define VERT_LINE 179
#define HORI_LINE 196
#define BOTH_LSR 193
#define BOTH_LB 180
#define BOTH_BR 195
#define BOTH_LRS 194
#define BOTH_SLR 194
static SUBTREE *subtrees; // subtrees to be printed
static PRLINE node_line; // buffering for node line
static PRLINE conn_line; // buffering for connectors line
static DECORATED* decoration; // decorated nodes
static DECOR decor_numb; // decoration counter
static COL buildNode( PTREE expr, SUBTREE *subtree, LINE *pred );
static char *stxcpy( // CONCATENATE HEXADECIMAL NUMBER
char *tgt, // - target location
unsigned value ) // - value to be concatenated
{
char buffer[16];
return stpcpy( tgt, utoa( value, buffer, 16 ) );
}
static DECOR addDecorated( // ADD A DECORATED NODE
NODE* node ) // - node
{
DECORATED* dec; // - decoration node (new or old for node)
dec = RingCarveAlloc( carveDecoration, &decoration );
dec->node = node;
return ++ decor_numb;
}
static void prlineFree( // FREE A PRINT LINE
PRLINE *prl ) // - line control
{
CMemFreePtr( &prl->buffer );
prl->width = 0;
}
static void prlineExtend( // EXTEND PRINT LINE IF REQD
PRLINE *prl, // - line control
COL width ) // - width to extend
{
char *old; // - old buffer
char *buf; // - new buffer
if( width > prl->width ) {
old = prl->buffer;
buf = CMemAlloc( width + 1 );
memcpy( buf, old, prl->width );
memset( buf + prl->width, ' ', width - prl->width );
prl->width = width;
prl->buffer = buf;
CMemFree( old );
}
}
static void prlineInit( // START BUFFERING ON A PRINT LINE
PRLINE *prl ) // - line control
{
memset( prl->buffer, ' ', prl->width );
}
static void prlineEmit( // EMIT A PRINT LINE
PRLINE *prl ) // - line control
{
char *p; // - used to scan
for( p = &prl->buffer[ prl->width ]; ; ) {
-- p;
if( p == prl->buffer ) break;
if( *p != ' ' ) break;
}
*(p+1) = '\0';
puts( prl->buffer );
}
static void begLine( // START PRINTING LINE OF NODES
void )
{
prlineExtend( &node_line, 32 );
prlineExtend( &conn_line, 32 );
prlineInit( &node_line );
prlineInit( &conn_line );
}
static void endLine( // COMPLETE PRINTING LINE OF NODES
void )
{
prlineEmit( &node_line );
prlineEmit( &conn_line );
}
static void centreText( // ADD CENTRED TEXT TO NODE LINE
char *text, // - text
COL posn ) // - centre position
{
COL size; // - text size
COL offset; // - offset back from centre
size = strlen( text );
offset = size / 2;
if( offset >= posn ) {
posn = 0;
} else {
posn -= offset + 1;
}
prlineExtend( &node_line, posn + size );
memcpy( &node_line.buffer[ posn ], text, size );
}
static void connect( // ADD A CONNECTION
COL beg, // - start of connection
COL end, // - end of connection
char beg_sym, // - symbol for start
char end_sym ) // - symbol for end
{
COL width; // - width of connector line
prlineExtend( &conn_line, end );
width = end - beg + 1;
if( width == 1 ) {
conn_line.buffer[ beg - 1 ] = VERT_LINE;
} else {
conn_line.buffer[ beg - 1 ] = beg_sym;
conn_line.buffer[ end - 1 ] = end_sym;
if( width > 2 ) {
memset( &conn_line.buffer[ beg - 1 + 1 ], HORI_LINE, width - 2 );
}
}
}
static void connectLeft( // ADD A LEFT CONNECTION
COL src, // - start of connection
COL tgt ) // - end of connection
{
if( tgt <= src ) {
connect( tgt, src, LEFT_TO, LEFT_FROM );
} else {
connect( src, tgt, RIGHT_FROM, RIGHT_TO );
}
}
static void connectRight( // ADD A RIGHT CONNECTION
COL src, // - start of connection
COL tgt ) // - end of connection
{
if( src <= tgt ) {
connect( src, tgt, RIGHT_FROM, RIGHT_TO );
} else {
connect( tgt, src, LEFT_TO, LEFT_FROM );
}
}
static void connectBoth( // ADD A TEE CONNECTOR(S)
COL src, // - position of tee
COL left, // - position of left
COL right ) // - position of right
{
if( src == left ) {
conn_line.buffer[ src - 1 ] = BOTH_BR; // L=S,R
} else if( src == right ) {
conn_line.buffer[ src - 1 ] = BOTH_LB; // L,S=R
} else if( left < src ) {
if( src < right ) {
conn_line.buffer[ src - 1 ] = BOTH_LSR; // L,S,R
} else {
conn_line.buffer[ right - 1 ] = BOTH_LRS; // L,R,S
}
} else {
conn_line.buffer[ left - 1 ] = BOTH_SLR; // S,L,R
}
}
static LINE *addLine( // ADD A LINE ENTRY TO SUBTREE
SUBTREE *subtree ) // - subtree
{
LINE *line; // - new line
line = RingCarveAlloc( carveLine, &subtree->lines );
line->nodes = NULL;
line->width = 0;
line->bound = 0;
return line;
}
static void textType( // GET TEXT FOR A TYPE
char *text, // - text location
TYPE type, // - the type
const char *id ) // - expression for id
{
VBUF prefix, suffix; // - used to print types
FormatType( type, &prefix, &suffix );
*text++ = ' ';
text = stpcpy( text, prefix.buf );
text = stpcpy( text, id );
text = stpcpy( text, suffix.buf );
VbufFree( &prefix );
VbufFree( &suffix );
}
static char *textPTREE( // GET TEXT FOR A PARSE-TREE NODE
NODE* node ) // - print node
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?