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