cmac2.c

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

C
840
字号
                    CurToken = T_MACRO_VAR_PARM;
                else
                    CurToken = T_MACRO_PARM;
                TokenBuf[i-1] = CurToken;
                TokenBuf[i] = j - 1;
                ++i;
            } else {
                j = 0;
                while( (TokenBuf[i++] = Buffer[j++]) )
                    ;   /*empty*/
            }
            break;
        case T_BAD_CHAR:
            TokenBuf[i++] = Buffer[0];
            if( Buffer[1] != '\0' )
                TokenBuf[i++] = T_WHITE_SPACE;
            break;
        case T_CONSTANT:
        case T_STRING:
        case T_LSTRING:
        case T_BAD_TOKEN:
        case T_PPNUMBER:
            j = 0;
            while( (TokenBuf[i++] = Buffer[j++]) )
                ;   /* empty */
            break;
        default:
            break;
        }
        if( CurToken != T_WHITE_SPACE ) {
            if( prev_non_ws_token == T_MACRO_SHARP &&       /* 26-mar-91 */
                CurToken != T_MACRO_PARM &&
                CurToken != T_MACRO_VAR_PARM ) {
                CErr1( ERR_MUST_BE_MACRO_PARM );
                prev_token = TokenBuf[0];
                TokenBuf[0] = T_SHARP;              /* 17-jul-92 */
                MacroCopy( TokenBuf, MacroOffset + mlen - 1, 1 );
                TokenBuf[0] = prev_token;
            }
            prev_non_ws_token = CurToken;
        }
        prev_token = CurToken;
        CurToken = ScanToken();
        MacroOverflow( mlen + i, mlen );
        MacroCopy( TokenBuf, MacroOffset + mlen, i );
        mlen += i;
    }
    if( prev_non_ws_token == T_MACRO_SHARP ) {      /* 16-nov-94 */
        CErr1( ERR_MUST_BE_MACRO_PARM );
    }
    if( prev_token == T_WHITE_SPACE ) {
        --mlen;
    }
    MacroOverflow( mlen + 1, mlen );                /* 27-apr-94 */
    *(char *)(MacroOffset + mlen) = T_NULL;
    ++mlen;
    if( prev_non_ws_token == T_SHARP_SHARP ) {
        CErr1( ERR_MISPLACED_SHARP_SHARP );
    }
    mentry->macro_len = mlen;
    MacLkAdd( mentry, mlen, MACRO_USER_DEFINED | (has_var_args ? MACRO_VAR_ARGS : 0) );
    CMemFree( mentry );                     /* 22-aug-88, FWC */
    MacroSize += mlen;
}


local int FormalParm( struct macro_parm *formal_parms )
{
    int i;

    i = 1;
    while( formal_parms != NULL ) {
        if( strcmp( formal_parms->parm, Buffer ) == 0 ) return( i );
        ++i;
        formal_parms = formal_parms->next_macro_parm;
    }
    return( 0 );
}


local void CIfDef( void )
{
    MEPTR       mentry;

    PPNextToken();
    if( CurToken != T_ID ) {
        ExpectIdentifier();
        IncLevel( 0 );
        return;
    }
    mentry = MacroLookup( Buffer );
    if( mentry != NULL ) {
        mentry->macro_flags |= MACRO_REFERENCED;
        IncLevel( 1 );
    } else {
        IncLevel( 0 );
    }
    PPNextToken();
    ChkEOL();
}


local void CIfNDef( void )
{
    MEPTR       mentry;

    PPNextToken();
    if( CurToken != T_ID ) {
        ExpectIdentifier();
        IncLevel( 0 );
        return;
    }
    mentry = MacroLookup( Buffer );
    if( mentry != NULL ) {
        mentry->macro_flags |= MACRO_REFERENCED;
        IncLevel( 0 );
    } else {
        IncLevel( 1 );
    }
    PPNextToken();
    ChkEOL();
}


local int GetConstExpr( void )                              /* 13-nov-91 */
{
    int         value;
    int         useful_side_effect;
    int         meaningless_stmt;

/* This solves the following weird condition.   */
/*      while( f() == 1 )                       */
/* The expression for the #if destroys the flags saved for the while expr */
/*   #if 1                                      */
/*              ;                               */
/*   #endif                                     */

    useful_side_effect = CompFlags.useful_side_effect;
    meaningless_stmt   = CompFlags.meaningless_stmt;
    value = BoolConstExpr();
    CompFlags.useful_side_effect = useful_side_effect;
    CompFlags.meaningless_stmt   = meaningless_stmt;
    return( value );
}

local void CIf( void )
{
    int value;

    CompFlags.pre_processing = 1;
    PPNextToken();
    value = GetConstExpr();
    IncLevel( value );
    ChkEOL();
}


local void CElif( void )
{
    int value;

    CompFlags.pre_processing = 1;
    PPNextToken();
    if( (NestLevel == 0) || (CppStack->cpp_type == PRE_ELSE) ) {
        CErr1( ERR_MISPLACED_ELIF );
    } else {
        if( NestLevel == SkipLevel ) {
            --SkipLevel;                /* start skipping else part */
            CppStack->processing = 0;
            CppStack->cpp_type = PRE_ELIF;
        } else if( NestLevel == SkipLevel + 1 ) {
            /* only evaluate the expression when required */
            if( CppStack->cpp_type == PRE_IF ) {        /* 30-jun-88 */
                value = GetConstExpr();         /* 21-jun-88 */
                ChkEOL();
                if( value ) {
                    SkipLevel = NestLevel; /* start including else part */
                    CppStack->processing = 1;
                    CppStack->cpp_type = PRE_ELIF;
                }
            }
        }
    }
}


local void IncLevel( int value )
{
    struct cpp_info *cpp;

    cpp = (struct cpp_info *)CMemAlloc( sizeof( struct cpp_info ) );
    cpp->prev_cpp = CppStack;
    cpp->file_name = ErrFName;
    cpp->line_num = TokenLine;
    cpp->cpp_type = PRE_IF;
    cpp->processing = 0;
    CppStack = cpp;
    if( NestLevel == SkipLevel ) {
        if( value ) {
            ++SkipLevel;
            cpp->processing = 1;
        }
    }
    ++NestLevel;
}


local void WantEOL( void )
{
    if( CompFlags.extensions_enabled ) {
        if( CurToken != T_NULL  &&  CurToken != T_EOF ) {
            if( NestLevel == SkipLevel ) {
                CWarn1( WARN_JUNK_FOLLOWS_DIRECTIVE, ERR_JUNK_FOLLOWS_DIRECTIVE );
            }
            Flush2EOL();
        }
    } else {
        ChkEOL();
    }
}


local void CElse( void )
{
    if( (NestLevel == 0) || (CppStack->cpp_type == PRE_ELSE) ) {
        CErr1( ERR_MISPLACED_ELSE );
    } else {
        if( NestLevel == SkipLevel ) {
            --SkipLevel;                /* start skipping else part */
            CppStack->processing = 0;
        } else if( NestLevel == SkipLevel + 1 ) {
            /* cpp_type will be PRE_ELIF if an elif was true */
            if( CppStack->cpp_type == PRE_IF ) {        /* 19-sep-88 */
                SkipLevel = NestLevel;  /* start including else part */
                CppStack->processing = 1;
            }
        }
        CppStack->cpp_type = PRE_ELSE;
    }
    PPNextToken();
    WantEOL();
}


local void CEndif( void )
{
    if( NestLevel == 0 ) {
        CErr1( ERR_MISPLACED_ENDIF );
    } else {
        struct cpp_info *cpp;

        --NestLevel;
        cpp = CppStack;
        if( cpp->file_name != ErrFName ) {
             CWarn( WARN_LEVEL_1, ERR_WEIRD_ENDIF_ENCOUNTER, cpp->file_name  );
        }
        CppStack = cpp->prev_cpp;
        CMemFree( cpp );
    }
    if( NestLevel < SkipLevel ) {
        SkipLevel = NestLevel;
    }
    PPNextToken();
    WantEOL();
}

extern bool MacroDel( char *name )
/********************************/
{
    MEPTR       mentry;
    MEPTR       prev_entry;
    int         len;
    bool        ret;

    ret = FALSE;
    if( strcmp( name, "defined" ) == 0 ) {
        CErr2p( ERR_CANT_UNDEF_THESE_NAMES, name  );
        return( ret );
    }
    prev_entry = NULL;
    len = strlen( name ) + 1;
    mentry = MacHash[ MacHashValue ];
    while( mentry != NULL ) {
        if( memcmp( mentry->macro_name, name, len ) == 0 ) break;
        prev_entry = mentry;
        mentry = mentry->next_macro;
    }
    if( mentry != NULL ) {
        if( mentry->macro_defn == 0 ) {
            CErr2p( ERR_CANT_UNDEF_THESE_NAMES, name );
        } else {
            if( prev_entry != NULL ) {
                prev_entry->next_macro = mentry->next_macro;
            } else {
                MacHash[ MacHashValue ] = mentry->next_macro;
            }
            if( (InitialMacroFlag & MACRO_DEFINED_BEFORE_FIRST_INCLUDE) == 0 ) {
                /* remember macros that were defined before first include */
                if( mentry->macro_flags & MACRO_DEFINED_BEFORE_FIRST_INCLUDE ) {
                    mentry->next_macro = UndefMacroList;
                    UndefMacroList = mentry;
                }
            }
            ret = TRUE;
        }
    }
    return( ret );
}


local void CUndef( void )
{

    PPNextToken();
    if( CurToken != T_ID ) {
        ExpectIdentifier();
        return;
    }
    MacroDel( Buffer );
    PPNextToken();
    ChkEOL();
}


local void ChkEOL( void )
{
    if( (CurToken != T_NULL) && (CurToken != T_EOF) ) { /* 15-dec-91 */
        ExpectEndOfLine();
    }
}


local void CLine( void )
{
    FNAMEPTR        flist;
    unsigned long   src_line;

    CompFlags.pre_processing = 1;
    PPNextToken();
    if( CurToken != T_CONSTANT ) {
        ExpectConstant();
        return;
    }
    if( CompFlags.cpp_ignore_line == 0 ) {
        src_line = Constant; // stash in case of side effects
        SrcFile->src_line = src_line - 1; /* don't count this line */
    }
    PPNextToken();
    if( CurToken != T_NULL ) {
        if( (CurToken != T_STRING) || CompFlags.wide_char_string ) {
            /* wide char string not allowed, 26-mar-91 */
            ExpectString();
            return;
        }
        if( CompFlags.cpp_ignore_line == 0 ) {
            //          RemoveEscapes( Buffer );                /* 04-apr-91 */
            flist = AddFlist( Buffer );
            flist->rwflag = FALSE;  // not a real file so no autodep
            SrcFile->src_name = flist->name;
            SrcFile->src_fno  = flist->index;
            TokenFno = flist->index;
            SrcFile->src_flist = flist;             /* 21-dec-93 */
            ErrFName = SrcFile->src_name;
            if( CompFlags.cpp_output ) {            /* 30-may-95 */
                EmitLine( src_line, SrcFile->src_name );
            }
        }
        PPNextToken();
        ChkEOL();
    } else if( CompFlags.cpp_ignore_line == 0 ) {
        if( CompFlags.cpp_output ) {            /* 30-may-95 */
            EmitLine( src_line, SrcFile->src_name );
        }
    }
}


local void CError( void )
{
    int i;
    int save;

    i = 0;
    while( CurrChar != '\n' && CurrChar != '\r' && CurrChar != EOF_CHAR ) {
        if( i != 0 || CurrChar != ' ' ) {
            Buffer[i] = CurrChar;
            ++i;
        }
        NextChar();
    }
    Buffer[i] = '\0';
    /* Force #error output to be reported, even with preprocessor */
    save = CompFlags.cpp_output;
    CompFlags.cpp_output = 0;
    CErr2p( ERR_USER_ERROR_MSG, Buffer );
    CompFlags.cpp_output = save;
}


void CppStackInit( void )
{
    NestLevel = 0;
    SkipLevel = 0;
    CppStack = NULL;
}


void CppStackFini( void )
{
    struct cpp_info *cpp;

    while( (cpp = CppStack) ) {
        SetErrLoc( cpp->file_name, cpp->line_num );
        CErr1( ERR_MISSING_CENDIF );
        CppStack = cpp->prev_cpp;
        CMemFree( cpp );
    }
    CppStack = NULL;
}

⌨️ 快捷键说明

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