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