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 + -
显示快捷键?