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 
23 
24 #ifndef ADC_CPP_SOWNSTCK_HXX
25 #define ADC_CPP_SOWNSTCK_HXX
26 
27 
28 
29 // USED SERVICES
30 	// BASE CLASSES
31 #include "cxt2ary.hxx"
32 	// COMPONENTS
33 #include <ary/cpp/c_types4cpp.hxx>
34 #include <estack.hxx>
35 	// PARAMETERS
36 #include <ary/cpp/c_namesp.hxx>
37 #include <x_parse.hxx>
38 
39 
40 namespace cpp
41 {
42 
43 using ary::cpp::E_Protection;
44 
45 
46 /** Implementation struct for cpp::ContextForAry.
47 */
48 struct ContextForAry::S_OwnerStack
49 {
50   public:
51                         S_OwnerStack();
52     void                SetGlobalNamespace(
53 							ary::cpp::Namespace &
54                                                 io_rGlobalNamespace );
55                         ~S_OwnerStack();
56 
57     void                Reset();
58 
59 	void                OpenNamespace(
60 							ary::cpp::Namespace &
61                                                 io_rOpenedNamespace );
62 	void                OpenExternC();
63 	void                OpenClass(
64 							ary::cpp::Class &	io_rOpenedClass );
65 	void                OpenEnum(
66 							ary::cpp::Enum &	io_rOpenedEnum );
67 	void                CloseBlock();
68 	void                CloseClass();
69 	void                CloseEnum();
70     void                SetCurProtection(
71                             ary::cpp::E_Protection
72                                                 i_eProtection );
73     ary::cpp::Namespace &
74                         CurNamespace() const;
75     ary::cpp::Class *   CurClass() const;
76     ary::cpp::Enum *    CurEnum() const;
77 
78     Owner &             CurOwner() const;
79     ary::cpp::E_Protection
80                         CurProtection() const;
IsExternCcpp::ContextForAry::S_OwnerStack81     bool                IsExternC() const       { return nExternC > 0; }
82 
83   private:
84     typedef std::pair< ary::cpp::Class*, E_Protection >     ClassEnv;
85     typedef EStack< ary::cpp::Namespace* >                  Stack_Namespaces;
86     typedef EStack< ClassEnv >                              Stack_Classes;
87     typedef ary::cpp::InputContext::Owner                   Ifc_Owner;
88 
89     void                SetOwner_2CurNamespace();
90     void                SetOwner_2CurClass();
91     void                SetOwner_2None();
92 
93     // DATA
94     Stack_Namespaces    aStack_Namespaces;
95     Stack_Classes       aStack_Classes;
96     ary::cpp::Enum *    pCurEnum;
97     uintt               nExternC;               /// This is a number, for the case that extern "C" blocks are nested.
98 
99     Dyn<Owner_Namespace>
100                         pOwner_Namespace;
101     Dyn<Owner_Class>    pOwner_Class;
102     Ifc_Owner *         pOwner_Cur;
103 };
104 
105 
106 // IMPLEMENTATION
107 
108 /*  The implementation is in header, though not inline, because this file is included
109     in cxt2ary.cxx only!
110 */
111 
112 inline ary::cpp::Namespace &
113 ContextForAry::
CurNamespace() const114 S_OwnerStack::CurNamespace() const
115 {
116     csv_assert( ! aStack_Namespaces.empty() );
117     return *aStack_Namespaces.top();
118 }
119 
120 inline ary::cpp::Class *
121 ContextForAry::
CurClass() const122 S_OwnerStack::CurClass() const
123 {
124     return !aStack_Classes.empty()
125                 ?   aStack_Classes.top().first
126                 :   (ary::cpp::Class *) 0;
127 }
128 
129 inline void
130 ContextForAry::
SetOwner_2CurNamespace()131 S_OwnerStack::SetOwner_2CurNamespace()
132 {
133     csv_assert( !aStack_Namespaces.empty() );
134     pOwner_Cur = pOwner_Namespace.MutablePtr();
135     pOwner_Namespace->SetAnotherNamespace( CurNamespace() );
136 }
137 
138 inline void
139 ContextForAry::
SetOwner_2CurClass()140 S_OwnerStack::SetOwner_2CurClass()
141 {
142     csv_assert( !aStack_Classes.empty() );
143     pOwner_Cur = pOwner_Class.MutablePtr();
144     pOwner_Class->SetAnotherClass( *CurClass() );
145 }
146 
147 ContextForAry::
S_OwnerStack()148 S_OwnerStack::S_OwnerStack()
149     :   // aStack_Namespaces,
150         // aStack_Classes,
151         pCurEnum(0),
152         nExternC(0),
153         pOwner_Namespace(new Owner_Namespace),
154         pOwner_Class(new Owner_Class),
155         pOwner_Cur(0)
156 {
157 }
158 
159 void
160 ContextForAry::
Reset()161 S_OwnerStack::Reset()
162 {
163     while ( aStack_Namespaces.top()->Owner().IsValid() )
164         aStack_Namespaces.pop();
165     while ( NOT aStack_Classes.empty() )
166         aStack_Classes.pop();
167     pCurEnum = 0;
168     nExternC = 0;
169     SetOwner_2CurNamespace();
170 }
171 
172 inline void
173 ContextForAry::
SetGlobalNamespace(ary::cpp::Namespace & io_rGlobalNamespace)174 S_OwnerStack::SetGlobalNamespace( ary::cpp::Namespace & io_rGlobalNamespace )
175 {
176     csv_assert( aStack_Namespaces.empty() );
177     aStack_Namespaces.push(&io_rGlobalNamespace);
178     SetOwner_2CurNamespace();
179 }
180 
181 ContextForAry::
~S_OwnerStack()182 S_OwnerStack::~S_OwnerStack()
183 {
184 }
185 
186 inline void
187 ContextForAry::
OpenNamespace(ary::cpp::Namespace & io_rOpenedNamespace)188 S_OwnerStack::OpenNamespace( ary::cpp::Namespace & io_rOpenedNamespace )
189 {
190     csv_assert( !aStack_Namespaces.empty()  OR io_rOpenedNamespace.Parent() == 0 );
191     aStack_Namespaces.push(&io_rOpenedNamespace);
192     SetOwner_2CurNamespace();
193 }
194 
195 inline void
196 ContextForAry::
OpenExternC()197 S_OwnerStack::OpenExternC()
198 {
199     ++nExternC;
200 //    SetOwner_2None();
201 }
202 
203 inline void
204 ContextForAry::
SetCurProtection(ary::cpp::E_Protection i_eProtection)205 S_OwnerStack::SetCurProtection( ary::cpp::E_Protection i_eProtection )
206 {
207     csv_assert( ! aStack_Classes.empty() );
208     aStack_Classes.top().second = i_eProtection;
209 }
210 
211 inline ary::cpp::Enum *
212 ContextForAry::
CurEnum() const213 S_OwnerStack::CurEnum() const
214 {
215     return pCurEnum;
216 }
217 
218 
219 inline ary::cpp::InputContext::Owner &
220 ContextForAry::
CurOwner() const221 S_OwnerStack::CurOwner() const
222 {
223     csv_assert( pOwner_Cur != 0 );
224     return *pOwner_Cur;
225 }
226 
227 inline E_Protection
228 ContextForAry::
CurProtection() const229 S_OwnerStack::CurProtection() const
230 {
231     return !aStack_Classes.empty()
232                 ?   aStack_Classes.top().second
233                 :   ary::cpp::PROTECT_global;
234 }
235 
236 inline void
237 ContextForAry::
SetOwner_2None()238 S_OwnerStack::SetOwner_2None()
239 {
240     pOwner_Cur = 0;
241 }
242 
243 void
244 ContextForAry::
OpenClass(ary::cpp::Class & io_rOpenedClass)245 S_OwnerStack::OpenClass( ary::cpp::Class & io_rOpenedClass )
246 {
247     E_Protection eDefaultProtection
248             = io_rOpenedClass.ClassKey() == ary::cpp::CK_class
249                     ?   ary::cpp::PROTECT_private
250                     :   ary::cpp::PROTECT_public;
251     aStack_Classes.push( ClassEnv(&io_rOpenedClass, eDefaultProtection) );
252     SetOwner_2CurClass();
253 }
254 
255 inline void
256 ContextForAry::
OpenEnum(ary::cpp::Enum & io_rOpenedEnum)257 S_OwnerStack::OpenEnum( ary::cpp::Enum & io_rOpenedEnum )
258 {
259     csv_assert( pCurEnum == 0 );
260     pCurEnum = &io_rOpenedEnum;
261     SetOwner_2None();
262 }
263 
264 void
265 ContextForAry::
CloseBlock()266 S_OwnerStack::CloseBlock()
267 {
268     if (nExternC > 0)
269     {
270         --nExternC;
271     }
272     else
273     {
274         // csv_assert( aStack_Classes.empty() );
275         if ( !aStack_Classes.empty() )
276     		throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
277 
278         csv_assert( pCurEnum == 0 );
279         aStack_Namespaces.pop();
280 
281         // csv_assert( !aStack_Namespaces.empty() );
282         if( aStack_Namespaces.empty() )
283     		throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
284 
285     }
286     SetOwner_2CurNamespace();
287 }
288 
289 void
290 ContextForAry::
CloseClass()291 S_OwnerStack::CloseClass()
292 {
293     // csv_assert( !aStack_Classes.empty() );
294     if ( aStack_Classes.empty() )
295   		throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
296 
297     aStack_Classes.pop();
298     if ( !aStack_Classes.empty() )
299         SetOwner_2CurClass();
300     else
301         SetOwner_2CurNamespace();
302 }
303 
304 void
305 ContextForAry::
CloseEnum()306 S_OwnerStack::CloseEnum()
307 {
308     csv_assert( pCurEnum != 0 );
309     pCurEnum = 0;
310     if ( !aStack_Classes.empty() )
311         SetOwner_2CurClass();
312     else
313         SetOwner_2CurNamespace();
314 }
315 
316 
317 }   // namespace cpp
318 
319 
320 #endif
321 
322