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 // NOT FULLY DEFINED SERVICES 26 #include <cosv/tpl/tpltools.hxx> 27 #include "all_toks.hxx" 28 #include "defdescr.hxx" 29 #include <tools/tkpchars.hxx> 30 #include "c_rcode.hxx" 31 32 namespace cpp 33 { 34 35 PreProcessor::F_TOKENPROC PreProcessor::aTokProcs[PreProcessor::state_MAX] = 36 { 37 &PreProcessor::On_plain, 38 &PreProcessor::On_expect_macro_bracket_left, 39 &PreProcessor::On_expect_macro_param 40 }; 41 42 PreProcessor::PreProcessor() 43 : pCppExplorer(0), 44 pSourceText(0), 45 pCurValidDefines(0), 46 // aTokens, 47 eState(plain), 48 pCurMacro(0), 49 dpCurMacroName(0), 50 // aCurMacroParams, 51 aCurParamText(60000), 52 nBracketInParameterCounter(0) 53 // aBlockedMacroNames 54 { 55 } 56 57 PreProcessor::~PreProcessor() 58 { 59 } 60 61 void 62 PreProcessor::AssignPartners( CodeExplorer & o_rCodeExplorer, 63 CharacterSource & o_rCharSource, 64 const MacroMap & i_rCurValidDefines ) 65 { 66 pCppExplorer = &o_rCodeExplorer; 67 pSourceText = &o_rCharSource; 68 pCurValidDefines = &i_rCurValidDefines; 69 } 70 71 void 72 PreProcessor::Process_Token( cpp::Token & let_drToken ) 73 { 74 csv_assert(pCppExplorer != 0); // Implies pSourceText and pCurValidDefines. 75 76 (this->*aTokProcs[eState])(let_drToken); 77 } 78 79 void 80 PreProcessor::On_plain( cpp::Token & let_drToken ) 81 { 82 if ( let_drToken.TypeId() == Tid_Identifier ) 83 { 84 if (CheckForDefine(let_drToken)) 85 return; 86 } 87 88 pCppExplorer->Process_Token(let_drToken); 89 } 90 91 void 92 PreProcessor::On_expect_macro_bracket_left( cpp::Token & let_drToken ) 93 { 94 if ( let_drToken.TypeId() == Tid_Bracket_Left ) 95 { 96 aCurParamText.seekp(0); 97 eState = expect_macro_param; 98 } 99 else 100 { 101 pCppExplorer->Process_Token(*dpCurMacroName); 102 dpCurMacroName = 0; 103 pCppExplorer->Process_Token(let_drToken); 104 eState = plain; 105 } 106 } 107 108 void 109 PreProcessor::On_expect_macro_param( cpp::Token & let_drToken ) 110 { 111 if ( let_drToken.TypeId() == Tid_Bracket_Left ) 112 nBracketInParameterCounter++; 113 else if ( let_drToken.TypeId() == Tid_Bracket_Right ) 114 { 115 if ( nBracketInParameterCounter > 0 ) 116 nBracketInParameterCounter--; 117 else 118 { 119 if ( NOT csv::no_str(aCurParamText.c_str()) ) 120 { 121 aCurMacroParams.push_back( String(aCurParamText.c_str()) ); 122 } 123 csv_assert( aCurMacroParams.size() == pCurMacro->ParamCount() ); 124 125 InterpretMacro(); 126 eState = plain; 127 return; 128 } 129 } 130 else if ( let_drToken.TypeId() == Tid_Comma AND nBracketInParameterCounter == 0 ) 131 { 132 aCurMacroParams.push_back( String (aCurParamText.c_str()) ); 133 aCurParamText.seekp(0); 134 return; 135 } 136 137 // KORR_FUTURE: 138 // If in future whitespace is parsed also, that should match exactly and the 139 // safety spaces, " ", here should be removed. 140 aCurParamText << let_drToken.Text() << " "; 141 } 142 143 bool 144 PreProcessor::CheckForDefine( cpp::Token & let_drToken ) 145 { 146 String sTokenText(let_drToken.Text()); 147 pCurMacro = csv::value_from_map( *pCurValidDefines, sTokenText ); 148 if (pCurMacro == 0 ) 149 return false; 150 for ( StringVector::const_iterator it = aBlockedMacroNames.begin(); 151 it != aBlockedMacroNames.end(); 152 ++it ) 153 { 154 if ( strcmp( (*it).c_str(), let_drToken.Text() ) == 0 ) 155 return false; 156 } 157 158 if ( pCurMacro->DefineType() == DefineDescription::type_define ) 159 { 160 delete &let_drToken; 161 162 aCurParamText.seekp(0); 163 pCurMacro->GetDefineText(aCurParamText); 164 165 if ( aCurParamText.tellp() > 1 ) 166 pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 167 } 168 else // ( pCurMacro->DefineType() == DefineDescription::type_macro ) 169 { 170 dpCurMacroName = &let_drToken; 171 eState = expect_macro_bracket_left; 172 csv::erase_container( aCurMacroParams ); 173 aCurParamText.seekp(0); 174 nBracketInParameterCounter = 0; 175 } // endif 176 177 return true; 178 } 179 180 void 181 PreProcessor::UnblockMacro( const char * i_sMacroName ) 182 { 183 for ( StringVector::iterator it = aBlockedMacroNames.begin(); 184 it != aBlockedMacroNames.end(); 185 ++it ) 186 { 187 if ( strcmp( (*it), i_sMacroName ) == 0 ) 188 { 189 aBlockedMacroNames.erase(it); 190 break; 191 } 192 } // end for 193 } 194 195 void 196 PreProcessor::InterpretMacro() 197 { 198 aCurParamText.seekp(0); 199 pCurMacro->GetMacroText(aCurParamText, aCurMacroParams); 200 201 if ( NOT csv::no_str(aCurParamText.c_str()) ) 202 { 203 aCurParamText.seekp(-1, csv::cur); 204 aCurParamText << " #unblock-" << dpCurMacroName->Text() << " "; 205 206 pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 207 String sCurMacroName(dpCurMacroName->Text()); 208 aBlockedMacroNames.insert( aBlockedMacroNames.begin(), sCurMacroName ); 209 } 210 211 delete dpCurMacroName; 212 dpCurMacroName = 0; 213 pCurMacro = 0; 214 csv::erase_container(aCurMacroParams); 215 aCurParamText.seekp(0); 216 } 217 218 219 } // end namespace cpp 220 221 /* vim: set noet sw=4 ts=4: */ 222