//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
void CPreprocessor::Init(CConfig* pcConfig, CMemoryStackExtended* pcStack)
{
	mcDefines.Init(32);
	mpcPost = NULL;
	mpcUnit = NULL;
	miIncludeDepth = 0;
	miBlockReuse = 0;
	mbLogBlocks = FALSE;
	mbLogInlucdes = FALSE;
	mbDumpLogs = FALSE;
	miDefineReuse = 0;

	mcConditionalStack.Init();
	mpcCurrentFile = NULL;
	mcHeadersStack.Init(8);

	mpcStack = pcStack;
	mcHeaderNames.Init(4);

	AddSpecialDefine("__DATE__");
	AddSpecialDefine("__FILE__");
	AddSpecialDefine("__LINE__");
	AddSpecialDefine("__TIME__");
	AddSpecialDefine("__TIMESTAMP__");

#ifdef __STDC__ 
	AddDefine("__STDC__", "1");
#else
	AddDefine("__STDC__", "0");
#endif

	InitPlatformSpecific();
	AddConfigDefines(pcConfig);
	mpcStack = NULL;
}
示例#2
0
std::unique_ptr<Configuration> ImportConfig(const nlohmann::json& json)
{
    if (IsValidConfig(json))
    {
        auto config = std::make_unique<Configuration>();

        config->SetName(json["name"]);

        if (json["pchheader"].is_string())
        {
            config->SetPrecompiledHeader(json["pchheader"]);
        }

        if (json["pchsource"].is_string())
        {
            config->SetPrecompiledSource(json["pchsource"]);
        }

        for (auto& define : json["defines"])
        {
            config->AddDefine(define);
        }

        for (auto& include : json["includedirs"])
        {
            config->AddInclude(include);
        }

        return config;
    }

    return nullptr;
}
示例#3
0
//
// Constant.h를 읽어 #define name value들을 모두 메모리에 적재
// Load()를 연속적으로 읽는다면 m_nMaxDef부터 추가로 읽게 된다.
// ex)  Load( "constant1.h" );	0 ~ 300 인덱스
//      Load( "constant2.h" );	301 ~ 600 인덱스
XE::xRESULT CDefine::Load( LPCTSTR strFileName )
{
	CToken	Token;
	TCHAR szName[256];

	if( Token.LoadFile( strFileName, TXT_EUCKR ) == XE::xFAIL )
		return XE::xFAIL;
	while(1)
	{
		if( Token.GetToken() == NULL )	break;
		if( Token == _T("define") )
		{
			Token.GetToken();
			// ex) #define OBJECT_DAO	1
			if( Token.m_Token[0] != '_' )		// #define _HUHU같이 첫자가밑줄 붙은건 읽지 않음
			{
				_tcscpy_s( szName, Token.m_Token );
				int		nVal = Token.GetNumber();
				// 읽어 메모리로 올릴때는 주석을 읽지 않는다.  
				// Object.inc에 있는 NAME부분을 가지고 저장할때만 기록한다.
				if( XE::xFAIL == AddDefine( szName, nVal, Token.GetRemark() ) )			// define 추가
				{
					XERROR( "%s 읽던중 CDefine의 최대 버퍼%d를 넘었다", strFileName, MAX_DEFINE );
					break;
				}
			} else
				XLOG( "define %s skip", Token.m_Token );
		}
	}
	return XE::xSUCCESS;
}
示例#4
0
Model * ModelBuilder :: Build( const ALib::XMLElement * tree ) {

	string name = tree->AttrValue( NAME_ATTRIB, "" );
	std::auto_ptr <Model> model( new Model( name, std::cout ) );

	for ( unsigned int i = 0; i < tree->ChildCount(); i++ ) {
		const ALib::XMLElement * ce = tree->ChildElement( i );
		if ( ce ) {
			if ( ce->Name() == DMKGEN_TAG) {
				BuildGenerator( model.get(), ce );
			}
			else if ( ce->Name() == DMKECHO_TAG ) {
				BuildEchoer( model.get(), ce );
			}
			else if ( ce->Name() == DMKDEF_TAG ) {
				AddDefine( model.get(), ce );
			}
			else {
				throw Exception( "Invalid top-level tag "
									+ ALib::SQuote( ce->Name() ) );
			}
		}
	}
	return model.release();
}
//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
CDefine* CPreprocessor::AddSpecialDefine(char* szDefine)
{
	CDefine* pcDefine;

	pcDefine = AddDefine(szDefine);
	pcDefine->SetSpecial(TRUE);
	return pcDefine;
}
//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
void CPreprocessor::AddConfigDefines(CConfig* pcConfig)
{
	int			i;
	CChars*		pszText;

	if (pcConfig)
	{
		for (i = 0; i < pcConfig->maszDefines.NumElements(); i++)
		{
			pszText = pcConfig->maszDefines.Get(i);
			AddDefine(pszText->Text());
		}
	}
}
示例#7
0
  void do_file_set_block(FileSetBlock *fsb) {
    String output_file_name = 
      _output_file_name_argument->get_string()->get_string();
    c_file = open_c_file(output_file_name);

    SuifEnv *s = get_suif_env();
    MacroObjectBuilder builder;
    MacroObjectPtr root =  builder.build_macro_object((Address)fsb,fsb->get_meta_class());

    char *text = get_file_text(_macro_file_name.c_str());
    if (text == NULL)
    {
      suif_error(s, "could not open macro file %s\n",_macro_file_name.c_str());
      //        fprintf(stderr,"could not open macro file %s\n",macro_filename);
      return;
      //        return -1;
    }
    size_t i;
    for (i = 0;i < _d_opts.size(); i++)
      AddDefine(root,_d_opts[i]);

    int len = strlen(text);
    S2CMacroExpansion expand(s,len);

    for (i = 0;i < _i_opts.size(); i++)
    {
      String value = _i_opts[i];
      expand.add_include(value);
    }

    // root->Print(0);

    expand.set_debug(debug_it);
    expand.Expand(_macro_file_name,text,root);
    for (int j=1;j<expand.file_count();j++) {
	const String x = expand.get_file_text(j);
        write_text(expand.get_file_name(j),x);
	}

    const String def = expand.get_file_text(0);
    if (def.length() > 0)
        fprintf(c_file,"%s",def.c_str());
    root->perform_final_cleanup();
    if (c_file  && c_file != stdout) 
      fclose(c_file);
    delete [] text;
    }
示例#8
0
// 바이너리 포맷으로 읽기
XE::xRESULT	CDefine :: LoadBIN( LPCTSTR szFileName )
{
	int		nNum = 0;
	int		nLen = 0;
	TCHAR buff[256];
	int		nMaxDef = 0;

	XResFile file, *pRes = &file;
	if( pRes->Open( szFileName, XBaseRes::xREAD ) == 0 ) {
		XERROR( "%s가 없다", szFileName );
		return XE::xFAIL;
	}
		
//	FILE	*fp = _tfopen( szFileName, _T("rb") );
//	if( fp == NULL )	
//	{
//		XERROR( "%s가 없다", szFileName );
//		return XE::xFAIL;
//	}

	int		i;
//	DEFINE	*pList = m_pList;

	memset( buff, 0, 256 );
	pRes->Read( &nMaxDef, 4 );
	for( i = 0; i < nMaxDef; i ++ )
	{
		pRes->Read( &nLen, 4 );
		pRes->Read( buff, nLen );
		pRes->Read( &nNum, 4 );
		if( XE::xFAIL == AddDefine( buff, nNum ) )			// define 추가
		{
			XERROR( "%s 읽던중 CDefine의 최대 버퍼%d를 넘었다", szFileName, MAX_DEFINE );
			break;
		}
	}

#ifdef	_LE
	g_pWatchView->Message( "%s 로딩완료", szFileName );
#endif

	return XE::xSUCCESS;
}
//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
CDefine* CPreprocessor::AddDefine(char* szDefine, char* szReplacement)
{
	CDefine*				pcDefine;
	int						iLen;
	char*					sz;
	CPPText					pcText;
	CPreprocessorTokeniser	cTokeniser;

	iLen = (int)strlen(szReplacement);
	pcDefine = AddDefine(szDefine);
	sz = (char*)gcTokenStrings.Add(iLen+1);
	memcpy(sz, szReplacement, iLen+1);

	cTokeniser.Init();
	cTokeniser.TokeniseDefine(&pcDefine->mcReplacement.mcTokens, sz, mpcStack);
	cTokeniser.Kill();

	return pcDefine;
}
示例#10
0
文件: lex.c 项目: vmezhang/sometest
static void ScanPPDefine (void) 
{
    char *name, *content;

    SKIP_SPACE (NULL);
    if (TK_ID != ScanIdentifierDef ()) {

        Error (&TokenCoord, "Define doesn't define key words");
    }
    name = TokenValue.p;

    if ('(' == *CURRENT) {

        PRINT ("待处理 \n");
        exit (1);
    }
    
    content = ReadLine ();
    AddDefine (name, content);
    INFO (5, "define : %s, %s", name, content);
}
示例#11
0
void CConfig::AddDefines(char* szDefines)
{
	CChars			szTemp;
	CArrayString	aszTemp;
	int				i;
	CChars*			pszDefine;

	szTemp.Init(szDefines);

	aszTemp.Init(16);
	szTemp.Split(&aszTemp, ';');

	for (i = 0; i < aszTemp.NumElements(); i++)
	{
		pszDefine = aszTemp.Get(i);
		pszDefine->StripWhiteSpace();
		AddDefine(pszDefine->Text());
	}

	szTemp.Kill();
	aszTemp.Kill();
}
示例#12
0
// preprocessor directives
BOOL FASTCALL comProc_Preprocess(U16 flags, S16 *brackCnt)
{
    BOOL PREP_OK=FALSE;
    int code;
    S32 index;
    char *label,*enumClass;

    if(*szTemp != '#') {
        if(!STRCMP(szTemp,"enum")) {
            if(IsStringLabel(GetNextWord())) {
                enumClass = strdup(szTemp);
                GetNextWord();
            } else
                enumClass = NULL;
            if(szTemp[0]!='{') {
                ssFree(enumClass);
                error(ERR_ENUMBRACK);
                SkipLine(FALSE);
                return TRUE;
            }
            GetNextWord();
            index = 0;
            while(szTemp[0]!='}') {
                label = strdup(szTemp);
                if(GetNextWord()[0]=='=') {
                    if(!IsStrNum(GetNextWord())) {
                        error(ERR_INTEXP);
                    } else {
                        index = ConfirmWord(StrToInt(szTemp));
                    }
                    if(*szTemp!='}' && *szTemp!=',')
                        GetNextWord();
                }
                AddEnum(enumClass,label,index++);
                ssFree(label);
                if(szTemp[0]!=',')
                    break;
                GetNextWord();
            }
            if(szTemp[0]!='}') {
                error(ERR_ENUMBRACK);
                SkipLine(FALSE);
                return TRUE;
            }
            ssFree(enumClass);
            return TRUE;
        }
        return FALSE;
    }
    switch(code = StrInPrep(GetNextWord(),szPreprocess)) {
        /**********************************************************************/
    case PREPROCESS_SETPAD:
        if(InFalseIfDef()) break;

        if(GetNextWord()[0]=='"') {
            if(!DoString()) {
                error(ERR_INTEXP);
            } else {
                strncpy(szPadding,szString,sizeof(szPadding)-1);
                szPadding[sizeof(szPadding)-1] = '\0';
            }
        } else if(IsStrNum(szTemp)) {
            index = StrToInt(szTemp);
            szPadding[0] = ConfirmChar(index);
            szPadding[1] = '\0';
            PREP_OK = TRUE;
        } else
            error(ERR_INTEXP);

        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_ALIGN:
        if(InFalseIfDef()) break;

        if(IsStrNum(GetNextWord())) {
            index = StrToInt(szTemp);
            AlignCode(ConfirmWord(index));
            PREP_OK = TRUE;
        } else
            error(ERR_INTEXP);

        break;

        /**********************************************************************/
    case PREPROCESS_INCLUDE:
        if(InFalseIfDef()) break;

        if(GetNextWord()[0]=='"' && DoStringDirect()) {
            if(CompileScript(szString,NULL,NULL))
                PREP_OK = TRUE;
            break;
        }
        error(ERR_STRINGEXP);

        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_INCBIN:
        // "filename"[,maxsize]
        if(InFalseIfDef()) break;

        if(GetNextWord()[0]=='"' && DoStringDirect()) {
            index = -1;
            if(PeekNextWord()[0]==',') {
                GetNextWord();
                if(IsStrNum(GetNextWord())) {
                    index = ConfirmWord(StrToInt(szTemp));
                } else {
                    error(ERR_INTEXP);
                    PREP_OK = FALSE;
                }
            }
            if(IncBin(szString,index))
                PREP_OK = TRUE;
            break;
        }
        error(ERR_STRINGEXP);

        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_USEPATH:
        // "pathname"
        if(InFalseIfDef()) break;

        if(GetNextWord()[0]=='"' && DoStringDirect()) {
            if(PRECOMPILING && !AddDirList(&includeDirList, szString)) {
                error(ERR_ADDINGPATH,szString);
            }
            PREP_OK = TRUE;
            break;
        }
        error(ERR_STRINGEXP);

        break;

        /**********************************************************************/
    case PREPROCESS_DEFINE:
        if(InFalseIfDef()) break;
                                      
        USE_DEFS = FALSE;
        AddDefine(GetNextWord(),NULL);
        USE_DEFS = TRUE;
        PREP_OK = TRUE;
        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_UNDEF:
        if(InFalseIfDef()) break;
                                      
        USE_DEFS = FALSE;
        if(!DelDefine(GetNextWord())) 
            error(ERR_UNDEFINE,szTemp);
        USE_DEFS = TRUE;
        PREP_OK = TRUE;

        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_IFDEF:
        if(InFalseIfDef()) break;
        USE_DEFS = FALSE;
        EnterIfDef(FindDefine(defList,GetNextWord())!=NULL);
        USE_DEFS = TRUE;
        PREP_OK = TRUE;
        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_IFNDEF:
        if(InFalseIfDef()) break;
        USE_DEFS = FALSE;
        EnterIfDef(FindDefine(defList,GetNextWord())==NULL);
        USE_DEFS = TRUE;
        PREP_OK = TRUE;
        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_ELSE:
        if(!curScript->ifdefTrack || curScript->ifdefTrack->ELSE) {
            error(ERR_PREPELSEUNEXP);
        } else {
            curScript->ifdefTrack->RESULT       = !curScript->ifdefTrack->RESULT;
            curScript->ifdefTrack->ELSE         = TRUE;
        }
                
        PREP_OK = TRUE;
        break;
        /*--------------------------------------------------------------------*/
    case PREPROCESS_ENDIF:
        //TODO fix this
        ReleaseIfDef();
        PREP_OK = TRUE;
        break;

        /**********************************************************************/
    case PREPROCESS_TODO:
    case PREPROCESS_WARNING:
    case PREPROCESS_ERROR:
    case PREPROCESS_FATAL:
        if(InFalseIfDef()) break;

        if(GetNextWord()[0]!='"' || !DoString())
            strcpy(szString,"<user message>");

        switch(code) {
        case PREPROCESS_TODO:
            todo(szString);
            break;
        case PREPROCESS_WARNING:
            warning(WRN_USERPREP,szString);
            break;
        case PREPROCESS_ERROR:
            error(ERR_USERPREP,szString);
            break;
        case PREPROCESS_FATAL:
            fatal(FTL_USERPREP,szString);
            break;
        }
        PREP_OK = TRUE;

        break;

        /**********************************************************************/
    case PREPROCESS_TELL:
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        switch(code=CheckSubList(code)) {
        case PREPROCESS_TELL_BANK:
            CheckCurBank();
            notice(code,"Current Bank: %s (#%d)", curBank->label, curBank->bank);
            break;
        case PREPROCESS_TELL_BANKOFFSET:
            CheckCurBank();
            notice(code,"Current Bank: %s (#%d); Offset: $%04X (%d)",
                   curBank->label, curBank->bank, (BANK_OFFSET(curBank)+curBank->org), (BANK_OFFSET(curBank)+curBank->org));
            break;
        case PREPROCESS_TELL_BANKSIZE:
            CheckCurBank();
            notice(code,"Current Bank: %s (#%d); Current Size: $%04X (%d bytes)",
                   curBank->label, curBank->bank, (BANK_OFFSET(curBank)), (BANK_OFFSET(curBank)));
            break;
        case PREPROCESS_TELL_BANKFREE:
            CheckCurBank();
            notice(code,"Current Bank: %s (#%d); Current Bytes Free In Bank: $%04X (%d)",
                   curBank->label, curBank->bank, (BANK_OFFSET(curBank)), (BANK_OFFSET(curBank)));
            break;
        case PREPROCESS_TELL_BANKTYPE:
            CheckCurBank();
            notice(code,"Current Bank: %s (#%d); Type: %s",
                   curBank->label, curBank->bank, szBankTypes[curBank->type]);
            break;
        default:
            error(ERR_PREPROCESSORID,szTemp);
            PREP_OK = FALSE;
        }
        break;

        /**********************************************************************/
    case PREPROCESS_RAM:   
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        switch(code=CheckSubList(code)) {
        case PREPROCESS_RAM_ORG:
            // blockaddress[, maxsize]
            if(IsStrNum(GetNextWord())) {
                ramBank.org = 0;
                ramBank.ptr = ramBank.buffer+ConfirmWord(StrToInt(szTemp));
                curBank = &ramBank;
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            if(PeekNextWord()[0]==',') {
                GetNextWord();
                if(IsStrNum(GetNextWord())) {
                    ramBank.maxsize = BANK_OFFSET(curBank)+ConfirmWord(StrToInt(szTemp));
                } else {
                    error(ERR_INTEXP);
                    PREP_OK = FALSE;
                }
            }
            curBank->end = curBank->buffer+ramBank.maxsize;
            break;
        case PREPROCESS_RAM_END:
            curBank = NULL;
            break;
        default:
            error(ERR_PREPROCESSORID,szTemp);
            PREP_OK = FALSE;
        }
        break;

        /**********************************************************************/
    case PREPROCESS_ROM: 
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        switch(code=CheckSubList(code)) {
        case PREPROCESS_ROM_ORG:
            // blockaddress[, maxsize]
            CheckRomBank();
            if(IsStrNum(GetNextWord())) {
#if 0
                curBank->org = ConfirmWord(StrToInt(szTemp));
#else
                curBank->org = ConfirmWord(StrToInt(szTemp))-BANK_OFFSET(curBank);
#endif
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            if(PeekNextWord()[0]==',') {
                GetNextWord();
                if(IsStrNum(GetNextWord())) {
                    curBank->maxsize = ConfirmWord(StrToInt(szTemp));
                } else {
                    error(ERR_INTEXP);
                    PREP_OK = FALSE;
                }
            }
            break;
        case PREPROCESS_ROM_END:
            CheckRomBank();
            curBank = NULL;
            break;
        case PREPROCESS_ROM_BANKSIZE:
            // size
            if(IsStrNum(GetNextWord())) {
                bankSizes[BANKTYPE_ROM] = StrToInt(szTemp);
                if(bankSizes[BANKTYPE_ROM] > MAX_BANKSIZE) {
                    error(ERR_BANKSIZE,bankSizes[BANKTYPE_ROM],MAX_BANKSIZE);
                    bankSizes[BANKTYPE_ROM] = MAX_BANKSIZE;
                }
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            if(PeekNextWord()[0]==',') {
                GetNextWord();
                CheckRomBank();
                if(IsStrNum(GetNextWord())) {
                    curBank->maxsize = (StrToInt(szTemp));
                } else {
                    error(ERR_INTEXP);
                    PREP_OK = FALSE;
                }
            }
            break;
        case PREPROCESS_ROM_BANK:
            // label
            if(!IsStringLabel(GetNextWord())) {
                error(ERR_BADLABEL,szTemp);
                strcpy(szTemp,"");
            }
            SetBank(BANKTYPE_ROM, szTemp);
            break;
        default:
            error(ERR_PREPROCESSORID,szTemp);
            PREP_OK = FALSE;
        }
        break;

        /**********************************************************************/
    case PREPROCESS_CHR:   
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        switch(code=CheckSubList(code)) {
        case PREPROCESS_CHR_BANKSIZE:
            // size
            if(IsStrNum(GetNextWord())) {
                bankSizes[BANKTYPE_CHR] = (StrToInt(szTemp));
                if(bankSizes[BANKTYPE_CHR] > MAX_BANKSIZE) {
                    error(ERR_BANKSIZE,bankSizes[BANKTYPE_CHR],MAX_BANKSIZE);
                    bankSizes[BANKTYPE_CHR] = MAX_BANKSIZE;
                }
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            if(PeekNextWord()[0]==',') {
                GetNextWord();
                if(IsStrNum(GetNextWord())) {
                    curBank->maxsize = (StrToInt(szTemp));
                } else {
                    error(ERR_INTEXP);
                    PREP_OK = FALSE;
                }
            }
            break;
        case PREPROCESS_CHR_BANK:
            // label
            if(!IsStringLabel(GetNextWord())) {
                error(ERR_BADLABEL,szTemp);
                strcpy(szTemp,"");
            }
            SetBank(BANKTYPE_CHR, szTemp);
            break;
        case PREPROCESS_CHR_END:
            CheckChrBank();
            curBank = NULL;
            break;

        default:
            error(ERR_PREPROCESSORID,szTemp);
            PREP_OK = FALSE;
        }
        break;

        /**********************************************************************/
    case PREPROCESS_INES:
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        switch(code=CheckSubList(code)) {
        case PREPROCESS_INES_MAPPER:
            // (number|"name")
            if(GetNextWord()[0]=='"') {
                if(DoString()) {
                    if((index=StrInStrint(szString, siMappers))==-1)
                        error(ERR_UNKMAPPER,szString);
                    else {
                        romHeader.mapper = siMappers[index].index;
                        PREP_OK = TRUE;
                    }
                }
            } else if(IsStrNum(szTemp)) {
                romHeader.mapper = ConfirmChar(StrToInt(szTemp));
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            break;
        case PREPROCESS_INES_MIRRORING:
            // (number|"name")
            if(GetNextWord()[0]=='"') {
                if(DoString()) {
                    if((index=StrInStrint(szString, siMirroring))==-1)
                        error(ERR_UNKMIRRORING,szString);
                    else {
                        romHeader.mirroring = siMirroring[index].index;
                        PREP_OK = TRUE;
                    }
                }
            } else if(IsStrNum(szTemp)) {
                romHeader.mirroring = ConfirmChar(StrToInt(szTemp));
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            break;
        case PREPROCESS_INES_BATTERY:
            romHeader.battery = PreprocessCheckYesNo(&PREP_OK);
            break;
        case PREPROCESS_INES_TRAINER:
            romHeader.trainer = PreprocessCheckYesNo(&PREP_OK);
            break;
        case PREPROCESS_INES_FOURSCREEN:
            romHeader.fourscreen = PreprocessCheckYesNo(&PREP_OK);
            break; 
        case PREPROCESS_INES_PRGREPEAT:
            if(IsStrNum(GetNextWord())) {
                romHeader.prgrepeat = ConfirmChar(StrToInt(szTemp));
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            break;
        case PREPROCESS_INES_CHRREPEAT:
            if(IsStrNum(GetNextWord())) {
                romHeader.chrrepeat = ConfirmChar(StrToInt(szTemp));
                PREP_OK = TRUE;
            } else
                error(ERR_INTEXP);
            break;  
        case PREPROCESS_INES_OFF:
            cfg.output.enableHeader = FALSE;
            break;
        default:
            error(ERR_PREPROCESSORID,szTemp);
            PREP_OK = FALSE;
        }
        break;

        /**********************************************************************/
    case PREPROCESS_INTERRUPT:  
        if(InFalseIfDef()) break;
        PREP_OK = TRUE;
        if(!PRECOMPILING) switch(code=CheckSubList(code)) {
            case PREPROCESS_INTERRUPT_NMI:
            case PREPROCESS_INTERRUPT_START:
            case PREPROCESS_INTERRUPT_IRQ:
                PREP_OK = PreprocessInterrupt(code);
                break;
            default:
                error(ERR_PREPROCESSORID,szTemp);
                PREP_OK = FALSE;
            }
        break;

        /**********************************************************************/
    default:
        error(ERR_PREPROCESSORID,szTemp);
    }
    if(!PREP_OK)
        SkipLine(TRUE); // if there was an error, skip to the next line

    return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
BOOL CPreprocessor::ProcessHashDefine(CPreprocessorTokenParser* pcParser)
{
	CExternalString		cIdentifier;
	CExternalString		cArgument;
	BOOL				bResult;
	CDefine*			pcDefine;
	CPPText*			pcText;
	CPPReplacement*		pcReplacement;
	int					iReplaceArg;
	CPPToken*			pcToken;
	BOOL				bAllocated;
	BOOL				bAllowWhiteSpace;
	CDefine*			pcExisting;
	CDefine*			pcNew;
	CChars				sz;

	bResult = pcParser->GetIdentifier(&cIdentifier);
	if (bResult)
	{
		pcDefine = AddDefine(&cIdentifier);
		if (pcDefine)
		{
			pcExisting = NULL;
		}
		else
		{
			pcExisting = GetDefine(&cIdentifier);
			pcDefine = (CDefine*)malloc(sizeof(CDefine));
			pcDefine->Init(mcDefines.mcDefinesTree.GetIndexForNew(cIdentifier.msz, cIdentifier.miLen), mcDefines.muiID, NULL);
		}

		bResult = pcParser->GetExactDecorator('(', FALSE);
		if (bResult)
		{
			pcDefine->SetBracketed(TRUE);
			for (;;)
			{
				bResult = pcParser->GetExactDecorator(')');
				if (bResult)
				{
					break;
				}
				bResult = pcParser->GetIdentifier(&cArgument);
				if (bResult)
				{
					pcDefine->AddArgument(&cArgument);
					pcParser->GetExactDecorator(',');
				}
				else
				{
					//Expected an Identifier.
				}
			}
		}

		bAllowWhiteSpace = FALSE;
		while (pcParser->HasToken())
		{
			bAllocated = FALSE;
			pcToken = pcParser->GetToken();
			if (pcToken->IsText())
			{
				pcText = (CPPText*)pcToken;
				if (pcText->meType == PPT_Identifier)
				{
					iReplaceArg = pcDefine->mcArguments.GetIndex(pcText->mcText.msz, pcText->mcText.miLen);
					if (iReplaceArg != -1)
					{
						pcReplacement = CPPReplacement::Construct(mpcStack->Add(sizeof(CPPReplacement)));
						pcReplacement->Init(pcDefine->miIndex, iReplaceArg, -1, -1);
						pcToken = pcReplacement;
						bAllocated = TRUE;
					}
				}
			}

			if (!pcToken->IsWhiteSpace() || bAllowWhiteSpace)  //Stop leading whitespace from being added.
			{
				bAllowWhiteSpace = TRUE;
				if (!bAllocated)
				{
					pcToken = DuplicatePPToken(pcToken, mpcStack);
				}
				pcDefine->AddReplacmentToken(pcToken);
			}

			pcParser->NextToken();
		}

		bResult = TRUE;
		if (pcExisting)
		{
			if (!pcExisting->Equals(pcDefine))
			{
				//Removing a define will not change the index or the ID of our new define.  Phew.
				RemoveDefine(&cIdentifier);
				pcNew = AddDefine(&cIdentifier, pcDefine);
				if (!pcNew)
				{
					sz.Init("Could not redefine #define ");
					sz.AppendSubString(cIdentifier.msz, cIdentifier.EndInclusive()+1);
					sz.Append(".  Probably index or ID is different.");
					gcUserError.Set(sz.Text());
					sz.Kill();
					bResult = FALSE;
				}
			}
			else
			{
				//Only kill the define if the existing one is identical.
				//pcNew depends on the allocations in the non-identical define case.
				pcDefine->Kill();
			}
			free(pcDefine);
		}
	}
	else
	{
		gcUserError.Set("Could not get an identifier for a #define.  Add one.");
	}
	return bResult;
}
//////////////////////////////////////////////////////////////////////////
//																		//
//																		//
//////////////////////////////////////////////////////////////////////////
void CPreprocessor::DeltaDefines(CArrayNamedDefines* pcDelta, CMemoryStackExtended* pcStack)
{
	int					i;
	CNamedDefine*		pcNamedDefine;
	CDefine*			pcExisting;
	CDefine*			pcDefine;
	CDefine*			pcNew;
	BOOL				bResult;
	CExternalString		cIdentifier;
	CChars				sz;

	for (i = 0; i < pcDelta->NumElements(); i++)
	{
		pcNamedDefine = pcDelta->Get(i);
		cIdentifier.Init(pcNamedDefine->mszName.Text(), pcNamedDefine->mszName.Length());
		if (pcNamedDefine->miFlags & NAMED_DEFINE_FLAGS_UNDEFFED)
		{
			RemoveDefine(&cIdentifier);
		}
		else
		{
			pcDefine = AddDefine(&cIdentifier);
			if (pcDefine)
			{
				pcExisting = NULL;
			}
			else
			{
				pcExisting = GetDefine(pcNamedDefine->mszName.Text());
				pcDefine = (CDefine*)malloc(sizeof(CDefine));
				pcDefine->Init(mcDefines.mcDefinesTree.GetIndexForNew(cIdentifier.msz, cIdentifier.miLen), mcDefines.muiID, NULL);
			}

			pcDefine->mcArguments.Copy(&pcNamedDefine->mcArguments);
			pcDefine->mcReplacement.Copy(&pcNamedDefine->mcReplacement, pcStack);
			pcDefine->SetBracketed(pcNamedDefine->IsBacketed());

			bResult = TRUE;
			if (pcExisting)
			{
				if (!pcExisting->Equals(pcDefine))
				{
					//Removing a define will not change the index or the ID of our new define.  Phew.
					RemoveDefine(&cIdentifier);
					pcNew = AddDefine(&cIdentifier, pcDefine);
					if (!pcNew)
					{
						sz.Init("Could not redefine #define ");
						sz.AppendSubString(cIdentifier.msz, cIdentifier.EndInclusive()+1);
						sz.Append(".  Probably index or ID is different.");
						gcUserError.Set(sz.Text());
						sz.Kill();
						bResult = FALSE;
					}
				}
				else
				{
					//Only kill the define if the existing one is identical.
					//pcNew depends on the allocations in the non-identical define case.
					pcDefine->Kill();
				}
				free(pcDefine);
			}
		}
	}
}