dbgscan.c

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

C
942
字号
    }
    CurrToken = FIRST_CMDLN_DELIM + (ptr - CmdLnDelimTab);
    if( *ScanPtr != NULLCHAR ) {
        ++ScanPtr;
    }
    return( TRUE );
}


/*
 * ScanRealNum -- try to scan a real number
 */

static bool ScanRealNum( void )
{
    char    *curr;

    curr = ScanPtr;
    while( isdigit( *curr ) ) ++curr;
    if( *curr != '.' ) return( FALSE );
    SToLD( ScanPtr, &ScanPtr, &TokenVal.real_val );
    if( curr == ScanPtr ) {    /* it isn't a number, it's just a dot */
        ScanPtr++;
        return( FALSE );
    }
    CurrToken = T_REAL_NUM;
    return( TRUE );
}


/*
 * GetDig -- get value of a digit
 */

static int GetDig( unsigned base )
{
    char     chr;

    chr = *ScanPtr;
    chr = toupper( chr );
    if( ( (chr < '0') || (chr > '9') )
     && ( (chr < 'A') || (chr > 'Z') ) ) return( -1 );
    if( chr >= 'A' ) chr -= 'A' - '0' - 10;
    if( chr - '0' >= base ) return( -1 );
    return( chr - '0' );
}



/*
 * GetNum -- evaluate a number
 */

static bool GetNum( unsigned base )
{
    bool        ok;
    unsigned_64 num;
    unsigned_64 big_base;
    unsigned_64 big_dig;
    int         dig;

    ok = FALSE;
    U32ToU64( base, &big_base );
    U64Clear( num );
    for( ; ; ) {
        dig = GetDig( base );
        if( dig < 0 ) break;
        U32ToU64( dig, &big_dig );
        U64Mul( &num, &big_base, &num );
        U64Add( &num, &big_dig, &num );
        ++ScanPtr;
        ok = TRUE;
    }
    TokenVal.int_val = num;
    return( ok );
}



/*
 * ScanNumber -- scan for a number
 */

static char ScanNumber( void )
{
    rad_str *pref;
    bool    ret;
    char    *hold_scan;

    ret = FALSE;
    hold_scan = ScanPtr;
    if( ScanCCharNum && (*ScanPtr == '\'') ) {
        if( ScanPtr[ 1 ] != NULLCHAR && ScanPtr[ 2 ] == '\'' ) {
            U32ToU64( ScanPtr[1], &TokenVal.int_val );
            ScanPtr += 3;
            CurrToken = T_INT_NUM;
            return( TRUE );
        }
    } else {
        CurrToken = T_BAD_NUM; /* assume we'll find a bad number */
        pref = RadStrs;
        while( pref != NULL ) {
            if( memicmp( ScanPtr, &pref->radstr[1], pref->radstr[0] ) == 0 ) {
                ret = TRUE;
                ScanPtr += pref->radstr[0];
                hold_scan = ScanPtr;
                if( GetNum( pref->radval ) ) {
                    CurrToken = T_INT_NUM;
                    return( TRUE );
                }
                ScanPtr -= pref->radstr[0];
            }
            pref = pref->next;
        }
        if( isdigit( *ScanPtr ) && GetNum( CurrRadix ) ) {
            CurrToken = T_INT_NUM;
            return( TRUE );
        }
    }
    ScanPtr = hold_scan;
    return( ret );
}

#define NAME_ESC        '`'

char *NamePos( void )
{
    if( *TokenStart == NAME_ESC ) return( TokenStart + 1 );
    return( TokenStart );
}

unsigned NameLen( void )
{
    char        *end;
    char        *start;

    end = ScanPtr;
    start = TokenStart;
    if( *start == NAME_ESC ) {
        ++start;
        if( end[-1] == NAME_ESC ) {
            --end;
        }
    }
    if( start >= end)
        return( 0 );
    else
        return( end - start );
}

/*
 * ScanId -- scan for an identifier
 */

static bool ScanId( void )
{
    char        c;

    c = *ScanPtr;
    if( c == NAME_ESC ) {
        for( ;; ) {
            c = *++ScanPtr;
            if( c == NULLCHAR ) break;
            if( c == NAME_ESC ) {
                ++ScanPtr;
                break;
            }
        }
    } else {
        while ( c == '_'  || c == '$' || isalnum( c ) ) {
             c = *++ScanPtr;
        }
    }
    if( NameLen() == 0 ) return( FALSE );
    CurrToken = T_NAME;
    return( TRUE );
}


static bool ScanKeyword( char *table )
{
    int   namelen;
    int   keylen;

    namelen = ScanPtr - TokenStart;
    for( ; *table != NULLCHAR ; table += (keylen + 3) ) {
         keylen = strlen( table );
         if( keylen == namelen &&  ( _IsOn( SW_CASE_SENSITIVE )  ?
                !memcmp( table, TokenStart, namelen )  :
                !memicmp( table, TokenStart, namelen ) ) ) {
             table += (namelen + 1);
             CurrToken = *table;
             return( TRUE );
         }
    }
    return( FALSE );
}


char *ReScan( char *point )
{
    char        *old;

    old = TokenStart;
    ScanPtr = point;
    if( point != NULL ) Scan();
    return( old );
}


void ScanExpr( void *tbl )
{
    ExprTokens = tbl;
    ReScan( TokenStart );
}


void AddActualChar( char data )
{
    char    *hold, *walk1, *walk2;
    unsigned len;

    len = ++StringLength;
    _Alloc( hold, len );
    if( hold == NULL ) {
        _Free( StringStart );
        Error( ERR_NONE, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
    }
    walk1 = hold;
    walk2 = StringStart;
    for( --len; len > 0; --len )  *walk1++ = *walk2++;
    *walk1 = data;
    _Free( StringStart );
    StringStart = hold;
}


void AddChar( void )
{
    AddActualChar( *ScanPtr );
}


void AddCEscapeChar( void )
{
    static char escape_seq[] = "\n\t\v\b\r\f\a\\\?\'\"\0";
                                /* the order above must match with SSL file */

    AddActualChar( escape_seq[(int)CurrToken & 0x7f] );
}


static void RawScan( void )
{
    if( ScanPtr[-1] == NULLCHAR ) {
        /* missing end quote; scanned past eol -- error */
        _Free( StringStart );
        StringStart = NULL;   /* this is necessary */
        StringLength = 0;
        scan_string = FALSE;  /* this is essential */
        Error( ERR_NONE, LIT( ERR_WANT_END_STRING ) );
    }
    if( *ScanPtr != NULLCHAR ) {
        TokenStart = ScanPtr;
        CurrToken = T_UNKNOWN;
        if( ExprTokens != NULL ) {
            ScanExprDelim( ExprTokens->delims );
        }
        ScanPtr = TokenStart;
    } else {
        TokenStart = ScanPtr;   /* this is necessary */
        CurrToken = T_LINE_SEPARATOR;
    }
}


/*
 * Scan -- scan a token
 */

void Scan( void )
{
    if( !scan_string ) {
        while( isspace( *ScanPtr ) ) {
            ++ScanPtr;
        }
        TokenStart = ScanPtr;
        if( ExprTokens != NULL ) {
            if( ScanExprDelim( ExprTokens->delims ) )     return;
        }
        if( ScanCmdLnDelim() )      return;   /*sf do this if the others fail */
        if( ScanRealNum() )         return;
        if( ScanNumber() )          return;
        if( ScanId() ) {
            if( ExprTokens != NULL && CurrToken == T_NAME ) {
                ScanKeyword( ExprTokens->keywords );
            }
            return;
        }
        ++ScanPtr;
        CurrToken = T_UNKNOWN;
    } else {
        RawScan();
    }
}


void RawScanInit( void )
{
    ScanPtr = TokenStart;
    CurrToken = T_UNKNOWN;
}

char RawScanChar( void )
{
    return( *ScanPtr );
}

void RawScanAdvance( void )
{
    if( *ScanPtr != NULLCHAR ) ++ScanPtr;
}

void RawScanFini( void )
{
    TokenStart = ScanPtr;
    Scan();
}

/*
 * IntNumVal -- return a integer number's value
 */

unsigned_64 IntNumVal( void )
{
    return( TokenVal.int_val );
}


/*
 * RealNumVal -- return a real number's value
 */

xreal RealNumVal( void )
{
    return( TokenVal.real_val );
}


/*
 * NewCurrRadix - use when you know there's no scanning in progress
 */

unsigned NewCurrRadix( unsigned rad )
{
    unsigned    old;

    old = CurrRadix;
    CurrRadix = rad;
    return( old );
}


/*
 * SetCurrRadix - set the current number radix
 */

unsigned SetCurrRadix( unsigned rad )
{
    unsigned    old;

    old = NewCurrRadix( rad );
    ReScan( TokenStart );
    return( old );
}


void RestoreRadix( void )
{
    SetCurrRadix( DefRadix );
}


void DefaultRadixSet( unsigned radix )
{
    DefRadix = radix;
    CurrRadix = radix;
    DbgUpdate( UP_RADIX_CHANGE );
}

/*
 * RadixSet - set the default numeric radix
 */

void RadixSet( void )
{
    unsigned   radix;
    unsigned   old;

    old = SetCurrRadix( 10 ); /* radix sets are always base 10 */
    radix = ReqExpr();
    ReScan( TokenStart );
    ReqEOC();
    if( radix < 2 || radix > 36 ) {
        Error( ERR_NONE, LIT( ERR_BAD_RADIX ), radix );
    }
    SetCurrRadix( old );
    DefaultRadixSet( radix );
}


void RadixConf( void )
{
    *CnvULongDec( DefRadix, TxtBuff ) = NULLCHAR;
    ConfigLine( TxtBuff );
}


void FindRadixSpec( unsigned char value, char **start, unsigned *len )
{
    rad_str     *rad;

    *start = NULL;
    *len = 0;
    for( rad = RadStrs; rad != NULL; rad = rad->next ) {
        if( rad->radval == value ) {
            *start = &rad->radstr[1];
            *len   = rad->radstr[0];
            return;
        }
    }
}


char *AddHexSpec( char *p )
{
    char        *pref;
    unsigned    len;

    if( CurrRadix == 16 ) return( p );
    FindRadixSpec( 16, &pref, &len );
    memcpy( p, pref, len );
    p += len;
    *p = '\0';
    return( p );
}


/*
 * ForceSym2Num -- try to force an unknown symbol into a number
 */

bool ForceSym2Num( char *start, unsigned len, unsigned_64 *val_ptr )
{
    char        *old_scanptr;
    char        *old_tokenstart;
    token_value old_token_val;
    bool        rtn;

    old_token_val = TokenVal;
    old_scanptr = ScanPtr;
    old_tokenstart = TokenStart;
    ScanPtr = TokenStart = start;
    rtn = ( GetNum( CurrRadix ) && (ScanPtr - TokenStart) == len );
    *val_ptr = TokenVal.int_val;
    ScanPtr = old_scanptr;
    TokenStart = old_tokenstart;
    TokenVal = old_token_val;
    return( rtn );
}

⌨️ 快捷键说明

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