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