⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cscan.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            *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 + -