void CPPAbstractHolder::Copy(CPPAbstractHolder* pcCast, CMemoryStackExtended* pcStack) { int i; CPPToken* pcToken; Init(pcCast->miLine, pcCast->miColumn); for (i = 0; i < pcCast->mcTokens.mcArray.NumElements(); i++) { pcToken = DuplicatePPToken(*pcCast->mcTokens.mcArray.Get(i), pcStack); mcTokens.Add(&pcToken); } }
////////////////////////////////////////////////////////////////////////// // // // // ////////////////////////////////////////////////////////////////////////// BOOL CPreprocessor::ExpandTokenIfNecessary(CPPToken* pcToken, CPPTokenHolder* pcDest, CPreprocessorTokenParser* pcParser, BOOL bAllowDefined, int iDepth) { CPPToken* pcNewToken; CPPText* pcText; BOOL bResult; CPPReplacement* pcReplacement; if (pcToken->IsText()) { pcText = (CPPText*)pcToken; if (pcText->meType == PPT_Identifier) { bResult = ProcessIdentifier(pcDest, pcText, pcParser, bAllowDefined, iDepth); return bResult; } else { pcNewToken = DuplicatePPToken(pcToken, mpcStack); pcDest->Add(&pcNewToken); pcParser->NextToken(); return TRUE; } } else if (pcToken->IsReplacement()) { pcReplacement = (CPPReplacement*)pcToken; ExpandReplacement(pcReplacement, pcDest, bAllowDefined, iDepth); pcParser->NextToken(); return TRUE; } else { pcNewToken = DuplicatePPToken(pcToken, mpcStack); pcDest->Add(&pcNewToken); pcParser->NextToken(); return TRUE; } };
void CCBlock::Copy(CPPToken* pcSource, CMemoryStackExtended* pcStack) { CCBlock* pcCast; CPPToken* pcToken; int i; if (pcSource->IsBlock()) { pcCast = (CCBlock*)pcSource; Init(pcCast->miLine, pcCast->miColumn); for (i = 0; i < pcCast->mcTokens.mcArray.NumElements(); i++) { pcToken = DuplicatePPToken(*pcCast->mcTokens.mcArray.Get(i), pcStack); mcTokens.Add(&pcToken); } mpcBlockSet = pcCast->mpcBlockSet; mpcStack = pcCast->mpcStack; } }
////////////////////////////////////////////////////////////////////////// // // // // ////////////////////////////////////////////////////////////////////////// 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::AddTokenToArgument(CPPTokenHolder* pcArgument, CPPToken* pcToken) { pcToken = DuplicatePPToken(pcToken, mpcStack); pcArgument->Add(&pcToken); }
////////////////////////////////////////////////////////////////////////// // // // // ////////////////////////////////////////////////////////////////////////// BOOL CPreprocessor::ProcessIdentifier(CPPTokenHolder* pcDest, CPPText* pcText, CPreprocessorTokenParser* pcParser, BOOL bAllowDefined, int iDepth) { CPPToken* pcToken; CDefine* pcDefine; BOOL bResult; CPPAbstractHolder* pcHolder; CPPText* pcDecorator; char* pcValue; int i; CPPTokenHolder* pcTokenHolder; SDefineArgument* psArguments; int iArgIndex; pcDefine = mcDefines.GetDefine(&pcText->mcText); if (pcDefine) { iArgIndex = -1; if (pcDefine->IsBacketed()) { pcParser->NextToken(); psArguments = mcArguments.Add(pcDefine->miIndex); iArgIndex = mcArguments.mcDefineToArguments.GetIndex(psArguments); bResult = FindArguments(pcParser, &psArguments->mcArguments); if ((!bResult) || (psArguments->mcArguments.NumElements() != pcDefine->mcArguments.NumElements())) { //Expected arguments but there weren't any. for (i = 0; i < psArguments->mcArguments.NumElements(); i++) { pcTokenHolder = psArguments->mcArguments.Get(i); pcTokenHolder->Kill(); } mcArguments.Remove(pcDefine->miIndex); return FALSE; } } else { pcParser->NextToken(); } if (pcDefine->mcReplacement.mcTokens.mcArray.NumElements() > 0) { pcHolder = ADD_TOKEN(CPPHolder, &pcDest->mcArray, mpcStack->Add(sizeof(CPPHolder))); pcHolder->Init(4, -1, -1); ExpandDefined(pcHolder, pcDefine, bAllowDefined, iDepth+1); } //I'm not sure if it's safe to do this anymore... another define might refer to it. if (iArgIndex != -1) { psArguments = mcArguments.Get(pcDefine->miIndex); for (i = 0; i < psArguments->mcArguments.NumElements(); i++) { pcTokenHolder = psArguments->mcArguments.Get(i); pcTokenHolder->Kill(); } mcArguments.Remove(pcDefine->miIndex); } return TRUE; } else if (bAllowDefined) { bResult = pcParser->GetExactIdentifier("defined", TRUE, TRUE); if (bResult) { pcParser->GetExactDecorator('('); pcParser->SkipWhiteSpace(); pcToken = pcParser->GetToken(); pcDecorator = CPPText::Construct(mpcStack->Add(sizeof(CPPText))); pcValue = (char*)gcTokenStrings.Add(1); *pcValue = '0'; pcDecorator->Init(PPT_Number, -1, -1, pcValue, pcValue+1); if (pcToken) { if (pcToken->IsText()) { pcText = (CPPText*)pcToken; if (pcText->meType == PPT_Identifier) { pcDefine = mcDefines.GetDefine(&pcText->mcText); pcParser->NextToken(); if (pcDefine) { *pcValue = '1'; } } } pcDest->Add((CPPToken**)&pcDecorator); pcParser->SkipWhiteSpace(); pcParser->GetExactDecorator(')'); } return TRUE; } } pcToken = DuplicatePPToken(pcText, mpcStack); pcDest->Add(&pcToken); pcParser->NextToken(); return TRUE; }