📄 cscan.c
字号:
*p++ = c;
c = *scanptr++;
if( (CharSet[c] & (C_AL | C_DI)) == 0 ) break;
*p++ = c;
c = *scanptr++;
if( (CharSet[c] & (C_AL | C_DI)) == 0 ) break;
*p++ = c;
c = *scanptr++;
if( (CharSet[c] & (C_AL | C_DI)) == 0 ) break;
*p++ = c;
c = *scanptr++;
if( p >= &Buffer[BufSize - 16] ) {
char *oldbuf = Buffer;
EnlargeBuffer( BufSize * 2 );
p += Buffer - oldbuf;
}
}
ScanCharPtr = scanptr;
if( (CharSet[c] & C_EX) == 0 ) break;
c = GetCharCheck( c );
if( (CharSet[c] & (C_AL | C_DI)) == 0 ) break;
}
CurrChar = c;
if( p >= &Buffer[BufSize - 18] ) {
char *oldbuf = Buffer;
EnlargeBuffer( BufSize * 2 );
p += Buffer - oldbuf;
}
*p = '\0';
TokenLen = p - Buffer;
}
static int doScanAsm( void )
{
BadTokenInfo = 0;
TokenLen = 0;
do {
Buffer[TokenLen++] = CurrChar;
doScanAsmToken();
} while( CurrChar == '.' );
CurToken = T_ID;
return( CurToken );
}
int ScanDot()
{
if( CompFlags.inside_asm_stmt == 1 )
return( doScanAsm() );
Buffer[0] = '.';
TokenLen = 1;
return( doScanFloat() );
}
static int ScanPPNumber()
{
int c;
int prevc;
// 3.1.8 pp-number
// pp-number:
// digit (checked by caller)
// . digit (checked by caller)
// pp-number digit
// pp-number non-digit
// pp-number e sign
// pp-number E sign
// pp-number .
//
c = 0;
for(;;) {
prevc = c;
c = SaveNextChar();
if( CharSet[c] & (C_AL | C_DI) )continue;
if( c == '.' )continue;
if( c == '+' || c == '-' ){
if( prevc == 'e' || prevc == 'E' ){
if( CompFlags.extensions_enabled ){
/* concession to existing practice...
#define A2 0x02
#define A3 0xaa0e+A2
// users want: 0xaa0e + 0x02
// not: 0xaa0e + A2 (but, this is what ISO C requires!)
*/
prevc = c; //advance to next
c = SaveNextChar();
if( !(CharSet[c] & C_DI) )break; //allow e+<digit>
}
continue;
}
}
break;
}
--TokenLen;
Buffer[TokenLen] = '\0';
return( T_PPNUMBER );
}
int ScanPPDigit()
{
Buffer[0] = CurrChar;
TokenLen = 1;
return ScanPPNumber();
}
int ScanPPDot()
{
int c;
Buffer[0] = '.';
TokenLen = 1;
c = SaveNextChar();
if( c >= '0' && c <= '9' ) {
return ScanPPNumber();
} else {
return ScanDotSomething( c );
}
}
int ScanHex( int max, const char **pbuf )
{
int c;
int count;
unsigned char chrclass;
char too_big;
unsigned long value;
too_big = 0;
count = max;
value = 0;
for( ;; ) {
if( pbuf == NULL ) {
c = SaveNextChar();
} else {
c = *++*pbuf;
}
if( max == 0 ) break;
chrclass = CharSet[ c ];
if( ( chrclass & (C_HX|C_DI) ) == 0 ) break;
if( chrclass & C_HX ) c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
if( value & 0xF0000000 ) too_big = 1; /* 26-mar-91 */
value = value * 16 + c - '0';
--max;
}
Constant = value;
if( count == max ) { /* no characters matched */
return( 0 ); /* indicate no characters matched */
/* CErr1( ERR_INVALID_HEX_CONSTANT ); */
}
if( too_big ) { /* 26-mar-91 */
BadTokenInfo = ERR_CONSTANT_TOO_BIG;
if( NestLevel == SkipLevel ) { /* 10-sep-92 */
CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
}
}
return( 1 ); /* indicate characters were matched */
}
typedef enum { CNV_32, CNV_64, CNV_OVR } cnv_cc;
static cnv_cc Cnv8( void ){
char *curr;
char c;
int len;
long value;
uint64 value64;
cnv_cc ret;
curr = Buffer;
len = TokenLen;
value = 0;
while( --len > 0 ){
c = *curr;
if( value & 0xE0000000 ) goto is64; /* 64 bit */
value = value * 8 + c - '0';
++curr;
}
Constant = value;
return( CNV_32 );
is64:
ret = CNV_64;
U32ToU64( value, &value64 );
do{
c = *curr;
if( U64Cnv8( &value64, c-'0' ) ){
ret = CNV_OVR;
}
++curr;
}while( --len > 0 );
Const64 = value64;
return( ret );
}
static cnv_cc Cnv16( void ){
unsigned char *curr;
unsigned char c;
int len;
unsigned long value;
uint64 value64;
cnv_cc ret;
curr = Buffer+2; //skip 0x thing
len = TokenLen-2;
value = 0;
while( --len > 0 ){
c = *curr;
if( value & 0xF0000000 ) goto is64; /* 64 bit */
if( CharSet[ c ] & C_HX ){
c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
}
value = value * 16 + c - '0';
++curr;
}
Constant = value;
return( CNV_32 );
is64:
ret = CNV_64;
U32ToU64( value, &value64 );
do{
c = *curr;
if( CharSet[ c ] & C_HX ){
c = (( c | HEX_MASK ) - HEX_BASE ) + 10 + '0';
}
if( U64Cnv16( &value64, c-'0' ) ){
ret = CNV_OVR;
}
++curr;
}while( --len > 0 );
Const64 = value64;
return( ret );
}
static cnv_cc Cnv10( void ){
char *curr;
char c;
int len;
unsigned long value;
uint64 value64;
cnv_cc ret;
curr = Buffer; //skip 0x thing
len = TokenLen;
value = 0;
while( --len > 0 ){
c = *curr;
if( value >= 429496729 ) { /* 15-feb-93 */
if( value == 429496729 ) {
if( c > '5' ) goto is64;
} else {
goto is64;
}
}
value = value * 10 + c - '0';
++curr;
}
Constant = value;
return( CNV_32 );
is64:
ret = CNV_64;
U32ToU64( value, &value64 );
do{
c = *curr;
if( U64Cnv10( &value64, c-'0') ){
ret = CNV_OVR;
}
++curr;
}while( --len > 0 );
Const64 = value64;
return( ret );
}
static int ScanNum( void )
{
int c;
int bad_token_type;
cnv_cc ov;
struct {
enum{ CON_DEC, CON_HEX, CON_OCT, CON_ERR }form;
enum { SUFF_NONE,SUFF_U, SUFF_L,SUFF_UL, SUFF_I, SUFF_UI,
SUFF_LL,SUFF_ULL } suffix;
}con;
if( CompFlags.inside_asm_stmt == 1 )
return( doScanAsm() );
BadTokenInfo = 0;
ov = CNV_32;
Constant = 0;
TokenLen = 1;
c = CurrChar;
Buffer[0] = c;
if( c == '0' ) {
c = SaveNextChar();
if( c == 'x' || c == 'X' ) {
unsigned char chrclass;
bad_token_type = ERR_INVALID_HEX_CONSTANT;
con.form = CON_HEX;
for( ;; ) {
c = SaveNextChar();
chrclass = CharSet[ c ];
if( ( chrclass & (C_HX|C_DI) ) == 0 ) break;
}
if( TokenLen == 3 ){ /* just collected a 0x */
BadTokenInfo = ERR_INVALID_HEX_CONSTANT;
if( NestLevel == SkipLevel ) {
CErr1( ERR_INVALID_HEX_CONSTANT );
con.form = CON_ERR;
}
}
} else { /* scan octal number */
unsigned char digit_mask;
bad_token_type = ERR_INVALID_OCTAL_CONSTANT;
con.form = CON_OCT;
digit_mask = 0;
// if collecting tokens for macro preprocessor, allow 8 and 9
// since the argument may be used in with # or ##. 28-oct-92
while( c >= '0' && c <= '9' ) {
digit_mask |= c;
c = SaveNextChar();
}
if( c == '.' || c == 'e' || c == 'E' ) {
return( doScanFloat() );
}
if( digit_mask & 0x08 ) { /* if digit 8 or 9 somewhere */
BadTokenInfo = ERR_INVALID_OCTAL_CONSTANT;
con.form = CON_ERR;
if( NestLevel == SkipLevel ) {
CErr1( ERR_INVALID_OCTAL_CONSTANT );
}
}
}
} else { /* scan decimal number */
bad_token_type = ERR_INVALID_CONSTANT;
con.form = CON_DEC;
for(;;) {
c = SaveNextChar();
if( c < '0' || c > '9' ) break;
}
if( c == '.' || c == 'e' || c == 'E' ) {
return( doScanFloat() );
}
}
switch( con.form ){
case CON_OCT:
ov = Cnv8();
break;
case CON_HEX:
ov = Cnv16();
break;
case CON_DEC:
ov = Cnv10();
break;
case CON_ERR:
ov = CNV_32;
}
con.suffix = SUFF_NONE;
if( c == 'l' || c == 'L' ) { // collect suffix
c = SaveNextChar();
if( c == 'u' || c == 'U' ) {
c = SaveNextChar();
con.suffix = SUFF_UL;
} else if( c == 'l' || c == 'L' ) {
c = SaveNextChar();
if( c == 'u' || c == 'U' ) {
c = SaveNextChar();
con.suffix = SUFF_ULL;
}else{
con.suffix = SUFF_LL;
}
}else{
con.suffix = SUFF_L;
}
} else if( c == 'u' || c == 'U' ) {
c = SaveNextChar();
if( c == 'l' || c == 'L' ) {
c = SaveNextChar();
if( c == 'l' || c == 'L' ) {
c = SaveNextChar();
con.suffix = SUFF_ULL;
}else{
con.suffix = SUFF_UL;
}
} else if( c == 'i' || c == 'I' ) {
c = SaveNextChar();
con.suffix = SUFF_UI;
}else{
con.suffix = SUFF_U;
}
} else if( c == 'i' || c == 'I' ) {
c = SaveNextChar();
con.suffix = SUFF_I;
}
if( con.suffix == SUFF_UI || con.suffix == SUFF_I ){
unsigned_32 value;
value = 0;
while( c >= '0' && c <= '9' ) {
value = value * 10 + c - '0';
c = SaveNextChar();
}
if( value == 64 ){
if( con.suffix == SUFF_I ){
ConstType = TYPE_LONG64;
}else{
ConstType = TYPE_ULONG64;
}
if( ov == CNV_32 ){
U32ToU64( Constant, &Const64 );
}
}else if( value == 32 ){
if( con.suffix == SUFF_I ){
ConstType = TYPE_LONG;
}else{
ConstType = TYPE_ULONG;
}
}else if( value == 16 ){
if( con.suffix == SUFF_I ){
ConstType = TYPE_SHORT;
}else{
ConstType = TYPE_USHORT;
}
}else if( value == 8 ){
if( con.suffix == SUFF_I ){
ConstType = TYPE_CHAR;
}else{
ConstType = TYPE_UCHAR;
}
}else{
if( NestLevel == SkipLevel ) {
CErr1( ERR_INVALID_CONSTANT );
}
}
if( ov == CNV_64 && value < 64 ){
BadTokenInfo = ERR_CONSTANT_TOO_BIG;
if( NestLevel == SkipLevel ) { /* 10-sep-92 */
CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
}
Constant = Const64.u._32[I64LO32];
}
}else if( ov == CNV_32 && con.suffix != SUFF_LL && con.suffix != SUFF_ULL ) {
switch( con.suffix ){
case SUFF_NONE:
if( Constant <= TARGET_INT_MAX ) {
ConstType = TYPE_INT;
#if TARGET_INT < TARGET_LONG
}else if( Constant <= TARGET_UINT_MAX && con.form != CON_DEC ){
ConstType = TYPE_UINT;
}else if( Constant <= 0x7ffffffful ) {
ConstType = TYPE_LONG;
}else{
ConstType = TYPE_ULONG;
}
#else
}else if( con.form != CON_DEC ){
ConstType = TYPE_UINT;
}else{
ConstType = TYPE_ULONG;
}
#endif
break;
case SUFF_L:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -