1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <precomp.h> 29 #include "preproc.hxx" 30 31 32 // NOT FULLY DEFINED SERVICES 33 #include <cosv/tpl/tpltools.hxx> 34 #include "all_toks.hxx" 35 #include "defdescr.hxx" 36 #include <tools/tkpchars.hxx> 37 #include "c_rcode.hxx" 38 39 40 namespace cpp 41 { 42 43 44 PreProcessor::F_TOKENPROC PreProcessor::aTokProcs[PreProcessor::state_MAX] = 45 { 46 &PreProcessor::On_plain, 47 &PreProcessor::On_expect_macro_bracket_left, 48 &PreProcessor::On_expect_macro_param 49 }; 50 51 52 PreProcessor::PreProcessor() 53 : pCppExplorer(0), 54 pSourceText(0), 55 pCurValidDefines(0), 56 // aTokens, 57 eState(plain), 58 pCurMacro(0), 59 dpCurMacroName(0), 60 // aCurMacroParams, 61 aCurParamText(60000), 62 nBracketInParameterCounter(0) 63 // aBlockedMacroNames 64 { 65 } 66 67 PreProcessor::~PreProcessor() 68 { 69 } 70 71 void 72 PreProcessor::AssignPartners( CodeExplorer & o_rCodeExplorer, 73 CharacterSource & o_rCharSource, 74 const MacroMap & i_rCurValidDefines ) 75 { 76 pCppExplorer = &o_rCodeExplorer; 77 pSourceText = &o_rCharSource; 78 pCurValidDefines = &i_rCurValidDefines; 79 } 80 81 void 82 PreProcessor::Process_Token( cpp::Token & let_drToken ) 83 { 84 csv_assert(pCppExplorer != 0); // Implies pSourceText and pCurValidDefines. 85 86 (this->*aTokProcs[eState])(let_drToken); 87 } 88 89 void 90 PreProcessor::On_plain( cpp::Token & let_drToken ) 91 { 92 if ( let_drToken.TypeId() == Tid_Identifier ) 93 { 94 if (CheckForDefine(let_drToken)) 95 return; 96 } 97 98 pCppExplorer->Process_Token(let_drToken); 99 } 100 101 void 102 PreProcessor::On_expect_macro_bracket_left( cpp::Token & let_drToken ) 103 { 104 if ( let_drToken.TypeId() == Tid_Bracket_Left ) 105 { 106 aCurParamText.seekp(0); 107 eState = expect_macro_param; 108 } 109 else 110 { 111 pCppExplorer->Process_Token(*dpCurMacroName); 112 dpCurMacroName = 0; 113 pCppExplorer->Process_Token(let_drToken); 114 eState = plain; 115 } 116 } 117 118 void 119 PreProcessor::On_expect_macro_param( cpp::Token & let_drToken ) 120 { 121 if ( let_drToken.TypeId() == Tid_Bracket_Left ) 122 nBracketInParameterCounter++; 123 else if ( let_drToken.TypeId() == Tid_Bracket_Right ) 124 { 125 if ( nBracketInParameterCounter > 0 ) 126 nBracketInParameterCounter--; 127 else 128 { 129 if ( NOT csv::no_str(aCurParamText.c_str()) ) 130 { 131 aCurMacroParams.push_back( String(aCurParamText.c_str()) ); 132 } 133 csv_assert( aCurMacroParams.size() == pCurMacro->ParamCount() ); 134 135 InterpretMacro(); 136 eState = plain; 137 return; 138 } 139 } 140 else if ( let_drToken.TypeId() == Tid_Comma AND nBracketInParameterCounter == 0 ) 141 { 142 aCurMacroParams.push_back( String (aCurParamText.c_str()) ); 143 aCurParamText.seekp(0); 144 return; 145 } 146 147 // KORR_FUTURE: 148 // If in future whitespace is parsed also, that should match exactly and the 149 // safety spaces, " ", here should be removed. 150 aCurParamText << let_drToken.Text() << " "; 151 } 152 153 bool 154 PreProcessor::CheckForDefine( cpp::Token & let_drToken ) 155 { 156 String sTokenText(let_drToken.Text()); 157 pCurMacro = csv::value_from_map( *pCurValidDefines, sTokenText ); 158 if (pCurMacro == 0 ) 159 return false; 160 for ( StringVector::const_iterator it = aBlockedMacroNames.begin(); 161 it != aBlockedMacroNames.end(); 162 ++it ) 163 { 164 if ( strcmp( (*it).c_str(), let_drToken.Text() ) == 0 ) 165 return false; 166 } 167 168 if ( pCurMacro->DefineType() == DefineDescription::type_define ) 169 { 170 delete &let_drToken; 171 172 aCurParamText.seekp(0); 173 pCurMacro->GetDefineText(aCurParamText); 174 175 if ( aCurParamText.tellp() > 1 ) 176 pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 177 } 178 else // ( pCurMacro->DefineType() == DefineDescription::type_macro ) 179 { 180 dpCurMacroName = &let_drToken; 181 eState = expect_macro_bracket_left; 182 csv::erase_container( aCurMacroParams ); 183 aCurParamText.seekp(0); 184 nBracketInParameterCounter = 0; 185 } // endif 186 187 return true; 188 } 189 190 void 191 PreProcessor::UnblockMacro( const char * i_sMacroName ) 192 { 193 for ( StringVector::iterator it = aBlockedMacroNames.begin(); 194 it != aBlockedMacroNames.end(); 195 ++it ) 196 { 197 if ( strcmp( (*it), i_sMacroName ) == 0 ) 198 { 199 aBlockedMacroNames.erase(it); 200 break; 201 } 202 } /// end for 203 } 204 205 void 206 PreProcessor::InterpretMacro() 207 { 208 aCurParamText.seekp(0); 209 pCurMacro->GetMacroText(aCurParamText, aCurMacroParams); 210 211 if ( NOT csv::no_str(aCurParamText.c_str()) ) 212 { 213 aCurParamText.seekp(-1, csv::cur); 214 aCurParamText << " #unblock-" << dpCurMacroName->Text() << " "; 215 216 pSourceText->InsertTextAtCurPos(aCurParamText.c_str()); 217 String sCurMacroName(dpCurMacroName->Text()); 218 aBlockedMacroNames.insert( aBlockedMacroNames.begin(), sCurMacroName ); 219 } 220 221 delete dpCurMacroName; 222 dpCurMacroName = 0; 223 pCurMacro = 0; 224 csv::erase_container(aCurMacroParams); 225 aCurParamText.seekp(0); 226 } 227 228 229 } // end namespace cpp 230 231 232