xref: /trunk/main/autodoc/source/parser/cpp/preproc.cxx (revision cdf0e10c)
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