blob: 9983d0a65959fde54b12b5f047cf5707c62ba033 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef ADC_CPP_SOWNSTCK_HXX
#define ADC_CPP_SOWNSTCK_HXX
// USED SERVICES
// BASE CLASSES
#include "cxt2ary.hxx"
// COMPONENTS
#include <ary/cpp/c_types4cpp.hxx>
#include <estack.hxx>
// PARAMETERS
#include <ary/cpp/c_namesp.hxx>
#include <x_parse.hxx>
namespace cpp
{
using ary::cpp::E_Protection;
/** Implementation struct for cpp::ContextForAry.
*/
struct ContextForAry::S_OwnerStack
{
public:
S_OwnerStack();
void SetGlobalNamespace(
ary::cpp::Namespace &
io_rGlobalNamespace );
~S_OwnerStack();
void Reset();
void OpenNamespace(
ary::cpp::Namespace &
io_rOpenedNamespace );
void OpenExternC();
void OpenClass(
ary::cpp::Class & io_rOpenedClass );
void OpenEnum(
ary::cpp::Enum & io_rOpenedEnum );
void CloseBlock();
void CloseClass();
void CloseEnum();
void SetCurProtection(
ary::cpp::E_Protection
i_eProtection );
ary::cpp::Namespace &
CurNamespace() const;
ary::cpp::Class * CurClass() const;
ary::cpp::Enum * CurEnum() const;
Owner & CurOwner() const;
ary::cpp::E_Protection
CurProtection() const;
bool IsExternC() const { return nExternC > 0; }
private:
typedef std::pair< ary::cpp::Class*, E_Protection > ClassEnv;
typedef EStack< ary::cpp::Namespace* > Stack_Namespaces;
typedef EStack< ClassEnv > Stack_Classes;
typedef ary::cpp::InputContext::Owner Ifc_Owner;
void SetOwner_2CurNamespace();
void SetOwner_2CurClass();
void SetOwner_2None();
// DATA
Stack_Namespaces aStack_Namespaces;
Stack_Classes aStack_Classes;
ary::cpp::Enum * pCurEnum;
uintt nExternC; /// This is a number, for the case that extern "C" blocks are nested.
Dyn<Owner_Namespace>
pOwner_Namespace;
Dyn<Owner_Class> pOwner_Class;
Ifc_Owner * pOwner_Cur;
};
// IMPLEMENTATION
/* The implementation is in header, though not inline, because this file is included
in cxt2ary.cxx only!
*/
inline ary::cpp::Namespace &
ContextForAry::
S_OwnerStack::CurNamespace() const
{
csv_assert( ! aStack_Namespaces.empty() );
return *aStack_Namespaces.top();
}
inline ary::cpp::Class *
ContextForAry::
S_OwnerStack::CurClass() const
{
return !aStack_Classes.empty()
? aStack_Classes.top().first
: (ary::cpp::Class *) 0;
}
inline void
ContextForAry::
S_OwnerStack::SetOwner_2CurNamespace()
{
csv_assert( !aStack_Namespaces.empty() );
pOwner_Cur = pOwner_Namespace.MutablePtr();
pOwner_Namespace->SetAnotherNamespace( CurNamespace() );
}
inline void
ContextForAry::
S_OwnerStack::SetOwner_2CurClass()
{
csv_assert( !aStack_Classes.empty() );
pOwner_Cur = pOwner_Class.MutablePtr();
pOwner_Class->SetAnotherClass( *CurClass() );
}
ContextForAry::
S_OwnerStack::S_OwnerStack()
: // aStack_Namespaces,
// aStack_Classes,
pCurEnum(0),
nExternC(0),
pOwner_Namespace(new Owner_Namespace),
pOwner_Class(new Owner_Class),
pOwner_Cur(0)
{
}
void
ContextForAry::
S_OwnerStack::Reset()
{
while ( aStack_Namespaces.top()->Owner().IsValid() )
aStack_Namespaces.pop();
while ( NOT aStack_Classes.empty() )
aStack_Classes.pop();
pCurEnum = 0;
nExternC = 0;
SetOwner_2CurNamespace();
}
inline void
ContextForAry::
S_OwnerStack::SetGlobalNamespace( ary::cpp::Namespace & io_rGlobalNamespace )
{
csv_assert( aStack_Namespaces.empty() );
aStack_Namespaces.push(&io_rGlobalNamespace);
SetOwner_2CurNamespace();
}
ContextForAry::
S_OwnerStack::~S_OwnerStack()
{
}
inline void
ContextForAry::
S_OwnerStack::OpenNamespace( ary::cpp::Namespace & io_rOpenedNamespace )
{
csv_assert( !aStack_Namespaces.empty() OR io_rOpenedNamespace.Parent() == 0 );
aStack_Namespaces.push(&io_rOpenedNamespace);
SetOwner_2CurNamespace();
}
inline void
ContextForAry::
S_OwnerStack::OpenExternC()
{
++nExternC;
// SetOwner_2None();
}
inline void
ContextForAry::
S_OwnerStack::SetCurProtection( ary::cpp::E_Protection i_eProtection )
{
csv_assert( ! aStack_Classes.empty() );
aStack_Classes.top().second = i_eProtection;
}
inline ary::cpp::Enum *
ContextForAry::
S_OwnerStack::CurEnum() const
{
return pCurEnum;
}
inline ary::cpp::InputContext::Owner &
ContextForAry::
S_OwnerStack::CurOwner() const
{
csv_assert( pOwner_Cur != 0 );
return *pOwner_Cur;
}
inline E_Protection
ContextForAry::
S_OwnerStack::CurProtection() const
{
return !aStack_Classes.empty()
? aStack_Classes.top().second
: ary::cpp::PROTECT_global;
}
inline void
ContextForAry::
S_OwnerStack::SetOwner_2None()
{
pOwner_Cur = 0;
}
void
ContextForAry::
S_OwnerStack::OpenClass( ary::cpp::Class & io_rOpenedClass )
{
E_Protection eDefaultProtection
= io_rOpenedClass.ClassKey() == ary::cpp::CK_class
? ary::cpp::PROTECT_private
: ary::cpp::PROTECT_public;
aStack_Classes.push( ClassEnv(&io_rOpenedClass, eDefaultProtection) );
SetOwner_2CurClass();
}
inline void
ContextForAry::
S_OwnerStack::OpenEnum( ary::cpp::Enum & io_rOpenedEnum )
{
csv_assert( pCurEnum == 0 );
pCurEnum = &io_rOpenedEnum;
SetOwner_2None();
}
void
ContextForAry::
S_OwnerStack::CloseBlock()
{
if (nExternC > 0)
{
--nExternC;
}
else
{
// csv_assert( aStack_Classes.empty() );
if ( !aStack_Classes.empty() )
throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
csv_assert( pCurEnum == 0 );
aStack_Namespaces.pop();
// csv_assert( !aStack_Namespaces.empty() );
if( aStack_Namespaces.empty() )
throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
}
SetOwner_2CurNamespace();
}
void
ContextForAry::
S_OwnerStack::CloseClass()
{
// csv_assert( !aStack_Classes.empty() );
if ( aStack_Classes.empty() )
throw X_Parser(X_Parser::x_UnspecifiedSyntaxError, "", String::Null_(), 0);
aStack_Classes.pop();
if ( !aStack_Classes.empty() )
SetOwner_2CurClass();
else
SetOwner_2CurNamespace();
}
void
ContextForAry::
S_OwnerStack::CloseEnum()
{
csv_assert( pCurEnum != 0 );
pCurEnum = 0;
if ( !aStack_Classes.empty() )
SetOwner_2CurClass();
else
SetOwner_2CurNamespace();
}
} // namespace cpp
#endif