dbgscan.c

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

C
942
字号
/****************************************************************************
*
*                            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:  Debugger lexical scanner.
*
****************************************************************************/


#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "dbgdefn.h"
#include "dbgtoken.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbglit.h"
#include "ldsupp.h"
#include "mad.h"
#include "madcli.h"
#include "dui.h"
#include "i64.h"


typedef struct rad_str {
    struct   rad_str *next;
    unsigned char    radval;
    char             radstr[1];         /* first byte is length */
} rad_str;

extern unsigned         Lookup( char *, char *, unsigned );
extern unsigned int     ReqExpr( void );
extern void             ConfigLine( char * );
extern char             *Format( char *, char *, ... );
extern char             *CnvULongDec( unsigned long, char * );
extern unsigned         GetMADTypeNameForCmd( mad_type_handle th, unsigned max, char *p );
extern void             DbgUpdate( update_list );
extern char             *ReScan( char *point );

extern tokens         CurrToken;
extern unsigned char  DefRadix;
extern unsigned char  CurrRadix;
extern char           *TxtBuff;

extern void Scan( void );

static char CmdLnDelimTab[] = { "<>*/(),{}!?;[]~#\0" };

typedef union {
        unsigned_64     int_val;
        xreal           real_val;
} token_value;


static  rad_str     *RadStrs;
static  char        *ScanPtr;
static  token_value  TokenVal;
static  char        *TokenStart;
static  token_table *ExprTokens;
        bool         scan_string = FALSE;
        char        *StringStart = NULL;
        unsigned     StringLength = 0;
        unsigned     ScanCCharNum = TRUE;


static void SetRadixSpec( char *str, unsigned len, unsigned radix, bool clear )
{

    rad_str   *pref;
    rad_str  **owner;

    owner = &RadStrs;
    pref = RadStrs;
    while( pref != NULL ) {
        if( pref->radstr[0] == len
         && memicmp( &pref->radstr[1], str, pref->radstr[0] ) == 0 ) break;
        if( pref->radstr[0] < len ) break;
        owner = &pref->next;
        pref = pref->next;
    }
    if( pref == NULL || pref->radstr[0] != len ) {
        if( clear ) return;
        pref = DbgMustAlloc( sizeof( rad_str ) + len );
        memcpy( &pref->radstr[1], str, len );
        pref->radstr[0] = len;
        pref->next = *owner;
        *owner = pref;
    } else if( clear ) {
        *owner = pref->next;
        _Free( pref );
        return;
    }
    pref->radval = radix;
}


/*
 * InitScan -- initialize scanner
 */

void InitScan( void )
{
    ScanPtr = LIT( Empty );
    TokenStart = ScanPtr;
    CurrToken = T_LINE_SEPARATOR;
    RadStrs = NULL;
    SetRadixSpec( "0x", 2, 16, FALSE );
    SetRadixSpec( "0n", 2, 10, FALSE );
}


void FiniScan( void )
{
    rad_str     *old;

    while( RadStrs != NULL ) {
        old = RadStrs;
        RadStrs = RadStrs->next;
        _Free( old );
    }
}


/*
 * ScanPos -- return the current scan position
 */

char *ScanPos( void )
{
    return( TokenStart );
}



/*
 * ScanLen -- return the length of current token
 */

unsigned ScanLen( void )
{
    return( ScanPtr - TokenStart );
}



/*
 * ScanCmd -- scan a command start of current token, looking up in given table
 */

unsigned ScanCmd( char *cmd_table )
{
    unsigned    ind;
    char        *saveptr;

    saveptr = ScanPtr;
    ScanPtr = TokenStart;
    while( isalpha( *ScanPtr ) || *ScanPtr == '_' ) {
        ++ScanPtr;
    }
    ind = Lookup( cmd_table, TokenStart, ScanPtr - TokenStart );
    if( ind != 0 ) {
        Scan();
    } else {
        ScanPtr = saveptr;
    }
    return( ind );
}

struct type_name {
    char                *start;
    unsigned            len;
    mad_type_handle     th;
};

static walk_result      FindTypeName( mad_type_handle th, void *d )
{
    struct type_name    *nd = d;
    char                *p;
    char                *q;
    unsigned            len;

    GetMADTypeNameForCmd( th, TXT_LEN, TxtBuff );
    p = nd->start;
    q = TxtBuff;
    for( ;; ) {
        if( tolower( *p ) != tolower( *q ) ) break;
        if( *q == '\0' ) break;
        ++p;
        ++q;
    }
    if( isalnum( *p ) ) return( WR_CONTINUE );
    len = q - TxtBuff;
    if( *q == '\0' ) {
        /* an exact match */
        nd->len = len;
        nd->th = th;
        return( WR_STOP );
    }
    if( len > nd->len ) {
        nd->len = len;
        nd->th = th;
    }
    return( WR_CONTINUE );
}

static mad_type_handle DoScanType( mad_type_kind tk, char *prefix )
{
    struct type_name    data;
    unsigned            len;

    len = strlen( prefix );
    if( memicmp( TokenStart, prefix, len ) != 0 ) {
        return( MAD_NIL_TYPE_HANDLE );
    }
    data.start = TokenStart + len;
    data.len = 0;
    data.th = MAD_NIL_TYPE_HANDLE;
    MADTypeWalk( tk, FindTypeName, &data );
    if( data.th == MAD_NIL_TYPE_HANDLE ) return( MAD_NIL_TYPE_HANDLE );
    ReScan( data.start + data.len );
    return( data.th );
}

mad_type_handle ScanType( mad_type_kind tk, mad_type_kind *tkr )
{
    mad_type_handle     th;

    if( tk & MAS_MEMORY ) {
        th = DoScanType( tk & ~MAS_IO, LIT( Empty ) );
        if( th != MAD_NIL_TYPE_HANDLE ) {
            if( tkr != NULL ) *tkr = MAS_MEMORY;
            return( th );
        }
    }
    if( th & MAS_IO ) {
        th = DoScanType( tk & ~MAS_MEMORY, LIT( IO ) );
        if( th != MAD_NIL_TYPE_HANDLE ) {
            if( tkr != NULL ) *tkr = MAS_IO;
            return( th );
        }
    }
    return( th );
}

mad_string ScanCall( void )
{
    char                *p;
    char                *q;
    const mad_string    *type;
    char                buff[NAM_LEN];

    type = MADCallTypeList();
    for( ;; ) {
        if( *type == MSTR_NIL ) return( MSTR_NIL );
        MADCliString( *type, sizeof( buff ), buff );
        q = buff;
        p = TokenStart;
        for( ;; ) {
            if( !isalnum( *p ) ) {
                if( p == TokenStart ) return( MSTR_NIL );
                ReScan( p );
                return( *type );
            }
            if( tolower( *p ) != tolower( *q ) ) break;
            ++p;
            ++q;
        }
        ++type;
    }
}

/*
 * ScanEOC -- check if at end of command
 */

bool ScanEOC( void )
{
    return( CurrToken == T_CMD_SEPARATOR || CurrToken == T_LINE_SEPARATOR );
}


static bool FindToken( char *table, unsigned token,
                       char **start, unsigned *len )
{
    unsigned chk;

    while( *table != NULLCHAR ) {
        *start = table;
        for( ; *table != NULLCHAR; ++table )
            ;
        chk = table[1];
        chk |= table[2] << 8;
        if( chk == token ) {
            *len = table - *start;
            return( TRUE );
        }
        table += 3;
    }
    return( FALSE );
}


bool TokenName( unsigned token, char **start, unsigned *len )
{
    switch( token ) {
    case T_LINE_SEPARATOR:
        *start = LIT( End_Of_Line );
        *len = strlen( LIT( End_Of_Line ) ) + 1;
        return( TRUE );
    case T_INT_NUM:
    case T_REAL_NUM:
        *start = LIT( Num_Name );
        *len = strlen( LIT( Num_Name ) ) + 1;
        return( TRUE );
    case T_NAME:
        *start = LIT( Sym_Name_Name );
        *len = strlen( LIT( Sym_Name_Name ) ) + 1;
        return( TRUE );
    }
    if( token < LAST_CMDLN_DELIM ) {
        *start = &CmdLnDelimTab[ token - FIRST_CMDLN_DELIM ];
        *len = sizeof( char );
        return( TRUE );
    }
    if( ExprTokens != NULL ) {
        if( FindToken( ExprTokens->delims, token, start, len ) ) return(TRUE);
        if( FindToken( ExprTokens->keywords, token, start, len ) ) return(TRUE);
    }
    return( FALSE );
}


void Recog( unsigned token )
{
    char        *start;
    unsigned    len;

    if( token != CurrToken ) {
        TokenName( token, &start, &len );
        Error( ERR_LOC, LIT( ERR_WANT_TOKEN ), start, len );
    }
    Scan();
}


/*
 * ScanQuote -- scan a debugger quoted string
 */

bool ScanQuote( char **start, unsigned *len )
{
    int   cnt;

    if( CurrToken != T_LEFT_BRACE ) {
        *start = NULL;
        *len   = 0;
        return( FALSE );
    }
    *start = ScanPtr;
    cnt = 1;
    while( cnt > 0 ) {
        Scan();
        if( CurrToken == T_LEFT_BRACE ) {
            cnt += 1;
        } else if( CurrToken == T_RIGHT_BRACE ) {
            cnt -= 1;
        } else if( CurrToken == T_LINE_SEPARATOR ) {
            Recog( T_RIGHT_BRACE ); /* cause error */
        }
    }
    *len = TokenStart - *start;
    Scan();
    return( TRUE );
}


/*
 * ScanItem - scan to a blank or EOC
 */

bool ScanItem( bool blank_delim, char **start, unsigned *len )
{
    if( ScanEOC() ) {
        *start = NULL;
        *len   = 0;
        return( FALSE );
    }
    if( ScanQuote( start, len ) ) return( TRUE );
    *start = TokenStart;
    for( ;; ) {
        if( blank_delim && isspace( *ScanPtr ) ) break;
        if( *ScanPtr == ';' ) break;
        if( *ScanPtr == NULLCHAR ) break;
        ++ScanPtr;
    }
    *len = ScanPtr - TokenStart;
    Scan();
    return( TRUE );
}


/*
 * ReqEOC -- require end of command
 */

void ReqEOC( void )
{
    if( !ScanEOC() ) Error( ERR_LOC, LIT( ERR_WANT_EOC ) );
}


/*
 * ReqEOC -- require end of command
 */

void FlushEOC( void )
{
    while( !ScanEOC() ) Scan();
}


static bool ScanExprDelim( char *table )
{
    char   *ptr;

    for( ; *table != NULLCHAR ; table += 3 ) {
        for( ptr = ScanPtr ;  ( _IsOn( SW_CASE_SENSITIVE ) ?
                *table == *ptr  :  toupper(*table) == toupper(*ptr) )
                && *table != NULLCHAR ;  ptr++, table++ );
        if( *table == NULLCHAR ) {
            table++;
            CurrToken = *table;
            ScanPtr = ptr;
            return( TRUE );
        }
        for( ; *table != NULLCHAR ; table++ );
    }
    return( FALSE );
}


static bool ScanCmdLnDelim( void )
{
    char    *ptr;

    for( ptr = CmdLnDelimTab; ; ptr++ ) {
        if( *ScanPtr == *ptr ) break;
        if( *ptr == NULLCHAR ) return( FALSE );

⌨️ 快捷键说明

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