static void cxxParserParseNextTokenApplyReplacement( const cppMacroInfo * pInfo, CXXToken * pParameterChainToken ) { CXX_DEBUG_ENTER(); CXX_DEBUG_ASSERT(pInfo,"Info must be not null"); CXX_DEBUG_ASSERT(pInfo->replacements,"There should be a replacement"); if(!pInfo->hasParameterList) { CXX_DEBUG_ASSERT(!pParameterChainToken,"This shouldn't have been extracted"); } CXXTokenChain * pParameters = NULL; const char ** aParameters = NULL; int iParameterCount = 0; if(pInfo->hasParameterList && pParameterChainToken && (pParameterChainToken->pChain->iCount >= 3)) { // kill parenthesis cxxTokenChainDestroyFirst(pParameterChainToken->pChain); cxxTokenChainDestroyLast(pParameterChainToken->pChain); pParameters = cxxTokenChainSplitOnComma( pParameterChainToken->pChain ); aParameters = (const char **)eMalloc(sizeof(const char *) * pParameters->iCount); CXXToken * pParam = cxxTokenChainFirst(pParameters); while(pParam) { aParameters[iParameterCount] = vStringValue(pParam->pszWord); iParameterCount++; pParam = pParam->pNext; } CXX_DEBUG_ASSERT(iParameterCount == pParameters->iCount,"Bad number of parameters found"); } vString * pReplacement = cppBuildMacroReplacement(pInfo,aParameters,iParameterCount); if(pParameters) { cxxTokenChainDestroy(pParameters); eFree(aParameters); } CXX_DEBUG_PRINT("Applying complex replacement '%s'",vStringValue(pReplacement)); cppUngetString(vStringValue(pReplacement),vStringLength(pReplacement)); vStringDelete(pReplacement); CXX_DEBUG_LEAVE(); }
void cxxTokenAPIDone(void) { CXXToken * t; while((t = cxxTokenChainTakeFirst(g_pTokenPool))) cxxTokenForceDestroy(t); cxxTokenChainDestroy(g_pTokenPool); }
void cxxScopeDone(void) { cxxTokenChainDestroy(g_pScope); if(g_szScopeName) { vStringDelete(g_szScopeName); g_szScopeName = NULL; } }
void cxxParserCleanup (langType language __unused__, boolean initialized __unused__) { if(g_bFirstRun) return; // didn't run at all // This function is used as finalizer for both C and C++ parsers. // The next line forces this function to be called only once g_bFirstRun = TRUE; if(g_cxx.pTokenChain) cxxTokenChainDestroy(g_cxx.pTokenChain); if(g_cxx.pTemplateTokenChain) cxxTokenChainDestroy(g_cxx.pTemplateTokenChain); cxxScopeDone(); cxxTokenAPIDone(); }
// // Parses a template<anything> prefix. // The parsed template parameter definition is stored in a separate token chain. // boolean cxxParserParseTemplatePrefix(void) { CXX_DEBUG_ENTER(); CXX_DEBUG_ASSERT(cxxTokenTypeIs(cxxTokenChainLast(g_cxx.pTokenChain),CXXTokenTypeKeyword),"We should be pointing at the template keyword here"); cxxTokenChainDestroyLast(g_cxx.pTokenChain); // kill the template keyword if(!cxxParserParseUpToOneOf(CXXTokenTypeSmallerThanSign | CXXTokenTypeEOF | CXXTokenTypeSemicolon)) { CXX_DEBUG_LEAVE_TEXT("Failed to parse up to the < sign"); return FALSE; } if(cxxTokenTypeIsOneOf(g_cxx.pToken,CXXTokenTypeEOF | CXXTokenTypeSemicolon)) { CXX_DEBUG_LEAVE_TEXT("Found EOF or semicolon: assuming this is unparseable"); cxxParserNewStatement(); return TRUE; // tolerate syntax error } CXXTokenChain * pSave = g_cxx.pTokenChain; g_cxx.pTokenChain = cxxTokenChainCreate(); cxxTokenChainAppend(g_cxx.pTokenChain,cxxTokenChainTakeLast(pSave)); if(!cxxParserParseTemplatePrefixAngleBrackets()) { CXX_DEBUG_LEAVE_TEXT("Failed to parse angle brackets"); cxxTokenChainDestroy(pSave); return FALSE; } if(g_cxx.pTemplateTokenChain) cxxTokenChainDestroy(g_cxx.pTemplateTokenChain); g_cxx.pTemplateTokenChain = g_cxx.pTokenChain; g_cxx.pTokenChain = pSave; CXX_DEBUG_LEAVE(); return TRUE; }
// // Reset parser state: // - Clear the token chain // - Reset "seen" keywords // void cxxParserNewStatement(void) { cxxTokenChainClear(g_cxx.pTokenChain); if(g_cxx.pTemplateTokenChain) { cxxTokenChainDestroy(g_cxx.pTemplateTokenChain); g_cxx.pTemplateTokenChain = NULL; } g_cxx.uKeywordState = 0; // FIXME: this cpp handling of end/statement is kind of broken: // it works only because the moon is in the correct phase. cppEndStatement(); }
void cxxTokenForceDestroy(CXXToken * t) { if(!t) return; if(t->pChain) { cxxTokenChainDestroy(t->pChain); t->pChain = NULL; } CXX_DEBUG_ASSERT(t->pszWord,"There should be a word here"); vStringDelete(t->pszWord); eFree(t); }
void cxxTokenDestroy(CXXToken * t) { if(!t) return; if(t->pChain) { cxxTokenChainDestroy(t->pChain); t->pChain = NULL; } CXX_DEBUG_ASSERT(t->pszWord,"There should be a word here"); if(g_pTokenPool->iCount < CXX_TOKEN_POOL_MAXIMUM_SIZE) { // this won't actually release memory (but we're taking care // to do not create very large strings) vStringClear(t->pszWord); cxxTokenChainAppend(g_pTokenPool,t); } else { vStringDelete(t->pszWord); eFree(t); } }