1*78bc99aaSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*78bc99aaSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*78bc99aaSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*78bc99aaSAndrew Rist * distributed with this work for additional information 6*78bc99aaSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*78bc99aaSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*78bc99aaSAndrew Rist * "License"); you may not use this file except in compliance 9*78bc99aaSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*78bc99aaSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*78bc99aaSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*78bc99aaSAndrew Rist * software distributed under the License is distributed on an 15*78bc99aaSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*78bc99aaSAndrew Rist * KIND, either express or implied. See the License for the 17*78bc99aaSAndrew Rist * specific language governing permissions and limitations 18*78bc99aaSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*78bc99aaSAndrew Rist *************************************************************/ 21cdf0e10cSrcweir 22cdf0e10cSrcweir #include <precomp.h> 23cdf0e10cSrcweir #include "preproc.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir 26cdf0e10cSrcweir // NOT FULLY DEFINED SERVICES 27cdf0e10cSrcweir #include <cosv/tpl/tpltools.hxx> 28cdf0e10cSrcweir #include "all_toks.hxx" 29cdf0e10cSrcweir #include "defdescr.hxx" 30cdf0e10cSrcweir #include <tools/tkpchars.hxx> 31cdf0e10cSrcweir #include "c_rcode.hxx" 32cdf0e10cSrcweir 33cdf0e10cSrcweir 34cdf0e10cSrcweir namespace cpp 35cdf0e10cSrcweir { 36cdf0e10cSrcweir 37cdf0e10cSrcweir 38cdf0e10cSrcweir PreProcessor::F_TOKENPROC PreProcessor::aTokProcs[PreProcessor::state_MAX] = 39cdf0e10cSrcweir { 40cdf0e10cSrcweir &PreProcessor::On_plain, 41cdf0e10cSrcweir &PreProcessor::On_expect_macro_bracket_left, 42cdf0e10cSrcweir &PreProcessor::On_expect_macro_param 43cdf0e10cSrcweir }; 44cdf0e10cSrcweir 45cdf0e10cSrcweir 46cdf0e10cSrcweir PreProcessor::PreProcessor() 47cdf0e10cSrcweir : pCppExplorer(0), 48cdf0e10cSrcweir pSourceText(0), 49cdf0e10cSrcweir pCurValidDefines(0), 50cdf0e10cSrcweir // aTokens, 51cdf0e10cSrcweir eState(plain), 52cdf0e10cSrcweir pCurMacro(0), 53cdf0e10cSrcweir dpCurMacroName(0), 54cdf0e10cSrcweir // aCurMacroParams, 55cdf0e10cSrcweir aCurParamText(60000), 56cdf0e10cSrcweir nBracketInParameterCounter(0) 57cdf0e10cSrcweir // aBlockedMacroNames 58cdf0e10cSrcweir { 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir PreProcessor::~PreProcessor() 62cdf0e10cSrcweir { 63cdf0e10cSrcweir } 64cdf0e10cSrcweir 65cdf0e10cSrcweir void 66cdf0e10cSrcweir PreProcessor::AssignPartners( CodeExplorer & o_rCodeExplorer, 67cdf0e10cSrcweir CharacterSource & o_rCharSource, 68cdf0e10cSrcweir const MacroMap & i_rCurValidDefines ) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir pCppExplorer = &o_rCodeExplorer; 71cdf0e10cSrcweir pSourceText = &o_rCharSource; 72cdf0e10cSrcweir pCurValidDefines = &i_rCurValidDefines; 73cdf0e10cSrcweir } 74cdf0e10cSrcweir 75cdf0e10cSrcweir void 76cdf0e10cSrcweir PreProcessor::Process_Token( cpp::Token & let_drToken ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir csv_assert(pCppExplorer != 0); // Implies pSourceText and pCurValidDefines. 79cdf0e10cSrcweir 80cdf0e10cSrcweir (this->*aTokProcs[eState])(let_drToken); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir void 84cdf0e10cSrcweir PreProcessor::On_plain( cpp::Token & let_drToken ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir if ( let_drToken.TypeId() == Tid_Identifier ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir if (CheckForDefine(let_drToken)) 89cdf0e10cSrcweir return; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir pCppExplorer->Process_Token(let_drToken); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir void 96cdf0e10cSrcweir PreProcessor::On_expect_macro_bracket_left( cpp::Token & let_drToken ) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir if ( let_drToken.TypeId() == Tid_Bracket_Left ) 99cdf0e10cSrcweir { 100cdf0e10cSrcweir aCurParamText.seekp(0); 101cdf0e10cSrcweir eState = expect_macro_param; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir else 104cdf0e10cSrcweir { 105cdf0e10cSrcweir pCppExplorer->Process_Token(*dpCurMacroName); 106cdf0e10cSrcweir dpCurMacroName = 0; 107cdf0e10cSrcweir pCppExplorer->Process_Token(let_drToken); 108cdf0e10cSrcweir eState = plain; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir } 111cdf0e10cSrcweir 112cdf0e10cSrcweir void 113cdf0e10cSrcweir PreProcessor::On_expect_macro_param( cpp::Token & let_drToken ) 114cdf0e10cSrcweir { 115cdf0e10cSrcweir if ( let_drToken.TypeId() == Tid_Bracket_Left ) 116cdf0e10cSrcweir nBracketInParameterCounter++; 117cdf0e10cSrcweir else if ( let_drToken.TypeId() == Tid_Bracket_Right ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir if ( nBracketInParameterCounter > 0 ) 120cdf0e10cSrcweir nBracketInParameterCounter--; 121cdf0e10cSrcweir else 122cdf0e10cSrcweir { 123cdf0e10cSrcweir if ( NOT csv::no_str(aCurParamText.c_str()) ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir aCurMacroParams.push_back( String(aCurParamText.c_str()) ); 126cdf0e10cSrcweir } 127cdf0e10cSrcweir csv_assert( aCurMacroParams.size() == pCurMacro->ParamCount() ); 128cdf0e10cSrcweir 129cdf0e10cSrcweir InterpretMacro(); 130cdf0e10cSrcweir eState = plain; 131cdf0e10cSrcweir return; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir } 134cdf0e10cSrcweir else if ( let_drToken.TypeId() == Tid_Comma AND nBracketInParameterCounter == 0 ) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir aCurMacroParams.push_back( String (aCurParamText.c_str()) ); 137cdf0e10cSrcweir aCurParamText.seekp(0); 138cdf0e10cSrcweir return; 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir // KORR_FUTURE: 142cdf0e10cSrcweir // If in future whitespace is parsed also, that should match exactly and the 143cdf0e10cSrcweir // safety spaces, " ", here should be removed. 144cdf0e10cSrcweir aCurParamText << let_drToken.Text() << " "; 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir bool 148cdf0e10cSrcweir PreProcessor::CheckForDefine( cpp::Token & let_drToken ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir String sTokenText(let_drToken.Text()); 151cdf0e10cSrcweir pCurMacro = csv::value_from_map( *pCurValidDefines, sTokenText ); 152cdf0e10cSrcweir if (pCurMacro == 0 ) 153cdf0e10cSrcweir return false; 154cdf0e10cSrcweir for ( StringVector::const_iterator it = aBlockedMacroNames.begin(); 155cdf0e10cSrcweir it != aBlockedMacroNames.end(); 156cdf0e10cSrcweir ++it ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir if ( strcmp( (*it).c_str(), let_drToken.Text() ) == 0 ) 159cdf0e10cSrcweir return false; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir 162cdf0e10cSrcweir if ( pCurMacro->DefineType() == DefineDescription::type_define ) 163cdf0e10cSrcweir { 164cdf0e10cSrcweir delete &let_drToken; 165cdf0e10cSrcweir 166cdf0e10cSrcweir aCurParamText.seekp(0); 167cdf0e10cSrcweir pCurMacro->GetDefineText(aCurParamText); 168cdf0e10cSrcweir 169cdf0e10cSrcweir if ( aCurParamText.tellp() > 1 ) 170cdf0e10cSrcweir pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir else // ( pCurMacro->DefineType() == DefineDescription::type_macro ) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir dpCurMacroName = &let_drToken; 175cdf0e10cSrcweir eState = expect_macro_bracket_left; 176cdf0e10cSrcweir csv::erase_container( aCurMacroParams ); 177cdf0e10cSrcweir aCurParamText.seekp(0); 178cdf0e10cSrcweir nBracketInParameterCounter = 0; 179cdf0e10cSrcweir } // endif 180cdf0e10cSrcweir 181cdf0e10cSrcweir return true; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir void 185cdf0e10cSrcweir PreProcessor::UnblockMacro( const char * i_sMacroName ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir for ( StringVector::iterator it = aBlockedMacroNames.begin(); 188cdf0e10cSrcweir it != aBlockedMacroNames.end(); 189cdf0e10cSrcweir ++it ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir if ( strcmp( (*it), i_sMacroName ) == 0 ) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir aBlockedMacroNames.erase(it); 194cdf0e10cSrcweir break; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir } /// end for 197cdf0e10cSrcweir } 198cdf0e10cSrcweir 199cdf0e10cSrcweir void 200cdf0e10cSrcweir PreProcessor::InterpretMacro() 201cdf0e10cSrcweir { 202cdf0e10cSrcweir aCurParamText.seekp(0); 203cdf0e10cSrcweir pCurMacro->GetMacroText(aCurParamText, aCurMacroParams); 204cdf0e10cSrcweir 205cdf0e10cSrcweir if ( NOT csv::no_str(aCurParamText.c_str()) ) 206cdf0e10cSrcweir { 207cdf0e10cSrcweir aCurParamText.seekp(-1, csv::cur); 208cdf0e10cSrcweir aCurParamText << " #unblock-" << dpCurMacroName->Text() << " "; 209cdf0e10cSrcweir 210cdf0e10cSrcweir pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 211cdf0e10cSrcweir String sCurMacroName(dpCurMacroName->Text()); 212cdf0e10cSrcweir aBlockedMacroNames.insert( aBlockedMacroNames.begin(), sCurMacroName ); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir delete dpCurMacroName; 216cdf0e10cSrcweir dpCurMacroName = 0; 217cdf0e10cSrcweir pCurMacro = 0; 218cdf0e10cSrcweir csv::erase_container(aCurMacroParams); 219cdf0e10cSrcweir aCurParamText.seekp(0); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir 223cdf0e10cSrcweir } // end namespace cpp 224cdf0e10cSrcweir 225cdf0e10cSrcweir 226