////////////////////////////////////////////////////////////////////////// // // // // ////////////////////////////////////////////////////////////////////////// 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; }
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; }
// // 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; }
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()); } } }
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; }
// 바이너리 포맷으로 읽기 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; }
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); }
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(); }
// 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); } } } }