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
PreProcessor()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
~PreProcessor()61 PreProcessor::~PreProcessor()
62 {
63 }
64
65 void
AssignPartners(CodeExplorer & o_rCodeExplorer,CharacterSource & o_rCharSource,const MacroMap & i_rCurValidDefines)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
Process_Token(cpp::Token & let_drToken)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
On_plain(cpp::Token & let_drToken)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
On_expect_macro_bracket_left(cpp::Token & let_drToken)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
On_expect_macro_param(cpp::Token & let_drToken)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
CheckForDefine(cpp::Token & let_drToken)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
UnblockMacro(const char * i_sMacroName)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
InterpretMacro()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