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
10*78bc99aaSAndrew Rist  *
11*78bc99aaSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*78bc99aaSAndrew Rist  *
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.
19*78bc99aaSAndrew Rist  *
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 
PreProcessor()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 
~PreProcessor()61cdf0e10cSrcweir PreProcessor::~PreProcessor()
62cdf0e10cSrcweir {
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir void
AssignPartners(CodeExplorer & o_rCodeExplorer,CharacterSource & o_rCharSource,const MacroMap & i_rCurValidDefines)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
Process_Token(cpp::Token & let_drToken)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
On_plain(cpp::Token & let_drToken)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
On_expect_macro_bracket_left(cpp::Token & let_drToken)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
On_expect_macro_param(cpp::Token & let_drToken)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
CheckForDefine(cpp::Token & let_drToken)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
UnblockMacro(const char * i_sMacroName)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
InterpretMacro()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