asmexpnd.c

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

C
491
字号
/****************************************************************************
*
*                            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:  WASM symbols expansion.
*
****************************************************************************/

#include "asmglob.h"

#include "asmins.h"
#include "asmeval.h"
#include "asmexpnd.h"
#include "asmdefs.h"

#if defined( _STANDALONE_ )

#include "asmalloc.h"
#include "asmsym.h"
#include "directiv.h"
#include "asmlabel.h"
#include "asminput.h"

#include "myassert.h"

#define    MAX_EQU_NESTING      20

extern void             GetInsString( enum asm_token , char *, int );

static int              createconstant( char *, bool, int, bool, bool );

static label_list *label_cmp( char *name, label_list *head )
{
    label_list  *curr;

    for( curr = head; curr; curr = curr->next ) {
        if( stricmp( curr->label, name ) == 0 ) {
            return( curr );
        }
    }
    return( NULL );
}


void AddTokens( ASM_TOK **buffer, int start, int count )
/************************************************************/
{
    int i;

    switch( count ) {
    case 0:
        return;
    case -1:
        /* it's an empty expansion */
        for( i = start; i <= Token_Count; ++i ) {
            *buffer[i] = *buffer[i+1];
        }
        break;
    default:
        for( i=Token_Count; i >= start; i-- ) {
            *buffer[i+count] = *buffer[i];
        }
        break;
    }
    Token_Count += count;
}

int ExpandSymbol( int i, bool early_only )
/***************************************/
{
    struct asm_sym      *sym;
    dir_node            *dir;
    int                 j;

    /* expand constant */
    sym = AsmGetSymbol( AsmBuffer[i]->string_ptr );
    if( sym == NULL ) return( NOT_ERROR );
    switch( sym->state ) {
    case SYM_CONST:
        dir = (dir_node *)sym;
        if(( dir->e.constinfo->expand_early == FALSE )
            && ( early_only == TRUE )) return( NOT_ERROR );
        DebugMsg(( "Expand Constant: %s ->", sym->name ));
        /* insert the pre-scanned data for this constant */
        AddTokens( AsmBuffer, i, dir->e.constinfo->count - 1 );
        for( j = 0; j < dir->e.constinfo->count; j++ ) {
            AsmBuffer[i+j]->token = dir->e.constinfo->data[j].token;
            AsmBuffer[i+j]->value = dir->e.constinfo->data[j].value;
            AsmBuffer[i+j]->string_ptr = dir->e.constinfo->data[j].string_ptr;
            #ifdef DEBUG_OUT
            if( AsmBuffer[i+j]->token == T_NUM ) {
                DebugMsg(( " %d", AsmBuffer[i+j]->value ));
            } else {
                DebugMsg(( " %s", AsmBuffer[i+j]->string_ptr ));
            }
            #endif
        }
        DebugMsg(( "\n" ));
        Globals.expand_count++;
        if( Globals.expand_count >= MAX_EQU_NESTING ) {
            AsmError( NESTING_LEVEL_TOO_DEEP );
            return( ERROR );
        }
        return( STRING_EXPANDED );
    }
    return( NOT_ERROR );
}

int ExpandProcString( int index )
/*******************************/
{
    int_8               i;
    int_8               cnt;
    int_8               count = 0; /* number of words in the name string */
    char                *string;
    char                *word;
    char                *replace = NULL;
    char                buffer[MAX_LINE_LEN];
    label_list          *label;

    string = AsmTmpAlloc( strlen( AsmBuffer[index]->string_ptr ) + 1 );
    strcpy( string, AsmBuffer[index]->string_ptr );
    wipe_space( string );
    word = strtok( string, " \t" );
    while( word != NULL ) {
        count++;

        /**/myassert( CurrProc != NULL );
        label = label_cmp( word, CurrProc->e.procinfo->paralist );
        if( label == NULL ) {
            label = label_cmp( word, CurrProc->e.procinfo->locallist );
        }
        if( label != NULL ) {
            if( label->replace != NULL ) {
                replace = label->replace;
            }
        }

        if( replace != NULL ) {
            if( *replace == '\0' ) {
                AsmErr( CANT_ACCESS_MULTI_REG_PARMS, replace+1 );
                return( ERROR );
            }
            if( index > 0 && AsmBuffer[index-1]->token == T_DIRECTIVE ) {
                switch( AsmBuffer[index-1]->value ) {
                case T_IFDEF:
                case T_IFNDEF:
                    /* do NOT expand strings in IFDEF and IFNDEF ins.
                     * we want to know if they are defined, NOT their value
                     */
                    return( NOT_ERROR );
                }
            }
            if( AsmBuffer[index+1]->token == T_DIRECTIVE ) {
                /* this will never happen with multiple words in a string */
                switch( AsmBuffer[index+1]->value ) {
                case T_EQU:
                case T_EQU2:
                case T_TEXTEQU:
                    return( NOT_ERROR );
                }
            }
            break;
        }
        word = strtok( NULL, " \t" );
    }
    if( replace == NULL ) return( NOT_ERROR );

    DebugMsg(( "ExpandString: %s -> %s \n", word, replace ));

    /* now we need to build the new line string to pass through the scanner */
    buffer[0] = '\0';
    /* NOTE: if we have a T_DIRECTIVE, token_count is always set to 1 !??! */
    for( i=0; i < Token_Count; i++ ) {
        if( i != index ) {
            // if( expand_directive_string( buffer, i ) == ERROR ) return( ERROR );
            if( AsmBuffer[i]->token == T_STRING &&
                *AsmBuffer[i]->string_ptr == '\0' ) {
                strcat( buffer, "<>" );
            } else {
                strcat( buffer, AsmBuffer[i]->string_ptr );
            }
        } else {
            if( AsmBuffer[i]->token == T_PERCENT ) {
                /* don't save the % */
                i++;
            }
            // if( expand_directive_string( buffer, i ) == ERROR ) return( ERROR );

            /* copy the string in ... 1 word at a time */
            string = AsmTmpAlloc( strlen( AsmBuffer[index]->string_ptr ) + 1 );
            strcpy( string, AsmBuffer[index]->string_ptr );
            wipe_space( string );
            word = strtok( string, " \t" );
            for( cnt = 1; cnt < count; cnt++ ) {
                strcat( buffer, word );
                strcat( buffer, " " );
                word = strtok( NULL, " \t" );
            }
            strcat( buffer, replace );
            word = strtok( NULL, " \t" );
            while( word != NULL ) {
                strcat( buffer, " " );
                strcat( buffer, word );
                word = strtok( NULL, " \t" );
            }
        }
        strcat( buffer, " " );
    }
    /* make sure this line goes at the front of the queue */
    PushLineQueue();
    InputQueueLine( buffer );
    AsmBuffer[0]->token = 0;
    AsmBuffer[0]->string_ptr = NULL;
    AsmBuffer[0]->value = 0;
    return( STRING_EXPANDED );
}

int DefineConstant( int i, bool redefine, bool expand_early )
/***********************************************************/
/* if expand_early is TRUE, expand before doing any parsing */
{

    char                *name;

⌨️ 快捷键说明

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