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