Exemplo n.º 1
0
static struct dsym *CreateGroup( const char *name )
/*************************************************/
{
    struct dsym    *grp;

    grp = (struct dsym *)SymSearch( name );

    if( grp == NULL || grp->sym.state == SYM_UNDEFINED ) {
        if ( grp == NULL )
            grp = (struct dsym *)SymCreate( name );
        else
            sym_remove_table( &SymTables[TAB_UNDEF], grp );

        grp->sym.state = SYM_GRP;
        grp->e.grpinfo = LclAlloc( sizeof( struct grp_info ) );
        grp->e.grpinfo->seglist = NULL;
        //grp->e.grpinfo->grp_idx = 0;
        //grp->e.grpinfo->lname_idx = 0;
        grp->e.grpinfo->numseg = 0;
        sym_add_table( &SymTables[TAB_GRP], grp );

        grp->sym.list = TRUE;
        grp->e.grpinfo->grp_idx = ++grpdefidx;
        grp->e.grpinfo->lname_idx = ++LnamesIdx;
        AddLnameData( &grp->sym );
    } else if( grp->sym.state != SYM_GRP ) {
        EmitErr( SYMBOL_REDEFINITION, name );
        return( NULL );
    }
    grp->sym.isdefined = TRUE;
    return( grp );
}
Exemplo n.º 2
0
static struct dsym *CreateSegment( struct dsym *seg, const char *name, bool add_global )
/**************************************************************************************/
{
    if ( seg == NULL )
        seg = ( add_global ? (struct dsym *)SymCreate( name ) : (struct dsym *)SymAlloc( name ) );
    else if ( seg->sym.state == SYM_UNDEFINED )
        sym_remove_table( &SymTables[TAB_UNDEF], seg );

    if ( seg ) {
        seg->sym.state = SYM_SEG;
        seg->e.seginfo = LclAlloc( sizeof( struct seg_info ) );
        memset( seg->e.seginfo, 0, sizeof( struct seg_info ) );
        seg->e.seginfo->Ofssize = ModuleInfo.defOfssize;
        seg->e.seginfo->alignment = 4; /* this is PARA (2^4) */
        seg->e.seginfo->combine = COMB_INVALID;
        /* null class name, in case none is mentioned */
        seg->e.seginfo->class_name_idx = 1;
        seg->next = NULL;
        /* don't use sym_add_table(). Thus the "prev" member
         * becomes free for another use.
         */
        if ( SymTables[TAB_SEG].head == NULL )
            SymTables[TAB_SEG].head = SymTables[TAB_SEG].tail = seg;
        else {
            SymTables[TAB_SEG].tail->next = seg;
            SymTables[TAB_SEG].tail = seg;
        }
    }
    return( seg );
}
Exemplo n.º 3
0
/* create external.
 * sym must be NULL or of state SYM_UNDEFINED!
 */
static struct asym *CreateExternal( struct asym *sym, const char *name, char weak )
/*********************************************************************************/
{
    if ( sym == NULL )
        sym = SymCreate( name );
    else
        sym_remove_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );

    if ( sym ) {
        sym->state = SYM_EXTERNAL;
        sym->seg_ofssize = ModuleInfo.Ofssize;
        sym->iscomm = FALSE;
        sym->weak = weak;
        sym_add_table( &SymTables[TAB_EXT], (struct dsym *)sym ); /* add EXTERNAL */
    }
    return( sym );
}
Exemplo n.º 4
0
/* create a (predefined) text macro.
 * used to create @code, @data, ...
 * there are 2 more locations where predefined text macros may be defined:
 * - assemble.c, add_cmdline_tmacros()
 * - symbols.c, SymInit()
 * this should be changed eventually.
 */
struct asym *AddPredefinedText( const char *name, const char *value )
/*******************************************************************/
{
    struct asym *sym;

    DebugMsg1(("AddPredefinedText(%s): >%s<\n", name, value ));
    /* v2.08: ignore previous setting */
    if ( NULL == ( sym = SymSearch( name ) ) )
        sym = SymCreate( name );
    sym->state = SYM_TMACRO;
    sym->isdefined = TRUE;
    sym->predefined = TRUE;
    sym->string_ptr = (char *)value;
    /* to ensure that a new buffer is used if the string is modified */
    sym->total_size = 0;
    return( sym );
}
Exemplo n.º 5
0
// make sure to get a predefined type so that the type system is not
// exercised in the back end
//
static SYMBOL rtSymbolCreate(   // CREATE NEW RUN-TIME SYMBOL
    RTS_TYPE runtime_type,      // - run-time type definition
    NAME name )                 // - name of run-time function
{
    SYMBOL sym;                 // - new symbol
    TYPE sym_type;              // - symbol's type
    symbol_flag flags;          // - symbol's flags

    flags = SF_REFERENCED;
    if( runtime_type & RTS_FUNCTION ) {
        if( runtime_type & RTS_POINTER ) {
            sym_type = TypePtrVoidFunOfVoid();
        } else if( runtime_type & RTS_HANDLER ) {
            sym_type = TypeVoidHandlerFunOfVoid();
        } else {
            sym_type = TypeVoidFunOfVoid();
        }
        if( runtime_type & RTS_INLINE ) {
            sym_type = AddFunctionFlag( sym_type, TF1_INTRINSIC );
        }
        if( runtime_type & RTS_CAN_THROW ) {
            flags |= SF_LONGJUMP;
        } else if( runtime_type & RTS_NO_THROW ) {
            flags |= SF_NO_LONGJUMP;
        } else if( runtime_type & RTS_IG_THROW ) {
            RepoFunAdd( name, RFFLAG_IG_LONGJUMP );
        }
        if( runtime_type & RTS_IS_THROW ) {
            flags |= SF_IS_THROW;
        }
    } else if( runtime_type & RTS_BASE_VOID ) {
        if( runtime_type & RTS_POINTER ) {
            sym_type = TypePtrToVoid();
        } else {
            sym_type = GetBasicType( TYP_VOID );
        }
    } else {
        sym_type = GetBasicType( TYP_SINT );
    }
    sym = SymCreate( sym_type, SC_EXTERN, flags, name, GetInternalScope() );
    LinkageSet( sym, "C" );
    return sym;
}
Exemplo n.º 6
0
ret_code SafeSEHDirective( int i, struct asm_tok tokenarray[] )
/*************************************************************/
{
    struct asym    *sym;
    struct qnode   *node;

    if ( Options.output_format != OFORMAT_COFF ) {
        if ( Parse_Pass == PASS_1)
            EmitWarn( 2, DIRECTIVE_IGNORED_WITHOUT_X, "coff" );
        return( NOT_ERROR );
    }
    if ( Options.safeseh == FALSE ) {
        if ( Parse_Pass == PASS_1)
            EmitWarn( 2, DIRECTIVE_IGNORED_WITHOUT_X, "safeseh" );
        return( NOT_ERROR );
    }
    i++;
    if ( tokenarray[i].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
    sym = SymSearch( tokenarray[i].string_ptr );

    /* make sure the argument is a true PROC */
    if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
        if ( Parse_Pass != PASS_1 ) {
            return( EmitErr( SYMBOL_NOT_DEFINED, tokenarray[i].string_ptr ) );
        }
    } else if ( sym->isproc == FALSE ) {
        return( EmitErr( SAFESEH_ARGUMENT_MUST_BE_A_PROC, tokenarray[i].string_ptr ) );
    }

    if ( Parse_Pass == PASS_1 ) {
        if ( sym ) {
            for ( node = ModuleInfo.g.SafeSEHQueue.head; node; node = node->next )
                if ( node->elmt == sym )
                    break;
        } else {
            sym = SymCreate( tokenarray[i].string_ptr );
            node = NULL;
        }
        if ( node == NULL ) {
            sym->used = TRUE; /* make sure an external reference will become strong */
#if 0 /* v2.11: use QAddItem() */
            node = LclAlloc( sizeof( struct qnode ) );
            node->elmt = sym;
            node->next = NULL;
            if ( ModuleInfo.g.SafeSEHQueue.head == 0 )
                ModuleInfo.g.SafeSEHQueue.head = ModuleInfo.g.SafeSEHQueue.tail = node;
            else {
                ((struct qnode *)ModuleInfo.g.SafeSEHQueue.tail)->next = node;
                ModuleInfo.g.SafeSEHQueue.tail = node;
            }
#else
            QAddItem( &ModuleInfo.g.SafeSEHQueue, sym );
#endif
        }
    }
    i++;
    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    return( NOT_ERROR );
}
Exemplo n.º 7
0
ret_code PublicDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
{
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    char                *token;
    struct asym         *sym;
    //struct dsym       *dir;
    char                skipitem;
    enum lang_type      langtype;

    DebugMsg1(("PublicDirective(%u) enter\n", i));
    i++; /* skip PUBLIC directive */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        /* read the optional language type */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        if ( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        /* get the symbol name */
        token = tokenarray[i++].string_ptr;

        DebugMsg1(("PublicDirective: sym=%s\n", token ));

        /* Add the public name */
        sym = SymSearch( token );
        if ( Parse_Pass == PASS_1 ) {
            if ( sym == NULL ) {
                if ( sym = SymCreate( token ) ) {
                    sym_add_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );
                    DebugMsg1(("PublicDirective(%s): new symbol\n", sym->name ));
                } else
                    return( ERROR ); /* name was too long */
            }
            skipitem = FALSE;
        } else {
            if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
                EmitErr( SYMBOL_NOT_DEFINED, token );
                //return( ERROR ); /* v2.04: dont exit */
            }
        }
        if ( sym ) {
            switch ( sym->state ) {
            case SYM_UNDEFINED:
                break;
            case SYM_INTERNAL:
                if ( sym->scoped == TRUE ) {
                    EmitErr( CANNOT_DECLARE_SCOPED_CODE_LABEL_AS_PUBLIC, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                }
                break;
            case SYM_EXTERNAL:
                if ( sym->iscomm == TRUE ) {
                    EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                } else if ( sym->weak == FALSE ) {
                    /* for EXTERNs, emit a different error msg */
                    EmitErr( SYMBOL_REDEFINITION, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                }
                break;
            default:
                EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
                skipitem = TRUE;
                //return( ERROR );
            }
            if( Parse_Pass == PASS_1 && skipitem == FALSE ) {
                if ( sym->ispublic == FALSE ) {
                    sym->ispublic = TRUE;
                    AddPublicData( sym ); /* put it into the public table */
                }
                SetMangler( sym, langtype, mangle_type );
            }
        }

        if ( tokenarray[i].token != T_FINAL )
            if ( tokenarray[i].token == T_COMMA ) {
                if ( (i + 1) < Token_Count )
                    i++;
            } else {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
            }

    } while ( i < Token_Count );

    return( NOT_ERROR );
}
Exemplo n.º 8
0
static ret_code HandleAltname( char *altname, struct asym *sym )
/**************************************************************/
{
    struct asym *symalt;

    if ( altname && sym->state == SYM_EXTERNAL ) {

        symalt = SymSearch( altname );

        /* altname symbol changed? */
        if ( sym->altname && sym->altname != symalt ) {
            return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
        }

        if ( Parse_Pass > PASS_1 ) {
            if ( symalt->state == SYM_UNDEFINED ) {
                EmitErr( SYMBOL_NOT_DEFINED, altname );
            } else if (symalt->state != SYM_INTERNAL && symalt->state != SYM_EXTERNAL ) {
                EmitErr( SYMBOL_TYPE_CONFLICT, altname );
            } else {
#if COFF_SUPPORT || ELF_SUPPORT
                if ( symalt->state == SYM_INTERNAL && symalt->ispublic == FALSE )
                    if ( Options.output_format == OFORMAT_COFF
#if ELF_SUPPORT
                        || Options.output_format == OFORMAT_ELF
#endif
                       ) {
                        EmitErr( MUST_BE_PUBLIC_OR_EXTERNAL, altname );
                    }
#endif
                if ( sym->mem_type != symalt->mem_type )
                    EmitErr( SYMBOL_TYPE_CONFLICT, altname );
            }
        } else {

            if ( symalt ) {
                DebugMsg(("HandleAltname: symbol '%s' found, state=%u\n", altname, symalt->state ));
                if ( symalt->state != SYM_INTERNAL &&
                    symalt->state != SYM_EXTERNAL &&
                    symalt->state != SYM_UNDEFINED ) {
                    return( EmitErr( SYMBOL_TYPE_CONFLICT, altname ) );
                }
            } else {
                symalt = SymCreate( altname );
                sym_add_table( &SymTables[TAB_UNDEF], (struct dsym *)symalt );
            }
            /* make sure the alt symbol becomes strong if it is an external
             * v2.11: don't do this for OMF ( maybe neither for COFF/ELF? )
             */
            if ( Options.output_format != OFORMAT_OMF )
                symalt->used = TRUE;
            /* symbol inserted in the "weak external" queue?
             * currently needed for OMF only.
             */
            if ( sym->altname == NULL ) {
                sym->altname = symalt;
#if 0 /* v2.11: removed. Member nextext wasn't free to use */
                DebugMsg1(("HandleAltname: symbol '%s' added to AltQueue\n", sym->name ));
                ((struct dsym *)sym)->nextext = NULL;
                if ( ModuleInfo.g.AltQueue.head == NULL )
                    ModuleInfo.g.AltQueue.head = ModuleInfo.g.AltQueue.tail = (struct dsym *)sym;
                else {
                    ((struct dsym *)ModuleInfo.g.AltQueue.tail)->nextext = (struct dsym *)sym;
                    ModuleInfo.g.AltQueue.tail = (struct dsym *)sym;
                }
#endif
            }
        }
    }
    return( NOT_ERROR );
}
Exemplo n.º 9
0
ret_code CatStrDir( int i, struct asm_tok tokenarray[] )
/******************************************************/
{
    struct asym *sym;
    int count;
    char *p;
    /* struct expr opndx; */

    DebugMsg1(("CatStrDir(%u) enter\n", i ));
    DebugCmd( catstrcnt++ );

#if 0 /* can't happen */
    /* syntax must be <id> CATSTR textitem[,textitem,...] */
    if ( i != 1 ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
    if ( tokenarray[0].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
    }
#endif
    i++; /* go past CATSTR/TEXTEQU */

    /* v2.08: don't copy to temp buffer */
    //*StringBufferEnd = NULLC;
    /* check correct syntax and length of items */
    for ( count = 0; i < Token_Count; ) {
        DebugMsg1(("CatStrDir(%s): item[%u]=%s delim=0x%x\n", tokenarray[0].string_ptr, i, tokenarray[i].string_ptr, tokenarray[i].string_delim ));
        if ( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
            DebugMsg(("CatStrDir: error, not a <>-literal: %s\n", tokenarray[i].tokpos ));
            return( TextItemError( &tokenarray[i] ) );
        }
        /* v2.08: using tokenarray.stringlen is not quite correct, since some chars
         * are stored in 2 bytes (!) */
        if ( ( count + tokenarray[i].stringlen ) >= MAX_LINE_LEN ) {
            DebugMsg(("CatStrDir: error, literal too long: %u + %u >= %u\n", count, tokenarray[i].stringlen, MAX_LINE_LEN ));
            return( EmitError( STRING_OR_TEXT_LITERAL_TOO_LONG ) );
        }
        /* v2.08: don't copy to temp buffer */
        //strcpy( StringBufferEnd + count, tokenarray[i].string_ptr );
        count = count + tokenarray[i].stringlen;
        i++;
        if ( ( tokenarray[i].token != T_COMMA ) &&
            ( tokenarray[i].token != T_FINAL ) ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        i++;
    }

    sym = SymSearch( tokenarray[0].string_ptr );
    if ( sym == NULL ) {
        sym = SymCreate( tokenarray[0].string_ptr );
        DebugMsg1(( "CatStrDir: new symbol %s created\n", sym->name));
    } else if( sym->state == SYM_UNDEFINED ) {
        /* v2.01: symbol has been used already. Using
         * a textmacro before it has been defined is
         * somewhat problematic.
         */
        sym_remove_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );
#if FASTPASS
        SkipSavedState(); /* further passes must be FULL! */
#endif
        EmitWarn( 2, TEXT_MACRO_USED_PRIOR_TO_DEFINITION, sym->name );
    } else if( sym->state != SYM_TMACRO ) {
        /* it is defined as something else, get out */
        DebugMsg(( "CatStrDir(%s) exit, symbol redefinition\n", sym->name));
        return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
    }


    sym->state = SYM_TMACRO;
    sym->isdefined = TRUE;
#if FASTMEM==0
    if ( sym->string_ptr )
        LclFree( sym->string_ptr );
    sym->string_ptr = (char *)LclAlloc( count + 1 );
#else
    /* v2.08: reuse string space if fastmem is on */
    if ( sym->total_size < ( count+1 ) ) {
        LclFree( sym->string_ptr ); /* is a noop if fastmem is on */
        sym->string_ptr = (char *)LclAlloc( count + 1 );
        sym->total_size = count + 1;
    }
#endif
    /* v2.08: don't use temp buffer */
    //memcpy( sym->string_ptr, StringBufferEnd, count + 1 );
    for ( i = 2, p = sym->string_ptr; i < Token_Count; i += 2 ) {
        memcpy( p, tokenarray[i].string_ptr, tokenarray[i].stringlen );
        p += tokenarray[i].stringlen;
    }
    *p = NULLC;
    DebugMsg1(("CatStrDir(%s) (new) value: >%s<\n", sym->name, sym->string_ptr ));

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_TMACRO, 0, sym );

    return( NOT_ERROR );
}
Exemplo n.º 10
0
/* SubStr()
 * defines a text equate.
 * syntax: name SUBSTR <string>, pos [, size]
 */
ret_code SubStrDir( int i, struct asm_tok tokenarray[] )
/******************************************************/
{
    struct asym         *sym;
    char                *name;
    char                *p;
    //char                *newvalue;
    int                 pos;
    int                 size;
    int                 cnt;
    bool                chksize;
    struct expr         opndx;

    DebugMsg1(("SubStrDir enter\n"));
    DebugCmd( substrcnt++ );

    /* at least 5 items are needed
     * 0  1      2      3 4    5   6
     * ID SUBSTR SRC_ID , POS [, LENGTH]
     */
#if 0 /* can't happen */
    if ( i != 1 ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
    if ( tokenarray[0].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
    }
#endif
    name = tokenarray[0].string_ptr;

    i++; /* go past SUBSTR */

    /* third item must be a string */

    if ( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
        DebugMsg(("SubStrDir: error, no text item\n"));
        return( TextItemError( &tokenarray[i] ) );
    }
    p = tokenarray[i].string_ptr;
    cnt = tokenarray[i].stringlen;

    i++;
    DebugMsg1(("SubStrDir(%s): src=>%s<\n", name, p));

    if ( tokenarray[i].token != T_COMMA ) {
        return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
    }
    i++;

    /* get pos, must be a numeric value and > 0 */
    /* v2.11: flag NOUNDEF added - no forward ref possible */

    if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, EXPF_NOUNDEF ) == ERROR ) {
        DebugMsg(("SubStrDir(%s): invalid pos value\n", name));
        return( ERROR );
    }

    /* v2.04: "string" constant allowed as second argument */
    //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
    if ( opndx.kind != EXPR_CONST ) {
        DebugMsg(("SubStrDir(%s): pos value is not a constant\n", name));
        return( EmitError( CONSTANT_EXPECTED ) );
    }

    /* pos is expected to be 1-based */
    pos = opndx.value;
    if ( pos <= 0 ) {
        return( EmitError( POSITIVE_VALUE_EXPECTED ) );
    }
    if ( tokenarray[i].token != T_FINAL ) {
        if ( tokenarray[i].token != T_COMMA ) {
            return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
        }
        i++;
        /* get size, must be a constant */
        /* v2.11: flag NOUNDEF added - no forward ref possible */
        if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, EXPF_NOUNDEF ) == ERROR ) {
            DebugMsg(("SubStrDir(%s): invalid size value\n", name));
            return( ERROR );
        }
        /* v2.04: string constant ok */
        //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
        if ( opndx.kind != EXPR_CONST ) {
            DebugMsg(("SubStrDir(%s): size value is not a constant\n", name));
            return( EmitError( CONSTANT_EXPECTED ) );
        }
        size = opndx.value;
        if ( tokenarray[i].token != T_FINAL ) {
            DebugMsg(("SubStrDir(%s): additional items found\n", name));
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        if ( size < 0 ) {
            return( EmitError( COUNT_MUST_BE_POSITIVE_OR_ZERO ) );
        }
        chksize = TRUE;
    } else {
        size = -1;
        chksize = FALSE;
    }
#if 0
    cnt = pos;
    /* position p to start of substring */
    for ( pos--; pos > 0 && *p ; pos--, p++ )
        if ( *p == '!' && *(p+1) != NULLC )
            p++;
    if ( *p == NULLC ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, cnt ) );
    }
    if ( *p == '!' && *(p+1) != NULLC )
        p++;
    for ( newvalue = p, cnt = size; *p && cnt; cnt--, p++ )
        if ( *p == '!' && *(p+1) != NULLC )
            p++;
    /* v2.04: check added */
    if ( chksize && cnt ) {
        return( EmitError( COUNT_VALUE_TOO_LARGE ) );
    }
    size = p - newvalue;
    p = newvalue;
#else
    if ( pos > cnt ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
    }
    if ( chksize && (pos+size-1) > cnt )  {
        return( EmitError( COUNT_VALUE_TOO_LARGE ) );
    }
    p += pos - 1;
    if ( size == -1 )
        size = cnt - pos + 1;
#endif

    sym = SymSearch( name );

    /* if we've never seen it before, put it in */
    if( sym == NULL ) {
        sym = SymCreate( name );
    } else if( sym->state == SYM_UNDEFINED ) {
        /* it was referenced before being defined. This is
         * a bad idea for preprocessor text items, because it
         * will require a full second pass!
         */
        sym_remove_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );
#if FASTPASS
        SkipSavedState();
        EmitWarn( 2, TEXT_MACRO_USED_PRIOR_TO_DEFINITION, sym->name );
#endif
    } else if( sym->state != SYM_TMACRO ) {
        /* it is defined as something incompatible, get out */
        DebugMsg(( "SubStrDir(%s) error, incompatible type\n", sym->name));
        return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
    }

    sym->state = SYM_TMACRO;
    sym->isdefined = TRUE;

#if FASTMEM==0
    if ( sym->string_ptr )
        LclFree( sym->string_ptr );
    sym->string_ptr = (char *)LclAlloc( size + 1 );
#else
    if ( sym->total_size < ( size + 1 ) ) {
        LclFree( sym->string_ptr );
        sym->string_ptr = LclAlloc ( size + 1 );
        sym->total_size = size + 1;
    }
#endif
    memcpy( sym->string_ptr, p, size );
    *(sym->string_ptr + size) = NULLC;
    DebugMsg1(("SubStrDir(%s): result=>%s<\n", sym->name, sym->string_ptr ));

    LstWrite( LSTTYPE_TMACRO, 0, sym );

    return( NOT_ERROR );
}
Exemplo n.º 11
0
/*
 * used by EQU if the value to be assigned to a symbol is text.
 * - sym:   text macro name, may be NULL
 * - name:  identifer ( if sym == NULL )
 * - value: value of text macro ( original line, BEFORE expansion )
 */
struct asym *SetTextMacro( struct asm_tok tokenarray[], struct asym *sym, const char *name, const char *value )
/*************************************************************************************************************/
{
    int count;
    //char *p;

    DebugCmd( equcnt++ );

    if ( sym == NULL )
        sym = SymCreate( name );
    else if ( sym->state == SYM_UNDEFINED ) {
        sym_remove_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );
#if FASTPASS
        /* the text macro was referenced before being defined.
         * this is valid usage, but it requires a full second pass.
         * just simply deactivate the fastpass feature for this module!
         */
        SkipSavedState();
#endif
        EmitWarn( 2, TEXT_MACRO_USED_PRIOR_TO_DEFINITION, sym->name );
    } else if ( sym->state != SYM_TMACRO ) {
        EmitErr( SYMBOL_REDEFINITION, name );
        return( NULL );
    }

    sym->state = SYM_TMACRO;
    sym->isdefined = TRUE;

    if ( tokenarray[2].token == T_STRING && tokenarray[2].string_delim == '<' ) {

        /* the simplest case: value is a literal. define a text macro! */
        /* just ONE literal is allowed */
        if ( tokenarray[3].token != T_FINAL ) {
            EmitErr( SYNTAX_ERROR_EX, tokenarray[3].tokpos );
            return( NULL );
        }
        value = tokenarray[2].string_ptr;
        count = tokenarray[2].stringlen;
    } else {
        /*
         * the original source is used, since the tokenizer has
         * deleted some information.
         */
        //while ( isspace( *value ) ) value++; /* probably obsolete */
        count = strlen( value );
        /* skip trailing spaces */
        for ( ; count; count-- )
            if ( isspace( *( value + count - 1 ) ) == FALSE )
                break;
    }
#if FASTMEM==0
    if ( sym->string_ptr )
        LclFree( sym->string_ptr );
    sym->string_ptr = (char *)LclAlloc( count + 1 );
#else
    if ( sym->total_size < ( count + 1 ) ) {
        LclFree( sym->string_ptr ); /* is a noop if fastmem is on */
        sym->string_ptr = (char *)LclAlloc( count + 1 );
        sym->total_size = count + 1;
    }
#endif
    memcpy( sym->string_ptr, value, count );
    *(sym->string_ptr + count) = NULLC;

    DebugMsg1(( "SetTextMacro(%s): value is >%s<, exit\n", sym->name, sym->string_ptr ));
    return( sym );
}