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