xref: /trunk/main/autodoc/source/parser/cpp/preproc.cxx (revision a3cdc23e488c57f3433f22cd4458e65c27aa499c)
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 // NOT FULLY DEFINED SERVICES
26 #include <cosv/tpl/tpltools.hxx>
27 #include "all_toks.hxx"
28 #include "defdescr.hxx"
29 #include <tools/tkpchars.hxx>
30 #include "c_rcode.hxx"
31 
32 namespace cpp
33 {
34 
35 PreProcessor::F_TOKENPROC PreProcessor::aTokProcs[PreProcessor::state_MAX] =
36     {
37         &PreProcessor::On_plain,
38         &PreProcessor::On_expect_macro_bracket_left,
39         &PreProcessor::On_expect_macro_param
40     };
41 
42 PreProcessor::PreProcessor()
43     :   pCppExplorer(0),
44         pSourceText(0),
45         pCurValidDefines(0),
46         // aTokens,
47         eState(plain),
48         pCurMacro(0),
49         dpCurMacroName(0),
50         // aCurMacroParams,
51         aCurParamText(60000),
52         nBracketInParameterCounter(0)
53         // aBlockedMacroNames
54 {
55 }
56 
57 PreProcessor::~PreProcessor()
58 {
59 }
60 
61 void
62 PreProcessor::AssignPartners( CodeExplorer &      o_rCodeExplorer,
63                               CharacterSource &   o_rCharSource,
64                               const MacroMap &    i_rCurValidDefines )
65 {
66     pCppExplorer = &o_rCodeExplorer;
67     pSourceText = &o_rCharSource;
68     pCurValidDefines = &i_rCurValidDefines;
69 }
70 
71 void
72 PreProcessor::Process_Token( cpp::Token & let_drToken )
73 {
74     csv_assert(pCppExplorer != 0); // Implies pSourceText and pCurValidDefines.
75 
76     (this->*aTokProcs[eState])(let_drToken);
77 }
78 
79 void
80 PreProcessor::On_plain( cpp::Token & let_drToken )
81 {
82     if ( let_drToken.TypeId() == Tid_Identifier )
83     {
84         if (CheckForDefine(let_drToken))
85             return;
86     }
87 
88     pCppExplorer->Process_Token(let_drToken);
89 }
90 
91 void
92 PreProcessor::On_expect_macro_bracket_left( cpp::Token & let_drToken )
93 {
94     if ( let_drToken.TypeId() == Tid_Bracket_Left )
95     {
96         aCurParamText.seekp(0);
97         eState = expect_macro_param;
98     }
99     else
100     {
101         pCppExplorer->Process_Token(*dpCurMacroName);
102         dpCurMacroName = 0;
103         pCppExplorer->Process_Token(let_drToken);
104         eState = plain;
105     }
106 }
107 
108 void
109 PreProcessor::On_expect_macro_param( cpp::Token & let_drToken )
110 {
111     if ( let_drToken.TypeId() == Tid_Bracket_Left )
112         nBracketInParameterCounter++;
113     else if ( let_drToken.TypeId() == Tid_Bracket_Right )
114     {
115         if ( nBracketInParameterCounter > 0 )
116             nBracketInParameterCounter--;
117         else
118         {
119             if ( NOT csv::no_str(aCurParamText.c_str()) )
120             {
121                 aCurMacroParams.push_back( String(aCurParamText.c_str()) );
122             }
123             csv_assert( aCurMacroParams.size() == pCurMacro->ParamCount() );
124 
125             InterpretMacro();
126             eState = plain;
127             return;
128         }
129     }
130     else if ( let_drToken.TypeId() == Tid_Comma AND nBracketInParameterCounter == 0 )
131     {
132         aCurMacroParams.push_back( String (aCurParamText.c_str()) );
133         aCurParamText.seekp(0);
134         return;
135     }
136 
137     // KORR_FUTURE:
138     // If in future whitespace is parsed also, that should match exactly and the
139     // safety spaces, " ", here should be removed.
140     aCurParamText << let_drToken.Text() << " ";
141 }
142 
143 bool
144 PreProcessor::CheckForDefine( cpp::Token & let_drToken )
145 {
146     String sTokenText(let_drToken.Text());
147     pCurMacro = csv::value_from_map( *pCurValidDefines, sTokenText );
148     if (pCurMacro == 0 )
149         return false;
150     for ( StringVector::const_iterator it = aBlockedMacroNames.begin();
151           it != aBlockedMacroNames.end();
152           ++it )
153     {
154         if ( strcmp( (*it).c_str(), let_drToken.Text() ) == 0 )
155             return false;
156     }
157 
158     if ( pCurMacro->DefineType() == DefineDescription::type_define )
159     {
160         delete &let_drToken;
161 
162         aCurParamText.seekp(0);
163         pCurMacro->GetDefineText(aCurParamText);
164 
165         if ( aCurParamText.tellp() > 1 )
166             pSourceText->InsertTextAtCurPos(aCurParamText.c_str());
167     }
168     else // ( pCurMacro->DefineType() == DefineDescription::type_macro )
169     {
170         dpCurMacroName = &let_drToken;
171         eState = expect_macro_bracket_left;
172         csv::erase_container( aCurMacroParams );
173         aCurParamText.seekp(0);
174         nBracketInParameterCounter = 0;
175     } // endif
176 
177     return true;
178 }
179 
180 void
181 PreProcessor::UnblockMacro( const char * i_sMacroName )
182 {
183     for ( StringVector::iterator it = aBlockedMacroNames.begin();
184           it != aBlockedMacroNames.end();
185           ++it )
186     {
187         if ( strcmp( (*it), i_sMacroName ) == 0 )
188         {
189             aBlockedMacroNames.erase(it);
190             break;
191         }
192     } // end for
193 }
194 
195 void
196 PreProcessor::InterpretMacro()
197 {
198     aCurParamText.seekp(0);
199     pCurMacro->GetMacroText(aCurParamText, aCurMacroParams);
200 
201     if ( NOT csv::no_str(aCurParamText.c_str()) )
202     {
203         aCurParamText.seekp(-1, csv::cur);
204         aCurParamText << " #unblock-" << dpCurMacroName->Text() << " ";
205 
206         pSourceText->InsertTextAtCurPos(aCurParamText.c_str());
207         String sCurMacroName(dpCurMacroName->Text());
208         aBlockedMacroNames.insert( aBlockedMacroNames.begin(), sCurMacroName );
209     }
210 
211     delete dpCurMacroName;
212     dpCurMacroName = 0;
213     pCurMacro = 0;
214     csv::erase_container(aCurMacroParams);
215     aCurParamText.seekp(0);
216 }
217 
218 
219 } // end namespace cpp
220 
221 /* vim: set noet sw=4 ts=4: */
222