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 ); }
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 ) ); }
static void genfailure( int signo ) /*********************************/ { #if CATCHBREAK if (signo != SIGBREAK) #else if (signo != SIGTERM) #endif EmitError( GENERAL_FAILURE ); close_files(); exit( EXIT_FAILURE ); }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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 ); }
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 ); }
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 */ }
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 ); }
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 ); }
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; }
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() ); }
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 ); }
/* 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 ); }
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 ); }
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 ); }
int PrintGenerateFailure(const wchar_t *szOut) { EmitError(IDS_SDL_GENERATE_FAILURE, szOut ? szOut : L"<unspecified>"); return 1; }
/* 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 ); }
/* 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 ); }
/* 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 ); }
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 ); }
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 ); }
/* .[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 ); }
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 ); }