示例#1
0
static ret_code SubStrFunc( struct macro_instance *mi, char *buffer, struct asm_tok tokenarray[] )
/************************************************************************************************/
{
    int pos;
    int size;
    char *src = mi->parm_array[0];

    DebugMsg1(("@SubStr( %s, %s, %s)\n",
              src ? src : "",
              mi->parm_array[1] ? mi->parm_array[1] : "",
              mi->parm_array[2] ? mi->parm_array[2] : "" ));

    if ( GetNumber( mi->parm_array[1], &pos, tokenarray ) == ERROR )
        return( ERROR );

    if ( pos <= 0 ) {
        /* Masm doesn't check if index is < 0;
         * might cause an "internal assembler error".
         * v2.09: negative index no longer silently changed to 1.
         */
        if ( pos ) {
            return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
        }
        DebugMsg(( "@SubStr(): index value 0 changed to 1\n", pos ));
        pos = 1;
    }

    size = strlen( src );
    if ( pos > size ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
    }

    size = size - pos + 1;

    if ( mi->parm_array[2] ) {
        int sizereq;
        if ( GetNumber( mi->parm_array[2], &sizereq, tokenarray ) == ERROR )
            return( ERROR );
        if ( sizereq < 0 ) {
            return( EmitError( COUNT_MUST_BE_POSITIVE_OR_ZERO ) );
        }
        if ( sizereq > size ) {
            return( EmitError( COUNT_VALUE_TOO_LARGE ) );
        }
        size = sizereq;
    }
#if 1
    memcpy( buffer, src + pos - 1, size );
    *(buffer+size) = NULLC;
#else
    for( src += pos - 1; size; size-- )
        *buffer++ = *src++;
    *buffer = NULLC;
#endif
    return( NOT_ERROR );
}
示例#2
0
int TextItemError( struct asm_tok *item )
/***************************************/
{
    if ( item->token == T_STRING && *item->string_ptr == '<' ) {
        return( EmitError( MISSING_ANGLE_BRACKET_OR_BRACE_IN_LITERAL ) );
    }
    /* v2.05: better error msg if (text) symbol isn't defined */
    if ( item->token == T_ID ) {
        struct asym *sym = SymSearch( item->string_ptr );
        if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
            return( EmitErr( SYMBOL_NOT_DEFINED, item->string_ptr ) );
        }
    }
    return( EmitError( TEXT_ITEM_REQUIRED ) );
}
示例#3
0
文件: main.c 项目: tonylazarew/jwasm
static void genfailure( int signo )
/*********************************/
{
#if CATCHBREAK
    if (signo != SIGBREAK)
#else
    if (signo != SIGTERM)
#endif
        EmitError( GENERAL_FAILURE );
    close_files();
    exit( EXIT_FAILURE );
}
示例#4
0
ATTR_METHOD_IMPL(CElementParser, OnSizeIs)
{
    TRACE_PARSE_ENTRY();

    CElement *pCurr = GetElement();
    if (pCurr != NULL)
    {
        return pCurr->SetSizeIs(wszValue, cchValue);
    }

    EmitError(IDS_SDL_INTERNAL);
    return E_FAIL;
}
示例#5
0
ATTR_METHOD_IMPL(CWSDLMessageParser, OnName)
{
	TRACE_PARSE_ENTRY();

	CWSDLMessage *pCurr = GetMessage();
	if (pCurr != NULL)
	{
		return pCurr->SetName(wszValue, cchValue);
	}

	EmitError(IDS_SDL_INTERNAL);

	return E_FAIL;
}
示例#6
0
ATTR_METHOD_IMPL(CSchemaParser, OnTargetNamespace)
{
	TRACE_PARSE_ENTRY();

	CSchema * pCurr = GetSchema();
	if (pCurr != NULL)
	{
		return pCurr->SetTargetNamespace(wszValue, cchValue);
	}

	EmitError(IDS_SDL_INTERNAL);

	return E_FAIL;
}
示例#7
0
ATTR_METHOD_IMPL(CWSDLBindingParser, OnType)
{
	TRACE_PARSE_ENTRY();

	CWSDLBinding * pCurr = GetBinding();
	if (pCurr != NULL)
	{
		return pCurr->SetType(wszValue, cchValue);
	}

	EmitError(IDS_SDL_INTERNAL);

	return E_FAIL;
}
示例#8
0
ATTR_METHOD_IMPL(CWSDLOperationParser, OnName)
{
	TRACE_PARSE_ENTRY();

	CWSDLPortTypeOperation * pCurr = GetOperation();
	if (pCurr != NULL)
	{
		return pCurr->SetName(wszValue, cchValue);
	}

	EmitError(IDS_SDL_INTERNAL);

	return E_FAIL;
}
示例#9
0
void CSchemaParser::EmitNamedElementError(const char *szElem)
{
	int nLine = 0;
	int nCol = 0;
	GetLocator()->getLineNumber(&nLine);
	GetLocator()->getColumnNumber(&nCol);
	CSchema *pCurr = GetSchema();
	if (pCurr != NULL)
	{
		EmitFileError(IDS_SDL_SCHEMALEVEL_NAME, 
			(LPCWSTR) pCurr->GetParentDocument()->GetDocumentUri(), 
			nLine, nCol, 0, szElem);
	}
	EmitError(IDS_SDL_INTERNAL);
}
示例#10
0
static void push_seg( struct dsym *seg )
/**************************************/
/* Push a segment into the current segment stack */
{
    //pushitem( &CurrSeg, seg ); /* changed in v1.96 */
    if ( stkindex >= MAX_SEG_NESTING ) {
        EmitError( NESTING_LEVEL_TOO_DEEP );
        return;
    }
    SegStack[stkindex] = CurrSeg;
    stkindex++;
    CurrSeg = seg;
    UpdateCurrSegVars();
    return;
}
示例#11
0
TAG_METHOD_IMPL(CComplexTypeParser, OnChoice)
{
	TRACE_PARSE_ENTRY();

	MarkUnsupported(wszQName, cchQName);
	EmitString(wszNamespaceUri, wszLocalName);

	CComplexType *pCurr = GetComplexType();
	if (pCurr != NULL)
	{
		if (pCurr->GetElementType() == XSD_COMPLEXTYPE)
		{
			pCurr->SetElementType(XSD_UNSUPPORTED);
			return SkipElement();
		}
		return E_FAIL;
	}

	EmitError(IDS_SDL_INTERNAL);
	return E_FAIL;
}
示例#12
0
ret_code SetOfssize( void )
/*************************/
{
    if( CurrSeg == NULL ) {
        ModuleInfo.Ofssize = ModuleInfo.defOfssize;
    } else {
        ModuleInfo.Ofssize = CurrSeg->e.seginfo->Ofssize;
        if( ModuleInfo.Ofssize > USE16 && ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < P_386 ) ) {
            DebugMsg(("SetOfssize, error: CurrSeg=%s, ModuleInfo.Ofssize=%u, curr_cpu=%X, defOfssize=%u\n",
                      CurrSeg->sym.name, ModuleInfo.Ofssize, ModuleInfo.curr_cpu, ModuleInfo.defOfssize ));
            EmitError( INCOMPATIBLE_CPU_MODE_FOR_32BIT_SEGMENT );
            return( ERROR );
        }
    }

    WordSize.value = (2 << ModuleInfo.Ofssize);

#if AMD64_SUPPORT
    Set64Bit( ModuleInfo.Ofssize == USE64 );
#endif

    return( NOT_ERROR );
}
示例#13
0
static direct_idx InsertClassLname( const char *name )
/****************************************************/
{
    struct asym *sym;

    if( strlen( name ) > MAX_LNAME ) {
        EmitError( CLASS_NAME_TOO_LONG );
        return( LNAME_NULL );
    }

    /* the classes aren't inserted into the symbol table
     but they are in a queue */

    sym = SymAlloc( name );
    sym->state = SYM_CLASS_LNAME;
    sym->class_lname_idx = ++LnamesIdx;

    /* put it into the lname table */

    AddLnameData( sym );

    return( LnamesIdx );
}
示例#14
0
文件: main.c 项目: tonylazarew/jwasm
int main( int argc, char **argv )
/*******************************/
{
    char    *pEnv;
    int     numArgs = 0;
    int     numFiles = 0;
    int     rc = 0;
#if WILDCARDS
    long    fh; /* _findfirst/next/close() handle, must be long! */
    struct  _finddata_t finfo;
    char    drv[_MAX_DRIVE];
    char    dir[_MAX_DIR];
    char    fname[_MAX_PATH];
#endif

#if 0 //def DEBUG_OUT    /* DebugMsg() cannot be used that early */
    int i;
    for ( i = 1; i < argc; i++ ) {
        printf("argv[%u]=>%s<\n", i, argv[i] );
    }
#endif

    pEnv = getenv( "JWASM" );
    if ( pEnv == NULL )
        pEnv = "";
    argv[0] = pEnv;

#ifndef DEBUG_OUT
    signal(SIGSEGV, genfailure);
#endif

#if CATCHBREAK
    signal(SIGBREAK, genfailure);
#else
    signal(SIGTERM, genfailure);
#endif

    MsgInit();

    while ( 1 ) {
        if ( ParseCmdline( (const char **)argv, &numArgs ) == NULL )
            break;  /* exit if no source file name supplied */
        numFiles++;
        write_logo();
#if WILDCARDS
        if ((fh = _findfirst( Options.names[ASM], &finfo )) == -1 ) {
            DebugMsg(("main: _findfirst(%s) failed\n", Options.names[ASM] ));
            EmitErr( CANNOT_OPEN_FILE, Options.names[ASM], ErrnoStr() );
            break;
        }
        _splitpath( Options.names[ASM], drv, dir, NULL, NULL );
        DebugMsg(("main: _splitpath(%s): drv=\"%s\" dir=\"%s\"\n", Options.names[ASM], drv, dir ));
        do {
            _makepath( fname, drv, dir, finfo.name, NULL );
            DebugMsg(("main: _makepath(\"%s\", \"%s\", \"%s\")=\"%s\"\n", drv, dir, finfo.name, fname ));
            rc = AssembleModule( fname );  /* assemble 1 module */
        } while ( ( _findnext( fh, &finfo ) != -1 ) );
        _findclose( fh );
#else
        rc = AssembleModule( Options.names[ASM] );
#endif
    };
    CmdlineFini();
    if ( numArgs == 0 ) {
        write_logo();
        printf( MsgGetEx( MSG_USAGE ) );
    } else if ( numFiles == 0 )
        EmitError( NO_FILENAME_SPECIFIED );

    MsgFini();
    return( 1 - rc ); /* zero if no errors */
}
示例#15
0
ret_code ExterndefDirective( int i, struct asm_tok tokenarray[] )
/***************************************************************/
{
    char                *token;
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    struct asym         *sym;
    enum lang_type      langtype;
    char isnew;
    struct qualified_type ti;

    DebugMsg1(("ExterndefDirective(%u) enter\n", i));

    i++; /* skip EXTERNDEF token */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        ti.Ofssize = ModuleInfo.Ofssize;

        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

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

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitError( COLON_EXPECTED ) );
        }
        i++;
        sym = SymSearch( token );

        //typetoken = tokenarray[i].string_ptr;
        ti.mem_type = MT_EMPTY;
        ti.size = 0;
        ti.is_ptr = 0;
        ti.is_far = FALSE;
        ti.ptr_memtype = MT_EMPTY;
        ti.symtype = NULL;
        ti.Ofssize = ModuleInfo.Ofssize;

        if ( tokenarray[i].token == T_ID && ( 0 == _stricmp( tokenarray[i].string_ptr, "ABS" ) ) ) {
            /* v2.07: MT_ABS is obsolete */
            //ti.mem_type = MT_ABS;
            i++;
        } else if ( tokenarray[i].token == T_DIRECTIVE && tokenarray[i].tokval == T_PROTO ) {
            /* dont scan this line further!
             * CreateProto() will either define a SYM_EXTERNAL or fail
             * if there's a syntax error or symbol redefinition.
             */
            sym = CreateProto( i + 1, tokenarray, token, langtype );
#if 0 /* global queue is obsolete */
            if ( sym && sym->isglobal == FALSE ) {
                sym->isglobal = TRUE;
                QAddItem( &ModuleInfo.g.GlobalQueue, sym );
            }
#endif
            return( sym ? NOT_ERROR : ERROR );
        } else if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );
        }

        isnew = FALSE;
        if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
            sym = CreateExternal( sym, token, TRUE );
            isnew = TRUE;
        }

        /* new symbol? */

        if ( isnew ) {
            DebugMsg1(("ExterndefDirective(%s): memtype=%X set, ofssize=%X\n", token, ti.mem_type, ti.Ofssize ));

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                CreateProc( sym, NULL, SYM_EXTERNAL );
                CopyPrototype( (struct dsym *)sym, (struct dsym *)ti.symtype );
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }
            switch ( ti.mem_type ) {
            //case MT_ABS:
            case MT_EMPTY:
                /* v2.04: hack no longer necessary */
                //if ( sym->weak == TRUE )
                //    sym->equate = TRUE; /* allow redefinition by EQU, = */
                break;
            case MT_FAR:
                /* v2.04: don't inherit current segment for FAR externals
                 * if -Zg is set.
                 */
                if ( Options.masm_compat_gencode )
                    break; 
                /* fall through */
            default:
                //SetSymSegOfs( sym );
                sym->segment = &CurrSeg->sym;
            }
            sym->Ofssize = ti.Ofssize;

            if ( ti.is_ptr == 0 && ti.Ofssize != ModuleInfo.Ofssize ) {
                sym->seg_ofssize = ti.Ofssize;
                if ( sym->segment && ((struct dsym *)sym->segment)->e.seginfo->Ofssize != sym->seg_ofssize )
                    sym->segment = NULL;
            }

            sym->mem_type = ti.mem_type;
            sym->is_ptr = ti.is_ptr;
            sym->isfar = ti.is_far;
            sym->ptr_memtype = ti.ptr_memtype;
            if ( ti.mem_type == MT_TYPE )
                sym->type = ti.symtype;
            else
                sym->target_type = ti.symtype;

            /* v2.04: only set language if there was no previous definition */
            SetMangler( sym, langtype, mangle_type );

        } else if ( Parse_Pass == PASS_1 ) {

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }
            /* ensure that the type of the symbol won't change */

            if ( sym->mem_type != ti.mem_type ) {
                /* if the symbol is already defined (as SYM_INTERNAL), Masm
                 won't display an error. The other way, first externdef and
                 then the definition, will make Masm complain, however */
                DebugMsg(("ExterndefDirective: type conflict for %s. mem_types old-new: %X-%X\n", sym->name, sym->mem_type, ti.mem_type));
                EmitWarn( 1, SYMBOL_TYPE_CONFLICT, sym->name );
            } else if ( sym->mem_type == MT_TYPE && sym->type != ti.symtype ) {
                struct asym *sym2 = sym;
                /* skip alias types and compare the base types */
                DebugMsg(("ExterndefDirective(%s): types differ: %X (%s) - %X (%s)\n", sym->name, sym->type, sym->type->name, ti.symtype, ti.symtype->name));
                while ( sym2->type )
                    sym2 = sym2->type;
                while ( ti.symtype->type )
                    ti.symtype = ti.symtype->type;
                if ( sym2 != ti.symtype ) {
                    DebugMsg(("ExterndefDirective(%s): type conflict old-new: %X (%s) - %X (%s)\n", sym->name, sym2, sym2->name, ti.symtype, ti.symtype->name));
                    EmitWarn( 1, SYMBOL_TYPE_CONFLICT, sym->name );
                }
            }

            /* v2.04: emit a - weak - warning if language differs.
             * Masm doesn't warn.
             */
            if ( langtype != LANG_NONE && sym->langtype != langtype )
                EmitWarn( 3, LANGUAGE_ATTRIBUTE_CONFLICT, sym->name );
        }
        sym->isdefined = TRUE;

#if 0
        /* write a global entry if none has been written yet */
        if ( sym->state == SYM_EXTERNAL && sym->weak == FALSE )
            ;/* skip EXTERNDEF if a real EXTERN/COMM was done */
        else if ( sym->isglobal == FALSE ) {
            sym->isglobal = TRUE;
            DebugMsg1(("ExterndefDirective(%s): writing a global entry\n", sym->name));
            QAddItem( &ModuleInfo.g.GlobalQueue, sym );
        }
#else
        if ( sym->state == SYM_INTERNAL && sym->ispublic == FALSE ) {
            sym->ispublic = TRUE;
            AddPublicData( sym );
        }
#endif

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

    } while ( i < Token_Count );

    return( NOT_ERROR );
}
示例#16
0
ret_code AssumeDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
/* Handles ASSUME
 * syntax is :
 * - ASSUME
 * - ASSUME NOTHING
 * - ASSUME segregister : seglocation [, segregister : seglocation ]
 * - ASSUME dataregister : qualified type [, dataregister : qualified type ]
 * - ASSUME register : ERROR | NOTHING | FLAT
 */
{
    int             reg;
    int             j;
    int             size;
    uint_32         flags;
    struct assume_info *info;
    bool            segtable;
    struct qualified_type ti;

    DebugMsg1(( "AssumeDirective enter, pass=%u\n", Parse_Pass+1 ));

    for( i++; i < Token_Count; i++ ) {

        if( ( tokenarray[i].token == T_ID )
            && (0 == _stricmp( tokenarray[i].string_ptr, szNothing )) ) {
            AssumeInit();
            i++;
            break;
        }

        /*---- get the info ptr for the register ----*/

        info = NULL;
        if ( tokenarray[i].token == T_REG ) {
            reg = tokenarray[i].tokval;
            j = GetRegNo( reg );
            flags = GetValueSp( reg );
            if ( flags & OP_SR ) {
                info = &SegAssumeTable[j];
                segtable = TRUE;
            } else if ( flags & OP_R ) {
                info = &StdAssumeTable[j];
                segtable = FALSE;
            }
        }
        if ( info == NULL ) {
            EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
            return( ERROR );
        }

        if( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < GetCpuSp( reg ) ) {
            EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
            return( ERROR );
        }

        i++; /* go past register */

        if( tokenarray[i].token != T_COLON ) {
            EmitError( COLON_EXPECTED );
            return( ERROR );
        }
        i++;

        if( tokenarray[i].token == T_FINAL ) {
            EmitError( SYNTAX_ERROR );
            return( ERROR );
        }

        /* check for ERROR and NOTHING */

        if( 0 == _stricmp( tokenarray[i].string_ptr, szError )) {
            if ( segtable ) {
                info->flat = FALSE;
                info->error = TRUE;
            } else
                info->error |= (( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            info->symbol = NULL;
            i++;
        } else if( 0 == _stricmp( tokenarray[i].string_ptr, szNothing )) {
            if ( segtable ) {
                info->flat = FALSE;
                info->error = FALSE;
            } else
                info->error &= ~(( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            info->symbol = NULL;
            i++;
        } else if ( segtable == FALSE ) {

            /* v2.05: changed to use new GetQualifiedType() function */
            ti.size = 0;
            ti.is_ptr = 0;
            ti.is_far = FALSE;
            ti.mem_type = MT_EMPTY;
            ti.ptr_memtype = MT_EMPTY;
            ti.symtype = NULL;
            ti.Ofssize = ModuleInfo.Ofssize;
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );

            /* v2.04: check size of argument! */
            size = OperandSize( flags, NULL );
            if ( ( ti.is_ptr == 0 && size != ti.size ) ||
                ( ti.is_ptr > 0 && size < CurrWordSize ) ) {
                EmitError( TYPE_IS_WRONG_SIZE_FOR_REGISTER );
                return( ERROR );
            }
            info->error &= ~(( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            if ( stdsym[j] == NULL ) {
                stdsym[j] = CreateTypeSymbol( NULL, "", FALSE );
                stdsym[j]->typekind = TYPE_TYPEDEF;
            }

            stdsym[j]->total_size = ti.size;
            stdsym[j]->mem_type   = ti.mem_type;
            stdsym[j]->is_ptr     = ti.is_ptr;
            stdsym[j]->isfar      = ti.is_far;
            stdsym[j]->Ofssize    = ti.Ofssize;
            stdsym[j]->ptr_memtype = ti.ptr_memtype; /* added v2.05 rc13 */
            if ( ti.mem_type == MT_TYPE )
                stdsym[j]->type = ti.symtype;
            else
                stdsym[j]->target_type = ti.symtype;

            info->symbol = stdsym[j];

        } else { /* segment register */
            struct expr opnd;

            /* v2.08: read expression with standard evaluator */
            if( EvalOperand( &i, tokenarray, Token_Count, &opnd, 0 ) == ERROR )
                return( ERROR );
            switch ( opnd.kind ) {
            case EXPR_ADDR:
                if ( opnd.sym == NULL || opnd.indirect == TRUE || opnd.value ) {
                    EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                    return( ERROR );
                } else if ( opnd.sym->state == SYM_UNDEFINED ) {
                    /* ensure that directive is rerun in pass 2
                     * so an error msg can be emitted.
                     */
                    FStoreLine(0);
                    info->symbol = opnd.sym;
                } else if ( ( opnd.sym->state == SYM_SEG || opnd.sym->state == SYM_GRP ) && opnd.instr == EMPTY ) {
                    info->symbol = opnd.sym;
                } else if ( opnd.instr == T_SEG ) {
                    info->symbol = opnd.sym->segment;
                } else {
                    EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                    return( ERROR );
                }
                info->flat = ( info->symbol == &ModuleInfo.flat_grp->sym );
                break;
            case EXPR_REG:
                if ( GetValueSp( opnd.base_reg->tokval ) & OP_SR ) {
                    info->symbol = SegAssumeTable[ GetRegNo( opnd.base_reg->tokval ) ].symbol;
                    info->flat = SegAssumeTable[ GetRegNo( opnd.base_reg->tokval ) ].flat;
                    break;
                }
            default:
                EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                return( ERROR );
            }
            info->error = FALSE;
        }

        /* comma expected */
        if( i < Token_Count && tokenarray[i].token != T_COMMA )
            break;
    }
    if ( i < Token_Count ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos );
        return( ERROR );
    }
    return( NOT_ERROR );
}
示例#17
0
int sproxy()
{
	unsigned __int64 nFlags;
	BOOL bHasInvalid;
	CStringW wszUrl;
	CStringW wszOut;
	CStringA szNamespace;
	wchar_t **argvW = NULL ;
	int argc = 0 ;

	argvW = CommandLineToArgvW(GetCommandLineW(),&argc);
	if(argvW == NULL)
	{
		EmitError(IDS_SDL_CMDLINE_FAILURE, GetLastError());
		return 1;
	}
	PreProcessCommandLine(argc, argvW, wszOut, szNamespace, &nFlags, &bHasInvalid);
	
	g_bUseWchar_t = ((nFlags & SPROXYFLAG_NOWCHAR_T) == 0);

	if ((nFlags & SPROXYFLAG_NOLOGO) == 0)
	{
		PrintHeader();
	}
	
	if (nFlags & SPROXYFLAG_USAGE)
	{
		PrintUsage(true);
		GlobalFree(argvW);
		return 0;
	}

	ParseCommandLine(argc, argvW, wszUrl, bHasInvalid);

	GlobalFree(argvW);	

	bHasInvalid = FALSE;
	if (wszUrl.IsEmpty())
	{
		EmitCmdLineError(IDS_SDL_MISSING_OPTION, nFlags & SPROXYFLAG_WSDLINPUT ?"<wsdl_location>":"<discomap_location>");
		bHasInvalid = TRUE;
	}

	if (bHasInvalid != FALSE)
	{
		printf("\r\n");
		PrintUsage();
		return 1;
	}

	if (nFlags & SPROXYFLAG_NOWARN)
	{
		SetEmitWarnings(false);
	}

	CHeapPtr<char> spSzNamespace;

	if (szNamespace && *szNamespace)
	{
		if (FAILED(CreateSafeCppName(&spSzNamespace, szNamespace)))
		{
			EmitErrorHr(E_OUTOFMEMORY);
			return 1;
		}
	}

	CoInitialize(NULL);
	HRESULT hr = S_OK;
	{
		CAutoPtr<CDiscoMapParser> dmParser;
		if(!(nFlags & SPROXYFLAG_WSDLINPUT))
		{
			CComPtr<ISAXXMLReader> spDMReader;
			hr = CoCreateInstance(__uuidof(SAXXMLReader30), NULL, CLSCTX_ALL,
				__uuidof(ISAXXMLReader), (void **)&spDMReader);

			if (FAILED(hr))
			{
				ATLTRACE( _T("CoCreateInstance failed!\n") );
				return 1;
			}

			dmParser.Attach(new CDiscoMapParser(spDMReader, NULL, 0));
			if(dmParser == NULL)
			{
				ATLTRACE(_T("Failed to create Discomap Parser : out of memory!\n"));
				return 1;
			}
			dmParser->SetDynamicAlloc(FALSE);
			hr = spDMReader->putContentHandler( dmParser );
			if (FAILED(hr))
			{
				ATLTRACE( _T("putContentHandler failed!\n") );
				return 1;
			}
			
			CErrorHandler errDM;
			errDM.SetLocation(wszUrl);

			hr = spDMReader->putErrorHandler( &errDM);
			if (FAILED(hr))
			{
				ATLTRACE( _T("putErrorHandler failed!\n") );
				return 1;
			}

			g_pDMDoc = dmParser->GetDiscoMapDocument();
			if (g_pDMDoc == NULL)
			{
				ATLTRACE( _T("failed to create document: out of memory!\n") );
				return 1;
			}
			

			hr = g_pDMDoc->SetDocumentUri( wszUrl, wszUrl.GetLength());

			if (FAILED(hr))
			{
				ATLTRACE( _T("failed to set document uri: out of memory!\n") );
				return 1;
			}

			g_wszFile = wszUrl;

			hr = spDMReader->parseURL( wszUrl );
			if (FAILED(hr))
			{
				ATLTRACE( _T("parseURL failed!\n") );
				if ((hr == E_SAX_LOADFAILED) || 
					(hr == E_SAX_FILENOTFOUND) ||
					(hr == E_SAX_PATHNOTFOUND) ||
					(hr == E_SAX_ACCESSDENIED))
				{
					EmitError(IDS_SDL_FAILED_DM_OPEN, wszUrl);
				}
				EmitError(IDS_SDL_PROCESS_DM_FAILURE, wszUrl);
				return 1;
			}
		}

		if(nFlags & SPROXYFLAG_WSDLINPUT)
			g_wszFile = wszUrl;
		else
			g_wszFile = g_pDMDoc->GetWSDLFile();

		CComPtr<ISAXXMLReader> spReader;
		hr = CoCreateInstance(__uuidof(SAXXMLReader30), NULL, CLSCTX_ALL,
			__uuidof(ISAXXMLReader), (void **)&spReader);

		if (FAILED(hr))
		{
			ATLTRACE( _T("CoCreateInstance failed!\n") );
			return 1;
		}

		CWSDLParser parser(spReader, NULL, 0);
		parser.SetDynamicAlloc(FALSE);
		hr = spReader->putContentHandler( &parser );
		if (FAILED(hr))
		{
			ATLTRACE( _T("putContentHandler failed!\n") );
			return 1;
		}

		CErrorHandler err;
		err.SetLocation(g_wszFile);

		hr = spReader->putErrorHandler( &err );
		if (FAILED(hr))
		{
			ATLTRACE( _T("putErrorHandler failed!\n") );
			return 1;
		}

		CWSDLDocument * pDoc = parser.GetWSDLDocument();
		if (pDoc == NULL)
		{
			ATLTRACE( _T("failed to create document: out of memory!\n") );
			return 1;
		}
		
		hr = pDoc->SetDocumentUri( g_wszFile, g_wszFile.GetLength());
		if (FAILED(hr))
		{
			ATLTRACE( _T("failed to set document uri: out of memory!\n") );
			return 1;
		}

		wchar_t wszTmp[ATL_URL_MAX_URL_LENGTH];
		if(g_wszFile.Find(L"://") != -1 && ((g_wszFile.Left(5)).MakeLower() != L"file:") )
		{
			// The URL needs to be escaped only if it's not a local file
			if(AtlEscapeUrl(g_wszFile,wszTmp,0,ATL_URL_MAX_URL_LENGTH-1,ATL_URL_BROWSER_MODE) == FALSE)
			{
				ATLTRACE( _T("failed to escape uri!\n") );
				return 1;
			}

			hr = spReader->parseURL( wszTmp );
		}
		else
		{
			hr = spReader->parseURL( g_wszFile );
		}
		
		if (FAILED(hr))
		{
			ATLTRACE( _T("parseURL failed!\n") );
			if ((hr == E_SAX_LOADFAILED) || 
			    (hr == E_SAX_FILENOTFOUND) ||
			    (hr == E_SAX_PATHNOTFOUND) ||
			    (hr == E_SAX_ACCESSDENIED))
			{
				EmitError(IDS_SDL_FAILED_WSDL_OPEN, g_wszFile);
			}
			EmitError(IDS_SDL_PROCESS_FAILURE, g_wszFile);
			return 1;
		}

		CCodeTypeBuilder builder;
		CCodeProxy proxy;
		hr = builder.Initialize(parser.GetWSDLDocument(), &proxy);

		if (FAILED(hr))
		{
			ATLTRACE( _T("builder.Initialize failed!\n") );
			return PrintGenerateFailure(wszOut);
		}

		hr = builder.Build();
		if (FAILED(hr))
		{
			ATLTRACE( _T("builder.Build failed!\n") );
			return PrintGenerateFailure(wszOut);
		}

		if (wszOut.IsEmpty())
		{
			wszOut.Preallocate(proxy.GetServiceName().GetLength()+4);
			wszOut = (LPCSTR)proxy.GetServiceName();
			wszOut.Append(L".h", 2);
		}

		Emit(IDS_SDL_SUCCESS, wszOut);
		CComObjectStack<CCppCodeGenerator> gen;
		hr = gen.Generate(wszOut, &proxy, 
				(nFlags & SPROXYFLAG_NOPRAGMA) ? false : true, 
				(nFlags & SPROXYFLAG_NOCLOBBER) ? true : false,
				(nFlags & SPROXYFLAG_NONAMESPACE) ? false : true,
				(nFlags & SPROXYFLAG_NOPROXY) ? false : true,
				spSzNamespace ? spSzNamespace : (szNamespace.IsEmpty() ? 0 : LPCSTR(szNamespace)));
		if (FAILED(hr))
		{
			ATLTRACE( _T("gen.Generate failed!\n") );
			return PrintGenerateFailure(wszOut);
		}
	}
	CoUninitialize();

	return 0;
}
示例#18
0
ret_code SegmentDir( int i, struct asm_tok tokenarray[] )
/*******************************************************/
{
    char                is_old;
    char                *token;
    int                 typeidx;
    const struct typeinfo *type;          /* type of option */
    int                 temp;
    int                 temp2;
    uint                initstate = 0;  /* flags for attribute initialization */
    unsigned char       oldreadonly;    /* readonly value of a defined segment */
    //unsigned char       oldsegtype;
    unsigned char       oldOfssize;
    char                oldalign;
    char                oldcombine;
    uint                oldclassidx;
    uint_8              oldcharacteristics;
    struct dsym         *dir;
    char                *name;
    struct asym         *sym;
    struct expr         opndx;

    if ( Parse_Pass != PASS_1 )
        return( SetCurrSeg( i, tokenarray ) );

    if( i != 1 ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }

    name = tokenarray[0].string_ptr;

    DebugMsg1(("SegmentDir(%s) enter: ModuleInfo.Ofssize=%u, num_seg=%u\n", name, ModuleInfo.Ofssize, ModuleInfo.g.num_segs ));

    /* See if the segment is already defined */
    sym = SymSearch( name );
    if( sym == NULL || sym->state == SYM_UNDEFINED ) {
        /* segment is not defined (yet) */
        sym = (struct asym *)CreateSegment( (struct dsym *)sym, name, TRUE );
        sym->list = TRUE; /* always list segments */
        dir = (struct dsym *)sym;
        dir->e.seginfo->seg_idx = ++ModuleInfo.g.num_segs;
        is_old = FALSE;
        /*
         * initialize segment with values from the one without suffix
         */
#if COFF_SUPPORT || ELF_SUPPORT
        if (Options.output_format == OFORMAT_COFF
#if ELF_SUPPORT
            || Options.output_format == OFORMAT_ELF
#endif
           ) {
            char *p;
            if ( p = strchr(sym->name, '$') ) {
                char buffer[MAX_ID_LEN+1];
                struct dsym *dir2;
                memcpy(buffer, sym->name, p - sym->name);
                buffer[p - sym->name] = NULLC;
                if ((dir2 = (struct dsym *)SymSearch(buffer)) && dir2->sym.state == SYM_SEG) {
                    dir->e.seginfo->readonly = dir2->e.seginfo->readonly;
                    dir->e.seginfo->segtype  = dir2->e.seginfo->segtype;
                    dir->e.seginfo->Ofssize  = dir2->e.seginfo->Ofssize;
                    dir->e.seginfo->alignment= dir2->e.seginfo->alignment;
                    dir->e.seginfo->characteristics = dir2->e.seginfo->characteristics;
                    dir->e.seginfo->combine         = dir2->e.seginfo->combine;
                    dir->e.seginfo->class_name_idx  = dir2->e.seginfo->class_name_idx;
                }
            }
        }
#endif
    } else if ( sym->state == SYM_SEG ) {
        /* segment already defined */
        dir = (struct dsym *)sym;
        is_old = TRUE;
        oldreadonly = dir->e.seginfo->readonly;
        //oldsegtype  = dir->e.seginfo->segtype;
        oldOfssize  = dir->e.seginfo->Ofssize;
        oldalign    = dir->e.seginfo->alignment;
        oldcharacteristics = dir->e.seginfo->characteristics;
        oldcombine  = dir->e.seginfo->combine;
        oldclassidx = dir->e.seginfo->class_name_idx;
        if( dir->e.seginfo->lname_idx == 0 ) {
            /* segment was mentioned in a group statement, but not really set up */
            is_old = FALSE;
            /* the segment list is to be sorted.
             * So unlink the segment and add it at the end.
             */
            UnlinkSeg( dir );
            dir->e.seginfo->seg_idx = ++ModuleInfo.g.num_segs;
            dir->next = NULL;
            if ( SymTables[TAB_SEG].head == NULL )
                SymTables[TAB_SEG].head = SymTables[TAB_SEG].tail = dir;
            else {
                SymTables[TAB_SEG].tail->next = dir;
                SymTables[TAB_SEG].tail = dir;
            }
        }
    } else {
        /* symbol is different kind, error */
        DebugMsg(("SegmentDir(%s): symbol redefinition\n", name ));
        EmitErr( SYMBOL_REDEFINITION, name );
        return( ERROR );
    }

    i++; /* go past SEGMENT */

    for( ; i < Token_Count; i++ ) {
        token = tokenarray[i].string_ptr;
        DebugMsg1(("SegmentDir(%s): i=%u, string=%s token=%X\n", name, i, token, tokenarray[i].token ));
        if( tokenarray[i].token == T_STRING ) {

            /* the class name - the only token which is of type STRING */
            /* string must be delimited by [double]quotes */
            if ( tokenarray[i].string_delim != '"' &&
                tokenarray[i].string_delim != '\'' ) {
                EmitErr( SYNTAX_ERROR_EX, token );
                continue;
            }
            /* remove the quote delimiters */
            token++;
            *(token+tokenarray[i].stringlen) = NULLC;

            SetSegmentClass( &dir->sym, token );

            DebugMsg1(("SegmentDir(%s): class found: %s\n", name, token ));
            continue;
        }

        /* check the rest of segment attributes.
         */
        typeidx = FindToken( token, SegAttrToken, sizeof( SegAttrToken )/sizeof( SegAttrToken[0] ) );
        if( typeidx < 0 ) {
            EmitErr( UNKNOWN_SEGMENT_ATTRIBUTE, token );
            continue;
        }
        type = &SegAttrValue[typeidx];

        /* initstate is used to check if any field is already
         * initialized
         */
        if( initstate & INIT_EXCL_MASK & type->init ) {
            EmitErr( SEGMENT_ATTRIBUTE_DEFINED_ALREADY, token );
            continue;
        } else {
            initstate |= type->init; /* mark it initialized */
        }

        switch ( type->init ) {
        case INIT_ATTR:
            dir->e.seginfo->readonly = TRUE;
            break;
        case INIT_ALIGN:
            DebugMsg1(("SegmentDir(%s): align attribute found\n", name ));
            dir->e.seginfo->alignment = type->value;
            break;
        case INIT_ALIGN_PARAM:
            DebugMsg1(("SegmentDir(%s): ALIGN() found\n", name ));
            if ( Options.output_format == OFORMAT_OMF ) {
                EmitErr( NOT_SUPPORTED_WITH_OMF_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
                break;
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            if ( opndx.kind != EXPR_CONST ) {
                EmitError( CONSTANT_EXPECTED );
                break;
            }
            /*
             COFF allows alignment values
             1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192
             */
            for( temp = 1, temp2 = 0; temp < opndx.value && temp < 8192 ; temp <<= 1, temp2++ );
            if( temp != opndx.value ) {
                EmitError( POWER_OF_2 );
            }
            dir->e.seginfo->alignment = temp2;
            break;
        case INIT_COMBINE:
            DebugMsg1(("SegmentDir(%s): combine attribute found\n", name ));
            dir->e.seginfo->combine = type->value;
            break;
        case INIT_COMBINE_AT:
            DebugMsg1(("SegmentDir(%s): AT found\n", name ));
            dir->e.seginfo->combine = type->value;
            /* v2.05: always use MAX_SEGALIGNMENT */
            //dir->e.seginfo->alignment = -1;
            dir->e.seginfo->alignment = MAX_SEGALIGNMENT;
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) != ERROR ) {
                if ( opndx.kind == EXPR_CONST ) {
                    dir->e.seginfo->abs_frame = opndx.value;
                    dir->e.seginfo->abs_offset = 0;
                } else {
                    EmitError( CONSTANT_EXPECTED );
                }
            }
            break;
#if COMDATSUPP
        case INIT_COMBINE_COMDAT:
            DebugMsg1(("SegmentDir(%s): COMDAT found\n", name ));
            if ( Options.output_format != OFORMAT_COFF ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
                break;
            if ( opndx.kind != EXPR_CONST ) {
                EmitError( CONSTANT_EXPECTED );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            if ( opndx.value < 1 || opndx.value > 6 ) {
                EmitErr( VALUE_NOT_WITHIN_ALLOWED_RANGE, "1-6" );
            } else {
                /* if value is IMAGE_COMDAT_SELECT_ASSOCIATIVE,
                 * get the associated segment name argument.
                 */
                if ( opndx.value == 5 ) {
                    struct asym *sym2;
                    if ( tokenarray[i].token != T_COMMA ) {
                        EmitError( EXPECTING_COMMA );
                        i = Token_Count; /* stop further parsing of this line */
                        break;
                    }
                    i++;
                    if ( tokenarray[i].token != T_ID ) {
                        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
                        i = Token_Count; /* stop further parsing of this line */
                        break;
                    }
                    /* associated segment must be COMDAT, but not associative */
                    sym2 = SymSearch( tokenarray[i].string_ptr );
                    if ( sym2 == NULL ||
                        sym2->state != SYM_SEG ||
                        ((struct dsym *)sym2)->e.seginfo->comdat_selection == 0 ||
                        ((struct dsym *)sym2)->e.seginfo->comdat_selection == 5 )
                        EmitErr( INVALID_ASSOCIATED_SEGMENT, tokenarray[i].string_ptr );
                    else
                        dir->e.seginfo->comdat_number = ((struct dsym *)sym2)->e.seginfo->seg_idx;
                    i++;
                }
            }
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            dir->e.seginfo->comdat_selection = opndx.value;
            dir->e.seginfo->combine = type->value;
            break;
#endif
        case INIT_OFSSIZE:
        case INIT_OFSSIZE_FLAT:
            /* v2.07: check for compatible cpu mode */
            if ( type->value == USE32 && ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < P_386 )
#if AMD64_SUPPORT
                || type->value == USE64 && ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < P_64 )
#endif
               ) {
                EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
                break;
            }
            if ( type->init == INIT_OFSSIZE_FLAT ) {
                DefineFlatGroup();
#if AMD64_SUPPORT
                dir->e.seginfo->Ofssize = ModuleInfo.defOfssize;
#else
                dir->e.seginfo->Ofssize = USE32;
#endif
                /* put the segment into the FLAT group.
                 * this is not quite Masm-compatible, because trying to put
                 * the segment into another group will cause an error.
                 */
                dir->e.seginfo->group = &ModuleInfo.flat_grp->sym;
            } else
                dir->e.seginfo->Ofssize = type->value;
            break;
#if COFF_SUPPORT || ELF_SUPPORT
        case INIT_CHAR_INFO:
            dir->e.seginfo->info = TRUE;
            break;
        case INIT_CHAR:
            DebugMsg1(("SegmentDir(%s): characteristics found\n", name ));
            ; /* characteristics are restricted to COFF/ELF */
            if ( Options.output_format == OFORMAT_OMF || Options.output_format == OFORMAT_BIN ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
            } else
                dir->e.seginfo->characteristics |= type->value;
            break;
        case INIT_ALIAS:
            DebugMsg1(("SegmentDir(%s): ALIAS found\n", name ));
            if ( Options.output_format != OFORMAT_COFF &&
                Options.output_format != OFORMAT_ELF ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( tokenarray[i].token != T_STRING ||
                ( tokenarray[i].string_delim != '"' &&
                tokenarray[i].string_delim != '\'' ) ) {
                EmitErr( SYNTAX_ERROR_EX, token );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            temp = i;
            i++;
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            dir->e.seginfo->aliasname = LclAlloc( tokenarray[temp].stringlen );
            memcpy( dir->e.seginfo->aliasname, tokenarray[temp].string_ptr+1, tokenarray[temp].stringlen );
            *(dir->e.seginfo->aliasname+tokenarray[temp].stringlen) = NULLC;
            break;
#endif
#ifdef DEBUG_OUT
        default: /* shouldn't happen */
            myassert( 0 );
            break;
#endif
        }
    } /* end for */

    /* make a guess about the segment's type */
    if( dir->e.seginfo->segtype != SEGTYPE_CODE ) {
        enum seg_type res;

        token = GetLname( dir->e.seginfo->class_name_idx );
        res = TypeFromClassName( dir, token );
        if( res != SEGTYPE_UNDEF ) {
            dir->e.seginfo->segtype = res;
        }
#if 0 /* v2.03: removed */
        else {
            res = TypeFromSegmentName( name );
            dir->e.seginfo->segtype = res;
        }
#endif
    }

    if( is_old ) {
        int txt = 0;

        /* Check if new definition is different from previous one */

        // oldobj = dir->e.seginfo->segrec;
        if(  oldreadonly      != dir->e.seginfo->readonly )
            txt = TXT_READONLY;
        else if ( oldalign    != dir->e.seginfo->alignment )
            txt = TXT_ALIGNMENT;
        else if ( oldcombine  != dir->e.seginfo->combine )
            txt = TXT_COMBINE;
        else if ( oldOfssize  != dir->e.seginfo->Ofssize )
            txt = TXT_SEG_WORD_SIZE;
        else if ( oldclassidx != dir->e.seginfo->class_name_idx )
            txt = TXT_CLASS; /* Masm warns only! */
        else if ( oldcharacteristics != dir->e.seginfo->characteristics )
            txt = TXT_CHARACTERISTICS;

        if ( txt ) {
            EmitErr( SEGDEF_CHANGED, dir->sym.name, MsgGetEx( txt ) );
            //return( ERROR ); /* v2: display error, but continue */
        }

    } else {
        /* A new definition */

        sym = &dir->sym;
        sym->isdefined = TRUE;
        sym->segment = sym;
        sym->offset = 0;
        if( dir->e.seginfo->lname_idx == 0 ) {
            dir->e.seginfo->lname_idx = ++LnamesIdx;
            AddLnameData( sym );
        }

    }
    push_seg( dir ); /* set CurrSeg */

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_LABEL, 0, NULL );

    return( SetOfssize() );
}
示例#19
0
ret_code GrpDir( int i, struct asm_tok tokenarray[] )
/***************************************************/
{
    char        *name;
    struct dsym *grp;
    struct dsym *seg;

    /* GROUP directive must be at pos 1, needs a name at pos 0 */
    if( i != 1 ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }
#if COFF_SUPPORT || ELF_SUPPORT
    /* GROUP valid for OMF + BIN only */
    if ( Options.output_format == OFORMAT_COFF
#if ELF_SUPPORT
        || Options.output_format == OFORMAT_ELF
#endif
       ) {
        EmitError( GROUP_DIRECTIVE_INVALID_FOR_COFF );
        return( ERROR );
    }
#endif
    grp = CreateGroup( tokenarray[0].string_ptr );
    if( grp == NULL )
        return( ERROR );

    i++; /* go past GROUP */

    do {

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

        seg = (struct dsym *)SymSearch( name );
        if ( Parse_Pass == PASS_1 ) {
            if( seg == NULL || seg->sym.state == SYM_UNDEFINED ) {
                seg = CreateSegment( seg, name, TRUE );
                /* inherit the offset magnitude from the group */
                if ( grp->e.grpinfo->seglist )
                    seg->e.seginfo->Ofssize = grp->sym.Ofssize;
            } else if( seg->sym.state != SYM_SEG ) {
                EmitErr( SEGMENT_EXPECTED, name );
                return( ERROR );
            } else if( seg->e.seginfo->group != NULL &&
                       seg->e.seginfo->group != &grp->sym ) {
                /* segment is in another group */
                DebugMsg(("GrpDir: segment >%s< is in group >%s< already\n", name, seg->e.seginfo->group->name));
                EmitErr( SEGMENT_IN_ANOTHER_GROUP, name );
                return( ERROR );
            }
            /* the first segment will define the group's word size */
            if( grp->e.grpinfo->seglist == NULL ) {
                grp->sym.Ofssize = seg->e.seginfo->Ofssize;
            } else if ( grp->sym.Ofssize != seg->e.seginfo->Ofssize ) {
                EmitErr( GROUP_SEGMENT_SIZE_CONFLICT, grp->sym.name, seg->sym.name );
                return( ERROR );
            }
        } else {
            /* v2.04: don't check the "defined" flag. It's for IFDEF only! */
            //if( seg == NULL || seg->sym.state != SYM_SEG || seg->sym.defined == FALSE ) {
            /* v2.07: check the "segment" field instead of "defined" flag! */
            //if( seg == NULL || seg->sym.state != SYM_SEG ) {
            if( seg == NULL || seg->sym.state != SYM_SEG || seg->sym.segment == NULL ) {
                EmitErr( SEG_NOT_DEFINED, name );
                return( ERROR );
            }
        }

        /* insert segment in group if it's not there already */
        if ( seg->e.seginfo->group == NULL ) {
            struct seg_item    *si;

            /* set the segment's grp */
            seg->e.seginfo->group = &grp->sym;

            si = LclAlloc( sizeof( struct seg_item ) );
            si->seg = seg;
            si->next = NULL;
            grp->e.grpinfo->numseg++;

            /* insert the segment at the end of linked list */
            if( grp->e.grpinfo->seglist == NULL ) {
                grp->e.grpinfo->seglist = si;
            } else {
                struct seg_item *curr;
                curr = grp->e.grpinfo->seglist;
                while( curr->next != NULL ) {
                    curr = curr->next;
                }
                curr->next = si;
            }
        }

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

    } while ( i < Token_Count );

    return( NOT_ERROR );
}
示例#20
0
文件: cpumodel.c 项目: JWasm/JWasm
/* handle .model directive
 * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>]
 * sets fields
 * - ModuleInfo.model
 * - ModuleInfo.language
 * - ModuleInfo.distance
 * - ModuleInfo.ostype
 * if model is FLAT, defines FLAT pseudo-group
 * set default segment names for code and data
 */
ret_code ModelDirective( int i, struct asm_tok tokenarray[] )
/***********************************************************/
{
    enum model_type model;
    enum lang_type language;
    enum dist_type distance;
    enum os_type ostype;
    int index;
    uint_8 init;
    uint_8 initv;

    DebugMsg1(("ModelDirective enter\n"));
    /* v2.03: it may occur that "code" is defined BEFORE the MODEL
     * directive (i.e. DB directives in AT-segments). For FASTPASS,
     * this may have caused errors because contents of the ModuleInfo
     * structure was saved before the .MODEL directive.
     */
    //if( Parse_Pass != PASS_1 ) {
    if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) {
        /* just set the model with SetModel() if pass is != 1.
         * This won't set the language ( which can be modified by
         * OPTION LANGUAGE directive ), but the language in ModuleInfo
         * isn't needed anymore once pass one is done.
         */
        SetModel();
        return( NOT_ERROR );
    }

    i++;
    if ( tokenarray[i].token == T_FINAL ) {
        return( EmitError( EXPECTED_MEMORY_MODEL ) );
    }
    /* get the model argument */
    index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) );
    if( index >= 0 ) {
        if( ModuleInfo.model != MODEL_NONE ) {
            //if ( Parse_Pass == PASS_1 ) /* not needed, this code runs in pass one only */
            EmitWarn( 2, MODEL_DECLARED_ALREADY );
        }
        model = index + 1; /* model is one-base ( 0 is MODEL_NONE ) */
        i++;
    } else {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    /* get the optional arguments: language, stack distance, os */
    init = 0;
    while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) {
        i++;
        if ( tokenarray[i].token != T_COMMA ) {
            if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) {
                initv = INIT_LANG;
            } else {
                index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) );
                if ( index < 0 )
                    break;
                initv = ModelAttrValue[index].init;
                switch ( initv ) {
                case INIT_STACK:
                    if ( model == MODEL_FLAT ) {
                        return( EmitError( INVALID_MODEL_PARAM_FOR_FLAT ) );
                    }
                    distance = ModelAttrValue[index].value;
                    break;
                case INIT_OS:
                    ostype = ModelAttrValue[index].value;
                    break;
                }
                i++;
            }
            /* attribute set already? */
            if ( initv & init ) {
                i--;
                break;
            }
            init |= initv;
        }
    }
    /* everything parsed successfully? */
    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
    }

    if ( model == MODEL_FLAT ) {
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) {
            return( EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE ) );
        }
#if AMD64_SUPPORT
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) >= P_64 ) /* cpu 64-bit? */
            switch ( Options.output_format ) {
            case OFORMAT_COFF: ModuleInfo.fmtopt = &coff64_fmtopt; break;
            case OFORMAT_ELF:  ModuleInfo.fmtopt = &elf64_fmtopt;  break;
            };
#endif
        /* v2.11: define FLAT symbol is to early here, because defOfssize isn't set yet */
        //DefineFlatGroup();
    }

    ModuleInfo.model = model;
    if ( init & INIT_LANG )
        ModuleInfo.langtype = language;
    if ( init & INIT_STACK )
        ModuleInfo.distance = distance;
    if ( init & INIT_OS )
        ModuleInfo.ostype = ostype;

    SetModelDefaultSegNames();
    SetModel();

    return( NOT_ERROR );
}
示例#21
0
文件: loop.c 项目: JWasm/JWasm
ret_code LoopDirective( int i, struct asm_tok tokenarray[] )
/**********************************************************/
{
    int directive = tokenarray[i].tokval;
    int arg_loc;
    int len;
    //int skipcomma;
    char *parmstring;
    char *ptr;
    struct dsym *macro;
    bool is_exitm;
    struct expr opnd;
    struct macro_info macinfo;
    struct dsym tmpmacro;
#ifdef DEBUG_OUT
    uint_32 count = 0;
#endif
    /* v2.08: use myalloca() to get space to store the argument */
    //char line[MAX_LINE_LEN];
    char buffer[4];

    DebugMsg1(("LoopDirective(%s) enter\n", GetResWName( directive, NULL ) ));

    i++; /* skip directive */
    if ( ModuleInfo.list == TRUE ) LstWriteSrcLine();

    switch ( directive ) {
    case T_WHILE:
        arg_loc = i;
    /* no break */
    case T_REPT:
    case T_REPEAT:
        /* the expression is "critical", that is, no forward
         * referenced symbols may be used here!
         */
        if ( EvalOperand( &i, tokenarray, Token_Count, &opnd, EXPF_NOUNDEF ) == ERROR ) {
            opnd.value = 0;
            i = Token_Count;
        } else if ( opnd.kind != EXPR_CONST ) { /* syntax <REPEAT|WHILE 'A'> is valid! */
            DebugMsg(( "LoopDirective(%s): invalid argument type %u\n", GetResWName( directive, NULL ), opnd.kind ));
            EmitError( CONSTANT_EXPECTED );
            opnd.value = 0;
        } else if( tokenarray[i].token != T_FINAL ) {
            EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos );
            /* v2.09: don't exit, the macro lines must be read first. */
            //return( ERROR );
            opnd.value = 0;
        }
        break;
    default: /* FOR, FORC, IRP, IRPC */
        /* get the formal parameter and the argument list */
        /* the format parameter will become a macro parameter, so it can
         * be a simple T_ID, but also an instruction or something else.
         * v2.02: And it can begin with a '.'!
         */
        if( tokenarray[i].token == T_FINAL ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i-1].tokpos ) );
        }
        /* v2.02: allow parameter name to begin with a '.' */
        //c = *tokenarray[i].string_ptr;
        //if( ( is_valid_id_char(c) == FALSE ) || ( isdigit(c) == TRUE ) ) {
        if( is_valid_id_first_char( *tokenarray[i].string_ptr ) == FALSE ) {
            DebugMsg(( "LoopDirective(FOR/FORC): token %s is not a valid parameter name\n", tokenarray[i].string_ptr ));
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
        }
        arg_loc = i;
        i++;

        if( directive == T_FORC || directive == T_IRPC ) {
            if( tokenarray[i].token != T_COMMA ) {
                return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
            }
            i++;
            /* FORC/IRPC accepts anything as "argument list", even nothing! */
            if( tokenarray[i].token == T_STRING && tokenarray[i].string_delim == '<' ) {
                len = tokenarray[i+1].tokpos - (tokenarray[i].tokpos+1);
                parmstring = myalloca( len );
                //GetLiteralValue( parmstring, tokenarray[i].string_ptr );
                memcpy( parmstring, tokenarray[i].tokpos+1, len );
                while( *(parmstring+len-1) != '>' ) len--;
                *(parmstring+len-1) = NULLC;
                /* v2.02: if there's additional stuff behind the <> literal,
                 * it's an error!
                 */
                if ( tokenarray[i+1].token != T_FINAL )
                    EmitErr( SYNTAX_ERROR_EX, tokenarray[i+1].tokpos );
            } else {
                char *ptr2;
                ptr = tokenarray[i].tokpos;
                ptr2 = ptr;
                /* this is what Masm does: use the string until a space
                 * is detected. Anything beyond the space is ignored.
                 */
                while ( *ptr2 && ( isspace( *ptr2 ) == FALSE ) )
                    ptr2++;
                len = ptr2 - ptr;
                parmstring = myalloca( len + 1 );
                memcpy( parmstring, ptr, len );
                *(parmstring+len) = NULLC;
            }
        } else {
            /* for FOR/IRP, skip everything between the name and the comma!
             * these items will be stored as (first) macro parameter.
             * for example, valid syntax is:
             * FOR xxx,<a, ...>
             * FOR xxx:REQ,<a, ...>
             */
            while ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA )
                i++;
            if( tokenarray[i].token != T_COMMA ) {
                return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
            }
            i++;
            /* FOR/IRP accepts a literal enclosed in <> only */
            if( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
            }
            /* v2.03: also ensure that the literal is the last item */
            if( tokenarray[i+1].token != T_FINAL ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i+1].tokpos ) );
            }
            /* v2.08: use myalloca() instead of a fixed-length buffer.
             * the loop directives are often nested, they call RunMacro()
             * and hence should be careful with stack usage because of JWASMR!
             */
            //parmstring = myalloca( tokenarray[i].stringlen + 1 );
            /* v2.0: use GetLiteralValue() instead of memcpy!!! */
            //memcpy( line, tokenarray[i].string_ptr, tokenarray[i].stringlen + 1 );
            //GetLiteralValue( parmstring, tokenarray[i].string_ptr );
            parmstring = tokenarray[i].string_ptr;
            DebugMsg1(("LoopDirective(FOR): param string >%s<\n", parmstring));
        }
        /* to run StoreMacro(), tokenarray must be setup correctly. */
        /* clear contents beginning with the comma! */
        i--;
        tokenarray[i].token = T_FINAL;
        Token_Count = i;
        i = arg_loc;
    }

    /* now make a temporary macro */
    macro = &tmpmacro;
    memset( &tmpmacro, 0, sizeof(tmpmacro) );
    tmpmacro.sym.name = "";
    tmpmacro.e.macroinfo = &macinfo;
    memset( &macinfo, 0, sizeof(macinfo) );
    macinfo.srcfile = get_curr_srcfile();

#if 0 //DEBUG_OUT
    if ( directive ==  T_WHILE )
        tmpmacro.sym.name = "<WHILE>";
    else if ( directive == T_REPEAT || directive == T_REPT )
        tmpmacro.sym.name = "<REPT>";
    else if ( directive == T_FORC || directive == T_IRPC )
        tmpmacro.sym.name = "<FORC>";
    else
        tmpmacro.sym.name = "<FOR>";
#endif

    DebugMsg1(("LoopDirective(%s): calling StoreMacro\n", GetResWName( directive, NULL )));
    if( StoreMacro( macro, i, tokenarray, TRUE ) == ERROR ) {
        ReleaseMacroData( macro );
        return( ERROR );
    }
    /* EXITM <> is allowed inside a macro loop.
     * This doesn't make the loop a macro function, reset the bit!
     */
    macro->sym.isfunc = FALSE;

    /* now run the just created macro in a loop */

    /* don't run the macro if there are no lines (macroinfo->data == NULL)!
     * this isn't exactly what Masm does; an empty 'WHILE 1'
     * will loop "forever" in Masm,
     */
    if ( macinfo.data ) /* added in v2.01 */
        switch ( directive ) {
        case T_REPEAT:
        case T_REPT:
            /* negative repeat counts are accepted and are treated like 0 */
            for ( ; macro->sym.value < opnd.value; macro->sym.value++ ) {
                /* v2.10: Token_Count becomes volatile if MF_NOSAVE is set */
                tokenarray[0].token = T_FINAL;
                Token_Count = 0;
                //RunMacro( macro, Token_Count, tokenarray, NULL, MF_NOSAVE, &is_exitm );
                RunMacro( macro, 0, tokenarray, NULL, MF_NOSAVE, &is_exitm );
                if ( is_exitm )
                    break;
                DebugMsg1(("LoopDirective REPT: iteration=%" I32_SPEC "u\n", ++count ));
            }
            break;
        case T_WHILE:
            while ( opnd.kind == EXPR_CONST && opnd.value != 0 ) {
                DebugMsg1(("LoopDirective WHILE: cnt=%u\n", count++ ));
                RunMacro( macro, Token_Count, tokenarray, NULL, 0, &is_exitm );
                if ( is_exitm )
                    break;
                i = arg_loc;
                if ( EvalOperand( &i, tokenarray, Token_Count, &opnd, 0 ) == ERROR )
                    break;
                macro->sym.value++;
            }
            break;
        case T_FORC:
        case T_IRPC:
            for( ptr = parmstring; *ptr; ptr++, macro->sym.value++ ) {
                tokenarray[0].token = T_STRING;
                tokenarray[0].string_delim = NULLC;
                tokenarray[0].string_ptr = buffer;
                tokenarray[0].tokpos = buffer;
                tokenarray[1].token = T_FINAL;
                buffer[2] = NULLC;
                Token_Count = 1;
                if ( *ptr == '!' ) {
                    buffer[0] = *ptr++;
                    buffer[1] = *ptr;
                    if ( *ptr == NULLC ) /* ensure the macro won't go beyond the 00 */
                        ptr--;
                    tokenarray[0].stringlen = 2;
                    tokenarray[1].tokpos = buffer+2;
                } else if ( isspace( *ptr ) ) {
                    buffer[0] = '!';
                    buffer[1] = *ptr;
                    tokenarray[0].stringlen = 2;
                    tokenarray[1].tokpos = buffer+2;
                } else {
                    buffer[0] = *ptr;
                    tokenarray[0].stringlen = 1;
                    tokenarray[1].tokpos = buffer+1;
                    buffer[1] = NULLC;
                }
                RunMacro( macro, 0, tokenarray, NULL, MF_NOSAVE, &is_exitm );
                if ( is_exitm )
                    break;
                DebugMsg1(("LoopDirective FORC: call RunMacro(), cnt=%" I32_SPEC "u, param=>%s<\n", count++, buffer ));
            }
            break;
        default: /* T_FOR, T_IRP */
            i = Token_Count + 1;
            Token_Count = Tokenize( parmstring, i, tokenarray, TOK_RESCAN | TOK_NOCURLBRACES );
            DebugMsg1(("LoopDirective FOR: full param=>%s<\n", tokenarray[i].tokpos ));

            /* v2.09: if a trailing comma is followed by white space(s), add a blank token */
            if ( i != Token_Count && tokenarray[Token_Count-1].token == T_COMMA &&
                    *(tokenarray[Token_Count-1].tokpos+1) ) {
                tokenarray[Token_Count].token = T_STRING;
                tokenarray[Token_Count].string_delim = NULLC;
                tokenarray[Token_Count].stringlen = strlen( tokenarray[Token_Count].tokpos );
                tokenarray[Token_Count+1].tokpos = tokenarray[Token_Count].tokpos + tokenarray[Token_Count].stringlen;
                Token_Count++;
                tokenarray[Token_Count].token = T_FINAL;
            }

            /* a FOR/IRP parameter can be a macro function call */
            /* that's why the macro calls must be run synchronously */
            /* v2.05: reset an optional VARARG attribute for the macro
             * parameter.
             * take care of a trailing comma, this is to make another
             * RunMacro() call with a "blank" argument.
             */
            macro->sym.mac_vararg = FALSE;
            /* v2.09: flag MF_IGNARGS introduced. This allows RunMacro() to
             * parse the full argument and trigger macro expansion if necessary.
             * No need anymore to count commas here. */
            for( ; i < Token_Count; i++, macro->sym.value++ ) {
                DebugMsg1(("LoopDirective FOR: cnt=%" I32_SPEC "u, calling RunMacro( param=>%s< )\n", count++, tokenarray[i].tokpos ));
                i = RunMacro( macro, i, tokenarray, NULL, MF_IGNARGS, &is_exitm );
                if ( i < 0 || is_exitm )
                    break;
            }
        }
    ReleaseMacroData( macro );
    DebugMsg1(("LoopDirective(%s) exit\n", GetResWName( directive, NULL ) ));
    return( NOT_ERROR );
}
示例#22
0
ret_code CommDirective( int i, struct asm_tok tokenarray[] )
/**********************************************************/
{
    char            *token;
#if MANGLERSUPP
    char            *mangle_type = NULL;
#endif
    bool            isfar;
    //int             distance;
    int             tmp;
    uint_32         size;  /* v2.12: changed from 'int' to 'uint_32' */
    uint_32         count; /* v2.12: changed from 'int' to 'uint_32' */
    struct asym     *sym;
    struct expr     opndx;
    enum lang_type  langtype;

    DebugMsg1(("CommDirective(%u) enter\n", i));
    i++; /* skip COMM token */
    for( ; i < Token_Count; i++ ) {
#if MANGLERSUPP
        mangle_type = Check4Mangler( &i, tokenarray );
#endif
        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        /* get the -optional- distance ( near or far ) */
        isfar = FALSE;
        if ( tokenarray[i].token == T_STYPE )
            switch ( tokenarray[i].tokval ) {
            case T_FAR:
            case T_FAR16:
            case T_FAR32:
                if ( ModuleInfo.model == MODEL_FLAT ) {
                    EmitError( FAR_NOT_ALLOWED_IN_FLAT_MODEL_COMM_VARIABLES );
                } else
                    isfar = TRUE;
                /* no break */
            case T_NEAR:
            case T_NEAR16:
            case T_NEAR32:
                i++;
            }

        /* v2.08: ensure token is a valid id */
        if( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        /* get the symbol name */
        token = tokenarray[i++].string_ptr;

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        i++;
        /* the evaluator cannot handle a ':' so scan for one first */
        for ( tmp = i; tmp < Token_Count;tmp++ )
            if ( tokenarray[tmp].token == T_COLON )
                break;
        /* v2.10: expression evaluator isn't to accept forward references */
        //if ( EvalOperand( &i, tokenarray, tmp, &opndx, 0 ) == ERROR )
        if ( EvalOperand( &i, tokenarray, tmp, &opndx, EXPF_NOUNDEF ) == ERROR )
            return( ERROR );

        /* v2.03: a string constant is accepted by Masm */
        /* v2.11: don't accept NEAR or FAR */
        /* v2.12: check for too large value added */
        //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
        if ( opndx.kind != EXPR_CONST )
            EmitError( CONSTANT_EXPECTED );
        else if ( ( opndx.mem_type & MT_SPECIAL_MASK) == MT_ADDRESS )
            EmitErr( INVALID_TYPE_FOR_DATA_DECLARATION, token );
        else if ( opndx.hvalue != 0 && opndx.hvalue != -1 )
            EmitConstError( &opndx );
        else if ( opndx.uvalue == 0 )
            EmitError( POSITIVE_VALUE_EXPECTED );

        size = opndx.uvalue;

        count = 1;
        if( tokenarray[i].token == T_COLON ) {
            i++;
            /* get optional count argument */
            /* v2.10: expression evaluator isn't to accept forward references */
            //if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, EXPF_NOUNDEF ) == ERROR )
                return( ERROR );

            /* v2.03: a string constant is acceptable! */
            /* v2.12: check for too large value added */
            //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
            if ( opndx.kind != EXPR_CONST )
                EmitError( CONSTANT_EXPECTED );
            else if ( opndx.hvalue != 0 && opndx.hvalue != -1 )
                EmitConstError( &opndx );
            else if ( opndx.uvalue == 0 )
                EmitError( POSITIVE_VALUE_EXPECTED );

            count = opndx.uvalue;
        }

        sym = SymSearch( token );
        if( sym == NULL || sym->state == SYM_UNDEFINED ) {
            sym = MakeComm( token, sym, size, count, isfar );
            if ( sym == NULL )
                return( ERROR );
        } else if ( sym->state != SYM_EXTERNAL || sym->iscomm != TRUE ) {
            return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
        } else {
            tmp = sym->total_size / sym->total_length;
            if( count != sym->total_length || size != tmp ) {
                return( EmitErr( NON_BENIGN_XXX_REDEFINITION, szCOMM, sym->name ) );
            }
        }
        sym->isdefined = TRUE;
        SetMangler( sym, langtype, mangle_type );

        if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
        }
    }
    return( NOT_ERROR );
}
示例#23
0
int PrintGenerateFailure(const wchar_t *szOut)
{
	EmitError(IDS_SDL_GENERATE_FAILURE, szOut ? szOut : L"<unspecified>");
	return 1;
}
示例#24
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 );
}
示例#25
0
/* handle .model directive
 * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>]
 * sets fields
 * - ModuleInfo.model
 * - ModuleInfo.language
 * - ModuleInfo.distance
 * - ModuleInfo.ostype
 * if model is FLAT, defines FLAT pseudo-group
 * set default segment names for code and data
 */
ret_code ModelDirective( int i, struct asm_tok tokenarray[] )
/***********************************************************/
{
    enum model_type model;
    enum lang_type language;
    enum dist_type distance;
    enum os_type ostype;
    int index;
    uint_8 init;
    uint_8 initv;

    DebugMsg1(("ModelDirective enter\n"));
    /* v2.03: it may occur that "code" is defined BEFORE the MODEL
     * directive (i.e. DB directives in AT-segments). For FASTPASS,
     * this may have caused errors because contents of the ModuleInfo
     * structure was saved before the .MODEL directive.
     */
    //if( Parse_Pass != PASS_1 ) {
    if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) {
        /* just set the model with SetModel() if pass is != 1.
         * This won't set the language ( which can be modified by
         * OPTION LANGUAGE directive ), but the language in ModuleInfo
         * isn't needed anymore once pass one is done.
         */
        SetModel();
        return( NOT_ERROR );
    }

    i++;
    if ( tokenarray[i].token == T_FINAL ) {
        EmitError( EXPECTED_MEMORY_MODEL );
        return( ERROR );
    }
    /* get the model argument */
    index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) );
    if( index >= 0 ) {
        if( ModuleInfo.model != MODEL_NONE ) {
            EmitWarn( 2, MODEL_DECLARED_ALREADY );
            return( NOT_ERROR );
        }
        model = index + 1;
        i++;
    } else {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }

    /* get the optional arguments: language, stack distance, os */
    init = 0;
    while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) {
        i++;
        if ( tokenarray[i].token != T_COMMA ) {
            if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) {
                initv = INIT_LANG;
            } else {
                index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) );
                if ( index < 0 )
                    break;
                initv = ModelAttrValue[index].init;
                switch ( initv ) {
                case INIT_STACK:
                    if ( model == MODEL_FLAT ) {
                        EmitError( INVALID_MODEL_PARAM_FOR_FLAT );
                        return( ERROR );
                    }
                    distance = ModelAttrValue[index].value;
                    break;
                case INIT_OS:
                    ostype = ModelAttrValue[index].value;
                    break;
                }
                i++;
            }
            /* attribute set already? */
            if ( initv & init ) {
                i--;
                break;
            }
            init |= initv;
        }
    }
    /* everything parsed successfully? */
    if ( tokenarray[i].token != T_FINAL ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos );
        return( ERROR );
    }

    if ( model == MODEL_FLAT ) {
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) {
            EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
            return( ERROR );
        }
        DefineFlatGroup();
    }

    ModuleInfo.model = model;
    if ( init & INIT_LANG ) {
        ModuleInfo.langtype = language;
#if AMD64_SUPPORT
        /* v2.03: set header and fastcall type to win64 if x64 is active.
         * This is rather hackish, but currently there's no other possibility
         * to enable the win64 ABI from the source.
         */
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) == P_64 )
            if ( language == LANG_FASTCALL &&
                model == MODEL_FLAT &&
                Options.output_format != OFORMAT_ELF ) {
                DebugMsg(("ModelDirective: FASTCALL type set to WIN64\n"));
                ModuleInfo.header_format = HFORMAT_WIN64;
                ModuleInfo.fctype = FCT_WIN64;
            }
#endif
    }
    if ( init & INIT_STACK )
        ModuleInfo.distance = distance;
    if ( init & INIT_OS )
        ModuleInfo.ostype = ostype;

    SetModelDefaultSegNames();
    SetModel();

    return( NOT_ERROR );
}
示例#26
0
/* InStr()
 * defines a numeric variable which contains position of substring.
 * syntax:
 * name INSTR [pos,]string, substr
 */
ret_code InStrDir( int i, struct asm_tok tokenarray[] )
/*****************************************************/
{
    struct asym *sym;
    int sizestr;
    int j;
    /* int commas; */
    char *src;
    char *p;
    char *q;
    char *string1;
    struct expr opndx;
    int start = 1;
    int strpos;

    DebugMsg1(("InStrDir entry\n"));
    DebugCmd( instrcnt++ );

    if ( i != 1) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
#if 0 /* this is checked in ParseLine() */
    if ( tokenarray[0].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
    }
#endif

    i++; /* go past INSTR */

    if ( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
        /* v2.11: flag NOUNDEF added - no forward reference accepted */
        if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, EXPF_NOUNDEF ) == ERROR )
            return( ERROR );
        if ( opndx.kind != EXPR_CONST ) {
            return( EmitError( CONSTANT_EXPECTED ) );
        }
        start = opndx.value;
        if ( start <= 0 ) {
            /* v2.05: don't change the value. if it's invalid, the result
             * is to be 0. Emit a level 3 warning instead.
             */
            //start = 1;
            EmitWarn( 3, POSITIVE_VALUE_EXPECTED );
        }
        if ( tokenarray[i].token != T_COMMA ) {
            return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
        }
        i++; /* skip comma */
    }

    if ( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
        return( TextItemError( &tokenarray[i] ) );
    }

    /* to compare the strings, the "visible" format is needed, since
     * the possible '!' operators inside the strings is optional and
     * must be ignored.
     */
    //src = StringBufferEnd;
    //sizestr = GetLiteralValue( src, tokenarray[i].string_ptr );
    src = tokenarray[i].string_ptr;
    sizestr = tokenarray[i].stringlen;
    DebugMsg1(("InStrDir: first string >%s< \n", src ));

    if ( start > sizestr ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, start ) );
    }
    p = src + start - 1;

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

    if ( tokenarray[i].token != T_STRING || tokenarray[i].string_delim != '<' ) {
        return( TextItemError( &tokenarray[i] ) );
    }
    //q = GetAlignedPointer( src, sizestr );
    //j = GetLiteralValue( q, tokenarray[i].string_ptr );
    q = tokenarray[i].string_ptr;
    j = tokenarray[i].stringlen;
    DebugMsg1(("InStrDir: second string >%s< \n", q ));
    i++;
    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    strpos = 0;
    /* v2.05: check for start > 0 added */
    /* v2.08: check for j > 0 added */
    if ( ( start > 0 ) && ( sizestr >= j ) && j && ( string1 = strstr( p, q ) ))
        strpos = string1 - src + 1;

    if ( sym = CreateVariable( tokenarray[0].string_ptr, strpos ) ) {
        DebugMsg1(("InStrDir(%s) exit, value=%u\n", tokenarray[0].string_ptr, strpos));
        LstWrite( LSTTYPE_EQUATE, 0, sym );
        return ( NOT_ERROR );
    }
    return( ERROR );
}
示例#27
0
ret_code ExternDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
{
    char                *token;
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    char                *altname;
    struct asym         *sym;
    enum lang_type      langtype;
    struct qualified_type ti;

    DebugMsg1(("ExternDirective(%u) enter\n", i));
    i++; /* skip EXT[E]RN token */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        altname = NULL;

        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

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

        /* go past the optional alternative name (weak ext, default resolution) */
        if( tokenarray[i].token == T_OP_BRACKET ) {
            i++;
            if ( tokenarray[i].token != T_ID ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
            }
            altname = tokenarray[i].string_ptr;
            i++;
            if( tokenarray[i].token != T_CL_BRACKET ) {
                return( EmitErr( EXPECTED, ")" ) );
            }
            i++;
        }

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitError( COLON_EXPECTED ) );
        }
        i++;
        sym = SymSearch( token );

        ti.mem_type = MT_EMPTY;
        ti.size = 0;
        ti.is_ptr = 0;
        ti.is_far = FALSE;
        ti.ptr_memtype = MT_EMPTY;
        ti.symtype = NULL;
        ti.Ofssize = ModuleInfo.Ofssize;

        if ( tokenarray[i].token == T_ID && ( 0 == _stricmp( tokenarray[i].string_ptr, "ABS" ) ) ) {
            //ti.mem_type = MT_ABS;
            i++;
        } else if ( tokenarray[i].token == T_DIRECTIVE && tokenarray[i].tokval == T_PROTO ) {
            /* dont scan this line further */
            /* CreateProto() will define a SYM_EXTERNAL */
            sym = CreateProto( i + 1, tokenarray, token, langtype );
            DebugMsg1(("ExternDirective(%s): CreateProto()=%X\n", token, sym));
            if ( sym == NULL )
                return( ERROR );
            if ( sym->state == SYM_EXTERNAL ) {
                sym->weak = FALSE;
                return( HandleAltname( altname, sym ) );
            } else {
                /* unlike EXTERNDEF, EXTERN doesn't allow a PROC for the same name */
                return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
            }
        } else if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );
        }

        DebugMsg1(("ExternDirective(%s): mem_type=%Xh\n", token, ti.mem_type ));

        if( sym == NULL || sym->state == SYM_UNDEFINED ) {
            /* v2.04: emit the error at the PUBLIC directive */
            //if ( sym && sym->public == TRUE ) {
            //    EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
            //    return( ERROR );
            //}
            if(( sym = MakeExtern( token, ti.mem_type,
                                  ti.mem_type == MT_TYPE ? ti.symtype : NULL, sym,
                                  ti.is_ptr ? ModuleInfo.Ofssize : ti.Ofssize )) == NULL )
                return( ERROR );

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                CreateProc( sym, NULL, SYM_EXTERNAL );
                sym->weak = FALSE; /* v2.09: reset the weak bit that has been set inside CreateProc() */
                CopyPrototype( (struct dsym *)sym, (struct dsym *)ti.symtype );
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
                DebugMsg1(("ExternDirective(%s): prototype copied, memtype=%X\n", token, ti.mem_type ));
            }

        } else {
#if MASM_EXTCOND
            /* allow internal AND external definitions for equates */
            //if ( sym->state == SYM_INTERNAL && sym->mem_type == MT_ABS )
            if ( sym->state == SYM_INTERNAL && sym->mem_type == MT_EMPTY )
                ;
            else
#endif
            if ( sym->state != SYM_EXTERNAL ) {
                DebugMsg(("ExternDirective: symbol %s redefinition, state=%u\n", token, sym->state ));
                return( EmitErr( SYMBOL_REDEFINITION, token ) );
            }
            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }

            if( sym->mem_type != ti.mem_type ||
               sym->is_ptr != ti.is_ptr ||
               sym->isfar != ti.is_far ||
               ( sym->is_ptr && sym->ptr_memtype != ti.ptr_memtype ) ||
               ((sym->mem_type == MT_TYPE) ? sym->type : sym->target_type) != ti.symtype ||
               ( langtype != LANG_NONE && sym->langtype != LANG_NONE && sym->langtype != langtype )) {
                DebugMsg(("ExternDirective: memtype:%X-%X ptr=%X-%X far=%X-%X ptr_memtype=%X-%X lang=%u-%u\n",
                          sym->mem_type, ti.mem_type,
                          sym->is_ptr, ti.is_ptr,
                          sym->isfar, ti.is_far,
                          sym->ptr_memtype, ti.ptr_memtype,
                          sym->langtype, langtype
                         ));
                return( EmitErr( SYMBOL_TYPE_CONFLICT, token ) );
            }
        }

        sym->isdefined = TRUE;
        sym->Ofssize = ti.Ofssize;

        if ( ti.is_ptr == 0 && ti.Ofssize != ModuleInfo.Ofssize ) {
            sym->seg_ofssize = ti.Ofssize;
            if ( sym->segment && ((struct dsym *)sym->segment)->e.seginfo->Ofssize != sym->seg_ofssize )
                sym->segment = NULL;
        }

        sym->mem_type = ti.mem_type;
        sym->is_ptr = ti.is_ptr;
        sym->isfar = ti.is_far;
        sym->ptr_memtype = ti.ptr_memtype;
        if ( ti.mem_type == MT_TYPE )
            sym->type = ti.symtype;
        else
            sym->target_type = ti.symtype;

        HandleAltname( altname, sym );

        SetMangler( sym, langtype, mangle_type );

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

    return( NOT_ERROR );
}
示例#28
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 );
}
示例#29
0
/* .[NO|X]LIST, .[NO|X]CREF, .LISTALL, 
 * .[NO]LISTIF, .[LF|SF|TF]COND,
 * PAGE, TITLE, SUBTITLE, SUBTTL directives
 */
ret_code ListingDirective( int i, struct asm_tok tokenarray[] )
/*************************************************************/
{
    int directive = tokenarray[i].tokval;
    i++;

    switch ( directive ) {
    case T_DOT_LIST:
        if ( CurrFile[LST] )
            ModuleInfo.list = TRUE;
        break;
    case T_DOT_CREF:
        ModuleInfo.cref = TRUE;
        break;
    case T_DOT_NOLIST:
    case T_DOT_XLIST:
        ModuleInfo.list = FALSE;
        break;
    case T_DOT_NOCREF:
    case T_DOT_XCREF:
        if ( i == Token_Count ) {
            ModuleInfo.cref = FALSE;
            break;
        }
        do {
            struct asym *sym;
            if ( tokenarray[i].token != T_ID ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
            }
            /* the name may be a forward reference. In this case it will
             * be created here.
             * v2.11: function call cannot fail. no need for checks.
             */
            sym = SymLookup( tokenarray[i].string_ptr );
            sym->list = FALSE;
            i++;
            if ( i < Token_Count ) {
                if ( tokenarray[i].token != T_COMMA )
                    return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );

                /* if there's nothing after the comma, don't increment */
                if ( i < ( Token_Count - 1 ) )
                    i++;
            }
        } while ( i < Token_Count );
        break;
    case T_DOT_LISTALL: /* list false conditionals and generated code */
        if ( CurrFile[LST] )
            ModuleInfo.list = TRUE;
        ModuleInfo.list_generated_code = TRUE;
        /* fall through */
    case T_DOT_LISTIF:
    case T_DOT_LFCOND: /* .LFCOND is synonym for .LISTIF */
        ModuleInfo.listif = TRUE;
        break;
    case T_DOT_NOLISTIF:
    case T_DOT_SFCOND: /* .SFCOND is synonym for .NOLISTIF */
        ModuleInfo.listif = FALSE;
        break;
    case T_DOT_TFCOND: /* .TFCOND toggles .LFCOND, .SFCOND */
        ModuleInfo.listif = !ModuleInfo.listif;
        break;
    case T_PAGE:
    default: /* TITLE, SUBTITLE, SUBTTL */
        /* tiny checks to ensure that these directives
         aren't used as code labels or struct fields */
        if ( tokenarray[i].token == T_COLON )
            break;
        /* this isn't really Masm-compatible, but ensures we don't get
         * struct fields with names page, title, subtitle, subttl.
         */
        if( CurrStruct ) {
            return( EmitError( STATEMENT_NOT_ALLOWED_INSIDE_STRUCTURE_DEFINITION ) );
        }
        if ( Parse_Pass == PASS_1 )
            EmitWarn( 4, DIRECTIVE_IGNORED, tokenarray[i-1].string_ptr );
        while ( tokenarray[i].token != T_FINAL) i++;
    }

    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    return( NOT_ERROR );
}
示例#30
0
ret_code SimplifiedSegDir( int i, struct asm_tok tokenarray[] )
/*************************************************************/
/*
 Handles simplified segment directives:
 .CODE, .STACK, .DATA, .DATA?, .FARDATA, .FARDATA?, .CONST
 */
{
    const char  *name = NULL;
    char        init;
    int         type;
    struct expr opndx;

    DebugMsg1(("SimplifiedSegDir(%s) enter\n", tokenarray[i].string_ptr ));

    LstWrite( LSTTYPE_DIRECTIVE, 0, NULL );

    if( ModuleInfo.model == MODEL_NONE ) {
        EmitError( MODEL_IS_NOT_DECLARED );
        return( ERROR );
    }

    //type = tokenarray[i].value;
    type = GetSflagsSp( tokenarray[i].tokval );
    i++; /* get past the directive token */

    if( type == SIM_STACK ) {
        if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
            return( ERROR );
        if( opndx.kind == EXPR_EMPTY )
            opndx.value = DEFAULT_STACK_SIZE;
        else if( opndx.kind != EXPR_CONST ) {
            EmitError( CONSTANT_EXPECTED );
            return( ERROR );
        }
    } else {
        /* Masm accepts a name argument for .CODE and .FARDATA[?] only.
         * JWasm also accepts this for .DATA[?] and .CONST unless
         * option -Zne is set.
         */
        if( tokenarray[i].token == T_ID &&
           ( type == SIM_CODE || type == SIM_FARDATA || type == SIM_FARDATA_UN
            || ( Options.strict_masm_compat == FALSE &&
                ( type == SIM_DATA || type == SIM_DATA_UN || type == SIM_CONST )))) {
            name = tokenarray[i].string_ptr;
            i++;
        }
    }
    if ( tokenarray[i].token != T_FINAL ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }

    NewLineQueue();

    if( type != SIM_STACK )
        close_currseg();  /* emit a "xxx ENDS" line to close current seg */

    if ( name == NULL )
        init = ( ModuleInfo.simseg_init & ( 1 << type ) );

    switch( type ) {
    case SIM_CODE: /* .code */
        SetSimSeg( SIM_CODE, name );

        if( ModuleInfo.model == MODEL_TINY ) {
            /* v2.05: add the named code segment to DGROUP */
            if ( name )
                AddToDgroup( SIM_CODE, name );
            name = szDgroup;
        } else if( ModuleInfo.model == MODEL_FLAT ) {
            name = "FLAT";
        } else {
            if( name == NULL )
                name = SegmNames[SIM_CODE];
        }
        AddLineQueueX( "%r %r:%s", T_ASSUME, T_CS, name );
        break;
    case SIM_STACK: /* .stack */
        /* if code is generated which does "emit" bytes,
         * the original source line has to be saved.
         * v2.05: must not be done after LstWrite() has been called!
         * Also, there are no longer bytes "emitted".
         */
        //FStoreLine();
        SetSimSeg( SIM_STACK, NULL );
        AddLineQueueX( "ORG 0%xh", NUMQUAL opndx.value );
        EndSimSeg( SIM_STACK );
        /* add stack to dgroup for some segmented models */
        if ( !init )
            if ( ModuleInfo.distance != STACK_FAR )
                AddToDgroup( SIM_STACK, NULL );
        break;
    case SIM_DATA:    /* .data  */
    case SIM_DATA_UN: /* .data? */
    case SIM_CONST:   /* .const */
        SetSimSeg( type, name );
        AddLineQueueX( "%r %r:ERROR", T_ASSUME, T_CS );
        if ( name || (!init) )
            AddToDgroup( type, name );
        break;
    case SIM_FARDATA:     /* .fardata  */
    case SIM_FARDATA_UN:  /* .fardata? */
        SetSimSeg( type, name );
        AddLineQueueX( "%r %r:ERROR", T_ASSUME, T_CS );
        break;
    default: /* shouldn't happen */
        /**/myassert( 0 );
        break;
    }

    RunLineQueue();

    DebugMsg1(("SimplifiedSegDir exit\n"));
    return( NOT_ERROR );
}