dbgprint.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,008 行 · 第 1/2 页

C
1,008
字号
    }
    if( count < 0 ) {
        PrtStr( " ...", 4 );
    }
}


void PrintString( void )
{
    DoPrintString( FALSE );
}


void ForcePrintString( void )
{
    DoPrintString( TRUE );
}


static void PrintCharBlock( void )
{
    char        *ascii_start;
    unsigned_16 *unicode_start;
    unsigned    len;

    PrtChar( '\'' );
    ascii_start = ExprSP->v.string.loc.e[0].u.p;
    len = ExprSP->info.size;
    switch( ExprSP->info.modifier ) {
    case TM_NONE:
    case TM_ASCII:
        PrtNeed( len );
        for( ;; ) {
            if( len == 0 ) break;
            if( *ascii_start == NULLCHAR ) break;
            PrtChar( *ascii_start++ );
            --len;
        }
        break;
    case TM_EBCIDIC:
        //NYI:
        break;
    case TM_UNICODE:
        unicode_start = (unsigned_16 *)ascii_start;
        len /= 2;
        PrtNeed( len );
        for( ;; ) {
            if( len == 0 ) break;
            if( *unicode_start == NULLCHAR ) break;
            PrtChar( *unicode_start++ );
            --len;
        }
        break;
    }
    PrtChar( '\'' );
}

static void GetExpr( void )
{
    if( !First && CurrToken == T_COMMA ) Scan();
    NormalExpr();
    if( CurrToken != T_COMMA & CurrToken != T_LEFT_BRACE ) ReqEOC();
    First = FALSE;
}

/*
 * DoFormat -- process a format string
 */
static void DoFormat( char *fmt_ptr, char *fmt_end )
{
    char        buff[BUFLEN+1];
    char        *pref;
    unsigned    pref_len;
    char        z_format;

    StartPrintBuff( buff, BUFLEN );
    First = TRUE;
    while( fmt_ptr < fmt_end ) {
        if( (*fmt_ptr != '%') || (fmt_end - fmt_ptr == 1) ) {
            PrtChar( *fmt_ptr );
        } else {
            ++fmt_ptr;
            switch( *fmt_ptr ) {
            case 'z':
            case 'Z':
                if( fmt_end - fmt_ptr == 1 ) {
                    z_format = 'G';
                } else {
                    ++fmt_ptr;
                    switch( *fmt_ptr ) {
                    case 'f':
                    case 'e':
                    case 'E':
                    case 'g':
                    case 'G':
                        z_format = *fmt_ptr;
                        break;
                    default:
                        --fmt_ptr;
                        z_format = 'G';
                        break;
                    }
                }
                GetExpr();
                PrintComplex( z_format );
                PopEntry();
                break;
            case 'd' :
            case 'i' :
                GetExpr();
                PrintRadix( 10, NULLCHAR, NUM_SIGNED, NULL, 0 );
                PopEntry();
                break;
            case 'u' :
                GetExpr();
                PrintRadix( 10, NULLCHAR, NUM_UNSIGNED, NULL, 0 );
                PopEntry();
                break;
            case 'o' :
                GetExpr();
                PrintRadix( 8, NULLCHAR, NUM_UNSIGNED, NULL, 0 );
                PopEntry();
                break;
            case 'x' :
                GetExpr();
                PrintRadix( 16, 'a', NUM_UNSIGNED, NULL, 0 );
                PopEntry();
                break;
            case 'X' :
                GetExpr();
                PrintRadix( 16, 'A', NUM_UNSIGNED, NULL, 0 );
                PopEntry();
                break;
            case 'p' :
                GetExpr();
                FindRadixSpec( 16, &pref, &pref_len );
                PrintRadix( 16, 'A', NUM_UNSIGNED, pref, pref_len );
                PopEntry();
                break;
            case 'c' :
                GetExpr();
                PrintChar();
                PopEntry();
                break;
            case 's' :
                GetExpr();
                PrintString();
                PopEntry();
                break;
            case 'f':
            case 'e':
            case 'E':
            case 'g':
            case 'G':
                GetExpr();
                PrintReal( *fmt_ptr );
                PopEntry();
                break;
            case 'r':
                GetExpr();
                PrintRadix( CurrRadix, 'A', NUM_CHECK, NULL, 0 );
                PopEntry();
                break;
            case 'a':
            case 'l':
                GetExpr();
                PrintAddress( *fmt_ptr );
                break;
            case '%':
                PrtChar( '%' );
                break;
            default :
                PrtChar( '%' );
                --fmt_ptr;
            }
        }
        ++fmt_ptr;
    }
    EndBuff();
}

typedef struct {
    bool        first_time;
} print_fld;


static walk_result PrintDlgField( sym_walk_info swi, sym_handle *member, void *_d )
{
    print_fld   *d = _d;
    char        *name;
    unsigned    len;

    if( swi == SWI_SYMBOL ) {
        if( !d->first_time ) {
            /* not the first time through */
            PrtChar( ',' );
            /* print a space if not at start of a line */
            if( OutPtr != OutBuff ) PrtChar( ' ' );
        }
        d->first_time = FALSE;
        DupStack();
        len = SymName( member, NULL, SN_SOURCE, NULL, 0 );
        _AllocA( name, len + 1 );
        len = SymName( member, NULL, SN_SOURCE, name, len + 1 );
        PrtStr( name, len );
        PrtChar( '=' );
        DoGivenField( member );
        ExprValue( ExprSP );
        PrintValue();
        PopEntry();
    }
    return( WR_CONTINUE );
}

static void PrintStruct( void )
{
    print_fld   d;

    d.first_time = TRUE;
    PrtChar( '{' );
    WalkSymList( SS_TYPE, ExprSP->th, PrintDlgField, &d );
    PrtChar( '}' );
}

static void PrintArray( void )
{
    array_info          ai;
    char                *ptr;
    unsigned            len;
    char                buff[TXT_LEN];
    bool                first_time;
    signed_64           tmp;

    first_time = TRUE;
    PrtChar( '{' );
    TypeArrayInfo( ExprSP->th, ExprSP->lc, &ai, NULL );
    while( ai.num_elts != 0 ) {
        ChkBreak();
        if( !first_time ) {
            /* not the first time through */
            PrtChar( ',' );
            /* print a space if not at start of a line */
            if( OutPtr != OutBuff ) PrtChar( ' ' );
        }
        DupStack();
        StartSubscript();
        PushNum( ai.low_bound );
        AddSubscript();
        EndSubscript();
        ExprValue( ExprSP );
        buff[0] = '[';
        I32ToI64( ai.low_bound, &tmp );
        ptr = FmtNum( tmp, CurrRadix, 'A', NUM_SIGNED, &buff[1], 1, NULL, 0 );
        *ptr++ = ']';
        *ptr++ = '=';
        len = ptr - buff;
        PrtStr( buff, len );
        PrintValue();
        PopEntry();
        ai.num_elts--;
        ai.low_bound++;
        first_time = FALSE;
    }
    PrtChar( '}' );
}

struct val2name {
    unsigned_64         value;
    unsigned_64         best_value;
    sym_handle          *sh;
    bool                found;
};

OVL_EXTERN walk_result ExactMatch( sym_walk_info swi, sym_handle *sh, void *d )
{
    struct val2name     *vd = d;
    unsigned_64         val;

    if( swi != SWI_SYMBOL ) return( WR_CONTINUE );
    U64Clear( val );
    if( SymValue( sh, ExprSP->lc, &val ) != DS_OK ) return( WR_STOP );
    if( U64Cmp( &val, &vd->value ) != 0 ) return( WR_CONTINUE );
    HDLAssign( sym, vd->sh, sh );
    vd->found = TRUE;
    return( WR_STOP );
}

OVL_EXTERN walk_result BestMatch( sym_walk_info swi, sym_handle *sh, void *d )
{
    struct val2name     *vd = d;
    unsigned_64         val;
    unsigned_64         tmp;

    if( swi != SWI_SYMBOL ) return( WR_CONTINUE );
    U64Clear( val );
    if( SymValue( sh, ExprSP->lc, &val ) != DS_OK ) return( WR_STOP );
    if( U64Test( &val ) == 0 ) return( WR_CONTINUE );
    U64And( &val, &vd->value, &tmp );
    if( U64Cmp( &tmp, &val ) == 0 ) {
        if( !vd->found || U64Cmp( &val, &vd->best_value ) > 0 ) {
            HDLAssign( sym, vd->sh, sh );
            vd->best_value = val;
            vd->found = TRUE;
        }
    }
    return( WR_CONTINUE );
}


static unsigned ValueToName( char *buff, unsigned len )
{
    char                *p;
    unsigned            name_len;
    struct val2name     d;
    DIPHDL( sym, sh );

    d.sh = sh;
    d.found = FALSE;
    d.value = ExprSP->v.uint;
    WalkSymList( SS_TYPE, ExprSP->th, ExactMatch, &d );
    if( d.found ) {
        return( SymName( sh, NULL, SN_SOURCE, buff, len ) );
    }
    p = buff;
    while( U64Test( &d.value ) != 0 ) {
        d.found = FALSE;
        WalkSymList( SS_TYPE, ExprSP->th, BestMatch, &d );
        if( !d.found ) return( 0 );
        U64Not( &d.best_value, &d.best_value );
        U64And( &d.value, &d.best_value, &d.value );
        if( p != buff ) {
            if( len == 0 ) return( 0 );
            *p++ = '+';
            --len;
        }
        name_len = SymName( sh, NULL, SN_SOURCE, p, len );
        if( name_len > len ) return( 0 );
        p += name_len;
        len -= name_len;
    }
    return( p - buff );
}

void PrintValue( void )
{
    char                *pref;
    unsigned            pref_len;
    char                buff[TXT_LEN];
    char                *p;
    char                *tstr;
    unsigned            tlen;

    switch( ExprSP->info.kind ) {
    case TK_VOID:
        break;
    case TK_ENUM:
        tlen = ValueToName( buff, TXT_LEN );
        if( tlen != 0 ) {
            /* we have a symbolic name for the value, print that out */
            PrtStr( buff, tlen );
            break; /* from switch */
        }
        PrintRadix( CurrRadix, 'A', NUM_CHECK, NULL, 0 );
        break;
    case TK_CHAR:
    case TK_BOOL:
    case TK_INTEGER:
        PrintRadix( CurrRadix, 'A', NUM_CHECK, NULL, 0 );
        break;
    case TK_ADDRESS:
        if( !IS_NIL_ADDR( ExprSP->v.addr ) ) {
            p = StrAddr( &ExprSP->v.addr, buff, sizeof( buff ) );
            PrtStr( buff, p - buff );
            break;
        }
        /* fall through */
    case TK_POINTER:
        if( IS_NIL_ADDR(ExprSP->v.addr) && ExprSP->v.addr.mach.offset == 0 ) {
            SetTokens( TRUE );
            if( !TokenName( TSTR_NULL, &tstr, &tlen ) ) {
                tlen = 0;
            }
            SetTokens( FALSE );
            if( tlen != 0 ) {
                PrtStr( tstr+1, tlen-1 );
            } else {
                FindRadixSpec( 16, &pref, &pref_len );
                PrintRadix( 16, 'A', NUM_UNSIGNED, pref, pref_len );
            }
        } else {
            FindRadixSpec( 16, &pref, &pref_len );
            PrintRadix( 16, 'A', NUM_UNSIGNED, pref, pref_len );
        }
        break;
    case TK_ARRAY:
        PrintArray();
        break;
    case TK_STRUCT:
        PrintStruct();
        break;
    case TK_REAL:
        PrintReal( 'G' );
        break;
    case TK_COMPLEX:
        PrintComplex( 'G' );
        break;
    case TK_STRING:
        PrintCharBlock();
        break;
    default:
        Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
    }
}


static void DoDefault( void )
{
    char        buff[BUFLEN+1];

    StartPrintBuff( buff, BUFLEN );
    GetExpr();
    PrintValue();
    PopEntry();
    EndBuff();
}

void DoPrintList( bool output )
{
    char        *fmt_start;
    unsigned    fmt_len;

    OutPgm = output;
    First = TRUE;
    while( !ScanEOC() ) {
        if( ScanQuote( &fmt_start, &fmt_len ) ) {
            DoFormat( fmt_start, fmt_start + fmt_len );
        } else {
            DoDefault();
        }
    }
}

static void LogPrintList( void )
{
    if( _IsOn( SW_CMD_INTERACTIVE ) ) {
        DUIShowLogWindow();
    }
    DoPrintList( FALSE );
}

void ChkPrintList( void )
{
    bool        first;
    char        *start;
    unsigned    len;

    first = TRUE;
    while( !ScanEOC() ) {
        if( ScanQuote( &start, &len ) ) first = TRUE;
        if( !first && CurrToken == T_COMMA ) Scan();
        ChkExpr();
        if( CurrToken != T_COMMA ) ReqEOC();
        first = FALSE;
    }
}



/*
 * ProcPrint -- process print command
 */

static char     PrintBuff[TXT_LEN];
void ProcPrint( void )
{
    char        *old;

    if( CurrToken == T_DIV ) {
        Scan();
        switch( ScanCmd( PrintOps ) ) {
        case 1:
            DoPrintList( TRUE );
            break;
        case 2:
            GraphicDisplay();
            break;
        default:
            Error( ERR_LOC, LIT( ERR_BAD_OPTION ), GetCmdName( CMD_PRINT ) );
            break;
        }
    } else {
        if( ScanEOC() ) {
            DlgNewWithSym( LIT( New_Expression ), PrintBuff, TXT_LEN );
            if( PrintBuff[0] != '\0' ) {
                old = ReScan( PrintBuff );
                LogPrintList();
                ReScan( old );
            }
        } else {
            LogPrintList();
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?